this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

🎨 Format code, update readme

+461 -444
-1
.github/workflows/tangle.yml
··· 12 12 with: 13 13 repo: gwen.works/portfolio 14 14 ssh-key: ${{ secrets.TANGLED_KEY }} 15 -
+22 -22
.github/workflows/trigger-publish.yml
··· 1 - name: Trigger build and deploy 2 - 3 - on: 4 - workflow_dispatch: 5 - push: 6 - branches: 7 - - main 8 - 9 - jobs: 10 - trigger: 11 - name: Trigger 12 - runs-on: ubuntu-latest 13 - strategy: 14 - matrix: 15 - language: [en, fr] 16 - steps: 17 - - name: Dispatch workflow 18 - uses: peter-evans/repository-dispatch@v3 19 - with: 20 - repository: gwennlbh/portfolio-build-${{ matrix.language }} 21 - event-type: build 22 - token: ${{ secrets.REPOSITORY_DISPATCH_PAT }} 1 + name: Trigger build and deploy 2 + 3 + on: 4 + workflow_dispatch: 5 + push: 6 + branches: 7 + - main 8 + 9 + jobs: 10 + trigger: 11 + name: Trigger 12 + runs-on: ubuntu-latest 13 + strategy: 14 + matrix: 15 + language: [en, fr] 16 + steps: 17 + - name: Dispatch workflow 18 + uses: peter-evans/repository-dispatch@v3 19 + with: 20 + repository: gwennlbh/portfolio-build-${{ matrix.language }} 21 + event-type: build 22 + token: ${{ secrets.REPOSITORY_DISPATCH_PAT }}
+13 -13
.ortfo/description.md
··· 2 2 started: "2018-10-20" 3 3 aliases: [ewen.works] 4 4 made with: 5 - - css 6 - - figma 7 - - go 8 - - html 9 - - javascript 10 - - markdown 11 - - yaml 12 - - svg 13 - - ortfo 14 - - go-templ 5 + - css 6 + - figma 7 + - go 8 + - html 9 + - javascript 10 + - markdown 11 + - yaml 12 + - svg 13 + - ortfo 14 + - go-templ 15 15 tags: 16 - - web 17 - - icons 18 - - site 16 + - web 17 + - icons 18 + - site 19 19 --- 20 20 21 21 # ewen.works
+2 -47
README.md
··· 1 - # Astro Starter Kit: Basics 1 + # gwen.works 2 2 3 - ```sh 4 - npm create astro@latest -- --template basics 5 - ``` 6 - 7 - [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics) 8 - [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics) 9 - [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json) 10 - 11 - > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 12 - 13 - ![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554) 14 - 15 - ## 🚀 Project Structure 16 - 17 - Inside of your Astro project, you'll see the following folders and files: 18 - 19 - ```text 20 - / 21 - ├── public/ 22 - │ └── favicon.svg 23 - ├── src/ 24 - │ ├── layouts/ 25 - │ │ └── Layout.astro 26 - │ └── pages/ 27 - │ └── index.astro 28 - └── package.json 29 - ``` 30 - 31 - To learn more about the folder structure of an Astro project, refer to [our guide on project structure](https://docs.astro.build/en/basics/project-structure/). 32 - 33 - ## 🧞 Commands 34 - 35 - All commands are run from the root of the project, from a terminal: 36 - 37 - | Command | Action | 38 - | :------------------------ | :----------------------------------------------- | 39 - | `npm install` | Installs dependencies | 40 - | `npm run dev` | Starts local dev server at `localhost:4321` | 41 - | `npm run build` | Build your production site to `./dist/` | 42 - | `npm run preview` | Preview your build locally, before deploying | 43 - | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 44 - | `npm run astro -- --help` | Get help using the Astro CLI | 45 - 46 - ## 👀 Want to learn more? 47 - 48 - Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). 3 + my portfolio :)
+1 -1
blog/end-to-end-xss-proection-for-graphql-clients.md
··· 12 12 13 13 As you turn around to your client code, you get that generated HTML _string_, and include it somewhere on your page, telling your templating engin / js framework “it's fine, this is safe for HTML inclusion”. 14 14 15 - A few months pass, you add more and more features, and suddenly your API has _a lot_of fields, some that output HTML and some that output plain text. 15 + A few months pass, you add more and more features, and suddenly your API has \_a lot_of fields, some that output HTML and some that output plain text. 16 16 17 17 As a documentation feature, you create a separate `HTML` scalar type to signal fields that have HTML content (and thus cannot be inserted into the page as simple text). 18 18
+1 -1
blog/making-an-lsp-server-in-go.md
··· 189 189 As with `Initialize`, hovering over the types of the parameters will help you greatly. 190 190 191 191 ```go 192 - // IMPORTANT: You _can't_ take a pointer to your handler struct as the receiver, 192 + // IMPORTANT: You _can't_ take a pointer to your handler struct as the receiver, 193 193 // your handler will no longer implement protocol.Server if you do that. 194 194 func (h Handler) Definition(ctx context.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) { 195 195 // ... do your processing ...
+14 -17
blog/on-applying-repeated-operators-to-the-empty-set.md
··· 5 5 mathjax: yes 6 6 --- 7 7 8 - 9 8 This is a sort of "theorem" that I made up in my mind has been itching me since my years in higher math education. 10 9 11 10 ## Context 12 11 13 - Let $E$ a set and $o \in E^2 \to E$, such that $(E, o)$ forms a [monoid](https://en.wikipedia.org/wiki/Monoid). 12 + Let $E$ a set and $o \in E^2 \to E$, such that $(E, o)$ forms a [monoid](https://en.wikipedia.org/wiki/Monoid). 14 13 15 14 We then define $\mathcal O$ as the _repeated variant_ of the binary operator $o$: 16 15 ··· 23 22 24 23 using an infix notation for $o$, defined as you would expect: $A\ o\ B = o(A, B)$. 25 24 26 - 27 25 This is why we need $(E, o)$ to be a monoid, instead of a unital magma: we need the operator to be associative, so that the repeated application of the operator is well-defined. 28 26 29 27 Note how repeated operators have their argument in a sequence space instead of a set. This is because: 30 28 31 29 1. we need to _iterate_ over the elements, which requires a well-defined order on the elements (otherwise, we would need $o$ to be commutative and therefore $(E, o)$ to be a group instead of just a monoid) 32 30 1. We also want to be able to represent repeated operations on duplicates, which sets cannot represent. 33 - 34 31 35 32 ## Theorem 36 33 ··· 58 55 59 56 1. $\bigwedge$ is the repeated variant of $\land$. 60 57 1. $(\{\top, \bot\}, \land)$ is a monoid: 61 - - $\land$ is a binary operation on $\{\top, \bot\}$. 62 - - $\land$ is associative: $a \land (b \land c) = (a \land b) \land c$. 63 - - $\land$ has a unit element $\top$ (as $a \land \top = a$ for any $a$) and $\top \in \{\top, \bot\}$. 58 + - $\land$ is a binary operation on $\{\top, \bot\}$. 59 + - $\land$ is associative: $a \land (b \land c) = (a \land b) \land c$. 60 + - $\land$ has a unit element $\top$ (as $a \land \top = a$ for any $a$) and $\top \in \{\top, \bot\}$. 64 61 1. $\operatorname{unit} \{\top, \bot\} = \top$. 65 62 66 63 Therefore, $\bigwedge(()) = \top$. ··· 134 131 135 132 ## Applications 136 133 137 - | Operation | Application | | 138 - | --------- | ------------------------------------------------------ |-- | 139 - | $+$ | $\sum_\emptyset = 0$ | | 140 - | $\cdot$ | $\prod_\emptyset = 1$ | | 141 - | $\max$ | $\max_\emptyset = -\infty$ | | 142 - | $\min$ | $\min_\emptyset = \infty$ | | 143 - | $\land$ | $\forall \emptyset = \top$ | | 144 - | $\lor$ | $\exists \emptyset = \bot$ | | 145 - | $\cup$ | $\bigcup_\emptyset = \emptyset$ | | 146 - | $\cap$ | $\bigcap_\emptyset = \mathbb U$ | where $\mathbb U$ is the universe set | 134 + | Operation | Application | | 135 + | --------- | ------------------------------- | ------------------------------------- | 136 + | $+$ | $\sum_\emptyset = 0$ | | 137 + | $\cdot$ | $\prod_\emptyset = 1$ | | 138 + | $\max$ | $\max_\emptyset = -\infty$ | | 139 + | $\min$ | $\min_\emptyset = \infty$ | | 140 + | $\land$ | $\forall \emptyset = \top$ | | 141 + | $\lor$ | $\exists \emptyset = \bot$ | | 142 + | $\cup$ | $\bigcup_\emptyset = \emptyset$ | | 143 + | $\cap$ | $\bigcap_\emptyset = \mathbb U$ | where $\mathbb U$ is the universe set |
+255 -207
public/bricks.js
··· 1 1 (function (global, factory) { 2 - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 - typeof define === 'function' && define.amd ? define(factory) : 4 - (global.Bricks = factory()); 5 - }(this, (function () { 'use strict'; 2 + typeof exports === "object" && typeof module !== "undefined" 3 + ? (module.exports = factory()) 4 + : typeof define === "function" && define.amd 5 + ? define(factory) 6 + : (global.Bricks = factory()); 7 + })(this, function () { 8 + "use strict"; 6 9 7 - var _extends = Object.assign || function (target) { 8 - for (var i = 1; i < arguments.length; i++) { 9 - var source = arguments[i]; 10 + var _extends = 11 + Object.assign || 12 + function (target) { 13 + for (var i = 1; i < arguments.length; i++) { 14 + var source = arguments[i]; 10 15 11 - for (var key in source) { 12 - if (Object.prototype.hasOwnProperty.call(source, key)) { 13 - target[key] = source[key]; 16 + for (var key in source) { 17 + if (Object.prototype.hasOwnProperty.call(source, key)) { 18 + target[key] = source[key]; 19 + } 20 + } 14 21 } 15 - } 16 - } 17 22 18 - return target; 19 - }; 23 + return target; 24 + }; 20 25 21 - var knot = function knot() { 22 - var extended = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 26 + var knot = function knot() { 27 + var extended = 28 + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 23 29 24 - var events = Object.create(null); 30 + var events = Object.create(null); 25 31 26 - function on(name, handler) { 27 - events[name] = events[name] || []; 28 - events[name].push(handler); 29 - return this; 30 - } 31 - 32 - function once(name, handler) { 33 - handler._once = true; 34 - on(name, handler); 35 - return this; 36 - } 37 - 38 - function off(name) { 39 - var handler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 32 + function on(name, handler) { 33 + events[name] = events[name] || []; 34 + events[name].push(handler); 35 + return this; 36 + } 40 37 41 - handler ? events[name].splice(events[name].indexOf(handler), 1) : delete events[name]; 38 + function once(name, handler) { 39 + handler._once = true; 40 + on(name, handler); 41 + return this; 42 + } 42 43 43 - return this; 44 - } 44 + function off(name) { 45 + var handler = 46 + arguments.length > 1 && arguments[1] !== undefined 47 + ? arguments[1] 48 + : false; 45 49 46 - function emit(name) { 47 - var _this = this; 50 + handler 51 + ? events[name].splice(events[name].indexOf(handler), 1) 52 + : delete events[name]; 48 53 49 - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 50 - args[_key - 1] = arguments[_key]; 54 + return this; 51 55 } 52 56 53 - // cache the events, to avoid consequences of mutation 54 - var cache = events[name] && events[name].slice(); 57 + function emit(name) { 58 + var _this = this; 55 59 56 - // only fire handlers if they exist 57 - cache && cache.forEach(function (handler) { 58 - // remove handlers added with 'once' 59 - handler._once && off(name, handler); 60 + for ( 61 + var _len = arguments.length, 62 + args = Array(_len > 1 ? _len - 1 : 0), 63 + _key = 1; 64 + _key < _len; 65 + _key++ 66 + ) { 67 + args[_key - 1] = arguments[_key]; 68 + } 60 69 61 - // set 'this' context, pass args to handlers 62 - handler.apply(_this, args); 63 - }); 70 + // cache the events, to avoid consequences of mutation 71 + var cache = events[name] && events[name].slice(); 64 72 65 - return this; 66 - } 73 + // only fire handlers if they exist 74 + cache && 75 + cache.forEach(function (handler) { 76 + // remove handlers added with 'once' 77 + handler._once && off(name, handler); 67 78 68 - return _extends({}, extended, { 79 + // set 'this' context, pass args to handlers 80 + handler.apply(_this, args); 81 + }); 69 82 70 - on: on, 71 - once: once, 72 - off: off, 73 - emit: emit 74 - }); 75 - }; 83 + return this; 84 + } 76 85 77 - var bricks = function bricks() { 78 - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 86 + return _extends({}, extended, { 87 + on: on, 88 + once: once, 89 + off: off, 90 + emit: emit, 91 + }); 92 + }; 79 93 80 - // privates 94 + var bricks = function bricks() { 95 + var options = 96 + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 81 97 82 - var persist = void 0; // packing new elements, or all elements? 83 - var ticking = void 0; // for debounced resize 98 + // privates 84 99 85 - var sizeIndex = void 0; 86 - var sizeDetail = void 0; 100 + var persist = void 0; // packing new elements, or all elements? 101 + var ticking = void 0; // for debounced resize 87 102 88 - var columnTarget = void 0; 89 - var columnHeights = void 0; 103 + var sizeIndex = void 0; 104 + var sizeDetail = void 0; 90 105 91 - var nodeTop = void 0; 92 - var nodeLeft = void 0; 93 - var nodeWidth = void 0; 94 - var nodeHeight = void 0; 106 + var columnTarget = void 0; 107 + var columnHeights = void 0; 95 108 96 - var nodes = void 0; 97 - var nodesWidths = void 0; 98 - var nodesHeights = void 0; 109 + var nodeTop = void 0; 110 + var nodeLeft = void 0; 111 + var nodeWidth = void 0; 112 + var nodeHeight = void 0; 99 113 100 - // resolve options 114 + var nodes = void 0; 115 + var nodesWidths = void 0; 116 + var nodesHeights = void 0; 101 117 102 - var packed = options.packed.indexOf('data-') === 0 ? options.packed : 'data-' + options.packed; 103 - var sizes = options.sizes.slice().reverse(); 104 - var position = options.position !== false; 118 + // resolve options 105 119 106 - var container = options.container.nodeType ? options.container : document.querySelector(options.container); 120 + var packed = 121 + options.packed.indexOf("data-") === 0 122 + ? options.packed 123 + : "data-" + options.packed; 124 + var sizes = options.sizes.slice().reverse(); 125 + var position = options.position !== false; 107 126 108 - var selectors = { 109 - all: function all() { 110 - return toArray(container.children); 111 - }, 112 - new: function _new() { 113 - return toArray(container.children).filter(function (node) { 114 - return !node.hasAttribute('' + packed); 115 - }); 116 - } 117 - }; 127 + var container = options.container.nodeType 128 + ? options.container 129 + : document.querySelector(options.container); 118 130 119 - // series 131 + var selectors = { 132 + all: function all() { 133 + return toArray(container.children); 134 + }, 135 + new: function _new() { 136 + return toArray(container.children).filter(function (node) { 137 + return !node.hasAttribute("" + packed); 138 + }); 139 + }, 140 + }; 120 141 121 - var setup = [setSizeIndex, setSizeDetail, setColumns]; 142 + // series 122 143 123 - var run = [setNodes, setNodesDimensions, setNodesStyles, setContainerStyles]; 144 + var setup = [setSizeIndex, setSizeDetail, setColumns]; 124 145 125 - // instance 126 - 127 - var instance = knot({ 128 - pack: pack, 129 - update: update, 130 - resize: resize 131 - }); 146 + var run = [ 147 + setNodes, 148 + setNodesDimensions, 149 + setNodesStyles, 150 + setContainerStyles, 151 + ]; 132 152 133 - return instance; 134 - 135 - // general helpers 153 + // instance 136 154 137 - function runSeries(functions) { 138 - functions.forEach(function (func) { 139 - return func(); 155 + var instance = knot({ 156 + pack: pack, 157 + update: update, 158 + resize: resize, 140 159 }); 141 - } 142 160 143 - // array helpers 161 + return instance; 144 162 145 - function toArray(input) { 146 - var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document; 163 + // general helpers 147 164 148 - return Array.prototype.slice.call(input); 149 - } 165 + function runSeries(functions) { 166 + functions.forEach(function (func) { 167 + return func(); 168 + }); 169 + } 150 170 151 - function fillArray(length) { 152 - return Array.apply(null, Array(length)).map(function () { 153 - return 0; 154 - }); 155 - } 171 + // array helpers 156 172 157 - // size helpers 173 + function toArray(input) { 174 + var scope = 175 + arguments.length > 1 && arguments[1] !== undefined 176 + ? arguments[1] 177 + : document; 158 178 159 - function getSizeIndex() { 160 - // find index of widest matching media query 161 - return sizes.map(function (size) { 162 - return size.mq && window.matchMedia('(min-width: ' + size.mq + ')').matches; 163 - }).indexOf(true); 164 - } 179 + return Array.prototype.slice.call(input); 180 + } 165 181 166 - function setSizeIndex() { 167 - sizeIndex = getSizeIndex(); 168 - } 182 + function fillArray(length) { 183 + return Array.apply(null, Array(length)).map(function () { 184 + return 0; 185 + }); 186 + } 169 187 170 - function setSizeDetail() { 171 - // if no media queries matched, use the base case 172 - sizeDetail = sizeIndex === -1 ? sizes[sizes.length - 1] : sizes[sizeIndex]; 173 - } 188 + // size helpers 174 189 175 - // column helpers 190 + function getSizeIndex() { 191 + // find index of widest matching media query 192 + return sizes 193 + .map(function (size) { 194 + return ( 195 + size.mq && window.matchMedia("(min-width: " + size.mq + ")").matches 196 + ); 197 + }) 198 + .indexOf(true); 199 + } 176 200 177 - function setColumns() { 178 - columnHeights = fillArray(sizeDetail.columns); 179 - } 201 + function setSizeIndex() { 202 + sizeIndex = getSizeIndex(); 203 + } 180 204 181 - // node helpers 205 + function setSizeDetail() { 206 + // if no media queries matched, use the base case 207 + sizeDetail = 208 + sizeIndex === -1 ? sizes[sizes.length - 1] : sizes[sizeIndex]; 209 + } 182 210 183 - function setNodes() { 184 - nodes = selectors[persist ? 'new' : 'all'](); 185 - } 211 + // column helpers 186 212 187 - function setNodesDimensions() { 188 - // exit if empty container 189 - if (nodes.length === 0) { 190 - return; 213 + function setColumns() { 214 + columnHeights = fillArray(sizeDetail.columns); 191 215 } 192 216 193 - nodesWidths = nodes.map(function (element) { 194 - return element.clientWidth; 195 - }); 196 - nodesHeights = nodes.map(function (element) { 197 - return element.clientHeight; 198 - }); 199 - } 217 + // node helpers 200 218 201 - function setNodesStyles() { 202 - nodes.forEach(function (element, index) { 203 - columnTarget = columnHeights.indexOf(Math.min.apply(Math, columnHeights)); 219 + function setNodes() { 220 + nodes = selectors[persist ? "new" : "all"](); 221 + } 204 222 205 - element.style.position = 'absolute'; 223 + function setNodesDimensions() { 224 + // exit if empty container 225 + if (nodes.length === 0) { 226 + return; 227 + } 228 + 229 + nodesWidths = nodes.map(function (element) { 230 + return element.clientWidth; 231 + }); 232 + nodesHeights = nodes.map(function (element) { 233 + return element.clientHeight; 234 + }); 235 + } 206 236 207 - nodeTop = columnHeights[columnTarget] + 'px'; 208 - nodeLeft = columnTarget * nodesWidths[index] + columnTarget * sizeDetail.gutter + 'px'; 237 + function setNodesStyles() { 238 + nodes.forEach(function (element, index) { 239 + columnTarget = columnHeights.indexOf( 240 + Math.min.apply(Math, columnHeights), 241 + ); 209 242 210 - // support positioned elements (default) or transformed elements 211 - if (position) { 212 - element.style.top = nodeTop; 213 - element.style.left = nodeLeft; 214 - } else { 215 - element.style.transform = 'translate3d(' + nodeLeft + ', ' + nodeTop + ', 0)'; 216 - } 243 + element.style.position = "absolute"; 217 244 218 - element.setAttribute(packed, ''); 245 + nodeTop = columnHeights[columnTarget] + "px"; 246 + nodeLeft = 247 + columnTarget * nodesWidths[index] + 248 + columnTarget * sizeDetail.gutter + 249 + "px"; 219 250 220 - // ignore nodes with no width and/or height 221 - nodeWidth = nodesWidths[index]; 222 - nodeHeight = nodesHeights[index]; 251 + // support positioned elements (default) or transformed elements 252 + if (position) { 253 + element.style.top = nodeTop; 254 + element.style.left = nodeLeft; 255 + } else { 256 + element.style.transform = 257 + "translate3d(" + nodeLeft + ", " + nodeTop + ", 0)"; 258 + } 223 259 224 - if (nodeWidth && nodeHeight) { 225 - columnHeights[columnTarget] += nodeHeight + sizeDetail.gutter; 226 - } 227 - }); 228 - } 260 + element.setAttribute(packed, ""); 229 261 230 - // container helpers 262 + // ignore nodes with no width and/or height 263 + nodeWidth = nodesWidths[index]; 264 + nodeHeight = nodesHeights[index]; 231 265 232 - function setContainerStyles() { 233 - container.style.position = 'relative'; 234 - container.style.width = sizeDetail.columns * nodeWidth + (sizeDetail.columns - 1) * sizeDetail.gutter + 'px'; 235 - container.style.height = Math.max.apply(Math, columnHeights) - sizeDetail.gutter + 'px'; 236 - } 266 + if (nodeWidth && nodeHeight) { 267 + columnHeights[columnTarget] += nodeHeight + sizeDetail.gutter; 268 + } 269 + }); 270 + } 237 271 238 - // resize helpers 272 + // container helpers 239 273 240 - function resizeFrame() { 241 - if (!ticking) { 242 - window.requestAnimationFrame(resizeHandler); 243 - ticking = true; 274 + function setContainerStyles() { 275 + container.style.position = "relative"; 276 + container.style.width = 277 + sizeDetail.columns * nodeWidth + 278 + (sizeDetail.columns - 1) * sizeDetail.gutter + 279 + "px"; 280 + container.style.height = 281 + Math.max.apply(Math, columnHeights) - sizeDetail.gutter + "px"; 244 282 } 245 - } 246 283 247 - function resizeHandler() { 248 - if (sizeIndex !== getSizeIndex()) { 249 - pack(); 250 - instance.emit('resize', sizeDetail); 284 + // resize helpers 285 + 286 + function resizeFrame() { 287 + if (!ticking) { 288 + window.requestAnimationFrame(resizeHandler); 289 + ticking = true; 290 + } 251 291 } 252 292 253 - ticking = false; 254 - } 293 + function resizeHandler() { 294 + if (sizeIndex !== getSizeIndex()) { 295 + pack(); 296 + instance.emit("resize", sizeDetail); 297 + } 255 298 256 - // API 299 + ticking = false; 300 + } 257 301 258 - function pack() { 259 - persist = false; 260 - runSeries(setup.concat(run)); 302 + // API 261 303 262 - return instance.emit('pack'); 263 - } 304 + function pack() { 305 + persist = false; 306 + runSeries(setup.concat(run)); 264 307 265 - function update() { 266 - persist = true; 267 - runSeries(run); 308 + return instance.emit("pack"); 309 + } 268 310 269 - return instance.emit('update'); 270 - } 311 + function update() { 312 + persist = true; 313 + runSeries(run); 271 314 272 - function resize() { 273 - var flag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; 315 + return instance.emit("update"); 316 + } 274 317 275 - var action = flag ? 'addEventListener' : 'removeEventListener'; 318 + function resize() { 319 + var flag = 320 + arguments.length > 0 && arguments[0] !== undefined 321 + ? arguments[0] 322 + : true; 276 323 277 - window[action]('resize', resizeFrame); 324 + var action = flag ? "addEventListener" : "removeEventListener"; 278 325 279 - return instance; 280 - } 281 - }; 326 + window[action]("resize", resizeFrame); 282 327 283 - return bricks; 328 + return instance; 329 + } 330 + }; 284 331 285 - }))); 332 + return bricks; 333 + });
+122 -106
public/fonts/import.css
··· 1 1 @font-face { 2 - font-family: 'Manrope'; 3 - src: url('Manrope-Bold.woff2') format('woff2'), 4 - url('Manrope-Bold.woff') format('woff'); 5 - font-weight: bold; 6 - font-style: normal; 7 - font-display: swap; 2 + font-family: "Manrope"; 3 + src: 4 + url("Manrope-Bold.woff2") format("woff2"), 5 + url("Manrope-Bold.woff") format("woff"); 6 + font-weight: bold; 7 + font-style: normal; 8 + font-display: swap; 8 9 } 9 10 10 11 @font-face { 11 - font-family: 'Manrope'; 12 - src: url('Manrope-Bold.woff2') format('woff2'), 13 - url('Manrope-Bold.woff') format('woff'); 14 - font-weight: bold; 15 - font-style: normal; 16 - font-display: swap; 12 + font-family: "Manrope"; 13 + src: 14 + url("Manrope-Bold.woff2") format("woff2"), 15 + url("Manrope-Bold.woff") format("woff"); 16 + font-weight: bold; 17 + font-style: normal; 18 + font-display: swap; 17 19 } 18 20 19 21 @font-face { 20 - font-family: 'Manrope'; 21 - src: url('Manrope-ExtraBold.woff2') format('woff2'), 22 - url('Manrope-ExtraBold.woff') format('woff'); 23 - font-weight: 800; 24 - font-style: normal; 25 - font-display: swap; 22 + font-family: "Manrope"; 23 + src: 24 + url("Manrope-ExtraBold.woff2") format("woff2"), 25 + url("Manrope-ExtraBold.woff") format("woff"); 26 + font-weight: 800; 27 + font-style: normal; 28 + font-display: swap; 26 29 } 27 30 28 31 @font-face { 29 - font-family: 'Manrope'; 30 - src: url('Manrope-ExtraBold.woff2') format('woff2'), 31 - url('Manrope-ExtraBold.woff') format('woff'); 32 - font-weight: 800; 33 - font-style: normal; 34 - font-display: swap; 32 + font-family: "Manrope"; 33 + src: 34 + url("Manrope-ExtraBold.woff2") format("woff2"), 35 + url("Manrope-ExtraBold.woff") format("woff"); 36 + font-weight: 800; 37 + font-style: normal; 38 + font-display: swap; 35 39 } 36 40 37 41 @font-face { 38 - font-family: 'Manrope'; 39 - src: url('Manrope-ExtraLight.woff2') format('woff2'), 40 - url('Manrope-ExtraLight.woff') format('woff'); 41 - font-weight: 200; 42 - font-style: normal; 43 - font-display: swap; 42 + font-family: "Manrope"; 43 + src: 44 + url("Manrope-ExtraLight.woff2") format("woff2"), 45 + url("Manrope-ExtraLight.woff") format("woff"); 46 + font-weight: 200; 47 + font-style: normal; 48 + font-display: swap; 44 49 } 45 50 46 51 @font-face { 47 - font-family: 'Manrope'; 48 - src: url('Manrope-ExtraLight.woff2') format('woff2'), 49 - url('Manrope-ExtraLight.woff') format('woff'); 50 - font-weight: 200; 51 - font-style: normal; 52 - font-display: swap; 52 + font-family: "Manrope"; 53 + src: 54 + url("Manrope-ExtraLight.woff2") format("woff2"), 55 + url("Manrope-ExtraLight.woff") format("woff"); 56 + font-weight: 200; 57 + font-style: normal; 58 + font-display: swap; 53 59 } 54 60 55 61 @font-face { 56 - font-family: 'Manrope'; 57 - src: url('Manrope-Light.woff2') format('woff2'), 58 - url('Manrope-Light.woff') format('woff'); 59 - font-weight: 300; 60 - font-style: normal; 61 - font-display: swap; 62 + font-family: "Manrope"; 63 + src: 64 + url("Manrope-Light.woff2") format("woff2"), 65 + url("Manrope-Light.woff") format("woff"); 66 + font-weight: 300; 67 + font-style: normal; 68 + font-display: swap; 62 69 } 63 70 64 71 @font-face { 65 - font-family: 'Manrope'; 66 - src: url('Manrope-Light.woff2') format('woff2'), 67 - url('Manrope-Light.woff') format('woff'); 68 - font-weight: 300; 69 - font-style: normal; 70 - font-display: swap; 72 + font-family: "Manrope"; 73 + src: 74 + url("Manrope-Light.woff2") format("woff2"), 75 + url("Manrope-Light.woff") format("woff"); 76 + font-weight: 300; 77 + font-style: normal; 78 + font-display: swap; 71 79 } 72 80 73 81 @font-face { 74 - font-family: 'Manrope'; 75 - src: url('Manrope-Medium.woff2') format('woff2'), 76 - url('Manrope-Medium.woff') format('woff'); 77 - font-weight: 500; 78 - font-style: normal; 79 - font-display: swap; 82 + font-family: "Manrope"; 83 + src: 84 + url("Manrope-Medium.woff2") format("woff2"), 85 + url("Manrope-Medium.woff") format("woff"); 86 + font-weight: 500; 87 + font-style: normal; 88 + font-display: swap; 80 89 } 81 90 82 91 @font-face { 83 - font-family: 'Manrope'; 84 - src: url('Manrope-Medium.woff2') format('woff2'), 85 - url('Manrope-Medium.woff') format('woff'); 86 - font-weight: 500; 87 - font-style: normal; 88 - font-display: swap; 92 + font-family: "Manrope"; 93 + src: 94 + url("Manrope-Medium.woff2") format("woff2"), 95 + url("Manrope-Medium.woff") format("woff"); 96 + font-weight: 500; 97 + font-style: normal; 98 + font-display: swap; 89 99 } 90 100 91 101 @font-face { 92 - font-family: 'Manrope'; 93 - src: url('Manrope-Regular.woff2') format('woff2'), 94 - url('Manrope-Regular.woff') format('woff'); 95 - font-weight: normal; 96 - font-style: normal; 97 - font-display: swap; 102 + font-family: "Manrope"; 103 + src: 104 + url("Manrope-Regular.woff2") format("woff2"), 105 + url("Manrope-Regular.woff") format("woff"); 106 + font-weight: normal; 107 + font-style: normal; 108 + font-display: swap; 98 109 } 99 110 100 111 @font-face { 101 - font-family: 'Manrope'; 102 - src: url('Manrope-Regular.woff2') format('woff2'), 103 - url('Manrope-Regular.woff') format('woff'); 104 - font-weight: normal; 105 - font-style: normal; 106 - font-display: swap; 112 + font-family: "Manrope"; 113 + src: 114 + url("Manrope-Regular.woff2") format("woff2"), 115 + url("Manrope-Regular.woff") format("woff"); 116 + font-weight: normal; 117 + font-style: normal; 118 + font-display: swap; 107 119 } 108 120 109 121 @font-face { 110 - font-family: 'Manrope'; 111 - src: url('Manrope-SemiBold.woff2') format('woff2'), 112 - url('Manrope-SemiBold.woff') format('woff'); 113 - font-weight: 600; 114 - font-style: normal; 115 - font-display: swap; 122 + font-family: "Manrope"; 123 + src: 124 + url("Manrope-SemiBold.woff2") format("woff2"), 125 + url("Manrope-SemiBold.woff") format("woff"); 126 + font-weight: 600; 127 + font-style: normal; 128 + font-display: swap; 116 129 } 117 130 118 131 @font-face { 119 - font-family: 'Manrope'; 120 - src: url('Manrope-SemiBold.woff2') format('woff2'), 121 - url('Manrope-SemiBold.woff') format('woff'); 122 - font-weight: 600; 123 - font-style: normal; 124 - font-display: swap; 132 + font-family: "Manrope"; 133 + src: 134 + url("Manrope-SemiBold.woff2") format("woff2"), 135 + url("Manrope-SemiBold.woff") format("woff"); 136 + font-weight: 600; 137 + font-style: normal; 138 + font-display: swap; 125 139 } 126 140 127 141 @font-face { 128 - font-family: 'Manrope Variable'; 129 - src: url('Manrope[wght].ttf') format('truetype-variations'); 130 - font-weight: 200 800; 131 - font-style: normal; 132 - font-display: swap; 142 + font-family: "Manrope Variable"; 143 + src: url("Manrope[wght].ttf") format("truetype-variations"); 144 + font-weight: 200 800; 145 + font-style: normal; 146 + font-display: swap; 133 147 } 134 148 135 149 @font-face { 136 - font-family: 'Inconsolata'; 137 - src: url('Inconsolata-Regular.woff2') format('woff2'), 138 - url('Inconsolata-Regular.woff') format('woff'); 139 - font-weight: normal; 140 - font-style: normal; 141 - font-display: swap; 150 + font-family: "Inconsolata"; 151 + src: 152 + url("Inconsolata-Regular.woff2") format("woff2"), 153 + url("Inconsolata-Regular.woff") format("woff"); 154 + font-weight: normal; 155 + font-style: normal; 156 + font-display: swap; 142 157 } 143 158 144 159 @font-face { 145 - font-family: 'Inconsolata'; 146 - src: url('Inconsolata-Black.woff2') format('woff2'), 147 - url('Inconsolata-Black.woff') format('woff'); 148 - font-weight: 900; 149 - font-style: normal; 150 - font-display: swap; 160 + font-family: "Inconsolata"; 161 + src: 162 + url("Inconsolata-Black.woff2") format("woff2"), 163 + url("Inconsolata-Black.woff") format("woff"); 164 + font-weight: 900; 165 + font-style: normal; 166 + font-display: swap; 151 167 } 152 168 153 169 @font-face { 154 - font-family: 'Inconsolata Variable'; 155 - src: url('Inconsolata[wdth][wgth].ttf') format('truetype-variations'); 156 - font-weight: 200 900; 157 - font-style: normal; 158 - font-display: swap; 170 + font-family: "Inconsolata Variable"; 171 + src: url("Inconsolata[wdth][wgth].ttf") format("truetype-variations"); 172 + font-weight: 200 900; 173 + font-style: normal; 174 + font-display: swap; 159 175 }
+31 -29
public/global.css
··· 1 1 /* Import font(s) */ 2 2 3 3 :root { 4 - --mono: "Lucida Console", Monaco, monospace; 4 + --mono: "Lucida Console", Monaco, monospace; 5 5 } 6 6 7 7 body { 8 - margin: 0; 9 - font-size: 14px; 10 - line-height: 1.5; 11 - font-family: Manrope Variable, Manrope; 12 - font-weight: 500; 8 + margin: 0; 9 + font-size: 14px; 10 + line-height: 1.5; 11 + font-family: 12 + Manrope Variable, 13 + Manrope; 14 + font-weight: 500; 13 15 } 14 16 15 17 h1, ··· 18 20 h4, 19 21 h5, 20 22 h6 { 21 - margin: 0 0 0.5em 0; 22 - font-weight: 400; 23 - line-height: 1.2; 23 + margin: 0 0 0.5em 0; 24 + font-weight: 400; 25 + line-height: 1.2; 24 26 } 25 27 26 28 h1 { 27 - font-size: 2em; 29 + font-size: 2em; 28 30 } 29 31 30 32 a { 31 - color: inherit; 33 + color: inherit; 32 34 } 33 35 34 36 code, 35 37 pre { 36 - font-family: "Lucida Console", Monaco, monospace; 38 + font-family: "Lucida Console", Monaco, monospace; 37 39 } 38 40 39 41 @media (min-width: 400px) { 40 - body { 41 - font-size: 16px; 42 - } 42 + body { 43 + font-size: 16px; 44 + } 43 45 } 44 46 45 47 pre { 46 - overflow: auto; 48 + overflow: auto; 47 49 } 48 50 49 51 .blog-entry pre { 50 - font-size: 0.75rem; 52 + font-size: 0.75rem; 51 53 } 52 54 53 55 .blog-entry h2, ··· 55 57 .blog-entry h4, 56 58 .blog-entry h5, 57 59 .blog-entry h6 { 58 - font-weight: bold; 59 - margin: 2rem 0; 60 + font-weight: bold; 61 + margin: 2rem 0; 60 62 } 61 63 62 64 .blog-entry :where(h2, h3, h4, h5, h6)::before { 63 - color: lightgray; 64 - font-weight: bold; 65 - margin-right: 1ch; 66 - font-family: var(--mono); 65 + color: lightgray; 66 + font-weight: bold; 67 + margin-right: 1ch; 68 + font-family: var(--mono); 67 69 } 68 70 69 71 .blog-entry h2::before { 70 - content: '##'; 72 + content: "##"; 71 73 } 72 74 73 75 .blog-entry h3::before { 74 - content: '###'; 76 + content: "###"; 75 77 } 76 78 77 79 .blog-entry h4::before { 78 - content: '####'; 80 + content: "####"; 79 81 } 80 82 81 83 .blog-entry h5::before { 82 - content: '#####'; 84 + content: "#####"; 83 85 } 84 86 85 87 .blog-entry h6::before { 86 - content: '######'; 88 + content: "######"; 87 89 } 88 90 89 91 .blog-entry img { 90 - max-width: 100%; 92 + max-width: 100%; 91 93 }