From ef96e25098ddef5d724d3a041689290c38f3ef55 Mon Sep 17 00:00:00 2001 From: OlivierHnt <38465572+OlivierHnt@users.noreply.github.com> Date: Wed, 10 Apr 2024 11:18:29 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20=20@=2030275?= =?UTF-8?q?ad1f3b2149ef61efc7da47cc18f566be63c=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 2 - .gitignore | 10 - .vscode/extensions.json | 14 - .vscode/settings.json | 22 - .vscode/tasks.json | 13 - Dockerfile | 29 - LICENSE.md | 14 - PlutoPages.jl | 1040 ----------------- Procfile | 1 - README.md | 7 - Website maintenance.md | 104 -- {src/assets => assets}/favicon.svg | 0 {src/assets => assets}/homepage/bg.svg | 0 {src/assets => assets}/homepage/swoosh.png | Bin {src/assets => assets}/julia-logo-color.svg | 0 {src/assets => assets}/julia-logo-dark.svg | 0 assets/scripts/get_highlights/index.html | 26 + assets/scripts/get_subjects/index.html | 38 + {src/assets => assets}/scripts/search.js | 0 {src/assets => assets}/scripts/sidebar.js | 0 {src/assets => assets}/styles/homepage.css | 0 {src/assets => assets}/styles/index.css | 0 {src/assets => assets}/styles/layout.css | 0 .../styles/lecture_header.css | 0 {src/assets => assets}/styles/newdefault.css | 0 {src/assets => assets}/styles/sidebar.css | 0 cheatsheets/index.html | 150 +++ develop.jl | 127 -- extra_outputs/index.html | 13 - generate.jl | 28 - .../add_pluto_8b10d72c.plutostate | Bin 0 -> 40733 bytes .../add_pluto_d0b17526.jl | 0 .../hw1_05791c9b.jl | 0 generated_assets/hw1_df96570f.plutostate | Bin 0 -> 23930 bytes .../plutoui_showcase_2971a541.jl | 0 .../plutoui_showcase_dd9dd2ec.plutostate | Bin 0 -> 192108 bytes homework/hw1/index.html | 146 +++ index.html | 199 ++++ installation/index.html | 240 ++++ logistics/index.html | 151 +++ mod1_setup_website/basic_info/index.html | 197 ++++ mod1_setup_website/getting_started/index.html | 172 +++ mod1_setup_website/working_locally/index.html | 149 +++ mod2_add_material/add_markdown/index.html | 200 ++++ mod2_add_material/add_pluto/index.html | 146 +++ mod2_add_material/plutoui_showcase/index.html | 146 +++ mod3_publish_website/deploy_static/index.html | 159 +++ .../precompute_output/index.html | 144 +++ mod3_publish_website/setup_server/index.html | 144 +++ pluto-deployment-environment/Manifest.toml | 697 ----------- .../PlutoDeployment.toml | 27 - pluto-deployment-environment/Project.toml | 22 - pp_search_data.json | 1 + search/index.html | 157 +++ src/_data/course_info.jl | 13 - src/_data/homepage.jl | 36 - src/_data/sidebar.jl | 6 - src/_data/tracks.jl | 5 - src/_includes/layout.jlhtml | 200 ---- src/_includes/md.jlmd | 9 - src/_includes/welcome.jlmd | 16 - src/assets/favicon.ico | Bin 121130 -> 0 bytes src/assets/homepage/bg.afdesign | Bin 22790 -> 0 bytes src/assets/scripts/get_highlights.jl | 26 - src/assets/scripts/get_subjects.jl | 38 - src/cheatsheets.md | 13 - src/index.jlmd | 4 - src/installation.md | 154 --- src/logistics.md | 17 - src/mod1_setup_website/basic_info.md | 89 -- src/mod1_setup_website/getting_started.md | 46 - src/mod1_setup_website/working_locally.md | 21 - src/mod2_add_material/add_markdown.md | 89 -- src/mod3_publish_website/deploy_static.md | 34 - src/mod3_publish_website/precompute_output.md | 10 - src/mod3_publish_website/setup_server.md | 11 - src/netlify.toml | 4 - src/search.md | 22 - tools/update_notebook_packages.jl | 35 - 79 files changed, 2565 insertions(+), 3068 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json delete mode 100644 Dockerfile delete mode 100644 LICENSE.md delete mode 100644 PlutoPages.jl delete mode 100644 Procfile delete mode 100644 README.md delete mode 100644 Website maintenance.md rename {src/assets => assets}/favicon.svg (100%) mode change 100755 => 100644 rename {src/assets => assets}/homepage/bg.svg (100%) rename {src/assets => assets}/homepage/swoosh.png (100%) rename {src/assets => assets}/julia-logo-color.svg (100%) rename {src/assets => assets}/julia-logo-dark.svg (100%) create mode 100644 assets/scripts/get_highlights/index.html create mode 100644 assets/scripts/get_subjects/index.html rename {src/assets => assets}/scripts/search.js (100%) rename {src/assets => assets}/scripts/sidebar.js (100%) rename {src/assets => assets}/styles/homepage.css (100%) rename {src/assets => assets}/styles/index.css (100%) rename {src/assets => assets}/styles/layout.css (100%) rename {src/assets => assets}/styles/lecture_header.css (100%) rename {src/assets => assets}/styles/newdefault.css (100%) rename {src/assets => assets}/styles/sidebar.css (100%) create mode 100644 cheatsheets/index.html delete mode 100644 develop.jl delete mode 100644 extra_outputs/index.html delete mode 100644 generate.jl create mode 100644 generated_assets/add_pluto_8b10d72c.plutostate rename src/mod2_add_material/add_pluto.jl => generated_assets/add_pluto_d0b17526.jl (100%) rename src/homework/hw1.jl => generated_assets/hw1_05791c9b.jl (100%) create mode 100644 generated_assets/hw1_df96570f.plutostate rename src/mod2_add_material/plutoui_showcase.jl => generated_assets/plutoui_showcase_2971a541.jl (100%) create mode 100644 generated_assets/plutoui_showcase_dd9dd2ec.plutostate create mode 100644 homework/hw1/index.html create mode 100644 index.html create mode 100644 installation/index.html create mode 100644 logistics/index.html create mode 100644 mod1_setup_website/basic_info/index.html create mode 100644 mod1_setup_website/getting_started/index.html create mode 100644 mod1_setup_website/working_locally/index.html create mode 100644 mod2_add_material/add_markdown/index.html create mode 100644 mod2_add_material/add_pluto/index.html create mode 100644 mod2_add_material/plutoui_showcase/index.html create mode 100644 mod3_publish_website/deploy_static/index.html create mode 100644 mod3_publish_website/precompute_output/index.html create mode 100644 mod3_publish_website/setup_server/index.html delete mode 100644 pluto-deployment-environment/Manifest.toml delete mode 100644 pluto-deployment-environment/PlutoDeployment.toml delete mode 100644 pluto-deployment-environment/Project.toml create mode 100644 pp_search_data.json create mode 100644 search/index.html delete mode 100644 src/_data/course_info.jl delete mode 100644 src/_data/homepage.jl delete mode 100644 src/_data/sidebar.jl delete mode 100644 src/_data/tracks.jl delete mode 100644 src/_includes/layout.jlhtml delete mode 100644 src/_includes/md.jlmd delete mode 100644 src/_includes/welcome.jlmd delete mode 100755 src/assets/favicon.ico delete mode 100644 src/assets/homepage/bg.afdesign delete mode 100644 src/assets/scripts/get_highlights.jl delete mode 100644 src/assets/scripts/get_subjects.jl delete mode 100644 src/cheatsheets.md delete mode 100644 src/index.jlmd delete mode 100644 src/installation.md delete mode 100644 src/logistics.md delete mode 100644 src/mod1_setup_website/basic_info.md delete mode 100644 src/mod1_setup_website/getting_started.md delete mode 100644 src/mod1_setup_website/working_locally.md delete mode 100644 src/mod2_add_material/add_markdown.md delete mode 100644 src/mod3_publish_website/deploy_static.md delete mode 100644 src/mod3_publish_website/precompute_output.md delete mode 100644 src/mod3_publish_website/setup_server.md delete mode 100644 src/netlify.toml delete mode 100644 src/search.md delete mode 100644 tools/update_notebook_packages.jl diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index bb05dd6c..00000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -page/* linguist-vendored -* text=auto \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index fee3d973..00000000 --- a/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ - -.DS_Store - -reduced_phil.png -notebooks/week9/testCSVwrite.csv - -_cache -_site -generation_report.html -src/week9/testCSVwrite.csv diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 550c7a7f..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. - // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp - - // List of extensions which should be recommended for users of this workspace. - "recommendations": [ - "esbenp.prettier-vscode", - "julialang.language-julia", - ], - // List of extensions recommended by VS Code that should not be recommended for users of this workspace. - "unwantedRecommendations": [ - - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 088b1e35..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "files.associations": { - "*.jlmd": "markdown", - "*.jlhtml": "html", - }, - - "prettier.printWidth": 160, - "prettier.tabWidth": 4, - "prettier.semi": false, - "prettier.quoteProps": "consistent", - "prettier.singleQuote": false, - - "editor.formatOnSave": false, - "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - }, - "[css]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - } -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 0e675d12..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "PlutoPages: run development server", - "type": "shell", - "command": "julia develop.jl", - "group": "build" - } - ] -} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index a484d02f..00000000 --- a/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -# Hi there! - -# This Dockerfile does _not_ run the Pluto notebooks. You can _not_ use it to work on the homework exercises. Instead, take a look at our website to learn how to get started with Pluto: http://computationalthinking.mit.edu . If you want to run a Pluto Container (e.g. for homework) take a look here: https://github.com/JuliaPluto/docker-stacks - -# This is an internal Dockerfile for the Pluto "@bind server" for the course website. It runs all the sliders, buttons and camera inputs, so that you can interact with them directly on the website, without having to wait for binder or a local Pluto session. -# Take a look at https://github.com/JuliaPluto/PlutoSliderServer.jl for more info. - -# -fonsi - -FROM julia:1.8.2 - -# HTTP port -EXPOSE 1234 -RUN apt-get update -y && apt-get upgrade -y -# add a new user called "pluto" -RUN useradd -ms /bin/bash pluto -# set the current directory -WORKDIR /home/pluto -# run the rest of commands as pluto user -USER pluto -# copy the contents of the github repository into /home/pluto -COPY --chown=pluto . ${HOME} - - -# Initialize the julia project environment that will be used to run the bind server. -RUN julia --project=${HOME}/pluto-deployment-environment -e "import Pkg; Pkg.instantiate(); Pkg.precompile()" - -# The "default command" for this docker thing. -CMD ["julia", "--project=/home/pluto/pluto-deployment-environment", "-e", "import PlutoSliderServer; PlutoSliderServer.run_directory(\".\"; SliderServer_port=1234 , SliderServer_host=\"0.0.0.0\")"] \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 81d06b1c..00000000 --- a/LICENSE.md +++ /dev/null @@ -1,14 +0,0 @@ -My license here: - - - - -This repository was generated from https://github.com/JuliaPluto/computational-thinking-template which is licensed as follows: - -Copyright 2023 Luca Ferranti, Fons van der Plas and the MIT Computational Thinking team: computationalthinking.mit.edu - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the β€œSoftware”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/PlutoPages.jl b/PlutoPages.jl deleted file mode 100644 index 832b288b..00000000 --- a/PlutoPages.jl +++ /dev/null @@ -1,1040 +0,0 @@ -### A Pluto.jl notebook ### -# v0.19.25 - -using Markdown -using InteractiveUtils - -# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). -macro bind(def, element) - quote - local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end - local el = $(esc(element)) - global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) - el - end -end - -# ╔═║ b8024c95-6a63-4409-9c75-9bad6b301a92 -begin - import Pkg - Pkg.activate("./pluto-deployment-environment") - - import PlutoSliderServer - import Pluto - using MarkdownLiteral -end - -# ╔═║ d4cfce05-bae4-49ae-b26d-ce27171a3853 -using PlutoUI - -# ╔═║ ce840b47-8406-48e6-abfb-1b00daab28dd -using HypertextLiteral - -# ╔═║ 7c53c1e3-6ccf-4804-8bc3-09126036608e -using PlutoHooks - -# ╔═║ 725cb996-68ac-4736-95ee-0a9754867bf3 -using BetterFileWatching - -# ╔═║ 9d996c55-0e37-4ae9-a6a2-8c8761e8c6db -using PlutoLinks - -# ╔═║ c5a0b072-7f49-4c0c-855e-773cfc03d308 -TableOfContents(include_definitions=true) - -# ╔═║ 644552c6-4e32-4caf-90ef-bee259977094 -import Logging - -# ╔═║ 66c97351-2294-4ac2-a93a-f334aaee8f92 -import Gumbo - -# ╔═║ bcbda2d2-90a5-43e6-8400-d5472578f86a -import ProgressLogging - -# ╔═║ cd576da6-59ae-4d1b-b812-1a35023b6875 -import ThreadsX - -# ╔═║ 86471faf-af03-4f35-8b95-c4011ceaf7c3 -function progressmap_generic(mapfn, f, itr; kwargs...) - l = length(itr) - id = gensym() - num_iterations = Threads.Atomic{Int}(0) - - function log(x) - Threads.atomic_add!(num_iterations, x) - Logging.@logmsg(ProgressLogging.ProgressLevel, "", progress=num_iterations[] / l, id=id) - end - - log(0) - - output = mapfn(enumerate(itr); kwargs...) do (i,x) - result = f(x) - log(1) - result - end - - log(0) - output -end - -# ╔═║ e0ae20f5-ffe7-4f0e-90be-168924526e03 -"Like `Base.map`, but with ProgressLogging." -function progressmap(f, itr) - progressmap_generic(map, f, itr) -end - -# ╔═║ d58f2a89-4631-4b19-9d60-5e590908b61f -"Like `Base.asyncmap`, but with ProgressLogging." -function progressmap_async(f, itr; kwargs...) - progressmap_generic(asyncmap, f, itr; kwargs...) -end - -# ╔═║ 2221f133-e490-4e3a-82d4-bd1c6c979d1c -"Like `ThreadsX.map`, but with ProgressLogging." -function progressmap_threaded(f, itr; kwargs...) - progressmap_generic(ThreadsX.map, f, itr; kwargs...) -end - -# ╔═║ 6c8e76ea-d648-449a-89de-cb6632cdd6b9 -md""" -# Template systems - -A **template** system is will turn an input file (markdown, julia, nunjucks, etc.) into an (HTML) output. This architecture is based on [eleventy](https://www.11ty.dev/docs/). - -To register a template handler for a file extension, you add a method to `template_handler`, e.g. - -```julia -function template_handler( - ::Val{Symbol(".md")}, - input::TemplateInput -)::TemplateOutput - - s = String(input.contents) - result = run_markdown(s) - - return TemplateOutput(; - contents=result.contents, - front_matter=result.front_matter, - ) -end -``` - -See `TemplateInput` and `TemplateOutput` for more info! -""" - -# ╔═║ 4a2dc5a4-0bf2-4678-b984-4ecb7b397d72 -md""" -## `.jlhtml`: HypertextLiteral.jl -""" - -# ╔═║ b3ce7742-fb47-4c17-bac2-e6a7710eb1a1 -md""" -## `.md` and `.jlmd`: MarkdownLiteral.jl -""" - -# ╔═║ f4a4b741-8028-4626-9187-0b6a52f062b6 -import CommonMark - -# ╔═║ 535efb29-73bd-4e65-8bbc-18b72ae8fe1f -import YAML - -# ╔═║ 90f0c676-b33f-441c-8ea6-d59c44a11547 -s_example = raw""" ---- -title: "Hello worfdsld!" -description: "A longer description of the same thing" -authors: ["Fonsi"] ---- - -### Hello there! - -My name is fons - - - -Want to embed some cool HTML? *Easy!* Just type the HTML! **or markdown**, it's all the same!! πŸ‘€ - -```math -\\sqrt{\\frac{1}{2}} -```` - -$(begin -a = 1 -b = 2 -export b -end) - -""" - -# ╔═║ 5381e8b3-d4f9-4e58-8da3-f1ee0a9b7a6d -@bind s TextField((70,20); default=s_example) - -# ╔═║ 08b42df7-9120-4b42-80ee-8e438752b50c -# s_result.exported - -# ╔═║ adb1ddac-d992-49ca-820f-e1ed8ca33bf8 -md""" -## `.jl`: PlutoSliderServer.jl -""" - -# ╔═║ bb905046-59b7-4da6-97ad-dbb9055d823a -const pluto_deploy_settings = PlutoSliderServer.get_configuration(PlutoSliderServer.default_config_path()) - -# ╔═║ b638df55-fd74-4ae8-bdbd-ec7b18214b40 -function prose_from_code(s::String)::String - replace(replace( - replace( - replace(s, - # remove embedded project/manifest - r"000000000001.+"s => ""), - # remove cell delimiters - r"^# [β•”β•Ÿβ• ].*"m => ""), - # remove some code-only punctiation - r"[\!\#\$\*\+\-\/\:\;\<\>\=\(\)\[\]\{\}\:\@\_]" => " "), - # collapse repeated whitespace - r"\s+"s => " ") -end - -# ╔═║ 87b4431b-438b-4da4-9d06-79e7f3a2fe05 -prose_from_code(""" -[xs for y in ab(d)] -fonsi -""") - -# ╔═║ cd4e479c-deb7-4a44-9eb0-c3819b5c4067 -find(f::Function, xs) = for x in xs - if f(x) - return x - end -end - -# ╔═║ 2e527d04-e4e7-4dc8-87e6-8b3dd3c7688a -const FrontMatter = Dict{String,Any} - -# ╔═║ a166e8f3-542e-4068-a076-3f5fd4daa61c -Base.@kwdef struct TemplateInput - contents::Vector{UInt8} - relative_path::String - absolute_path::String - frontmatter::FrontMatter=FrontMatter() -end - -# ╔═║ 6288f145-444b-41cb-b9e3-8f273f9517fb -begin - Base.@kwdef struct TemplateOutput - contents::Union{Vector{UInt8},String,Nothing} - file_extension::String="html" - frontmatter::FrontMatter=FrontMatter() - search_index_data::Union{Nothing,String}=nothing - end - TemplateOutput(t::TemplateOutput; kwargs...) = TemplateOutput(; - contents=t.contents, - file_extension=t.file_extension, - frontmatter=t.frontmatter, - search_index_data=t.search_index_data, - kwargs..., - ) -end - -# ╔═║ ff55f7eb-a23d-4ca7-b428-ab05dcb8f090 -# fallback method -function template_handler(::Any, input::TemplateInput)::TemplateOutput - TemplateOutput(; - contents=nothing, - file_extension="nothing", - ) -end - -# ╔═║ 692c1e0b-07e1-41b3-abcd-2156bda65b41 -""" -Turn a MarkdownLiteral.jl string into HTML contents and front matter. -""" -function run_mdx(s::String; - data::Dict{String,<:Any}=Dict{String,Any}(), - cm::Bool=true, - filename::AbstractString="unknown", - ) - # take a look at https://github.com/JuliaPluto/MarkdownLiteral.jl if you want to use it this too! - - # Just HTL, CommonMark parsing comes in a later step - code = "@htl(\"\"\"$(s)\"\"\")" - - m = Module() - Core.eval(m, :(var"@mdx" = var"@md" = $(MarkdownLiteral.var"@mdx"))) - Core.eval(m, :(var"@htl" = $(HypertextLiteral.var"@htl"))) - # Core.eval(m, :(setpage = $(setpage))) - Core.eval(m, :(using Markdown, InteractiveUtils)) - for (k,v) in data - Core.eval(m, :($(Symbol(k)) = $(v))) - end - - result = Base.include_string(m, code, filename) - - to_render, frontmatter = if !cm - result, FrontMatter() - else - - # we want to apply our own CM parser, so we do the MarkdownLiteral.jl trick manually: - result_str = repr(MIME"text/html"(), result) - cm_parser = CommonMark.Parser() - CommonMark.enable!(cm_parser, [ - CommonMark.AdmonitionRule(), - CommonMark.AttributeRule(), - CommonMark.AutoIdentifierRule(), - CommonMark.CitationRule(), - CommonMark.FootnoteRule(), - CommonMark.MathRule(), - CommonMark.RawContentRule(), - CommonMark.TableRule(), - CommonMark.TypographyRule(), - # TODO: allow Julia in front matter by using Meta.parse as the TOML parser? - # but you probably want to be able to use those variables inside the document, so they have to be evaluated *before* running the expr. - CommonMark.FrontMatterRule(yaml=YAML.load), - ]) - - ast = cm_parser(result_str) - - ast, CommonMark.frontmatter(ast) - end - - contents = repr(MIME"text/html"(), to_render) - - # TODO: might be nice: - # exported = filter(names(m; all=false, imported=false)) do s - # s_str = string(s) - # !(startswith(s_str, "#") || startswith(s_str, "anonymous")) - # end - - (; - contents, - frontmatter, - # exported, - ) -end - -# ╔═║ 7717e24f-62ee-4852-9dec-d09b734d0693 -s_result = run_mdx(s; data=Dict("num" => 3)); - -# ╔═║ 9f945292-ff9e-4f29-93ea-69b10fc4428d -s_result.contents |> HTML - -# ╔═║ 83366d96-4cd3-4def-a0da-16a22b40124f -s_result.frontmatter - -# ╔═║ 94bb6730-a4ad-42d2-aa58-41b70a15cd0e -md""" -## `.css`, `.html`, `.js`, `.png`, etc: passthrough - -""" - -# ╔═║ e15cf987-3615-4e96-8ccd-04cad3bcd48e -function template_handler(::Union{ - Val{Symbol(".css")}, - Val{Symbol(".html")}, - Val{Symbol(".js")}, - Val{Symbol(".png")}, - Val{Symbol(".svg")}, - Val{Symbol(".gif")}, - }, input::TemplateInput)::TemplateOutput - - TemplateOutput(; - contents=input.contents, - file_extension=lstrip(isequal('.'), splitext(input.relative_path)[2]), - ) -end - -# ╔═║ 940f3995-1739-4b30-b8cf-c27a671043e5 -md""" -## Generated assets -""" - -# ╔═║ 5e91e7dc-82b6-486a-b745-34f97b6fb20c -struct RegisteredAsset - url::String - relative_path::String - absolute_path::String -end - -# ╔═║ 8f6393a4-e945-4f06-90f6-0a71f874c8e9 -import SHA - -# ╔═║ 4fcdd524-86a8-4033-bc7c-4a7c04224eeb -import Unicode - -# ╔═║ 070c710d-3746-4706-bd03-b5b00a576007 -function myhash(data) - s = SHA.sha256(data) - string(reinterpret(UInt32, s)[1]; base=16, pad=8) -end - -# ╔═║ a5c22f80-58c7-4c63-95b8-ecb30bc896d0 -myhash(rand(UInt8, 50)) - -# ╔═║ 750782a1-3aeb-4816-8f6a-ec31055373c1 -legalize(filename) = replace( - Unicode.normalize( - replace(filename, " " => "_"); - stripmark=true) - , r"[^\w-]" => "") - -# ╔═║ f6b89b8c-3750-4dd2-940e-579be953c1c2 -legalize(" Γ«asdfa sd23__--f//asd f?\$%^&*() .") - -# ╔═║ 29a81ad7-3803-4b7a-98ca-6e5b1077e1c7 -md""" -# Input folder -""" - -# ╔═║ c52c9786-a25f-11ec-1fdc-9b13922d7ccb -const dir = joinpath(@__DIR__, "src") - -# ╔═║ cf27b3d3-1689-4b3a-a8fe-3ad639eb2f82 -md""" -## File watching -""" - -# ╔═║ 7f7f1981-978d-4861-b840-71ab611faf74 -@bind manual_update_trigger Button("Read input files again") - -# ╔═║ e1a87788-2eba-47c9-ab4c-74f3344dce1d -ignored_dirname(s; allow_special_dirs::Bool=false) = - startswith(s, "_") && (!allow_special_dirs || s != "_includes") - -# ╔═║ 485b7956-0774-4b25-a897-3d9232ef8590 -const this_file = split(@__FILE__, "#==#")[1] - -# ╔═║ d38dc2aa-d5ba-4cf7-9f9e-c4e4611a57ac -function ignore(abs_path; allow_special_dirs::Bool=false) - p = relpath(abs_path, dir) - - # (_cache, _site, _andmore) - any(x -> ignored_dirname(x; allow_special_dirs), splitpath(p)) || - startswith(p, ".git") || - startswith(p, ".vscode") || - abs_path == this_file -end - -# ╔═║ 8da0c249-6094-49ab-9e59-d6e356818651 -dir_changed_time = let - valx, set_valx = @use_state(time()) - - @info "Starting watch task" - - @use_task([dir]) do - BetterFileWatching.watch_folder(dir) do e - @debug "File event" e - try - is_caused_by_me = all(x -> ignore(x; allow_special_dirs=true), e.paths) - - if !is_caused_by_me - @info "Reloading!" e - set_valx(time()) - end - catch e - @error "Failed to trigger" exception=(e,catch_backtrace()) - end - end - end - - valx -end - -# ╔═║ 7d9cb939-da6b-4961-9584-a905ad453b5d -allfiles = filter(PlutoSliderServer.list_files_recursive(dir)) do p - # reference to retrigger when files change - dir_changed_time - manual_update_trigger - - !ignore(joinpath(dir, p)) -end - -# ╔═║ d314ab46-b866-44c6-bfca-9a413bc06514 -md""" -# Output folder generation -""" - -# ╔═║ e01ebbab-dc9a-4aaf-ae16-200d171fcbd9 -const output_dir = mkpath(joinpath(@__DIR__, "_site")) - -# ╔═║ 37b2cecc-e4c7-4b80-b7d9-71c68f3c0339 - - -# ╔═║ 7a95681a-df77-408f-919a-2bee5afd7777 -""" -This directory can be used to store cache files that are persisted between builds. Currently used as PlutoSliderServer.jl cache. -""" -const cache_dir = mkpath(joinpath(@__DIR__, "_cache")) - -# ╔═║ f3d225b8-b9a5-4639-97eb-7785b1a78f5a -md""" -## Running a dev web server -""" - -# ╔═║ c3a495c1-3e1f-42a1-ac08-8dc0b9175fe9 -# import Deno_jll - -# ╔═║ 3b2d1919-41d9-4bba-9774-c8497bba5003 -# dev_server_port = 4507 - -# ╔═║ 6f7f66e8-ed10-4cc4-8672-a06861111aec -# dev_server_url = "http://localhost:$(dev_server_port)/" - -# ╔═║ d09ee809-33d8-44f8-aa7a-be4b3fdc21eb - - -# ╔═║ a0a80dce-2199-45b6-b4e9-d4168f520c85 -# @htl("
Go to $(dev_server_url) to preview the site.
") - -# ╔═║ 4e88cf07-8d85-4327-b310-6c71ba951bba -md""" -## Running the templates - -(This can take a while if you are running this for the first time with an empty cache.) -""" - -# ╔═║ f700357f-e21c-4d23-b56c-be4f9c90465f -const NUM_PARALLEL_WORKERS = 4 - -# ╔═║ aaad71bd-5425-4783-952c-82e4d4fa7bb8 -md""" -## URL generation -""" - -# ╔═║ 76c2ac85-2e89-4396-a498-a4ceb1cc80bd -Base.@kwdef struct Page - url::String - full_url::String - input::TemplateInput - output::TemplateOutput -end - -# ╔═║ a510857f-528b-43e8-be78-69e554d165a6 -function short_url(s::String) - a = replace(s, r"index.html$" => "") - isempty(a) ? "." : a -end - -# ╔═║ 1c269e16-65c7-47ae-aeab-001f1b205e14 -ishtml(output::TemplateOutput) = output.file_extension == "html" - -# ╔═║ 898eb093-444c-45cf-88d7-3dbe9708ae31 -function final_url(input::TemplateInput, output::TemplateOutput)::String - if ishtml(output) - # Examples: - # a/b.jl -> a/b/index.html - # a/index.jl -> a/index.html - - in_dir, in_filename = splitdir(input.relative_path) - in_name, in_ext = splitext(in_filename) - - if in_name == "index" - joinpath(in_dir, "index.html") - else - joinpath(in_dir, in_name, "index.html") - end - else - ext = lstrip(isequal('.'), output.file_extension) - join((splitext(input.relative_path)[1], ".", ext)) - end -end - -# ╔═║ 76193b12-842c-4b82-a23e-fb7403274234 -md""" -## Collections from `tags` -""" - -# ╔═║ 4f563136-fc7b-4322-92ba-78c0183c40cc -struct Collection - tag::String - pages::Vector{Page} -end - -# ╔═║ 41ab51f9-0b33-4548-b08a-ad1ef7d38f1b -function sort_by(p::Page) - bn = basename(p.input.relative_path) - num = get(p.output.frontmatter, "order", Inf) - if num isa AbstractString - num = tryparse(Float64, num) - if isnothing(num) - num = Inf - end - end - return ( - num, - splitext(bn)[1] != "index", - # TODO: sort based on dates if we ever need that - bn, - ) -end - -# ╔═║ b0006e61-b037-41ed-a3e4-9962d15584c4 -md""" -## Layouts -""" - -# ╔═║ f2fbcc70-a714-4eda-8786-7ee5692e3268 -with_doctype(p::Page) = Page(p.url, p.full_url, p.input, with_doctype(p.output)) - -# ╔═║ 57fd383b-d791-4170-a353-f839356f9d7a -with_doctype(output::TemplateOutput) = if ishtml(output) && output.contents !== nothing - TemplateOutput(output; - contents="" * String(output.contents) - ) -else - output -end - -# ╔═║ 05f735e0-01cc-4276-a3f9-8420296e68be -md""" -## Search index -""" - -# ╔═║ 1a303aa4-bed5-4d9b-855c-23355f4a88fe -md""" -## Writing to the output directory -""" - -# ╔═║ 834294ff-9441-4e71-b5c0-edaf32d860ee -import JSON - -# ╔═║ eef54261-767a-4ce4-b549-0b1828379f7e -SafeString(x) = String(x) - -# ╔═║ cda8689d-9ae5-42c4-8e7e-715cf44c33bb -SafeString(x::Vector{UInt8}) = String(copy(x)) - -# ╔═║ 995c6810-8df2-483d-a87a-2277af0d43bd -function template_handler( - ::Union{Val{Symbol(".jlhtml")}}, - input::TemplateInput)::TemplateOutput - s = SafeString(input.contents) - result = run_mdx(s; - data=input.frontmatter, - cm=false, - filename=input.absolute_path, - ) - - return TemplateOutput(; - contents=result.contents, - search_index_data=Gumbo.text(Gumbo.parsehtml(result.contents).root), - frontmatter=result.frontmatter, - ) -end - -# ╔═║ 7e86cfc7-5439-4c7a-9c3b-381c776d8371 -function template_handler( - ::Union{ - Val{Symbol(".jlmd")}, - Val{Symbol(".md")} - }, - input::TemplateInput)::TemplateOutput - s = SafeString(input.contents) - result = run_mdx(s; - data=input.frontmatter, - filename=input.absolute_path, - ) - - return TemplateOutput(; - contents=result.contents, - search_index_data=Gumbo.text(Gumbo.parsehtml(result.contents).root), - frontmatter=result.frontmatter, - ) -end - -# ╔═║ 4013400c-acb4-40fa-a826-fd0cbae09e7e -reprhtml(x) = repr(MIME"text/html"(), x) - -# ╔═║ 5b325b50-8984-44c6-8677-3c6bc5c2b0b1 -"A magic token that will turn into a relative URL pointing to the website root when used in output." -const root_url = "++magic#root#url~$(string(rand(UInt128),base=62))++" - -# ╔═║ 0d2b7382-2ddf-48c3-90c8-bc22de454c97 -""" -```julia -register_asset(contents, original_name::String) -``` - -Place an asset in the `/generated_assets/` subfolder of the output directory and return a [`RegisteredAsset`](@ref) referencing it for later use. (The original filename will be sanitized, and a content hash will be appended.) - -To be used inside `process_file` methods which need to generate additional files. You can use `registered_asset.url` to get a location-independent href to the result. -""" -function register_asset(contents, original_name::String) - h = myhash(contents) - n, e = splitext(basename(original_name)) - - - mkpath(joinpath(output_dir, "generated_assets")) - newpath = joinpath(output_dir, "generated_assets", "$(legalize(n))_$(h)$(e)") - write(newpath, contents) - rel = relpath(newpath, output_dir) - return RegisteredAsset(joinpath(root_url, rel), rel, newpath) -end - -# ╔═║ e2510a44-df48-4c05-9453-8822deadce24 -function template_handler( - ::Val{Symbol(".jl")}, - input::TemplateInput -)::TemplateOutput - - - if Pluto.is_pluto_notebook(input.absolute_path) - temp_out = mktempdir() - Logging.with_logger(Logging.NullLogger()) do - PlutoSliderServer.export_notebook( - input.absolute_path; - Export_create_index=false, - Export_cache_dir=cache_dir, - Export_baked_state=false, - Export_baked_notebookfile=false, - Export_output_dir=temp_out, - ) - end - d = readdir(temp_out) - - statefile = find(contains("state") ∘ last ∘ splitext, d) - notebookfile = find(!contains("html") ∘ last ∘ splitext, d) - - reg_s = register_asset(read(joinpath(temp_out, statefile)), statefile) - reg_n = register_asset(read(joinpath(temp_out, notebookfile)), notebookfile) - - # TODO these relative paths can't be right... - h = @htl """ - - """ - - frontmatter = Pluto.frontmatter(input.absolute_path) - - return TemplateOutput(; - contents = repr(MIME"text/html"(), h), - search_index_data=prose_from_code(SafeString(input.contents)), - frontmatter, - ) - else - - s = SafeString(input.contents) - - h = @htl """ -
$(s)
- """ - - return TemplateOutput(; - contents=repr(MIME"text/html"(), h), - search_index_data=prose_from_code(s), - ) - end -end - -# ╔═║ 079a6399-50eb-4dee-a36d-b3dcb81c8456 -template_results = let - # delete any old files - for f in readdir(output_dir) - rm(joinpath(output_dir, f); recursive=true) - end - - # let's go! running all the template handlers - progressmap_async(allfiles; ntasks=NUM_PARALLEL_WORKERS) do f - absolute_path = joinpath(dir, f) - - input = TemplateInput(; - contents=read(absolute_path), - absolute_path, - relative_path=f, - frontmatter=FrontMatter( - "root_url" => root_url, - ), - ) - - output = try - template_handler(Val(Symbol(splitext(f)[2])), input) - catch e - @error "Template handler failed" f exception=(e,catch_backtrace()) - rethrow() - end - - input, output - end -end - -# ╔═║ 318dc59e-15f6-4b25-bcf5-1ab6b0d87af7 -pages = Page[ - let - u = final_url(input, output) - Page( - short_url(u), u, input, output, - ) - end - for (input, output) in template_results if output.contents !== nothing -] - -# ╔═║ f93da14a-e4c8-4c28-ab01-4a5ba1a3cf47 -collections = let - result = Dict{String,Set{Page}}() - - for page in pages - for t in get(page.output.frontmatter, "tags", String[]) - old = get!(result, t, Set{Page}()) - push!(old, page) - end - end - - - Dict{String,Collection}( - k => Collection(k, sort(collect(v); by=sort_by)) for (k,v) in result - ) -end - -# ╔═║ c2ee20be-16f5-47a8-851a-67a361bb0316 -""" -```julia -process_layouts(page::Page)::Page -``` - -Recursively apply the layout specified in the frontmatter, returning a new `Page` with updated `output`. -""" -function process_layouts(page::Page)::Page - output = page.output - - if haskey(output.frontmatter, "layout") - @assert output.file_extension == "html" "Layout is not (yet) supported on non-HTML outputs." - - layoutname = output.frontmatter["layout"] - @assert layoutname isa String - layout_file = joinpath(dir, "_includes", layoutname) - @assert isfile(layout_file) "$layout_file is not a valid layout path" - - - content = if ishtml(output) - HTML(SafeString(output.contents)) - else - output.contents - end - - metadata = Dict() - for data_file in readdir(joinpath(dir, "_data"); join=true) - key = splitext(basename(data_file))[1] - metadata[key] = include(data_file) - end - - input = TemplateInput(; - contents=read(layout_file), - absolute_path=layout_file, - relative_path=relpath(layout_file, dir), - frontmatter=merge(output.frontmatter, - FrontMatter( - "content" => content, - "page" => page, - "collections" => collections, - "root_url" => root_url, - "metadata" => metadata - ), - ) - ) - - result = template_handler(Val(Symbol(splitext(layout_file)[2])), input) - - @assert result.file_extension == "html" "Non-HTML output from Layouts is not (yet) supported." - - - - old_frontmatter = copy(output.frontmatter) - delete!(old_frontmatter, "layout") - new_frontmatter = merge(old_frontmatter, result.frontmatter) - - process_layouts(Page( - page.url, - page.full_url, - page.input, - TemplateOutput( - result; - search_index_data=output.search_index_data, - frontmatter=new_frontmatter, - ), - )) - else - page - end -end - -# ╔═║ 06edb2d7-325f-4f80-8c55-dc01c7783054 -rendered_results = progressmap(with_doctype ∘ process_layouts, pages) - -# ╔═║ d8e9b950-6e71-40e2-bac1-c3ba85bc83ee -collected_search_index_data = [ - ( - url=page.url::String, - title=get( - page.output.frontmatter, "title", - splitext(basename(page.input.relative_path))[1] - )::String, - tags=get(page.output.frontmatter, "tags", String[]), - text=page.output.search_index_data, - ) - for page in rendered_results if page.output.search_index_data !== nothing -] - -# ╔═║ 1be06e4b-6072-46c3-a63d-aa95e51c43b4 -write( - joinpath(output_dir, "pp_search_data.json"), - JSON.json(collected_search_index_data) -) - -# ╔═║ 9845db00-149c-45be-9e4f-55d1157afc87 -process_results = map(rendered_results) do page - input = page.input - output = page.output - - if output !== nothing && output.contents !== nothing - - # TODO: use front matter for permalink - - output_path2 = joinpath(output_dir, page.full_url) - mkpath(output_path2 |> dirname) - # Our magic root url: - # in Julia, you can safely call `String` and `replace` on arbitrary, non-utf8 data :) - write(output_path2, - replace(SafeString(output.contents), root_url => relpath(output_dir, output_path2 |> dirname)) - ) - end -end - -# ╔═║ 70fa9af8-31f9-4e47-b36b-828c88166b3d -md""" -# Verify output -""" - -# ╔═║ d17c96fb-8459-4527-a139-05fdf74cdc39 -allfiles_output = let - process_results - PlutoSliderServer.list_files_recursive(output_dir) -end - -# ╔═║ 9268f35e-1a4e-414e-a7ea-3f5796e0bbf3 -allfiles_output2 = filter(allfiles_output) do f - !startswith(f, "generated_assets") -end - -# ╔═║ e0a25f24-a7de-4eac-9f88-cb7632de09eb -begin - @assert length(allfiles_output2) β‰₯ length(pages) - - @htl(""" - - """) -end - -# ╔═║ Cell order: -# ╠═b8024c95-6a63-4409-9c75-9bad6b301a92 -# ╠═c5a0b072-7f49-4c0c-855e-773cfc03d308 -# ╠═d4cfce05-bae4-49ae-b26d-ce27171a3853 -# ╠═644552c6-4e32-4caf-90ef-bee259977094 -# ╠═66c97351-2294-4ac2-a93a-f334aaee8f92 -# ╠═bcbda2d2-90a5-43e6-8400-d5472578f86a -# ╠═cd576da6-59ae-4d1b-b812-1a35023b6875 -# β•Ÿβ”€e0ae20f5-ffe7-4f0e-90be-168924526e03 -# β•Ÿβ”€d58f2a89-4631-4b19-9d60-5e590908b61f -# β•Ÿβ”€2221f133-e490-4e3a-82d4-bd1c6c979d1c -# β•Ÿβ”€86471faf-af03-4f35-8b95-c4011ceaf7c3 -# β•Ÿβ”€6c8e76ea-d648-449a-89de-cb6632cdd6b9 -# ╠═a166e8f3-542e-4068-a076-3f5fd4daa61c -# ╠═6288f145-444b-41cb-b9e3-8f273f9517fb -# ╠═ff55f7eb-a23d-4ca7-b428-ab05dcb8f090 -# β•Ÿβ”€4a2dc5a4-0bf2-4678-b984-4ecb7b397d72 -# ╠═ce840b47-8406-48e6-abfb-1b00daab28dd -# ╠═995c6810-8df2-483d-a87a-2277af0d43bd -# β•Ÿβ”€b3ce7742-fb47-4c17-bac2-e6a7710eb1a1 -# ╠═f4a4b741-8028-4626-9187-0b6a52f062b6 -# ╠═535efb29-73bd-4e65-8bbc-18b72ae8fe1f -# ╠═7e86cfc7-5439-4c7a-9c3b-381c776d8371 -# ╠═90f0c676-b33f-441c-8ea6-d59c44a11547 -# ╠═5381e8b3-d4f9-4e58-8da3-f1ee0a9b7a6d -# ╠═9f945292-ff9e-4f29-93ea-69b10fc4428d -# ╠═83366d96-4cd3-4def-a0da-16a22b40124f -# ╠═08b42df7-9120-4b42-80ee-8e438752b50c -# ╠═7717e24f-62ee-4852-9dec-d09b734d0693 -# ╠═692c1e0b-07e1-41b3-abcd-2156bda65b41 -# β•Ÿβ”€adb1ddac-d992-49ca-820f-e1ed8ca33bf8 -# ╠═e2510a44-df48-4c05-9453-8822deadce24 -# ╠═bb905046-59b7-4da6-97ad-dbb9055d823a -# ╠═b638df55-fd74-4ae8-bdbd-ec7b18214b40 -# ╠═87b4431b-438b-4da4-9d06-79e7f3a2fe05 -# β•Ÿβ”€cd4e479c-deb7-4a44-9eb0-c3819b5c4067 -# ╠═2e527d04-e4e7-4dc8-87e6-8b3dd3c7688a -# β•Ÿβ”€94bb6730-a4ad-42d2-aa58-41b70a15cd0e -# ╠═e15cf987-3615-4e96-8ccd-04cad3bcd48e -# β•Ÿβ”€940f3995-1739-4b30-b8cf-c27a671043e5 -# ╠═0d2b7382-2ddf-48c3-90c8-bc22de454c97 -# ╠═5e91e7dc-82b6-486a-b745-34f97b6fb20c -# ╠═8f6393a4-e945-4f06-90f6-0a71f874c8e9 -# ╠═4fcdd524-86a8-4033-bc7c-4a7c04224eeb -# β•Ÿβ”€070c710d-3746-4706-bd03-b5b00a576007 -# β•Ÿβ”€a5c22f80-58c7-4c63-95b8-ecb30bc896d0 -# β•Ÿβ”€750782a1-3aeb-4816-8f6a-ec31055373c1 -# β•Ÿβ”€f6b89b8c-3750-4dd2-940e-579be953c1c2 -# β•Ÿβ”€29a81ad7-3803-4b7a-98ca-6e5b1077e1c7 -# ╠═c52c9786-a25f-11ec-1fdc-9b13922d7ccb -# ╠═7c53c1e3-6ccf-4804-8bc3-09126036608e -# ╠═725cb996-68ac-4736-95ee-0a9754867bf3 -# ╠═9d996c55-0e37-4ae9-a6a2-8c8761e8c6db -# β•Ÿβ”€cf27b3d3-1689-4b3a-a8fe-3ad639eb2f82 -# β•Ÿβ”€7f7f1981-978d-4861-b840-71ab611faf74 -# β•Ÿβ”€7d9cb939-da6b-4961-9584-a905ad453b5d -# ╠═e1a87788-2eba-47c9-ab4c-74f3344dce1d -# ╠═d38dc2aa-d5ba-4cf7-9f9e-c4e4611a57ac -# ╠═485b7956-0774-4b25-a897-3d9232ef8590 -# ╠═8da0c249-6094-49ab-9e59-d6e356818651 -# β•Ÿβ”€d314ab46-b866-44c6-bfca-9a413bc06514 -# ╠═e01ebbab-dc9a-4aaf-ae16-200d171fcbd9 -# ╠═37b2cecc-e4c7-4b80-b7d9-71c68f3c0339 -# β•Ÿβ”€7a95681a-df77-408f-919a-2bee5afd7777 -# β•Ÿβ”€f3d225b8-b9a5-4639-97eb-7785b1a78f5a -# ╠═c3a495c1-3e1f-42a1-ac08-8dc0b9175fe9 -# ╠═3b2d1919-41d9-4bba-9774-c8497bba5003 -# ╠═6f7f66e8-ed10-4cc4-8672-a06861111aec -# ╠═d09ee809-33d8-44f8-aa7a-be4b3fdc21eb -# β•Ÿβ”€a0a80dce-2199-45b6-b4e9-d4168f520c85 -# β•Ÿβ”€4e88cf07-8d85-4327-b310-6c71ba951bba -# ╠═f700357f-e21c-4d23-b56c-be4f9c90465f -# ╠═079a6399-50eb-4dee-a36d-b3dcb81c8456 -# β•Ÿβ”€aaad71bd-5425-4783-952c-82e4d4fa7bb8 -# ╠═76c2ac85-2e89-4396-a498-a4ceb1cc80bd -# ╠═898eb093-444c-45cf-88d7-3dbe9708ae31 -# β•Ÿβ”€a510857f-528b-43e8-be78-69e554d165a6 -# β•Ÿβ”€1c269e16-65c7-47ae-aeab-001f1b205e14 -# β•Ÿβ”€318dc59e-15f6-4b25-bcf5-1ab6b0d87af7 -# β•Ÿβ”€76193b12-842c-4b82-a23e-fb7403274234 -# ╠═4f563136-fc7b-4322-92ba-78c0183c40cc -# ╠═f93da14a-e4c8-4c28-ab01-4a5ba1a3cf47 -# ╠═41ab51f9-0b33-4548-b08a-ad1ef7d38f1b -# β•Ÿβ”€b0006e61-b037-41ed-a3e4-9962d15584c4 -# ╠═c2ee20be-16f5-47a8-851a-67a361bb0316 -# ╠═06edb2d7-325f-4f80-8c55-dc01c7783054 -# β•Ÿβ”€f2fbcc70-a714-4eda-8786-7ee5692e3268 -# β•Ÿβ”€57fd383b-d791-4170-a353-f839356f9d7a -# β•Ÿβ”€05f735e0-01cc-4276-a3f9-8420296e68be -# ╠═d8e9b950-6e71-40e2-bac1-c3ba85bc83ee -# β•Ÿβ”€1a303aa4-bed5-4d9b-855c-23355f4a88fe -# ╠═834294ff-9441-4e71-b5c0-edaf32d860ee -# ╠═1be06e4b-6072-46c3-a63d-aa95e51c43b4 -# ╠═9845db00-149c-45be-9e4f-55d1157afc87 -# β•Ÿβ”€eef54261-767a-4ce4-b549-0b1828379f7e -# β•Ÿβ”€cda8689d-9ae5-42c4-8e7e-715cf44c33bb -# β•Ÿβ”€4013400c-acb4-40fa-a826-fd0cbae09e7e -# β•Ÿβ”€5b325b50-8984-44c6-8677-3c6bc5c2b0b1 -# β•Ÿβ”€70fa9af8-31f9-4e47-b36b-828c88166b3d -# ╠═d17c96fb-8459-4527-a139-05fdf74cdc39 -# ╠═9268f35e-1a4e-414e-a7ea-3f5796e0bbf3 -# ╠═e0a25f24-a7de-4eac-9f88-cb7632de09eb diff --git a/Procfile b/Procfile deleted file mode 100644 index 80f7ba1e..00000000 --- a/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: julia --project="pluto-deployment-environment" -e "import PlutoSliderServer; PlutoSliderServer.run_directory(\".\"; port=$PORT , host=\"0.0.0.0\")" diff --git a/README.md b/README.md deleted file mode 100644 index 9968d671..00000000 --- a/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Computational thinking template - -

Go to template website :balloon:

- -This repository is a template to build a website like the [Computational thinking course](https://computationalthinking.mit.edu/) tought at MIT. - -**Note**: This is an early experiment and very WIP, use at your own risk. diff --git a/Website maintenance.md b/Website maintenance.md deleted file mode 100644 index e2ec6a4a..00000000 --- a/Website maintenance.md +++ /dev/null @@ -1,104 +0,0 @@ -# Website maintenance - -This document describes how the website works. - -# Overview - -This is the source code for the computational thinking website! It uses a site generation system inspired by [https://www.11ty.dev/](https://www.11ty.dev/), but there are only three template systems: -- **`.jlhtml` files** are rendered by [HypertextLiteral.jl](https://github.com/JuliaPluto/HypertextLiteral.jl) -- **`.jlmd` files** are rendered by [MarkdownLiteral.jl](https://github.com/JuliaPluto/MarkdownLiteral.jl) -- **`.jl` files** are rendered by [PlutoSliderServer.jl](https://github.com/JuliaPluto/PlutoSliderServer.jl) - -The `/src/` folder is scanned for files, and all files are turned into HTML pages. - -Paths correspond to URLs. For example, `src/data_science/pca.jl` will become available at `https://computationalthinking.mit.edu/data_science/pca/`. For files called *"index"*, the URL will point to its parent, e.g. `src/docs/index.jlmd` becomes `https://computationalthinking.mit.edu/docs/`. Remember that changing URLs is very bad! You can't share this site with your friends if the links break. - -> **To add something to our website, just create a new file!** Fons will be happy to figure out the technical bits. - -You can generate & preview the website locally (more on this later), and we have a github action generating the website when we push to the `Fall23` branch. The result (in the `Fall23-output` branch) is deployed with GitHub Pages. - -# Content - -## Literal templates -We use *Julia* as our templating system! Because we use HypertextLiteral and MarkdownLiteral, you can write regular Markdown files and HTML files, but you can also include `$(interpolation)` to spice up your documents! For example: - -```markdown -# Hey there! - -This is some *text*. Here is a very big number: $(1 + 1). -``` - -Besides small inline values, you can also write big code blocks, with `$(begin ... end)`, and you can output HTML. Take a look at some of our files to learn more! - -## Pluto notebooks - -Pluto notebooks will be rendered to HTML and included in the page. What you see is what you get! - -On a separate system, we are running a PlutoSliderServer that is synchronized to the `Fall23` brach. This makes our notebooks interactive! - -Notebook outputs are **cached** (for a long time) by the file hash. This means that a notebook file will only ever run once, which makes it much faster to work on the website. If you need to re-run your notebook, add a space somewhere in the code :) - -## `.css`, `.html`, `.gif`, etc - -Web assets go through the system unchanged. - -# Front matter - -Like many SSG systems, we use [*front matter*](https://www.11ty.dev/docs/data-frontmatter/) to add metadata to pages. In `.jlmd` files, this is done with a front matter block, e.g.: -```markdown ---- -title: "🌼 How to install" -description: "Instructions to install Pluto.jl" -tags: ["docs", "introduction"] -layout: "md.jlmd" ---- - -# Let's install Pluto - -here is how you do it -``` - -Every page **should probably** include: -- *`title`*: Will be used in the sidebar, on Google, in the window header, and on social media. -- *`description`*: Will be used on hover, on Google, and on social media. -- *`tags`*: List of *tags* that are used to create collections out of pages. Our sidebar uses collections to know which pages to list. (more details in `sidebar data.jl`) -- *`layout`*: The name of a layout file in `src/_includes`. For basic Markdown or HTML, you probably want `md.jlmd`. For Pluto, you should use `layout.jlhtml`. - -## How to write front matter -For `.jlmd` files, see the example above. - -For `.jl` notebooks, use the [Frontmatter GUI](https://github.com/fonsp/Pluto.jl/pull/2104) built into Pluto. - -For `.jlhtml`, we still need to figure something out πŸ˜„. - -# Running locally - -## Developing *content, styles, etc.* - -Open this repository in VS Code, and install the recommended extensions. - -To start running the development server, open the VS Code *command palette* (press `Cmd+Shift+P`), and search for **`Tasks: Run Task`**, then **`PlutoPages: run development server`**. The first run can take some time, as it builds up the notebook outputs cache. Leave it running. - -This will start two things in parallel: the PlutoPages.jl notebook (which generates the website), and a static file server (with Deno_jll). It will open two tabs in your browser: one is the generation dashboard (PlutoPages), the other is the current site preview (Deno_jll). - -Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the "Read input files again" button. - -This workflow is recommended for writing static content, styles, and for site maintenance. But for writing Pluto notebooks, it's best to prepare the notebook first, and then run the site (because it re-runs the entire notebook on any change). - -## Developing PlutoPages itself - - -You need to manually run the notebook with Pluto: -1. Go to this folder, and run `julia --project=pluto-deployment-environment`. Then `import Pkg; Pkg.instantiate();`. -1. `import Pluto; Pluto.run()` and open the `PlutoPages.jl` notebook in this repository. The first run can take some time, as it builds up the notebook outputs cache. Leave it running. -2. In a second terminal, go to this folder, and run `julia --project=pluto-deployment-environment`, then: - ```julia - import Deno_jll - run(`$(Deno_jll.deno()) run --allow-read --allow-net https://deno.land/std@0.102.0/http/file_server.ts _site`) - ``` -3. Go to the URL printed to your terminal. -4. Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the "Read input files again" button. - -# PlutoPages.jl? - -The PlutoPages.jl is still in experimental stage, and I'm not sure if the Julia community is waiting for another SSG system. So right now it's sort of released in secret. If you use it, be sure to respect our LICENSE and be sure to share your feedback with fons@plutojl.org! Bug reports welcome. diff --git a/src/assets/favicon.svg b/assets/favicon.svg old mode 100755 new mode 100644 similarity index 100% rename from src/assets/favicon.svg rename to assets/favicon.svg diff --git a/src/assets/homepage/bg.svg b/assets/homepage/bg.svg similarity index 100% rename from src/assets/homepage/bg.svg rename to assets/homepage/bg.svg diff --git a/src/assets/homepage/swoosh.png b/assets/homepage/swoosh.png similarity index 100% rename from src/assets/homepage/swoosh.png rename to assets/homepage/swoosh.png diff --git a/src/assets/julia-logo-color.svg b/assets/julia-logo-color.svg similarity index 100% rename from src/assets/julia-logo-color.svg rename to assets/julia-logo-color.svg diff --git a/src/assets/julia-logo-dark.svg b/assets/julia-logo-dark.svg similarity index 100% rename from src/assets/julia-logo-dark.svg rename to assets/julia-logo-dark.svg diff --git a/assets/scripts/get_highlights/index.html b/assets/scripts/get_highlights/index.html new file mode 100644 index 00000000..18954488 --- /dev/null +++ b/assets/scripts/get_highlights/index.html @@ -0,0 +1,26 @@ +
if isempty(get(metadata["homepage"], "highlights", []))
+    nothing
+else
+    highlights = [
+      @htl("""
+      <section>
+      <div class="content">
+          <h2>$(x["name"])</h2>
+          <p>$(x["text"])</p>
+      </div>
+      <div class="preview">
+          <img src="$(x["img"])">
+      </div>
+      </section>
+      """) for x in metadata["homepage"]["highlights"]
+    ]
+
+    @htl("""
+    <div class="subjectscontainer wide">
+      <h1>Highlights</h1>
+      <div class="contain">
+      $(highlights)      
+      </div>
+    </div>
+    """)
+end
diff --git a/assets/scripts/get_subjects/index.html b/assets/scripts/get_subjects/index.html new file mode 100644 index 00000000..ea4042e5 --- /dev/null +++ b/assets/scripts/get_subjects/index.html @@ -0,0 +1,38 @@ +
let
+    sections = metadata["sidebar"]
+    sections = [
+        @htl("""
+        $([
+            let
+                input = other_page.input
+                output = other_page.output
+                
+                name = get(output.frontmatter, "title", basename(input.relative_path))
+                desc = get(output.frontmatter, "description", nothing)
+                tags = get(output.frontmatter, "tags", String[])
+                
+                image = get(output.frontmatter, "image", nothing)
+                
+                class = [
+                    "no-decoration",
+                    ("tag_$(replace(x, " "=>"_"))" for x in tags)...,
+                ]
+                
+                image === nothing || isempty(image) ? nothing : @htl("""<a title=$(desc) class=$(class) href=$(root_url * "/" * other_page.url)>
+                    <h3>$(name)</h3>
+                    <img src=$(image)>
+                </a>""")
+            end for other_page in collections[section_id].pages
+        ])
+        """)
+        for (section_id, section_name) in sections
+    ]
+
+    isempty(sections) ? nothing : @htl("""<div class="wide subjectscontainer">
+    <h1>Subjects</h1>
+    <div class="subjects">
+      $(sections)
+    </div>
+    </div>
+    """)
+end
diff --git a/src/assets/scripts/search.js b/assets/scripts/search.js similarity index 100% rename from src/assets/scripts/search.js rename to assets/scripts/search.js diff --git a/src/assets/scripts/sidebar.js b/assets/scripts/sidebar.js similarity index 100% rename from src/assets/scripts/sidebar.js rename to assets/scripts/sidebar.js diff --git a/src/assets/styles/homepage.css b/assets/styles/homepage.css similarity index 100% rename from src/assets/styles/homepage.css rename to assets/styles/homepage.css diff --git a/src/assets/styles/index.css b/assets/styles/index.css similarity index 100% rename from src/assets/styles/index.css rename to assets/styles/index.css diff --git a/src/assets/styles/layout.css b/assets/styles/layout.css similarity index 100% rename from src/assets/styles/layout.css rename to assets/styles/layout.css diff --git a/src/assets/styles/lecture_header.css b/assets/styles/lecture_header.css similarity index 100% rename from src/assets/styles/lecture_header.css rename to assets/styles/lecture_header.css diff --git a/src/assets/styles/newdefault.css b/assets/styles/newdefault.css similarity index 100% rename from src/assets/styles/newdefault.css rename to assets/styles/newdefault.css diff --git a/src/assets/styles/sidebar.css b/assets/styles/sidebar.css similarity index 100% rename from src/assets/styles/sidebar.css rename to assets/styles/sidebar.css diff --git a/cheatsheets/index.html b/cheatsheets/index.html new file mode 100644 index 00000000..d5f2c9d6 --- /dev/null +++ b/cheatsheets/index.html @@ -0,0 +1,150 @@ + + + +Cheatsheets β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + diff --git a/develop.jl b/develop.jl deleted file mode 100644 index 90401bb6..00000000 --- a/develop.jl +++ /dev/null @@ -1,127 +0,0 @@ -cd(@__DIR__) -notebook_path = joinpath(@__DIR__, "PlutoPages.jl") - -@assert VERSION >= v"1.6.0" - -begin - begin - begin - # copy paste from pluto source code - function detectwsl() - Sys.islinux() && - isfile("/proc/sys/kernel/osrelease") && - occursin(r"Microsoft|WSL"i, read("/proc/sys/kernel/osrelease", String)) - end - - function open_in_default_browser(url::AbstractString)::Bool - try - if Sys.isapple() - Base.run(`open $url`) - true - elseif Sys.iswindows() || detectwsl() - Base.run(`powershell.exe Start "'$url'"`) - true - elseif Sys.islinux() - Base.run(`xdg-open $url`) - true - else - false - end - catch ex - false - end - end - end - end -end - - - -import Pkg -Pkg.activate("./pluto-deployment-environment") -Pkg.instantiate() -import Pluto -import Deno_jll - - -pluto_port_channel = Channel{UInt16}(1) -function on_event(e::Pluto.ServerStartEvent) - put!(pluto_port_channel, e.port) -end -function on_event(e) - # ignore -end - -req_s = false - -# We create a session: -sesh = Pluto.ServerSession(options=Pluto.Configuration.from_flat_kwargs(; - # workspace_use_distributed=false, - # disable_writing_notebook_files=true, - auto_reload_from_file=true, - launch_browser=false, - on_event, - require_secret_for_access=req_s, - require_secret_for_open_links=req_s -)) - -notebook_launch_task = @async Pluto.SessionActions.open(sesh, notebook_path; run_async=true) - -@info "Pluto app: Starting server..." - -println("Ignore the message \"Go to ... in your browser\":") -pluto_server_task = @async Pluto.run(sesh) - -pluto_port = take!(pluto_port_channel) # This waits for the server to get ready -@info "Pluto app: waiting for notebook to launch..." -notebook = fetch(notebook_launch_task) # This waits for the notebook to finish - -output_dir = joinpath(@__DIR__, "_site") - -dev_server_port = rand(40507:40999) - - -dev_server_task = @async run(`$(Deno_jll.deno()) run --allow-read --allow-net https://deno.land/std@0.102.0/http/file_server.ts --cors --port $(dev_server_port) $(output_dir)`) # <=v"0.102.0" because of https://github.com/denoland/deno_std/issues/2251 - -sleep(.5) - -ccall(:jl_exit_on_sigint, Cvoid, (Cint,), 0) -@info "Press Ctrl+C multiple times to exit" - -isolated_cell_ids = [ - "cf27b3d3-1689-4b3a-a8fe-3ad639eb2f82" - "7f7f1981-978d-4861-b840-71ab611faf74" - "7d9cb939-da6b-4961-9584-a905ad453b5d" - "4e88cf07-8d85-4327-b310-6c71ba951bba" - "079a6399-50eb-4dee-a36d-b3dcb81c8456" - "b0006e61-b037-41ed-a3e4-9962d15584c4" - "06edb2d7-325f-4f80-8c55-dc01c7783054" - "e0a25f24-a7de-4eac-9f88-cb7632de09eb" -] - -isolated_cell_query = join("&isolated_cell_id=$(i)" for i in isolated_cell_ids) - -dev_server_url = "http://localhost:$(dev_server_port)/" -pluto_server_url = "http://localhost:$(pluto_port)/edit?id=$(notebook.notebook_id)$(isolated_cell_query)" - -@info """ - -βœ…βœ…βœ… - -Ready! To see the website, visit: -➑️ $(dev_server_url) - -To inspect the generation process, go to: -➑️ $(pluto_server_url) - -βœ…βœ…βœ… - -""" - - - -open_in_default_browser(dev_server_url) -open_in_default_browser(pluto_server_url) - -wait(dev_server_task) -wait(pluto_server_task) \ No newline at end of file diff --git a/extra_outputs/index.html b/extra_outputs/index.html deleted file mode 100644 index 9df59be8..00000000 --- a/extra_outputs/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/generate.jl b/generate.jl deleted file mode 100644 index a870f89d..00000000 --- a/generate.jl +++ /dev/null @@ -1,28 +0,0 @@ -import Pluto - -s = Pluto.ServerSession() - -# s.options.server.disable_writing_notebook_files = true -s.options.server.launch_browser = false - -@info "PlutoPages: Starting..." -nb = Pluto.SessionActions.open(s, joinpath(@__DIR__, "PlutoPages.jl"); run_async=false) -@info "PlutoPages: Finished. Analyzing result..." - -write("generation_report.html", Pluto.generate_html(nb)) - -failed = filter(c -> c.errored, nb.cells) - -for c in failed - println(stderr, "Cell errored: ", c.cell_id) - println(stderr) - show(stderr, MIME"text/plain"(), c.output.body) - println(stderr) - println(stderr) -end - -Pluto.SessionActions.shutdown(s, nb) - -if !isempty(failed) - exit(1) -end diff --git a/generated_assets/add_pluto_8b10d72c.plutostate b/generated_assets/add_pluto_8b10d72c.plutostate new file mode 100644 index 0000000000000000000000000000000000000000..f29df4ebf3dd6d288ee3653950551359b4052988 GIT binary patch literal 40733 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 NnDYIXuZkwf{{xj|d7uCQ literal 0 HcmV?d00001 diff --git a/src/mod2_add_material/plutoui_showcase.jl b/generated_assets/plutoui_showcase_2971a541.jl similarity index 100% rename from src/mod2_add_material/plutoui_showcase.jl rename to generated_assets/plutoui_showcase_2971a541.jl diff --git a/generated_assets/plutoui_showcase_dd9dd2ec.plutostate b/generated_assets/plutoui_showcase_dd9dd2ec.plutostate new file mode 100644 index 0000000000000000000000000000000000000000..0a7b3dcc98eb8b7b64972c551bb33a25c38c2086 GIT binary patch literal 192108 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 Dn3cQ7 literal 0 HcmV?d00001 diff --git a/homework/hw1/index.html b/homework/hw1/index.html new file mode 100644 index 00000000..a52a1522 --- /dev/null +++ b/homework/hw1/index.html @@ -0,0 +1,146 @@ + + + +sample homework β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Homework 1

+

sample homework

+ + +
+ + + +
+
+ + diff --git a/index.html b/index.html new file mode 100644 index 00000000..36ed915c --- /dev/null +++ b/index.html @@ -0,0 +1,199 @@ + + + +index β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +
+
+

Highlights

+
+
+
+

Easy to customise

+

Let the template automate all of the website development and infrastructure, so that you can focus on the most important thing: easily develop your lesson materials!

+

+
+
+ +
+
+
+
+

Revolutionary interactivity with Pluto.jl

+

Thanks to Pluto.jl, the website is built using real code, and instead of a book, we have a series of interactive notebooks. On the website, students can play with sliders, buttons and images to interact with our simulations. You can even go further, and modify and run any code on our website!

+

+
+
+ +
+
+
+
+

Learn Julia

+

In literature it's not enough to just know the technicalities of grammar. In music it's not enough to learn the scales. The goal is to communicate experiences and emotions. For a computer scientist, it's not enough to write a working program, the program should be written with beautiful high level abstractions that speak to your audience. Julia is designed with this purpose in mind, use it in your teaching to harness its power.

+

+
+
+ +
+
+
+
+ +
+ + +
+
+ + diff --git a/installation/index.html b/installation/index.html new file mode 100644 index 00000000..7d7776d6 --- /dev/null +++ b/installation/index.html @@ -0,0 +1,240 @@ + + + +Software installation β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

Software installation

+ +
+ +

Lecture Video

+
+ +
+
+ +
+
+
+

First-time setup: Install Julia & Pluto

+


+
+
+Text and pictures version:

+

Step 1: Install Julia 1.8.2

+

Go to https://julialang.org/downloads and download the current stable release, Julia 1.8.2, using the correct version for your operating system (Linux x86, Mac, Windows, etc).

+

Step 2: Run Julia

+

After installing, make sure that you can run Julia. On some systems, this means searching for the β€œJulia 1.8.2” program installed on your computer; in others, it means running the command julia in a terminal. Make sure that you can execute 1 + 1:

+

image

+

Make sure that you are able to launch Julia and calculate 1+1 before proceeding!

+

Step 3: Install Pluto

+

Next we will install the Pluto, the notebook environment that we will be using during the course. Pluto is a Julia programming environment designed for interactivity and quick experiments.

+

Open the Julia REPL. This is the command-line interface to Julia, similar to the previous screenshot.

+

Here you type Julia commands, and when you press ENTER, it runs, and you see the result.

+

To install Pluto, we want to run a package manager command. To switch from Julia mode to Pkg mode, type ] (closing square bracket) at the julia> prompt:

+

+julia> ]
+

(@v1.8) pkg> +

+

The line turns blue and the prompt changes to pkg>, telling you that you are now in package manager mode. This mode allows you to do operations on packages (also called libraries).

+

To install Pluto, run the following (case sensitive) command to add (install) the package to your system by downloading it from the internet. +You should only need to do this once for each installation of Julia:

+

+(@v1.8) pkg> add Pluto
+
+

This might take a couple of minutes, so you can go get yourself a cup of tea!

+

image

+

You can now close the terminal.

+

Step 4: Use a modern browser: Mozilla Firefox or Google Chrome

+

We need a modern browser to view Pluto notebooks with. Firefox and Chrome work best.

+

Second time: Running Pluto & opening a notebook

+

Repeat the following steps whenever you want to work on a project or homework assignment.

+

Step 1: Start Pluto

+

Start the Julia REPL, like you did during the setup. In the REPL, type:

+
julia> using Pluto
+

julia> Pluto.run() +

+

image

+

The terminal tells us to go to http://localhost:1234/ (or a similar URL). Let’s open Firefox or Chrome and type that into the address bar.

+

image

+
+

If you’re curious about what a Pluto notebook looks like, have a look at the Featured Notebooks. These notebooks are useful for learning some basics of Julia programming.

+

If you want to hear the story behind Pluto, have a look a the JuliaCon presentation.

+
+

If nothing happens in the browser the first time, close Julia and try again. And please let us know!

+

Step 2a: Opening a notebook from the web

+

This is the main menu - here you can create new notebooks, or open existing ones. Our homework assignments will always be based on a template notebook, available in this GitHub repository. To start from a template notebook on the web, you can paste the URL into the blue box and press ENTER.

+

For example, homework 0 is available here. Go to this page, and on the top right, click on the button that says β€œEdit or run this notebook”. From these instructions, copy the notebook link, and paste it into the box. Press ENTER, and select OK in the confirmation box.

+

image

+

The first thing we will want to do is to save the notebook somewhere on our own computer; see below.

+

Step 2b: Opening an existing notebook file

+

When you launch Pluto for the second time, your recent notebooks will appear in the main menu. You can click on them to continue where you left off.

+

If you want to run a local notebook file that you have not opened before, then you need to enter its full path into the blue box in the main menu. More on finding full paths in step 3.

+

Step 3: Saving a notebook

+

We first need a folder to save our homework in. Open your file explorer and create one.

+

Next, we need to know the absolute path of that folder. Here’s how you do that in Windows, MacOS and Ubuntu.

+

For example, you might have:

+
    +
  • +

    C:\Users\fons\Documents\18S191_assignments\ on Windows

    +
  • +
  • +

    /Users/fons/Documents/18S191_assignments/ on MacOS

    +
  • +
  • +

    /home/fons/Documents/18S191_assignments/ on Ubuntu

    +
  • +
+

Now that we know the absolute path, go back to your Pluto notebook, and at the top of the page, click on β€œSave notebook…”.

+

image

+

This is where you type the new path+filename for your notebook:

+

image

+

Click Choose.

+

Step 4: Sharing a notebook

+

After working on your notebook (your code is autosaved when you run it), you will find your notebook file in the folder we created in step 3. This the file that you can share with others, or submit as your homework assignment to Canvas.

+ +
+
+ + +
+
+ + diff --git a/logistics/index.html b/logistics/index.html new file mode 100644 index 00000000..e3ea759b --- /dev/null +++ b/logistics/index.html @@ -0,0 +1,151 @@ + + + +Class logistics β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

Class logistics

+ + +
+
+
+ +

Course logistics

+

Describe here the logistics of your class.

+
+
+ + +
+
+ + diff --git a/mod1_setup_website/basic_info/index.html b/mod1_setup_website/basic_info/index.html new file mode 100644 index 00000000..503f3590 --- /dev/null +++ b/mod1_setup_website/basic_info/index.html @@ -0,0 +1,197 @@ + + + +Fill course basic information β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 1.2

+

Fill course basic information

+ + +
+
+
+

Add basic information

+

If you look at the homepage of the template website, you will see it has a bunch of placeholder text, such as β€œname of your course”, β€œa short catchy phrase” etc.

+

To customize this, you will need to customize the metadata of the website. That is, add basic info for your class.

+

To do so, you will need to fill the info in the files under the folder src/_data. Let us analyze these one by one.

+

course_info.jl

+

This file contains a julia Dict with the basic info of the class. For each key (course_name, course_subtitle, etc.) replace the corresponding placeholder with an appropriate text for your class.

+

When filling the institution_logo data with the name of your university logo file, do not forget to actually put the file under src/assets.

+

Authors are listed as a vector of pairs, where the first element is the author name and the second is their homepage address. If you dont have a homepage address for the author, put an empty string "".

+

homepage.jl

+

This file contains metadata for the info displayed in the homepage, particularly

+
    +
  • title: the title displayed on top of the homepage
  • +
  • disclaimer: the disclaimer displayed below the title. If you don’t want a disclaimer, you can remove this entry.
  • +
  • highlights: in this entry you can specify the highlights of your class, which will be displayed on the homepage. This entry should be a vector of highlights. Each entry in the vector should be a dict with the following fields +
      +
    • name: the title of the highlight
    • +
    • text: short description of the highlight
    • +
    • img: link to an image summarizing the highlight
    • +
    +
  • +
+

sidebar.jl

+

In this file you can specify the sidebar of the website. All lecture materials will be grouped in modules in the sidebar, which are defined in this file.

+

The modules in the file are specified as a vector of pairs, in the form

+
module_id => module_title
+
+

for example

+
"module1" => "Week 1: Introduction to the class"
+
+

To link a file to a module, you will need to add the module identifier in the page tags. For more info about this, see Add frontmatter

+

tracks.jl

+

In this file you will specify tracks. Tracks can be used to group lectures across modules, e.g. if they have a commmon theme. When a track is selected on the sidebar, only the pages +belonging to that track will be highlighted.

+

Similar to modules, tracks are stored in a vector of pairs in the form

+
track_id => track_title
+
+

for example

+
"julia" => "πŸ’» Julia programming"
+
+

To link a file to a track, you will need to add the track id, prefixed with track_, to the tags of the page. For example, to add a lesson to the julia track defined above, you would add the tag track_julia to the tags of that lesson file.

+

License

+

Choosing an appropriate license is important to make your material properly reusable.

+ +

To add the license, open the file LICENSE.md and replace the text

+
<insert license for your material judge>
+
+

with your license(s).

+
+
+ + +
+
+ + diff --git a/mod1_setup_website/getting_started/index.html b/mod1_setup_website/getting_started/index.html new file mode 100644 index 00000000..6abf1243 --- /dev/null +++ b/mod1_setup_website/getting_started/index.html @@ -0,0 +1,172 @@ + + + +Getting started β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 1.1

+

Getting started

+ + +
+
+
+

Fork the template

+

Go to the template repository and click Use this template on the top-right corner. This will fork the repository under your github profile.

+

+

Folder structure

+

Let us have a look at what this repository looks like. The most important folder, where you will be mainly working is src. Here you will place all your lecture materials. So let us take a closer look at this.

+

Opening the src folder, you will see the following

+
    +
  • _data folder: here you will place metadata about your website (university name, class semester, define tracks, etc.), more on this in the next lesson.
  • +
  • _include: This folder contains the layout templates that are used to generate the final pages on your website. Unless you want to tweak the layout, you will not need to modify this.
  • +
  • assets: in this folder you can place all attachements, such as your university logo and other pictures. The folder also contains the CSS and scripts used to render the website.
  • +
+

That was for the β€œinfrastructure part” of the website, the rest is content! To add new pages to your website, simply them under the src folder. You can group them in subfolders, as done in this template, but that is not a strict requirement.

+

When downloading this template, you will get the following material:

+
    +
  • installation.md: this page contains instructions on how to install Julia and Pluto. If you find it useful, you may keep it as is, or edit to match your wanted installation instructions.
  • +
  • cheatsheets.md: contains a list of julia related resources. Again, you can keep it or remove it.
  • +
  • logistics.md: empty markdown page, where you can describe the logistics of your class
  • +
  • index.jlmd: this is used to render the homepage. Do not remove or modify this!
  • +
  • search.md: this is used to render the search tab on the sidebar, do not modify or remove this file.
  • +
+

The remaining folders

+
    +
  • mod1_setup_website
  • +
  • mod2_add_material
  • +
  • mod3_publish_website
  • +
  • homework
  • +
+

are placeholder samples, used to showcase what a deployed website looks like. As a bonus, these placeholder files actually document how to use this template. You can read it and see what the final result looks like on the template webpage.

+

When starting adding your course material, you will most likely want to remove these.

+
+
+ + +
+
+ + diff --git a/mod1_setup_website/working_locally/index.html b/mod1_setup_website/working_locally/index.html new file mode 100644 index 00000000..25bdc1ce --- /dev/null +++ b/mod1_setup_website/working_locally/index.html @@ -0,0 +1,149 @@ + + + +Working locally β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 1.3

+

Working locally

+ + +
+
+
+

Working locally

+

Open this repository in VS Code, and install the recommended extensions.

+

To start running the development server, open the VS Code command palette (press Cmd+Shift+P), and search for Tasks: Run Task, then PlutoPages: run development server. The first run can take some time, as it builds up the notebook outputs cache. Leave it running.

+

This will start two things in parallel: the PlutoPages.jl notebook (which generates the website), and a static file server (with Deno_jll). It will open two tabs in your browser: one is the generation dashboard (PlutoPages), the other is the current site preview (Deno_jll).

+

Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the β€œRead input files again” button.

+

Note!: This workflow is recommended for writing static content, styles, and for site maintenance. But for writing Pluto notebooks, it’s best to prepare the notebook first, and then run the site (because it re-runs the entire notebook on any change).

+
+
+ + +
+
+ + diff --git a/mod2_add_material/add_markdown/index.html b/mod2_add_material/add_markdown/index.html new file mode 100644 index 00000000..8f767234 --- /dev/null +++ b/mod2_add_material/add_markdown/index.html @@ -0,0 +1,200 @@ + + + +Add markdown files β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 2.1

+

Add markdown files

+ + +
+
+
+

Add markdown files

+

If your lecture does not need to run code or use interactivity. You can write it as a markdown file.

+

As an extra twist, you can evaluate julia code inside a $ symbol. For example,

+
$(1 + 1)
+
+

will become

+

2

+

Add Front-matter

+

For each file, markdown or pluto, you will need to add a front-matter, which specifies the page metadata. For markdown files, the front-matter is specified at the top of the file between three dashes ---. For example, the front-matter of this file is

+
---
+title: "Add markdown file"
+order: 1
+chapter: 2
+section: 1
+layout: "md.jlmd"
+tags: ["module2", "track_material", "markdown", "frontmatter"]
+---
+
+

You will need to specify the following attributes

+
    +
  • title: title of the page
  • +
  • order: the position of the page in the module on the sidebar. Hint!: You can also use fractional numbers, e.g. 1.5. This can be handy for homeworks, so you can include the homework between the first and second lesson without messing up lessons counting.
  • +
  • layout: set to "md.jlmd", unless you are using some custom layout
  • +
  • chapter and section (optional): used to number the page. If for example chapter=1 and section=2, the page will be displayed as 1.2 on the sidebar and page header.
  • +
  • image (optional): link to summarizing image to display in the subjects section on the homepage. If left empty, the page wont be included in the subjects section. If no page has an image field in the front-matter, the subjects section is not displayed.
  • +
  • description (optional): short description of the notebook
  • +
  • youtube_id (optional): youtube id of the video associated with the page. If included, the page header will embed the youtube video.
  • +
  • homework_number: needed only for homeworks, the number of the homework
  • +
  • tags: list of keywords for the page. It should at least include the module name, as defined in _data/sidebar.jl to include the page in the sidebar. You can also associate pages to a given track by adding the track id, prefixed with track_ to the tags. For example, if you want to include the page in the julia track, add track_julia in the tags list.
  • +
+

Markdown 101

+

If you are not familiar with markdown, you can see for example here. Here is a quick and dirty cheatsheet

+
    +
  1. Use # for headers, for example
  2. +
+
# Header
+## Subheader
+### Sub-sub-header
+
+
    +
  1. You can create links with the syntax
  2. +
+
[text](adddress)
+
+

For example the link to the mardown tutorial above was typed as

+
[here](https://www.markdowntutorial.com/)
+
+
    +
  1. You can insert pictures with the syntax
  2. +
+
![optional alternative text](link-to-picture)
+
+

for example

+
![](https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.png)
+
+

will give

+

+
+
+ + +
+
+ + diff --git a/mod2_add_material/add_pluto/index.html b/mod2_add_material/add_pluto/index.html new file mode 100644 index 00000000..0bb5c317 --- /dev/null +++ b/mod2_add_material/add_pluto/index.html @@ -0,0 +1,146 @@ + + + +Add Pluto notebooks β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 2.2

+

Add Pluto notebooks

+ + +
+ + + +
+
+ + diff --git a/mod2_add_material/plutoui_showcase/index.html b/mod2_add_material/plutoui_showcase/index.html new file mode 100644 index 00000000..ba8ac483 --- /dev/null +++ b/mod2_add_material/plutoui_showcase/index.html @@ -0,0 +1,146 @@ + + + +PlutoUI showcase β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 2.3

+

PlutoUI showcase

+ + +
+ + + +
+
+ + diff --git a/mod3_publish_website/deploy_static/index.html b/mod3_publish_website/deploy_static/index.html new file mode 100644 index 00000000..eae4d9e2 --- /dev/null +++ b/mod3_publish_website/deploy_static/index.html @@ -0,0 +1,159 @@ + + + +Deploy your website as static β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 3.1

+

Deploy your website as static

+ + +
+
+
+

Deploying with github pages

+

Deploying your website as static page with github pages is a breeze.

+

Whenever you push to main, the website will be deployed to a branch called gh-pages. All you need to do is go to your repository and from Settings > Pages choose to deploy from gh-pages branch, as the following picture shows.

+

+

After that, the website will be available at

+
https://yourusername.github.io/your-repository-name
+
+

Note that this is a static webpage, so sliders will not work. Students will still be able to play with interactivity by downloading the notebook or running it on binder.

+

If you want interactivity to work on the webpage, you can either

+
    +
  1. Precompute the notebooks outputs (experimental)
  2. +
+

or

+
    +
  1. Run your own server
  2. +
+
+
+ + +
+
+ + diff --git a/mod3_publish_website/precompute_output/index.html b/mod3_publish_website/precompute_output/index.html new file mode 100644 index 00000000..fe8d6a75 --- /dev/null +++ b/mod3_publish_website/precompute_output/index.html @@ -0,0 +1,144 @@ + + + +Precompute the pluto notebooks β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 3.2

+

Precompute the pluto notebooks

+ + +
+
+
+

COMING SOON

+
+
+ + +
+
+ + diff --git a/mod3_publish_website/setup_server/index.html b/mod3_publish_website/setup_server/index.html new file mode 100644 index 00000000..9bbc3bd0 --- /dev/null +++ b/mod3_publish_website/setup_server/index.html @@ -0,0 +1,144 @@ + + + +Setup a server for your website β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+

Section 3.3

+

Setup a server for your website

+ + +
+
+
+

COMING SOON

+
+
+ + +
+
+ + diff --git a/pluto-deployment-environment/Manifest.toml b/pluto-deployment-environment/Manifest.toml deleted file mode 100644 index f4924457..00000000 --- a/pluto-deployment-environment/Manifest.toml +++ /dev/null @@ -1,697 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.8.5" -manifest_format = "2.0" -project_hash = "1897773a8065215ef94f8d665d12f3684212efac" - -[[deps.AbstractPlutoDingetjes]] -deps = ["Pkg"] -git-tree-sha1 = "8eaf9f1b4921132a4cff3f36a1d9ba923b14a481" -uuid = "6e696c72-6542-2067-7265-42206c756150" -version = "1.1.4" - -[[deps.AbstractTrees]] -git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.4" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.6.2" - -[[deps.ArgCheck]] -git-tree-sha1 = "a3a402a35a2f7e0b87828ccabbd5ebfbebe356b4" -uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197" -version = "2.3.0" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[deps.BangBang]] -deps = ["Compat", "ConstructionBase", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables"] -git-tree-sha1 = "e28912ce94077686443433c2800104b061a827ed" -uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66" -version = "0.3.39" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.Baselet]] -git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e" -uuid = "9718e550-a3fa-408a-8086-8db961cd8217" -version = "0.1.1" - -[[deps.BetterFileWatching]] -deps = ["Deno_jll", "JSON"] -git-tree-sha1 = "0d7ee0a1acad90d544fa87cc3d6f463e99abb77a" -uuid = "c9fd44ac-77b5-486c-9482-9798bd063cc6" -version = "0.1.5" - -[[deps.BitFlags]] -git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.7" - -[[deps.CodeTracking]] -deps = ["InteractiveUtils", "UUIDs"] -git-tree-sha1 = "d730914ef30a06732bdd9f763f6cc32e92ffbff1" -uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" -version = "1.3.1" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "9c209fb7536406834aa938fb149964b985de6c83" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.1" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" - -[[deps.CommonMark]] -deps = ["Crayons", "JSON", "PrecompileTools", "URIs"] -git-tree-sha1 = "532c4185d3c9037c0237546d817858b23cf9e071" -uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" -version = "0.8.12" - -[[deps.Compat]] -deps = ["Dates", "LinearAlgebra", "UUIDs"] -git-tree-sha1 = "7a60c856b9fa189eb34f5f8a6f6b5529b7942957" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.6.1" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.1+0" - -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "96d823b94ba8d187a6d8f0826e731195a74b90e9" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.2.0" - -[[deps.Configurations]] -deps = ["ExproniconLite", "OrderedCollections", "TOML"] -git-tree-sha1 = "62a7c76dbad02fdfdaa53608104edf760938c4ca" -uuid = "5218b696-f38b-4ac9-8b61-a12ec717816d" -version = "0.17.4" - -[[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "738fec4d684a9a6ee9598a8bfee305b26831f28c" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.2" - -[[deps.Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[deps.DataAPI]] -git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.15.0" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DefineSingletons]] -git-tree-sha1 = "0fba8b706d0178b4dc7fd44a96a92382c9065c2c" -uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52" -version = "0.1.2" - -[[deps.Deno_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cd6756e833c377e0ce9cd63fb97689a255f12323" -uuid = "04572ae6-984a-583e-9378-9577a1c2574d" -version = "1.33.4+0" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "bad72f730e9e91c08d9427d5e8db95478a3c323d" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.4.8+0" - -[[deps.ExproniconLite]] -deps = ["Pkg", "TOML"] -git-tree-sha1 = "c2eb763acf6e13e75595e0737a07a0bec0ce2147" -uuid = "55351af7-c7e9-48d6-89ff-24e801d99491" -version = "0.7.11" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" - -[[deps.FromFile]] -deps = ["Downloads", "Requires"] -git-tree-sha1 = "5df4ca248bed8c35164d6a7ae006073bbf8289ff" -uuid = "ff7dd447-1dcb-4ce3-b8ac-22a812192de7" -version = "0.1.5" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.FuzzyCompletions]] -deps = ["REPL"] -git-tree-sha1 = "e16dd964b4dfaebcded16b2af32f05e235b354be" -uuid = "fb4132e2-a121-4a70-b8a1-d5b831dcdcc2" -version = "0.5.1" - -[[deps.Git]] -deps = ["Git_jll"] -git-tree-sha1 = "51764e6c2e84c37055e846c516e9015b4a291c7d" -uuid = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" -version = "1.3.0" - -[[deps.GitHubActions]] -deps = ["JSON", "Logging"] -git-tree-sha1 = "56e01ec63d13e1cf015d9ff586156eae3cc7cd6f" -uuid = "6b79fd1a-b13a-48ab-b6b0-aaee1fee41df" -version = "0.1.4" - -[[deps.Git_jll]] -deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "d8be4aab0f4e043cc40984e9097417307cce4c03" -uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" -version = "2.36.1+2" - -[[deps.Glob]] -git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" -uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" -version = "1.3.1" - -[[deps.Gumbo]] -deps = ["AbstractTrees", "Gumbo_jll", "Libdl"] -git-tree-sha1 = "a1a138dfbf9df5bace489c7a9d5196d6afdfa140" -uuid = "708ec375-b3d6-5a57-a7ce-8257bf98657a" -version = "0.8.2" - -[[deps.Gumbo_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "29070dee9df18d9565276d68a596854b1764aa38" -uuid = "528830af-5a63-567c-a44a-034ed33b8444" -version = "0.10.2+0" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "5e77dbf117412d4f164a464d610ee6050cc75272" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.9.6" - -[[deps.Hyperscript]] -deps = ["Test"] -git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9" -uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" -version = "0.0.4" - -[[deps.HypertextLiteral]] -deps = ["Tricks"] -git-tree-sha1 = "c47c5fa4c5308f27ccaac35504858d8914e102f9" -uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" -version = "0.9.4" - -[[deps.IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.3" - -[[deps.InitialValues]] -git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3" -uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c" -version = "0.3.1" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLLWrappers]] -deps = ["Preferences"] -git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.4.1" - -[[deps.JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.4" - -[[deps.JuliaInterpreter]] -deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "6a125e6a4cb391e0b9adbd1afa9e771c2179f8ef" -uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.23" - -[[deps.LRUCache]] -git-tree-sha1 = "48c10e3cc27e30de82463c27bef0b8bdbd1dc634" -uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" -version = "1.4.1" - -[[deps.LazilyInitializedFields]] -git-tree-sha1 = "410fe4739a4b092f2ffe36fcb0dcc3ab12648ce1" -uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" -version = "1.2.1" - -[[deps.LeftChildRightSiblingTrees]] -deps = ["AbstractTrees"] -git-tree-sha1 = "fb6803dafae4a5d62ea5cab204b1e657d9737e7f" -uuid = "1d6d02ad-be62-4b6b-8a6d-2f90e265016e" -version = "0.2.0" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.3" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "7.84.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.10.2+0" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c7cb1f5d892775ba13767a87c7ada0b980ea0a71" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.16.1+2" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "cedb76b37bc5a6c702ade66be44f831fa23c681e" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.0" - -[[deps.LoweredCodeUtils]] -deps = ["JuliaInterpreter"] -git-tree-sha1 = "60168780555f3e663c536500aa790b6368adc02a" -uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "2.3.0" - -[[deps.MIMEs]] -git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb" -uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" -version = "0.1.4" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.10" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MarkdownLiteral]] -deps = ["CommonMark", "HypertextLiteral"] -git-tree-sha1 = "0d3fa2dd374934b62ee16a4721fe68c418b92899" -uuid = "736d6165-7244-6769-4267-6b50796e6954" -version = "0.1.1" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] -git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.7" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.0+0" - -[[deps.Memoize]] -deps = ["MacroTools"] -git-tree-sha1 = "2b1dfcba103de714d31c033b5dacc2e4a12c7caa" -uuid = "c03570c3-d221-55d1-a50c-7939bbd78826" -version = "0.4.4" - -[[deps.MicroCollections]] -deps = ["BangBang", "InitialValues", "Setfield"] -git-tree-sha1 = "629afd7d10dbc6935ec59b32daeb33bc4460a42e" -uuid = "128add7d-3638-4c79-886c-908ea0c25c34" -version = "0.1.4" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2022.2.1" - -[[deps.MsgPack]] -deps = ["Serialization"] -git-tree-sha1 = "fc8c15ca848b902015bd4a745d350f02cf791c2a" -uuid = "99f44e22-a591-53d1-9472-aa23ef4bd671" -version = "1.2.0" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.20+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1aa4b74f80b01c6bc2b89992b861b5f210e665b5" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "1.1.21+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "d321bf2de576bf25ec4d3e4360faca399afca282" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.0" - -[[deps.PCRE2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.40.0+0" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "a5aef8d4a6e8d81f171b2bd4be5265b01384c74c" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.5.10" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.8.0" - -[[deps.Pluto]] -deps = ["Base64", "Configurations", "Dates", "Distributed", "FileWatching", "FuzzyCompletions", "HTTP", "HypertextLiteral", "InteractiveUtils", "Logging", "LoggingExtras", "MIMEs", "Markdown", "MsgPack", "Pkg", "PrecompileSignatures", "REPL", "RegistryInstances", "RelocatableFolders", "SnoopPrecompile", "Sockets", "TOML", "Tables", "URIs", "UUIDs"] -git-tree-sha1 = "c3127195e4d10d9de5aa7364b5924ae062dcad35" -uuid = "c3e4b0f8-55cb-11ea-2926-15256bba5781" -version = "0.19.25" - -[[deps.PlutoHooks]] -deps = ["InteractiveUtils", "Markdown", "UUIDs"] -git-tree-sha1 = "072cdf20c9b0507fdd977d7d246d90030609674b" -uuid = "0ff47ea0-7a50-410d-8455-4348d5de0774" -version = "0.0.5" - -[[deps.PlutoLinks]] -deps = ["FileWatching", "InteractiveUtils", "Markdown", "PlutoHooks", "Revise", "UUIDs"] -git-tree-sha1 = "8f5fa7056e6dcfb23ac5211de38e6c03f6367794" -uuid = "0ff47ea0-7a50-410d-8455-4348d5de0420" -version = "0.1.6" - -[[deps.PlutoSliderServer]] -deps = ["AbstractPlutoDingetjes", "Base64", "BetterFileWatching", "Configurations", "Distributed", "FromFile", "Git", "GitHubActions", "Glob", "HTTP", "JSON", "Logging", "Pkg", "Pluto", "SHA", "Sockets", "TOML", "TerminalLoggers", "UUIDs"] -git-tree-sha1 = "2bca19d5d90959f6ffda8ec4bcfaa25ebf09b6b7" -uuid = "2fc8631c-6f24-4c5b-bca7-cbb509c42db4" -version = "0.3.25" - -[[deps.PlutoUI]] -deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] -git-tree-sha1 = "b478a748be27bd2f2c73a7690da219d0844db305" -uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" -version = "0.7.51" - -[[deps.PrecompileSignatures]] -git-tree-sha1 = "18ef344185f25ee9d51d80e179f8dad33dc48eb1" -uuid = "91cefc8d-f054-46dc-8f8c-26e11d7c5411" -version = "3.0.3" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "9673d39decc5feece56ef3940e5dafba15ba0f81" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.1.2" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "7eb1686b4f04b82f96ed7a4ea5890a4f0c7a09f1" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.0" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.ProgressLogging]] -deps = ["Logging", "SHA", "UUIDs"] -git-tree-sha1 = "80d919dee55b9c50e8d9e2da5eeafff3fe58b539" -uuid = "33c8b6b6-d38a-422a-b730-caa89a2f386c" -version = "0.1.4" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA", "Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.Referenceables]] -deps = ["Adapt"] -git-tree-sha1 = "e681d3bfa49cd46c3c161505caddf20f0e62aaa9" -uuid = "42d2dcc6-99eb-4e98-b66c-637b7d73030e" -version = "0.1.2" - -[[deps.RegistryInstances]] -deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] -git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" -uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" -version = "0.1.0" - -[[deps.RelocatableFolders]] -deps = ["SHA", "Scratch"] -git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691" -uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.0" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[deps.Revise]] -deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] -git-tree-sha1 = "feafdc70b2e6684314e188d95fe66d116de834a7" -uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" -version = "3.5.2" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.0" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.1.0" - -[[deps.SnoopPrecompile]] -deps = ["Preferences"] -git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" -uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" -version = "1.0.3" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.SplittablesBase]] -deps = ["Setfield", "Test"] -git-tree-sha1 = "e08a62abc517eb79667d0a29dc08a3b589516bb5" -uuid = "171d559e-b47b-412a-8079-5efa626c420e" -version = "0.1.15" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "6b7ba252635a5eff6a0b0664a41ee140a1c9e72a" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.0" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.StringEncodings]] -deps = ["Libiconv_jll"] -git-tree-sha1 = "33c0da881af3248dafefb939a21694b97cfece76" -uuid = "69024149-9ee7-55f6-a4c4-859efe599b68" -version = "0.3.6" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.0" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"] -git-tree-sha1 = "1544b926975372da01227b382066ab70e574a3ec" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.10.1" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.1" - -[[deps.TerminalLoggers]] -deps = ["LeftChildRightSiblingTrees", "Logging", "Markdown", "Printf", "ProgressLogging", "UUIDs"] -git-tree-sha1 = "f133fab380933d042f6796eda4e130272ba520ca" -uuid = "5d786b92-1e48-4d6f-9151-6b4477ca9bed" -version = "0.1.7" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.ThreadsX]] -deps = ["ArgCheck", "BangBang", "ConstructionBase", "InitialValues", "MicroCollections", "Referenceables", "Setfield", "SplittablesBase", "Transducers"] -git-tree-sha1 = "34e6bcf36b9ed5d56489600cf9f3c16843fa2aa2" -uuid = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d" -version = "0.1.11" - -[[deps.TranscodingStreams]] -deps = ["Random", "Test"] -git-tree-sha1 = "9a6ae7ed916312b41236fcef7e0af564ef934769" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.9.13" - -[[deps.Transducers]] -deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"] -git-tree-sha1 = "25358a5f2384c490e98abd565ed321ffae2cbb37" -uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999" -version = "0.4.76" - -[[deps.Tricks]] -git-tree-sha1 = "aadb748be58b492045b4f56166b5188aa63ce549" -uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" -version = "0.1.7" - -[[deps.URIs]] -git-tree-sha1 = "074f993b0ca030848b897beff716d93aca60f06a" -uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.4.2" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.YAML]] -deps = ["Base64", "Dates", "Printf", "StringEncodings"] -git-tree-sha1 = "dbc7f1c0012a69486af79c8bcdb31be820670ba2" -uuid = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" -version = "0.4.8" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.12+3" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl", "OpenBLAS_jll"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.1.1+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.48.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+0" diff --git a/pluto-deployment-environment/PlutoDeployment.toml b/pluto-deployment-environment/PlutoDeployment.toml deleted file mode 100644 index b0eb859d..00000000 --- a/pluto-deployment-environment/PlutoDeployment.toml +++ /dev/null @@ -1,27 +0,0 @@ -[Export] -baked_state = false -baked_notebookfile = false -offer_binder = true -ignore_cache = [ - "index.jl", -] -create_index = false -exclude = [ - # these are in the repo but not used on the website - "tools/*", - "PlutoPages.jl", -] - -[SliderServer] -port = 8080 -host = "0.0.0.0" -exclude=[ - # these are in the repo but not used on the website - "tools/*", - "PlutoPages.jl", - - # notebooks not interactive - - # don't run homeworks - "*/hw*.jl", -] diff --git a/pluto-deployment-environment/Project.toml b/pluto-deployment-environment/Project.toml deleted file mode 100644 index 8c7f90ac..00000000 --- a/pluto-deployment-environment/Project.toml +++ /dev/null @@ -1,22 +0,0 @@ -[deps] -BetterFileWatching = "c9fd44ac-77b5-486c-9482-9798bd063cc6" -CommonMark = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" -Deno_jll = "04572ae6-984a-583e-9378-9577a1c2574d" -Gumbo = "708ec375-b3d6-5a57-a7ce-8257bf98657a" -HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" -JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" -Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" -MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" -Memoize = "c03570c3-d221-55d1-a50c-7939bbd78826" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -Pluto = "c3e4b0f8-55cb-11ea-2926-15256bba5781" -PlutoHooks = "0ff47ea0-7a50-410d-8455-4348d5de0774" -PlutoLinks = "0ff47ea0-7a50-410d-8455-4348d5de0420" -PlutoSliderServer = "2fc8631c-6f24-4c5b-bca7-cbb509c42db4" -PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" -ProgressLogging = "33c8b6b6-d38a-422a-b730-caa89a2f386c" -ThreadsX = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d" -URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" diff --git a/pp_search_data.json b/pp_search_data.json new file mode 100644 index 00000000..4f177064 --- /dev/null +++ b/pp_search_data.json @@ -0,0 +1 @@ +[{"url":"cheatsheets/","title":"Cheatsheets","tags":["welcome"],"text":"Cheatsheets Getting Started with Julia - live . Fastrack to Julia cheatsheet. MATLAB-Julia-Python comparative cheatsheet by QuantEcon group Plots.jl cheatsheet"},{"url":".","title":"index","tags":["homepage"],"text":""},{"url":"installation/","title":"Software installation","tags":["welcome"],"text":"First-time setup: Install Julia & Pluto Text and pictures version: Step 1: Install Julia 1.8.2 Go to https://julialang.org/downloads and download the current stable release, Julia 1.8.2 , using the correct version for your operating system (Linux x86, Mac, Windows, etc). Step 2: Run Julia After installing, make sure that you can run Julia . On some systems, this means searching for the β€œJulia 1.8.2 ” program installed on your computer; in others, it means running the command julia in a terminal. Make sure that you can execute 1 + 1 : Make sure that you are able to launch Julia and calculate 1+1 before proceeding! Step 3: Install Pluto Next we will install the Pluto , the notebook environment that we will be using during the course. Pluto is a Julia programming environment designed for interactivity and quick experiments. Open the Julia REPL . This is the command-line interface to Julia, similar to the previous screenshot. Here you type Julia commands , and when you press ENTER, it runs, and you see the result. To install Pluto, we want to run a package manager command . To switch from Julia mode to Pkg mode, type ] (closing square bracket) at the julia> prompt: \njulia> ]\n\n(@v 1.8 ) pkg>\n The line turns blue and the prompt changes to pkg> , telling you that you are now in package manager mode . This mode allows you to do operations on packages (also called libraries). To install Pluto, run the following (case sensitive) command to add (install) the package to your system by downloading it from the internet.\nYou should only need to do this once for each installation of Julia: \n(@v 1.8 ) pkg> add Pluto\n This might take a couple of minutes, so you can go get yourself a cup of tea! You can now close the terminal. Step 4: Use a modern browser: Mozilla Firefox or Google Chrome We need a modern browser to view Pluto notebooks with. Firefox and Chrome work best. Second time: Running Pluto & opening a notebook Repeat the following steps whenever you want to work on a project or homework assignment. Step 1: Start Pluto Start the Julia REPL, like you did during the setup. In the REPL, type: julia> using Pluto\n\njulia> Pluto.run()\n The terminal tells us to go to http://localhost:1234/ (or a similar URL). Let’s open Firefox or Chrome and type that into the address bar. If you’re curious about what a Pluto notebook looks like, have a look at the Featured Notebooks . These notebooks are useful for learning some basics of Julia programming. If you want to hear the story behind Pluto, have a look a the JuliaCon presentation . If nothing happens in the browser the first time, close Julia and try again. And please let us know! Step 2a: Opening a notebook from the web This is the main menu - here you can create new notebooks, or open existing ones. Our homework assignments will always be based on a template notebook , available in this GitHub repository. To start from a template notebook on the web, you can paste the URL into the blue box and press ENTER. For example, homework 0 is available here . Go to this page, and on the top right, click on the button that says β€œEdit or run this notebook”. From these instructions, copy the notebook link, and paste it into the box. Press ENTER, and select OK in the confirmation box. The first thing we will want to do is to save the notebook somewhere on our own computer; see below. Step 2b: Opening an existing notebook file When you launch Pluto for the second time, your recent notebooks will appear in the main menu. You can click on them to continue where you left off. If you want to run a local notebook file that you have not opened before, then you need to enter its full path into the blue box in the main menu. More on finding full paths in step 3. Step 3: Saving a notebook We first need a folder to save our homework in. Open your file explorer and create one. Next, we need to know the absolute path of that folder. Here’s how you do that in Windows , MacOS and Ubuntu . For example, you might have: C:\\Users\\fons\\Documents\\18S191_assignments\\ on Windows /Users/fons/Documents/18S191_assignments/ on MacOS /home/fons/Documents/18S191_assignments/ on Ubuntu Now that we know the absolute path, go back to your Pluto notebook, and at the top of the page, click on β€œSave notebook…” . This is where you type the new path+filename for your notebook : Click Choose . Step 4: Sharing a notebook After working on your notebook (your code is autosaved when you run it), you will find your notebook file in the folder we created in step 3. This the file that you can share with others, or submit as your homework assignment to Canvas. \nconst run = f => f();\nrun(async () => {\nconst versions = await (await fetch(`https://julialang-s3.julialang.org/bin/versions.json`)).json()\nconst version_names = Object.keys(versions).sort().reverse()\nconst stable = version_names.find(v => versions[v].stable)\nconsole.log({stable})\nconst pkg_stable = /\\d+\\.\\d+/.exec(stable)[0]\ndocument.querySelectorAll(\"auto-julia-version\").forEach(el => {\n console.log(el)\n el.innerText = el.getAttribute(\"short\") == null ? stable : pkg_stable\n})\n});"},{"url":"logistics/","title":"Class logistics","tags":["welcome"],"text":"main a img {\n width: 5rem;\n margin: 1rem;\n}\n Course logistics Describe here the logistics of your class."},{"url":"search/","title":"Search results","tags":[],"text":"window.init_search(); Search Results \nLoading..."},{"url":"assets/scripts/get_highlights/","title":"get_highlights","tags":[],"text":"if isempty get metadata \"homepage\" , \"highlights\", nothing else highlights htl \"\"\" section div class \"content\" h2 x \"name\" h2 p x \"text\" p div div class \"preview\" img src \" x \"img\" \" div section \"\"\" for x in metadata \"homepage\" \"highlights\" htl \"\"\" div class \"subjectscontainer wide\" h1 Highlights h1 div class \"contain\" highlights div div \"\"\" end"},{"url":"assets/scripts/get_subjects/","title":"get_subjects","tags":[],"text":"let sections metadata \"sidebar\" sections htl \"\"\" let input other page.input output other page.output name get output.frontmatter, \"title\", basename input.relative path desc get output.frontmatter, \"description\", nothing tags get output.frontmatter, \"tags\", String image get output.frontmatter, \"image\", nothing class \"no decoration\", \"tag replace x, \" \" \" \" \" for x in tags ..., image nothing || isempty image ? nothing htl \"\"\" a title desc class class href root url \" \" other page.url h3 name h3 img src image a \"\"\" end for other page in collections section id .pages \"\"\" for section id, section name in sections isempty sections ? nothing htl \"\"\" div class \"wide subjectscontainer\" h1 Subjects h1 div class \"subjects\" sections div div \"\"\" end"},{"url":"homework/hw1/","title":"sample homework","tags":["module2","track_julia","track_material","homeworks","pluto","PlutoTeachingTools"],"text":" A Pluto.jl notebook v0.19.25 frontmatter homework number \"1\" order \"2.5\" title \"sample homework\" tags \"module2\", \"track julia\", \"track material\", \"homeworks\", \"pluto\", \"PlutoTeachingTools\" layout \"layout.jlhtml\" description \"sample howework\" using Markdown using InteractiveUtils using PlutoTeachingTools, PlutoUI md\"\"\" Sample Homework This notebook showcases some of the features of `PlutoTeachingTools.jl` https github.com JuliaPluto PlutoTeachingTools.jl and how to use these to write homework assignment in Pluto. \"\"\" tip md\"\"\"For a deeper tour of `PlutoTeachingTools.jl`, check their documentation https juliapluto.github.io PlutoTeachingTools.jl example.html \"\"\" md\"\"\" Useful functionalities `PlutoTeachingTools.jl` has some functions like `correct`, `still missing`, here a few demoes \"\"\" correct still missing keep working keep working md\"you can also give custom text to the boxes\" hint md\"this is a hint, hover the box to unblur the text\" md\"\"\" Exercise 1 a simple exercise Replace missing with the value `1`. \"\"\" x missing if ismissing x still missing elseif x 1 && x isa Int correct elseif x 1 && x isa Int b1 almost md\"\"\"Your variable has the right value, but it's not quite the right answer. Read carefully the instructions\"\"\" b2 hint md\"\"\"What type should the value of x be?\"\"\" md\"\"\" b1 b2 \"\"\" else keep working md\"\"\"That is not the right answer Keep trying \"\"\" end md\"\"\" here is a short demo of how it looks like when the student tries to solve the exercise \"\"\" Resource \"https user images.githubusercontent.com 49938764 249749643 8cc12de3 2b50 4182 b95d 686c2c18332c.mov\", width 500, autoplay \"\", loop \"\" md\"\"\" Exercise 2 Write a function called `myfun` that takes as input an integer and returns its square. Define a variable called `y` and assign `myfun 3 ` to it. \"\"\" let if isdefined myfun func not defined myfun else test values 1, 2, 3, 4, 5 msg1 correct for t in test values if myfun t t^2 msg1 keep working md\"Test failed for input t, expected t^2 , but got myfun t \" break end end msg1 end end if isdefined y var not defined y elseif y 9 correct else keep working md\"Evaluated expression y y is incorrect.\" end md\"\"\" and here is a quick demo of the exercise in action \"\"\" Resource \"https user images.githubusercontent.com 49938764 249748007 d0b2d773 6b21 49d4 89db ad737af510fe.mov\", width 500, autoplay \"\", loop \"\" "},{"url":"mod1_setup_website/basic_info/","title":"Fill course basic information","tags":["module1","track_setup","teaching","metadata"],"text":"Add basic information If you look at the homepage of the template website, you will see it has a bunch of placeholder text, such as β€œname of your course”, β€œa short catchy phrase” etc. To customize this, you will need to customize the metadata of the website. That is, add basic info for your class. To do so, you will need to fill the info in the files under the folder src/_data . Let us analyze these one by one. course_info.jl This file contains a julia Dict with the basic info of the class. For each key ( course_name , course_subtitle , etc.) replace the corresponding placeholder with an appropriate text for your class. When filling the institution_logo data with the name of your university logo file, do not forget to actually put the file under src/assets . Authors are listed as a vector of pairs, where the first element is the author name and the second is their homepage address. If you dont have a homepage address for the author, put an empty string \"\" . homepage.jl This file contains metadata for the info displayed in the homepage, particularly title : the title displayed on top of the homepage disclaimer : the disclaimer displayed below the title. If you don’t want a disclaimer, you can remove this entry. highlights : in this entry you can specify the highlights of your class, which will be displayed on the homepage. This entry should be a vector of highlights. Each entry in the vector should be a dict with the following fields\n name : the title of the highlight text : short description of the highlight img : link to an image summarizing the highlight sidebar.jl In this file you can specify the sidebar of the website. All lecture materials will be grouped in modules in the sidebar, which are defined in this file. The modules in the file are specified as a vector of pairs, in the form module_id => module_title\n for example \"module1\" => \"Week 1: Introduction to the class\"\n To link a file to a module, you will need to add the module identifier in the page tags. For more info about this, see Add frontmatter tracks.jl In this file you will specify tracks. Tracks can be used to group lectures across modules, e.g. if they have a commmon theme. When a track is selected on the sidebar, only the pages\nbelonging to that track will be highlighted. Similar to modules, tracks are stored in a vector of pairs in the form track_id => track_title\n for example \"julia\" => \"πŸ’» Julia programming\"\n To link a file to a track, you will need to add the track id, prefixed with track_ , to the tags of the page. For example, to add a lesson to the julia track defined above, you would add the tag track_julia to the tags of that lesson file. License Choosing an appropriate license is important to make your material properly reusable. For text, popular licenses are Creative Commons , for example CC BY-SA 4.0 For code, an OSI open source license is recommended. For example MIT or Apache 2.0 license. To add the license, open the file LICENSE.md and replace the text \n with your license(s)."},{"url":"mod1_setup_website/getting_started/","title":"Getting started","tags":["module1","track_setup","teaching","repository structure"],"text":"Fork the template Go to the template repository and click Use this template on the top-right corner. This will fork the repository under your github profile. Folder structure Let us have a look at what this repository looks like. The most important folder, where you will be mainly working is src . Here you will place all your lecture materials. So let us take a closer look at this. Opening the src folder, you will see the following _data folder: here you will place metadata about your website (university name, class semester, define tracks, etc.), more on this in the next lesson. _include : This folder contains the layout templates that are used to generate the final pages on your website. Unless you want to tweak the layout, you will not need to modify this. assets : in this folder you can place all attachements, such as your university logo and other pictures. The folder also contains the CSS and scripts used to render the website. That was for the β€œinfrastructure part” of the website, the rest is content! To add new pages to your website, simply them under the src folder. You can group them in subfolders, as done in this template, but that is not a strict requirement. When downloading this template, you will get the following material: installation.md : this page contains instructions on how to install Julia and Pluto. If you find it useful, you may keep it as is, or edit to match your wanted installation instructions. cheatsheets.md : contains a list of julia related resources. Again, you can keep it or remove it. logistics.md : empty markdown page, where you can describe the logistics of your class index.jlmd : this is used to render the homepage. Do not remove or modify this! search.md : this is used to render the search tab on the sidebar, do not modify or remove this file. The remaining folders mod1_setup_website mod2_add_material mod3_publish_website homework are placeholder samples, used to showcase what a deployed website looks like. As a bonus, these placeholder files actually document how to use this template. You can read it and see what the final result looks like on the template webpage . When starting adding your course material, you will most likely want to remove these."},{"url":"mod1_setup_website/working_locally/","title":"Working locally","tags":["module1","track_setup","track_julia","PlutoSliderServer","pluto"],"text":"Working locally Open this repository in VS Code, and install the recommended extensions. To start running the development server, open the VS Code command palette (press Cmd+Shift+P ), and search for Tasks: Run Task , then PlutoPages: run development server . The first run can take some time, as it builds up the notebook outputs cache. Leave it running. This will start two things in parallel: the PlutoPages.jl notebook (which generates the website), and a static file server (with Deno_jll). It will open two tabs in your browser: one is the generation dashboard (PlutoPages), the other is the current site preview (Deno_jll). Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the β€œRead input files again” button. Note! : This workflow is recommended for writing static content, styles, and for site maintenance. But for writing Pluto notebooks, it’s best to prepare the notebook first, and then run the site (because it re-runs the entire notebook on any change)."},{"url":"mod2_add_material/add_markdown/","title":"Add markdown files","tags":["module2","track_material","markdown","frontmatter"],"text":"Add markdown files If your lecture does not need to run code or use interactivity. You can write it as a markdown file. As an extra twist, you can evaluate julia code inside a $ symbol. For example, $(1 + 1)\n will become 2 Add Front-matter For each file, markdown or pluto, you will need to add a front-matter , which specifies the page metadata. For markdown files, the front-matter is specified at the top of the file between three dashes --- . For example, the front-matter of this file is ---\ntitle: \"Add markdown file\"\norder: 1\nchapter: 2\nsection: 1\nlayout: \"md.jlmd\"\ntags: [\"module2\", \"track_material\", \"markdown\", \"frontmatter\"]\n---\n You will need to specify the following attributes title : title of the page order : the position of the page in the module on the sidebar. Hint! : You can also use fractional numbers, e.g. 1.5 . This can be handy for homeworks, so you can include the homework between the first and second lesson without messing up lessons counting. layout : set to \"md.jlmd\" , unless you are using some custom layout chapter and section (optional): used to number the page. If for example chapter=1 and section=2 , the page will be displayed as 1.2 on the sidebar and page header. image (optional): link to summarizing image to display in the subjects section on the homepage. If left empty, the page wont be included in the subjects section. If no page has an image field in the front-matter, the subjects section is not displayed. description (optional): short description of the notebook youtube_id (optional): youtube id of the video associated with the page. If included, the page header will embed the youtube video. homework_number : needed only for homeworks, the number of the homework tags : list of keywords for the page. It should at least include the module name, as defined in _data/sidebar.jl to include the page in the sidebar. You can also associate pages to a given track by adding the track id, prefixed with track_ to the tags. For example, if you want to include the page in the julia track, add track_julia in the tags list. Markdown 101 If you are not familiar with markdown, you can see for example here . Here is a quick and dirty cheatsheet Use # for headers, for example # Header\n## Subheader\n### Sub-sub-header\n You can create links with the syntax [text](adddress)\n For example the link to the mardown tutorial above was typed as [here](https://www.markdowntutorial.com/)\n You can insert pictures with the syntax ![optional alternative text](link-to-picture)\n for example ![](https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.png)\n will give"},{"url":"mod2_add_material/add_pluto/","title":"Add Pluto notebooks","tags":["module2","track_julia","track_material","Pluto","PlutoUI"],"text":" A Pluto.jl notebook v0.19.25 frontmatter chapter 2 section 2 order 2 image \"https raw.githubusercontent.com fonsp Pluto.jl 580ab811f13d565cc81ebfa70ed36c84b125f55d demo plutodemo.gif\" title \"Add Pluto notebooks\" tags \"module2\", \"track julia\", \"track material\", \"Pluto\", \"PlutoUI\" layout \"layout.jlhtml\" using Markdown using InteractiveUtils using PlutoTeachingTools, PlutoUI TableOfContents md\"\"\" Add Pluto notebooks Pluto.jl https plutojl.org is a revolutionary text editor for reactive and interactive programming. To start creating a Pluto notebook, open a terminal and launch Julia, then do ```julia using Pluto Pluto.run ``` This will launch a Pluto session, where you can write your notebook. To add the front matter, you can use Plut FrontmatterGUI, as the following short video clip shows. danger md\"For pluto notebooks, you will need to set layout to layout.jlhtml\" \"\"\" html\"\"\" video controls \"controls\" width \"800\" height \"600\" name \"Video Name\" source src \"https user images.githubusercontent.com 6933510 207080363 b912d591 f6f6 4522 a6fe 701e5ab04f0b.mov\" video \"\"\" md\"\"\" Pluto 101 Pluto is a notebook for Julia It is reactive , lightweight and has powerful interactivity tools . This will allow you to make your lesson material more engaging for students. Here are a few highlights of Pluto. tip md\" To learn more, check out Pluto featured notebooks https featured.plutojl.org , the JuliaCon video at the beginning of this notebook, or the presentations at PlutoCon 2021 https www.youtube.com playlist?list PLP8iPy9hna6T5sNOTeGdiqygHe 09geEW .\" Writing code in Pluto In Pluto code is written in cells, to add some code, simply create a new cell and type in. Each cell should contain 1 julia expression function definition, if statement, variable assignment, etc. . ```julia if rand 0.5 \"hi\" else \"there\" end ``` or ```julia a 1 ``` or ```julia function f return rand ^ 2 end ``` However , multiple expressions in the same cell are not allowed, for example ```julia a 1 b 2 a b ``` cannot be written in the same cell. You have two alternatives 1. Split it into multiple cells recommended to make reactivity better . 2. Wrap your staments inside a `begin ... end` or `let ... end` block. The difference is that the latter introduces a local scope, hence variables defined inside `let` are not visibles from outside. Reactivity Pluto is reactive This means that if you define a variable `a` in a cell, when you edit the variable value, all cells depending on that variable are automatically re evaluated. A few notes 1. As mentioned above, better to have a single variable assignment per cell, this will make the dependency graph slimmer and reactivity smoother. 2. Code modifying a given variable should be in the same cell, i.e. you cannot have two cells modifying the same variable. Here is a summarizing demo \"\"\" Resource \"https raw.githubusercontent.com fonsp Pluto.jl 580ab811f13d565cc81ebfa70ed36c84b125f55d demo plutodemo.gif\", width 350 md\"\"\" Built in environment Pluto is designed with reproducibility in mind To use packages registered in the Julia general registry, just type `using MyPackage` in some cells, as done at the beginning of this notebook. Pluto will automatically download the package The `Project.toml` and `Manifest.toml` what Julia uses to record all libraries, their versions and dependencies are stored inside the notebook, making it fully batteries included Resource \"https user images.githubusercontent.com 6933510 134823403 fbb79d7f dd3e 4712 b5d5 b48ad0770f13.gif\", width 400 \"\"\" md\"\"\" Interactivity Pluto has great support to make your notebooks interactive It allows you to associate variables with sliders and buttons that you can use to interactively change the result of the code. https user images.githubusercontent.com 6933510 136196607 16207911 53be 4abb b90e d46c946e6aaf.gif The easiest way to harness the power of Pluto interactivity is to use PlutoUI.jl https github.com juliapluto PlutoUI.jl , which is showcased in the next lecture https juliapluto.github.io mod2 add material plutoui showcase . \"\"\" "},{"url":"mod2_add_material/plutoui_showcase/","title":"PlutoUI showcase","tags":["module2","track_julia","track_material","Pluto","PlutoUI","interactivity"],"text":" A Pluto.jl notebook v0.19.25 frontmatter chapter \"2\" image \"https user images.githubusercontent.com 6933510 174067690 50c8128d 748b 4f50 8a76 2ce18166642b.png\" order \"3\" section \"3\" title \"PlutoUI showcase\" tags \"module2\", \"track julia\", \"track material\", \"Pluto\", \"PlutoUI\", \"interactivity\" layout \"layout.jlhtml\" using Markdown using InteractiveUtils This Pluto notebook uses bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of bind gives bound variables a default value instead of an error . macro bind def, element quote local iv try Base.loaded modules Base.PkgId Base.UUID \"6e696c72 6542 2067 7265 42206c756150\" , \"AbstractPlutoDingetjes\" .Bonds.initial value catch b missing end local el esc element global esc def Core.applicable Base.get, el ? Base.get el iv el el end end using PlutoUI md\"\"\" PlutoUI.jl Pluto notebooks can use ` bind` to add interactivity to your notebook. It's a simple concept it uses the same reactivity that you have when editing code, except now you use sliders and buttons, instead of editing code. This notebook showcases some features of `PlutoUI.jl` , which allows you to easily add interactivity to your notebooks. This notebook is from Pluto featured notebooks https featured.plutojl.org , make sure to also check the others to learn more cool Pluto tricks \"\"\" md\"\"\" To use it in other notebooks Simply import the `PlutoUI` package, and Pluto's built in package manager takes care of the rest \"\"\" TableOfContents This is all you need to get a nice table of content md\"\"\" Basics \"\"\" md\" Slider\" bind x Slider 5 15 x md\"The first argument is a `Vector` or range. You can set the default value using a keyword argument \" bind y Slider 20 0.1 30, default 25 y md\"\"\" Scrubbable `Scrubbable` makes a number interactive, you can click and drag its value left or right. Try it in the text below \"\"\" md\"\"\" If Alice has bind a Scrubbable 20 apples, and she gives bind b Scrubbable 3 apples to Bob... \"\"\" md\"\"\" ...then Alice has a b apples left. \"\"\" md\"\"\" Use the Live Docs to learn more about `Scrubbable` \"\"\" md\" NumberField A `NumberField` can be used just like a `Slider`, it just looks different \" bind x different NumberField 0 100, default 20 md\" CheckBox\" bind z CheckBox z md\"Default value \" bind having fun CheckBox default true having fun having fun ? md\"🎈🎈\" md\"β˜•\" md\" TextField\" bind s TextField s md\"With a default value \" bind sentence TextField default \"te dansen omdat men leeft\" sentence md\"You can also create a multi line text box \" bind poem TextField 30, 3 , \"Je opent en sluit je armen,\\nMaar houdt niets vast.\\nHet is net zwemmen\" poem by Sanne de Kroon split poem, \"\\n\" md\" Select\" bind vegetable Select \"potato\", \"carrot\" vegetable bind favourite function Select sin, cos, tan, sqrt favourite function 2 md\"Instead of an array of values, you can also give an array of pairs , where the first item is the bound value, and the second item is displayed. \" bind fruit Select \"apple\" \"🍎\", \"melon\" \"πŸ‰\" fruit md\"\"\" MultiSelect This widget allows the user to select multiple element by holding `Ctrl` `Cmd` while clicking a more items. \"\"\" bind vegetable basket MultiSelect \"potato\", \"carrot\", \"boerenkool\" vegetable basket md\"Just like `Select`, you can also give an array of pairs.\" md\"\"\" MultiCheckBox This widget allows the user to select multiple elements using checkboxes. \"\"\" bind fruit basket MultiCheckBox \"apple\", \"blueberry\", \"mango\" fruit basket md\"\"\" You can use `MultiSelect` and `MultiCheckBox` with any vector of objects, not just strings \"\"\" bind my functions MultiCheckBox sin, cos, tan f Ο€ for f in my functions md\"Just like `Select`, you can also give an array of pairs. See the Live Docs for `MultiCheckBox` for all the customization options \" md\" Button\" bind clicked Button \"Hello world\" clicked md\"\"\" Button as reactive trigger In the example above, any cell that references `clicked` will re evaluate when you click the button. This means that you can a button as a reactive trigger , by referencing its value in another cell. \"\"\" bind go Button \"Recompute\" let go md\"I am rand 1 15 years old \" end md\" FilePicker\" bind important document FilePicker important document md\"The file picker is useful if you want to show off your notebook on a dataset or image uploaded by the reader . It will work anywhere you don't access files using their path. The caveat is that large files might take a long time to get processed everything needs to pass through the browser. If you are using large datasets, a better option is to use `Select` to let the reader pick a filename. You can then read the file using `Base.read filename, type `\" md\" Extras\" md\" Clock\" bind t Clock t md\"You can set the interval `5.0` seconds , and disable the UI `true` \" bind t slow Clock 5.0, true t slow md\"You can use a `Clock` to drive an animation Or use it to repeat the same command at an interval just like with `Button`, you can reference a bound reactive variable without actually using it \" md\" DownloadButton\" md\"\"\" The download button is not an input element that you can ` bind` to, it's an output that you can use to get processed data from your notebook easily. The second argument is the output filename . \"\"\" DownloadButton poem, \"poem.txt\" DownloadButton 0x01, 0x02, 0x03 , \"secret data.bin\" md\"\"\" High level inputs \"\"\" md\"\"\" Confirm Normally, when you move a `Slider` ref or type in a `TextField` ref , all intermediate values are sent back to ` bind`. By wrapping an input element in `confirm`, you get a button to manually control when the value is sent , intermediate updates are hidden from Pluto. \"\"\" bind distance confirm Slider 1 100 distance md\"\"\" `confirm` can be wrapper around any input element to create a new one, including inputs from other packages, or inputs that you have made yourself \"\"\" md\"\"\" Combine This next high level component is a bit tricky, but very powerful Using `combine`, you can create a single input out of multiple existing ones In the example below, we create a new input, `wind speed input` . Notice that the list of wind directions is dynamic if you add a new direction, a 5th slider will appear \"\"\" import PlutoUI combine function wind speed input directions Vector return combine do Child inputs md\"\"\" name Child name, Slider 1 100 \"\"\" for name in directions md\"\"\" Wind speeds inputs \"\"\" end end bind speeds wind speed input \"North\", \"East\", \"South\", \"West\" speeds speeds.North md\"\"\" Use the Live Docs to learn more about `combine` and to see additional examples. πŸ™‹ `combine` is very useful in combination with HypertextLiteral.jl https github.com MechanicalRabbit HypertextLiteral.jl , which you can learn using our JavaScript sample notebook. \"\"\" md\"\"\" Loading resources Notebooks use data from different places. For example, you use `Base.read` https docs.julialang.org en v1 base io network ~ text read filename%3A%3AAbstractString%2C%20String to access local data files inside your Julia code, and `Downloads.jl` https github.com JuliaLang Downloads.jl for remote data interwebs . `PlutoUI` helps you communicate with the person reading the notebook To get remote media URL inside your Markdown text , use `PlutoUI.Resource`. To get local media file inside your Markdown text , use `PlutoUI.LocalResource`. With media , we mean images , video and audio. We strongly recommend that you use remote media inside Pluto notebooks If your notebook uses local images, then those images will not show when someone else opens your notebook, unless they have the same images on their computer, at the exact same location. More on this later. \"\"\" md\"\"\" Resource If you just want to show images inside Markdown , you can use the built in syntax without `PlutoUI` ``` md\"Here is a dog https fonsp.com img doggoSmall.jpg \" ``` `PlutoUI.Resource` has some extra features specify image dimensions and spacing support for videos support for audio\"\"\" dog url \"https upload.wikimedia.org wikipedia commons thumb 1 15 Welsh Springer Spaniel.jpg 640px Welsh Springer Spaniel.jpg\" Resource dog url, width x x different t rex url \"https upload.wikimedia.org wikipedia commons transcoded 6 62 Meow.ogg Meow.ogg.mp3\" flower url \"https upload.wikimedia.org wikipedia commons 4 41 Sunflower Flower Opening Time Lapse.ogv\" md\"\"\"Hello I am a dog Resource dog url \"\"\" md\"\"\"And I sound like this Resource t rex url \"\"\" md\"\"\"This is my flower friend Resource flower url, width 200 \"\"\" md\" Attributes You can pass additional HTML attributes to `Resource`, these will be added to the element. For example \" md\"\"\" Resource dog url, width 20 Resource dog url, width 50 Resource dog url, width 100 Resource dog url, width 100, style \"filter grayscale 100% border 3px solid black \" \"\"\" Resource flower url, width 200, autoplay \"\", loop \"\" md\" YouTube, Vimeo, etc. If you use `Resource` for video, the URL has to point to a video file like `.mp4` or `.mov` . Popular video sites don't give you that link, instead, you can use their embed codes . You can find these inside the video player, by right clicking or using the menu buttons. You then use that inside an HTML block ``` html\\\"\\\"\\\" ~ paste embed code here ~ \\\"\\\"\\\" ``` You might need to change the `width` to `100%` to make it fit.\" html\"\"\" div style \"padding 56.25% 0 0 0 position relative \" iframe src \"https player.vimeo.com video 438210156\" style \"position absolute top 0 left 0 width 100% height 100% \" frameborder \"0\" allow \"autoplay fullscreen\" allowfullscreen iframe div script src \"https player.vimeo.com api player.js\" script \"\"\" md\" LocalResource not recommended The examples above use `Resource` to make media from a URL available inside Markdown. To use local files , simply replace `Resource` with `LocalResource` , and use a file path instead of a URL.\" html\" span style 'font family cursive color purple ' I really hope that this works span \" md\"\"\"Hello I am a dog LocalResource \"C \\\\Users\\\\fons\\\\Pictures\\\\hannes.jpg\" \"\"\" md\"\"\" html\" span style 'font family cursive color purple ' OOPS span \" , it didn't html\" br \" Here are two tips for getting local images to work correctly 1. Go to imgur.com https imgur.com and drag&drop the image to the page. Right click on the image, and select \"Copy image location\". You can now use the image like so ```PlutoUI.Resource \"https i.imgur.com SAzsMMA.jpg\" ``` 2. If your notebook is part of a git repository, place the image in the repository and use a relative path ```PlutoUI.LocalResource \".. images cat.jpg\" ``` \"\"\" md\" Why does it have to be so difficult? Pluto only stores code in the notebook file, not images. This minimal file format is very valuable, but it means that images need to be addressed , not stored. Addressing local files is fragile if someone else opens the notebook, or if you move the notebook to a different folder, that image file needs to be available at exactly the same path. This is difficult to do correctly, and if it works for you, it is hard to tell if it will work for someone else. Putting images online might be a hassle, but once it works, it will work everywhere The stateless nature of URLs means that the images will work regardless of how the notebook file is accessed, while keeping a minimal file format.\" md\" PlutoUI without Pluto Huh? Did you know that you can run Pluto notebooks without Pluto ? If your notebook is called `wow.jl`, then ```sh julia wow.jl ``` will run the notebook just fine. When you use ` bind`, your notebook can still run without Pluto Sort of. Normally, all bound variables are assigned the value `missing` when you run it elsewhere. However, the `PlutoUI` types have all been configured to assign a more sensible default value. For example, if your notebook contains ```julia bind x Slider 10 20 ``` and you run it without Pluto, then this statement simply assigns `x 10`. \" md\"`Pluto` and `PlutoUI` work independently of each other In fact, you could write a package with fun input elements, or add ` bind`able values to existing packages.\" md\" Appendix\" space html\" br br br \" space space space space space "},{"url":"mod3_publish_website/deploy_static/","title":"Deploy your website as static","tags":["module3","track_setup","deploy","netlify","github actions","github pages"],"text":"Deploying with github pages Deploying your website as static page with github pages is a breeze. Whenever you push to main, the website will be deployed to a branch called gh-pages . All you need to do is go to your repository and from Settings > Pages choose to deploy from gh-pages branch, as the following picture shows. After that, the website will be available at https://yourusername.github.io/your-repository-name\n Note that this is a static webpage, so sliders will not work. Students will still be able to play with interactivity by downloading the notebook or running it on binder. If you want interactivity to work on the webpage, you can either Precompute the notebooks outputs (experimental) or Run your own server"},{"url":"mod3_publish_website/precompute_output/","title":"Precompute the pluto notebooks","tags":["module3","track_setup","track_julia","deploy","precompute","Pluto","PlutoSliderServer"],"text":"COMING SOON"},{"url":"mod3_publish_website/setup_server/","title":"Setup a server for your website","tags":["module3","track_setup","deploy","server","dynamic","droplet"],"text":"COMING SOON"}] \ No newline at end of file diff --git a/search/index.html b/search/index.html new file mode 100644 index 00000000..1d50a633 --- /dev/null +++ b/search/index.html @@ -0,0 +1,157 @@ + + + +Search results β€” Name of your course + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +

