├── docs ├── .nojekyll ├── assets │ ├── favicon │ │ └── favicon.png │ ├── vendor │ │ ├── docsify │ │ │ ├── plugins │ │ │ │ ├── docsify-footer.min.js │ │ │ │ ├── docsify-fontawesome.min.js │ │ │ │ ├── docsify-footer.js │ │ │ │ ├── docsify-img-grid.js │ │ │ │ ├── toc.js │ │ │ │ ├── docsify-fontawesome.js │ │ │ │ └── search.js │ │ │ └── LICENSE │ │ └── themeable │ │ │ ├── LICENSE │ │ │ └── docsify-themeable.min.js │ └── css │ │ ├── editor.css │ │ ├── toc.css │ │ ├── print.css │ │ ├── custom.css │ │ └── theme.css ├── images │ ├── 12650723674_d5c85af332_k.jpg │ ├── 4642289926_7964e733d1_b.jpg │ ├── 4853380320_492f9dce63_b.jpg │ ├── 6384294717_5047a35d48_b.jpg │ ├── 6968244538_4c0f7c7e64_k.jpg │ ├── ux-toolkit-8-no-numbers.png │ ├── dave-hoefler-vl2uAIdBWJ8-unsplash.jpg │ └── belinda-fewings-6wAGwpsXHE0-unsplash.jpg ├── _navbar.md ├── contact.md ├── module-06.md ├── module-07.md ├── module-08.md ├── module-09.md ├── module-10.md ├── module-11.md ├── module-12.md ├── module-13.md ├── _footer.md ├── course-welcome.md ├── home.md ├── module-05.md ├── module-03.md ├── topics.md ├── module-01.md ├── module-04.md ├── module-02.md ├── _sidebar.md ├── lms-topics.md ├── schedule.md ├── lms-schedule.md ├── resources.md └── index.html ├── screenshot.jpg ├── screenshot-2.jpg ├── .gitignore ├── LICENSE ├── CHANGELOG.md └── README.md /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/screenshot.jpg -------------------------------------------------------------------------------- /screenshot-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/screenshot-2.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | .DS_Store? 5 | .vscode 6 | .vscode? 7 | .obsidian 8 | .obsidian? -------------------------------------------------------------------------------- /docs/assets/favicon/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/assets/favicon/favicon.png -------------------------------------------------------------------------------- /docs/images/12650723674_d5c85af332_k.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/12650723674_d5c85af332_k.jpg -------------------------------------------------------------------------------- /docs/images/4642289926_7964e733d1_b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/4642289926_7964e733d1_b.jpg -------------------------------------------------------------------------------- /docs/images/4853380320_492f9dce63_b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/4853380320_492f9dce63_b.jpg -------------------------------------------------------------------------------- /docs/images/6384294717_5047a35d48_b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/6384294717_5047a35d48_b.jpg -------------------------------------------------------------------------------- /docs/images/6968244538_4c0f7c7e64_k.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/6968244538_4c0f7c7e64_k.jpg -------------------------------------------------------------------------------- /docs/images/ux-toolkit-8-no-numbers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/ux-toolkit-8-no-numbers.png -------------------------------------------------------------------------------- /docs/_navbar.md: -------------------------------------------------------------------------------- 1 | * [Schedule](schedule.md) 2 | * [Topics](topics.md) 3 | * [Resources](resources.md) 4 | * [UX Techniques Guide](ux-techniques-guide.md) 5 | * [Contact](contact.md) 6 | -------------------------------------------------------------------------------- /docs/images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg -------------------------------------------------------------------------------- /docs/images/belinda-fewings-6wAGwpsXHE0-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hibbitts-design/docsify-open-course-starter-kit/HEAD/docs/images/belinda-fewings-6wAGwpsXHE0-unsplash.jpg -------------------------------------------------------------------------------- /docs/contact.md: -------------------------------------------------------------------------------- 1 | # Contact 2 | 3 | ## Course Instructor 4 | Some Name 5 | somename@somewhere.edu 6 | 7 | Online office hours: 8 | Mondays 12:00-1:30pm 9 | Fridays 12:00-1:00pm 10 | 11 | Suggestion, concern or complaint? 12 | Send me your [anonymous course feedback](#)! 13 | -------------------------------------------------------------------------------- /docs/module-06.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-07.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-08.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-09.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-10.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-11.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-12.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/module-13.md: -------------------------------------------------------------------------------- 1 | ![Image Description](images/dave-hoefler-vl2uAIdBWJ8-unsplash.jpg ':class=banner-image') 2 | 3 | # Module Title 4 | 5 | ## Content Header 6 | Module content here. 7 | 8 | ## Content Header 9 | Module content here. 10 | 11 | ## Content Header 12 | Module content here. 13 | 14 | ## Content Header 15 | Module content here. 16 | -------------------------------------------------------------------------------- /docs/_footer.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/docsify-footer.min.js: -------------------------------------------------------------------------------- 1 | !function(o,i,t){i.plugins=[].concat((function(i,t){const{loadFooter:e,ext:n,requestHeaders:c}=t.config;e&&i.afterEach((function(i,l){try{var s=window.location.hash.slice(1).split("/").slice(0,-1).join("/"),r=!1,a=(s=s?s+"/":"")+(!0===e?"_footer"+n:e);o.get(t.router.getFile(a),!1,c).then((o=>{const e=t.compiler.compile(o);r=!0,l(i+e)}))}finally{r||l(i)}}))}),i.plugins)}(Docsify,$docsify); -------------------------------------------------------------------------------- /docs/course-welcome.md: -------------------------------------------------------------------------------- 1 | ![Welcome sign](images/belinda-fewings-6wAGwpsXHE0-unsplash.jpg ':class=banner-image') 2 | 3 | # Welcome to CPT-363 User Interface Design 👋🏼 4 | 5 | To help orientate yourself to the course, explore the [course syllabus](https://canvas.sfu.ca/courses/44038/assignments/syllabus). You may also want to view a brief tour of [Blackboard Collaborate Ultra](https://www.youtube.com/watch?v=1W4sGpVmJaY). 6 | 7 | Is this your first online course? If so, you might find these articles of help: 8 | 9 | * [8 Strategies for Getting the Most Out of an Online Class](https://www.northeastern.edu/graduate/blog/tips-for-taking-online-classes/) 10 | * [What Makes a Successful Online Learner?](https://careerwise.minnstate.edu/education/successonline.html) 11 | * [Student toolkit to help tackle remote learning](https://socialmediaforlearning.com/2020/03/22/guest-post-a-student-toolkit-to-help-you-tackle-remote-learning-written-by-students-for-students/) 12 | -------------------------------------------------------------------------------- /docs/home.md: -------------------------------------------------------------------------------- 1 | > # What’s Happening This Week 2 | > ## How to explore the problem space? 3 | > ### Important Reminders 4 | > * [Journey Map](#) assignment Tue Jun 12th 11:59pm PDT 5 | > * [Course Reflection Log](#) assignment Fri Aug 3rd 11:59pm PDT 6 | > 7 | > ### Required Reading 8 | > * [The Skeptic’s Guide To Low-Fidelity Prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/) 9 | > 10 | > [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button') 11 | 12 | # Looking Ahead to Next Week 13 | ## How to plan, conduct, and summarize usability tests? 14 | ### Week 5 Required Reading 15 | The Art of Guerrilla Usability Testing | UX Booth 16 | 17 | ### Week 5 Slides to be Discussed 18 | [Usability Testing](https://www.google.ca/slides/about/) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Paul Hibbitts 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 - present cinwell.li 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/assets/vendor/themeable/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 John Hildenbiddle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/module-05.md: -------------------------------------------------------------------------------- 1 | ![Usability Test](images/4642289926_7964e733d1_b.jpg ':class=banner-image') 2 | 3 | # How to plan, conduct, and summarize usability tests? 4 | 5 | ## Summaries and Questions 6 | [Jun 6th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377746) 7 | 8 | ## Presented Slides 9 |
10 | 11 | ## Supplemental Materials 12 |
13 | 14 | ## Required Reading 15 | The Art of Guerrilla Usability Testing 16 | -------------------------------------------------------------------------------- /docs/module-03.md: -------------------------------------------------------------------------------- 1 | ![Bullseye](images/6384294717_5047a35d48_b.jpg ':class=banner-image') 2 | 3 | # How to make more strategic design decisions? 4 | 5 | ## Summaries and Questions 6 | [May 23rd Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377744) 7 | 8 | ## Presented Slides 9 |
10 | 11 | ## Supplemental Materials 12 |
13 | 14 | ## Assignments 15 | [Journey Map](https://sso.canvaslms.com/courses/1924881/assignments/14377756) 16 | 17 | ## Required Reading 18 | What is a User Journey Map? 19 | -------------------------------------------------------------------------------- /docs/topics.md: -------------------------------------------------------------------------------- 1 | # Topics 2 | 3 | [A](#a)| B | C |[D](#d)| E |[F](#f)| G |[H](#h)| I |[J](#j)|[K](#k)|[L](#l)|[M](#m)| N | O |[P](#p)| Q | R |[S](#s)|[T](#t)|[U](#u)|[V](#v)| W | X | Y | Z 4 | 5 | ## A 6 | [Agile UX](module-02) 7 | 8 | ## D 9 | [Design Ethics](module-02) 10 | [Design Thinking](module-01) 11 | 12 | ## F 13 | [5-Second Test](module-05) 14 | [Five Whys](module-01) 15 | 16 | ## H 17 | [Hypothesis](module-02) 18 | 19 | ## J 20 | [Journey Maps](module-03) 21 | 22 | ## K 23 | [Kano Model](module-03) 24 | 25 | ## L 26 | [Lean UX](module-02) 27 | 28 | ## M 29 | [Microsoft Product Reaction Cards](module-02) 30 | 31 | ## P 32 | [Problem Statement](module-03) 33 | [Product Design Principles](module-03) 34 | [Prototyping](module-04) 35 | 36 | ## S 37 | [Scenario-based Design (and Task-Centered Design)](module-04) 38 | [Scenarios (and Design Scenarios)](module-04) 39 | [Sketching](module-04) 40 | [Social Design](module-01) 41 | [Software Design Processes](module-02) 42 | [Storyboards](module-04) 43 | 44 | ## T 45 | [Task Analysis](module-02) 46 | 47 | ## U 48 | [Usability](module-01) 49 | [Usability Goals](module-02) 50 | [Usability Testing](module-05) 51 | [User-centered Design (UCD)](module-01) 52 | [User Experience Design](module-02) 53 | [UX Goals](module-02) 54 | [UX Strategy](module-03) 55 | 56 | ## V 57 | [Value Proposition](module-03) 58 | -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/docsify-fontawesome.min.js: -------------------------------------------------------------------------------- 1 | !function(e){var n={};function r(t){if(n[t])return n[t].exports;var o=n[t]={i:t,l:!1,exports:{}};return e[t].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=n,r.d=function(e,n,t){r.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,n){if(1&n&&(e=r(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(r.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)r.d(t,o,function(n){return e[n]}.bind(null,o));return t},r.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(n,"a",n),n},r.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r.p="",r(r.s=0)}([function(e,n,r){"use strict";r.r(n),window.$docsify=window.$docsify||{},window.$docsify.plugins=(window.$docsify.plugins||[]).concat((function(e){const n=/:fa[\w -]+:/gm;e.beforeEach(e=>e.replace(n,(function(e,n){return console.log("m: "+e.replace(/:/gi,"")),``}))),e.afterEach((function(e,r){r(e.replace(n,(function(e,n){return console.log("m: "+e.replace(/:/gi,"")),``})))}))}))}]); -------------------------------------------------------------------------------- /docs/module-01.md: -------------------------------------------------------------------------------- 1 | ![UX - User Experience](images/12650723674_d5c85af332_k.jpg ':class=banner-image') 2 | 3 | # What is usability and user experience design? 4 | 5 | ## Summaries and Questions 6 | [May 9th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377751) 7 | 8 | ## Presented Slides 9 |
10 | 11 | ## Supplemental Materials 12 | [Elements of User Experience by Jesse James Garrett](https://qofr.files.wordpress.com/2016/11/q-of-r-presentation-11.pdf) 13 |
14 | 15 | ## Downloads 16 | [Course Overview](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Course%20Overview) 17 | 18 | ## Recommended Reading 19 | Usability 101: Introduction to Usability 20 | -------------------------------------------------------------------------------- /docs/module-04.md: -------------------------------------------------------------------------------- 1 | ![Wireframe](images/6968244538_4c0f7c7e64_k.jpg ':class=banner-image') 2 | 3 | # How to explore the problem space? 4 | 5 | ## Summaries and Questions 6 | [May 30th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377745) 7 | 8 | ## Presented Slides 9 |
10 | 11 | ## Supplemental Materials 12 |
13 | 14 | ## Downloads 15 | [4-UP BROWSERS + GRID](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Sketching%20Templates/sneakpeekit-4-browsers) 16 | [4-UP MOBILES + GRID](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Sketching%20Templates/sneakpeekit-4-mobiles) 17 | 18 | ## Required Reading 19 | The Skeptic’s Guide To Low-Fidelity Prototyping 20 | -------------------------------------------------------------------------------- /docs/module-02.md: -------------------------------------------------------------------------------- 1 | ![Flowchart](images/4853380320_492f9dce63_b.jpg ':class=banner-image') 2 | 3 | # What does a holistic user experience design process look like? 4 | 5 | ## Summaries and Questions 6 | [May 16th Class One-minute Summaries](https://sso.canvaslms.com/courses/1924881/assignments/14377743) 7 | 8 | ## Presented Slides 9 |
10 | 11 | ## CPT-363 UX Design Process/Toolkit 12 | ![UX Design Process/Toolkit](images/ux-toolkit-8-no-numbers.png) 13 | 14 | ## Downloads 15 | [Product Reaction Cards](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Product%20Reaction%20Cards) 16 | 17 | ## Assignments 18 | [Course Reflection Log](https://sso.canvaslms.com/courses/1413912/assignments/9519528) 19 | 20 | ## Quick Quiz 21 | 22 | 23 | ## Recommended Reading 24 | The Evolution of UX Process Methodology 25 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | - [Course Welcome](course-welcome) 2 | - [Week 1 (May 9 - 15)](module-01) 3 | - [Week 2 (May 16 - 22)](module-02) 4 | - [Week 3 (May 23 - 29)](module-03) 5 | - [Week 4 (May 30 - Jun 5)](module-04) 6 | - **LMS Links** 7 | - [![Calendar Icon](https://icongr.am/fontawesome/calendar.svg?size=16&color=808080)Calendar](https://canvas.sfu.ca/courses/44038/calendar) 8 | - [![Assignments Icon](https://icongr.am/fontawesome/pencil.svg?size=16&color=808080)Assignments](https://canvas.sfu.ca/courses/44038/assignments ) 9 | - [![Quizzes Icon](https://icongr.am/fontawesome/check-circle.svg?size=16&color=808080)Quizzes](https://canvas.sfu.ca/courses/44038/quizzes) 10 | - [![Class Discussions Icon](https://icongr.am/fontawesome/comments-o.svg?size=16&color=808080)Class Discussions](https://canvas.sfu.ca/courses/44038/discussion_topics) 11 | - [![Syllabus Icon](https://icongr.am/fontawesome/list.svg?size=16&color=808080)Syllabus](https://canvas.sfu.ca/courses/44038/assignments/syllabus) 12 | - **Project Info** 13 | - [GitHub Repository](https://github.com/hibbitts-design/docsify-open-course-starter-kit/) 14 | - [ReadMe](https://github.com/hibbitts-design/docsify-open-course-starter-kit/blob/main/README.md) 15 | 16 |
17 | 18 |
-------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/docsify-footer.js: -------------------------------------------------------------------------------- 1 | // Support for footer files ('_footer.md') in subfolders 2 | // Original source plugin 'docsify-footer' by @alertbox 3 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 4 | (function (Docsify, $docsify, undefined) { 5 | const DEFAULT_FOOTER = "_footer"; 6 | 7 | const install = function (hook, vm) { 8 | const { loadFooter, ext, requestHeaders } = vm.config; 9 | 10 | // Fail fast if loadFooter is not defined 11 | if (!loadFooter) { 12 | return; 13 | } 14 | 15 | hook.afterEach(function (html, next) { 16 | try { 17 | // Parse current URL to extract folder path 18 | var urlFragment = window.location.hash.slice(1); // Remove '#' character 19 | var pathSegments = urlFragment.split("/"); 20 | var folderPath = pathSegments.slice(0, -1).join("/"); // Exclude the file part 21 | folderPath = folderPath ? folderPath + "/" : ""; // Ensure folder path ends with '/' 22 | 23 | var footerAppended = false; // Flag to indicate footer append status 24 | 25 | var footerFile = 26 | folderPath + 27 | (loadFooter === true ? DEFAULT_FOOTER + ext : loadFooter); 28 | 29 | // Fetch and append the footer content 30 | Docsify.get(vm.router.getFile(footerFile), false, requestHeaders) 31 | .then((content) => { 32 | const footerHtml = vm.compiler.compile(content); 33 | footerAppended = true; // Set flag to true as footer is appended 34 | next(html + footerHtml); // Append the footer to the current page content 35 | }) 36 | } finally { 37 | // Check if footer was not appended, then pass html 38 | if (!footerAppended) { 39 | next(html); 40 | } 41 | } 42 | }); 43 | }; 44 | 45 | $docsify.plugins = [].concat(install, $docsify.plugins); 46 | })(Docsify, $docsify); 47 | -------------------------------------------------------------------------------- /docs/assets/css/editor.css: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================================================================== 3 | CSS for better Markdown previews within a text editor. 4 | =============================================================================================================================== 5 | */ 6 | 7 | .badge { 8 | color: var(--badge-text-color, #fff); /* Default text color */ 9 | background-color: var(--badge-bg-color, #6c757d); /* Default background */ 10 | 11 | display: inline-block; 12 | padding: .25em .4em .25em .4em; 13 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 14 | font-size: 75%; 15 | font-weight: 700; 16 | line-height: 1; 17 | text-align: center; 18 | white-space: nowrap; 19 | vertical-align: middle; 20 | margin-top: -0.4em; 21 | border-radius: .25rem; 22 | transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; 23 | text-decoration: none; 24 | } 25 | 26 | .badge a { 27 | color: var(--badge-text-color, #fff)!important; /* Default text color */ 28 | text-decoration: none !important; 29 | } 30 | 31 | ul { 32 | list-style: square outside none; 33 | } 34 | 35 | .alert { 36 | overflow: visible; 37 | margin: 2em 0; 38 | padding: 1.5em; 39 | background: #f7f7f7; 40 | } 41 | 42 | .alert ul { 43 | list-style: none; 44 | margin-top: .8em; 45 | } 46 | 47 | .alert ul li { 48 | margin: 2px 0; 49 | } 50 | 51 | .alert ul li:before { 52 | position: absolute; 53 | content: '\2B29'; 54 | margin-left: -18px; 55 | } 56 | 57 | .blockquote ul { 58 | list-style: none; 59 | margin-top: .8em; 60 | } 61 | 62 | .blockquote ul li { 63 | margin: 2px 0; 64 | } 65 | 66 | .blockquote ul li:before { 67 | position: absolute; 68 | content: '\2B29'; 69 | margin-left: -18px; 70 | } 71 | 72 | .video-container-4by3 { 73 | position: relative; 74 | padding-bottom: 75%; 75 | height: 0; 76 | overflow: hidden; 77 | max-width: 100%; 78 | } 79 | 80 | .video-container-16by9 { 81 | position: relative; 82 | padding-bottom: 56.25%; 83 | height: 0; 84 | overflow: hidden; 85 | max-width: 100%; 86 | } 87 | 88 | .video-container-16by9 iframe, .video-container-4by3 iframe, .embed-container object, .embed-container embed { 89 | position: absolute; 90 | top: 0; 91 | left: 0; 92 | width: 100%; 93 | height: 93%; 94 | } 95 | -------------------------------------------------------------------------------- /docs/lms-topics.md: -------------------------------------------------------------------------------- 1 | # Topics 2 | 3 | [A](#a)| B | C |[D](#d)| E |[F](#f)| G |[H](#h)| I |[J](#j)|[K](#k)|[L](#l)|[M](#m)| N | O |[P](#p)| Q | R |[S](#s)|[T](#t)|[U](#u)|[V](#v)| W | X | Y | Z 4 | 5 | ## A 6 | [Agile UX](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 7 | 8 | ## D 9 | [Design Ethics](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 10 | [Design Thinking](https://canvas.sfu.ca/courses/44038/modules/items/1096965) 11 | 12 | ## F 13 | [5-Second Test](https://canvas.sfu.ca/courses/44038/modules/items/1096974) 14 | [Five Whys](https://canvas.sfu.ca/courses/44038/modules/items/1096965) 15 | 16 | ## H 17 | [Hypothesis](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 18 | 19 | ## J 20 | [Journey Maps](https://canvas.sfu.ca/courses/44038/modules/items/1096970) 21 | 22 | ## K 23 | [Kano Model](https://canvas.sfu.ca/courses/44038/modules/items/1096970) 24 | 25 | ## L 26 | [Lean UX](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 27 | 28 | ## M 29 | [Microsoft Product Reaction Cards](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 30 | 31 | ## P 32 | [Problem Statement](https://canvas.sfu.ca/courses/44038/modules/items/1096970) 33 | [Product Design Principles](https://canvas.sfu.ca/courses/44038/modules/items/1096970) 34 | [Prototyping](https://canvas.sfu.ca/courses/44038/modules/items/1096967) 35 | 36 | ## S 37 | [Scenario-based Design (and Task-Centered Design)](https://canvas.sfu.ca/courses/44038/modules/items/1096967) 38 | [Scenarios (and Design Scenarios)](https://canvas.sfu.ca/courses/44038/modules/items/1096967) 39 | [Sketching](https://canvas.sfu.ca/courses/44038/modules/items/1096967) 40 | [Social Design](https://canvas.sfu.ca/courses/44038/modules/items/1096965) 41 | [Software Design Processes](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 42 | [Storyboards](https://canvas.sfu.ca/courses/44038/modules/items/1096967) 43 | 44 | ## T 45 | [Task Analysis](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 46 | 47 | ## U 48 | [Usability](https://canvas.sfu.ca/courses/44038/modules/items/1096965) 49 | [Usability Goals](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 50 | [Usability Testing](https://canvas.sfu.ca/courses/44038/modules/items/1096974) 51 | [User-centered Design (UCD)](https://canvas.sfu.ca/courses/44038/modules/items/1096965) 52 | [User Experience Design](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 53 | [UX Goals](https://canvas.sfu.ca/courses/44038/modules/items/1096966) 54 | [UX Strategy](https://canvas.sfu.ca/courses/44038/modules/items/1096970) 55 | 56 | ## V 57 | [Value Proposition](https://canvas.sfu.ca/courses/44038/modules/items/1096970) 58 | -------------------------------------------------------------------------------- /docs/schedule.md: -------------------------------------------------------------------------------- 1 | # Schedule 2 | 3 | ## :fas fa-calendar fa-pull-left: [Week 1 (May 9 - 15)](module-01) 4 | **What is usability and user experience design?** 5 | :fas fa-desktop fa-fw: [Introduction to UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 6 | :fas fa-book fa-fw: [Usability 101: Introduction to Usability](https://www.nngroup.com/articles/usability-101-introduction-to-usability/) 7 | 8 | ## :fas fa-calendar fa-pull-left: [Week 2 (May 16 - 22)](module-02) 9 | **What does a holistic user experience design process look like?** 10 | :fas fa-keyboard fa-fw: [Course Reflection Log](https://sso.canvaslms.com/courses/1924881/assignments/14377752) Fri Aug 3rd 11:59pm PDT 11 | :fas fa-desktop fa-fw: [The Process of UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 12 | :fas fa-book fa-fw: [The Evolution of UX Process Methodology](https://uxplanet.org/the-evolution-of-ux-process-methodology-47f52557178b) 13 | 14 | ## :fas fa-calendar fa-pull-left: [Week 3 (May 23 - 29)](module-03) 15 | **How to make more strategic design decisions?** 16 | :fas fa-keyboard fa-fw: [Journey Map](https://sso.canvaslms.com/courses/1924881/assignments/14377756) Tue Jun 12th 11:59pm PDT 17 | :fas fa-folder fa-fw: [Informed Consent Materials](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Informed%20Consent) 18 | :fas fa-desktop fa-fw: [Strategic UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 19 | :fas fa-book fa-fw: [What is a User Journey Map?](https://www.aytech.ca/blog/user-journey-map/) 20 | 21 | ## :fas fa-calendar fa-pull-left: [Week 4 (May 30 - Jun 5)](module-04) 22 | **How to explore the problem space?** 23 | :fas fa-desktop fa-fw: [Prototyping](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 24 | :fas fa-book fa-fw: [The Skeptic’s Guide To Low-Fidelity Prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/) 25 | :fas fa-users fa-fw: In-class office hours (tentative) 26 | 27 | ## :fas fa-calendar fa-pull-left: [Week 5 (Jun 6 - 12)](module-05) 28 | **How to plan, conduct, and summarize usability tests?** 29 | :fas fa-desktop fa-fw: [Usability Testing](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 30 | :fas fa-book fa-fw: [The Art of Guerrilla Usability Testing](http://www.uxbooth.com/articles/the-art-of-guerrilla-usability-testing/) 31 | :fas fa-users fa-fw: In-class office hours (tentative) 32 | -------------------------------------------------------------------------------- /docs/assets/css/toc.css: -------------------------------------------------------------------------------- 1 | .content *::-webkit-scrollbar { 2 | background-color: transparent; 3 | width: 12px; 4 | } 5 | .content *::-webkit-scrollbar-track { 6 | background-color: transparent; 7 | } 8 | .content *::-webkit-scrollbar-thumb { 9 | border-radius: 20px; 10 | border: 3px solid transparent; 11 | background-color: rgba(0,0,0,0.3); 12 | background-clip: content-box; 13 | } 14 | .content { 15 | display: flex; 16 | flex-direction: row-reverse; 17 | justify-content: center; 18 | } 19 | /* Specific style for .token.content inside code blocks */ 20 | .content code .token.content { 21 | display: inline; 22 | } 23 | .markdown-section { 24 | flex: 1 1 0%; 25 | margin: 0 48px; 26 | } 27 | .nav { 28 | width: var(--toc-width, 280px); 29 | min-width: 200px; 30 | align-self: flex-start; 31 | flex: 0 0 auto; 32 | } 33 | aside.nav.nothing { 34 | width: 0; 35 | } 36 | 37 | .page_toc { 38 | border-left-style: solid; 39 | border-left-width: 1px; 40 | border-left-color: rgba(0, 0, 0, 0.07); 41 | border-image-slice: 1; 42 | padding-left: 5px; 43 | position: -webkit-sticky; 44 | position: fixed; 45 | overflow: auto; 46 | max-height: 100vh; 47 | top: 0; 48 | bottom: auto; 49 | margin-right: 10px; 50 | scrollbar-width: thin !important; 51 | scrollbar-color: grey transparent; 52 | } 53 | 54 | .page_toc a > * { 55 | pointer-events: none; 56 | } 57 | 58 | .page_toc code { 59 | background-color: #f8f8f8; 60 | border-radius: 2px; 61 | color: #e96900; 62 | font-family: 'Roboto Mono', Monaco, courier, monospace; 63 | font-size: 0.8rem; 64 | margin: 0 2px; 65 | padding: 3px 5px; 66 | } 67 | 68 | .page_toc p.title { 69 | margin: 0px 0 0px 9px; 70 | padding-top: 15px; 71 | padding-bottom: 5px; 72 | font-weight: 400; 73 | font-size: 1.2em; 74 | } 75 | .page_toc .anchor:hover:after { 76 | content: ""; 77 | } 78 | 79 | .page_toc ul { 80 | list-style-type: none; 81 | margin-top: 0px; 82 | padding-left: 10px; 83 | color: var(--base-color, black); 84 | text-decoration: none; 85 | font-weight: 400; 86 | line-height: 1.2em; 87 | } 88 | 89 | .page_toc ul a:hover span { 90 | border-bottom: none !important; 91 | text-decoration:underline !important; 92 | } 93 | 94 | .page_toc ul a { 95 | color: var(--base-color, black); 96 | text-decoration: none; 97 | font-weight: 400; 98 | line-height: 1.2em; 99 | } 100 | 101 | .page_toc ul li { 102 | padding-top: 7px; 103 | } 104 | 105 | @media screen and (max-width: 900px) { 106 | .page_toc { 107 | position: relative; 108 | top: -20px; 109 | padding: 10px 0; 110 | border: none; 111 | border-bottom: 1px solid #ddd; 112 | font-size: 1.0em; 113 | } 114 | .nav { 115 | margin: 0 auto; 116 | width: 900px; 117 | } 118 | .page_toc p.title { 119 | font-weight: 400; 120 | font-size: 1.2em; 121 | } 122 | .content { 123 | display: block; 124 | } 125 | .markdown-section { 126 | margin: 0 auto; 127 | } 128 | } 129 | 130 | /* 131 | .page_toc .active { 132 | border-left: 5px solid; 133 | color: var(--theme-color, #42b983); 134 | padding-left: 10px; 135 | } 136 | */ 137 | -------------------------------------------------------------------------------- /docs/lms-schedule.md: -------------------------------------------------------------------------------- 1 | # Schedule 2 | 3 | ## :fas fa-calendar fa-pull-left: Week 1 (May 9 - 15) 4 | **[What is usability and user experience design?](https://canvas.sfu.ca/courses/44038/modules/items/1096965)** 5 | :fas fa-desktop fa-fw: [Introduction to UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 6 | :fas fa-book fa-fw: [Usability 101: Introduction to Usability](https://www.nngroup.com/articles/usability-101-introduction-to-usability/) 7 | 8 | ## :fas fa-calendar fa-pull-left: Week 2 (May 16 - 22) 9 | **[What does a holistic user experience design process look like?](https://canvas.sfu.ca/courses/44038/modules/items/1096966)** 10 | :fas fa-keyboard fa-fw: [Course Reflection Log](https://sso.canvaslms.com/courses/1924881/assignments/14377752) Fri Aug 3rd 11:59pm PDT 11 | :fas fa-desktop fa-fw: [The Process of UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 12 | :fas fa-book fa-fw: [The Evolution of UX Process Methodology](https://uxplanet.org/the-evolution-of-ux-process-methodology-47f52557178b) 13 | 14 | ## :fas fa-calendar fa-pull-left: Week 3 (May 23 - 29) 15 | **[How to make more strategic design decisions?](https://canvas.sfu.ca/courses/44038/modules/items/1096970)** 16 | :fas fa-keyboard fa-fw: [Journey Map](https://sso.canvaslms.com/courses/1924881/assignments/14377756) Tue Jun 12th 11:59pm PDT 17 | :fas fa-folder fa-fw: [Informed Consent Materials](https://sso.canvaslms.com/courses/1924881/files/folder/Downloads/Informed%20Consent) 18 | :fas fa-desktop fa-fw: [Strategic UX Design](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 19 | :fas fa-book fa-fw: [What is a User Journey Map?](https://www.aytech.ca/blog/user-journey-map/) 20 | 21 | ## :fas fa-calendar fa-pull-left: Week 4 (May 30 - Jun 5) 22 | **[How to explore the problem space?](https://canvas.sfu.ca/courses/44038/modules/items/1096967)** 23 | :fas fa-desktop fa-fw: [Prototyping](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 24 | :fas fa-book fa-fw: [The Skeptic’s Guide To Low-Fidelity Prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/) 25 | :fas fa-users fa-fw: In-class office hours (tentative) 26 | 27 | ## :fas fa-calendar fa-pull-left: Week 5 (Jun 6 - 12) 28 | **[How to plan, conduct, and summarize usability tests?](https://canvas.sfu.ca/courses/44038/modules/items/1096974)** 29 | :fas fa-desktop fa-fw: [Usability Testing](https://docs.google.com/presentation/d/e/2PACX-1vRnnRFelgw1ksq_p8Eryg3dnyLCRRLPf5fBgdwdv9p-tCIwcxqWvzDGrGbjxGHL7HqEJVpmV26ntk3a/pub?start=false&loop=false&delayms=3000) 30 | :fas fa-book fa-fw: [The Art of Guerrilla Usability Testing](http://www.uxbooth.com/articles/the-art-of-guerrilla-usability-testing/) 31 | :fas fa-users fa-fw: In-class office hours (tentative) 32 | -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/docsify-img-grid.js: -------------------------------------------------------------------------------- 1 | // Original source plugin 'img-grid' by @gllmAR 2 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 3 | (function () { 4 | const DEFAULT_CONFIG = { 5 | columns: 3, 6 | minItems: 3, 7 | minWidth: 200 8 | }; 9 | 10 | const config = Object.assign({}, DEFAULT_CONFIG, (window.$docsify && window.$docsify.imgGrid) || {}); 11 | 12 | function createImageGrid(images, columns = config.columns, minWidth = config.minWidth) { 13 | const gridContainer = document.createElement('div'); 14 | gridContainer.className = 'img-grid'; 15 | gridContainer.style.cssText = ` 16 | display: flex; 17 | flex-wrap: wrap; 18 | gap: 10px; 19 | justify-content: center; 20 | margin: 1rem 0; 21 | `; 22 | 23 | images.forEach(img => { 24 | const wrapper = document.createElement('div'); 25 | wrapper.className = 'img-grid-item'; 26 | wrapper.style.cssText = ` 27 | flex: 0 1 calc(${100 / columns}% - 10px); 28 | min-width: ${minWidth}px; 29 | `; 30 | 31 | const parentAnchor = img.closest('a'); 32 | if (parentAnchor) { 33 | const anchorClone = parentAnchor.cloneNode(false); 34 | const imgClone = img.cloneNode(true); 35 | imgClone.style.cssText = ` 36 | width: 100%; 37 | height: 100%; 38 | object-fit: contain; 39 | `; 40 | anchorClone.appendChild(imgClone); 41 | wrapper.appendChild(anchorClone); 42 | } else { 43 | const clone = img.cloneNode(true); 44 | clone.style.cssText = ` 45 | width: 100%; 46 | height: 100%; 47 | object-fit: contain; 48 | `; 49 | wrapper.appendChild(clone); 50 | } 51 | 52 | gridContainer.appendChild(wrapper); 53 | }); 54 | 55 | return gridContainer; 56 | } 57 | 58 | function processImageLists(content) { 59 | const container = document.createElement('div'); 60 | container.innerHTML = content; 61 | 62 | const lists = container.getElementsByTagName('ul'); 63 | Array.from(lists).forEach(list => { 64 | const images = Array.from(list.getElementsByTagName('img')); 65 | 66 | if (images.length >= config.minItems && images.length === list.children.length) { 67 | const columns = list.getAttribute('data-columns') || config.columns; 68 | const minWidth = config.minWidth; 69 | const grid = createImageGrid(images, parseInt(columns), minWidth); 70 | list.parentNode.replaceChild(grid, list); 71 | } 72 | }); 73 | 74 | return container.innerHTML; 75 | } 76 | 77 | window.$docsify = window.$docsify || {}; 78 | window.$docsify.plugins = (window.$docsify.plugins || []).concat(hook => { 79 | hook.afterEach((html, next) => { 80 | next(processImageLists(html)); 81 | }); 82 | }); 83 | })(); 84 | -------------------------------------------------------------------------------- /docs/assets/css/print.css: -------------------------------------------------------------------------------- 1 | /* CSS generated/assisted by Anthropic Claude AI */ 2 | @media print { 3 | :root { 4 | --print-body-size: 10pt; 5 | --print-h1-size: 14pt; 6 | --print-h2-size: 12pt; 7 | --print-h3-size: 11pt; 8 | --print-h4-h6-size: 10pt; 9 | --print-code-size: 9pt; 10 | --print-url-size: 8pt; 11 | } 12 | 13 | /* Reset minimum heights to prevent phantom spacing */ 14 | * { 15 | min-height: 0 !important; 16 | } 17 | 18 | /* Hide UI elements */ 19 | .button-secondary, 20 | .button-rounded, 21 | .button-secondary-rounded, 22 | .edit-link, 23 | .cover, 24 | .skip-link, 25 | .app-nav, 26 | #__sidebar, 27 | aside, 28 | .button, 29 | .github-corner, 30 | .docsify-pagination-container, 31 | .emoji { 32 | display: none !important; 33 | } 34 | 35 | /* Reset layout for print */ 36 | body, 37 | main, 38 | .content, 39 | .app, 40 | .markdown-section { 41 | margin: 0 !important; 42 | padding: 0 !important; 43 | width: 100% !important; 44 | max-width: none !important; 45 | transform: none !important; 46 | position: static !important; 47 | } 48 | 49 | body { 50 | font-size: var(--print-body-size); 51 | line-height: 1.4; 52 | } 53 | 54 | * { 55 | background: transparent !important; 56 | color: #000 !important; 57 | box-shadow: none !important; 58 | } 59 | 60 | @page { 61 | margin: 2cm; 62 | } 63 | 64 | /* Typography */ 65 | .markdown-section h1 { 66 | font-size: var(--print-h1-size) !important; 67 | page-break-after: avoid; 68 | margin-top: 1.5em; 69 | } 70 | 71 | .markdown-section h2 { 72 | font-size: var(--print-h2-size) !important; 73 | page-break-after: avoid; 74 | margin-top: 1.2em; 75 | } 76 | 77 | .markdown-section h3 { 78 | font-size: var(--print-h3-size) !important; 79 | page-break-after: avoid; 80 | margin-top: 1em; 81 | } 82 | 83 | .markdown-section h4, 84 | .markdown-section h5, 85 | .markdown-section h6 { 86 | font-size: var(--print-h4-h6-size) !important; 87 | page-break-after: avoid; 88 | margin-top: 0.8em; 89 | } 90 | 91 | .markdown-section p, 92 | .markdown-section li, 93 | .markdown-section td, 94 | .markdown-section th { 95 | font-size: var(--print-body-size) !important; 96 | } 97 | 98 | code, 99 | pre { 100 | font-family: monospace; 101 | font-size: var(--print-code-size) !important; 102 | white-space: pre-wrap; 103 | word-wrap: break-word; 104 | } 105 | 106 | /* Page flow */ 107 | p, 108 | li { 109 | orphans: 3; 110 | widows: 3; 111 | } 112 | 113 | /* Make columns print-friendly */ 114 | .row { 115 | display: flex !important; 116 | page-break-inside: avoid !important; 117 | } 118 | 119 | .column { 120 | flex: 1 !important; 121 | page-break-inside: avoid !important; 122 | break-inside: avoid !important; 123 | } 124 | 125 | img { 126 | max-width: 100% !important; 127 | page-break-inside: avoid; 128 | } 129 | 130 | blockquote, 131 | pre, 132 | table { 133 | page-break-inside: avoid; 134 | } 135 | 136 | /* Tables */ 137 | table { 138 | border-collapse: collapse; 139 | width: 100%; 140 | font-size: 0.9em; 141 | } 142 | 143 | th, 144 | td { 145 | border: 1pt solid #ccc; 146 | padding: 4pt; 147 | text-align: left; 148 | vertical-align: top; 149 | } 150 | 151 | /* Links */ 152 | a { 153 | color: #000 !important; 154 | text-decoration: underline; 155 | } 156 | 157 | /* External URLs */ 158 | a[href^="http"]:after { 159 | content: " (" attr(href) ")"; 160 | font-size: var(--print-url-size); 161 | font-style: italic; 162 | } 163 | 164 | .no-print { 165 | display: none !important; 166 | } 167 | } -------------------------------------------------------------------------------- /docs/resources.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | ## Reflective Writing 4 | * [A short guide to reflective writing](https://intranet.birmingham.ac.uk/as/libraryservices/library/skills/asc/documents/public/Short-Guide-Reflective-Writing.pdf) 5 | * [How Reflecting On Your Work Can Make You A Better Designer](https://medium.com/center-centre-cohort-01/how-reflecting-on-your-work-can-make-you-a-better-designer-5ce2f3886f51) 6 | * [Online Guide to Reflective Writing](https://nile.northampton.ac.uk/bbcswebdav/pid-1244383-dt-content-rid-3278540_1/courses/Centre-for-Achievement-and-Performance/Skills/Reflective%20Writing/Reflective%20Writing%20-%20Feb%202017.pdf) 7 | * [Reflective Toolbox](http://writeonline.ca/media/documents/ReflectiveToolbox.pdf) 8 | * [Reflective writing: a basic introduction](http://www.port.ac.uk/media/contacts-and-departments/student-support-services/ask/downloads/Reflective-writing---a-basic-introduction.pdf) 9 | 10 | ## UX Platform Guideline Collections 11 | * [Android User Interface Design Guidelines](https://developer.android.com/guide/practices/ui_guidelines/index.html) 12 | * [Google Material Design Guidelines](https://material.google.com/) 13 | * [iOS Human Interface Design Guidelines (iPhone and iPad)](https://developer.apple.com/ios/human-interface-guidelines/) 14 | * [KDE Human Interface Design Guidelines](https://community.kde.org/KDE_Visual_Design_Group/HIG) 15 | * [OS X Human Interface Design Guidelines](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html#//apple_ref/doc/uid/TP40002720-TPXREF101) 16 | * [Windows App Design Guidelines (Touch)](https://msdn.microsoft.com/en-us/library/dn742468.aspx) 17 | 18 | ## UX Templates 19 | * [Contextual Interview Form](http://userfocus.co.uk/pdf/cisheet.pdf) 20 | * [One Page User Research Plan](https://www.smashingmagazine.com/2012/01/ux-research-plan-stakeholders-love/) 21 | * [Templates & Downloadable Documents | Usability.gov](http://www.usability.gov/how-to-and-tools/resources/templates.html) 22 | * [cxpartners | Resources](http://www.cxpartners.co.uk/ux-resources/) 23 | * [The PM Toolkit](http://thepmtoolkit.com/) 24 | * [UX Project Checklist](http://uxchecklist.github.io/) 25 | 26 | ## UX Design Checklists 27 | * [A Checklist for Designing Mobile Input Fields](http://www.nngroup.com/articles/mobile-input-checklist/) 28 | * [Mobile UX Checklist (PDF, by Mobify)](http://downloads.mobify.com.s3.amazonaws.com/ebooks/25-Ways-to-Make-Your-Mobile-E-Commerce-Revenue-Skyrocket-Mobify.pdf) 29 | * [One-Page Touch Interaction Design Checklist (PDF)](https://canvas.sfu.ca/courses/38847/files/folder/Handouts/Touch%20Interaction%20Checklist) 30 | * [Usability checklist (Userium)](https://userium.com/) 31 | * [UX Project Checklist](http://uxchecklist.github.io/) 32 | 33 | ## UX Technique Collections 34 | * [Methods | Usability.gov](http://www.usability.gov/how-to-and-tools/methods/) 35 | * [Methods | Usability Body of Knowledge](http://www.usabilitybok.org/methods) 36 | * [Usability Planner](http://usabilityplanner.org/#home) 37 | * [UX Techniques (by UX Mastery)](http://uxmastery.com/resources/techniques) 38 | 39 | ## UX Article Collections 40 | * [The UX Bookmark](http://www.theuxbookmark.com/) 41 | * [User Experience Magazine (UXPA)](http://uxpamagazine.org/) 42 | * [UI/UX Articles (Medium)](https://medium.com/ui-ux-articles) 43 | 44 | ## UX eBooks 45 | * [50 UX Best Practices by Above the Fold (email address required)](http://www.userexperiencedesigns.com/) 46 | * [Bright Ideas for User Experience Designers](http://www.userfocus.co.uk/ebooks/uxdesign.html) 47 | * [The Fable of the User-Centered Designer](http://www.userfocus.co.uk/fable/) 48 | 49 | ## UX Design MOOCs & Courses 50 | * [Human-Computer Interaction | Coursera](https://www.coursera.org/course/hciucsd) 51 | * [The Design of Everyday Things | Udacity](https://www.udacity.com/course/design101) 52 | * [Rapid Wireframing: Finding the Right Product Design](https://www.skillshare.com/classes/design/Rapid-Wireframing-Finding-the-Right-Product-Design/1947996659) 53 | 54 | ## UX Podcast Collections 55 | * [Design Critique: Products for People](http://designcritique.net/) 56 | * [Podcasts - UIE Brain Sparks](http://www.uie.com/brainsparks/topics/podcasts/) 57 | * [Boagworld Podcast](https://boagworld.com/show/) 58 | * [User Experience Podcast](http://www.infodesign.com.au/uxpod) 59 | 60 | ## UX Video Collections 61 | * [Google Developers Channel](https://www.youtube.com/user/GoogleDevelopers/search?query=user+experience+usability) 62 | * [Interaction Design Association Vimeo Channels](http://vimeo.com/ixdaglobal/channels) 63 | * [NNgroup YouTube Channel](https://www.youtube.com/user/NNgroup/videos) 64 | * [UX Mastery YouTube Channel](https://www.youtube.com/channel/UCXmQyv8sAjmvgCCgvRKi9hw) 65 | -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/toc.js: -------------------------------------------------------------------------------- 1 | var defaultOptions = { 2 | headings: 'h1, h2', 3 | scope: '.markdown-section', 4 | 5 | // To make work 6 | title: 'Contents', 7 | listType: 'ul', 8 | } 9 | 10 | // Element builders 11 | var tocHeading = function(Title) { 12 | return document.createElement('h2').appendChild( 13 | document.createTextNode(Title) 14 | ) 15 | } 16 | 17 | var aTag = function(src) { 18 | var a = document.createElement('a'); 19 | var content = src.firstChild.innerHTML; 20 | 21 | // Use this to clip text w/ HTML in it. 22 | // https://github.com/arendjr/text-clipper 23 | a.innerHTML = content; 24 | a.href = src.firstChild.href; 25 | a.onclick = tocClick 26 | 27 | // In order to remove this gotta fix the styles. 28 | a.setAttribute('class', 'anchor'); 29 | 30 | return a 31 | }; 32 | 33 | var tocClick = function(e) { 34 | var divs = document.querySelectorAll('.page_toc .active'); 35 | 36 | // Remove the previous classes 37 | [].forEach.call(divs, function(div) { 38 | div.setAttribute('class', 'anchor') 39 | }); 40 | 41 | // Make sure this is attached to the parent not itself 42 | e.currentTarget.setAttribute('class', 'active') 43 | }; 44 | 45 | var createList = function(wrapper, count) { 46 | while (count--) { 47 | if(wrapper){ 48 | wrapper = wrapper.appendChild( 49 | document.createElement('ul') 50 | ); 51 | } 52 | if (count) { 53 | wrapper = wrapper.appendChild( 54 | document.createElement('li') 55 | ); 56 | } 57 | } 58 | 59 | return wrapper; 60 | }; 61 | 62 | //------------------------------------------------------------------------ 63 | 64 | var getHeaders = function(selector) { 65 | var headings2 = document.querySelectorAll(selector); 66 | var ret = []; 67 | 68 | [].forEach.call(headings2, function(heading) { 69 | ret = ret.concat(heading); 70 | }); 71 | 72 | return ret; 73 | }; 74 | 75 | var getLevel = function(header) { 76 | var decs = header.match(/\d/g); 77 | 78 | return decs ? Math.min.apply(null, decs) : 1; 79 | }; 80 | 81 | var jumpBack = function(currentWrapper, offset) { 82 | while (offset--) { 83 | currentWrapper = currentWrapper.parentElement; 84 | } 85 | 86 | return currentWrapper; 87 | }; 88 | 89 | var buildTOC = function(options) { 90 | var ret = document.createElement('ul'); 91 | var wrapper = ret; 92 | var lastLi = null; 93 | var selector = options.scope + ' ' + options.headings 94 | var headers = getHeaders(selector).filter(h => h.id); 95 | 96 | headers.reduce(function(prev, curr, index) { 97 | var currentLevel = getLevel(curr.tagName); 98 | var offset = currentLevel - prev; 99 | 100 | wrapper = (offset > 0) 101 | ? createList(lastLi, offset) 102 | : jumpBack(wrapper, -offset * 2) 103 | 104 | wrapper = wrapper || ret; 105 | 106 | var li = document.createElement('li'); 107 | 108 | wrapper.appendChild(li).appendChild(aTag(curr)); 109 | 110 | lastLi = li; 111 | 112 | return currentLevel; 113 | }, getLevel(options.headings)); 114 | 115 | return ret; 116 | }; 117 | 118 | // Docsify plugin functions 119 | function plugin(hook, vm) { 120 | var userOptions = vm.config.toc; 121 | 122 | hook.mounted(function () { 123 | var content = window.Docsify.dom.find(".content"); 124 | if (content) { 125 | var nav = window.Docsify.dom.create("aside", ""); 126 | window.Docsify.dom.toggleClass(nav, "add", "nav"); 127 | window.Docsify.dom.before(content, nav); 128 | } 129 | }); 130 | 131 | hook.doneEach(function () { 132 | var nav = document.querySelectorAll('.nav')[0] 133 | var t = Array.from(document.querySelectorAll('.nav')) 134 | 135 | if (!nav) { 136 | return; 137 | } 138 | 139 | const toc = buildTOC(userOptions); 140 | 141 | // Just unset it for now. 142 | if (!toc.innerHTML) { 143 | nav.innerHTML = null 144 | return; 145 | } 146 | 147 | // Fix me in the future 148 | var title = document.createElement('p'); 149 | title.innerHTML = userOptions.title; 150 | title.setAttribute('class', 'title'); 151 | 152 | var container = document.createElement('div'); 153 | container.setAttribute('class', 'page_toc'); 154 | 155 | container.appendChild(title); 156 | container.appendChild(toc); 157 | 158 | // Existing TOC 159 | var tocChild = document.querySelectorAll('.nav .page_toc'); 160 | 161 | if (tocChild.length > 0) { 162 | tocChild[0].parentNode.removeChild(tocChild[0]); 163 | } 164 | 165 | nav.appendChild(container); 166 | }); 167 | } 168 | 169 | // Docsify plugin options 170 | window.$docsify['toc'] = Object.assign(defaultOptions, window.$docsify['toc']); 171 | window.$docsify.plugins = [].concat(plugin, window.$docsify.plugins); 172 | -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/docsify-fontawesome.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 3 | * This devtool is neither made for production nor for readable output files. 4 | * It uses "eval()" calls to create a separate source file in the browser devtools. 5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 6 | * or disable the default devtool with "devtool: false". 7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 8 | */ 9 | /******/ (() => { // webpackBootstrap 10 | /******/ "use strict"; 11 | /******/ var __webpack_modules__ = ({ 12 | 13 | /***/ "./src/index.js": 14 | /*!**********************!*\ 15 | !*** ./src/index.js ***! 16 | \**********************/ 17 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 18 | 19 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _plugin_fontawesome__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./plugin-fontawesome */ \"./src/plugin-fontawesome.js\");\n\n\n// if (!window.$docsify) {\n// window.$docsify = {}\n// }\nwindow.$docsify = window.$docsify || {};\nwindow.$docsify.plugins = (window.$docsify.plugins || []).concat(_plugin_fontawesome__WEBPACK_IMPORTED_MODULE_0__.install);\n\n\n//# sourceURL=webpack://docsify-fontawesome/./src/index.js?"); 20 | 21 | /***/ }), 22 | 23 | /***/ "./src/plugin-fontawesome.js": 24 | /*!***********************************!*\ 25 | !*** ./src/plugin-fontawesome.js ***! 26 | \***********************************/ 27 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 28 | 29 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"install\": () => (/* binding */ install)\n/* harmony export */ });\nfunction install(hook) {\n const faRegExp = /:fa[\\w -]+:/gm;\n\n hook.beforeEach(content => {\n let faHtmlRendered = content.replace(faRegExp, function (m, code) {\n console.log('m: ' + m.replace(/:/gi, ''));\n let rendered = ``;\n return rendered;\n });\n return faHtmlRendered;\n });\n hook.afterEach(function (html, next) {\n let faHtmlRendered = html.replace(faRegExp, function (m, code) {\n console.log('m: ' + m.replace(/:/gi, ''));\n let rendered = ``;\n return rendered;\n });\n //console.log('faHtmlRendered: '+faHtmlRendered);\n next(faHtmlRendered);\n });\n}\n\n\n//# sourceURL=webpack://docsify-fontawesome/./src/plugin-fontawesome.js?"); 30 | 31 | /***/ }) 32 | 33 | /******/ }); 34 | /************************************************************************/ 35 | /******/ // The module cache 36 | /******/ var __webpack_module_cache__ = {}; 37 | /******/ 38 | /******/ // The require function 39 | /******/ function __webpack_require__(moduleId) { 40 | /******/ // Check if module is in cache 41 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 42 | /******/ if (cachedModule !== undefined) { 43 | /******/ return cachedModule.exports; 44 | /******/ } 45 | /******/ // Create a new module (and put it into the cache) 46 | /******/ var module = __webpack_module_cache__[moduleId] = { 47 | /******/ // no module.id needed 48 | /******/ // no module.loaded needed 49 | /******/ exports: {} 50 | /******/ }; 51 | /******/ 52 | /******/ // Execute the module function 53 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 54 | /******/ 55 | /******/ // Return the exports of the module 56 | /******/ return module.exports; 57 | /******/ } 58 | /******/ 59 | /************************************************************************/ 60 | /******/ /* webpack/runtime/define property getters */ 61 | /******/ (() => { 62 | /******/ // define getter functions for harmony exports 63 | /******/ __webpack_require__.d = (exports, definition) => { 64 | /******/ for(var key in definition) { 65 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 66 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 67 | /******/ } 68 | /******/ } 69 | /******/ }; 70 | /******/ })(); 71 | /******/ 72 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 73 | /******/ (() => { 74 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 75 | /******/ })(); 76 | /******/ 77 | /******/ /* webpack/runtime/make namespace object */ 78 | /******/ (() => { 79 | /******/ // define __esModule on exports 80 | /******/ __webpack_require__.r = (exports) => { 81 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 82 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 83 | /******/ } 84 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 85 | /******/ }; 86 | /******/ })(); 87 | /******/ 88 | /************************************************************************/ 89 | /******/ 90 | /******/ // startup 91 | /******/ // Load entry module and return exports 92 | /******/ // This entry module can't be inlined because the eval devtool is used. 93 | /******/ var __webpack_exports__ = __webpack_require__("./src/index.js"); 94 | /******/ 95 | /******/ })() 96 | ; -------------------------------------------------------------------------------- /docs/assets/css/custom.css: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================================================================== 3 | Put your custom CSS in this file. 4 | =============================================================================================================================== 5 | */ 6 | 7 | /* CSS to better visually match Docsify pages within Canvas LMS (uncomment to use) */ 8 | /* 9 | @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap'); 10 | 11 | body .markdown-section { 12 | font-family: "Lato Extended","Lato","Helvetica Neue",Arial,sans-serif; 13 | line-height: 1.4; 14 | font-size: 16px; 15 | } 16 | */ 17 | 18 | /* Link colors to match SFU branding visual styling (uncomment to use) */ 19 | /* 20 | :root { 21 | --link-color: #CC0633!important; 22 | --link-text-decoration: none!important; 23 | --link-text-decoration--hover: underline!important; 24 | 25 | --sidebar-name-color: #CC0633!important; 26 | --sidebar-nav-link-color: #757575!important; 27 | --sidebar-nav-link-color--active: #CC0633!important; 28 | --sidebar-nav-link-border-color--active: #CC0633!important; 29 | 30 | --sidebar-nav-pagelink-background--active: 31 | no-repeat 0px center / 5px 6px 32 | linear-gradient(225deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px), 33 | no-repeat 5px center / 5px 6px 34 | linear-gradient(135deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px)!important; 35 | --sidebar-nav-pagelink-background--collapse: 36 | no-repeat 2px calc(50% - 2.5px) / 6px 5px 37 | linear-gradient(45deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4px), 38 | no-repeat 2px calc(50% + 2.5px) / 6px 5px 39 | linear-gradient(135deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4px)!important; 40 | --sidebar-nav-pagelink-background--loaded: 41 | no-repeat 0px center / 5px 6px 42 | linear-gradient(225deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px), 43 | no-repeat 5px center / 5px 6px 44 | linear-gradient(135deg, transparent 2.75px, #CC0633 2.75px 4.25px, transparent 4.25px)!important; 45 | 46 | --navbar-root-color: #757575!important; 47 | --navbar-root-color--active: #CC0633!important; 48 | 49 | --blockquote-border-color: #757b7f!important; 50 | 51 | --pagination-title-color: #CC0633!important; 52 | } 53 | */ 54 | 55 | /* Dark mode colours to match SFU branding visual styling for use with light + dark theme (uncomment to use) */ 56 | /* 57 | @media (prefers-color-scheme: dark) { 58 | :root { 59 | 60 | --link-color: #EA7688!important; 61 | --link-text-decoration: none!important; 62 | --link-text-decoration--hover: underline!important; 63 | 64 | --sidebar-name-color: #EA7688!important; 65 | --sidebar-nav-link-color: #B2B4B4!important; 66 | --sidebar-nav-link-color--active: #EA7688!important; 67 | --sidebar-nav-link-border-color--active: #EA7688!important; 68 | 69 | --sidebar-nav-pagelink-background--active: 70 | no-repeat 0px center / 5px 6px linear-gradient(225deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px), no-repeat 5px center / 5px 6px linear-gradient(135deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px)!important; 71 | --sidebar-nav-pagelink-background--collapse: 72 | no-repeat 2px calc(50% - 2.5px) / 6px 5px linear-gradient(45deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4px), no-repeat 2px calc(50% + 2.5px) / 6px 5px linear-gradient(135deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4px)!important; 73 | --sidebar-nav-pagelink-background--loaded: 74 | no-repeat 0px center / 5px 6px linear-gradient(225deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px), no-repeat 5px center / 5px 6px linear-gradient(135deg, transparent 2.75px, #EA7688 2.75px 4.25px, transparent 4.25px)!important; 75 | 76 | --navbar-root-color: #B2B4B4!important; 77 | --navbar-root-color--active: #EA7688!important; 78 | 79 | --blockquote-border-color: #757B7F!important; 80 | 81 | --pagination-title-color: #EA7688!important; 82 | } 83 | } 84 | */ 85 | 86 | /* CSS to better visually match Docsify pages within Moodle LMS (uncomment to use) */ 87 | /* 88 | body .markdown-section { 89 | font-family: system-ui,sans-serif; 90 | line-height: 1.5; 91 | font-size: 15px; 92 | } 93 | */ 94 | 95 | /* Link colors to match visual styling of Moodle LMS (uncomment to use) */ 96 | /* 97 | :root { 98 | --link-color: #0F6CBF!important; 99 | --link-color--hover: #03005D!important; 100 | --link-text-decoration: none!important; 101 | --link-text-decoration--hover: underline!important; 102 | 103 | --sidebar-name-color: #0F6CBF!important; 104 | --sidebar-nav-link-color--active: #0F6CBF!important; 105 | --sidebar-nav-link-border-color--active: #0F6CBF!important; 106 | 107 | --sidebar-nav-pagelink-background--active: 108 | no-repeat 0px center / 5px 6px 109 | linear-gradient(225deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px), 110 | no-repeat 5px center / 5px 6px 111 | linear-gradient(135deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px)!important; 112 | --sidebar-nav-pagelink-background--collapse: 113 | no-repeat 2px calc(50% - 2.5px) / 6px 5px 114 | linear-gradient(45deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4px), 115 | no-repeat 2px calc(50% + 2.5px) / 6px 5px 116 | linear-gradient(135deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4px)!important; 117 | --sidebar-nav-pagelink-background--loaded: 118 | no-repeat 0px center / 5px 6px 119 | linear-gradient(225deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px), 120 | no-repeat 5px center / 5px 6px 121 | linear-gradient(135deg, transparent 2.75px, #0F6CBF 2.75px 4.25px, transparent 4.25px)!important; 122 | --navbar-root-color--active: #0F6CBF!important; 123 | 124 | --blockquote-border-color: #0F6CBF!important; 125 | 126 | --pagination-title-color: #0F6CBF!important; 127 | } 128 | */ 129 | 130 | /* CSS to better visually match Docsify pages within Sakai LMS (uncomment to use) */ 131 | /* 132 | @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&display=swap'); 133 | 134 | body .markdown-section { 135 | font-family: "Open Sans",sans-serif; 136 | line-height: 1.3; 137 | font-size: 14px; 138 | } 139 | */ 140 | 141 | /* Link colors to match visual styling of Sakai LMS (uncomment to use) */ 142 | /* 143 | :root { 144 | --link-color: #0B1660!important; 145 | 146 | --sidebar-name-color: #0B1660!important; 147 | --sidebar-nav-link-color--active: #0B1660!important; 148 | --sidebar-nav-link-border-color--active: #0B1660!important; 149 | 150 | --sidebar-nav-pagelink-background--active: 151 | no-repeat 0px center / 5px 6px 152 | linear-gradient(225deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px), 153 | no-repeat 5px center / 5px 6px 154 | linear-gradient(135deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px)!important; 155 | --sidebar-nav-pagelink-background--collapse: 156 | no-repeat 2px calc(50% - 2.5px) / 6px 5px 157 | linear-gradient(45deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4px), 158 | no-repeat 2px calc(50% + 2.5px) / 6px 5px 159 | linear-gradient(135deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4px)!important; 160 | --sidebar-nav-pagelink-background--loaded: 161 | no-repeat 0px center / 5px 6px 162 | linear-gradient(225deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px), 163 | no-repeat 5px center / 5px 6px 164 | linear-gradient(135deg, transparent 2.75px, #0B1660 2.75px 4.25px, transparent 4.25px)!important; 165 | 166 | --navbar-root-color--active: #0B1660!important; 167 | --navbar-root-color--active: #0B1660!important; 168 | 169 | --blockquote-border-color: #0B1660!important; 170 | 171 | --pagination-title-color: #0B1660!important; 172 | } 173 | */ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v1.3.6](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.6) 4 | ### XX/XX/2025 5 | 6 | **Improved:** 7 | * Hide empty rows in responsive tables 8 | * Left align rows in responsive tables 9 | * Version-lock Font Awesome CSS assets 10 | 11 | ## [v1.3.5](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.5) 12 | ### 11/26/2025 13 | 14 | **New:** 15 | * Added sidebar banner image support via HTML image 16 | * Automatic image path resolution for HTML image assets using data-src attribute relative to site base path with fallback support 17 | * Added (long overdue) basic support for printing 18 | 19 | **Improved:** 20 | * Improved support for Docsify configuration settings of 'topMargin' 21 | 22 | **Bugfix:** 23 | * Restored missing content-max-width default 24 | 25 | ## [v1.3.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.4) 26 | ### 08/01/2025 27 | 28 | **New:** 29 | * Added CSS Markdown classes to support cards (`card` & `card-rounded`) and responsive card lists (`card-list`) 30 | * Added CSS Markdown classes to support header overlays on full-width images (`header-image-full-width-headings-overlay` and `header-tall-image-full-width-headings-overlay`) 31 | * Added support for topic index using standard links in first paragraph 32 | 33 | **Improved:** 34 | * Updated ReadMe 35 | * Improve visual design of h1 and h2 below top full width image (use HTML tags to keep default styling) 36 | 37 | **Bugfix:** 38 | * Minor CSS fixes 39 | 40 | ## [v1.3.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.3) 41 | ### 07/02/2025 42 | 43 | **Improved:** 44 | * Updated to use latest docsify-footnotes plugin (v2.2.1) 45 | 46 | ## [v1.3.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.2) 47 | ### 04/09/2025 48 | 49 | **Bugfix:** 50 | * Set margin instead of padding for images contained in columns 51 | 52 | ## [v1.3.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.1) 53 | ### 03/04/2025 54 | 55 | **Improved:** 56 | * Various minor enhancements to Search plugin 57 | * Adjusted default behaviour of image grid to add needed whitespace (padding) instead of cropping when source images are of different sizes (thanks to a helpful discussion with @davidmalawey) 58 | 59 | **Bugfix:** 60 | * Fixed incorrect theme CSS with regards to image scaling (with thanks and appreciation to @harlows for the PR) 61 | 62 | ## [v1.3.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.3.0) 63 | ### 02/04/2025 64 | 65 | **New:** 66 | * Support for image grid plugin, including customizations (with thanks and appreciation to @gllmAR) 67 | * Include zoom image plugin (not enabled by default) 68 | * Use of Docsify and Docsify Themeable preview build assets for access to upcoming Docsify accessibility enhancements authored by @jhildenbiddle (with thanks and appreciation to John and tested extensively in Docsify-This) 69 | 70 | **Improved:** 71 | * Updated ReadMe 72 | * Updated example custom CSS for Moodle LMS 73 | * Updated to latest stable Docsify 4.x preview build (including Marked 4.2.12) 74 | * Support horizontal scrolling in code blocks 75 | * Adjusted bottom margin for summary elements 76 | * Match Docsify-This CSS with Docsify Starter Kits CSS 77 | * Browser-level image lazy loading via plugin 'docsify-loading' no longer enabled by default to match updated Docsify-This behaviour 78 | * Default search plugin settings adjusted to match Docsify-This 79 | 80 | ## [v1.2.20](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.20) 81 | ### 12/03/2024 82 | 83 | **New:** 84 | * Added default setting of false for `mergeNavbar` to move Navbar items to the top of the Sidebar on smaller screens 85 | 86 | **Improved:** 87 | * Updated CSS with word-wrap for code blocks 88 | * Use of window.matchMedia.addListener replaced with window.matchMedia.addEventListener 89 | * Cleanup HTML 90 | * Update uses of Font Awesome 91 | * Match Docsify-This CSS with Docsify Starter Kits CSS 92 | 93 | **Bugfix:** 94 | * Scroll offset fix (with thanks and appreciation to @rizdaprasetya for the initial code) 95 | * Added missing Prism language files 96 | * Fix formatting conflict with Prism formatted code blocks 97 | 98 | ## [v1.2.19](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.19) 99 | ### 10/09/2024 100 | 101 | **Improved:** 102 | * Minor theme update 103 | 104 | ## [v1.2.18](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.18) 105 | ### 09/03/2024 106 | 107 | **Improved:** 108 | * Updated ReadMe 109 | 110 | ## [v1.2.17](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.17) 111 | ### 07/23/2024 112 | 113 | **Improved:** 114 | * Improve accessibility of Font Awesome icons when used for decorative elements (automatic addition of `aria-hidden` attribute assuming decorative icons) 115 | 116 | **Bugfix:** 117 | * Added indentation for LMS Links items in Docsify Sidebar 118 | 119 | ## [v1.2.16](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.16) 120 | ### 06/24/2024🏒 121 | 122 | **Improved:** 123 | * Adjusted bottom margin for summary elements 124 | * Improved Search plugin results list presentation, including source page title when appropriate 125 | 126 | **Bugfix:** 127 | * Check the global variable 'standalone' when setting externalLinkTarget 128 | 129 | ## [v1.2.15](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.15) 130 | ### 06/03/2024 131 | 132 | **Improved:** 133 | * Added CSS Markdown class to support responsive HTML images `responsive` 134 | 135 | **Bugfix:** 136 | * Added CSS to automatically wrap links that overflow 137 | * Added CSS to automatically wrap code blocks that overflow 138 | * Added CSS to better vertically align 'Edit this Page' emoji and text 139 | 140 | ## [v1.2.14](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.14) 141 | ### 04/29/2024 142 | 143 | **Bugfix:** 144 | * Remove CSS for use with accordion elements with plain details/summary elements 145 | 146 | ## [v1.2.13](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.13) 147 | ### 03/04/2024 148 | 149 | **New:** 150 | * Support for the Browser-level image lazy loading (with thanks and appreciation to @sy-records for the source plugin 'docsify-loading') 151 | 152 | **Improved:** 153 | * Add ability to define custom colors for badges (with thanks to @cmadland for the example use of colored badges) 154 | * Updated ReadMe 155 | * Updated Editor.css file for improved Markdown previews 156 | * Use docsify-loading plugin rather than added Javascript 157 | * Reorganize and update custom assets (as used in Docsify-This) 158 | 159 | **Bugfix:** 160 | * Include missing docsify-footnotes plugin 161 | 162 | ## [v1.2.12](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.12) 163 | ### 02/09/2024 164 | 165 | **New:** 166 | * Added CSS Markdown class for right-aligned columns `column-right` 167 | * Added CSS Markdown class for full width background gradient header image (`header-image-fade-full-width`) 168 | 169 | **Improved:** 170 | * ReadMe updated 171 | 172 | ## [v1.2.11](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.11) 173 | ### 01/18/2024 174 | 175 | **New:** 176 | * Added CSS Markdown class `reverse-columns` 177 | * Added CSS Markdown class for taller full width header image `header-tall-image-full-width` 178 | * Added CSS Markdown class for rounded button `button-rounded` 179 | * Added CSS Markdown classes for secondary buttons `button-secondary` and `button-secondary-rounded` 180 | 181 | **Improved:** 182 | * Improved image alignment with two column layouts 183 | * Improved contrast for unselected Tabs 184 | * Improved support of logo image in Docsify Sidebar 185 | * Adjusted display of full width header image 186 | 187 | ## [v1.2.10](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.10) 188 | ### 11/27/2023 189 | 190 | **Improved:** 191 | * Added 'onedrive.live.com' to domains made responsive through the automatic addition of the CSS Markdown class `video-container-16by9` 192 | 193 | ## [v1.2.9](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.9) 194 | ### 11/15/2023 195 | 196 | **Improved:** 197 | * ReadMe updated 198 | 199 | ## [v1.2.8](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.8) 200 | ### 08/31/2023 201 | 202 | **Improved:** 203 | * ReadMe updated 204 | 205 | ## [v1.2.7](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.7) 206 | ### 08/25/2023 207 | 208 | **Improved:** 209 | * Updated example custom CSS for LMSs 210 | * Cleanup default CSS 211 | * Adjusted badge colours for dark theme 212 | * Use light/dark theme display for topic indexes 213 | * Clarify light + dark theme use comments 214 | * ReadMe updated 215 | 216 | ## [v1.2.6](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.6) 217 | ### 08/15/2023 218 | 219 | **New:** 220 | * Support for nav pill (`navpill`) Markdown CSS class 221 | 222 | **Improved:** 223 | * Added 'youtube-nocookie.com' to domains made responsive through the automatic addition of the CSS Markdown class `video-container-16by9` 224 | 225 | **Improved:** 226 | * ReadMe updated 227 | 228 | ## [v1.2.5](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.5) 229 | ### 06/27/2023 230 | 231 | **Improved:** 232 | * Match Docsify-This Markdown file rendering with Docsify Starter Kits CSS (incl. faded header image ToC adjustments and automatic responsive iFrames for YouTube and Google Docs embeds) 233 | 234 | ## [v1.2.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.4) 235 | ### 05/08/2023 236 | 237 | **Improved:** 238 | * Refined responsize header line heights 239 | 240 | ## [v1.2.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.3) 241 | ### 04/09/2023 242 | 243 | **Improved:** 244 | * Set font of buttons to sans-serif 245 | * Set font of badges to sans-serif 246 | * Remove unneeded GitHub image file path adjustments 247 | * Refined responsize header font size and line heights 248 | 249 | ## [v1.2.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.2) 250 | ### 03/13/2023 251 | 252 | **Improved:** 253 | * Restore initial header spacing except for alerts and blockquotes 254 | * Remove extra space between Sidebar icons and labels 255 | * ReadMe updated 256 | 257 | ## [v1.2.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.1) 258 | ### 02/13/2023 259 | 260 | **New:** 261 | * Support for images with border and rounded border (`image-border`,`image-border-rounded`) 262 | * Support for 75%, 50% and 25% scaled images with border (`image-75-border`,`image-50-border` and `image-25-border`) 263 | 264 | **Improved:** 265 | * Consolidate and simplify example custom CSS for LMSs 266 | * Additional support and improvements for optional dark mode 267 | * Match Docsify-This CSS with Docsify Starter Kits CSS 268 | 269 | ## [v1.2.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.2.0) 270 | ### 01/02/2023 271 | 272 | **New:** 273 | * Support for 75%, 50% and 25% scaled images (`image-75`,`image-50` and `image-25`) 274 | * Additional languages for Prismjs (Bash, Go, Java, Kotlin, PHP, Python and Swift in addition to the base set https://docsify.js.org/#/language-highlight?id=language-highlighting) 275 | 276 | **Improved:** 277 | * Adjust page margins when content is being embedded 278 | * Adjust margins and padding for alerts and blockquotes 279 | * Increase clickable areas for Topics alphabetical index 280 | * ReadMe updated 281 | 282 | ## [v1.1.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.4) 283 | ### 01/17/2023 284 | 285 | **New:** 286 | * Support for optionaly showing the navbar when embedded/standalone (now fully supported with v1.1.2 release) 287 | * Support for displaying a footer ('_footer.md' file) via 'footer' setting in index.html or using the URL parameter 'footer=true' 288 | 289 | **Improved:** 290 | * Adjusted opacity of 'header-image-fade' class for improved accessibility 291 | 292 | **Bugfix:** 293 | * Pass 'navbar' URL parameter for page-to-page navigation links 294 | 295 | ## [v1.1.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.3) 296 | ### 12/15/2022 297 | 298 | **New** 299 | * Support for background gradient header image (`header-image-fade`, with thanks to Jamie Adam for original CSS) 300 | * Support for full-width header image (`header-image-full-width`, optional Table of Contents not available) 301 | 302 | **Improved:** 303 | * ReadMe updated 304 | 305 | ## [v1.1.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.2) 306 | ### 11/23/2022 307 | 308 | **Improved:** 309 | * Aligned ToC CSS with Docsify-This.net 310 | * Support for scrolling of Table of Contents 311 | * ReadMe updated 312 | * Removed deprecated emoji plugin (as of Docsify v4.13) 313 | * Support for page-to-page navigation when embedded/standalone 314 | * Changed support for light/dark Themeable theme switching to optional 315 | 316 | ## [v1.1.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.1) 317 | ### 09/02/2022 318 | 319 | **Improved:** 320 | * Reduced page margins when displayed as embedded or standalone 321 | * Adjusted font size and line height for Topics index items 322 | * Added example CSS colours to be the same as Sakai LMS 323 | * Streamlined settings for custom CSS colours 324 | * Simplified 'ToC' setting in index.html 325 | * Reduced left margin of page Table of Contents on smaller screens 326 | * Updated Table of Contents plugin items 327 | * Added Editor.css file for better Markdown previews 328 | * Added new Themeable support for light/dark theme switching (OS-level) 329 | * Adjusted link colours for dark theme 330 | 331 | **Bugfix:** 332 | * Removed unused JS and CSS resources 333 | * Fixed incorrect links in example course content 334 | * Added missing Sidebar name and link colour settings 335 | * Support the removal of the '_sidebar.md' file with standalone setting 336 | * Fixed embedded code blocks overflow issues 337 | 338 | ## [v1.1.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.1.0) 339 | ### 05/30/2022 340 | 341 | **Improved:** 342 | * Aligned default link colour to be the same as Canvas LMS 343 | * Added example link colours to be the same as Moodle LMS 344 | * Adjusted left Markdown section padding 345 | * Adjusted margins for site name in Sidebar 346 | * Added 'standalone' setting in index.html to permanently alter the display of all pages (i.e. hidden Sidebar and Navbar) 347 | 348 | **Bugfix:** 349 | * Fixed 'hidegitlink' URL parameter detection 350 | 351 | ## [v1.0.8](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.8) 352 | ### 03/21/2022 353 | 354 | **Improved:** 355 | * Adjusted link colours for improved contrast 356 | 357 | ## [v1.0.7](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.7) 358 | ### 02/15/2022 359 | 360 | **New:** 361 | * Added conditional display of page table of contents (`?toc=true`) 362 | 363 | **Improved:** 364 | * Restored user zoom ability for improved accessibility 365 | * Revised alt image text for improved accessibility 366 | * Revised JS function `getURLParameterByName` to accept multiple terms (i.e. to support aliases) and also include functionality of previous returnByURLParameterByName function 367 | 368 | **Bugfix:** 369 | * Fixed incorrect H3 headers 370 | 371 | ## [v1.0.6](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.6) 372 | ### 11/15/2021 373 | 374 | **Improved:** 375 | * Adjusted header line heights for improved readability 376 | * Added initial support for responsive font sizing (480px only) 377 | * Improved badge alignment 378 | * Improved text label spacing for buttons 379 | * Removed unneeded embedded check for Pagination Plugin 380 | * Adjusted right margin of navbar to improve alignment 381 | * Removed background colour from accordions to better support a dark theme 382 | 383 | **Bugfix:** 384 | * Added an additional new line before Edit this Page on GitHub links to ensure proper formatting break 385 | 386 | ## [v1.0.5](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.5) 387 | ### 10/15/2021 388 | 389 | **Improved:** 390 | * Relocated images to be within top-level docs folder 391 | 392 | ## [v1.0.4](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.4) 393 | ### 10/05/2021 394 | 395 | **Improved:** 396 | * Added 'Use this Template on GitHub' button on Sidebar 397 | * Changed name of Sidebar page 398 | * Revised Sidebar project links 399 | * Updated example image descriptions 400 | * Adjusted tall banner images for use in multi-course setups 401 | 402 | ## [v1.0.3](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.3) 403 | ### 08/03/2021 404 | 405 | **Improved:** 406 | * Added variable for text of Edit this Page on GitHub links to make modifications easier 407 | * Changed JS function name from `getParameterByName` to `getURLParameterByName` for improved clarity 408 | * Added the new JS function `returnByURLParameterByName` to return one of two values based on URL parameter (e.g. choose external link behaviour based on embedded status) 409 | 410 | ## [v1.0.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.2) 411 | ### 06/16/2021 412 | 413 | **Improved:** 414 | * Adjusted custom list bullet presentation 415 | 416 | ## [v1.0.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.1) 417 | ### 05/30/2021 418 | 419 | **Improved:** 420 | * Changed variable name `yourRepoURL` to `gitLinkRepoURL` for improved clarity 421 | 422 | ## [v1.0.0](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.0) 423 | ### 05/18/2021 424 | 425 | **Improved:** 426 | * ReadMe and screenshot updates 427 | * Changed conditional loading of Pagination script to asynchronous 428 | * Adjusted breakpoint for two column display 429 | * Decreased padding between items in navbar 430 | 431 | **Bugfix:** 432 | * Fixed URL to project ReadMe file 433 | 434 | ## [v1.0.0-preview.2](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.0-preview.2) 435 | ### 05/10/2021 436 | 437 | **Improved:** 438 | * Moved example Canvas LMS visual style adjustments from index.html to custom.css file 439 | * Adjusted CSS of Headers for improved line wrapping 440 | * Adjusted root base line height to increase lines in Sidebar 441 | * Renamed 'responsive-wrap' class to 'responsive-container' for improved consistency 442 | * Changed default external target link to '_top' 443 | * Updated example styling for matching Docsify pages within Canvas LMS 444 | * Increased padding below custom navbar to support more menu items 445 | * Adjusted header sizes and margins 446 | * List and button style updates 447 | * Updated GitHub repo URL config and documentation 448 | * Relocated embedly script to index.html file 449 | 450 | **Bugfix:** 451 | * Fixed label colour for linked badges 452 | * Consistent hover behaviour for linked badges and buttons 453 | 454 | ## [v1.0.0-preview.1](https://github.com/hibbitts-design/docsify-open-course-starter-kit/releases/tag/v1.0.0-preview.1) 455 | ### 05/04/2021 456 | 457 | **New:** 458 | * Welcome to the preview release of Docsify Open Course Starter Kit! 459 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Docsify Open Course Starter Kit 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 96 | 97 | 98 | 99 | 100 |
101 | 437 | 438 | 439 | 440 | 441 | 442 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docsify Open Course Starter Kit 2 | 3 | [![Docsify](https://img.shields.io/npm/v/docsify?label=docsify)](https://docsify.js.org/) 4 | [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/hibbitts-design/docsify-open-course-starter-kit/blob/main/LICENSE) 5 | 6 | 7 | Docsify Discord Chat 8 | 9 | 10 | > This is a starter kit to quickly create a Markdown-based open course site with the site generator [Docsify](https://docsify.js.org). Global navigation elements can be hidden for seamlessly embedding pages (i.e., into an LMS). Includes an optional "Edit this Page" link. 11 | 12 | Docsify sites use client-side rendering, which means your content will not be indexed by search engines like Google, Bing, or DuckDuckGo. 13 | 14 | 📸 Docsify Open Course Screenshots 15 | --- 16 | ![ Docsify Open Course Starter Kit](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/smartmockups_kud8xtd3.png) 17 | _Figure 1. Docsify Open Course Starter Kit. Explore a demo at [hibbitts-design.github.io/demo-docsify-open-course-starter-kit/](https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/)_ 18 | 19 | 🚀 GitHub Pages Quickstart 20 | --- 21 | **Pre-flight Checklist** 22 | 23 | 1. GitHub account 24 | 25 | **Installation and Deployment** 26 | 27 | 1. Sign in to [GitHub](https://github.com) if you have not already done so 28 | 29 | 2. Tap **Use this template** on the source repository (upper-right green button) and then choose **Create a new repository** 30 | ![ Docsify Open Course Starter Kit - Install Page 1](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-install-1.png) 31 | 32 | 3. Choose the name for your new repository to contain the copied site files and then tap **Create repository from template** 33 | ![ Docsify Open Course Starter Kit - Install Page 2](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-install-2.png) 34 | 35 | 4. Go to **Settings** of your newly created repository, tap the **Pages** tab (on the left-hand side), choose **main branch**, then **docs folder** and finally tap the **Save** button (see more details in the [Docsify documentation](https://docsify.js.org/#/deploy?id=github-pages)) 36 | ![ Docsify Open Course Starter Kit - Install Page 3](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-install-3.png) 37 | 38 | 5. And you're done! (view your new site using the provided URL on the **Pages** tab - it can take up to 10 minutes for your site to be initially available) 39 | ![ Docsify Open Course Starter Kit - Install Page 4](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-install-4.png) 40 | 41 | Do you use GitLab? You can also use Docsify with [GitLab Pages](https://docsify.js.org/#/deploy?id=gitlab-pages)! 42 | 43 | ✏️ Editing Your Docsify Site Pages on GitHub 44 | --- 45 | 46 | 1. Go to the Docsify Markdown (.md) page in the `docs` folder of your repository you want to edit 47 | ![ Editing Your Docsify Site Pages 1](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-page-edit-1.png) 48 | 49 | 2. Tap the **Pencil Icon** (top left-hand toolbar area) to start the editor 50 | ![ Editing Your Docsify Site Pages 2](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-page-edit-2.png) 51 | 52 | 3. Scroll down to the bottom of the page and tap the **Commit changes** button to save your changes 53 | ![ Editing Your Docsify Site Pages 3](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-page-edit-3.png) 54 | 55 | [Learn more about creating pages in Docsify.](https://docsify.js.org/#/more-pages) 56 | 57 | 🔗 Activating the “Edit this Page” Link on Your Docsify Site 58 | --- 59 | 60 | 1. At the top-level of your GitHub Repository copy the URL 61 | ![ Docsify Open Course Starter Kit - “Edit this Page” Link 1](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-gitlink-1.png) 62 | 63 | 2. Tap on the **docs** folder 64 | ![ Docsify Open Course Starter Kit - “Edit this Page” Link 2](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-gitlink-2.png) 65 | 66 | 2. Tap on the **index.html** file 67 | ![ Docsify Open Course Starter Kit - “Edit this Page” Link 3](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-gitlink-3.png) 68 | 69 | 3. Tap the **Pencil Icon** (top left-hand toolbar area) to start the editor 70 | ![ Docsify Open Course Starter Kit - “Edit this Page” Link 4](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-gitlink-4.png) 71 | 72 | 4. Find the line `var gitLinkRepoURL = '';` and enter the URL of your own GitHub Repository between the two quotes (replace `github.com` with `github.dev` to use the GitHub.dev web-based editor currently in Beta) and then scroll down to the bottom of the page and tap the **Commit changes** button to save your changes 73 | ![ Docsify Open Course Starter Kit - “Edit this Page” Link 5](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-gitlink-5.png) 74 | 75 | To remove the “Edit this Page” link on your Docsify site, restore the value of `gitLinkRepoURL` to `''`. 76 | 77 | 💻 Locally Editing Your Docsify Site Pages 78 | --- 79 | 80 | **Editing Your Docsify Site Pages on Your Desktop** 81 | 1. Tap **Code** on your repository (upper-right green button) 82 | 2. Choose **Open Desktop** and follow the prompts, installing [GitHub Desktop](https://desktop.github.com/) if not already present 83 | 3. You will now be able to edit your Docsify site (in the `docs` folder) using the desktop editor of your choice (e.g. [Atom](https://atom.io/)) 84 | 4. Use GitHub Desktop to push any changes to your repository. 85 | 86 | [Learn more about using GitHub Desktop](https://help.github.com/en/desktop/contributing-to-projects/committing-and-reviewing-changes-to-your-project). 87 | 88 | You can also clone (i.e download) a copy of your repository to your computer and [run Docsify locally](https://docsify.js.org/#/quickstart) to preview your site. See the below video for details. 89 | 90 | 🧩 Embedding your Docsify Page Content into Other Systems 91 | --- 92 | 93 | ![ Docsify Open Course Page Embedded into the Canvas LMS](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/docsify-oc-canvas.png) 94 | _Figure 2. Docsify Open Course Page Embedded into the Canvas LMS. Explore an example Canvas LMS course using Docsify Open Course pages for content at [https://canvas.sfu.ca/courses/44038/](https://canvas.sfu.ca/courses/44038)_ 95 | 96 | The optional `embedded` (all lowercase) URL parameter hides a site’s sidebar for seamlessly embedding Docsify page content within another platform such as Canvas LMS, Moodle, Microsoft Teams or being displayed in an existing or new Browser tab. The parameter `standalone` is supported as an alias for `embedded`. 97 | 98 | To only display Docsify page content, add the following to a Docsify page URL: 99 | 100 | `?embedded=true` 101 | 102 | Example standard Docsify page: 103 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources 104 | 105 | Example Docsify page displaying only page content (i.e., no sidebar is shown): 106 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true 107 | 108 | To optionally show a page Table of Contents (based on included Headers), use the following: 109 | 110 | `?embedded=true&toc=true` 111 | 112 | Example Docsify page displaying only page content: 113 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true 114 | 115 | Example Docsify page displaying only page content with a page Table of Contents included: 116 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&toc=true 117 | 118 | To optionally override the hiding of the navbar when displaying only page content, use the following: 119 | 120 | `?embedded=true&navbar=true` 121 | 122 | Example Docsify page displaying only page content: 123 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true 124 | 125 | Example Docsify page displaying only page content with the navbar still displayed: 126 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&navbar=true 127 | 128 | To optionally hide the 'Edit this Page' link, use the following: 129 | 130 | `?embedded=true&hidegitlink=true` 131 | 132 | Example Docsify page displaying only page content: 133 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true 134 | 135 | Example Docsify page displaying only page content with the 'Edit this Page' link hidden: 136 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&hidegitlink=true 137 | 138 | To optionally show the footer ('_footer.md' file), use the following: 139 | 140 | `?embedded=true&footer=true` 141 | 142 | Example Docsify page without footer: 143 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true 144 | 145 | Example Docsify page with footer shown: 146 | https://hibbitts-design.github.io/demo-docsify-open-course-starter-kit/#/resources?embedded=true&footer=true 147 | 148 | 🖼 Presenting your Docsify Page Content as Standalone Webpages 149 | --- 150 | 151 | In addition to using URL parameters when embedding Docsify page content into other systems, it is possible to permanently display all pages as standalone, and to also always display a page Table of Contents. 152 | 153 | **To Display all Pages as Standalone** 154 | 1. Open the `index.html` file for editing. 155 | 2. Locate the line `var standalone = false;` and change it to `var standalone = true;`. 156 | 3. Save the `index.html` file and reload site. 157 | 158 | **To Display Page Table of Contents** 159 | 1. Open the `index.html` file for editing. 160 | 2. Locate the line `var ToC = false;` and change it to `var showToC = true;`. 161 | 3. Save the `index.html` file and reload site. 162 | 163 | Please note a page must have a series of Headings (#, ##, ###) for the Table of Contents to be displayed correctly. 164 | 165 | ❛❜ Setting the Name of your Docsify Site 166 | --- 167 | 168 | 1. Open the `index.html` file for editing. 169 | 2. Locate the line `Docsify Open Course Starter Kit` and change the text between the title tags to be displayed as the site name on the Browser tab 170 | 3. Locate the line `name: 'Docsify Open Course Starter Kit',` and change the text between the quotes to be displayed as the site name at the top of the Docsify Sidebar 171 | 4. Save the `index.html` file and reload site. 172 | 173 | ⚠️ Troubleshooting 174 | --- 175 | _Site not displaying on GitHub Pages_ 176 | The most likely cause of not seeing your Docsify site on GitHub Pages is that the 'docs' folder is not selected as the source folder. Go to **Settings** of your repository, tap the **Pages** tab (on the left-hand side), choose **main branch**, then **docs folder** and finally tap the **Save** button. 177 | 178 | 🛠 Using an LMS to Host a Docsify Open Course Site 179 | --- 180 | 181 | As Docsify Open Course Starter Kit does not require a web server, it can actually be hosted on many LMSs that support file libraries such as Canvas and Moodle. 182 | 183 | For example, here is a [Docsify Open Course Site hosted within a Canvas course](https://canvas.sfu.ca/courses/44038/files/15884796/download). Single Docsify Open Course site pages can also be embedded while hosted on the same system. 184 | 185 | **Hosting a Docsify Open Course Site on your LMS** 186 | 1. Tap **Download** on your repository page 187 | 2. Upload to your LMS file storage area, and unzip the upload file 188 | 3. Based on your LMS, determine the external URL required to load the `index.html` file within the Docsify `Docs` folder. In Canvas, an example URL would look similar to `https://canvas.sfu.ca/courses/44038/files/15884796/download`. 189 | 190 | | :warning: | Once hosted within your LMS, changes made to the source GitHub repository are no longer automatically reflected on your hosted Docsify site. Any GitHub repository updates must be manually uploaded to the LMS file library area. | 191 | |---|:--| 192 | 193 | 📚 Docsify and Markdown Resources 194 | --- 195 | **Docsify** 196 | [Docsify Documentation](https://docsify.js.org/#/?id=docsifyg) 197 | [Docsify Basics by MichaelCurrin](https://michaelcurrin.github.io/docsify-js-tutorial/#/?id=docsify-basics) 198 | 199 | **Docsify Themable** 200 | [Docsify Themeable Documentation](https://jhildenbiddle.github.io/docsify-themeable/#/introduction) 201 | [Docsify Themeable GitHub](https://github.com/jhildenbiddle/docsify-themeable) 202 | 203 | **Markdown** 204 | [Markdown Here Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Here-Cheatsheet) 205 | [Markdown Guide](https://www.markdownguide.org/) 206 | 207 | 💡 Content Display Tips and Techniques 208 | --- 209 | **Including Code Blocks** 210 | Using [Prismjs](https://prismjs.com/) code blocks with syntax highlighting is supported for the languages [included with Docsify](https://docsify.js.org/#/language-highlight?id=language-highlighting) and as well Bash, Go, Java, Kotlin, PHP, Python and Swift. To embed a code block use the Markdown standard of triple backticks and start the block with the name of the language, for example to embed a block of Javascript code with syntax highlight the following would be used: 211 | 212 |
213 | ```javascript
214 | function test() {
215 |   console.log("Hello world!");
216 | }
217 | ```
218 | 
219 | Which would then appear as: 220 | ```javascript 221 | function test() { 222 | console.log("Hello world!"); 223 | } 224 | ``` 225 | 226 | **Displaying Images in a Grid** 227 | 3 or more images can be transformed into a responsive grid gallery by including them in lists. For example: 228 | ```markdown 229 | - ![image1](path/to/image1.jpg) 230 | - ![image2](path/to/image2.jpg) 231 | - ![image3](path/to/image3.jpg) 232 | ``` 233 | 234 | 🧰 Useful Markdown CSS Classes 235 | --- 236 | 237 | `accordion` 238 | 239 | ```html 240 |
241 | 242 |
243 | Topic One 244 | 245 | Topic one details here. 246 | 247 |
248 | 249 |
250 | Topic Two 251 | 252 | Topic two details here. 253 | 254 |
255 | 256 |
257 | ``` 258 | 259 | `badge` 260 | 261 | ```html 262 | Tue Jun 12th 11:59pm PDT 263 | ``` 264 | 265 | ```html 266 | Tue Jun 12th 11:59pm PDT 267 | ``` 268 | 269 | ```html 270 | Tue Jun 12th 11:59pm PDT 271 | ``` 272 | 273 | ```html 274 | [Tue May 16 2:30pm PT](https://www.timeanddate.com/worldclock/fixedtime.html?msg=CMPT-363+Blackboard+Mini-lectures+and+Activities&iso=20220516T1430&p1=256&ah=1&am=50) 275 | ``` 276 | 277 | `banner-image` (cropped to height of 250px on large screens, 125px on small screens) 278 | 279 | ```markdown 280 | ![UX - User Experience](images/12650723674_d5c85af332_k.jpg ':class=banner-image') 281 | ``` 282 | 283 | `banner-tall-image` (cropped to height of 350px on large screens, 175px on small screens) 284 | 285 | ```markdown 286 | ![UX - User Experience](images/12650723674_d5c85af332_k.jpg ':class=banner-tall-image') 287 | ``` 288 | 289 | `button` 290 | 291 | ```markdown 292 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button') 293 | ``` 294 | 295 | `button-rounded` 296 | 297 | ```markdown 298 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button-rounded') 299 | ``` 300 | 301 | `button-secondary` 302 | 303 | ```markdown 304 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button-secondary') 305 | ``` 306 | 307 | `button-rounded-secondary` 308 | 309 | ```markdown 310 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=button-rounded-secondary') 311 | ``` 312 | 313 | `card` 314 | 315 | ```html 316 |
317 | 318 | ## [Card Title](#) 319 | ![Card Image](images/example.jpg) 320 | Card content goes here. 321 | 322 |
323 | ``` 324 | 325 | `card-list` 326 | 327 | ```html 328 |
329 |
330 | 331 | ## [Blog Post Title Link](#) 332 | ![Blog Post Image](images/mountain.jpg) 333 | 334 | Blog post preview text goes here with more details about the content. 335 | 336 | Jan 1, 1970. 337 | 338 | [Read More](# ":class=navpill") 339 | 340 |
341 |
342 | 343 | ## [Another Blog Post](#) 344 | ![Blog Post Image](images/forest.jpg) 345 | 346 | Another blog post preview with different content. 347 | 348 | Jan 1, 1970. 349 | 350 | [Read More](# ":class=navpill") 351 | 352 |
353 |
354 | ``` 355 | 356 | `card-rounded` 357 | 358 | ```html 359 |
360 | 361 | ## [Card Title](#) 362 | ![Card Image](images/example.jpg) 363 | Card content goes here. 364 | 365 |
366 | ``` 367 | 368 | `embedly-card` (for linked article previews, embedded slides/videos, etc.) 369 | 370 | ```markdown 371 | Defining usability 372 | ``` 373 | 374 | `header-image-fade` (suggested width of 1200px to 2000px) 375 | 376 | ```markdown 377 | ![Photo of Mountain](images/mountain.jpg ':class=header-image-fade') 378 | ``` 379 | 380 | `header-image-fade-full-width` (suggested size of 1200px to 2000px, and display of Table of Contents is not available) 381 | 382 | ```markdown 383 | ![Photo of Mountain](images/mountain.jpg ':class=header-image-fade-full-width') 384 | ``` 385 | 386 | `header-image-full-width` (suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available) 387 | 388 | ```markdown 389 | ![Photo of Mountain](images/mountain.jpg ':class=header-image-full-width') 390 | ``` 391 | 392 | `header-tall-image-full-width` (suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available) 393 | 394 | ```markdown 395 | ![Photo of Mountain](images/mountain.jpg ':class=header-tall-image-full-width') 396 | ``` 397 | 398 | `header-image-full-width-headings-overlay` (Suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available) 399 | 400 | ```markdown 401 | ![Photo of Mountain](images/mountain.jpg ":class=header-image-full-width-headings-overlay") 402 | 403 | # Page Title 404 | ``` 405 | 406 | `header-tall-image-full-width-headings-overlay` (Suggested size of 1200px to 2000px width and 400px to 600px height, and display of Table of Contents is not available) 407 | 408 | ```markdown 409 | ![Photo of Mountain](images/mountain.jpg ":class=header-tall-image-full-width-headings-overlay") 410 | 411 | # Page Title 412 | ``` 413 | 414 | `image-75` (scale image to 75%) 415 | 416 | ```markdown 417 | ![Photo of Mountain](images/mountain.jpg ':class=image-75') 418 | ``` 419 | 420 | `image-50` (scale image to 50%) 421 | 422 | ```markdown 423 | ![Photo of Mountain](images/mountain.jpg ':class=image-50') 424 | ``` 425 | 426 | `image-25` (scale image to 25%) 427 | 428 | ```markdown 429 | ![Photo of Mountain](images/mountain.jpg ':class=image-25') 430 | ``` 431 | 432 | `image-75-border` 433 | 434 | ```markdown 435 | ![Photo of Mountain](images/mountain.jpg ':class=image-75-border') 436 | ``` 437 | 438 | `image-50-border` 439 | 440 | ```markdown 441 | ![Photo of Mountain](images/mountain.jpg ':class=image-50-border') 442 | ``` 443 | 444 | `image-25-border` 445 | 446 | ```markdown 447 | ![Photo of Mountain](images/mountain.jpg ':class=image-25-border') 448 | ``` 449 | 450 | `image-border` 451 | 452 | ```markdown 453 | ![Photo of Mountain](images/mountain.jpg ':class=image-border') 454 | ``` 455 | 456 | `image-border-rounded` 457 | 458 | ```markdown 459 | ![Photo of Mountain](images/mountain.jpg ':class=image-border-rounded') 460 | ``` 461 | 462 | `navpill` 463 | 464 | ```markdown 465 | [GitHub](https://github.com/hibbitts-design/docsify-this ':class=navpill') 466 | ``` 467 | 468 | ```html 469 | GitHub 470 | ``` 471 | 472 | `responsive` 473 | 474 | ```html 475 | Docsify-This Web Page Builder 476 | ``` 477 | 478 | `row` & `column` 479 | 480 | ```html 481 |
482 |
483 | 484 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 485 | 486 |
487 |
488 | 489 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 490 | 491 |
492 |
493 | ``` 494 | 495 | ```html 496 |
497 |
498 | 499 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 500 | 501 |
502 |
503 | 504 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 505 | 506 |
507 |
508 | ``` 509 | 510 | ```html 511 |
512 |
513 | 514 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 515 | 516 |
517 |
518 | 519 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 520 | 521 |
522 |
523 | ``` 524 | 525 | `video-container-4by3` 526 | 527 | ```html 528 |
529 | ``` 530 | 531 | `video-container-16by9` 532 | Automatically added to all iFrames with the source domains 'youtube.com' or 'docs.google.com'. 533 | ```html 534 |
535 | ``` 536 | 537 | 🎨 Visual Customization 538 | --- 539 | 540 | A Docsify Open Course Starter Kit site can be visually customized using CSS within the `custom.css` file located in the folder `docs/assets/css`. Using this file new Markdown CSS classes can be defined. 541 | 542 | CSS: 543 | ```css 544 | .markdown-section .mybutton, .markdown-section .mybutton:hover { 545 | cursor: pointer; 546 | color: #CC0000; 547 | height: auto; 548 | display: inline-block; 549 | border: 2px solid #CC0000; 550 | border-radius: 4rem; 551 | margin: 2px 0px 2px 0px; 552 | padding: 8px 18px 8px 18px; 553 | line-height: 1.2rem; 554 | background-color: white; 555 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 556 | font-weight: bold; 557 | text-decoration: none; 558 | } 559 | ``` 560 | 561 | Markdown: 562 | ```markdown 563 | [Required Reading Quiz due Jun 4th](https://canvas.sfu.ca/courses/44038/quizzes/166553 ':class=mybutton') 564 | ``` 565 | 566 | [Docsify Themeable CSS settings](https://jhildenbiddle.github.io/docsify-themeable/#/customization?id=base) can also be configured, as seen in the examples provided in the default `custom.css` file. 567 | 568 | CSS: 569 | ```css 570 | :root { 571 | --link-color: #0F6CBF!important; 572 | } 573 | */ 574 | ``` 575 | 576 | It is also possible for dual CSS styling to be configured, with CSS applied to when viewing the site (with overriding custom CSS included in a `STYLE` tag in the `_sidebar.md` file) and then other CSS settings within the `custom.css` file applied to when viewing standalone pages (i.e. `?embedded=true`) 577 | 578 | CSS in Sidebar file (`_sidebar.md`): 579 | ```css 580 | 587 | ``` 588 | 589 | 🌐 Using MAMP to View Docsify Sites Locally 590 | --- 591 | 592 | An alternative to installing Docsify locally (as described following this section) is to use MAMP to view your Docsify sites locally on your own computer. 593 | 594 | 1. Download [MAMP](https://www.mamp.info/) 595 | 2. Move your local Docsify site to the **htdocs** folder of MAMP 596 | 3. Turn MAMP on, tap **WebStart** and then tap **My Website** 597 | 4. Tap on the folder containing your local Docsify site and then tap on the **docs** folder 598 | 599 | 📼 Video Walkthrough of Local Docsify Install/Config 600 | --- 601 | [![Generating Documentation Sites with GitHub and Docsify - Alysson Alvaran](https://raw.githubusercontent.com/paulhibbitts/github-repo-images/master/youtube.png)](https://www.youtube.com/watch?v=TV88lp7egMw) 602 | _Video 1. Generating Documentation Sites with GitHub and Docsify - Alysson Alvaran_ 603 | 604 | 🙇‍Credits and Special Thanks 605 | --- 606 | [Docsify Themeable](https://github.com/jhildenbiddle/docsify-themeable) 607 | -------------------------------------------------------------------------------- /docs/assets/vendor/themeable/docsify-themeable.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * docsify-themeable 3 | * v0.9.0 4 | * https://jhildenbiddle.github.io/docsify-themeable/ 5 | * (c) 2018-2024 John Hildenbiddle 6 | * MIT license 7 | */ 8 | !function(){"use strict";function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},n={mimeType:t.mimeType||null,onBeforeSend:t.onBeforeSend||Function.prototype,onSuccess:t.onSuccess||Function.prototype,onError:t.onError||Function.prototype,onComplete:t.onComplete||Function.prototype},r=Array.isArray(e)?e:[e],o=Array.apply(null,Array(r.length)).map((function(e){return null}));function s(e){var t="string"==typeof e,n=t&&"<"===e.trim().charAt(0);return t&&!n}function a(e,t){n.onError(e,r[t],t)}function c(e,t){var s=n.onSuccess(e,r[t],t);e=!1===s?"":s||e,o[t]=e,-1===o.indexOf(null)&&n.onComplete(o)}var i=document.createElement("a");r.forEach((function(e,t){if(i.setAttribute("href",e),i.href=String(i.href),Boolean(document.all&&!window.atob)&&i.host.split(":")[0]!==location.host.split(":")[0]){if(i.protocol===location.protocol){var r=new XDomainRequest;r.open("GET",e),r.timeout=0,r.onprogress=Function.prototype,r.ontimeout=Function.prototype,r.onload=function(){var e=r.responseText;s(e)?c(e,t):a(r,t)},r.onerror=function(e){a(r,t)},setTimeout((function(){r.send()}),0)}else console.warn("Internet Explorer 9 Cross-Origin (CORS) requests must use the same protocol (".concat(e,")")),a(null,t)}else{var o=new XMLHttpRequest;o.open("GET",e),n.mimeType&&o.overrideMimeType&&o.overrideMimeType(n.mimeType),n.onBeforeSend(o,e,t),o.onreadystatechange=function(){if(4===o.readyState){var e=o.responseText;o.status<400&&s(e)||0===o.status&&s(e)?c(e,t):a(o,t)}},o.send()}}))}function r(e){var t={cssComments:/\/\*[\s\S]+?\*\//g,cssImports:/(?:@import\s*)(?:url\(\s*)?(?:['"])([^'"]*)(?:['"])(?:\s*\))?(?:[^;]*;)/g},r={rootElement:e.rootElement||document,include:e.include||'style,link[rel="stylesheet"]',exclude:e.exclude||null,filter:e.filter||null,skipDisabled:!1!==e.skipDisabled,useCSSOM:e.useCSSOM||!1,onBeforeSend:e.onBeforeSend||Function.prototype,onSuccess:e.onSuccess||Function.prototype,onError:e.onError||Function.prototype,onComplete:e.onComplete||Function.prototype},s=Array.apply(null,r.rootElement.querySelectorAll(r.include)).filter((function(e){return t=e,n=r.exclude,!(t.matches||t.matchesSelector||t.webkitMatchesSelector||t.mozMatchesSelector||t.msMatchesSelector||t.oMatchesSelector).call(t,n);var t,n})),a=Array.apply(null,Array(s.length)).map((function(e){return null}));function c(){if(-1===a.indexOf(null)){a.reduce((function(e,t,n){return""===t&&e.push(n),e}),[]).reverse().forEach((function(e){return[s,a].forEach((function(t){return t.splice(e,1)}))}));var e=a.join("");r.onComplete(e,a,s)}}function i(e,t,n,o){var s=r.onSuccess(e,n,o);l(e=void 0!==s&&!1===Boolean(s)?"":s||e,n,o,(function(e,o){null===a[t]&&(o.forEach((function(e){return r.onError(e.xhr,n,e.url)})),!r.filter||r.filter.test(e)?a[t]=e:a[t]="",c())}))}function u(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],s={};return s.rules=(e.replace(t.cssComments,"").match(t.cssImports)||[]).filter((function(e){return-1===r.indexOf(e)})),s.urls=s.rules.map((function(e){return e.replace(t.cssImports,"$1")})),s.absoluteUrls=s.urls.map((function(e){return o(e,n)})),s.absoluteRules=s.rules.map((function(e,t){var r=s.urls[t],a=o(s.absoluteUrls[t],n);return e.replace(r,a)})),s}function l(e,t,o,s){var a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],c=arguments.length>5&&void 0!==arguments[5]?arguments[5]:[],i=u(e,o,c);i.rules.length?n(i.absoluteUrls,{onBeforeSend:function(e,n,o){r.onBeforeSend(e,t,n)},onSuccess:function(e,n,o){var s=r.onSuccess(e,t,n),a=u(e=!1===s?"":s||e,n,c);return a.rules.forEach((function(t,n){e=e.replace(t,a.absoluteRules[n])})),e},onError:function(n,r,u){a.push({xhr:n,url:r}),c.push(i.rules[u]),l(e,t,o,s,a,c)},onComplete:function(n){n.forEach((function(t,n){e=e.replace(i.rules[n],t)})),l(e,t,o,s,a,c)}}):s(e,a)}s.length?s.forEach((function(e,t){var s=e.getAttribute("href"),u=e.getAttribute("rel"),l="link"===e.nodeName.toLowerCase()&&s&&u&&-1!==u.toLowerCase().indexOf("stylesheet"),d=!1!==r.skipDisabled&&e.disabled,f="style"===e.nodeName.toLowerCase();if(l&&!d)if(-1!==s.indexOf("data:text/css")){var m=decodeURIComponent(s.substring(s.indexOf(",")+1));r.useCSSOM&&(m=Array.apply(null,e.sheet.cssRules).map((function(e){return e.cssText})).join("")),i(m,t,e,location.href)}else n(s,{mimeType:"text/css",onBeforeSend:function(t,n,o){r.onBeforeSend(t,e,n)},onSuccess:function(n,r,a){var c=o(s);i(n,t,e,c)},onError:function(n,o,s){a[t]="",r.onError(n,e,o),c()}});else if(f&&!d){var p=e.textContent;r.useCSSOM&&(p=Array.apply(null,e.sheet.cssRules).map((function(e){return e.cssText})).join("")),i(p,t,e,location.href)}else a[t]="",c()})):r.onComplete("",[])}function o(e,t){var n=document.implementation.createHTMLDocument(""),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),r.href=t||document.baseURI||(document.querySelector("base")||{}).href||location.href,o.href=e,o.href}var s=a;function a(e,t,n){e instanceof RegExp&&(e=c(e,n)),t instanceof RegExp&&(t=c(t,n));var r=i(e,t,n);return r&&{start:r[0],end:r[1],pre:n.slice(0,r[0]),body:n.slice(r[0]+e.length,r[1]),post:n.slice(r[1]+t.length)}}function c(e,t){var n=t.match(e);return n?n[0]:null}function i(e,t,n){var r,o,s,a,c,i=n.indexOf(e),u=n.indexOf(t,i+1),l=i;if(i>=0&&u>0){if(e===t)return[i,u];for(r=[],s=n.length;l>=0&&!c;)l==i?(r.push(l),i=n.indexOf(e,l+1)):1==r.length?c=[r.pop(),u]:((o=r.pop())=0?i:u;r.length&&(c=[s,a])}return c}function u(e){var n=t({},{preserveStatic:!0,removeComments:!1},arguments.length>1&&void 0!==arguments[1]?arguments[1]:{});function r(e){throw new Error("CSS parse error: ".concat(e))}function o(t){var n=t.exec(e);if(n)return e=e.slice(n[0].length),n}function a(){return o(/^{\s*/)}function c(){return o(/^}/)}function i(){o(/^\s*/)}function u(){if(i(),"/"===e[0]&&"*"===e[1]){for(var t=2;e[t]&&("*"!==e[t]||"/"!==e[t+1]);)t++;if(!e[t])return r("end of comment is missing");var n=e.slice(2,t);return e=e.slice(t+2),{type:"comment",comment:n}}}function l(){for(var e,t=[];e=u();)t.push(e);return n.removeComments?[]:t}function d(){for(i();"}"===e[0];)r("extra closing bracket");var t=o(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/);if(t){var n,s=t[0].trim();/\/\*/.test(s)&&(s=s.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g,""));var a=/["']\w*,\w*["']/.test(s);return a&&(s=s.replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g,(function(e){return e.replace(/,/g,"‌")}))),n=/,/.test(s)?s.split(/\s*(?![^(]*\)),\s*/):[s],a&&(n=n.map((function(e){return e.replace(/\u200C/g,",")}))),n}}function f(){if("@"===e[0])return v();o(/^([;\s]*)+/);var t=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,n=o(/^(\*?[-#/*\\\w.]+(\[[0-9a-z_-]+\])?)\s*/);if(n){if(n=n[0].trim(),!o(/^:\s*/))return r("property missing ':'");var s=o(/^((?:\/\*.*?\*\/|'(?:\\'|.)*?'|"(?:\\"|.)*?"|\((\s*'(?:\\'|.)*?'|"(?:\\"|.)*?"|[^)]*?)\s*\)|[^};])+)/),a={type:"declaration",property:n.replace(t,""),value:s?s[0].replace(t,"").trim():""};return o(/^[;\s]*/),a}}function m(){if(!a())return r("missing '{'");for(var e,t=l();e=f();)t.push(e),t=t.concat(l());return c()?t:r("missing '}'")}function p(){i();for(var e,t=[];e=o(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/);)t.push(e[1]),o(/^,\s*/);if(t.length)return{type:"keyframe",values:t,declarations:m()}}function v(){if(i(),"@"===e[0]){var t=function(){var e=o(/^@(import|charset|namespace)\s*([^;]+);/);if(e)return{type:e[1],name:e[2].trim()}}()||function(){if(o(/^@font-face\s*/))return{type:"font-face",declarations:m()}}()||function(){var e=o(/^@media([^{]+)*/);if(e)return{type:"media",media:(e[1]||"").trim(),rules:y()}}()||function(){var e=o(/^@([-\w]+)?keyframes\s*/);if(e){var t=e[1];if(!(e=o(/^([-\w]+)\s*/)))return r("@keyframes missing name");var n,s=e[1];if(!a())return r("@keyframes missing '{'");for(var i=l();n=p();)i.push(n),i=i.concat(l());return c()?{type:"keyframes",name:s,vendor:t,keyframes:i}:r("@keyframes missing '}'")}}()||function(){var e=o(/^@supports *([^{]+)/);if(e)return{type:"supports",supports:e[1].trim(),rules:y()}}()||function(){var e=o(/^@([-\w]+)?document *([^{]+)/);if(e)return{type:"document",document:e[2].trim(),vendor:e[1]?e[1].trim():null,rules:y()}}()||function(){var e=o(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);if(e)return{type:"custom-media",name:e[1].trim(),media:e[2].trim()}}()||function(){if(o(/^@host\s*/))return{type:"host",rules:y()}}()||function(){if(o(/^@page */))return{type:"page",selectors:d()||[],declarations:m()}}()||function(){var e=o(/@(top|bottom|left|right)-(left|center|right|top|middle|bottom)-?(corner)?\s*/);if(e)return{type:"page-margin-box",name:"".concat(e[1],"-").concat(e[2])+(e[3]?"-".concat(e[3]):""),declarations:m()}}();if(t&&!n.preserveStatic){var s=!1;if(t.declarations)s=t.declarations.some((function(e){return/var\(/.test(e.value)}));else s=(t.keyframes||t.rules||[]).some((function(e){return(e.declarations||[]).some((function(e){return/var\(/.test(e.value)}))}));return s?t:{}}return t}}function h(){if(!n.preserveStatic){var t=s("{","}",e);if(t){var o=/:(?:root|host)(?![.:#(])/.test(t.pre)&&/--\S*\s*:/.test(t.body),a=/var\(/.test(t.body);if(!o&&!a)return e=e.slice(t.end+1),{}}}var c=d()||[],i=n.preserveStatic?m():m().filter((function(e){var t=c.some((function(e){return/:(?:root|host)(?![.:#(])/.test(e)}))&&/^--\S/.test(e.property),n=/var\(/.test(e.value);return t||n}));return c.length||r("selector missing"),{type:"rule",selectors:c,declarations:i}}function y(t){if(!t&&!a())return r("missing '{'");for(var n,o=l();e.length&&(t||"}"!==e[0])&&(n=v()||h());)n.type&&o.push(n),o=o.concat(l());return t||c()?o:r("missing '}'")}return{type:"stylesheet",stylesheet:{rules:y(!0),errors:[]}}}function l(e){var n=t({},{parseHost:!1,store:{},onWarning:function(){}},arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}),r=new RegExp(":".concat(n.parseHost?"host":"root","$"));return"string"==typeof e&&(e=u(e,n)),e.stylesheet.rules.forEach((function(e){"rule"===e.type&&e.selectors.some((function(e){return r.test(e)}))&&e.declarations.forEach((function(e,t){var r=e.property,o=e.value;r&&0===r.indexOf("--")&&(n.store[r]=o)}))})),n.store}function d(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2?arguments[2]:void 0,r={charset:function(e){return"@charset "+e.name+";"},comment:function(e){return 0===e.comment.indexOf("__CSSVARSPONYFILL")?"/*"+e.comment+"*/":""},"custom-media":function(e){return"@custom-media "+e.name+" "+e.media+";"},declaration:function(e){return e.property+":"+e.value+";"},document:function(e){return"@"+(e.vendor||"")+"document "+e.document+"{"+o(e.rules)+"}"},"font-face":function(e){return"@font-face{"+o(e.declarations)+"}"},host:function(e){return"@host{"+o(e.rules)+"}"},import:function(e){return"@import "+e.name+";"},keyframe:function(e){return e.values.join(",")+"{"+o(e.declarations)+"}"},keyframes:function(e){return"@"+(e.vendor||"")+"keyframes "+e.name+"{"+o(e.keyframes)+"}"},media:function(e){return"@media "+e.media+"{"+o(e.rules)+"}"},namespace:function(e){return"@namespace "+e.name+";"},page:function(e){return"@page "+(e.selectors.length?e.selectors.join(", "):"")+"{"+o(e.declarations)+"}"},"page-margin-box":function(e){return"@"+e.name+"{"+o(e.declarations)+"}"},rule:function(e){var t=e.declarations;if(t.length)return e.selectors.join(",")+"{"+o(t)+"}"},supports:function(e){return"@supports "+e.supports+"{"+o(e.rules)+"}"}};function o(e){for(var o="",s=0;s1&&void 0!==arguments[1]?arguments[1]:{});return"string"==typeof e&&(e=u(e,n)),f(e.stylesheet,(function(e,t){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;if(-1===e.indexOf("var("))return e;var r=s("(",")",e);return r?"var"===r.pre.slice(-3)?0===r.body.trim().length?(t.onWarning("var() must contain a non-whitespace string"),e):r.pre.slice(0,-3)+function(e){var r=e.split(",")[0].replace(/[\s\n\t]/g,""),o=(e.match(/(?:\s*,\s*){1}(.*)?/)||[])[1],s=Object.prototype.hasOwnProperty.call(t.variables,r)?String(t.variables[r]):void 0,a=s||(o?String(o):void 0),c=n||e;return s||t.onWarning('variable "'.concat(r,'" is undefined')),a&&"undefined"!==a&&a.length>0?y(a,t,c):"var(".concat(c,")")}(r.body)+y(r.post,t):r.pre+"(".concat(y(r.body,t),")")+y(r.post,t):(-1!==e.indexOf("var(")&&t.onWarning('missing closing ")" in the value "'.concat(e,'"')),e)}var g="undefined"!=typeof window,b=g&&window.CSS&&window.CSS.supports&&window.CSS.supports("(--a: 0)"),w={group:0,job:0},S={rootElement:g?document:null,shadowDOM:!1,include:"style,link[rel=stylesheet]",exclude:"",variables:{},onlyLegacy:!0,preserveStatic:!0,preserveVars:!1,silent:!1,updateDOM:!0,updateURLs:!0,watch:null,onBeforeSend:function(){},onError:function(){},onWarning:function(){},onSuccess:function(){},onComplete:function(){},onFinally:function(){}},E={cssComments:/\/\*[\s\S]+?\*\//g,cssKeyframes:/@(?:-\w*-)?keyframes/,cssMediaQueries:/@media[^{]+\{([\s\S]+?})\s*}/g,cssUrls:/url\((?!['"]?(?:data|http|\/\/):)['"]?([^'")]*)['"]?\)/g,cssVarDeclRules:/(?::(?:root|host)(?![.:#(])[\s,]*[^{]*{\s*[^}]*})/g,cssVarDecls:/(?:[\s;]*)(-{2}\w[\w-]*)(?:\s*:\s*)([^;]*);/g,cssVarFunc:/var\(\s*--[\w-]/,cssVars:/(?:(?::(?:root|host)(?![.:#(])[\s,]*[^{]*{\s*[^;]*;*\s*)|(?:var\(\s*))(--[^:)]+)(?:\s*[:)])/},C={dom:{},job:{},user:{}},x=!1,A=null,O=0,k=null,L=!1;function _(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n="cssVars(): ",o=t({},S,e);function s(e,t,r,s){!o.silent&&window.console&&console.error("".concat(n).concat(e,"\n"),t),o.onError(e,t,r,s)}function a(e){!o.silent&&window.console&&console.warn("".concat(n).concat(e)),o.onWarning(e)}function c(e){o.onFinally(Boolean(e),b,M()-o.__benchmark)}if(g){if(o.watch)return o.watch=S.watch,function(e){function t(e){var t=n(e)&&e.hasAttribute("disabled"),r=(e.sheet||{}).disabled;return t||r}function n(e){return"link"===e.nodeName.toLowerCase()&&-1!==(e.getAttribute("rel")||"").indexOf("stylesheet")}function r(e){return"style"===e.nodeName.toLowerCase()}function o(r){var o=!1;if("attributes"===r.type&&n(r.target)&&!t(r.target)){var s="disabled"===r.attributeName,a="href"===r.attributeName,c="skip"===r.target.getAttribute("data-cssvars"),i="src"===r.target.getAttribute("data-cssvars");s?o=!c&&!i:a&&(c?r.target.setAttribute("data-cssvars",""):i&&T(e.rootElement,!0),o=!0)}return o}function s(e){var t=!1;if("childList"===e.type){var n=r(e.target),o="out"===e.target.getAttribute("data-cssvars");t=n&&!o}return t}function a(e){var o=!1;return"childList"===e.type&&(o=[].slice.call(e.addedNodes).some((function(e){var o=1===e.nodeType&&e.hasAttribute("data-cssvars"),s=r(e)&&E.cssVars.test(e.textContent);return!o&&(n(e)||s)&&!t(e)}))),o}function c(t){var n=!1;return"childList"===t.type&&(n=[].slice.call(t.removedNodes).some((function(t){var n=1===t.nodeType,r=n&&"out"===t.getAttribute("data-cssvars"),o=n&&"src"===t.getAttribute("data-cssvars"),s=o;if(o||r){var a=t.getAttribute("data-cssvars-group"),c=e.rootElement.querySelector('[data-cssvars-group="'.concat(a,'"]'));o&&T(e.rootElement,!0),c&&c.parentNode.removeChild(c)}return s}))),n}if(!window.MutationObserver)return;A&&(A.disconnect(),A=null);A=new MutationObserver((function(t){t.some((function(e){return o(e)||s(e)||a(e)||c(e)}))&&_(e)})),A.observe(document.documentElement,{attributes:!0,attributeFilter:["disabled","href"],childList:!0,subtree:!0})}(o),void _(o);if(!1===o.watch&&A&&(A.disconnect(),A=null),!o.__benchmark){if(x===o.rootElement)return void function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100;clearTimeout(k),k=setTimeout((function(){e.__benchmark=null,_(e)}),t)}(e);var i=[].slice.call(o.rootElement.querySelectorAll('[data-cssvars]:not([data-cssvars="out"])'));if(o.__benchmark=M(),o.exclude=[A?'[data-cssvars]:not([data-cssvars=""])':'[data-cssvars="out"]',"link[disabled]:not([data-cssvars])",o.exclude].filter((function(e){return e})).join(","),o.variables=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=/^-{2}/;return Object.keys(e).reduce((function(n,r){return n[t.test(r)?r:"--".concat(r.replace(/^-+/,""))]=e[r],n}),{})}(o.variables),i.forEach((function(e){var t="style"===e.nodeName.toLowerCase()&&e.__cssVars.text,n=t&&e.textContent!==e.__cssVars.text;t&&n&&(e.sheet&&(e.sheet.disabled=!1),e.setAttribute("data-cssvars",""))})),!A)[].slice.call(o.rootElement.querySelectorAll('[data-cssvars="out"]')).forEach((function(e){var t=e.getAttribute("data-cssvars-group");(t?o.rootElement.querySelector('[data-cssvars="src"][data-cssvars-group="'.concat(t,'"]')):null)||e.parentNode.removeChild(e)})),O&&i.length2&&void 0!==arguments[2]?arguments[2]:[],i=t({},C.dom,C.user);if(C.job={},r.forEach((function(e,t){var r=n[t];if(e.__cssVars=e.__cssVars||{},e.__cssVars.text=r,E.cssVars.test(r))try{var c=u(r,{preserveStatic:o.preserveStatic,removeComments:!0});l(c,{parseHost:Boolean(o.rootElement.host),store:C.dom,onWarning:a}),e.__cssVars.tree=c}catch(t){s(t.message,e)}})),t(C.job,C.dom),o.updateDOM?(t(C.user,o.variables),t(C.job,C.user)):(t(C.job,C.user,o.variables),t(i,o.variables)),w.job>0&&Boolean(Object.keys(C.job).length>Object.keys(i).length||Boolean(Object.keys(i).length&&Object.keys(C.job).some((function(e){return C.job[e]!==i[e]})))))T(o.rootElement),_(o);else{var f=[],m=[],p=!1;if(o.updateDOM&&w.job++,r.forEach((function(e,r){var c=!e.__cssVars.tree;if(e.__cssVars.tree)try{v(e.__cssVars.tree,t({},o,{variables:C.job,onWarning:a}));var i=d(e.__cssVars.tree);if(o.updateDOM){var u=n[r],l=E.cssVarFunc.test(u);if(e.getAttribute("data-cssvars")||e.setAttribute("data-cssvars","src"),i.length&&l){var h=e.getAttribute("data-cssvars-group")||++w.group,y=i.replace(/\s/g,""),g=o.rootElement.querySelector('[data-cssvars="out"][data-cssvars-group="'.concat(h,'"]'))||document.createElement("style");p=p||E.cssKeyframes.test(i),o.preserveStatic&&e.sheet&&(e.sheet.disabled=!0),g.hasAttribute("data-cssvars")||g.setAttribute("data-cssvars","out"),y===e.textContent.replace(/\s/g,"")?(c=!0,g&&g.parentNode&&(e.removeAttribute("data-cssvars-group"),g.parentNode.removeChild(g))):y!==g.textContent.replace(/\s/g,"")&&([e,g].forEach((function(e){e.setAttribute("data-cssvars-job",w.job),e.setAttribute("data-cssvars-group",h)})),g.textContent=i,f.push(i),m.push(g),g.parentNode||e.parentNode.insertBefore(g,e.nextSibling))}}else e.textContent.replace(/\s/g,"")!==i&&f.push(i)}catch(t){s(t.message,e)}c&&e.setAttribute("data-cssvars","skip"),e.hasAttribute("data-cssvars-job")||e.setAttribute("data-cssvars-job",w.job)})),O=o.rootElement.querySelectorAll('[data-cssvars]:not([data-cssvars="out"])').length,o.shadowDOM)for(var h,y=[].concat(o.rootElement).concat([].slice.call(o.rootElement.querySelectorAll("*"))),g=0;h=y[g];++g){if(h.shadowRoot&&h.shadowRoot.querySelector("style"))_(t({},o,{rootElement:h.shadowRoot}))}o.updateDOM&&p&&function(e){var t=["animation-name","-moz-animation-name","-webkit-animation-name"].filter((function(e){return getComputedStyle(document.body)[e]}))[0];if(t){for(var n=[].slice.call(e.querySelectorAll("*")),r=[],o="__CSSVARSPONYFILL-KEYFRAMES__",s=0,a=n.length;s1&&void 0!==arguments[1]?arguments[1]:location.href,n=document.implementation.createHTMLDocument(""),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),r.href=t,o.href=e,o.href}function M(){return g&&(window.performance||{}).now?window.performance.now():(new Date).getTime()}function T(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];[].slice.call(e.querySelectorAll('[data-cssvars="skip"],[data-cssvars="src"]')).forEach((function(e){return e.setAttribute("data-cssvars","")})),t&&(C.dom={})}function V(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=3===e.childNodes[0].nodeType,o=e.querySelector("ul");if(r&&o&&!Array.apply(null,e.children).some((function(e){return e.tabIndex>-1})).length){var s=document.createElement("span");for(null!==n&&s.setAttribute("tabindex",n),e.insertBefore(s,o);e.childNodes[0]!==s;)s.appendChild(e.childNodes[0])}}_.reset=function(){for(var e in w.job=0,w.group=0,x=!1,A&&(A.disconnect(),A=null),O=0,k=null,L=!1,C)C[e]={}};var N="0.9.0";function R(e){for(var t=((window.Docsify||{}).version||"0.0.0").split("."),n=e.split(".");n.length a");e&&(e.parentNode.innerHTML=e.innerHTML)}))},function(e,t){e.doneEach((function(){var e=Array.apply(null,document.querySelectorAll("body > nav.app-nav > ul > li")),t=Array.apply(null,document.querySelectorAll(".sidebar > nav > ul > li"));e.forEach((function(e){var t="focus-within";V(e,"span",0),e.addEventListener("focusin",(function(n){e.contains(document.activeElement)&&e.classList.add(t)})),e.addEventListener("focusout",(function(n){e.contains(document.activeElement)||e.classList.remove(t)}))})),t.forEach((function(e){V(e,"span")}))}))},function(e,t){e.doneEach((function(){Array.apply(null,document.querySelectorAll("pre[data-lang]")).forEach((function(e){var t=e.querySelector("code"),n="language-".concat(e.getAttribute("data-lang"));e.classList.add(n),t.classList.add(n)}))}))},function(e,t){e.mounted((function(){var e=document.querySelector(".content"),t=setInterval((function(){e.textContent.length&&(document.body.classList.add("ready-fix"),clearInterval(t))}),250)})),e.ready((function(){document.body.classList.add("ready-fix")}))},function(e,t){e.init((function(){if(!1!==((window.$docsify||{}).themeable||{}).responsiveTables){var e=window.$docsify.markdown=window.$docsify.markdown||{},t=e.renderer=e.renderer||{};t.table=t.table||function(e,t){var n='\n
\n \n '.concat(e,"\n ").concat(t,"\n
\n
");try{var r=document.createElement("div"),o=document.head.appendChild(document.createElement("style")).sheet,s="_"+Math.random().toString(36).substr(2,9);r.innerHTML=n;var a=r.querySelector("table");Array.apply(null,a.getElementsByTagName("th")).map((function(e){return e.innerHTML.replace(" "," ")})).forEach((function(e,t){var n="#".concat(s," td:nth-child(").concat(t+1,')::before{content:"').concat(e,'";}');o.insertRule(n,o.cssRules.length)})),a.id=s,n=r.innerHTML}catch(e){console.log("Failed to render responsive table: "+e)}return n}}}))}],window.$docsify.plugins||[],[function(e,t){e.ready((function(){var e=document.querySelector(".sidebar .search .clear-button");if(e){var t=document.createElement("button");t.className="clear-button",t.setAttribute("aria-label","Clear search"),t.innerHTML='\n \n \n \n \n \n ',e.parentNode.replaceChild(t,e)}}))},R("4.8.0"),R("4.8.0")]).filter((function(e){return null!==e})),"object"!==e(window.$docsify.search)?window.$docsify.search={}:Array.isArray(window.$docsify.search)&&(window.$docsify.search={paths:window.$docsify.search}),window.$docsify.search.hideOtherSidebarContent=!0,window.$docsify.themeable=window.$docsify.themeable||{},window.$docsify.themeable.version=N,window.$docsify.themeable.semver=N.split("."),window.$docsify.themeable.util={cssVars:function(){_(arguments.length>0&&void 0!==arguments[0]?arguments[0]:q)}}}}(); 9 | //# sourceMappingURL=docsify-themeable.min.js.map 10 | -------------------------------------------------------------------------------- /docs/assets/css/theme.css: -------------------------------------------------------------------------------- 1 | .app-nav:not(:empty) ~ main .markdown-section { 2 | padding-top: 5rem; 3 | } 4 | 5 | .sidebar-nav a, 6 | .sidebar nav a { 7 | overflow: visible; 8 | white-space: break-spaces; 9 | } 10 | 11 | .pagination-item, 12 | .pagination-item-title { 13 | opacity: 0.9 !important; 14 | } 15 | 16 | .pagination-item:not(:last-child) a .pagination-item-label, 17 | .pagination-item:not(:last-child) a .pagination-item-subtitle, 18 | .pagination-item:not(:last-child) a .pagination-item-title { 19 | opacity: 0.9 !important; 20 | transition: all 0.2s; 21 | } 22 | 23 | .markdown-section { 24 | padding: 1rem 40px; 25 | } 26 | 27 | .markdown-section .alert, 28 | .markdown-section blockquote { 29 | overflow: visible; 30 | margin: 1em 0; 31 | padding: 1em; 32 | border-width: var(--blockquote-border-width, 0); 33 | border-style: var(--blockquote-border-style); 34 | border-color: var(--blockquote-border-color); 35 | border-radius: var(--blockquote-border-radius); 36 | background: var(--blockquote-background); 37 | color: var(--blockquote-color); 38 | font-family: var(--blockquote-font-family); 39 | font-size: var(--blockquote-font-size); 40 | font-style: var(--blockquote-font-style); 41 | font-weight: var(--blockquote-font-weight); 42 | quotes: "“" "”" "‘" "’"; 43 | } 44 | 45 | .markdown-section ul { 46 | list-style: square outside none; 47 | } 48 | 49 | .markdown-section .alert ul, 50 | .markdown-section blockquote ul { 51 | list-style: none; 52 | margin-top: 0.8em; 53 | } 54 | 55 | .markdown-section .alert ul li, 56 | .markdown-section blockquote ul li { 57 | margin: 2px 0; 58 | } 59 | 60 | .markdown-section .alert ul li:before, 61 | .markdown-section blockquote ul li:before { 62 | position: absolute; 63 | content: "\2B29"; 64 | margin-left: -18px; 65 | } 66 | 67 | .markdown-section .button { 68 | cursor: pointer; 69 | color: var(--base-background-color); 70 | height: auto; 71 | display: inline-block; 72 | padding: 10px; 73 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 74 | line-height: 1.2rem; 75 | background-color: var(--link-color); 76 | text-decoration: none; 77 | border-radius: 0.25rem; 78 | } 79 | 80 | .markdown-section a.button { 81 | cursor: pointer; 82 | color: var(--base-background-color); 83 | text-decoration: none !important; 84 | } 85 | 86 | .markdown-section .button-secondary { 87 | cursor: pointer; 88 | color: var(--link-color); 89 | height: auto; 90 | display: inline-block; 91 | padding: 10px; 92 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 93 | line-height: 1.2rem; 94 | background-color: transparent; 95 | text-decoration: none; 96 | border: 1px solid var(--link-color) !important; 97 | border-radius: 0.25rem; 98 | } 99 | 100 | .markdown-section a.button-secondary { 101 | cursor: pointer; 102 | color: var(--link-color); 103 | text-decoration: none !important; 104 | } 105 | 106 | .markdown-section .button-rounded { 107 | cursor: pointer; 108 | color: var(--base-background-color); 109 | height: auto; 110 | display: inline-block; 111 | padding: 10px min(20px, 5%) 10px min(20px, 5%); 112 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 113 | line-height: 1.2rem; 114 | background-color: var(--link-color); 115 | text-decoration: none; 116 | border-radius: 1.2rem; 117 | } 118 | 119 | .markdown-section a.button-rounded { 120 | cursor: pointer; 121 | color: var(--base-background-color); 122 | text-decoration: none !important; 123 | } 124 | 125 | .markdown-section .button-secondary-rounded { 126 | cursor: pointer; 127 | color: var(--link-color); 128 | height: auto; 129 | display: inline-block; 130 | padding: 10px min(20px, 5%) 10px min(20px, 5%); 131 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 132 | line-height: 1.2rem; 133 | background-color: transparent; 134 | text-decoration: none; 135 | border: 1px solid var(--link-color) !important; 136 | border-radius: 1.4rem; 137 | } 138 | 139 | .markdown-section a.button-secondary-rounded { 140 | cursor: pointer; 141 | color: var(--link-color); 142 | text-decoration: none !important; 143 | } 144 | 145 | .markdown-section .navpill { 146 | cursor: pointer; 147 | color: var(--base-color); 148 | height: auto; 149 | display: inline-block; 150 | border: 1px solid var(--base-color); 151 | border-radius: 4rem; 152 | padding: 4px 14px 4px 14px; 153 | margin-bottom: 4px; 154 | margin-right: 6px; 155 | font-size: 0.8rem; 156 | line-height: 0.9rem; 157 | background-color: var(--base-background-color); 158 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 159 | font-weight: bold; 160 | text-decoration: none; 161 | } 162 | 163 | .markdown-section a.navpill { 164 | cursor: pointer; 165 | color: var(--base-color) !important; 166 | border: 1px solid var(--base-color); 167 | text-decoration: none !important; 168 | } 169 | 170 | .markdown-section .badge { 171 | color: var( 172 | --badge-text-color, 173 | var(--base-background-color) 174 | ); /* Default text color */ 175 | background-color: var( 176 | --badge-bg-color, 177 | color-mix(in srgb, var(--base-color) 70%, transparent) 178 | ); /* Default background */ 179 | 180 | display: inline-block; 181 | padding: 0.25em 0.4em 0.25em 0.4em; 182 | font-family: -apple-system, "Segoe UI", "Helvetica Neue", sans-serif; 183 | font-size: 75%; 184 | font-weight: 700; 185 | line-height: 1; 186 | text-align: center; 187 | white-space: nowrap; 188 | vertical-align: middle; 189 | margin-top: -0.4em; 190 | border-radius: 0.25rem; 191 | transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, 192 | border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; 193 | text-decoration: none; 194 | } 195 | 196 | .markdown-section .badge a { 197 | color: var( 198 | --badge-text-color, 199 | var(--base-background-color) 200 | ) !important; /* Default text color */ 201 | text-decoration: none !important; 202 | } 203 | 204 | .markdown-section a[href$="?id=a"], 205 | .markdown-section a[href$="?id=b"], 206 | .markdown-section a[href$="?id=c"], 207 | .markdown-section a[href$="?id=d"], 208 | .markdown-section a[href$="?id=e"], 209 | .markdown-section a[href$="?id=f"], 210 | .markdown-section a[href$="?id=g"], 211 | .markdown-section a[href$="?id=h"], 212 | .markdown-section a[href$="?id=i"], 213 | .markdown-section a[href$="?id=j"], 214 | .markdown-section a[href$="?id=k"], 215 | .markdown-section a[href$="?id=l"], 216 | .markdown-section a[href$="?id=m"], 217 | .markdown-section a[href$="?id=n"], 218 | .markdown-section a[href$="?id=o"], 219 | .markdown-section a[href$="?id=p"], 220 | .markdown-section a[href$="?id=q"], 221 | .markdown-section a[href$="?id=r"], 222 | .markdown-section a[href$="?id=s"], 223 | .markdown-section a[href$="?id=t"], 224 | .markdown-section a[href$="?id=u"], 225 | .markdown-section a[href$="?id=v"], 226 | .markdown-section a[href$="?id=w"], 227 | .markdown-section a[href$="?id=x"], 228 | .markdown-section a[href$="?id=y"], 229 | .markdown-section a[href$="?id=z"] { 230 | display: inline-flex; 231 | padding-top: 0px; 232 | padding-right: 6px; 233 | padding-bottom: 0px; 234 | padding-left: 6px; 235 | line-height: 1.2em; 236 | } 237 | 238 | .markdown-section #a, 239 | .markdown-section #b, 240 | .markdown-section #c, 241 | .markdown-section #d, 242 | .markdown-section #e, 243 | .markdown-section #f, 244 | .markdown-section #g, 245 | .markdown-section #h, 246 | .markdown-section #i, 247 | .markdown-section #j, 248 | .markdown-section #k, 249 | .markdown-section #l, 250 | .markdown-section #m, 251 | .markdown-section #n, 252 | .markdown-section #o, 253 | .markdown-section #p, 254 | .markdown-section #q, 255 | .markdown-section #r, 256 | .markdown-section #s, 257 | .markdown-section #t, 258 | .markdown-section #u, 259 | .markdown-section #v, 260 | .markdown-section #w, 261 | .markdown-section #x, 262 | .markdown-section #y, 263 | .markdown-section #z { 264 | width: 2em; 265 | color: var(--base-background-color); 266 | font-weight: 700; 267 | margin-top: 1rem; 268 | background: color-mix(in srgb, var(--base-color) 70%, transparent); 269 | background-clip: content-box; 270 | } 271 | 272 | /* Target first paragraphs with 5+ links (reasonable index minimum) */ 273 | .markdown-section p:first-of-type:has(a[href^="#"]):has(a:nth-of-type(5)) { 274 | flex-wrap: wrap; 275 | gap: 2px; 276 | font-size: var(--font-size-l); 277 | font-weight: 500; 278 | line-height: 1.4; 279 | } 280 | 281 | .markdown-section p:first-of-type:has(a[href^="#"]):has(a:nth-of-type(5)) a { 282 | padding: 0 4px; 283 | } 284 | 285 | .markdown-section .accordion { 286 | margin-top: 1.05rem; 287 | position: relative; 288 | display: -ms-flexbox; 289 | display: flex; 290 | -ms-flex-direction: column; 291 | flex-direction: column; 292 | min-width: 0; 293 | word-wrap: break-word; 294 | background-clip: border-box; 295 | border-top: 1px solid #cccccc; 296 | border-right: 1px solid #cccccc; 297 | border-left: 1px solid #cccccc; 298 | border-radius: 0.15rem; 299 | } 300 | 301 | .markdown-section .accordion details { 302 | padding: 0.75rem 1.25rem; 303 | margin-bottom: 0; 304 | border-bottom: 1px solid #cccccc; 305 | } 306 | 307 | .markdown-section summary { 308 | cursor: pointer; 309 | color: var(--link-color); 310 | padding: 0; 311 | 312 | h1, 313 | h2, 314 | h3 { 315 | margin: 0; 316 | display: inline-block; 317 | } 318 | } 319 | 320 | .markdown-section code { 321 | white-space: pre-wrap !important; 322 | overflow-wrap: break-word; 323 | } 324 | 325 | .markdown-section pre { 326 | white-space: pre-wrap !important; 327 | overflow-wrap: break-word; 328 | } 329 | 330 | .markdown-section pre code { 331 | white-space: pre-wrap !important; 332 | overflow-wrap: break-word; 333 | } 334 | 335 | .markdown-section a { 336 | overflow-wrap: anywhere; 337 | } 338 | 339 | /* Included to support earlier Markdown Schedule templates */ 340 | .markdown-section h2 .fa-fw { 341 | text-align: left; 342 | } 343 | 344 | .markdown-section .video-container-4by3 { 345 | position: relative; 346 | padding-bottom: 75%; 347 | height: 0; 348 | overflow: hidden; 349 | max-width: 100%; 350 | } 351 | 352 | .markdown-section .video-container-16by9 { 353 | position: relative; 354 | padding-bottom: 56.25%; 355 | height: 0; 356 | overflow: hidden; 357 | max-width: 100%; 358 | } 359 | 360 | .video-container-16by9 iframe, 361 | .video-container-4by3 iframe, 362 | .embed-container object, 363 | .embed-container embed { 364 | position: absolute; 365 | top: 0; 366 | left: 0; 367 | width: 100%; 368 | height: 93%; 369 | } 370 | 371 | .markdown-section .responsive-container iframe { 372 | max-width: 100%; 373 | } 374 | 375 | .markdown-section .responsive { 376 | max-width: 100%; 377 | height: auto; 378 | } 379 | 380 | aside#__sidebar .card-image-sidebar, 381 | aside#__sidebar .card-image-sidebar-rounded { 382 | width: 100%; /* fills full width of sidebar */ 383 | height: auto; 384 | max-height: 165px; /* prevents it from getting too tall */ 385 | object-fit: cover; /* crops image to fit dimensions */ 386 | display: block; 387 | margin-top:0px; 388 | } 389 | 390 | aside#__sidebar .card-image-sidebar-rounded { 391 | border-radius: 6px 6px 0 0; 392 | } 393 | 394 | /* Make sidebar a flex container when banner image exists */ 395 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child) { 396 | display: flex; 397 | flex-direction: column; 398 | } 399 | 400 | /* Put sidebar-nav (with image) first */ 401 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child) .sidebar-nav { 402 | order: 1; 403 | } 404 | 405 | /* Put secondary nav second */ 406 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child) nav[aria-label="secondary"] { 407 | order: 2; 408 | } 409 | 410 | /* Only apply negative margin when both banner image and mergedNavbar nav exist */ 411 | aside#__sidebar:has(.sidebar-nav > [class*="card-image-sidebar"]:first-child):has(nav[aria-label="secondary"]) .sidebar-nav > ul > li:last-child { 412 | margin-bottom: -40px !important; 413 | } 414 | 415 | .markdown-section .banner-image { 416 | width: 100%; 417 | height: 125px; 418 | object-fit: cover; 419 | object-position: 50% 50%; 420 | } 421 | 422 | @media (min-width: 576px) { 423 | .markdown-section .banner-image { 424 | height: 250px; 425 | } 426 | } 427 | 428 | .markdown-section .banner-tall-image { 429 | width: 100%; 430 | height: 175px; 431 | object-fit: cover; 432 | object-position: 50% 50%; 433 | } 434 | 435 | @media (min-width: 576px) { 436 | .markdown-section .banner-tall-image { 437 | height: 350px; 438 | } 439 | } 440 | 441 | .markdown-section .header-image-fade { 442 | width: 100%; 443 | margin: 0px auto; 444 | position: absolute; 445 | top: 0px; 446 | left: 0; 447 | -webkit-mask-image: -webkit-gradient( 448 | linear, 449 | left top, 450 | left bottom, 451 | from(rgba(0, 0, 0, 1)), 452 | to(rgba(0, 0, 0, 0)) 453 | ); 454 | mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); 455 | opacity: 0.4; 456 | z-index: -1; 457 | } 458 | 459 | /* CSS currently only works with sidebar and standalone pages */ 460 | .markdown-section .header-image-fade-full-width { 461 | margin-top: -2rem; 462 | left: 50%; 463 | right: 50%; 464 | margin-left: -50vw; 465 | margin-right: -50vw; 466 | position: absolute; 467 | width: 100vw; 468 | max-width: 100vw; 469 | -webkit-mask-image: -webkit-gradient( 470 | linear, 471 | left top, 472 | left bottom, 473 | from(rgba(0, 0, 0, 1)), 474 | to(rgba(0, 0, 0, 0)) 475 | ); 476 | mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); 477 | opacity: 0.4; 478 | z-index: -1; 479 | } 480 | 481 | /* CSS currently only works with sidebar and standalone pages */ 482 | .markdown-section .header-image-full-width, 483 | .markdown-section .header-image-full-width-headings-overlay { 484 | margin-top: -3rem; 485 | left: 50%; 486 | margin-left: -50vw; 487 | margin-right: -50vw; 488 | max-width: 100vw; 489 | position: relative; 490 | right: 50%; 491 | width: 100vw; 492 | height: 30dvh; 493 | object-fit: cover; 494 | object-position: center 50%; 495 | } 496 | 497 | .markdown-section .header-tall-image-full-width, 498 | .markdown-section .header-tall-image-full-width-headings-overlay { 499 | margin-top: -3rem; 500 | left: 50%; 501 | margin-left: -50vw; 502 | margin-right: -50vw; 503 | max-width: 100vw; 504 | position: relative; 505 | right: 50%; 506 | width: 100vw; 507 | height: 40dvh; 508 | object-fit: cover; 509 | object-position: center 50%; 510 | } 511 | 512 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + h1[tabindex="-1"], 513 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + * + h1[tabindex="-1"] { 514 | font-size: clamp(2rem, 5vw, 3.0rem); /* Scales between 2rem and 3.0rem */ 515 | line-height: clamp(2.2rem, 5.5vw, 3.4rem); 516 | margin-left: -3px; 517 | font-weight: 600; 518 | letter-spacing: clamp(-0.02em, -0.5vw, -0.01em); /* Tighten large text */ 519 | margin-top: clamp(1.5rem, 3vw, 2.5rem); 520 | margin-bottom: clamp(0.75rem, 1.5vw, 1.25rem); 521 | } 522 | 523 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + h1[tabindex="-1"] + h2[tabindex="-1"], 524 | .markdown-section p:has(.header-tall-image-full-width, .header-image-full-width) + * + h1[tabindex="-1"] + h2[tabindex="-1"] { 525 | font-size: clamp(1.2rem, 3vw, 1.8rem); /* Scales between 1.2rem and 1.8rem */ 526 | line-height: clamp(1.4rem, 3.5vw, 2rem); 527 | margin-left: -2px; 528 | font-weight: 500; 529 | margin-bottom: clamp(1.5rem, 3vw, 2.5rem); 530 | } 531 | 532 | /* CSS generated/assisted by Anthropic Claude AI */ 533 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay, 534 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] { 535 | position: absolute; 536 | top: calc(-3rem + 20dvh + 1rem); /* h1 center + spacing */ 537 | left: 50%; 538 | transform: translate(-50%, -50%); 539 | color: white; 540 | text-shadow: 541 | 2px 2px 4px rgba(0,0,0,0.8), 542 | 0 0 20px rgba(0,0,0,0.4); 543 | z-index: 10; 544 | margin: 0; 545 | font-size: clamp(2rem, 5vw, 3.0rem); /* Scales between 2rem and 3.0rem */ 546 | line-height: clamp(2.2rem, 5.5vw, 3.4rem); 547 | width: 100%; 548 | text-align: center; 549 | font-weight: 500; 550 | letter-spacing: -0.03em; 551 | backdrop-filter: blur(2px); 552 | background: linear-gradient( 553 | 135deg, 554 | rgba(0,0,0,0.3) 0%, 555 | rgba(0,0,0,0.1) 100% 556 | ); 557 | padding: clamp(0.5rem, 2vw, 1rem) clamp(1rem, 4vw, 2rem); 558 | border-radius: 8px; 559 | max-width: 90vw; 560 | } 561 | 562 | .markdown-section p:has(.header-image-full-width-headings-overlay) + h1[tabindex="-1"] { 563 | top: calc(-3rem + 15dvh + 1rem); /* h1 center + spacing for regular images */ 564 | } 565 | 566 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay, 567 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] { 568 | position: absolute; 569 | top: calc(-3rem + 20dvh + 3.5rem); /* h1 center + spacing */ 570 | left: 50%; 571 | transform: translateX(-50%); /* Only center horizontally */ 572 | color: rgba(255,255,255,0.95); 573 | text-shadow: 574 | 1px 1px 3px rgba(0,0,0,0.7), 575 | 0 0 15px rgba(0,0,0,0.3); 576 | z-index: 10; 577 | margin: 0; 578 | font-size: clamp(1.2rem, 3vw, 1.8rem); /* Scales between 1.2rem and 1.8rem */ 579 | line-height: clamp(1.4rem, 3.5vw, 2rem); 580 | width: 100%; 581 | text-align: center; 582 | font-weight: 300; 583 | letter-spacing: 0.05em; 584 | padding: clamp(0.25rem, 1vw, 0.5rem) clamp(0.75rem, 3vw, 1.5rem); 585 | max-width: 80vw; 586 | border: 0; 587 | } 588 | 589 | .markdown-section p:has(.header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] { 590 | top: calc(-3rem + 15dvh + 3.5rem); /* h2 center + spacing for regular images */ 591 | } 592 | 593 | /* Keep text-shadow for links in h1 and h2 (same as parent) */ 594 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay, 595 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] a, 596 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay, 597 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] a { 598 | text-shadow: inherit; /* Inherit shadow from parent */ 599 | text-decoration: none; /* Remove default underline */ 600 | } 601 | 602 | /* Apply underline only on hover */ 603 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay, 604 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] a:hover, 605 | .markdown-section p:has(.header-tall-image-full-width-headings-overlay, 606 | .header-image-full-width-headings-overlay) + h1[tabindex="-1"] + h2[tabindex="-1"] a:hover { 607 | text-decoration: underline; /* Show underline on hover */ 608 | } 609 | 610 | .markdown-section .image-75 { 611 | width: 75%; 612 | height: auto; 613 | } 614 | 615 | .markdown-section .image-50 { 616 | width: 50%; 617 | height: auto; 618 | } 619 | 620 | .markdown-section .image-25 { 621 | width: 25%; 622 | height: auto; 623 | } 624 | 625 | .markdown-section .image-75-border { 626 | width: 75%; 627 | height: auto; 628 | border: 1px solid #dfdfdf; 629 | } 630 | 631 | .markdown-section .image-50-border { 632 | width: 50%; 633 | height: auto; 634 | border: 1px solid #dfdfdf; 635 | } 636 | 637 | .markdown-section .image-25-border { 638 | width: 25%; 639 | height: auto; 640 | border: 1px solid #dfdfdf; 641 | } 642 | 643 | .markdown-section .image-border { 644 | border: 1px solid #dfdfdf; 645 | } 646 | 647 | .markdown-section .image-border-rounded { 648 | border-radius: 0.35em; 649 | border: 1px solid #dfdfdf; 650 | } 651 | 652 | .markdown-section .column { 653 | float: left; 654 | padding-right: 1rem; 655 | width: 50%; 656 | } 657 | 658 | .markdown-section .column-right { 659 | float: right; 660 | padding-left: 1rem; 661 | width: 50%; 662 | } 663 | 664 | .markdown-section .column img { 665 | margin-top: 0.35rem; 666 | } 667 | 668 | .markdown-section .column-right img { 669 | margin-top: 0.35rem; 670 | } 671 | 672 | .markdown-section .reverse-columns .column { 673 | float: right; 674 | } 675 | 676 | .markdown-section .row:after { 677 | content: ""; 678 | display: table; 679 | clear: both; 680 | } 681 | 682 | /* Hide empty rows in responsive tables */ 683 | @media (max-width: 30em) { 684 | .markdown-section .table-wrapper td:empty::before { 685 | display: none; 686 | } 687 | } 688 | 689 | /* Left align rows in responsive tables */ 690 | @media (max-width: 30em) { 691 | .markdown-section .table-wrapper tbody td { 692 | text-align: left !important; 693 | } 694 | } 695 | 696 | @media screen and (max-width: 800px) { 697 | .markdown-section .column, 698 | .markdown-section .column-right { 699 | width: 100%; 700 | padding-right: 0rem; 701 | padding-left: 0rem; 702 | } 703 | 704 | .markdown-section .image-75, 705 | .markdown-section .image-50, 706 | .markdown-section .image-25, 707 | .markdown-section .image-75-border, 708 | .markdown-section .image-50-border, 709 | .markdown-section .image-25-border { 710 | width: 100%; 711 | height: auto; 712 | } 713 | } 714 | 715 | /* CSS generated/assisted by Anthropic Claude AI */ 716 | .markdown-section .card-list { 717 | display: grid; 718 | grid-template-columns: repeat(2, 1fr); 719 | gap: 2rem; 720 | margin-top: 2rem; 721 | } 722 | 723 | .markdown-section .card:not(.card-list .card), 724 | .markdown-section .card-rounded:not(.card-list .card-rounded) { 725 | margin-top: 2rem; 726 | } 727 | 728 | .markdown-section .card, 729 | .markdown-section .card-rounded { 730 | border: 1px solid var(--mono-tint2); 731 | padding: 1rem; 732 | display: flex; 733 | flex-direction: column; 734 | overflow: hidden; /* This ensures images respect border-radius */ 735 | } 736 | 737 | .markdown-section .card-rounded { 738 | border-radius: 0.35em; 739 | } 740 | 741 | .markdown-section .card h2, 742 | .markdown-section .card-rounded h2 { 743 | margin: 0 0 .1rem 0; 744 | padding-bottom: .5rem; 745 | font-size: 1.3rem; 746 | } 747 | 748 | /* Adjust space above and below h2 that follows edge-to-edge images */ 749 | .markdown-section .card p:has(img):first-child + h2, 750 | .markdown-section .card-rounded p:has(img):first-child + h2 { 751 | margin-top: 1rem; 752 | padding-bottom: .25rem; 753 | } 754 | 755 | /* All images have normal padding by default */ 756 | .markdown-section .card p:has(img), 757 | .markdown-section .card-rounded p:has(img) { 758 | margin: 0; 759 | } 760 | 761 | /* First images extend to card edges */ 762 | .markdown-section .card p:has(img):first-child, 763 | .markdown-section .card-rounded p:has(img):first-child { 764 | margin: -1.6rem -1.5rem -1rem -1.5rem; 765 | } 766 | 767 | .markdown-section .card img, 768 | .markdown-section .card-rounded img { 769 | width: 100%; 770 | height: 240px; 771 | object-fit: cover; 772 | } 773 | 774 | .markdown-section .card p, 775 | .markdown-section .card-rounded p { 776 | flex-grow: 1; 777 | margin-bottom: .1rem; 778 | } 779 | 780 | /* Mobile */ 781 | @media screen and (max-width: 768px) { 782 | .markdown-section .card-list { 783 | grid-template-columns: 1fr; 784 | gap: 1.5rem; 785 | } 786 | 787 | .markdown-section .card, 788 | .markdown-section .card-rounded { 789 | padding: 1.25rem; 790 | } 791 | 792 | .markdown-section .card img, 793 | .markdown-section .card-rounded img { 794 | height: 200px; 795 | } 796 | 797 | .markdown-section .card p:has(img):first-child, 798 | .markdown-section .card-rounded p:has(img):first-child { 799 | margin: -1.35rem -1.25rem -0.75rem -1.25rem; 800 | } 801 | } 802 | 803 | .markdown-section figure, 804 | .markdown-section p, 805 | .markdown-section ol, 806 | .markdown-section ul { 807 | margin: 1em 0em 0.5em 0em; 808 | } 809 | 810 | .markdown-section h1 { 811 | line-height: 1.9rem; 812 | } 813 | 814 | .markdown-section h2 { 815 | line-height: 1.7rem; 816 | } 817 | 818 | .markdown-section h3 { 819 | line-height: 1.5rem; 820 | } 821 | 822 | .markdown-section h4 { 823 | line-height: 1.45rem; 824 | } 825 | 826 | .markdown-section h5 { 827 | line-height: 1.4rem; 828 | } 829 | 830 | .markdown-section h6 { 831 | line-height: 1.3rem; 832 | } 833 | 834 | .markdown-section .alert hr, 835 | .markdown-section blockquote hr { 836 | margin: 1em 0; 837 | } 838 | 839 | .markdown-section .alert h1, 840 | .markdown-section blockquote h1 { 841 | font-size: 1.5rem; 842 | line-height: 1.6rem; 843 | } 844 | 845 | .markdown-section .alert h2, 846 | .markdown-section blockquote h2 { 847 | font-size: 1.35rem; 848 | line-height: 1.5rem; 849 | } 850 | 851 | .markdown-section .alert h3, 852 | .markdown-section blockquote h3 { 853 | font-size: 1.2rem; 854 | line-height: 1.35rem; 855 | } 856 | 857 | .markdown-section .alert h4, 858 | .markdown-section blockquote h4 { 859 | font-size: 1.15rem; 860 | line-height: 1.3rem; 861 | } 862 | 863 | .markdown-section .alert h5, 864 | .markdown-section blockquote h5 { 865 | font-size: 1.1rem; 866 | line-height: 1.25rem; 867 | } 868 | 869 | .markdown-section .alert h6, 870 | .markdown-section blockquote h6 { 871 | font-size: 1rem; 872 | line-height: 1.15rem; 873 | } 874 | 875 | .markdown-section .edit-link { 876 | display: inline-flex; 877 | align-items: center; 878 | } 879 | 880 | .markdown-section .edit-link .emoji { 881 | margin-right: 2px; 882 | } 883 | 884 | body .app-nav { 885 | margin-right: -10px; 886 | } 887 | 888 | body .docsify-pagination-container { 889 | display: flex; 890 | flex-wrap: wrap; 891 | justify-content: space-between; 892 | overflow: hidden; 893 | margin: 3em 0 1em; 894 | border-top: 0px solid rgba(0, 0, 0, 0.07); 895 | } 896 | 897 | @media only screen and (max-width: 480px) { 898 | .markdown-section h1 { 899 | font-size: 1.45rem; 900 | line-height: 1.75rem; 901 | } 902 | 903 | .markdown-section h2 { 904 | font-size: 1.35rem; 905 | line-height: 1.65rem; 906 | } 907 | 908 | .markdown-section h3 { 909 | font-size: 1.25rem; 910 | line-height: 1.55rem; 911 | } 912 | 913 | .markdown-section h4 { 914 | font-size: 1.15rem; 915 | line-height: 1.45rem; 916 | } 917 | 918 | .markdown-section h5 { 919 | font-size: 1.1rem; 920 | line-height: 1.4rem; 921 | } 922 | 923 | .markdown-section h6 { 924 | font-size: 1rem; 925 | line-height: 1.3rem; 926 | } 927 | 928 | .markdown-section .alert h1, 929 | .markdown-section blockquote h1 { 930 | font-size: 1.3rem; 931 | line-height: 1.4rem; 932 | } 933 | 934 | .markdown-section .alert h2, 935 | .markdown-section blockquote h2 { 936 | font-size: 1.2rem; 937 | line-height: 1.35rem; 938 | } 939 | 940 | .markdown-section .alert h3, 941 | .markdown-section blockquote h3 { 942 | font-size: 1.15rem; 943 | line-height: 1.3rem; 944 | } 945 | 946 | .markdown-section .alert h4, 947 | .markdown-section blockquote h4 { 948 | font-size: 1.1rem; 949 | line-height: 1.25rem; 950 | } 951 | 952 | .markdown-section .alert h5, 953 | .markdown-section blockquote h5 { 954 | font-size: 1.05rem; 955 | line-height: 1.20rem; 956 | } 957 | 958 | .markdown-section .alert h6, 959 | .markdown-section blockquote h6 { 960 | font-size: 1rem; 961 | line-height: 1.15rem; 962 | } 963 | } 964 | 965 | /* Dark mode colours for use with Simple light + dark theme (uncomment to use) */ 966 | @media (prefers-color-scheme: dark) { 967 | /* 968 | :root { 969 | --link-color: #1BA1EE!important; 970 | 971 | --sidebar-name-color: #1BA1EE!important; 972 | --sidebar-nav-link-color--active: #1BA1EE!important; 973 | --sidebar-nav-link-border-color--active: #1BA1EE!important; 974 | 975 | --sidebar-nav-pagelink-background--active: 976 | no-repeat 0px center / 5px 6px 977 | linear-gradient(225deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px), 978 | no-repeat 5px center / 5px 6px 979 | linear-gradient(135deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px)!important; 980 | --sidebar-nav-pagelink-background--collapse: 981 | no-repeat 2px calc(50% - 2.5px) / 6px 5px 982 | linear-gradient(45deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4px), 983 | no-repeat 2px calc(50% + 2.5px) / 6px 5px 984 | linear-gradient(135deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4px)!important; 985 | --sidebar-nav-pagelink-background--loaded: 986 | no-repeat 0px center / 5px 6px 987 | linear-gradient(225deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px), 988 | no-repeat 5px center / 5px 6px 989 | linear-gradient(135deg, transparent 2.75px, #1BA1EE 2.75px 4.25px, transparent 4.25px)!important; 990 | 991 | --navbar-root-color--active: #1BA1EE!important; 992 | --navbar-root-color--active: #1BA1EE!important; 993 | 994 | --blockquote-border-color: #1BA1EE!important; 995 | 996 | --pagination-title-color: #1BA1EE!important; 997 | } 998 | } 999 | */ -------------------------------------------------------------------------------- /docs/assets/vendor/docsify/plugins/search.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | /** 4 | * Converts a colon formatted string to a object with properties. 5 | * 6 | * This is process a provided string and look for any tokens in the format 7 | * of `:name[=value]` and then convert it to a object and return. 8 | * An example of this is ':include :type=code :fragment=demo' is taken and 9 | * then converted to: 10 | * 11 | * ``` 12 | * { 13 | * include: '', 14 | * type: 'code', 15 | * fragment: 'demo' 16 | * } 17 | * ``` 18 | * 19 | * @param {string} str The string to parse. 20 | * 21 | * @return {{str: string, config: object}} The original string formatted, and parsed object, { str, config }. 22 | */ 23 | function getAndRemoveConfig(str = '') { 24 | const config = {}; 25 | 26 | if (str) { 27 | str = str 28 | .replace(/^('|")/, '') 29 | .replace(/('|")$/, '') 30 | .replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g, (m, key, value) => { 31 | if (key.indexOf(':') === -1) { 32 | config[key] = (value && value.replace(/"/g, '')) || true; 33 | return ''; 34 | } 35 | 36 | return m; 37 | }) 38 | .trim(); 39 | } 40 | 41 | return { str, config }; 42 | } 43 | 44 | /** 45 | * Remove the docsifyIgnore configs and return the str 46 | * @param {string} content The string to deal with. 47 | * 48 | * @return {{content: string, ignoreAllSubs: boolean, ignoreSubHeading: boolean}} The string after delete the docsifyIgnore configs, and whether to ignore some or all. 49 | */ 50 | function getAndRemoveDocisfyIgnoreConfig(content = '') { 51 | let ignoreAllSubs, ignoreSubHeading; 52 | if (//g.test(content)) { 53 | content = content.replace('', ''); 54 | ignoreSubHeading = true; 55 | } 56 | 57 | if (/{docsify-ignore}/g.test(content)) { 58 | content = content.replace('{docsify-ignore}', ''); 59 | ignoreSubHeading = true; 60 | } 61 | 62 | if (//g.test(content)) { 63 | content = content.replace('', ''); 64 | ignoreAllSubs = true; 65 | } 66 | 67 | if (/{docsify-ignore-all}/g.test(content)) { 68 | content = content.replace('{docsify-ignore-all}', ''); 69 | ignoreAllSubs = true; 70 | } 71 | 72 | return { content, ignoreAllSubs, ignoreSubHeading }; 73 | } 74 | 75 | /* eslint-disable no-unused-vars */ 76 | 77 | let INDEXS = {}; 78 | 79 | const LOCAL_STORAGE = { 80 | EXPIRE_KEY: 'docsify.search.expires', 81 | INDEX_KEY: 'docsify.search.index', 82 | }; 83 | 84 | function resolveExpireKey(namespace) { 85 | return namespace 86 | ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` 87 | : LOCAL_STORAGE.EXPIRE_KEY; 88 | } 89 | 90 | function resolveIndexKey(namespace) { 91 | return namespace 92 | ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` 93 | : LOCAL_STORAGE.INDEX_KEY; 94 | } 95 | 96 | function escapeHtml(string) { 97 | const entityMap = { 98 | '&': '&', 99 | '<': '<', 100 | '>': '>', 101 | '"': '"', 102 | "'": ''', 103 | }; 104 | 105 | return String(string).replace(/[&<>"']/g, s => entityMap[s]); 106 | } 107 | 108 | function getAllPaths(router) { 109 | const paths = []; 110 | 111 | Docsify.dom 112 | .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])') 113 | .forEach(node => { 114 | const href = node.href; 115 | const originHref = node.getAttribute('href'); 116 | const path = router.parse(href).path; 117 | 118 | if ( 119 | path && 120 | paths.indexOf(path) === -1 && 121 | !Docsify.util.isAbsolutePath(originHref) 122 | ) { 123 | paths.push(path); 124 | } 125 | }); 126 | 127 | return paths; 128 | } 129 | 130 | function getTableData(token) { 131 | if (!token.text && token.type === 'table') { 132 | token.rows.unshift(token.header); 133 | token.text = token.rows 134 | .map(columns => columns.map(r => r.text).join(' | ')) 135 | .join(' |\n '); 136 | } 137 | return token.text; 138 | } 139 | 140 | function getListData(token) { 141 | if (!token.text && token.type === 'list') { 142 | token.text = token.raw; 143 | } 144 | return token.text; 145 | } 146 | 147 | function saveData(maxAge, expireKey, indexKey) { 148 | localStorage.setItem(expireKey, Date.now() + maxAge); 149 | localStorage.setItem(indexKey, JSON.stringify(INDEXS)); 150 | } 151 | 152 | function genIndex(path, content = '', router, depth) { 153 | const tokens = window.marked.lexer(content); 154 | const slugify = window.Docsify.slugify; 155 | const index = {}; 156 | let slug; 157 | let title = ''; 158 | 159 | tokens.forEach((token, tokenIndex) => { 160 | if (token.type === 'heading' && token.depth <= depth) { 161 | const { str, config } = getAndRemoveConfig(token.text); 162 | 163 | const text = getAndRemoveDocisfyIgnoreConfig(token.text).content; 164 | 165 | // Extract title from Markdown link 166 | const match = text.match(/\[(.*?)\]\((.*?)\)/); 167 | let title = match ? match[1] : text; 168 | if (config.id) { 169 | slug = router.toURL(path, { id: slugify(config.id) }); 170 | } else { 171 | // Sanitize title for ID only if using title for the slug 172 | slug = router.toURL(path, { 173 | id: slugify(title) 174 | .replace(/\//g, '') // Remove slashes 175 | .replace(/\?/g, '') // Remove question marks 176 | .replace(/[^a-zA-Z0-9-]/g, '-') // Replace other non-alphanumeric 177 | .replace(/^\(|\)$/g, '') // Remove parentheses 178 | .replace(/['"]/g, '') // Remove straight quotes 179 | .replace(/[\u2018\u2019\u201C\u201D]/g, '') // Remove curved quotes 180 | .replace(/^-/, '_') // Remove leading hyphen with underscore 181 | .toLowerCase() 182 | }); 183 | } 184 | 185 | if (str) { 186 | title = getAndRemoveDocisfyIgnoreConfig(str).content; 187 | } 188 | 189 | index[slug] = { slug, title: title, body: '' }; 190 | } else { 191 | if (tokenIndex === 0) { 192 | slug = router.toURL(path); 193 | index[slug] = { 194 | slug, 195 | title: path !== '/' ? path.slice(1) : 'Home Page', 196 | body: token.text || '', 197 | }; 198 | } 199 | 200 | if (!slug) { 201 | return; 202 | } 203 | 204 | if (!index[slug]) { 205 | index[slug] = { slug, title: '', body: '' }; 206 | } else if (index[slug].body) { 207 | token.text = getTableData(token); 208 | token.text = getListData(token); 209 | 210 | index[slug].body += '\n' + (token.text || ''); 211 | } else { 212 | token.text = getTableData(token); 213 | token.text = getListData(token); 214 | 215 | index[slug].body = token.text || ''; 216 | } 217 | } 218 | }); 219 | slugify.clear(); 220 | return index; 221 | } 222 | 223 | function ignoreDiacriticalMarks(keyword) { 224 | if (keyword && keyword.normalize) { 225 | return keyword.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); 226 | } 227 | return keyword; 228 | } 229 | 230 | // Function to convert string to title case and replace hyphens with spaces 231 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 232 | function convertToTitle(str) { 233 | return str 234 | .split('-') // Split the string by hyphens 235 | .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize the first letter and lower case the rest 236 | .join(' '); // Join the words with spaces 237 | } 238 | 239 | // Function to strip common Markdown markup 240 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 241 | function stripCommonMarkdown(markdown) { 242 | // Regular expressions for common Markdown elements 243 | const regexes = [ 244 | { pattern: /(\*\*|__)(.*?)\1/g, replacement: '$2' }, // Bold: **text** or __text__ 245 | { pattern: /(\*|_)(.*?)\1/g, replacement: '$2' }, // Italic: *text* or _text_ 246 | { pattern: /[-+*]\s+(.*?)/g, replacement: '$1' }, // Unordered lists: - item, + item, * item 247 | { pattern: /\d+\.\s+(.*?)/g, replacement: '$1' }, // Ordered lists: 1. item 248 | { pattern: /^#{1,6}\s+(.*)/gm, replacement: '$1' } // Headers: # Header, ## Header, etc. 249 | ]; 250 | 251 | // Apply all regular expressions to the input text 252 | let plainText = markdown; 253 | regexes.forEach(({ pattern, replacement }) => { 254 | plainText = plainText.replace(pattern, replacement); 255 | }); 256 | 257 | // Trim leading/trailing whitespace and return 258 | return plainText.trim(); 259 | } 260 | 261 | // Function to replace Markdown links with their titles and remove Markdown images 262 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 263 | function replaceMarkdownLinksWithTitlesandRemoveImages(content) { 264 | // Regular expression to match both Markdown images and links 265 | // Capture images separately to identify and remove them 266 | const markdownLinkRegex = /(!?\[([^\]]+)\]\(([^)]+)\))/g; 267 | 268 | return content.replace(markdownLinkRegex, (match, fullMatch, title, url) => { 269 | // Check if it's an image link by the presence of '!' at the start 270 | if (fullMatch.startsWith('!')) { 271 | // Return an empty string to remove the image 272 | return ''; 273 | } 274 | // Otherwise, replace the link with its title 275 | return title; 276 | }); 277 | } 278 | 279 | // Function to strip all HTML tags from a string 280 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 281 | function stripHtmlTags(content) { 282 | // Regular expression to match HTML tags 283 | const htmlTagRegex = /<[^>]*>/g; 284 | 285 | // Replace all HTML tags with an empty string 286 | return content.replace(htmlTagRegex, ''); 287 | } 288 | 289 | /** 290 | * @param {String} query Search query 291 | * @returns {Array} Array of results 292 | */ 293 | function search(query) { 294 | const matchingResults = []; 295 | let data = []; 296 | Object.keys(INDEXS).forEach(key => { 297 | data = [ 298 | ...data, 299 | ...Object.keys(INDEXS[key]).map(page => INDEXS[key][page]), 300 | ]; 301 | }); 302 | 303 | query = query.trim(); 304 | let keywords = query.split(/[\s\-,\\/]+/); 305 | if (keywords.length !== 1) { 306 | keywords = [query, ...keywords]; 307 | } 308 | 309 | for (const post of data) { 310 | let matchesScore = 0; 311 | let resultStr = ''; 312 | let handlePostTitle = ''; 313 | let handlePostContent = ''; 314 | const postTitle = post.title && post.title.trim(); 315 | const postContent = stripHtmlTags(stripCommonMarkdown(replaceMarkdownLinksWithTitlesandRemoveImages(post.body && post.body.trim()))); 316 | const postUrl = post.slug || ''; 317 | const postPageSlug = postUrl.split('/')[1].split('?')[0].replace('0', ''); 318 | const postPageTitle = convertToTitle(postPageSlug); 319 | 320 | // Skip posts that contain iframes, Font Awesome icons, or embedly cards 321 | // console.log(postContent); 322 | // const isImage = /!\[[^\]]*\]\([^)]*\)/g.test(postContent); // Check if it's a Markdown image 323 | 324 | if (postContent.includes('iframe') || postContent.includes(':fas') || postContent.includes(':fab') || postContent.includes('embedly-card')) { 325 | continue; 326 | } 327 | 328 | if (postTitle) { 329 | keywords.forEach(keyword => { 330 | // From https://github.com/sindresorhus/escape-string-regexp 331 | const regEx = new RegExp( 332 | escapeHtml(ignoreDiacriticalMarks(keyword)).replace( 333 | /[|\\{}()[\]^$+*?.]/g, 334 | '\\$&' 335 | ), 336 | 'gi' 337 | ); 338 | let indexTitle = -1; 339 | let indexContent = -1; 340 | handlePostTitle = postTitle 341 | ? escapeHtml(ignoreDiacriticalMarks(postTitle)) 342 | : postTitle; 343 | 344 | // Remove Markdown link syntax from title 345 | handlePostTitle = handlePostTitle.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1').trim(); 346 | 347 | handlePostContent = postContent 348 | ? escapeHtml(ignoreDiacriticalMarks(postContent)) 349 | : postContent; 350 | 351 | indexTitle = postTitle ? handlePostTitle.search(regEx) : -1; 352 | indexContent = postContent ? handlePostContent.search(regEx) : -1; 353 | 354 | if (indexTitle >= 0 || indexContent >= 0) { 355 | matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0; 356 | if (indexContent < 0) { 357 | indexContent = 0; 358 | } 359 | 360 | let start = 0; 361 | let end = 0; 362 | 363 | start = indexContent < 11 ? 0 : indexContent - 10; 364 | end = start === 0 ? 70 : indexContent + keyword.length + 60; 365 | 366 | if (postContent && end > postContent.length) { 367 | end = postContent.length; 368 | } 369 | 370 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 371 | const matchContent = handlePostContent && (() => { 372 | // Extract the substring where the match will be applied 373 | const contentSegment = handlePostContent.substring(start, end); 374 | 375 | // Find the first occurrence of the word using the regular expression 376 | const match = contentSegment.match(regEx); 377 | 378 | if (match) { 379 | // Get the position of the first match 380 | const matchIndex = contentSegment.indexOf(match[0]); 381 | 382 | // Split the content segment into before, match, and after parts 383 | const beforeMatch = contentSegment.substring(0, matchIndex); 384 | const firstMatch = contentSegment.substring(matchIndex, matchIndex + match[0].length); 385 | const afterMatch = contentSegment.substring(matchIndex + match[0].length); 386 | 387 | // Return the reassembled string with the first match wrapped in tags 388 | return '...' + 389 | beforeMatch + 390 | `${firstMatch}` + 391 | afterMatch + 392 | '...'; 393 | } 394 | 395 | // If no match is found, return the original segment surrounded by ellipses 396 | return '...' + contentSegment + '...'; 397 | })(); 398 | 399 | resultStr += matchContent; 400 | } 401 | }); 402 | 403 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 404 | // Only prepend postPageTitle when it is not empty and not equal to handlePostTitle (case insensitive) 405 | if (matchesScore > 0) { 406 | const matchingPost = { 407 | title: handlePostTitle, 408 | content: ( 409 | // Convert both postPageTitle and handlePostTitle to lowercase for case-insensitive comparison 410 | postPageTitle && 411 | postPageTitle.toLowerCase() !== handlePostTitle.toLowerCase() && 412 | postPageTitle.toLowerCase() !== 'readme' // Exclude 'ReadMe' from being prepended 413 | ? `${postPageTitle}
` 414 | : '' 415 | ) + (postContent ? resultStr : ''), 416 | url: postUrl, 417 | score: matchesScore, 418 | }; 419 | 420 | matchingResults.push(matchingPost); 421 | } 422 | } 423 | } 424 | 425 | const uniquePageTitles = new Set(); 426 | matchingResults.forEach(result => { 427 | const contentMatch = result.content.match(/^(.*?)<\/strong>
/); 428 | if (contentMatch) { 429 | uniquePageTitles.add(contentMatch[1]); 430 | } 431 | }); 432 | 433 | // If all results share the same postPageTitle, remove it from display 434 | if (uniquePageTitles.size === 1) { 435 | const sharedPageTitle = [...uniquePageTitles][0]; // Extract the single title 436 | matchingResults.forEach(result => { 437 | // Ensure we only remove the correct title, avoiding partial removals 438 | result.content = result.content.replace(new RegExp(`^${sharedPageTitle}
`, 'i'), ''); 439 | }); 440 | } 441 | 442 | return matchingResults.sort((r1, r2) => r2.score - r1.score); 443 | } 444 | 445 | // This code was developed with the assistance of ChatGPT, an AI language model by OpenAI 446 | function init$1(config, vm) { 447 | const isAuto = config.paths === 'auto'; 448 | const paths = isAuto ? getAllPaths(vm.router) : config.paths; 449 | 450 | let namespaceSuffix = ''; 451 | 452 | // only in auto mode 453 | if (paths.length && isAuto && config.pathNamespaces) { 454 | const path = paths[0]; 455 | 456 | if (Array.isArray(config.pathNamespaces)) { 457 | namespaceSuffix = 458 | config.pathNamespaces.filter( 459 | prefix => path.slice(0, prefix.length) === prefix 460 | )[0] || namespaceSuffix; 461 | } else if (config.pathNamespaces instanceof RegExp) { 462 | const matches = path.match(config.pathNamespaces); 463 | 464 | if (matches) { 465 | namespaceSuffix = matches[0]; 466 | } 467 | } 468 | const isExistHome = paths.indexOf(namespaceSuffix + '/') === -1; 469 | const isExistReadme = paths.indexOf(namespaceSuffix + '/README') === -1; 470 | if (isExistHome && isExistReadme) { 471 | paths.unshift(namespaceSuffix + '/'); 472 | } 473 | } else if (paths.indexOf('/') === -1 && paths.indexOf('/README') === -1) { 474 | paths.unshift('/'); 475 | } 476 | 477 | const expireKey = resolveExpireKey(config.namespace) + namespaceSuffix; 478 | const indexKey = resolveIndexKey(config.namespace) + namespaceSuffix; 479 | 480 | // Check if the database is expired 481 | const isExpired = localStorage.getItem(expireKey) < Date.now(); 482 | 483 | if (isExpired) { 484 | // If expired, clear the existing database 485 | localStorage.removeItem(expireKey); 486 | localStorage.removeItem(indexKey); 487 | // console.log('Existing database expired and deleted.'); 488 | } else { 489 | // console.log('Database is not expired, but it will still be reset.'); 490 | } 491 | 492 | // Clear the database every load regardless of expiration 493 | localStorage.removeItem(expireKey); 494 | localStorage.removeItem(indexKey); 495 | // console.log('Existing database cleared.'); 496 | 497 | // Initialize INDEXS to an empty object 498 | INDEXS = {}; 499 | 500 | const len = paths.length; 501 | let count = 0; 502 | 503 | paths.forEach(path => { 504 | if (INDEXS[path]) { 505 | return count++; 506 | } 507 | 508 | Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then( 509 | result => { 510 | INDEXS[path] = genIndex(path, result, vm.router, config.depth); 511 | len === ++count && saveData(config.maxAge, expireKey, indexKey); 512 | } 513 | ); 514 | }); 515 | } 516 | 517 | /* eslint-disable no-unused-vars */ 518 | 519 | let NO_DATA_TEXT = ''; 520 | let options; 521 | 522 | function style() { 523 | const code = ` 524 | .sidebar { 525 | padding-top: 0; 526 | } 527 | 528 | .search { 529 | margin-bottom: 20px; 530 | padding: 6px; 531 | border-bottom: 1px solid #eee; 532 | } 533 | 534 | .search .input-wrap { 535 | display: flex; 536 | align-items: center; 537 | } 538 | 539 | .search .results-status:not(:empty) { 540 | margin-top: 10px; 541 | font-size: smaller; 542 | } 543 | 544 | .search .results-panel { 545 | display: none; 546 | } 547 | 548 | .search .results-panel.show { 549 | display: block; 550 | } 551 | 552 | .search input { 553 | outline: none; 554 | border: none; 555 | width: 100%; 556 | padding: 0.6em 7px; 557 | font-size: inherit; 558 | border: 1px solid transparent; 559 | } 560 | 561 | .search input:focus { 562 | box-shadow: 0 0 5px var(--theme-color, #42b983); 563 | border: 1px solid var(--theme-color, #42b983); 564 | } 565 | 566 | .search input::-webkit-search-decoration, 567 | .search input::-webkit-search-cancel-button, 568 | .search input { 569 | -webkit-appearance: none; 570 | -moz-appearance: none; 571 | appearance: none; 572 | } 573 | 574 | .search input::-ms-clear { 575 | display: none; 576 | height: 0; 577 | width: 0; 578 | } 579 | 580 | .search .clear-button { 581 | cursor: pointer; 582 | width: 36px; 583 | text-align: right; 584 | display: none; 585 | } 586 | 587 | .search .clear-button.show { 588 | display: block; 589 | } 590 | 591 | .search .clear-button svg { 592 | transform: scale(.5); 593 | } 594 | 595 | .search kbd { 596 | position: absolute; 597 | right: 8px; 598 | margin: 0; 599 | } 600 | 601 | .search input:focus ~ kbd, 602 | .search input:not(:empty) ~ kbd { 603 | display: none; 604 | } 605 | 606 | .search h2 { 607 | font-size: 17px; 608 | margin: 10px 0; 609 | } 610 | 611 | .search a { 612 | text-decoration: none; 613 | color: inherit; 614 | } 615 | 616 | .search .matching-post { 617 | border-bottom: 1px solid #eee; 618 | } 619 | 620 | .search .matching-post:last-child { 621 | border-bottom: 0; 622 | } 623 | 624 | .search p { 625 | font-size: 14px; 626 | overflow: hidden; 627 | text-overflow: ellipsis; 628 | display: -webkit-box; 629 | -webkit-line-clamp: 2; 630 | -webkit-box-orient: vertical; 631 | } 632 | 633 | .search p.empty { 634 | text-align: center; 635 | } 636 | 637 | .sidebar-nav.hide { 638 | display: none; 639 | }`; 640 | 641 | Docsify.dom.style(code); 642 | } 643 | 644 | function tpl(defaultValue = '') { 645 | const html = /* html */ ` 646 |
647 | 648 |
649 | 650 | 651 | 652 | 653 | 654 |
655 | / 656 |
657 |
658 |
659 | `; 660 | const el = Docsify.dom.create('div', html); 661 | const aside = Docsify.dom.find('aside'); 662 | 663 | Docsify.dom.toggleClass(el, 'search'); 664 | el.setAttribute('role', 'search'); 665 | Docsify.dom.before(aside, el); 666 | } 667 | 668 | function doSearch(value) { 669 | const $search = Docsify.dom.find('div.search'); 670 | const $panel = Docsify.dom.find($search, '.results-panel'); 671 | const $clearBtn = Docsify.dom.find($search, '.clear-button'); 672 | const $sidebarNav = Docsify.dom.find('.sidebar-nav'); 673 | const $status = Docsify.dom.find('div.search .results-status'); 674 | 675 | if (!value) { 676 | $panel.classList.remove('show'); 677 | $clearBtn.classList.remove('show'); 678 | $panel.innerHTML = ''; 679 | $status.textContent = ''; 680 | 681 | if (options.hideOtherSidebarContent) { 682 | $sidebarNav && $sidebarNav.classList.remove('hide'); 683 | } 684 | 685 | return; 686 | } 687 | 688 | const matches = search(value); 689 | 690 | let html = ''; 691 | matches.forEach((post, i) => { 692 | html += /* html */ ` 693 |
694 | 695 |

${post.title}

696 |

${post.content}

697 |
698 |
699 | `; 700 | }); 701 | 702 | $panel.classList.add('show'); 703 | $clearBtn.classList.add('show'); 704 | $panel.innerHTML = html || /* html */ `

${NO_DATA_TEXT}

`; 705 | $status.textContent = `Found ${matches.length} results`; 706 | 707 | if (options.hideOtherSidebarContent) { 708 | $sidebarNav && $sidebarNav.classList.add('hide'); 709 | } 710 | } 711 | 712 | function bindEvents() { 713 | const $search = Docsify.dom.find('div.search'); 714 | const $input = Docsify.dom.find($search, 'input'); 715 | const $inputWrap = Docsify.dom.find($search, '.input-wrap'); 716 | 717 | let timeId; 718 | 719 | /** 720 | Prevent to Fold sidebar. 721 | 722 | When searching on the mobile end, 723 | the sidebar is collapsed when you click the INPUT box, 724 | making it impossible to search. 725 | */ 726 | Docsify.dom.on( 727 | $search, 728 | 'click', 729 | e => 730 | ['A', 'H2', 'P', 'EM'].indexOf(e.target.tagName) === -1 && 731 | e.stopPropagation() 732 | ); 733 | Docsify.dom.on($input, 'input', e => { 734 | clearTimeout(timeId); 735 | timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100); 736 | }); 737 | Docsify.dom.on($inputWrap, 'click', e => { 738 | // Click input outside 739 | if (e.target.tagName !== 'INPUT') { 740 | $input.value = ''; 741 | doSearch(); 742 | } 743 | }); 744 | } 745 | 746 | function updatePlaceholder(text, path) { 747 | const $input = Docsify.dom.getNode('.search input[type="search"]'); 748 | 749 | if (!$input) { 750 | return; 751 | } 752 | 753 | if (typeof text === 'string') { 754 | $input.placeholder = text; 755 | } else { 756 | const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]; 757 | $input.placeholder = text[match]; 758 | } 759 | } 760 | 761 | function updateNoData(text, path) { 762 | if (typeof text === 'string') { 763 | NO_DATA_TEXT = text; 764 | } else { 765 | const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]; 766 | NO_DATA_TEXT = text[match]; 767 | } 768 | } 769 | 770 | function updateOptions(opts) { 771 | options = opts; 772 | } 773 | 774 | function init(opts, vm) { 775 | const keywords = vm.router.parse().query.s; 776 | 777 | updateOptions(opts); 778 | style(); 779 | tpl(keywords); 780 | bindEvents(); 781 | keywords && setTimeout(_ => doSearch(keywords), 500); 782 | } 783 | 784 | function update(opts, vm) { 785 | updateOptions(opts); 786 | updatePlaceholder(opts.placeholder, vm.route.path); 787 | updateNoData(opts.noData, vm.route.path); 788 | } 789 | 790 | /* eslint-disable no-unused-vars */ 791 | 792 | const CONFIG = { 793 | placeholder: 'Type to search', 794 | noData: 'No matches found.', 795 | paths: 'auto', 796 | depth: 2, 797 | maxAge: 86400000, // 1 day 798 | hideOtherSidebarContent: false, 799 | namespace: undefined, 800 | pathNamespaces: undefined, 801 | keyBindings: ['/', 'meta+k', 'ctrl+k'], 802 | }; 803 | 804 | const install = function (hook, vm) { 805 | const { util } = Docsify; 806 | const opts = vm.config.search || CONFIG; 807 | 808 | if (Array.isArray(opts)) { 809 | CONFIG.paths = opts; 810 | } else if (typeof opts === 'object') { 811 | CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto'; 812 | CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge; 813 | CONFIG.placeholder = opts.placeholder || CONFIG.placeholder; 814 | CONFIG.noData = opts.noData || CONFIG.noData; 815 | CONFIG.depth = opts.depth || CONFIG.depth; 816 | CONFIG.hideOtherSidebarContent = 817 | opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent; 818 | CONFIG.namespace = opts.namespace || CONFIG.namespace; 819 | CONFIG.pathNamespaces = opts.pathNamespaces || CONFIG.pathNamespaces; 820 | CONFIG.keyBindings = opts.keyBindings || CONFIG.keyBindings; 821 | } 822 | 823 | const isAuto = CONFIG.paths === 'auto'; 824 | 825 | hook.init(() => { 826 | const { keyBindings } = vm.config; 827 | 828 | // Add key bindings 829 | if (keyBindings.constructor === Object) { 830 | keyBindings.focusSearch = { 831 | bindings: CONFIG.keyBindings, 832 | callback(e) { 833 | const sidebarElm = document.querySelector('.sidebar'); 834 | const sidebarToggleElm = document.querySelector('.sidebar-toggle'); 835 | const searchElm = sidebarElm?.querySelector('input[type="search"]'); 836 | const isSidebarHidden = sidebarElm?.getBoundingClientRect().x < 0; 837 | 838 | isSidebarHidden && sidebarToggleElm?.click(); 839 | 840 | setTimeout(() => searchElm?.focus(), isSidebarHidden ? 250 : 0); 841 | }, 842 | }; 843 | } 844 | }); 845 | hook.mounted(_ => { 846 | init(CONFIG, vm); 847 | !isAuto && init$1(CONFIG, vm); 848 | }); 849 | hook.doneEach(_ => { 850 | update(CONFIG, vm); 851 | isAuto && init$1(CONFIG, vm); 852 | }); 853 | }; 854 | 855 | window.$docsify = window.$docsify || {}; 856 | $docsify.plugins = [install, ...($docsify.plugins || [])]; 857 | 858 | })(); 859 | --------------------------------------------------------------------------------