Search results

+ + +
+
+
+ +
+
+

Search

+ +

Results

+
+Loading... +
+
+
+ + +
+
+ + diff --git a/src/_data/course_info.jl b/src/_data/course_info.jl deleted file mode 100644 index 37a30352..00000000 --- a/src/_data/course_info.jl +++ /dev/null @@ -1,13 +0,0 @@ -Dict( - "course_name" => "Name of your course", - "course_subtitle" => "a short catchy phrase about your course", - "code" => "code of your course", - "semester" => "Fall 20XX", - "authors" => [ - "First author name" => "first author homepage link", - "Second author name" => "second author homepage link" - ], - "institution" => "Your university (or similar) name", - "institution_logo" => "name of your institution logo file, e.g. `logo.svg`. Place this under `assets`", - "repo" => "link to the repository of the source code" -) \ No newline at end of file diff --git a/src/_data/homepage.jl b/src/_data/homepage.jl deleted file mode 100644 index 1ab7bd81..00000000 --- a/src/_data/homepage.jl +++ /dev/null @@ -1,36 +0,0 @@ -Dict( - "title" => @htl("Computational thinking website template"), - - # # add a disclaimer to the course webpage. Remove it if you dont want to include it. - "disclaimer" => md""" - This template will allow you to build a website like the **Computational thinking with Julia** class tought at MIT. - Use it to harness the power of Julia and Pluto in your own teaching and enhance students learning experience. - """, - - # Highlights the key features of your class to make it more engaging. Remove it if you dont want to include it. - "highlights" => [ - Dict("name" => "Easy to customise", - "text" => md"Let the template automate all of the website development and infrastructure, so that you can focus on the most important thing: - **easily develop your lesson materials!**", - "img" => "https://user-images.githubusercontent.com/6933510/168320383-a401459b-97f5-41df-bc7b-ebe76e4886cc.png" - ), - Dict("name" => "Revolutionary interactivity with Pluto.jl", - "text" => md""" - Thanks to Pluto.jl, the website is built using real code, and instead of a book, we have a series of interactive notebooks. - **On the website, students can play with sliders, buttons and images to interact with our simulations.** - You can even go further, and modify and run any code on our website! - """, - "img" => "https://user-images.githubusercontent.com/6933510/136196607-16207911-53be-4abb-b90e-d46c946e6aaf.gif" - ), - Dict("name" => "Learn Julia", - "text" => md""" - In literature it's not enough to just know the technicalities of grammar. - In music it's not enough to learn the scales. The goal is to communicate experiences and emotions. - For a computer scientist, it's not enough to write a working program, - the program should be written with beautiful high level abstractions that speak to your audience. - **Julia is designed with this purpose in mind, use it in your teaching to harness its power.** - """, - "img" => "https://user-images.githubusercontent.com/6933510/136203632-29ce0a96-5a34-46ad-a996-de55b3bcd380.png" - ) - ] -) \ No newline at end of file diff --git a/src/_data/sidebar.jl b/src/_data/sidebar.jl deleted file mode 100644 index 14ad5661..00000000 --- a/src/_data/sidebar.jl +++ /dev/null @@ -1,6 +0,0 @@ -[ - "welcome" => "Welcome", - "module1" => "Module 1: Website setup", - "module2" => "Module 2: Adding course material", - "module3" => "Module 3: Publishing your website" -] \ No newline at end of file diff --git a/src/_data/tracks.jl b/src/_data/tracks.jl deleted file mode 100644 index 4b3b0e24..00000000 --- a/src/_data/tracks.jl +++ /dev/null @@ -1,5 +0,0 @@ -[ - "julia" => "πŸ’» Julia programming", - "material" => "Material development", - "setup" => "Website maintenance" -] \ No newline at end of file diff --git a/src/_includes/layout.jlhtml b/src/_includes/layout.jlhtml deleted file mode 100644 index 4b34c276..00000000 --- a/src/_includes/layout.jlhtml +++ /dev/null @@ -1,200 +0,0 @@ -$(begin - import Pluto - "The contents of `` from a Pluto HTML export." - const pluto_head = let - default = Pluto.generate_html(; - pluto_cdn_root=Pluto.PLUTO_VERSION < v"0.19" ? "https://cdn.jsdelivr.net/gh/fonsp/Pluto.jl@9ca70c36/frontend/" : nothing) - m = match(r"(.*)"s, default) - reduce([ - # r""s - r"" - r"" - r"" - r"" - ]; init=m[1]) do s,r - replace(s, r => "") - end |> HTML - end - - f(x,y) = get(page.output.frontmatter, x, y) - - function section_number(frontmatter) - ch = get(frontmatter, "chapter", nothing) - se = get(frontmatter, "section", nothing) - - isnothing(ch) || isnothing(se) ? nothing : "$(ch).$(se)" - end - - nothing -end) - - -$(f("title", splitext(basename(page.input.relative_path))[1])) β€” $(metadata["course_info"]["course_name"]) -$(let d = f("description", nothing) - if d !== nothing - @htl("""""") - end -end) - - - - - - - - - - - - - - - - - - - - - -$(pluto_head) - - - -
- - -
- $(isempty(f("title", "")) ? nothing : @htl("""
- $(if !isempty(f("homework_number", "")) - @htl("""

Homework $(f("homework_number", ""))

""") - elseif !isempty(f("chapter", "")) && !isempty(f("section", "")) - @htl("""

Section $(f("chapter", "-")).$(f("section", "-"))

""") - else - nothing - end) -

$( - f("title", basename(page.input.relative_path)) - )

- - $(!isempty(f("youtube_id", "")) ? @htl(""" -
- -

Lecture Video

-
- -
-
- """) : nothing) -
""")) - $(content) - -
-
- - diff --git a/src/_includes/md.jlmd b/src/_includes/md.jlmd deleted file mode 100644 index a4b45795..00000000 --- a/src/_includes/md.jlmd +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: "layout.jlhtml" ---- - -
-
-$(content) -
-
\ No newline at end of file diff --git a/src/_includes/welcome.jlmd b/src/_includes/welcome.jlmd deleted file mode 100644 index c88d607c..00000000 --- a/src/_includes/welcome.jlmd +++ /dev/null @@ -1,16 +0,0 @@ ---- -layout: "layout.jlhtml" ---- - - - - - -$(isempty(get(metadata["homepage"], "disclaimer", "")) ? nothing : @htl("""""")) - -
-$(Base.include(@__MODULE__, joinpath(@__DIR__, "..", "assets", "scripts", "get_highlights.jl"))) -$(Base.include(@__MODULE__, joinpath(@__DIR__, "..", "assets", "scripts", "get_subjects.jl"))) -
\ No newline at end of file diff --git a/src/assets/favicon.ico b/src/assets/favicon.ico deleted file mode 100755 index 8ea641a90b6f3b9cba556ba83f6876a7c46325aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121130 zcmeI5>04CC(!j|-a6i4z`}uynpWft6y!R$52nq<|f(tIlCWuRnCK@#{8rK+a)M(;{ zD{B;y7z~K)xWy%G0l|HVCN6Qo1w|Awb-RYNo<4JCff;5FR2`pVpBZN9Q}yfW>gwtq zAD=hGzwB%u@&Dg_{^$G~KL6|EK;fA=$h@gsK~O@dR_k^6PTGJP#mj3v2xV874y^tDWxudb7YEB?T9F^=N- z(5}-BbFa!4Z6eNjcJ#ow?PZ>WV&BKZV-$?Rb~K)KljEn%sfRh0{S3xmojq_qO1_Uv zwVz^nct##Lo_BO`-|rb+F!T21jB^E!JXef$u^jEok>%qV`Cz__y#sw))`e$u!E&}Q z=W}RVZ6s%5{yxjkzWi7|o|TWSIf5%sIgg)N^el^xNcpcxmq6**1s!W#DnWh1dBxD>HtbclsdQ-vy5=ocqUi)#P?nj;}CJfbE5M z>;=o+Ik{ubKOQ*m$})3KW-KS~$q8BI^;F)IKeO+=>~XyS%gcFrv8=o&E1m~%UG}w& zkD;ip5xy(F1xepuhi}ra!P>NIkhJG_$SAr61+|S(bMG4@Fnuqs%v`Vt(z{D7Htl38ZeF{>x9H^FCLT?F6$6)rQXXSi=b1?mqx#1I!Ic&t zxBijs`cNO&F{{RGRNQQWsk6`8VXVT!Wq3p_M8-D2gh^-Yp5w)9!XxS+D6|^Tch$2h zAIDE`faAYCVjF8G32SQu%APQ{{qqRj`_63Z%o2z7&4+3eEp4m zijZN|P$*&t)a|JL{+U&k)%==!5IoqZ&#!<%!)hRQqJ8^mi%+BHV<(=5Fu}c%ogFZ+ z5`H*-hk4c5S7!A!tEFe|Ly&=Q+OK~ljE(NR9W~-q`&?vfJ@^l(w6f#q!yc%<$GrZ< zE3?|p>IvZ^hK;PT;w3Po%B{9k%c%A`Ht`Gu53-Jh1rMp_xE8be%3k5vJ7GqH6{k3! zj}r`Ond;i>(-1nuy1hguoPxUhJa@o$wHa2YT(jadFtp0UoVK?KY#Rd&?CX+smtVCl z{g{KwW9qCPx%2?~iMXhY8DZH^_>MU4=~^3V+g>BD0m16{4(AL?8t#+kl{%{*%sZ!W z+S{)}#7pbF#;I%{QE?5>M;Ft=*eewqYIL8JS;cX`KJNtMo{|@Dm%~QYD(whu{=SoR z<5-kgowfM9!h)Ze?~hCLUf-{88|Vx82de(bq*gjD%pO=Dh zP51F-dyLF<|f2Wr8&l;Xjd_>zki5ot0E##nU>YD(e+9nfO)jP+@-fBh9axQ zB2KC8|1o#OoAFdfwid@&eMEkjw$3>x=*0slvYK9SQ_;JBV3lcYs^oaUKy_{a*B$nB zKTUss6j@!l{i?z$&ihLy%v$R61QxBm#H?_8DfC z0ILgDT~hRp>qzu$nC%vZ-??9)pbN6t^*|=lHwm zWZ@$mvHATYMyoLZ+-IXF+D%9IM3vR0->UNgnA5Chb#me<*dTmPJzM(6xiOm{f8tgs zn3@cQ(^H}7!!*l@*9GqQ#FMZqdb>@&awlvST&6(TC%fR#=X;zw%RbG7q8X`>7r)u&=VnE1g*gew zUezN~th>_J^M_;f@>a0zQDqhHJt9`^TXA1BWEK6=z2lAT;QoXyP&)fNr`WW|aOs?# zus?CDA+tGA8(~p=nWZiR2dn!93>N)A)x88Mv$`$khLz2l7gY>724nl&*d!>KmEkg@ zdVWhj&VbywBr9eyX0Rltz-q6nZ!+k`s-!NWrrcJlSA`gwI|#!h+>X4v)aCoRZ4z)F6;2Xa`-;dI#yaZExF4Wm8{AV zeOdi@3){|^z)}mZn+WEtN=~t)Y*(cmrcAGcv@zSPI4PQu<}pqsuf-o($8UFz-2xNh ztH}DPQcuikGZd^oV8v-o>x#Y%M z<$=l8@v@5J^m411)z|w27l<*F)Z`*KMlgxkSWqwe1M6PnOj)t74o*sg2^j7A@VYu&_UVi)lEOyyD!g zme&F?Pex5o@_wn>)!M7K;YTq)q~)Nr3u66}xz3iQbF6J^%^7;@t&vx%tRBrip>T@x zQU{%!*Y7NMoqeA^f8cQ1A(FP0Dyv0{)%>XfFUF`GF` z6n0dr|5BlUN6dKZ@0g#Ztt-aZPTipQTS64=YIXfpMfX2OZ!~THFWZMc{}p2xa?C-c zq{!;Y;yQ)ZJQI%pC8M&$d~L05J@#V-vr51ZII`;}MejIAB$+U4iR%lrtRCD}#;g)x z_0W!TMehY3%%$pVTPPB15VWk8uP|yzi*>A)uFPXr39x!N`JlpTcklslO{~_gvJXHbC*Wx2F-7kOrgVp~mAb|S zeQqkTDtVt2V^$|hPbsY89Hz5=qxN+L3o~H-@)a<9)khGsCJsW^4+H-Vq44g;{+6?! zxE{EEC`7G|fmy3Qgm0IB3HggUx7I+P!*V>YidiM#1Ju-CQ&`0umP2BFo|Z#f*ZGUm z;fwz)fbef4;LS~a;s28Qbm)95sV@v(Hv$%a^%>+XN_FZxu`c?#fXbhFpFnAEdve)u zzX@#OL=d-T~8BPlI& zl2t6V>sOZi=QF@QT5kjK@mrgH!9Qgv3>RERX1@>Pv!^+Iju89?q=W-9ZuHsc1JCp(kG%#%hjLDkpG@G_K9=B%- z1f`7<+#55SxMmWRf4&=V|152LDimu5WqYGmQuP5)&sEiz6%KNu*2BaV35J~Z*%1n( zcPF~csGeQq-ZweS@H?YcMFZAJ%WB0DdcVIS+azUHQ3geevR|<#~pLSaE{m^PxMVyPQ+W z?eNSAhJNh4IWsK0R#nmaT}v&G)a@$DB5P|F^xB}tP2Uv0Y51;Kk8vt_9hn(#<-@+c z(HBzI?I7!?N?xh6+VJ=ZjLKH~e(d)#)+G7ybQ!)g7O)Ole_+tgNU`@?6KP(lv%0bN z2Zagb1IPNF=2QQD=p$=c#p_iSY0RqV2c?~*RMtLx2>xlq6ej+?EfB`<=~&EE&zZX( z_ud|&)a|_;1EK2vU6Q&&E-Bm9bv4-v3)t^stlnL$x%xRHcP9v6z*ni`mnZ4^t&~{} z-8D|(0Ov|w<;&gg$N4d>FW{Ft1nQd}leDc=S_xI8Ht<#H_GOL7G9lSeAVbv3JQyt+```SSn zs;?4|9?q;1VfEy_TUPPQQDPjU<-<(Zm@}aF1IljF`<+XQ{_6LaPAIy6drLplaw^-* zKezT*>YRF}h@5Su$m+K>S&H5n8YHid%w+=8ptM6?esML8w?OtY;0IS8<&nkLH zZpUU#F)go=*;B>3K{Yop=L-K`0EJv@%&F^>9IEi@%{42I{0?0ArR@iLZ4H259zI~Z zO2DpSdra8>iK2f$v4@W%X1w+H05SH{vN|qj8aYlWuM0@3-KXdu`&iry#aleu`d;k+ zF<(K;>Z*ziW|fFd#Wq^=uo3dg5z_}q?%y{d0+~Y!9$G5il!Ld8nnN>opBCj8n ze4%jgj<8?j_DnSmuV_!R|FNF9_6F-t z@uWBxpw;uVqJ;{pxRw?7>hV^eFTWRazj0qeZ99t1okfySsW0lR9=r29{Cj(l!o)jU z0$}VO*Y~ZI+;y}ZC;EPzpU`rOaVm;y0VJnbQfC!qu(o=)!UZz&?)G4a^n&k-dk^FO znOaWqdfD-9q-`p*+V1z^o>mF_t@jD+y(0wB#&y&#cJ}q-#C|WhM}eNxu{rOP-4lTA zs`c2UqVYC_>{N3^E%tR=5R7)iKGu%-MW3U$Zq6USAJ?p+pQ6T6a}HYGRCLH~4hZIfgO=V8ZW zO>!HvV}-rOTtEH(mH2&qQ^FwcYAtiBiO(^sDyzur(c4!cEOWe-okNCjpLG9}Vc^Ps z0;6_M1kCT&=T6Bs5tI=@e$218srZ;#wPqFNf^)DR6fZX9RWkLi@MVM2M~ZlCoZa~@ zoD0L(U~KzgtNHr3@YqXvvhT`;TmSw%TjJ-7#pj&8J?Gtl$ana3FO$9>>14k2~I zrLj(!Rb#mr@q&FbuGI?JspdX)hS9)`QLyybW;k*8CNpZsmTL9DtUAxCR&JO>^2PD3 zfN^?#ZlMvoy|xX2(R-)B62WKAua$uF58BV;YsY$ERvpX88ICY^kS+FfOFdHzTTbP{ z=DJ+VHSY6&p>J*nFizW-+Ut>u};uHJp# z%B-?oH8lf&JZrVE`uIhgsq4vhrSoIwo+7)4FJ4$!eaUevZmTBmS6T(5^5F3m+b*-( z;ET;I5>rcghkaJIttPdte>{7xu-Ymn1A=cjMe+C?c;yRsJ28umit`VeXd#be_qV1z8?K+DQ&-gAmUhNsVmomcAIIm zV^bx$9KWK?h#71I&i~u9sghM3cbTESTnD;s=1E(d#L;1i^RLVbT~@rQ`y0A=sv}s@ z{<1H?ta_SRj8R!fQytL?fb#>qW`KG16t8EWG{ZB4xW8jk+h6gt?Iqx6c&fhqJv3#F zYyKX0z(=*kFMbBEAEe2Ur)&q#L%Hj~aT%_8@l@UUduX%`w1MvARPv7g0Q;{r81jUz zK-<@m*p%eZ*%EVJImd;0b(Lit@4GUNa+X(&XL0zEd35G=IKRa) zSZ3B)W-kj{+ARD?ZyuQM!ueUutSx3Qh`D{t?enxPwbv$aJjcE)Gb@?JJ{Q-Ynu$?8 zzc}B8>$kA39G9iVF81@N`{%e(S~ojzJ$I9^x42&h?(c&9V!ju~zL?|g$1&;*b%*`> x6~QIy6m^R_#yuyy`tad{CBPD339tlM0xSWR084-+z!G2yumo5FECDhS_%DdPGmroP diff --git a/src/assets/homepage/bg.afdesign b/src/assets/homepage/bg.afdesign deleted file mode 100644 index 4314e14ee808df9788395bc190375269b44941a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22790 zcmZ^}b9^69xCR>AHX7Sb8oRM=+qP{sPQwO`?Ivk#J85k78}H5UoOADg_xbE_cV=ha z(K9nI7$7f-2nGk{=;o?SA?s*aMF#diz$O1*SLgr2{~H1W`|+x2@}D2>(?EP0WmhM6 zq)(SZ%Eq3yh2=Q@^*^GG~h7s0M%SZS%MpUIY3>Or*>^oys#uDrHPDvkpY}3kr_M6?Fn3 zN8%VL111Ir9j1h~TuiN6KjQdQu0uxiV;@2m%mn;)m^WfVr$2{^EtCv-@b0c!^p6AI zH>Sneu-_6k;G_S zr1?lpY-7Yi5j6Zs`~I9~P<{=@6A~Fluhhgae2~Vh4AI;ZA+m`VmYSReht~QAjG*fe zKqnE%D2K4gp*F7WhfVpDHnf*O^T4_9M$RG7e&Y(q11}afWP_GRQdQ>06LN-3#Ygno z{YcP>W(y`CMo>I}%FQ0WK!d=ifa=~24ihlsI?K>PgK7UI!Y@MDKWtm9PN!}g@ntxf zQOi7L@Zt2Risza-uyHj1Y#GY3Ehht?YZ$kyuMj476lt#w|KD;u;ID;8UThjts# ztpRv)$mRy(Ra?O{TxW}hPJY9wPAaSMnr%Ms;S8hr2TNAMBFYqpk?H?t&FL>o2420x z$Kk(YuUm`CjK-6NTF-wM4Uz~2>(s_&a2BzK#g>_Y7v=y)Xk@I#rQo&0l~I3jmTWfP zj(}1Sz>}RVkXdHYAVQ%f31pFOi-qN4L~)?uzNDGO(+}VxWs|=X7T$ozA|f*e29FKwdBLQD|sJ#?s zh4}l^Kqy=xujTPP~3E5s?|Axxfe)_}JV2YMOgz1y} z2(~}gCV%&+a0eL7t#A~fBsb$57>lt}Eyg;GI z$fzqprAHHg0r8W#jxzQ#xqFEc#o|+pu~~~cRq|?16_Xf#C3+3+{G*Xy-c4LOH^9`t z&6tlJdj+irfMWwscMi{-nlOiniN`nS*+C5Q1;~rrljCgi#GI#oE!YJ}%>5QZo|VG! z`|KyoeoeuDR3uuwUaO7HzX>OQz4wi^igbDpa&PQuW0X1zZp>Sk$U4LpGRRyY^wwe4 zx?$NN)+Tb$Ui`!=+1Ol+^!2sh61v!@5b%2YENnLKOD%jd#{3_E%wcnfYrul--r*Uz zdp6=RD{`TXYD&yPWayT26yy#Hn)$(g2S_^Ht!lk}6!K@j?^Glz06S$f-39v~P|n^4 z06GB-3TQT7fjiEfOmreWu&`h#Rwerprg-dy22$1*C&&2^F zf{lX3c@0|0W;ag<-up%=ML*i;!oq}S*~i$^7%|7gbt7mP4iQXhIItVlX*Hwi$MV<> z{sK6bo!ZQgK;7D5p31Z#aGk4zf?sCkgz_wrMpXl?0TzYe$!pJB+z-VNm_<1MCtMnPTn(SKo4FJ~m%Ua#u?D;Y!GQI|P!pZh=E2?r` zYnFgtQ4JGwkKOmuu$6CTF&?$dSrkB8aIc{LX;AX|_z&!NCpr&C#Rp*Y+e&WNC`Mgba0-Dno{+zkfnsNb-DRmjc_+9rOSw&30y76p0_!v;=46`=vnP-0f+2Lu= zDeic9&v$Bi1Dd9f7~|Sv7Vx@}6wGdpky{S+&wfMzGtId#2jb#lJU$m2FFRb^M+5O3 zcx0a_T5Q>px+P39q`2SjzrI#I8Xn92967Y&icU4FuHIIqkbA@gZ8yM;;$_IGSEt(^ zK-%rLNB1>Ip_~#Bj%0Q-RC@y|E|9O59N7?}Zh!0E0GRYV4fi#&ChYUy3YC4tpt&h* zj4i)qel5NWf?mWqPyf1Maxe!}C@zv@UjxR1rBcIMzpd>(p47;O)C*%_ z){xX#m3G~SI9@Hp3Ir4h9-|ylb?x^924P;zlUA*~IE1a=hmD6k*|7X4IaO}eRMqYP zR)XrkK||KouK)+~L2<`Eh$nt@^S$pIaP5XW)N_4J$dPpqSnXtY5Z%5CSU8;kL;My_ zl~1WcI_OabE@Cf1igwPMz*ODZZrW4i?QhoEO&_B<70UUOj6+IlwiKCCQjaewQuT~q zVmMzEDCaA8I4)M50YU>K@9|G7Tgn9Yh;unyF&EiJ{h;B(y7@Ncc0F&-`hcQoxN|Pa zKF&e;qb*wy2j|_X>NdB(1T=|r&zVZV^0lYj!{`>6%c>ZB6AtDJ%ZmQM>wJ>@wO_`Z zSiF1hRTXDPO9YoZcQT4f`t`TrjCzX9MF7Xru;fL{4wLfM=IEXY z%QH|+&)hc$l_;QaSoh)H#hktQ4V!5_ z6p)~i`v!xI#t&_xG89iW&wD4KjKfK54DQ-*Y(3U3;0RbfY5{#oT4e++u2tXa)UdQ@ zu^HU+%NRHnwCOo@%IUvZG{N;&&3%944sWPflWu6aDsaCVjWn$;7b)~m&Q8te@ zZE0j^(*L41NplFt6i?I^-L9HnrC~Ur%$$jzS+2>TKA>MUo1s%NOF6bA+o)>x7G4y` z0BvkWGzc3tjKQ&pCxyvKYYg?J_%@12g2VR7_%VP861I-mI<<%*oq?g7#v5HSh$w9Q z99ktgBs3+O7;4ki*mrk_b|j}P7EIlZXs|q14+{SlgdWe5E;4{(9dC?PQU(bXy~w&i zI-HzB#x9CYT8he}(~Rdr9vXCj$3O}8ZwQ_gFGzWC7><0T;1AZlZ__IvE`~=C%NI|k zG61R7Ek$pERlFbBEHg`JVT~RMwrqTGI5LL9Ss){FMh&_$qx^vkWOM?GM%nm4gyI88mF01$5=$}fQwzFX%In( zEQFahkt^Oggt(qal!x~c?GVlp;Rbr;Y?5KAW4yu}L3VBtL5)e9o>7Nd^ACn3dW3EY z6kb2bM+FSLyB!RcgEJX3eTZ1NvJ~hdql_5;xok7es&%H|Z85 zcxD#+*p`VcpQa<|b-1S-%W{eJPk?{L)#fXXVH}4OOP)oqMV3jS&+Fc$4Mt|>G)BoI zW8gd4P4yP9j7SxnTCB2AtyTT0Y@RdD`s>?6Us>xQ{Ul)a2dJl>Zjl2%CVmNB0hwdw zt3Y2d(1x@D33_2lD?b4WPQ9JgtUWzXPlYpY8tw|E74qydw%KjoJUfQUD}>9}ouz7I zE?u;;ubpyGr~#vupbEAb1+xNy!&kkQy&wGVI}wp?kedf7BlU{ob|^V?-<$_WCK(Vh zC=zGkbK1fn4_|jmp*Slzp!w2Q4lokfczU>h>b-vTZU=k*NOJbw*NEb=wev|> z*WEr1LZ#%-OFU^<9SIFW3^AXIkrYzgsH^xft^NIq3W!rCA=0_R53iKk4)1iR7`cyQ(GjF=yur~}w6B_jK#3O4T5g;)E7J3A zLn=5a1G9bqs2s*uO~Vh^6cfKq)jk_$8;--*??CvwWTOX=&N({<`?2T#G5|nNL1F}b{B&kWVE;J~;-kXo{KP*&&yp#rB+CVpd-;8^`)GvfY20+7p)_YH zlF);oPrjeZmj4Bq%BX%H?WPf@?7SWt>D?10u|c3t@gRw*CEBT zTH3Q*5#6bddXv$@x|c-X5>(GaqjGKjVJpZ~HJJ?uH}uk;3!yi-2~HF=#X3QUPVhK{ z!DJP|;po409U8MkCNRt{g~BoJM@&dT&w}TaVqx!w8~77F0YyOGo$EXpIf+FrxJw02 zWB=!y$snXN7!00qFgOfeJ%jN7pq}8bYll8F$QCj}tXR2n1!j3x!&K+9QQi+rI~bNgFA?Uz@c1Ltd%0dU?E^pEPav+SJU< zgccBPN{}tNzFxH00F>sdCR$6TYPd{3gh8vTf!+Qen+xl2PZK<#hq1fdyn<92cb2@p^p;D!;lB%KU!ZR${jqyrtu;^d&CEdo z_5=8uQ+tdJ2;*GuZiBo!8_$86S zaB=F-beSVqZQ#xa_wmkqb4poT&r6M$lI{AqPPyA|e*l`bJp6$APM&tqJF%UMAduu) zGkhD(ri3JKvO%Oh4gyteFMbp*SB$G+?rU;hUED+}r%Go7O8F&fiXLBtN@Y`pWR~re7_g{G zeaWcx??+RkbZe_~Vi_l1{3w%^@8-gf969^hyT4nOW$6j|LT|!8%kwme-GwA1oqNMi zKc|~q*-u9L2N7bI`)|Xr11iyxvy(UfaNajI<}CU6F&`gsWravin|Vs=$Y{b*eikX$ zcF-i(7rsrsaEUJoiQU;>{ChINUOPL8I(#{z||+-+X? zNk_55$T3i`+u;j17uo`0kbQki>}BskXu1kUx!#Q0zl;Y$p%HNyMLyvLwg>C^RD{B> zn>ix1zY^9<^uH%k(xU^AWPF}z(pIN{wt61N6~KS8$;>>n4jdOPxoKer-D$UmhY{up zW=0$!*o5=gD~IJ}f<{h*a0%MyMyw(dKB|PnJ}L`T)YR0>nxtNzMkA1PP03PSb&022 zr{4hZFfy9BFv);&pMVg8Uns4o?E&3W_ zXo~RMBH@u)j3P>rh*>gsC~MqzEu8eYv|o~F=<&g};9#6_A3$7iWDx)$fWPjRhQuJEPKfMEs35VZK0sbOerYqoU zLT?>iYXV&pWb4@H8p>TY5h|R7oG=PBnOmsOIml_k_;2Shu5#1Qz;8<(4Tm_WHS+#) zux!P(C(I!xUgf5o2+bP1IO%6rafAK1)+TIYP3WzFCkar%v|kYPG9GgNfi&6SIrvm* zW7a}yo;J5y2_tD%dVNhm*z^v-xhEv7#R68n{)5&f3a5aLWxOW;nfgMg)4fIN9Bx2G z_nd#p?)RQU!<(Sv?TydF3nNfZ%m>hO>skWrOxQuheFX84bYUJ|{JuST6_|1E0A`Bs znU8;aP1C&6MVXNUYCn}c8*5hCc#r#Uv0s3$xWF>38IwO>#CAh0zJu*=(XqBV2V`-3W4{OanrWyMo^*va>!Uc5 zk4@lsrAa*W$+q^O_oxvxF4H0F3UK-6(meIS`ld2X0>nZJEmWCmHCEMVit0{;#xD8q{aAdULi*vt^z1yri5cfE=&`E47CWiVfu5kM6h*+Yw{J=Z1OH>^@G)maO>l#Ghd8HBVHhY} z+odWAJbsJ}90z$BI&}j(kA;@pIDl|j!=)U};GkW!{nT&;J}O3<;3u_Q`v5X?G;rfk z>|C^OUIqHfUjg|SbUXrr>RRwHr^-+l;=e?uk!a#jU{IF7TftS4&`Pt_5csn=FpNX+ z2#(33P54Ietl+@=KQCgyz`%pS(v#toF=6>ls8{z|zB_~0kT1vM`QA&$AwVSZkI?wB*Jhc5*(v%yt1f^WQJa1 z^P0-z@H=|>Hs@+kROYczCB#KoP}{o+Jw)bxBYJZKo*eQAe^;V_A(eYf#7YZG0}Cfz zD_x9hou#1iH|cGPN;p{}2g>Kgw#obV8Y%B5lVbfDjHhFS=7JvEz}@);&bfKe9D zg)iH_va&h63nkcrs7D==$3Is#c)=fAu9_X4rxshWoM%Bkp$bHJ7);#~poX${5nHqeg(TNrTw#o=@0Opt18{`6IG#qI$)wknW>>BM9?IJKW>Admx^uz(ZTF5-*uIZ8!i&%oR(B&}EsZpf{Q6=9w zywZFw;u+pXs2W0Z(KQmPvM7B9{G{l^u0~H+kDK`%lOcuC+@BrXrW3}*VVnA~f+P~s zVeNtjVqdxNX}V2UDn*D@VHdsQ2~0-m8p`5dm%&fNb?)`F^-vGnmX;)1`l^h2zOziz z*UXY;echQ#N})(j<@0lF)5&AhcRJ{xR+|kH_6Aqx#+qY=@3WY)+}xww`?nORH@_z> z-K|8?c{kw?wz^07(p0g(7tvFylHjB&UrYzPd`FZcaK`qD7pqv86;jz(`9>jEILuW} zXg8==ngRV&T;P;j)Z7&|)(>~ODsqL?WneF7C$OV=-na9Mxo8u)XSfgY>0E$TYwZ&R!~ zLp!1dCT0xC&2>mv9ZD>|s zW`vGw7HMoSoeaW!8mP=91C9>(9^Xw6o<*tAmlZtQXJH|A*8`N-QN+j3?#ca6r?iE| zvcaQH$vsaJ$)4f)?ywB-+C_1=IyA0)Wf3#RA=R|zRfJN9)5f)`rDWhw_?hs$Rm$r8 z44S8G<#{-Iv_bPKA$3K%*shHF4j-4tG~|gPX;tsChFJXcwQeG`FsAY-$K#q63Lz}H zF)9YQuQi#D_kMA&ENDWrm2T|0*E{Q#w_m<1j< zi)p&~%8l!4Qio4!1yS9f*MZMq{yL;D^LsmM{P?X3!@%ShxBJsgYO;T3OX+3`niIwP z^?}yf0<(YeM)zVOoSDhtVsy6}zC#QNb1n2w0hz<9)Cc$~>V||k98K<+klE`di38T3 zvg$UqNZT)oOeG9Aetm~{QIf;6YXqdX0_?WoFzcgCq>%kxd%GkQfyZ4U!-Zj_P~SzDX3JI>^Nw(4b=@e4BK58a<#$MXR1>p_)X3PtD$u zdKlt1fy-gAnf~gG$0Q~#QY=C{ifK~FO!G4tTiYVOXmX8awdlImHoz5O7WM#Qr_z&u zzW?I!x$nu_of7Hvjzt<=`g=0b!2#?fjogIOkUjg8B{iKy0mKEx4y%3!5_yxpw}^A) zTC(o<)3$jIX8TVA^8Ibd;^dEs-*Zfb)pEd*> z%%^Yn!+7Y^fp?bCaRUQG`Td^(&tO0y1Op=jla&xv_s+ZQv2oKIo8Nh!sOCq+30>Ef z_u9GYb*mRbk)Hhd{6T8Gy^12eT3|)8F=NoV#1xY%W6Gz;bYB9NiUy8G295@H8)ux1 zC3&+ObZ2hyiLsy;766WDjsC2GWtYws>m8jp_5+ScG6+gN7fuRMj^tIf0Oe@dE#OfB z4o$3|&zU5bdX^LX9D-aQD5O9g+I*9Ol7K2B1HWU;4T3XvC~CNE@&Lacczt^QW1HOt z$amw*exZa9MuXtRwYD#E9N`&^JW%^ZDIfE}^u;*dI6m3R*r1erkDM*p!u1gf%Yq0sar0=PWJiKdS&lU(`B+&aWT5}xP37%-jm87Km_LMWM{-&2 zz^sbqsHoTA2#vJdfUK6=`hvMle0%{vVZ(zHdI%#nMrjqjlFA4;sH#z;OASGnN%C4^ z&KCYo!fGJt?iV3No;zoLqHpTe(cE^U>Z}c&uR%hf>7dha#f&)Aoj$9STj1%he{A)Z zP0_*2v*(?o*a4wzgK@`^6Y@$LuVHdD*2uM!3j()-0v4+%u!b+g}baOsu#dlP3vckjOAXhKWD%z{TU zig(>hfGv|K(Q{#6l1u?YxVz;+adUA7VmIG;PRn1ABYo*He^qCW=9~YU^ItD|lg#XX zo0-yeh?Cm{dWeI{BlHMiAs2tp_}uh+`gNV%-o4h;b6I&^gygm}i$v6UvnZU( zlf$bwy7&F~-Tt%tB(ig0)$@anTDmP=*ec$2H{DF~q8zV$VV*e-eC)YZcD-$oDddVnlw}neu zu^T%buS-wCPZ>Ag5r*pRfs#~iJR}tS&J7(?DFiXXQCFZ8X}cmd0g-Aph9VdX6c7){>!?8{PUNw=~L|m!)P@r_V#| zkIt`%h0e+)kUvgs>!j$spEqy2kLyavuJ;adwxf5QgGYOygextg!_S`!RIxf zSII6!aWruW2d2?b_zF0&9<4_qMaC)>^6-G`{!T+PI2Wl{&=0uovG<2)jt;{$2v+F+ug4 zdq6a<08iT2?B+p{mLUw)wWZ^UjaPf_U|S#dLqzg2URmd79Z@=*bSS+Igr5UnD>*|bs)LN$wQO`>Z{gJ3Bh{Ag zg~$4heOnU$js?o$>`0t?Uv0VA7wGi;mrH%6y|H2~6<&46dkozcE*ykZURPc7w(W_` zwXUS_+M~tW=T`^ai@w$IZUHBfUublqMQ%P`{V~>I= zs<|GI4WXB??HEHMcG0j8s;Nz0Uh#VjFs^#?A8hS1{=DtIF7Bh5asX>aP=l|tKAni^ zbzq2shOe(iQeO(x?y6+vipJ2Ub6ta%k9vwmktXSaZRkp6)p#NeWh6!l?_WNqL7Xy~ z_YYiAgZi=%(4+~EosX#JG}xj1z^nGS_~`hvF5JoV;ZV}(_}@Q^j)hwv)S)@YLO1k) zmq*Y~ZQp0OgJsoH1vAL3_bmlcifN%l4!k zesRgeLCiuq^Kqa*gNt^_qoUbR>62Ug=%Bk!ZN>1Y*#c+MF|!s%KqEP~tS6HnuBCrV zHlv1Ky;sh!=94eZ>kIDdw#NdmEEL_#4IWQsi!>(R=NJ-?~Npb;>Zp@M+}gnrOuP zeu|jItEneyoh)`_Ptnft+bmAY7c_61Gu}CF7GTQ zEp#y~-;9H!?a|d#tg^n`FjgWS=lu9S_$4J+N5wtmGiH}eB1-$1-G%Mexp(RPr8PAX zmZH<`j6R7OW0pbJH*d{xchJ(Aw?vPND)*%v%m%+zW5%1cWWxzYt#(iY6lZa>cVehH z64cZu!_b!+2mckVwHe8WwFFX)m^mE*?;r~$D&MTk%#CDFG{!Kn346=Bui41!t9`BN zbCHCXqC!XZZ}0R?hu-b5PjMB$6iL9AxBjrZ%!*y<*}0-_3&ZTGtH^?DT-@qN{VS+f z`@qjTM<{S<+PKL4a853w;ow!c6ehW%A$h()dpzc%ywkfug$8@L~&bC2!2+;EOL6N5wlZUX$r%D za13W-InN)p#_bS*n%vO`LwyAdR@5>JP@?7r^ToN4 zYgvq}^YgdPmFmSFHpZ4-Y#58(c%4W+4%Xjkq-{luW#CRqqJdf)85Wib{S+-`@O8ph~W z2|CuNwt}J<*H$Cr@VCAjkxSEAICo*M^}lQAw?X-r8~EP{Df*p}zVrtF^E> z^)>xnBPj#d&)uJTi*_?TWpoxF=W}1shu?TUNcu@gxxMgwfZE9Q^#0MWvJ&zka{IWy zuG}0+y0ccBh5hxNrV>_*i)v-`D{T5V<-CJN+ zeWrWpIdOkB>=_ZHylZ~%UuV>pY7>)fnD-rjuRr1UdhGA+PAksb0v{B_;T8FSj1yIa zUcbE)kF0tkZ(3B0EhdbByK66<7jH>#l~hI}moM02_Fz0j5qcKb+e0h&r%loeoHtwY z0v^5x)IQl|ZMt5uBoa6;fi5WUCUs@v-|*{GnOnJ8@usiG)t7F)UphOuFBLcLx8$Ww zxrNmNvQKolSL&5&1gsO}7oJ(z$MzV#TQl6`SzwnvcHic=Iy!}k=mOujzDaUa(0s~! zYh-J3h^YzYS#yrza`lK;;T`=6I8+Xfiu(mfF*yv!o;1R z=Y}I4CpR3xc+R0yJ%cV3-j3(O=Nx~vR=4c;jlY%em{QIuy5;;aToi%B~EZbkt$tvI4$1# z^;7rhW{j1-E`o>p=BTC2t1&RnNIta5|HEI7GwWDw$It9Y>4${K-*Mt8i#)|__t~y? zcckS-9(KhNtiB*l^`#a{9~|%3b(h8?yg;UsS4xwoqp2m(Qj?Y1*L6Y;uP@jmK0a9% z;Q}>1Ri&%%q8D||(}%4wH^AGF@ny@P&(ZUqL(}qrheOrd-JyK-f|`D=>Z5NPRO{ux zZ+3<4xDwXummT#xiv@A_k&Wy6YZ7p*MD!mkJ84yLwDOQaA8J$gR_Am~I^R#e%ANoZ zn8!iy46O?tkN4#ZIr#OjoISqux%hoNqGBSg>cWQUv3>8kiV6i1yT_yi+dZvnG#Hyv zEzG(doC!^f_$af4;tQvnFKbiIt|=!W!*SH-maOV;FMjM??GXN;`MawGs+r8w7@qI7 zby&+i+qDNxj*-rxb=f~p%Ze!4m3?~J`{h4>`sZ_gFEf_lXfOVrG+ z=pJnoyRX-`x^5}%&-y1nZ)W05lRcbb2+{K9-Al++a7xY((k1+JVc(Zj$rYG~(kpii zM=ivN9lX8k_#SKC$a(YcvzM0qw=wv~r4g_NXMIp2fQuXTbDX7z!YA7UugpPl{3}?- zSY_&#GYiix$utX>WR-W|nfJ$JO4*9klB3Vve;e+H*WCNwl4|p&60IfgwaMB{nkt3y z<7xT3a!MCuBYu`vg3@|94Mb95LT1?5tQq1N#drT5_4pGP(>*+F z5M#bbyLDmeTI{4|UYk|D;w8rRP^EG_!f=+`5XgyupXZD!Bi4~dp7`$L{k4UPlltdP z*xUz+U^}yfY4O>)Rw8Fij}`UTAg0W(d<>P02PTbOo~iw2X!6gT@5SXS9uJB{wSvji zdwV533W7&PH6%``Gt6d8{(LL?57_ydMH{yu+^r7p8+DB+nrpet0lqy~G9)Pwo(zpN z1@7>f%2*2TZXKm>jsK%x5YD4nlk$TLv9jP$-A$6~%Mv-enmcL#+NyVX&0r~s(!H_- zluBs)PZV={eD+s`2(SS^F}QGKMs&rPEB&H|hTw`S(6Nl4O6cdj=7FV6m#!LJ;2-eL z2Qz`WcN~2MIpEhFNBU`jpm1-t4{C-sURhKL!Or(X>OF{udL29*x>(k&-A!4mL}_3w zICU8$&gmvHxiYMvN#O>PoTT~%k{lRYZLO;bv^FvbY;x}rrOnJpe;Rm@k6SltMvkea za*EnO^Mq$0*VD#eKq2#tGc6=bP5JlxNvka{N-C(SKMB+O{kpVCyo>dnztZv-vc-AZ|mATX(Yf zH5Yo|8z5D|P~<(T@$9NdYDt-4h_8>!Y~WLGC>2{3Hx zfChfR%Q8?+sikU0awj!=_#o1j+6bSgdbq|;pbsB9`<2AO$rgMDQw1d}U|LXVv})n= z@z!U$vKiO9Prit)Pg_6oXEREXMD2@dO43Pg+c;>tXW;p=D2?$yUrCZCMc5mYVWX$d zHTycO&vYs+SK~H(ouhiGt;v_xO1+Zc>`beX#8-*!-uQCeDx-Tk*Ll4=P;&lz)+bPG zdF6EUt@axWAiP%t?mVq>(}gf&Jt&AxHQ) zd!T)S)RujyS>Q+Lg~`MbaQ4JqQG-au4`L8ohdh zf>C~)i@`;EW04FL|1SMq>=Mn(NrE0l05Eb3bTL_q+=z~%a$b$BfJdOx2NEwXJ4wNX z?7K>+E%#G!txRkgd$|fmN;073ly_AQDh7917r$2A;&cD7>jU3@ zwm$T5dvqeiHjo#WN0!lu$%K(~C;rKL$z5Xi^iPB&ds90OBj`9Geq~Rz1T822Mt4t4 z>`+g=Hv##aPP$4O`_Pzk3Bnb!1XfjJUIo{@)7T$p1*5Ob+FuHDKMHvc`iT|(S7t;1 zlUMrFZJIfoYMPAy;L(;d7YRo^=a1^$a2C$5W+w$|FUzSxuiV>yFhj-}hVCzJ(wigM8(`>Y;H z;@-M14rdTPYhDDK{#B$6fW^hopS|#MkQRv}?3w}ZASvp-eFu*~j7$+IzM41G-hF4iVD|DywC2diUR#n_=$CdsmtEV9=^> zlX0g?Y&~0;J8mOkODg%t1oMwi;Zy&sB1Szgo8?D!H})f^=972%vu|C4WAE)0mJmuh zl|g`Lxzwh+BDmz`{ZH02G^ST(D5binX7xgK4YmC!uw&d@C8PZu&!+X#9SnoLF^|H! zuYK4M>&dF^jt@qAb8Z$%i8zE-n|pbTIsc$6sPY2X@{H(f^0_DJ<`OuYJ%|{cPzXpQ zPx-Mv!bgsk<~xt~Y~>#hA!n2b3m!KYI}WF%e*#Zy${H)V207;~_4MU1@`S1|S8Gf0 z7k{`0U_Uz(9jtO@qzZX=;Hk{$sF^J^O93AS=F>r%iTZB=Q!sXoSq`ffkPD?{7=WSh3eT>pw9GB#XTE*<^?6uhpa?$gD~yZYKS6V-+F9PB-+| zuM?MrVDxVJ` z`#CGbPs6$?1)zuU)HAXeNr2b~_y#tyy5aG~U*iY8cmnrczo{*&hneoN36S?kafmxa ztgtZoaR0l18M#GjnK|vk<@{)uHAZ)#vW|AJv{HA%fXFMftHIvxZfxElG10eQe2VW4 zkPSeBz5YQkA}*OZ4Esq)``%6P5=Z`=318FL`le`KBvOeT0yhNLyREqyA zvIf&1(joSCrkeE&A#!InD=KU3MotNNVOO5RU;e*#(UQ7$3YQ|Je{*HdJsUgJdttq! zP%r8HliC^==Zg)5ZMChGI@CoC6N>E(-i16Y>eoDPa^;QfO)jslibN$9>^r1=AqoYh zhe51t0@?>YM3RN#YFz4eaOhSpSOGBPzZpvk-CVCe^ZFXrXrzqWcK`Q$pZ0|Z>KH$; z!#u4bk5m$f+#3cvUKaM={!9CUY`>+965GKQ{ohyFX!{a>c2qFhP!da$Tw2OVH0<)P zW)5ii=f=-VbnR5_&_~yK`*ozbx&^8%@~AwxV(et}F@Jhw44gg9RYLVisLhq0fZOZL z)EI#)4=gajb`#{esQ$z4ONX;a<&fJzT0kkSNzjNS3(Y$J-jJDK_!{q35GUNLjJs4@ zShef3Bz)ijP^|Ab1v91PO>~d4UMrs>{hXScKQGCp;}x;B^F2K5frkC_J++(e7E&_j zFH+O=0*=sA|H-+3)?WHZ^`p#>&y^?9;vV&(P|E>`2#v_5D+VbWzuF*>Y~0sQ zJmxnaG?Q$vr^n$W{bt3Le_n+bBDx83%pXsU^X9a6^oGbYyu=1Yq0(Z}qzp&M1wT$) z5TE%hg4`dS)&($D^kZ!FH(O8BN8-Ljqe(cIphHyEj^)N?GX2R#I1IQj;OK?d;-UC0 zq#yG13ht8&SyfA5k9}|_OBAU3c&aXru~8Hz?)byAhqhZ)+oDoI&Vt=GZ9Y5PWVx7| zZbYv+sjnh5sebQZMJ&3W?Zex*Bx)7Kym6&TOaJcb%}bRhXif||$(7`Q(FZe5I_%G) z0_{9bX|qB~YdN)8lecTh#)xXxN=$85*bE|cVN|$t2Fi)LxPGyXyO;(0^u|oPbw0*X zUi`lYiFyKiA7W~5U!j(~b%ACtbA@5qwPTOFlq8yZt61QNnAEkPhKeE+FW~YLsnXi3 z@JH<7ptf`OcqZuh)6ldmD9xu~Z0X2zMclUlD(bRGsP5|?Jn!abvfi=5f2YN=7X*v+MV?!}!ozVO`k zrL}MT#2ZI$WFD#!x3yFC%jZ#YP_Q&(tQ&k7otkw`9nAOFcEBqqj?}TD&$ywKz_l6+ z44T>4*)g+sqgq`Gw;=l9;xGQ@8rwWfc8(#DjJB^pFnYy9Biyg;t%Qe|;QZKWXlj4G z_+YphhASlS+CK)o;JRxB-y>FBq~RY({QBbHk^^eDf2^E*@k}6fC+J6l&HG3K#OC|9 z@T{=AX(N52?w2`Up2wDKXM5_;MYWm^Dm%q$i=AblXJqG&f1E6wgxBXE>;J7#m-U?R zV0`pN?JXf5@$6izn1Q!Lg2Y_8dAXwy4tf@FViumQ)~de{vYrdbb-BH=>MiKj_j}7< z&((V82;>D43>$J^`K>_^tb;dYpvbtIiPMu%L!THIFDEu581mVwNdN0?j!Ay`uG}!( z9%g!iIZmG>(dEO^fPjpV%g@dR`UOEz!I|abM70w*Te8tPuw|XME2%<-uaWAq8~`n{ zPpGRQx}8qRd^As!Rxt)E;X;E*kOqCOvV7FIG&E)#b}AaTosPWCTrk2zUu;9A-|DN^ zSq(`dBM!IPIpEa3{PvZo=489G7CXFdd?415Fs^n5v#jQO7?x0YaP5UA!rS$bN$i!N z0$THV!5iD5n25Br^xUH*8<0iD zZx4WL`*E!&fzTvTN%+9*>f^S&n4H~Q|DN@bDCf7d6Dv3eOthSk2Q%%3wD=`Ss&O;$ zkOVURKLNcLLg=Q_0MgWPP~AhCvffGui*@i#?j<1gXz#4uJCCjHep)&Ju8G3$5w>pr zWk#X^02g>kL_t*Wc0c?%%*!&?#a<1nP1Wp0d_G~e=)oi9V51$|)`hnYyGQ;U7Uk1j zgVc++aqj}QaXYb1iV65{$Y)ipxj!@!mQHpC7h)>oK`UsdRv*LP8*<9WdKH zoGSRh=wh(bbuD*s&-(Q7;2J#m79q*w0h}8r5So&D1BZiblZRD!xdy5MQe12&C2VU{ zGo-z(d%PhYz7r$(X!WjvBqyY8xX0egJN^jN<<)#4&jsfdgTa2KpeL+v`%CapkC3JS zof5JRXv4#f+YI1+jF@gLoD0xxE1ZR*+&|&hzvn27{k^R~Cj^~ z5WjX!e2oQetJ_sL7pR-Z4`Ekfvm3o!6WtC(p_Pfdmjyt^;!8{=2Oq@_9=vCnxqw#C zX)D~oIGkY&OL^soIE0$=| zzZ2}qW!_Da2zkCA)_yRe19V#ZVeNZxiOZw4&~ESkTiX3AT#FW<|G&(WpM5B`go#<%g(qK-yHT_|VwTC6V)`B)05M4lNJuR*= zD5FruptVAo`15Z`q~gSU!DMNy-a0hll>(z8E2s7>ibnmq~b(> zCR4F4RDARQU0srOii>_m)2w^BZ53v`sY(7F8Gk*_$xrg}-1u6qtv{+iYPgk8Ia;>WmhN0_WhNA@MgigCAG4Vf$1iI}SqXVPTEaz^Niff|EjKww6 z>!MGDL@GM^f?N-#dbQh-GIXaD?j#PRRc-J==(cOpBvwv|K%O-i;}{hQWo2f&8=Vl6 zEG|CF*pm0m6|4gxkgFkWeL(2cBxe2eT z);O2bZacEfqQ`eq2(Dy84_*A~oL@L)E^; z$n~gv3(w+cZ@%a{A>>_xPAPn#Y4Y*te0d|-j~8Q1O%_JfKBx3u8lSE0EV#!+2pCn- zQUg*|&J^1R&Cs1v`Ytvsm&BL%@891}2dRY6KD||aD+IJOwDl!z-ABF|sRKd?iY8=? zT#wRsR(qE_!X*4_={|{6h}=FODWE7^m!a$7Lb{TX-4&kRRy^kkw}SA&D6yUo>Ud2svrbK9Wt7bV?%-uI(`s8Z{lf~ zSg|6Cti@rZB2^_u>bXy9Kw*7C6EZ5_rt<4KxAah$CurYj4S8k&TIUYp_Y9lW0Cg!5=dC^Hx8%n`OYmM&0 zx|EUY#hIOyq^crO$0lo3p7X28LITM25Rl3zUA|TYEMeSPP#%@M6 zaiT>t9_*qIj;mT>2^Vqg??aHQf!T%x8#0mML$fGP9C$|;%TC`Sp#w;qIO|4 ze`=_s=G$ktW2*z@DEcFC6#WrUZqNGE9s;V`;Ugpu6=nD6EQv$GcXy zovnEHBS9bJe&Llc5RZFrs+v{Pyy6{ZG^G9O-^f3_NBo?2eIhg`r&KRq5%!@W%Z4!k z-Z|<~g~^iTcAkZRE(`Lr543;%8@gQFhSjz@41WF#wmrLa_^AMDJh!JL%W6 zC0P5zxN2vwG`V>ICM)?OS!xM^mJ9(+LF|Ar|R9~kJC$@tPr85q*M&aYry1pUZ;s(3i#G3? zj39zcgcre^1efKMZ@#De?k&13c=4bAACk+j3;&2uQU*W&6?<~J){Ea)=8Asaen#RN z@?g7IW?+2u+$ig!OAWAZuNDY^=tcjxbU zKKyb$s4hZ;;g7#C`18Lf=wqZZi-n@A;CVUt%(Kz?QiA&=W%R?(jDGy(DEI>AiY^3B z%090KXXqu;04~cJ{rC&T_dnrpOn}6DWV}Efl#2fSi7#f%6g?q<@L33Y4`3W4Qcx|MAKD`S~-_YDA}A9Hj)UDc^k0=-r>NC#M7; zxx66%^an}*96cJM>*{J|>ssw&?gcQ$NIbnPgz@M2gVW+-p&zf3jQ)>*#(n<-ATe7^dQ1T>y!_@H&ia?S!H?g{-3n}@xM_E zmhoKPqIz}Ay}%szA_Db`=VYTHs%c^mT&1XbJqFKTQ6xEOWoh>>`R>2|3wgb`1Y?qo zwB6oD-o(B!yPeb+Jznt%TH}%gpCqxGt0-uF`9l8rGs-Srr1nX|=udxU_~S3f>aH;h zRd7jyOQv%s`T05Rj~_9^;oY&j2*tZUG5Y?equ@7KS_$!<*2j;u&(6@*avKRo?|x+X zr$0aW5b;}<5?wh*=ly$HpFhuB5xR{q`r&5=fBtvTB^{aKPSM3Vy8rwqtuJ4eim`(T zqj%pk`14-~N5N;Za8*IPr~T;@`T2sSyBm087=Hgf!`I(IIXTw;I2rnu`J#tFc5y-L z)2F3eipw&F@7^(b{W_)sLO_ZOXv*U(^c&{77iBH&4Kh0 zLbqUBEr##jQTKZIyK?8jLsKB$67rJ=w<6qk=Dz!Rix5F6%9k%0zI}^JSBSqu09zx& zuY}eqn5P@N&#wk}@q%O+b1yJX<34{*`SRszVt-5U$mkrhHX&_4Nq4g__oA$gRa;8o z(saFbD_4h^v_bDi>%MKVxCFzPsin8I5&|?O;$1vN#^g_C8Sn8&G}j=N1KULL_2JKA zA769;@4**{t0Bn`+ShyQcSQ6F-a$1)Y)!~c;DAc;oOKiz14b9a9TRi`Xhos*+Z`0b3B?dmpX2sHuwz*I2yw zO9_3GJrn%~!N)}sTO*<%$p|K2Urr|kY;CE_8e7)XWgYj|u3>3le?`AZ@K6^>UBvia zC-IOhJvsgNcJj`9t{TR99|+##8cS0}-)yVRHIzFH(Qgtw*jTM_<#4WCPdts?d0{ki z6h(9m+wRtPnA5&*nG|UT58k73v@=K(wk|k4713v)HJo%5X}bOB=gEo=QTSe0Va#@g zf6}4@7$fw$3Z=Fu{F4_QAW4L7TiBNFN70GFO`a?ATy157dlY?)QqXS8RtDCi=r=H0 z=yo{wax>ZbtoKr!XHIn5)pWQs@9U9 zIf}jl#t7Z+!^6m<=qr+EF){WKj-s!KQqXP*X>xyaKZ<@25+k%*>fQtEQS^I~=R%&z zz5M%8^as#s3&}lZt4GlvfKtLqS25$ZnsC#*GQTOttHAhj-s!T=w{TNZssWZno$Zm?ZssrN6|Mx zk_g?-{MqVJ^bL`vicWjByhqVDgh+HVv;6x}^bI0HEYtfY8+jCc!x$s9+tbwqN6|No z$au9WyN=(FqHlr8YSSc)Jc_<0j1k(c7)Bo6KGGW~2`Cj%I-r$Dseo4T-=?=d3xwO7 zp+itOFE}SS7r*xY{%fPHTv3)`KShteF(7d-E=mQA@g#{O(H^Y>BJpDr#2caTUa(Hl zScS71Kfad%ncLE`ccS(~^msbNwWVqmFxsPy$7nyc-0cysVY>ft2;iK;I)%0I!v!ID z!H4T7L~Gey(M1AA-w@Y$675hr+`Du+gvm)aLf~e{m>V}uroUYFhKhh0Unk@95hqWC z8$S)!#+$NJqN}k5Cy665K3dcYmK=gazw558D+KUCqR>8yJrN(cCGt(8i;81|sBk?- zOg>+Y53{*?A`(X)!1;Isc0%;jc=EgkWKvt+3y zF|(tO$pzGniG!e1Pv+>1wTdnh{dFt17~@ehEZbT|Q6GNG)^lZr&{g9!o3Dv+gNVO3I|S~{H?qi^S_%i1s+ zCNxex`9X3S41jF{MHyyRC5Z$&?V5JW-Us%hfrv}>|-dWEF1D*EnY2zYO%;`FKt zv@*|W&(Uc&Q-ftp+!%&MLem_Np??TdqH7)KbZSmIZYp2my)Y`0W6ZrKu0+qXz}wfB zUe`^@u*0ldFO3iST zBP*c(`Fp~bb3Hd<6(bpsbF+VbWOdZn^Sfj4x(U?v(Z#HbrQ?!O>5u8# zHLJ|8 z(cRd^q{;o-o^Ax45R&n6$Fkc;-QT-_w5|g-5BF+&x>iI%)`^14eneIG7QL~7x&dPr z21y%4qIKupc&79o@t{)as`TWkUaA-2T2VS4U7xmh+KtTPL84Cv)O8)uu@u@6(hel~ z_WtIYd9V{46WW?2a6tn{$Rt_E&^Ex z%zj(=gtf$2*2awm8^h#;q_w%%-!f|pY)3_yxyJfnL=p1N2448_Sexh@v-bQX&M*&% zwTT`=EVZ_Fjf1LA2nXWFZ?e{Tb7Ny9v#!;pIJMvJNM#ml6@9X4Y%Rq}N{_?C!(;6k zqDkETP-_o5*_#B`s%+$4jfyq+cD38-*@v(Z(VYtnhW`E`q)1$V*z=j^JT~_HR&`)7 zy0_{FYvr)vUb{u%Daw1enaN80fwEE2LxADPuQzr-0RDd|#r97Cvm&qn0000 -
-

$(x["name"])

-

$(x["text"])

-
-
- -
- - """) for x in metadata["homepage"]["highlights"] - ] - - @htl(""" -
-

Highlights

-
- $(highlights) -
-
- """) -end \ No newline at end of file diff --git a/src/assets/scripts/get_subjects.jl b/src/assets/scripts/get_subjects.jl deleted file mode 100644 index 5fb0a930..00000000 --- a/src/assets/scripts/get_subjects.jl +++ /dev/null @@ -1,38 +0,0 @@ -let - sections = metadata["sidebar"] - sections = [ - @htl(""" - $([ - let - input = other_page.input - output = other_page.output - - name = get(output.frontmatter, "title", basename(input.relative_path)) - desc = get(output.frontmatter, "description", nothing) - tags = get(output.frontmatter, "tags", String[]) - - image = get(output.frontmatter, "image", nothing) - - class = [ - "no-decoration", - ("tag_$(replace(x, " "=>"_"))" for x in tags)..., - ] - - image === nothing || isempty(image) ? nothing : @htl(""" -

$(name)

- -
""") - end for other_page in collections[section_id].pages - ]) - """) - for (section_id, section_name) in sections - ] - - isempty(sections) ? nothing : @htl("""
-

Subjects

-
- $(sections) -
-
- """) -end \ No newline at end of file diff --git a/src/cheatsheets.md b/src/cheatsheets.md deleted file mode 100644 index fbf0040b..00000000 --- a/src/cheatsheets.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: "Cheatsheets" -tags: ["welcome"] -order: 3 -layout: "md.jlmd" ---- - -# Cheatsheets - -- [Getting Started with Julia - live](/basic_syntax/). -- [Fastrack to Julia](https://juliadocs.github.io/Julia-Cheat-Sheet/) cheatsheet. -- [MATLAB-Julia-Python comparative cheatsheet](https://cheatsheets.quantecon.org/) by [QuantEcon group](https://quantecon.org) -- [Plots.jl cheatsheet](https://github.com/sswatson/cheatsheets/blob/master/plotsjl-cheatsheet.pdf) diff --git a/src/index.jlmd b/src/index.jlmd deleted file mode 100644 index b30034c1..00000000 --- a/src/index.jlmd +++ /dev/null @@ -1,4 +0,0 @@ ---- -tags: ["homepage"] -layout: "welcome.jlmd" ---- diff --git a/src/installation.md b/src/installation.md deleted file mode 100644 index 1ed1eba0..00000000 --- a/src/installation.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: "Software installation" -tags: ["welcome"] -order: 2 -layout: "md.jlmd" -youtube_id: "OOjKEgbt8AI" ---- - -$( - begin - # these special elements will automatically update to read the latest Julia version. See the JavaScript snippet at the bottom of this page to see how it works! - - version = html"1.8.2" - pkg_version = html"1.8" - - nothing - end -) - -# First-time setup: Install Julia & Pluto - -\\ -\\ -\\ -**Text and pictures version:** - -## Step 1: Install Julia $version - -Go to [https://julialang.org/downloads](https://julialang.org/downloads) and download the current stable release, Julia $(version), using the correct version for your operating system (Linux x86, Mac, Windows, etc). - -## Step 2: Run Julia - -After installing, **make sure that you can run Julia**. On some systems, this means searching for the "Julia $(version)" program installed on your computer; in others, it means running the command `julia` in a terminal. Make sure that you can execute `1 + 1`: - -![image](https://user-images.githubusercontent.com/6933510/91439734-c573c780-e86d-11ea-8169-0c97a7013e8d.png) - -*Make sure that you are able to launch Julia and calculate `1+1` before proceeding!* - -## Step 3: Install [`Pluto`](https://github.com/fonsp/Pluto.jl) - -Next we will install the [**Pluto**](https://github.com/fonsp/Pluto.jl), the notebook environment that we will be using during the course. Pluto is a Julia _programming environment_ designed for interactivity and quick experiments. - -Open the **Julia REPL**. This is the command-line interface to Julia, similar to the previous screenshot. - -Here you type _Julia commands_, and when you press ENTER, it runs, and you see the result. - -To install Pluto, we want to run a _package manager command_. To switch from _Julia_ mode to _Pkg_ mode, type `]` (closing square bracket) at the `julia>` prompt: - -

-julia> ]
-
-(@v$(pkg_version)) pkg>
-
- -The line turns blue and the prompt changes to `pkg>`, telling you that you are now in _package manager mode_. This mode allows you to do operations on **packages** (also called libraries). - -To install Pluto, run the following (case sensitive) command to *add* (install) the package to your system by downloading it from the internet. -You should only need to do this *once* for each installation of Julia: - -

-(@v$(pkg_version)) pkg> add Pluto
-
- -This might take a couple of minutes, so you can go get yourself a cup of tea! - -![image](https://user-images.githubusercontent.com/6933510/91440380-ceb16400-e86e-11ea-9352-d164911774cf.png) - -You can now close the terminal. - -## Step 4: Use a modern browser: Mozilla Firefox or Google Chrome -We need a modern browser to view Pluto notebooks with. Firefox and Chrome work best. - - -# Second time: _Running Pluto & opening a notebook_ -Repeat the following steps whenever you want to work on a project or homework assignment. - -## Step 1: Start Pluto - -Start the Julia REPL, like you did during the setup. In the REPL, type: -```julia -julia> using Pluto - -julia> Pluto.run() -``` - -![image](https://user-images.githubusercontent.com/6933510/91441094-eb01d080-e86f-11ea-856f-e667fdd9b85c.png) - -The terminal tells us to go to `http://localhost:1234/` (or a similar URL). Let's open Firefox or Chrome and type that into the address bar. - -![image](https://user-images.githubusercontent.com/6933510/199279574-4b1d0494-2783-49a0-acca-7b6284bede44.png) - -> If you're curious about what a _Pluto notebook_ looks like, have a look at the **Featured Notebooks**. These notebooks are useful for learning some basics of Julia programming. -> -> If you want to hear the story behind Pluto, have a look a the [JuliaCon presentation](https://www.youtube.com/watch?v=IAF8DjrQSSk). - -If nothing happens in the browser the first time, close Julia and try again. And please let us know! - -## Step 2a: Opening a notebook from the web - -This is the main menu - here you can create new notebooks, or open existing ones. Our homework assignments will always be based on a _template notebook_, available in this GitHub repository. To start from a template notebook on the web, you can _paste the URL into the blue box_ and press ENTER. - -For example, homework 0 is available [here](/hw0/). Go to this page, and on the top right, click on the button that says "Edit or run this notebook". From these instructions, copy the notebook link, and paste it into the box. Press ENTER, and select OK in the confirmation box. - -![image](https://user-images.githubusercontent.com/6933510/91441968-6b750100-e871-11ea-974e-3a6dfd80234a.png) - -**The first thing we will want to do is to save the notebook somewhere on our own computer; see below.** - -## Step 2b: Opening an existing notebook file -When you launch Pluto for the second time, your recent notebooks will appear in the main menu. You can click on them to continue where you left off. - -If you want to run a local notebook file that you have not opened before, then you need to enter its _full path_ into the blue box in the main menu. More on finding full paths in step 3. - -## Step 3: Saving a notebook -We first need a folder to save our homework in. Open your file explorer and create one. - -Next, we need to know the _absolute path_ of that folder. Here's how you do that in [Windows](https://www.top-password.com/blog/copy-full-path-of-a-folder-file-in-windows/), [MacOS](https://www.josharcher.uk/code/find-path-to-folder-on-mac/) and [Ubuntu](). - -For example, you might have: - -- `C:\\Users\\fons\\Documents\\18S191_assignments\\` on Windows - -- `/Users/fons/Documents/18S191_assignments/` on MacOS - -- `/home/fons/Documents/18S191_assignments/` on Ubuntu - -Now that we know the absolute path, go back to your Pluto notebook, and at the top of the page, click on _"Save notebook..."_. - -![image](https://user-images.githubusercontent.com/6933510/91444741-77fb5880-e875-11ea-8f6b-02c1c319e7f3.png) - -This is where you type the **new path+filename for your notebook**: - -![image](https://user-images.githubusercontent.com/6933510/91444565-366aad80-e875-11ea-8ed6-1265ded78f11.png) - -Click _Choose_. - -## Step 4: Sharing a notebook - -After working on your notebook (your code is autosaved when you run it), you will find your notebook file in the folder we created in step 3. This the file that you can share with others, or submit as your homework assignment to Canvas. - - - diff --git a/src/logistics.md b/src/logistics.md deleted file mode 100644 index fa55809c..00000000 --- a/src/logistics.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Class logistics" -tags: ["welcome"] -order: 1 -layout: "md.jlmd" ---- - - - -# Course logistics - -Describe here the logistics of your class. \ No newline at end of file diff --git a/src/mod1_setup_website/basic_info.md b/src/mod1_setup_website/basic_info.md deleted file mode 100644 index b849766b..00000000 --- a/src/mod1_setup_website/basic_info.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "Fill course basic information" -order: 2 -chapter: 1 -section: 2 -layout: "md.jlmd" -image: "https://user-images.githubusercontent.com/49938764/249464984-ae268773-b804-459a-9c33-ed2839802ad8.png" -tags: ["module1", "track_setup", "teaching", "metadata"] ---- - -## Add basic information - -If you look at the homepage of the template website, you will see it has a bunch of placeholder text, such as "name of your course", "a short catchy phrase" etc. - -To customize this, you will need to customize the *metadata* of the website. That is, add basic info for your class. - -To do so, you will need to fill the info in the files under the folder `src/_data`. Let us analyze these one by one. - -## course_info.jl - -This file contains a julia `Dict` with the basic info of the class. For each key (`course_name`, `course_subtitle`, etc.) replace the corresponding placeholder with an appropriate text for your class. - -When filling the `institution_logo` data with the name of your university logo file, do not forget to actually put the file under `src/assets`. - -Authors are listed as a vector of pairs, where the first element is the author name and the second is their homepage address. If you dont have a homepage address for the author, put an empty string `""`. - -## `homepage.jl` - -This file contains metadata for the info displayed in the homepage, particularly - -- **`title`**: the title displayed on top of the homepage -- **`disclaimer`**: the disclaimer displayed below the title. If you don't want a disclaimer, you can remove this entry. -- **`highlights`**: in this entry you can specify the highlights of your class, which will be displayed on the homepage. This entry should be a vector of highlights. Each entry in the vector should be a dict with the following fields - - **`name`**: the title of the highlight - - **`text`**: short description of the highlight - - **`img`**: link to an image summarizing the highlight - -## `sidebar.jl` - -In this file you can specify the sidebar of the website. All lecture materials will be grouped in *modules* in the sidebar, which are defined in this file. - -The modules in the file are specified as a vector of pairs, in the form - -```julia -module_id => module_title -``` - -for example - -```julia -"module1" => "Week 1: Introduction to the class" -``` - -To link a file to a module, you will need to add the module identifier in the page tags. For more info about this, see [Add frontmatter](https://juliapluto.github.io/computational-thinking-template/add_markdown) - -## `tracks.jl` - -In this file you will specify tracks. Tracks can be used to group lectures across modules, e.g. if they have a commmon theme. When a track is selected on the sidebar, only the pages -belonging to that track will be highlighted. - -Similar to modules, tracks are stored in a vector of pairs in the form - -```julia -track_id => track_title -``` - -for example - -```julia -"julia" => "πŸ’» Julia programming" -``` - -To link a file to a track, you will need to add the track id, prefixed with `track_`, to the tags of the page. For example, to add a lesson to the julia track defined above, you would add the tag `track_julia` to the tags of that lesson file. - -## License - -Choosing an appropriate license is important to make your material properly reusable. - -- For text, popular licenses are [Creative Commons](https://creativecommons.org/about/cclicenses/), for example [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) - -- For code, an [OSI open source license](https://opensource.org/licenses/) is recommended. For example [MIT](https://opensource.org/license/mit/) or [Apache 2.0](https://opensource.org/license/apache-2-0/) license. - -To add the license, open the file `LICENSE.md` and replace the text - -``` - -``` - -with your license(s). \ No newline at end of file diff --git a/src/mod1_setup_website/getting_started.md b/src/mod1_setup_website/getting_started.md deleted file mode 100644 index b0cbaabb..00000000 --- a/src/mod1_setup_website/getting_started.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Getting started" -order: 1 -chapter: 1 -section: 1 -layout: "md.jlmd" -image: "https://user-images.githubusercontent.com/49938764/249456747-c93b41a0-308a-4ad4-9afb-6ce3309633d1.png" -tags: ["module1", "track_setup", "teaching", "repository structure"] ---- - -## Fork the template - -Go to the [template repository](https://github.com/juliapluto/computational-thinking-template) and click `Use this template` on the top-right corner. This will fork the repository under your github profile. - -![](https://user-images.githubusercontent.com/49938764/249456747-c93b41a0-308a-4ad4-9afb-6ce3309633d1.png) - -## Folder structure - -Let us have a look at what this repository looks like. The most important folder, where you will be mainly working is `src`. Here you will place all your lecture materials. So let us take a closer look at this. - -Opening the `src` folder, you will see the following - -- `_data` folder: here you will place metadata about your website (university name, class semester, define tracks, etc.), more on this in the next lesson. -- `_include`: This folder contains the layout templates that are used to generate the final pages on your website. Unless you want to tweak the layout, you will not need to modify this. -- `assets`: in this folder you can place all attachements, such as your university logo and other pictures. The folder also contains the CSS and scripts used to render the website. - -That was for the "infrastructure part" of the website, the rest is content! To add new pages to your website, simply them under the `src` folder. You can group them in subfolders, as done in this template, but that is not a strict requirement. - -When downloading this template, you will get the following material: - -- **`installation.md`**: this page contains instructions on how to install Julia and Pluto. If you find it useful, you may keep it as is, or edit to match your wanted installation instructions. -- **`cheatsheets.md`**: contains a list of julia related resources. Again, you can keep it or remove it. -- **`logistics.md`**: empty markdown page, where you can describe the logistics of your class -- **`index.jlmd`**: this is used to render the homepage. **Do not remove or modify this!** -- **`search.md`**: this is used to render the search tab on the sidebar, do not modify or remove this file. - -The remaining folders - -- `mod1_setup_website` -- `mod2_add_material` -- `mod3_publish_website` -- `homework` - -are placeholder samples, used to showcase what a deployed website looks like. As a bonus, these placeholder files actually document how to use this template. You can read it and see what the final result looks like on the [template webpage](https://juliapluto.github.io/computational-thinking-template). - -When starting adding your course material, you will most likely want to remove these. \ No newline at end of file diff --git a/src/mod1_setup_website/working_locally.md b/src/mod1_setup_website/working_locally.md deleted file mode 100644 index 201adffc..00000000 --- a/src/mod1_setup_website/working_locally.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: "Working locally" -order: 3 -chapter: 1 -section: 3 -layout: "md.jlmd" -image: "https://user-images.githubusercontent.com/49938764/249456721-2ff021b2-326d-443d-a3ac-b433692647e0.png" -tags: ["module1", "track_setup", "track_julia", "PlutoSliderServer", "pluto"] ---- - -## Working locally - -Open this repository in VS Code, and install the recommended extensions. - -To start running the development server, open the VS Code *command palette* (press `Cmd+Shift+P`), and search for **`Tasks: Run Task`**, then **`PlutoPages: run development server`**. The first run can take some time, as it builds up the notebook outputs cache. Leave it running. - -This will start two things in parallel: the PlutoPages.jl notebook (which generates the website), and a static file server (with Deno_jll). It will open two tabs in your browser: one is the generation dashboard (PlutoPages), the other is the current site preview (Deno_jll). - -Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the "Read input files again" button. - -**Note!**: This workflow is recommended for writing static content, styles, and for site maintenance. But for writing Pluto notebooks, it's best to prepare the notebook first, and then run the site (because it re-runs the entire notebook on any change). \ No newline at end of file diff --git a/src/mod2_add_material/add_markdown.md b/src/mod2_add_material/add_markdown.md deleted file mode 100644 index f34c1aa5..00000000 --- a/src/mod2_add_material/add_markdown.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "Add markdown files" -order: 1 -chapter: 2 -section: 1 -layout: "md.jlmd" -tags: ["module2", "track_material", "markdown", "frontmatter"] ---- - -## Add markdown files - -If your lecture does not need to run code or use interactivity. You can write it as a markdown file. - -As an extra twist, you can evaluate julia code inside a `\$` symbol. For example, - -```julia -\$(1 + 1) -``` -will become - -$(1 + 1) - -## Add Front-matter - -For each file, markdown or pluto, you will need to add a *front-matter*, which specifies the page metadata. For markdown files, the front-matter is specified at the top of the file between three dashes `---`. For example, the front-matter of this file is - -``` ---- -title: "Add markdown file" -order: 1 -chapter: 2 -section: 1 -layout: "md.jlmd" -tags: ["module2", "track_material", "markdown", "frontmatter"] ---- -``` - -You will need to specify the following attributes - -- **`title`**: title of the page -- **`order`**: the position of the page in the module on the sidebar. **Hint!**: You can also use fractional numbers, e.g. `1.5`. This can be handy for homeworks, so you can include the homework between the first and second lesson without messing up lessons counting. -- **`layout`**: set to `"md.jlmd"`, unless you are using some custom layout -- **`chapter`** and **`section`** (optional): used to number the page. If for example `chapter=1` and `section=2`, the page will be displayed as `1.2` on the sidebar and page header. -- **`image`** (optional): link to summarizing image to display in the `subjects` section on the homepage. If left empty, the page wont be included in the subjects section. If no page has an `image` field in the front-matter, the subjects section is not displayed. -- **`description`** (optional): short description of the notebook -- **`youtube_id`** (optional): youtube id of the video associated with the page. If included, the page header will embed the youtube video. -- **`homework_number`**: needed only for homeworks, the number of the homework -- **`tags`**: list of keywords for the page. It should at least include the module name, as defined in `_data/sidebar.jl` to include the page in the sidebar. You can also associate pages to a given track by adding the track id, prefixed with `track_` to the tags. For example, if you want to include the page in the julia track, add `track_julia` in the tags list. - - -## Markdown 101 - -If you are not familiar with markdown, you can see for example [here](https://www.markdowntutorial.com/). Here is a quick and dirty cheatsheet - -1. Use `#` for headers, for example - -```markdown -# Header -## Subheader -### Sub-sub-header -``` - -2. You can create links with the syntax - -```markdown -[text](adddress) -``` - -For example the link to the mardown tutorial above was typed as - -```markdown -[here](https://www.markdowntutorial.com/) -``` - -3. You can insert pictures with the syntax - -```markdown -![optional alternative text](link-to-picture) -``` - -for example - -``` -![](https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.png) -``` - -will give - -![](https://raw.githubusercontent.com/JuliaLang/julia-logo-graphics/master/images/julia-logo-color.png) \ No newline at end of file diff --git a/src/mod3_publish_website/deploy_static.md b/src/mod3_publish_website/deploy_static.md deleted file mode 100644 index dd26dfa5..00000000 --- a/src/mod3_publish_website/deploy_static.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "Deploy your website as static" -order: 1 -chapter: 3 -section: 1 -layout: "md.jlmd" -tags: ["module3", "track_setup", "deploy", "netlify", "github actions", "github pages"] ---- - - -## Deploying with github pages - -Deploying your website as static page with github pages is a breeze. - -Whenever you push to main, the website will be deployed to a branch called `gh-pages`. All you need to do is go to your repository and from `Settings > Pages` choose to deploy from `gh-pages` branch, as the following picture shows. - - -![](https://user-images.githubusercontent.com/49938764/249790280-d9c46b7f-eecd-42aa-8e51-ce44dfdfce58.png) - -After that, the website will be available at - -``` -https://yourusername.github.io/your-repository-name -``` - -Note that this is a **static** webpage, so sliders will not work. Students will still be able to play with interactivity by downloading the notebook or running it on binder. - -If you want interactivity to work on the webpage, you can either - -1. [Precompute the notebooks outputs](https://juliapluto.github.io/computational-thinking-template/mod3_publish_website/precompute_output/) (experimental) - -or - -2. [Run your own server](https://juliapluto.github.io/computational-thinking-template/mod3_publish_website/setup_server/) \ No newline at end of file diff --git a/src/mod3_publish_website/precompute_output.md b/src/mod3_publish_website/precompute_output.md deleted file mode 100644 index 05291a41..00000000 --- a/src/mod3_publish_website/precompute_output.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Precompute the pluto notebooks" -order: 2 -chapter: 3 -section: 2 -layout: "md.jlmd" -tags: ["module3", "track_setup", "track_julia", "deploy", "precompute", "Pluto", "PlutoSliderServer"] ---- - -COMING SOON \ No newline at end of file diff --git a/src/mod3_publish_website/setup_server.md b/src/mod3_publish_website/setup_server.md deleted file mode 100644 index b9ec4126..00000000 --- a/src/mod3_publish_website/setup_server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: "Setup a server for your website" -order: 3 -chapter: 3 -section: 3 -layout: "md.jlmd" -tags: ["module3", "track_setup", "deploy", "server", "dynamic", "droplet"] ---- - -COMING SOON - diff --git a/src/netlify.toml b/src/netlify.toml deleted file mode 100644 index 44c32965..00000000 --- a/src/netlify.toml +++ /dev/null @@ -1,4 +0,0 @@ -[[headers]] - for = "/*" - [headers.values] - Access-Control-Allow-Origin = "*" diff --git a/src/search.md b/src/search.md deleted file mode 100644 index 34006bbd..00000000 --- a/src/search.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "Search results" -tags: [] -layout: "md.jlmd" ---- - - -
-
-

Search

- - -

Results

-
-Loading... -
- diff --git a/tools/update_notebook_packages.jl b/tools/update_notebook_packages.jl deleted file mode 100644 index 7ae9b188..00000000 --- a/tools/update_notebook_packages.jl +++ /dev/null @@ -1,35 +0,0 @@ -if !isdir("pluto-deployment-environment") || length(ARGS) != 1 - error(""" - Run me from the root of the repository directory, using: - - julia tools/update_notebook_packages.jl - - Where is one of: PATCH, MINOR, MAJOR - """) -end - -if VERSION < v"1.6.0-aaa" - @error "Our website needs to be generated with Julia 1.6. Go to julialang.org/downloads to install it." -end - -import Pkg -Pkg.activate("./pluto-deployment-environment") -Pkg.instantiate() - -import Pluto - -flatmap(args...) = vcat(map(args...)...) - - -all_files_recursive = flatmap(walkdir("src")) do (root, _dirs, files) - joinpath.((root,), files) -end - -all_notebooks = filter(Pluto.is_pluto_notebook, all_files_recursive) - -level = getfield(Pkg, Symbol("UPLEVEL_$(ARGS[1])")) - -for n in all_notebooks - @info "Updating" n - Pluto.update_notebook_environment(n; backup=false, level) -end