{"version":"https://jsonfeed.org/version/1","title":"Deniz Akşimşek","icon":"https://denizaksimsek.com/assets/me.jpeg","home_page_url":"https://denizaksimsek.com/","feed_url":"https://denizaksimsek.com/feed.json","author":{"name":"Deniz Akşimşek","url":"https://denizaksimsek.com/","avatar":"https://denizaksimsek.com/assets/me.jpeg"},"items":[{"id":"/2024/kill-all-distros/","title":"kill all distros","content_html":"\n\n
\n\n\n\nkill all distros\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nkill all distros\n\n\n\n \n \n \n
kill all distros
\n \n\n \n \n \n\n \n
\n
so insane to me that people advocate for distro packaging over flatpak
\n
hmm yes i love being unable to use up-and-coming software thet nobody packages
\n
yet and making it harder for new distros to get off the ground
\n
vertical monopolies are good when open source i guess
\n
the concept of software package management existing is a failure
\n
one (1) software should be expressible as one thing
\n
\n\n \n\n \n \n\n\n","content_text":"so insane to me that people advocate for distro packaging over flatpak\n\nhmm yes i love being unable to use up-and-coming software thet nobody packages \n\nyet and making it harder for new distros to get off the ground \n\nvertical monopolies are good when open source i guess\n\nthe concept of software package management existing is a failure\n\none (1) software should be expressible as one thing\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2024/bamboo-paper/","title":"Why Bamboo Paper is my favorite note taking app that I never use","content_html":"\n\n\n\n\n\nWhy Bamboo Paper is my favorite note taking app that I never use\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nWhy Bamboo Paper is my favorite note taking app that I never use\n\n\n\n \n \n \n
Why Bamboo Paper is my favorite note taking app that I never use
\n \n\n \n \n \n\n \n
\n
Bamboo Paper is an app released by Wacom in 2014, presumably to promote their Bamboo series of capacitive pens. It features 6 pens, 3 of which need to be unlocked via in-app purchases. Notes are stored in the proprietary WILL format, and can only be synced to Wacom’s own Inkspace cloud service. Otherwise, backing up notes involves exporting each notebook manually to PDF.
\n
Due to these restrictions, I don’t use it that often to actually take notes. However, I can’t think of a single note taking app that I enjoy as much.
\n
It’s not because of the minimalist interface, or the satisfying action of the pressure-sensitive brushes and pens, though I love both of those things. Only recently have I realized what draws me to this app.
\n
Notebooks in Bamboo Paper have the same size as your device’s display. When you rotate the device, the UI rotates, but the notebook itself remains in the same orientation relative to the device. Zooming in is possible, but unwieldy, and you can’t zoom out beyond 100%.
\n
All these limitations mean that writing on Bamboo Paper feels like writing on a notebook, whereas using any other app feels like playing a game where your character writes in a notebook. When penstrokes are bound to the specific location on the tablet’s front glass where I put the pen, it makes spatial reasoning more natural, and spatial reasoning is the main advantage of taking handwritten notes over textual notes using handwriting recognition.
\n
Using Bamboo Paper with floating windows of other apps in front of it, as Samsung lets me do, is the closest feeling I’ll probably get to using a Microsoft Courier – at least, it would be if Paper had drag-and-drop support. It might be a 10 year old app but it did get an update last August, so come on Wacom…
\n
Despite all my searching, I haven’t found another app on Android that imitates Paper’s model. Some apps like Samsung Notes zoom and scroll like Word documents, while other apps have an infinite canvas that makes me feel disoriented. Since I want to store my notes somewhere that’s not too likely to disappear next year, I put up with the Word doc, but I’m putting this out there in case someone points me to the perfect virtual notebook
\n
\n\n \n\n \n \n\n\n","content_text":"[Bamboo Paper] is an app released by Wacom in 2014, presumably to promote their Bamboo series of capacitive pens. It features 6 pens, 3 of which need to be unlocked via in-app purchases. Notes are stored in the proprietary WILL format, and can only be synced to Wacom's own Inkspace cloud service. Otherwise, backing up notes involves exporting each notebook manually to PDF.\n\n[Bamboo Paper]: https://www.wacom.com/en-us/products/apps-services/bamboo-paper\n\nDue to these restrictions, I don't use it that often to actually take notes. However, I can't think of a single note taking app that I enjoy as much.\n\nIt's not because of the minimalist interface, or the satisfying action of the pressure-sensitive brushes and pens, though I love both of those things. Only recently have I realized what draws me to this app.\n\nNotebooks in Bamboo Paper have the same size as your device's display. When you rotate the device, the UI rotates, but the notebook itself remains in the same orientation relative to the device. Zooming in is possible, but unwieldy, and you can't zoom out beyond 100%.\n\nAll these limitations mean that writing on Bamboo Paper feels like writing on a notebook, whereas using any other app feels like playing a game where your character writes in a notebook. When penstrokes are bound to the specific location on the tablet's front glass where I put the pen, it makes spatial reasoning more natural, and spatial reasoning is the main advantage of taking handwritten notes over textual notes using handwriting recognition.\n\nUsing Bamboo Paper with floating windows of other apps in front of it, as Samsung lets me do, is the closest feeling I'll probably get to using a Microsoft Courier -- at least, it would be if Paper had drag-and-drop support. It might be a 10 year old app but it did get an update last August, so come on Wacom...\n\nDespite all my searching, I haven't found another app on Android that imitates Paper's model. Some apps like Samsung Notes zoom and scroll like Word documents, while other apps have an infinite canvas that makes me feel disoriented. Since I want to store my notes somewhere that's not too likely to disappear next year, I put up with the Word doc, but I'm putting this out there in case someone points me to the perfect virtual notebook \n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2023/starting-denizen/","title":"Introducing Denizen","content_html":"\n\n\n\n\n\nIntroducing Denizen\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nIntroducing Denizen\n\n\n\n \n \n \n
Introducing Denizen
\n \n\n \n \n \n\n \n
\n
I’m building Denizen (https://denizen.dz4k.com/), a personal website system that is IndieWeb and Fediverse compatible.
\n\n \n\n \n \n \n\n\n","content_text":"I'm building Denizen (), a personal website system that is IndieWeb and Fediverse compatible.\n\nSource code: \n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2023/xpath/","title":"Using XPath in 2023","content_html":"\n\n\n\n\n\nUsing XPath in 2023\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nUsing XPath in 2023\n\n\n\n \n \n \n
Using XPath in 2023
\n \n\n \n \n \n\n \n
\n
In the latest release of htmx,\nyou can add event listeners to elements with hx-on:
For all the other hx- attributes, we use CSS attribute selectors.\nHowever, with hx-on, the attribute name is not fixed as it contains the event.\nCSS attribute selectors support wildcards on the value of attributes,\nbut not the name:
\n
[hx-trigger] /* common and normal */\n[href^="https://dz4k.com"] /* "starts with" operator */\n[^ĥx-on:] /* not a thing */\n
\n
XPath
\n
XPath is a query language for extracting information from XML(-like) documents.\nIts main use cases are XSLT and parsing API responses.
\n
The XPath language is significantly more expressive than CSS,\nmaking it possible to traverse the XML tree in any direction,\nfilter nodes based on arbitrary predicates,\nand select any kind of node\n(including comments, text nodes, and individual attributes).\nOur non-existent CSS attribute could be written as follows:
\n
//@*[starts-with(name(), "hx-on:")]\n
\n
This post is not supposed to be an XPath tutorial, but I’ll break this one down:
\n
\n
//
\n
traverse the document (in CSS, this is the default)
\n
@*
\n
find any attribute (mnemonic: at-tribute)
\n
[ ... ]
\n
where…
\n
starts-with(name(), "hx-on:")
\n
its name starts with "hx-on:"
\n
\n
CSS selectors don’t have these kinds of features,\nand it has good reasons not to.\nCSS has strict performance requirements\n– to the point that “CSS optimization” is generally not a thing –\nand selectors that offer more control could make slow selectors possible.\nIn addition, CSS has well-defined specificity rules, whereas XPath does not.
\n
However, while these features make CSS great for stylesheets,\nCSS selectors are also the most common way to find DOM elements in\nJavaScript code and lacking in that regard.\nMany libraries which extend HTML do so by traversing the entire document\nand finding elements manually.\nThis is often not needed since, if you didn’t know,\nXPath is built into browsers.
\n
document.evaluate
\n
The document.evaluate API is somewhat archaic,\npartly because it was designed for talking to XML APIs over XMLHTTPRequest.\nHere’s a DOM-friendly wrapper:
\n\n \n\n \n \n \n\n\n","content_text":"In the latest release of [htmx],\nyou can add event listeners to elements with `hx-on`:\n\n```html\n<form hx-on::beforeRequest=\"addCsrfToken(event);\">\n```\n\nFor all the other `hx-` attributes, we use CSS attribute selectors.\nHowever, with `hx-on`, the attribute name is not fixed as it contains the event.\nCSS attribute selectors support wildcards on the _value_ of attributes,\nbut not the name:\n\n```css\n[hx-trigger] /* common and normal */\n[href^=\"https://dz4k.com\"] /* \"starts with\" operator */\n[^ĥx-on:] /* not a thing */\n```\n\n## XPath\n\nXPath is a query language for extracting information from XML(-like) documents.\nIts main use cases are XSLT and parsing API responses.\n\nThe XPath language is significantly more expressive than CSS,\nmaking it possible to traverse the XML tree in any direction,\nfilter nodes based on arbitrary predicates,\nand select any kind of node\n(including comments, text nodes, and individual attributes).\nOur non-existent CSS attribute could be written as follows:\n\n```xpath\n//@*[starts-with(name(), \"hx-on:\")]\n```\n\nThis post is not supposed to be an XPath tutorial, but I'll break this one down:\n\n\n`//`\n: traverse the document (in CSS, this is the default)\n\n`@*`\n: find any attribute (mnemonic: **at**-tribute)\n\n`[ ... ]`\n: where...\n\n`starts-with(name(), \"hx-on:\")`\n: its name starts with `\"hx-on:\"`\n\n\nCSS selectors don't have these kinds of features,\nand it has good reasons not to.\nCSS has strict performance requirements\n-- to the point that \"CSS optimization\" is generally not a thing --\nand selectors that offer more control could make slow selectors possible.\nIn addition, CSS has well-defined specificity rules, whereas XPath does not.\n\nHowever, while these features make CSS great for stylesheets,\nCSS selectors are also the most common way to find DOM elements in\nJavaScript code and lacking in that regard.\nMany libraries which extend HTML do so by traversing the entire document\nand finding elements manually.\nThis is often not needed since, if you didn't know,\n**XPath is built into browsers.**\n\n## document.evaluate\n\nThe [`document.evaluate` API] is somewhat archaic,\npartly because it was designed for talking to XML APIs over `XMLHTTPRequest`.\nHere's a DOM-friendly wrapper:\n\n```ts\nfunction* xpath(...args) {\n let path, root = document;\n if (args.length > 1) [root, path] = args;\n else [path] = args;\n\n const nodeIterator = document.evaluate(\n path,\n root,\n null,\n XPathResult.UNORDERED_NODE_ITERATOR_TYPE,\n null,\n );\n\n for (\n let node = nodeIterator.iterateNext();\n node != null;\n node = nodeIterator.iterateNext()\n ) {\n yield node;\n }\n}\n\n// TypeScript declaration\nfunction xpath(path: string): Iterable;\nfunction xpath(root: Element, path: string): Iterable;\n```\n\n[htmx]: https://htmx.org\n[`document.evaluate` API]: https://developer.mozilla.org/en-US/Web/XPath/Introduction_to_using_XPath_in_JavaScript\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2023/programming-on-a-tablet/","title":"Programming on an Android tablet","content_html":"\n\n\n\n\n\nProgramming on an Android tablet\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nProgramming on an Android tablet\n\n\n\n \n \n \n
Programming on an Android tablet
\n \n\n \n \n \n\n \n
\n
I recently purchased a Samsung Galaxy Tab S7 FE.\nI wasn’t planning on making it a laptop replacement,\nbut I had some experience with Android’s capabilities for development\n(from when I only had a phone)\nand the possibility was irresistible.
\n
SSH into my laptop was a no-go.\nI have no idea how to expose my laptop to the internet in a way that works,\nlet alone is safe.\nBesides, my model didn’t have mobile data support for on-the-go.\nI wanted to run a Linux dev environment on the tablet itself.
\n\n
Termux
\n
\n
Termux is an Android terminal emulator and Linux environment app\nthat works directly with no rooting or setup required.\nA minimal base system is installed automatically -\nadditional packages are available using the APT package manager.
Termux is not a VM, container or emulator –\nit’s a terminal in the host system.\nBecause the places where a Linux distro would usually install software\nare write-only on an Android device,\nTermux places software and your home directory inside its data directory\n(TODO)\nand uses the $PREFIX environment variable.
\n
In my experience, this works until it doesn’t.\nSoftware in the Termux repositories works as expected,\nbut anything that needs to be built locally or piped to sh from an URL\nwill likely be confused by the odd directory structure.
\n
In my phone-only days, this worked fine.\nHowever, I have projects now that depend on software not packaged for Termux.
\n
Can’t I just have a container or something?
\n
PRoot-Distro
\n
\n
PRoot is a user-space implementation of chroot, mount --bind, and binfmt_misc.
\n
\n
I’m not super clear on the details,\nbut it seems that Android doesn’t let you do most of the things you need for a\ncontainer runtime.\nPRoot is a solution to that.
\n
The Termux project maintains a fork of PRoot as well as a wrapper program\ncalled PRoot-Distro.\nPRoot-Distro has an interface that will be familiar to anyone who has used\nDistrobox or toolbx:
This drops you into a fully-functional Fedora shell.\nAfter my previous failed attempts, I was surprised to see how well it works:
\n
\n
You can access the network\n(this didn’t work with another PRoot solution I tried –\nsomething to do with Android not allowing raw DNS traffic?)
\n
You can start a server on the container and access it from the host
\n
You can access the host Android filesystem\n(not the Termux home, the one that has your pictures and\nWhatsApp voice messages) from the container through the /storage directory
\n
\n
One thing to note is you are still on an ARM device.\nSoftware that is not compiled for ARM will not work.\nHowever, I only hit this once while installing Deno –\nand even then, ARM builds are available through a fork.
\n
Summary
\n
\n
\n
Install Termux
\n
\n
\n
Install PRoot-Distro
\n
pkg install proot-distro\n
\n
\n
\n
Set up a container
\n
proot-distro create fedora\n
\n
\n
\n
Enter your container
\n
proot-distro login fedora\n
\n
\n
\n
Hardware
\n
\n
Samsung Galaxy Tab S7 FE SM-T733
\n
Ztotop Magnetic Case
\n
Logitech K380 Bluetooth Keyboard
\n
\n
\n\n \n\n \n \n \n\n\n","content_text":"I recently purchased a Samsung Galaxy Tab S7 FE.\nI wasn't planning on making it a laptop replacement,\nbut I had some experience with Android's capabilities for development\n(from when I only had a phone)\nand the possibility was irresistible.\n\nSSH into my laptop was a no-go.\nI have no idea how to expose my laptop to the internet in a way that works,\nlet alone is safe.\nBesides, my model didn't have mobile data support for on-the-go.\nI wanted to run a Linux dev environment on the tablet itself.\n\n![The tablet, in a magnetic stand case, with a keyboard in front of it, on a desk](/assets/photos/tablet-programming.jpg)\n\n## Termux\n\n> Termux is an Android terminal emulator and Linux environment app\n> that works directly with no rooting or setup required.\n> A minimal base system is installed automatically -\n> additional packages are available using the APT package manager.\n\n-- \n\nTermux is not a VM, container or emulator --\nit's a terminal in the host system.\nBecause the places where a Linux distro would usually install software\nare write-only on an Android device,\nTermux places software and your home directory inside its data directory\n(`TODO`)\nand uses the `$PREFIX` environment variable.\n\nIn my experience, this works until it doesn't.\nSoftware in the Termux repositories works as expected,\nbut anything that needs to be built locally or piped to `sh` from an URL\nwill likely be confused by the odd directory structure.\n\nIn my phone-only days, this worked fine.\nHowever, I have projects now that depend on software not packaged for Termux.\n\nCan't I just have a container or something?\n\n## PRoot-Distro\n\n> PRoot is a user-space implementation of chroot, mount --bind, and binfmt_misc.\n\nI'm not super clear on the details,\nbut it seems that Android doesn't let you do most of the things you need for a\ncontainer runtime.\nPRoot is a solution to that.\n\nThe Termux project maintains a fork of PRoot as well as a wrapper program\ncalled PRoot-Distro.\nPRoot-Distro has an interface that will be familiar to anyone who has used\nDistrobox or toolbx:\n\n```\nproot-distro create fedora\nproot-distro login fedora\n```\n\nThis drops you into a fully-functional Fedora shell.\nAfter my previous failed attempts, I was surprised to see how well it works:\n\n - You can access the network\n (this didn't work with another PRoot solution I tried --\n something to do with Android not allowing raw DNS traffic?)\n - You can start a server on the container and access it from the host\n - You can access the host Android filesystem\n (not the Termux home, the one that has your pictures and\n WhatsApp voice messages) from the container through the `/storage` directory\n\nOne thing to note is you are still on an ARM device.\nSoftware that is not compiled for ARM will not work.\nHowever, I only hit this once while installing Deno --\nand even then, ARM builds are available through a fork.\n\n## Summary\n\n- Install Termux\n\n- Install PRoot-Distro\n ```\n pkg install proot-distro\n ```\n\n- Set up a container\n ```\n proot-distro create fedora\n ```\n\n- Enter your container\n ```\n proot-distro login fedora\n ```\n\n## Hardware\n\n- Samsung Galaxy Tab S7 FE SM-T733\n- Ztotop Magnetic Case\n- Logitech K380 Bluetooth Keyboard\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2023/you-dont-need-modal/","title":"You don't need a modal window","content_html":"\n\n\n\n\n\nYou don't need a modal window\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nYou don't need a modal window\n\n\n\n \n \n \n
this is a new programming language, right?\nand the people who made it are also making a blockchain thing for it to run on.\nwhich made some people, including me, sad.\nso someone laments this, and someone else comes in:
\n\n
\n
The author writes in the Kindelia Readme:
\n
\n
There is no native coin. It is not a cryptocurrency. It is a cryptocomputer.\nWhich to me says they’re focusing on the decentralized application portion of blockchains instead of the scam coins.
\n
\n
\n
now, i wasn’t convinced.\nbecause, i’m no expert but, a blockchain can’t work without a currency, right?\nit’s part of the algorithmic foundation to have some token that the chain itself can reimburse participants with…
\n
so how did they do this? did they finally invent a Good Blockchain?
\n
website takes me to readme, “There is no native coin” ok but how? readme takes me to whitepaper:
\n\n
It’s a marketing trick.\n“No native coin” just means that the coin is pluggable.
\n
I’m going to commit crimes.
\n
\n\n \n\n \n \n\n\n","content_text":"<%~ await includeFile(\"embed.eta\", { filters, url: \"https://lobste.rs/s/22yudo/kindelia_kind_next_gen_functional\" }) %>\n\n\nthis is a new programming language, right?\nand the people who made it are also making a blockchain thing for it to run on.\nwhich made some people, including me, sad.\nso someone laments this, and someone else comes in: \n\n\n\n> The author writes in the Kindelia Readme:\n> > There is no native coin. It is not a cryptocurrency. It is a cryptocomputer.\n> Which to me says they’re focusing on the decentralized application portion of blockchains instead of the scam coins.\n\nnow, i wasn't convinced.\nbecause, i'm no expert but, a blockchain can't work without a currency, right?\nit's part of the algorithmic foundation to have some token that the chain itself can reimburse participants with...\n\nso how did they do this? did they finally invent a Good Blockchain?\n\nwebsite takes me to readme, \"There is no native coin\" ok but how? readme takes me to whitepaper:\n\n\n\n**It's a marketing trick.**{.allcaps}\n\"No native coin\" just means that the coin is pluggable.\n\nI'm going to commit crimes.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/a-hypermedia-canvas/","title":"A Hypermedia Canvas","content_html":"\n\n\n\n\n\nA Hypermedia Canvas\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nA Hypermedia Canvas\n\n\n\n \n \n \n
A Hypermedia Canvas
\n \n\n \n \n \n\n \n
\n
/fileshare/2022-09-30 a hypermedia canvas 2022-10-25.pdf
\n
\n\n \n\n \n \n\n\n","content_text":"/fileshare/2022-09-30 a hypermedia canvas 2022-10-25.pdf","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/java-and-javascript/","title":"Similarities between Java and JavaScript","content_html":"\n\n\n\n\n\nSimilarities between Java and JavaScript\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nSimilarities between Java and JavaScript\n\n\n\n \n \n \n
Similarities between Java and JavaScript
\n \n\n \n \n \n\n \n
\n
Java and JavaScript are a lot more similar than we give them credit for.
\n
\n
A much-maligned language.
\n
Old, crufty APIs.
\n
Nicer today than many people remember.
\n
Complex build tools.
\n
Frameworks and metaframeworks galore.
\n
So, so much reflection.
\n
A vast universe of libraries for everything.
\n
Runs on very cursed places. (Java on SIM cards, JavaScript on spacecrafts)
\n
How do I make this an executable?
\n
Brilliant runtime.
\n
\n
The main difference:\nJava programmers pretend they’re using JavaScript,\nand JavaScript programmers pretend they’re using Java.
\n
\n\n \n\n \n \n\n\n","content_text":"Java and JavaScript are a lot more similar than we give them credit for.\n\n * A much-maligned language.\n * Old, crufty APIs.\n * Nicer today than many people remember.\n * Complex build tools.\n * Frameworks and metaframeworks galore.\n * So, so much reflection.\n * A vast universe of libraries for everything.\n * Runs on very cursed places. (Java on SIM cards, JavaScript on spacecrafts)\n * How do I make this an executable?\n * Brilliant runtime.\n\nThe main difference:\nJava programmers pretend they're using JavaScript,\nand JavaScript programmers pretend they're using Java.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/cdns-run-code/","title":"CDNs can run code now","content_html":"\n\n\n\n\n\nCDNs can run code now\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nCDNs can run code now\n\n\n\n \n \n \n
CDNs can run code now
\n \n\n \n \n \n\n \n
\n
One area where htmx apps lag behind SPAs is interaction delay.\nWhile htmx apps usually have a much improved initial load time,\nthe need for a server roundtrip for most interactions is a disadvantage.
\n
For most apps, this doesn’t matter, as they are all frontends to databases anyway.\nThus, there is always a request to the server;\nthe difference is whether the response is HTML or a proprietary JSON-based format that needs to be converted to HTML.
\n
The latency issue is even less of a problem thanks to… let’s call it Application on CDN (AoCDN).\nThe common term for this technology is “edge compute”,\nwhich I refuse to say.
\n
AoCDN is a service offered by some hosting and CDN providers.\nIt means that your code runs on several servers all across the world, close to the user.
\n
\n\n \n\n \n \n\n\n","content_text":"One area where htmx apps lag behind SPAs is interaction delay.\nWhile htmx apps usually have a much improved initial load time,\nthe need for a server roundtrip for most interactions is a disadvantage.\n\nFor most apps, this doesn't matter, as they are all frontends to databases anyway.\nThus, there is always a request to the server;\nthe difference is whether the response is HTML or a proprietary JSON-based format that needs to be converted to HTML.\n\nThe latency issue is even less of a problem thanks to... let's call it Application on CDN (AoCDN).\nThe common term for this technology is \"edge compute\",\nwhich I refuse to say.\n\nAoCDN is a service offered by some hosting and CDN providers.\nIt means that your code runs on several servers all across the world, close to the user.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/2022-07-19T12:49:37.803Z/","title":"Resource Traversal","content_html":"\n\n\n\n\n\nResource Traversal\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nResource Traversal\n\n\n\n \n \n \n
Server will internally GET each link up to the last, and respond with a 307\nredirect to the last.
\n
\n\n \n\n \n \n\n\n","content_text":"## Resource Expansion ##\n\n < GET https://example.com/users/john_doe\n > { \"name\": \"John Doe\", \"friends\": \"/users/john_doe/friends\" }\n \n < GET https://example.com/users/john_doe?expand=friends\n > { \"name\": \"John Doe\", \"friends\": { \"joe_bloggs\": \"/users/joe_bloggs\" } }\n\nSubstitute the link named `friends` with the resource at that link.\n\n\n## Resource Traversal ##\n\n < DELETE https://example.com/users/john_doe?traverse=friends.joe_bloggs\n > { \"msg\": \"Removed friend joe_bloggs\" }\n\nServer will internally GET each link up to the last, and respond with a 307\nredirect to the last.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/writing-things-down/","title":"Writing things down","content_html":"\n\n\n\n\n\nWriting things down\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nWriting things down\n\n\n\n \n \n \n
Writing things down
\n \n\n \n \n \n\n \n
\n
the Ideal Self looks on in and says: pakala
\n
There are a few intersecting online communities I lurk around that revolve around writing things down:
\n
\n
notebook fans, r/notebooks (“I can stop buying them whenever I want.”)
\n
plain text enjoyers (“Clearly the solution is to write a parser.”)
\n
“productivity” communities (“look at my Notion/Org Mode/Obsidian/… setup!” / unixporn for people with jobs)
\n
the Bullet Journal community (Plug in your own snarky comment for this one)
\n
\n
Why I want to do it
\n
I want to write things down, I really do. I want to keep a diary, and todo lists, and kanban boards. Why? Any of the communities above would be happy to give you a laundry list of reasons to write things down, but there are two in particular that resonate with me.
\n
The first: I want to get things out of my brain. I’ve always been a forgetful person, so, I rode the productivity tool carousel.
\n
A few times, something actually worked for a bit. My best streak was keeping weekly Bullet Journal-like to-do lists throughout the last year of high school, as I was preparing for university entrance exams.
\n
That brings me to the second reason I want to write things down: keeping a log[1]. Having a record of things you did and thought seems useful in theory. Yet, I threw out the lovely little book I kept my to-dos in, and I don’t really miss them. I feel like I should be upset about not having it, and that does bother me, but I’m not bothered by the book itself. Why is that?
\n
Looking upon my own works and despairing
\n
I want to write things down quickly. I want to take notes in lectures without having to splice them with textbooks later. I want to write down an appointment before I forget, or an idea before I free-associate away from it.
\n
But I can’t bring myself to commit anything to paper. I can’t just take notes, I have to write myself a textbook. If I write down an idea, I can’t pull away without preparing a design document. Yet every sentence of such tomes would be subject to the same fear, and the result is pages half-reserved (read: empty).
\n
This leads to a conflict between the two motivations for writing things down.
\n
ijo nasa li pona e mi
\n
I’ve been keeping a journal for around a year now. I write in it pretty infrequently, but it’s still helpful and I managed to actually finish a (admittedly very thin) notebook for once!
\n
The unique thing is that I write most of my entries in Toki Pona. I’ve heard of people using it in this way, and I gave it a try. It was initially just the novelty of the language that motivated me to keep going, but I was surprised to actually enjoy reading these back after a few months.
\n
The trick is that the simplicity of the language (combined with my lack of actual conversation experience) means that my entries don’t have a voice, that mix of word choice, syntax, and many other things that identify a particular author. They don’t have the trace of yesterday-me’s self image, which today-me finds repugnant.
\n
Am I genuinely going to write about cringing at my past self? Right now? This is repugnant already! Pressing through…
\n
That’s really it — there is a stark difference between words for the public eye and words for myself, and I can’t get myself to write the second on paper. Paper seems like another person.
\n\n
It dawns on me after writing (aha!) that I can’t write things that identify me — that when I write something for the public eye, I edit it down and remove any trace of myself I spot. That doesn’t seem healthy…
\n
I think what that makes me is self-conscious, but that sounds too positive to be right. Why wouldn’t you want to be conscious of yourself? At the same time, I don’t want so spend time thinking of ways to pity myself.
\n
Maybe this is something I’ll just get over. Then writing this post down would be pretty pointless…
\n
But I wouldn’t care!
\n\n\n\n
There is a secret third reason why I want to write things down: notebooks and text editors are fun. ↩︎
\n
\n\n\n
\n\n \n\n \n \n\n\n","content_text":"_the Ideal Self looks on in and says: pakala_\n\nThere are a few intersecting online communities I lurk around that revolve around writing things down:\n\n - notebook fans, [r/notebooks] (\"I can stop buying them whenever I want.\")\n - plain text enjoyers (\"Clearly the solution is to write a parser.\")\n - \"productivity\" communities (\"look at my Notion/Org Mode/Obsidian/... setup!\" / unixporn for people with jobs)\n - the Bullet Journal community (Plug in your own snarky comment for this one)\n\n[r/notebooks]: https://reddit.com/r/notebooks\n\n\n## Why I want to do it\n\nI want to write things down, I really do. I want to keep a diary, and todo lists, and kanban boards. Why? Any of the communities above would be happy to give you a laundry list of reasons to write things down, but there are two in particular that resonate with me.\n\nThe first: I want to get things out of my brain. I've always been a forgetful person, so, I rode the productivity tool carousel.\n\nA few times, something actually worked for a bit. My best streak was keeping weekly Bullet Journal-like to-do lists throughout the last year of high school, as I was preparing for university entrance exams.\n\nThat brings me to the second reason I want to write things down: keeping a log[^1]. Having a record of things you did and thought seems useful in theory. Yet, I threw out the lovely little book I kept my to-dos in, and I don't really miss them. I _feel_ like I should be upset about not having it, and that does bother me, but I'm not bothered by the book itself. Why is that?\n\n\n## Looking upon my own works and despairing\n\nI want to write things down quickly. I want to take notes in lectures without having to splice them with textbooks later. I want to write down an appointment before I forget, or an idea before I free-associate away from it.\n\nBut I can't bring myself to commit anything to paper. I can't just take notes, I have to write myself a textbook. If I write down an idea, I can't pull away without preparing a design document. Yet every sentence of such tomes would be subject to the same fear, and the result is pages half-reserved (read: empty).\n\nThis leads to a conflict between the two motivations for writing things down.\n\n\n# ijo nasa li pona e mi {lang=tok}\n\nI've been keeping a journal for around a year now. I write in it pretty infrequently, but it's still helpful and I managed to actually finish a (admittedly very thin) notebook for once!\n\nThe unique thing is that I write most of my entries in Toki Pona. I've heard of people using it in this way, and I gave it a try. It was initially just the novelty of the language that motivated me to keep going, but I was surprised to actually enjoy reading these back after a few months.\n\nThe trick is that the simplicity of the language (combined with my lack of actual conversation experience) means that my entries don't have a _voice_, that mix of word choice, syntax, and many other things that identify a particular author. They don't have the trace of yesterday-me's self image, which today-me finds repugnant.\n\n_Am I genuinely going to write about cringing at my past self? Right now? This is repugnant already! Pressing through..._\n\nThat's really it --- there is a stark difference between words for the public eye and words for myself, and I can't get myself to write the second on paper. Paper seems like another person.\n\n\n---\n\nIt dawns on me after writing (aha!) that I can't write things that identify me --- that when I write something for the public eye, I edit it down and remove any trace of myself I spot. That doesn't seem healthy...\n\nI think what that makes me is _self-conscious_, but that sounds too positive to be right. Why wouldn't you want to be conscious of yourself? At the same time, I don't want so spend time thinking of ways to pity myself.\n\nMaybe this is something I'll just get over. Then writing this post down would be pretty pointless...\n\n_But I wouldn't care!_\n\n[^1]: There is a secret third reason why I want to write things down: notebooks and text editors are **fun**.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/2022-06-27T18:54:05.038Z/","title":"A missing.css conundrum","content_html":"\n\n\n\n\n\nA missing.css conundrum\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nA missing.css conundrum\n\n\n\n \n \n \n
A missing.css conundrum
\n \n\n \n \n \n\n \n
\n
I want to add a dark theme to missing.css out of the box using the prefers-color-scheme media query. This is a pretty straightforward thing to do, but it causes a problem when you add your own styles on top of missing.css (the expected main usage). Consider:
If the user has dark theme enabled system-wide, two things might happen depending on how we implement things:
\n
\n
The dark theme accent color in missing.css overrides the custom accent
\n
The custom accent is used with missing.css’s dark theme colors, probably ugly and bad contrast
\n
\n
Neither of these are desirable. The only way to prevent this would be to force everyone to specify their custom colors in both light and dark theme – even if they don’t want to support dark theme.
\n
As for solutions:
\n
\n
One option is to require a class to enable automatic theme switching. This will work and not be much trouble, but makes missing.css less valuable as a classless CSS library.
\n
\n
Thoughts?
\n
\n\n \n\n \n \n\n\n","content_text":" I want to add a dark theme to missing.css out of the box using the `prefers-color-scheme` media query. This is a pretty straightforward thing to do, but it causes a problem when you add your own styles on top of missing.css (the expected main usage). Consider:\n\n - You install missing.css\n - You override the [`--accent`](https://missing.style/docs/variables/#--accent) variable\n\nIf the user has dark theme enabled system-wide, two things might happen depending on how we implement things:\n\n - The dark theme accent color in missing.css overrides the custom accent\n - The custom accent is used with missing.css's dark theme colors, probably ugly and bad contrast\n\nNeither of these are desirable. The only way to prevent this would be to force everyone to specify their custom colors in both light and dark theme -- even if they don't want to support dark theme.\n\nAs for solutions:\n\n - One option is to require a class to enable automatic theme switching. This will work and not be much trouble, but makes missing.css less valuable as a classless CSS library.\n\nThoughts?\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/hyperscript-cheatsheet/","title":"_hyperscript Cheatsheet","content_html":"\n\n\n\n\n\n_hyperscript Cheatsheet\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\n_hyperscript Cheatsheet\n\n\n\n \n \n \n
_hyperscript Cheatsheet
\n \n\n \n \n \n\n \n
\n \n\n
Event listeners
\n
\n\n
\n
\n
Syntax
\n
Meaning
\n
\n\n\n
\n
\n
on
\n
add event listener
\n
\n
\n
\n
every
\n
do not queue events
\n
\n
\n
\n
mousemove
\n
event name
\n
\n
\n
\n
(clientX, clientY)
\n
expose the event’s properties
\n
\n
\n
\n
[clientX > 100]
\n
filter events
\n
\n
\n
\n
3
\n
only respond to 3rd click
\n
\n
\n
or
\n
3 to 10
\n
respond to 3rd, 4th … 10th click
\n
\n
\n
or
\n
3 and on
\n
respond to all clicks except 1st and 2nd
\n
\n
\n
\n
from #my-form
\n
element to attach listeners to, (?? me)
\n
\n
\n
\n
debounced at 200ms
\n
trailing debounce (200ms delay, resets on every event)
\n
\n
\n
or
\n
throttled at 200ms
\n
every 200ms at most regardless of the number of events
\n
\n
\n
\n
or keyup ...
\n
specify many events, each with its own from/debounce/…
\n
\n
\n
\n
\n
if events arrive while the listener is already running…
\n
\n
\n
\n
queue all
\n
add them to a FIFO queue
\n
\n
\n
or
\n
queue none
\n
discard them
\n
\n
\n
or
\n
queue first
\n
enqueue the first one, discard the rest
\n
\n
\n
or
\n
queue last
\n
enqueue the last one, discard the rest (this is the default)
\n
\n\n
\n\n\n
Property access
\n
\n
user.data.name
\n
user’s data’s name
\n
name of data of user
\n
data.name of user
\n
user’s data.name
\n
\n\n\n
CSS literals
\n
\n
#my-form
\n
Get element by id
\n
#{getID()}
\n
Dynamic ID
\n
.active
\n
Get elements by class
\n
.{getClass()}
\n
Dynamic class
\n
<em, i />
\n
Query selector all
\n
<ul:nth-child(${n}) />
\n
Dynamic selector
\n
\n\n\n
Sigils
\n
\n
foo
\n
local variable by default
\n
:foo
\n
element scoped variable, persisted. can be declared with top-level set. behaviors are isolated from one another
\n
$foo
\n
global variable
\n
@foo
\n
HTML attribute
\n
\n\n\n
Array operations
\n
first in arr ≡ first from arr\n≡ first of arr ≡ first arr
\n
also random arr, last arr
\n\n\n
Finding elements
\n
\n
closest <section/>
\n
nearest enclosing section
\n
previous <section/> from #sec-2
\n
last section that comes before section 2 (?? me)
\n
next <input, button, a/> from document.activeElement within #dialog with wrapping
\n
element to focus when pressing Tab in a modal dialog
\n
\n\n\n
Other top-level features
\n
\n\n
\n
Feature
\n
Description
\n
\n\n\n
\n
behavior
\n
Define cross-cutting behaviors that are applied to many HTML elements
\n
\n
\n
def
\n
Defines a function
\n
\n
\n
eventsource
\n
Subscribe to Server Sent Events (SSE)
\n
\n
\n
js
\n
Embed JavaScript code at the top level
\n
\n
\n
set
\n
Defines a new element-scoped variable
\n
\n
\n
init
\n
Initialization logic to be run when the code is first loaded
\n
\n
\n
on
\n
Creates an event listener \ton click log “clicked!”
\n
\n
\n
socket
\n
Create a Web Socket
\n
\n
\n
worker
\n
Create a Web Worker for asynchrnous work
\n
\n\n
\n\n\n
Command index
\n
\n
\n
add .class to elt\n
add @attribute=value to elt\n
add { font-size: ${elt}px; } to elt\n
add classes/attributes/inline styles to elt (?? me)\n
\n
\n
append value to target\n
append to strings/arrays/elements, sets it = target (?? it)\n
\n
\n
async command | async do command… end\n
run commands in a non-blocking manner\n
\n
\n
call expr | get expr\n
sets it = expr\n
\n
\n
continue\n
skips to next iteration in a loop\n
\n
\n
decrement lvalue by amount\n
sets lvalue = lvalue - amount (?? 1)\n
\n
\n
fetch /url with option: value, …\n
fetch `/url/${id}/` with option: value, …\n
makes an HTTP request, see Fetch API docs for options\n
\n
\n
go to url /url in new window\n
go to url `/url/${id}/`\n
navigate to a URL in the browser\n
\n
\n
go to top of elt -- top/middle/bottom \n
go to top left of elt -- left/center/right\n
go to left of elt smoothly -- /instantly\n
scroll an element into view\n
\n
\n
halt the event’s default\n
prevent default behavior\n
\n
\n
halt default\n
same as above, and exits listener\n
\n
\n
halt the event’s bubbling\n
stop event bubbling\n
\n
\n
halt bubbling\n
same as above, and exits listener\n
\n
\n
halt the event\n
stop both default and bubbling\n
\n
\n
halt\n
all of the above\n
\n
\n
hide elt with strategy\n
see `show`\n
\n
\n
if cond then … else … end\n
if statement\n
\n
\n
increment\n
see decrement\n
\n
\n
js(var) … end\n
embed JavaScript\n
\n
\n
log value with func\n
logs the value to the console using func (?? console.log)\n
\n
\n
make a <tag#id.class /> called name\n
creates an element with the given tag, id and classes, sets name (?? it) = the created element\n
\n
\n
make a Class from args called name\n
calls the Class constructor with the args, sets name (?? it) = the created object\n
\n
\n
put rvalue into lvalue\n
see set\n
\n
\n
put content into elt -- into/before/after/at start of/at end of\n
insert content into various parts of the elt\n
\n
\n
remove .class from elt\n
see add\n
\n
\n
remove @attribute from elt\n
see add\n
\n
\n
remove elt\n
removes elt (?? me) from the document\n
\n
\n
repeat for name in iterable index i … end\n
for name in iterable index i … end\n
loop over an iterable, the loop variable is name (?? it)\n
\n
\n
repeat until event e from elt index i … end\n
Repeat every tick until event e is received from elt (?? me)\n
\n
\n
repeat while cond | repeat until cond … end\n
repeat n times index i … end\n
repeat forever … end\n
--\n
\n
\n
return value | exit\n
return, see also halt\n
\n
\n
send evt(args…) to elt\n
trigger evt(args…) on elt\n
dispatch a DOM event on elt (?? me)\n
\n
\n
set lvalue to rvalue\n
--\n
\n
\n
settle\n
waits for any animations/transitions to end\n
\n
\n
show elt with strategy when cond -- strategy: display:_/visibility/opacity/…\n
show elt (?? me) using the strategy (?? display:block) if cond (?? true) is true, else hide it\n
\n
\n
take .class from eltA for eltB\n
remove class from eltA (?? .class) and add it to eltB (?? me)\n
\n
\n
tell elt … end\n
set you = elt, default to you over me\n
\n
\n
throw exception\n
throws an exception\n
\n
\n
toggle .class on eltA for t s \n
toggle [@attr=value] until evt from eltB\n
toggle between .class1 and .class2 on eltA\n
toggle classes and attributes on eltA (?? me)\n
\n
\n
transition the elt's prop to value … over t s\n
Animate style properties\n
\n
\n
wait t s -- or ms\n
Waits for the given duration\n
\n
\n
wait for event or event2 or t s\n
waits for one of the events to occur, sets it=the event\n
\n
\n\n
\n\n \n\n \n \n\n\n","content_text":"\n\n\n\n## Event listeners\n\n| | Syntax | Meaning |\n|------|----------------------|--------------------------------------------------------------|\n| | **`on`** | add event listener |\n| | `every` | do not queue events |\n| | **`mousemove`** | event name |\n| | `(clientX, clientY)` | expose the event’s properties |\n| | `[clientX > 100]` | filter events |\n| | `3` | only respond to 3rd click |\n| _or_ | `3 to 10` | respond to 3rd, 4th … 10th click |\n| _or_ | `3 and on` | respond to all clicks except 1st and 2nd |\n| | `from #my-form` | element to attach listeners to, (?? me) |\n| | `debounced at 200ms` | trailing debounce (200ms delay, resets on every event) |\n| _or_ | `throttled at 200ms` | every 200ms at most regardless of the number of events |\n| | `or keyup ...` | specify many events, each with its own from/debounce/… |\n| | | if events arrive while the listener is already running… |\n| | `queue all` | add them to a FIFO queue |\n| _or_ | `queue none` | discard them |\n| _or_ | `queue first` | enqueue the first one, discard the rest |\n| _or_ | `queue last` | enqueue the last one, discard the rest (this is the default) |\n\n\n\n\n\n## Property access\n\n - `user.data.name`\n - `user’s data’s name`\n - `name of data of user` \n - `data.name of user`\n - `user’s data.name`\n\n\n\n\n## CSS literals\n\n`#my-form`\n: Get element by id\n\n`#{getID()}`\n: Dynamic ID\n\n`.active`\n: Get elements by class\n\n`.{getClass()}`\n: Dynamic class\n\n``\n: Query selector all\n\n``\n: Dynamic selector\n\n\n\n\n## Sigils\n\n`foo`\n: local variable by default\n\n`:foo`\n: element scoped variable, persisted. can be declared with top-level set. behaviors are isolated from one another\n\n`$foo`\n: global variable\n\n`@foo`\n: HTML attribute\n\n\n\n\n## Array operations\n\n`first in arr` ≡ `first from arr`\n≡ `first of arr` ≡ `first arr`\n\nalso `random arr`, `last arr`\n\n\n\n\n## Finding elements\n\n`closest <section/>`\n: nearest enclosing section\n\n`previous <section/> from #sec-2`\n: last section that comes before section 2 (?? me)\n\n`next <input, button, a/> from document.activeElement within #dialog with wrapping`\n: element to focus when pressing Tab in a modal dialog\n\n\n\n\n\n## Other top-level features\n\n| Feature | Description |\n|---------------|---------------------------------------------------------------------------|\n| `behavior` | \tDefine cross-cutting behaviors that are applied to many HTML elements |\n| `def` | \tDefines a function \t |\n| `eventsource` | \tSubscribe to Server Sent Events (SSE) \t |\n| `js` | \tEmbed JavaScript code at the top level \t |\n| `set` | \tDefines a new element-scoped variable \t |\n| `init` | \tInitialization logic to be run when the code is first loaded \t |\n| `on` | \tCreates an event listener \ton click log \"clicked!\" |\n| `socket` | \tCreate a Web Socket \t |\n| `worker` | \tCreate a Web Worker for asynchrnous work |\n\n\n\n\n## Command index\n\n
\n\n
\n
add .class to elt\n
add @attribute=value to elt\n
add { font-size: ${elt}px; } to elt\n
add classes/attributes/inline styles to elt (?? me)\n
\n\n
\n
append value to target\n
append to strings/arrays/elements, sets it = target (?? it)\n
\n\n
\n
async command | async do command… end\n
run commands in a non-blocking manner\n
\n\n
\n
call expr | get expr\n
sets it = expr\n
\n\n
\n
continue\n
skips to next iteration in a loop\n
\n\n
\n
decrement lvalue by amount\n
sets lvalue = lvalue - amount (?? 1)\n
\n\n
\n
fetch /url with option: value, …\n
fetch `/url/${id}/` with option: value, …\n
makes an HTTP request, see Fetch API docs for options\n
\n\n
\n
go to url /url in new window\n
go to url `/url/${id}/`\n
navigate to a URL in the browser\n
\n\n
\n
go to top of elt -- top/middle/bottom \n
go to top left of elt -- left/center/right\n
go to left of elt smoothly -- /instantly\n
scroll an element into view\n
\n\n
\n
halt the event’s default\n
prevent default behavior\n
\n\n
\n
halt default\n
same as above, and exits listener\n
\n\n
\n
halt the event’s bubbling\n
stop event bubbling\n
\n\n
\n
halt bubbling\n
same as above, and exits listener\n
\n\n
\n
halt the event\n
stop both default and bubbling\n
\n\n
\n
halt\n
all of the above\n
\n\n
\n
hide elt with strategy\n
see `show`\n
\n\n
\n
if cond then … else … end\n
if statement\n
\n\n
\n
increment\n
see decrement\n
\n\n
\n
js(var) … end\n
embed JavaScript\n
\n\n
\n
log value with func\n
logs the value to the console using func (?? console.log)\n
\n\n
\n
make a <tag#id.class /> called name\n
creates an element with the given tag, id and classes, sets name (?? it) = the created element\n
\n\n
\n
make a Class from args called name\n
calls the Class constructor with the args, sets name (?? it) = the created object\n
\n\n
\n
put rvalue into lvalue\n
see set\n
\n\n
\n
put content into elt -- into/before/after/at start of/at end of\n
insert content into various parts of the elt\n
\n\n
\n
remove .class from elt\n
see add\n
\n\n
\n
remove @attribute from elt\n
see add\n
\n\n
\n
remove elt\n
removes elt (?? me) from the document\n
\n\n
\n
repeat for name in iterable index i … end\n
for name in iterable index i … end\n
loop over an iterable, the loop variable is name (?? it)\n
\n\n
\n
repeat until event e from elt index i … end\n
Repeat every tick until event e is received from elt (?? me)\n
\n\n
\n
repeat while cond | repeat until cond … end\n
repeat n times index i … end\n
repeat forever … end\n
--\n
\n\n
\n
return value | exit\n
return, see also halt\n
\n\n
\n
send evt(args…) to elt\n
trigger evt(args…) on elt\n
dispatch a DOM event on elt (?? me)\n
\n\n
\n
set lvalue to rvalue\n
--\n
\n\n
\n
settle\n
waits for any animations/transitions to end\n
\n\n
\n
show elt with strategy when cond -- strategy: display:_/visibility/opacity/…\n
show elt (?? me) using the strategy (?? display:block) if cond (?? true) is true, else hide it\n
\n\n
\n
take .class from eltA for eltB\n
remove class from eltA (?? .class) and add it to eltB (?? me)\n
\n\n
\n
tell elt … end\n
set you = elt, default to you over me\n
\n\n
\n
throw exception\n
throws an exception\n
\n\n
\n
toggle .class on eltA for t s \n
toggle [@attr=value] until evt from eltB\n
toggle between .class1 and .class2 on eltA\n
toggle classes and attributes on eltA (?? me)\n
\n\n
\n
transition the elt's prop to value … over t s\n
Animate style properties\n
\n\n
\n
wait t s -- or ms\n
Waits for the given duration\n
\n\n
\n
wait for event or event2 or t s\n
waits for one of the events to occur, sets it=the event\n
in .tmTheme files the scope key defines how a element is highlighted:\n\n <dict>\n <key>name</key>\n <string>HTML: Attribute Values</string>\n <k...
\n \n \n
\n
Thanks to Phrogz
\n
\n
comment
\n
\n
for comments.
\n
\n
line
\n
\n
line comments, we specialize further so that the type of comment start character(s) can be extracted from the scope.
\n
\n
double-slash
\n
// comment
\n
double-dash
\n
-- comment
\n
number-sign
\n
# comment
\n
percentage
\n
% comment
\n
character
\n
other types of line comments.
\n
\n
\n
block
\n
\n
multi-line comments like /* … */ and <!-- … -->.
\n
\n
documentation
\n
embedded documentation.
\n
\n
\n
\n
\n
constant
\n
\n
various forms of constants.
\n
\n
numeric
\n
\n
those which represent numbers, e.g. 42, 1.3f, 0x4AB1U.
\n
\n
character
\n
\n
those which represent characters, e.g. <, \\e, \\031.
\n
\n
escape
\n
escape sequences like \\e would be constant.character.escape.
\n
\n
\n
language
\n
\n
constants (generally) provided by the language which are “special” like true, false, nil, YES, NO, etc.
\n
\n
other
\n
\n
other constants, e.g. colors in CSS.
\n
\n
\n
\n
entity
\n
\n
an entity refers to a larger part of the document, for example a chapter, class, function, or tag. We do not scope the entire entity as entity.* (we use meta.* for that). But we do use entity.* for the “placeholders” in the larger entity, e.g. if the entity is a chapter, we would use entity.name.section for the chapter title.
\n
\n
name
\n
\n
we are naming the larger entity.
\n
\n
function
\n
the name of a function.
\n
type
\n
the name of a type declaration or class.
\n
tag
\n
a tag name.
\n
section
\n
the name is the name of a section/heading.
\n
\n
\n
other
\n
\n
other entities.
\n
\n
inherited-class
\n
the superclass/baseclass name.
\n
attribute-name
\n
the name of an attribute (mainly in tags).
\n
\n
\n
\n
\n
invalid
\n
\n
stuff which is “invalid”.
\n
\n
illegal
\n
illegal, e.g. an ampersand or lower-than character in HTML (which is not part of an entity/tag).
\n
deprecated
\n
for deprecated stuff e.g. using an API function which is deprecated or using styling with strict HTML.
\n
\n
\n
keyword
\n
\n
keywords (when these do not fall into the other groups).
\n
\n
control
\n
mainly related to flow control like continue, while, return, etc.
\n
operator
\n
operators can either be textual (e.g. or) or be characters.
\n
other
\n
other keywords.
\n
\n
\n
markup
\n
\n
this is for markup languages and generally applies to larger subsets of the text.
\n
\n
underline
\n
\n
underlined text.
\n
\n
link
\n
this is for links, as a convenience this is derived from markup.underline so that if there is no theme rule which specifically targets markup.underline.link then it will inherit the underline style.
\n
\n
\n
bold
\n
\n
bold text (text which is strong and similar should preferably be derived from this name).
\n
\n
heading
\n
\n
a section header. Optionally provide the heading level as the next element, for example markup.heading.2.html for <h2>…</h2> in HTML.
\n
\n
italic
\n
\n
italic text (text which is emphasized and similar should preferably be derived from this name).
\n
\n
list
\n
\n
list items.
\n
\n
numbered
\n
numbered list items.
\n
unnumbered
\n
unnumbered list items.
\n
\n
\n
quote
\n
\n
quoted (sometimes block quoted) text.
\n
\n
raw
\n
\n
text which is verbatim, e.g. code listings. Normally spell checking is disabled for markup.raw.
\n
\n
other
\n
\n
other markup constructs.
\n
\n
\n
\n
meta
\n
\n
the meta scope is generally used to markup larger parts of the document. For example the entire line which declares a function would be meta.function and the subsets would be storage.type, entity.name.function, variable.parameter etc. and only the latter would be styled. Sometimes the meta part of the scope will be used only to limit the more general element that is styled, most of the time meta scopes are however used in scope selectors for activation of bundle items. For example in Objective-C there is a meta scope for the interface declaration of a class and the implementation, allowing the same tab-triggers to expand differently, depending on context.
\n
\n
storage
\n
\n
things relating to “storage”.
\n
\n
type
\n
the type of something, class, function, int, var, etc.
\n
modifier
\n
a storage modifier like static, final, abstract, etc.
\n
\n
\n
string
\n
\n
strings.
\n
\n
quoted
\n
\n
quoted strings.
\n
\n
single
\n
single quoted strings: ‘foo’.
\n
double
\n
double quoted strings: “foo”.
\n
triple
\n
triple quoted strings: “”“Python”“”.
\n
other
\n
other types of quoting: $‘shell’, %s{…}.
\n
\n
\n
unquoted
\n
\n
for things like here-docs and here-strings.
\n
\n
interpolated
\n
\n
strings which are “evaluated”: date, $(pwd).
\n
\n
regexp
\n
\n
regular expressions: /(\\w+)/.
\n
\n
other
\n
\n
other types of strings (should rarely be used).
\n
\n
\n
\n
support
\n
\n
things provided by a framework or library should be below support.
\n
\n
function
\n
functions provided by the framework/library. For example NSLog in Objective-C is support.function.
\n
class
\n
when the framework/library provides classes.
\n
type
\n
types provided by the framework/library, this is probably only used for languages derived from C, which has typedef (and struct). Most other languages would introduce new types as classes.
\n
constant
\n
constants (magic values) provided by the framework/library.
\n
variable
\n
variables provided by the framework/library. For example NSApp in AppKit.
\n
other
\n
the above should be exhaustive, but for everything else use support.other.
\n
\n
\n
variable
\n
\n
variables. Not all languages allow easy identification (and thus markup) of these.
\n
\n
parameter
\n
when the variable is declared as the parameter.
\n
language
\n
reserved language variables like this, super, self, etc.
\n
other
\n
other variables, like $some_variables.
\n
\n
\n
\n
\n\n \n\n \n \n\n\n","content_text":"Thanks to Phrogz\n\n`comment`\n: for comments.\n\n `line`\n : line comments, we specialize further so that the type of comment start character(s) can be extracted from the scope.\n\n `double-slash`\n : `//` comment\n\n `double-dash`\n : `--` comment\n\n `number-sign`\n : `#` comment\n\n `percentage`\n : `%` comment\n\n `character`\n : other types of line comments.\n\n `block`\n : multi-line comments like `/* … */` and ``.\n\n `documentation`\n : embedded documentation.\n\n`constant`\n: various forms of constants.\n\n `numeric`\n : those which represent numbers, e.g. `42`, `1.3f`, `0x4AB1U`.\n\n `character`\n : those which represent characters, e.g. `<`, `\\e`, `\\031`.\n\n `escape`\n : escape sequences like `\\e` would be constant.character.escape.\n\n `language`\n : constants (generally) provided by the language which are “special” like `true`, `false`, `nil`, `YES`, `NO`, etc.\n\n `other`\n : other constants, e.g. colors in CSS.\n\n`entity`\n: an entity refers to a larger part of the document, for example a chapter, class, function, or tag. We do not scope the entire entity as `entity.*` (we use `meta.*` for that). But we do use `entity.*` for the “placeholders” in the larger entity, e.g. if the entity is a chapter, we would use `entity.name.section` for the chapter title.\n\n `name`\n : we are naming the larger entity.\n\n `function`\n : the name of a function.\n\n `type`\n : the name of a type declaration or class.\n\n `tag`\n : a tag name.\n\n `section`\n : the name is the name of a section/heading.\n\n `other`\n : other entities.\n\n `inherited-class`\n : the superclass/baseclass name.\n\n `attribute-name`\n : the name of an attribute (mainly in tags).\n\n`invalid`\n: stuff which is “invalid”.\n\n `illegal`\n : illegal, e.g. an ampersand or lower-than character in HTML (which is not part of an entity/tag).\n\n `deprecated`\n : for deprecated stuff e.g. using an API function which is deprecated or using styling with strict HTML.\n\n`keyword`\n: keywords (when these do not fall into the other groups).\n\n `control`\n : mainly related to flow control like continue, while, return, etc.\n\n `operator`\n : operators can either be textual (e.g. or) or be characters.\n\n `other`\n : other keywords.\n\n`markup`\n: this is for markup languages and generally applies to larger subsets of the text.\n\n `underline`\n : underlined text.\n\n `link`\n : this is for links, as a convenience this is derived from markup.underline so that if there is no theme rule which specifically targets markup.underline.link then it will inherit the underline style.\n\n `bold`\n : bold text (text which is strong and similar should preferably be derived from this name).\n\n `heading`\n : a section header. Optionally provide the heading level as the next element, for example markup.heading.2.html for `
…
` in HTML.\n\n `italic`\n : italic text (text which is emphasized and similar should preferably be derived from this name).\n\n `list`\n : list items.\n\n `numbered`\n : numbered list items.\n\n `unnumbered`\n : unnumbered list items.\n\n `quote`\n : quoted (sometimes block quoted) text.\n\n `raw`\n : text which is verbatim, e.g. code listings. Normally spell checking is disabled for markup.raw.\n\n `other`\n : other markup constructs.\n\n`meta`\n: the meta scope is generally used to markup larger parts of the document. For example the entire line which declares a function would be meta.function and the subsets would be storage.type, entity.name.function, variable.parameter etc. and only the latter would be styled. Sometimes the meta part of the scope will be used only to limit the more general element that is styled, most of the time meta scopes are however used in scope selectors for activation of bundle items. For example in Objective-C there is a meta scope for the interface declaration of a class and the implementation, allowing the same tab-triggers to expand differently, depending on context.\n\n`storage`\n: things relating to “storage”.\n\n `type`\n : the type of something, class, function, int, var, etc.\n\n `modifier`\n : a storage modifier like static, final, abstract, etc.\n\n`string`\n: strings.\n\n `quoted`\n : quoted strings.\n\n `single`\n : single quoted strings: 'foo'.\n\n `double`\n : double quoted strings: \"foo\".\n\n `triple`\n : triple quoted strings: \"\"\"Python\"\"\".\n\n `other`\n : other types of quoting: $'shell', %s{...}.\n\n `unquoted`\n : for things like here-docs and here-strings.\n\n `interpolated`\n : strings which are “evaluated”: date, $(pwd).\n\n `regexp`\n : regular expressions: /(\\w+)/.\n\n `other`\n : other types of strings (should rarely be used).\n\n`support`\n: things provided by a framework or library should be below support.\n\n `function`\n : functions provided by the framework/library. For example NSLog in Objective-C is support.function.\n\n `class`\n : when the framework/library provides classes.\n\n `type`\n : types provided by the framework/library, this is probably only used for languages derived from C, which has typedef (and struct). Most other languages would introduce new types as classes.\n\n `constant`\n : constants (magic values) provided by the framework/library.\n\n `variable`\n : variables provided by the framework/library. For example NSApp in AppKit.\n\n `other`\n : the above should be exhaustive, but for everything else use support.other.\n\n`variable`\n: variables. Not all languages allow easy identification (and thus markup) of these.\n\n `parameter`\n : when the variable is declared as the parameter.\n\n `language`\n : reserved language variables like this, super, self, etc.\n\n `other`\n : other variables, like $some_variables.\n","url":"https://denizaksimsek.com/undefined","summary":"Naming conventions for scopes in TextMate grammars and themes, which are also used in Sublime Text and VSCode.","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/cloudflare-internal-error/","title":"Cloudflare Pages: Failed: an internal error occurred","content_html":"\n\n\n\n\n\nCloudflare Pages: Failed: an internal error occurred\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nCloudflare Pages: Failed: an internal error occurred\n\n\n\n \n \n \n
Cloudflare Pages: Failed: an internal error occurred
\n \n\n \n \n \n\n \n
\n
I deploy my website on Cloudflare Pages (at time of writing). My builds were\nfailing with the error message:
\n
17:24:49.795\tDeploying your site to Cloudflare's global network...\n17:24:50.632\tFailed: an internal error occurred\n
\n
No other information.
\n
Googling yields that many things can cause this issue. \nIn my case, it was a directory called _redirects/ in the output folder.
\n
Cloudflare expects _redirects to be a file to read redirect information from.\n(Indeed, that’s what I was using it for — it was output to a directory by\naccident).
\n
\n\n \n\n \n \n\n\n","content_text":"I deploy my website on Cloudflare Pages (at time of writing). My builds were \nfailing with the error message:\n\n ~~~\n 17:24:49.795\tDeploying your site to Cloudflare's global network...\n 17:24:50.632\tFailed: an internal error occurred\n ~~~\n\nNo other information.\n\nGoogling yields that many things can cause this issue. \nIn my case, it was a **directory called `_redirects/` in the output folder**.\n\nCloudflare expects `_redirects` to be a file to read redirect information from.\n(Indeed, that's what I was using it for --- it was output to a directory by \naccident).\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/intentionally-unscalable/","title":"Intentionally Unscalable","content_html":"\n\n\n\n\n\nIntentionally Unscalable\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nIntentionally Unscalable\n\n\n\n \n \n \n
_hyperscript is intentionally unscalable. We make decisions that would be\nobviously inadvisable to anyone looking to make scalable software, and dismiss\nfeatures like reactivity that seem to have proven themselves in this regard. To\nunderstand why, I examine and critique the concept of “scalable”.
\n
Scalability refers to the ability of a system to handle more work given more\nresources. This definition matches both formal definitions and common use in\napplication development circles. Given this definition, we can see that:
\n
\n
\n
Scalability is unidirectional — it only refers to scaling up, never\nscaling down. In fact, I never hear “scaling down” discussed at all.\nDeclaring it out-of-scope to ascribe this to a wider culture of growth, I’ll\njust speculate that perhaps scaling down is assumed to be trivial, or not\nnecessary as a system that handles a large amount of work can necessarily\nhandle a small amount, adequately, without modification.
\n
\n
\n
When people talk about the scalability of a tool, they are usually employing\nmetonymy.\nmetonymy: I was excited when looking up this word on\nTureng, but “metonymy” doesn’t really have the barebones simplicity of\nthe Turkish “ad aktarması” or the weight of the Arabic loan “mecaz-ı\nmürsel”.\nThey are discussing the impact of the tool on other systems’\nscalability (will _hyperscript hinder us as we get more users/our app gets\nmore complex?) and not the scalability of the tool itself (can we get\nhyperscript to run N lines of code in T time with better hardware?)
\n
\n
\n
System, work, resources — a software development team consists of multiple\nsystems using multiple kinds of resources to do multiple kinds of work.\nWhich system is being discussed is usually clear through context, but we\nshould be aware when “scalable” is used without such context.
\n
\n
The two main systems in a software organization
\n\n
\n
System
\n
More Work
\n
Resources
\n
\n\n\n
\n
Software
\n
Serve more users.
\n
Computers.
\n
\n
\n
Team
\n
Add complexity to the software and maintain it.
\n
Time, money.
\n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
Why is scalability desired?
\n\n
\n
“As our app gets more complex, X will prevent us from growing and\nmaintaining it”.
\n
There is an assumption that your app will get more complex and partly that\ncomplexity is an environmental factor, as opposed to a consequence of the\nteam’s choices. Growing a codebase is adding complexity. Lamenting not being\nable to do that seems odd given the amount of lip service we pay to the\nglory of removing complexity.
\n
\n
\n
“As we get more users, the app we built with X will need rewriting”.
\n
There is an assumption that we will get more users. If this is true, and\nthe organization containing the team has an actual monetization\nstrategy, then it follows that we will also get more money.\nmonetization: The way that the “we’ll need rewriting”\nargument assumes growth, but rejects relying on it reminds me of paying\npeople in shares. If you can’t trust it enough to just pay me the money\nyou’ll definitely make back, why should I?\nIf we need to build an app that serves N users eventually, does it not make\nsense to do so when you have F(N-ε) dollars?\nepsilon: I originally said this much more pithily: “if you\nare certain you’ll grow to 1 billion users, and you need an app that can\nhandle that, why build it now on a startup budget when you’re going to have\nthe budget of a 1B-user app soon”\nMy more business-savvy friend Ben Pate informs me that “many\nmillion-user budgets have been wasted doing that [building a million-user\nsystem before you have any users at all]”, and that “You won’t get a billion\nusers until you first earn a thousand”.
\n
I don’t know shit about running a company, but I reject designing our tools\nfor startups that eat some VC money, don’t generate profit or any benefit\nfor humanity, and get sold for the advertising value of their data.
\n
And what’s so bad about rewriting anyway? I thought programmers liked\nwriting code.\nliked writing code: I’m aware that some people do\nprogramming purely as a job. I sometimes envy the indifference I imagine\nthey have towards our petty squabbles.\nWe again pay lip service to how code is the easy part, and\nhow legacy code sucks… Erlang has the famous “let it crash”, anticipating\nissues and focusing on recovering from failure instead of preventing it. We\ncan apply a similar concept: “write to rewrite”.
\n
\n\n
Write to rewrite
\n
Expect that you might need to rewrite your code, and be considerate of your\nfuture self who is doing that. _hyperscript helps you do this in two ways:
\n
\n
\n
Readability over writability. The fact that _hyperscript code examples\nlook like plain English is just as much an achievement of the author as it\nis _hyperscript’s. We do not do anything smart like Natural Language\nProcessing; _hyperscript uses common and normal parsing techniques. C++,\nPerl, perhaps even Ruby have more complex grammars than _hyperscript. We\ngive you tools like the prop of object and object's prop syntax. and the\nit variable that might seem magical but is actually little more than the\naccumulator register in an 8-bit processor. It is up to you the programmer\nto use these tools to create readable code. The burden you take upon your\nshoulders can include (but will not be limited to):
\n
\n
Choosing between rates of the result's data, its data.rates, or\nresult.data.rates.
\n
Breaking up long expressions into statements. Besides readability and\nEnglish-like flow, this is also good for stepping through with a\ndebugger (yet another tool for a rewriter to understand the code).
\n
Reordering statements to make efficient use of it. If we do this\nconsistently, code that doesn’t do this will stick out as\norder-dependent and vulnerable to race conditions.
\n
\n
\n
\n
Locality of behavior. Ever looked through a GitHub repo, not been able\nto find the code you were looking for, eventually clone the repo locally and\nstart “Jump to Definition”-ing and “Peek References”-ing your way towards\nyour target, only to find out it’s a wrapper for yet another function? If it\nis a Java project, I usually give up before reaching any source code files\nat all. Htmx “Carson” Org has written about Locality of Behavior\npreviously, so I’ll direct you there.
\n
\n
\n
Conclusion
\n
I recall what I now know to be an urban legend about the great architect Mimar\nSinan. Supposedly, when the keystones of some arches in a mosque he built were\nyielding to old age, an engineer working on the restorations found a note in a\nbottle signed by Koca Mimar Sinan Ağa himself. It was a step-by-step guide on\nhow to replace the keystone without disruption to the rest of the structure,\ncomplete with drawings.
\n
Putting aside the implication that our modern architects don’t know how stone\narches are built, and that Great Sinan Agha The Architect expected such\narchitects to restore his works, this fictional Mimar Sinan clearly doesn’t know\nanything about scalability. If he did, he would predict when the Sultan would\ndie and make the mosque last exactly that long.
\n
\n
When asked what their language is good for, many designers would say\n“everything” which really means “nothing”.
Nystrom said this in the context of choosing a niche for your language, but I\nbelieve it applies just as well to choosing a scale.
\n
\n\n \n\n \n \n\n\n","content_text":"\\_hyperscript is intentionally unscalable. We make decisions that would be\nobviously inadvisable to anyone looking to make scalable software, and dismiss\nfeatures like reactivity that seem to have proven themselves in this regard. To\nunderstand why, I examine and critique the concept of \"scalable\".\n\n**Scalability refers to the ability of a system to handle more work given more\nresources.** This definition matches both formal definitions and common use in\napplication development circles. Given this definition, we can see that:\n\n* Scalability is unidirectional --- it only refers to scaling up, never\n\tscaling down. In fact, I never hear \"scaling down\" discussed at all.\n\tDeclaring it out-of-scope to ascribe this to a wider culture of growth, I'll\n\tjust speculate that perhaps scaling down is assumed to be trivial, or not\n\tnecessary as a system that handles a large amount of work can necessarily\n\thandle a small amount, adequately, without modification.\n* When people talk about the scalability of a tool, they are usually employing\n\tmetonymy. \n\t:sidenote[metonymy: I was excited when looking up this word on \n\t[Tureng][], but \"metonymy\" doesn't really have the barebones simplicity of \n\tthe Turkish \"ad aktarması\" or the weight of the Arabic loan \"mecaz-ı \n\tmürsel\".]\n\tThey are discussing the impact of the tool on other systems'\n\tscalability (will _hyperscript hinder us as we get more users/our app gets\n\tmore complex?) and not the scalability of the tool itself (can we get\n\thyperscript to run N lines of code in T time with better hardware?)\n* System, work, resources --- a software development team consists of multiple\n\tsystems using multiple kinds of resources to do multiple kinds of work.\n\tWhich system is being discussed is usually clear through context, but we\n\tshould be aware when \"scalable\" is used without such context.\n\n\t| System | More Work | Resources |\n\t|----------|-------------------------------------------------|-----------------|\n\t| Software | Serve more users. | Computers. |\n\t| Team | Add complexity to the software and maintain it. | Time, money. |\n\t{.responsive-table}\n\t\n\t: The two main systems in a software organization\n\n\n## Why is scalability desired?\n\n1. \"As our app gets more complex, X will prevent us from growing and\n\tmaintaining it\".\n\n There is an assumption that your app _will_ get more complex and partly that\n complexity is an environmental factor, as opposed to a consequence of the\n team's choices. Growing a codebase is adding complexity. Lamenting not being\n able to do that seems odd given the amount of lip service we pay to the\n glory of removing complexity.\n\n2.\t\"As we get more users, the app we built with X will need rewriting\".\n\n\tThere is an assumption that we _will_ get more users. If this is true, and\n\tthe organization containing the team has an actual monetization\n\tstrategy, then it follows that we will also get more money.\n\t:sidenote[**monetization:** The way that the \"we'll need rewriting\" \n\targument assumes growth, but rejects relying on it reminds me of paying \n\tpeople in shares. If you can't trust it enough to just pay me the money \n\tyou'll definitely make back, why should I?]\n\tIf we need to build an app that serves N users eventually, does it not make \n\tsense to do so when you have F(N-ε) dollars?\n\t:sidenote[**epsilon:** I originally said this much more pithily: \"if you\n\tare certain you'll grow to 1 billion users, and you need an app that can \n\thandle that, why build it now on a startup budget when you're going to have\n\tthe budget of a 1B-user app soon\"]\n\tMy more business-savvy friend [Ben Pate][] informs me that \"many \n\tmillion-user budgets have been wasted doing that [building a million-user \n\tsystem before you have any users at all]\", and that \"You won’t get a billion\n\tusers until you first earn a thousand\".\n\n\tI don't know shit about running a company, but I reject designing our tools\n\tfor startups that eat some VC money, don't generate profit _or_ any benefit\n\tfor humanity, and get sold for the advertising value of their data.\n\n\tAnd what's so bad about rewriting anyway? I thought programmers liked\n\twriting code.\n\t:sidenote[**liked writing code:** I'm aware that some people do \n\tprogramming purely as a job. I sometimes envy the indifference I imagine \n\tthey have towards our petty squabbles.]\n\tWe again pay lip service to how code is the easy part, and\n\thow legacy code sucks... Erlang has the famous \"let it crash\", anticipating\n\tissues and focusing on recovering from failure instead of preventing it. We\n\tcan apply a similar concept: **\"write to rewrite\"**.\n\n\n## Write to rewrite\n\nExpect that you might need to rewrite your code, and be considerate of your\nfuture self who is doing that. _hyperscript helps you do this in two ways:\n\n-\t**Readability over writability.** The fact that _hyperscript code examples\n\tlook like plain English is just as much an achievement of the author as it\n\tis _hyperscript's. We do not do anything smart like Natural Language\n\tProcessing; _hyperscript uses common and normal parsing techniques. C++,\n\tPerl, perhaps even Ruby have more complex grammars than _hyperscript. We\n\tgive you tools like the `prop of object` and `object's prop` syntax. and the\n\t`it` variable that might seem magical but is actually little more than the\n\taccumulator register in an 8-bit processor. It is up to you the programmer\n\tto use these tools to create readable code. The burden you take upon your\n\tshoulders can include (but will not be limited to):\n - Choosing between `rates of the result's data`, `its data.rates`, or\n \t`result.data.rates`.\n -\tBreaking up long expressions into statements. Besides readability and\n \tEnglish-like flow, this is also good for stepping through with a\n \tdebugger (yet another tool for a rewriter to understand the code).\n -\tReordering statements to make efficient use of `it`. If we do this\n \tconsistently, code that doesn't do this will stick out as\n \torder-dependent and vulnerable to race conditions.\n\n-\t**Locality of behavior.** Ever looked through a GitHub repo, not been able\n\tto find the code you were looking for, eventually clone the repo locally and\n\tstart \"Jump to Definition\"-ing and \"Peek References\"-ing your way towards\n\tyour target, only to find out it's a wrapper for yet another function? If it\n\tis a Java project, I usually give up before reaching any source code files\n\tat all. Htmx \"Carson\" Org has written about [Locality of Behavior][]\n\tpreviously, so I'll direct you there.\n\n\n## Conclusion\n\nI recall what I now know to be an urban legend about the great architect Mimar\nSinan. Supposedly, when the keystones of some arches in a mosque he built were\nyielding to old age, an engineer working on the restorations found a note in a\nbottle signed by Koca Mimar Sinan Ağa himself. It was a step-by-step guide on\nhow to replace the keystone without disruption to the rest of the structure,\ncomplete with drawings.\n\nPutting aside the implication that our modern architects don't know how stone\narches are built, and that Great Sinan Agha The Architect expected such\narchitects to restore his works, this fictional Mimar Sinan clearly doesn't know\nanything about scalability. If he did, he would predict when the Sultan would\ndie and make the mosque last exactly that long.\n\n> When asked what their language is good for, many designers would say\n> “everything” which really means “nothing”.\n>\n> -- Robert Nystrom, [What I Learned at the Emerging Languages Camp](http://journal.stuffwithstuff.com/2010/07/23/what-i-learned-at-the-emerging-languages-camp/)\n\nNystrom said this in the context of choosing a niche for your language, but I\nbelieve it applies just as well to choosing a scale.\n\n[Ben Pate]: https://twitter.com/benpate5280\n\n[Locality of Behavior]: https://htmx.org/essays/locality-of-behaviour\n\n[Tureng]: https://tureng.com\n\n\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2022/nanpa-pi-ken-ala-kipisi/","title":"nanpa pi ken ala kipisi pi mute ale li lon","content_html":"\n\n\n\n\n\nnanpa pi ken ala kipisi pi mute ale li lon\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nnanpa pi ken ala kipisi pi mute ale li lon\n\n\n\n \n \n \n
nanpa pi ken ala kipisi pi mute ale li lon
\n \n\n \n \n
ni li tan mi ala. mi sona ala e ni: jan seme li pali e ni.
\n \n\n \n
\n
tawa kama lon e ni, o sitelen insa e ijo jasima: nanpa pi ken ala kipisi mute pini li lon. o nimi e kulupu pi nanpa ni kepeken sitelen P.
\n
ni la o mute e nanpa ale pi kulupu P, o namako e wan. (ni li ken tan ni: kulupu Pli suli pini). o nimi e nanpa sin ni kepeken sitelen N.
\n
nanpa Nla ken tu li lon: ona li nanpa pi ken ala kipisi, anu ona li ijo tan mute pi nanpa ante pi ken ala kipisi.
\n
ken nanpa wan li ken ala tan ni: nanpa N li lon ala kulupu P. (nanpa tan kulupu P, la nanpa N li suli mute). taso ,ona li nanpa pi ken ala kipisi. kulupu P li wile jo e nanpa ale pi ken ala kipisi, la ni li ken ala.
\n
tenpo ni la o sitelen insa e ken nanpa tu. nanpa ni li wile lon: ona li nanpa pi ken ala kipisi, ona li ken kipisi e nanpa N. o nimi e ona kepeken sitelen L. o sona e ni: nanpa pi kulupu P li ken ala kipisi e nanpa N. (nanpa p li lon kulupu P la ona li lukin kipisi e nanpa N la wan li ante). tan ni, la nanpa L li ken ala lon kulupu P. taso ,ona li nanpa pi ken ala kipisi. sama tenpo pini, la ni li ken ala.
\n
ale ni, la kulupu P li suli pini, la ale li ijo pakala pi ken ala. tan ni, la kulupu P li wile kulupu pi suli ale.
\n
\n\n \n\n \n \n\n\n","content_text":"tawa kama lon e ni, o sitelen insa e ijo jasima: nanpa pi ken ala kipisi mute pini li lon. o nimi e kulupu pi nanpa ni kepeken sitelen P.\n\nni la o mute e nanpa ale pi kulupu P, o namako e wan. (ni li ken tan ni: kulupu Pli suli pini). o nimi e nanpa sin ni kepeken sitelen N.\n\nnanpa Nla ken tu li lon: ona li nanpa pi ken ala kipisi, anu ona li ijo tan mute pi nanpa ante pi ken ala kipisi.\n\nken nanpa wan li ken ala tan ni: nanpa N li lon ala kulupu P. (nanpa tan kulupu P, la nanpa N li suli mute). taso ,ona li nanpa pi ken ala kipisi. kulupu P li wile jo e nanpa ale pi ken ala kipisi, la ni li ken ala.\n\ntenpo ni la o sitelen insa e ken nanpa tu. nanpa ni li wile lon: ona li nanpa pi ken ala kipisi, ona li ken kipisi e nanpa N. o nimi e ona kepeken sitelen L. o sona e ni: nanpa pi kulupu P li ken ala kipisi e nanpa N. (nanpa p li lon kulupu P la ona li lukin kipisi e nanpa N la wan li ante). tan ni, la nanpa L li ken ala lon kulupu P. taso ,ona li nanpa pi ken ala kipisi. sama tenpo pini, la ni li ken ala.\n\nale ni, la kulupu P li suli pini, la ale li ijo pakala pi ken ala. tan ni, la kulupu P li wile kulupu pi suli ale.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/vstlbx/","title":"VSCode/Toolbx","content_html":"\n\n\n\n\n\nVSCode/Toolbx\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nVSCode/Toolbx\n\n\n\n \n \n \n
VSCode/Toolbx
\n \n\n \n \n \n\n \n
\n
A GUI script to run VSCode in a toolbox container.
\n\n
Recently, I switched to [Fedora Silverblue] as my desktop operating system. To give a basic summary, Silverblue is an operating system where the system files are immutable, and can be restored to a previous state at any time. This version of Fedora does not ship the package manager dnf. Instead, you are expected to install applications in one of three ways:
\n
\n
\n
[Flatpak]. These are applications with Android-like isolation and permission management capabilities.
\n
Flatpaks are nice, but there are still some rough edges (especially with less popular applications, where the packaging is not as well-maintained) and limitations (the VSCode terminal runs inside a container, and it’s pretty inconvenient to use any of your tools).
\n
\n
\n
[RPM-OSTree] allows you to “layer” packages onto the immutable image. The package installation creates a new image such that you can restore to a previous state of your system at any point.
\n
While it works, layering packages all the time is not ideal, and best reserved for things that don’t work any other way. The docs give the fish shell as an example. I used it for a package that the internet told me to install to make Eduroam work. Layered packages don’t take effect until a reboot.
\n
\n
\n
[Toolboxes]! Toolbox, or Toolbx as it’s been recently renamed[^1], is a tool for setting up development containers really easily.
\n
You type something to the effect of toolbox create my-project-container, and you have a place where you can sudo without password, install whatever package with dnf, just trash the place. The containers use your real home directory, can access USB devices, and other things that just work. If anything goes wrong, you can just create a new container and start over.
\n
\n
\n
Toolbx
\n
I set up toolboxes for a few projects to test the waters:
\n
\n
www: This website
\n
_hyperscript: The hypermedia programming language
\n
this-week-in-htmx: The weekly blog that I was running late on at the time. Sorry…
\n
\n
Great, I’m all set up!
\n
So… How do I develop in here?
\n
Some DDGing led me to the amazing [toolbox-vscode] script. It gives you a script that you can place into ~/.local/bin/code. The first time you run it, it sets up everything for connecting to the container via VSCode’s remote feature, and launches it. The setup needs to be performed once per container, which wasn’t the most convenient, but oh well.
\n
In which I have to have my GUIs
\n
Previously, I would launch VSCode and pick my project from the Open Recent menu. The flow of
\n
\n
opening a terminal
\n
entering the toolbox
\n
entering the project folder
\n
code .
\n
now I can code, but I’m left with a useless terminal open
\n
\n
was far too janky. What I wanted was:
\n
\n
launch an app
\n
pick my project from a list
\n
VSCode is open to the right toolbox and project directory, and the list is out of my way
\n
\n
After some relearning Bash and overengineering later, I have a script in my hands.
I’m still getting myself set up, but I’m happy that I figured this part out early on.
\n
\n\n \n\n \n \n\n\n","content_text":"A GUI script to run VSCode in a toolbox container.\n\n***\n\nRecently, I switched to [Fedora Silverblue] as my desktop operating system. To give a basic summary, Silverblue is an operating system where the system files are immutable, and can be restored to a previous state at any time. This version of Fedora does not ship the package manager `dnf`. Instead, you are expected to install applications in one of three ways:\n\n- [Flatpak]. These are applications with Android-like isolation and permission management capabilities.\n\n Flatpaks are nice, but there are still some rough edges (especially with less popular applications, where the packaging is not as well-maintained) and limitations (the VSCode terminal runs inside a container, and it's pretty inconvenient to use any of your tools).\n\n- [RPM-OSTree] allows you to \"layer\" packages onto the immutable image. The package installation creates a new image such that you can restore to a previous state of your system at any point.\n\n While it works, layering packages all the time is not ideal, and best reserved for things that don't work any other way. The docs give the `fish` shell as an example. I used it for a package that the internet told me to install to make Eduroam work. Layered packages don't take effect until a reboot.\n\n- [Toolboxes]! Toolbox, or Toolbx as it's been recently renamed[^1], is a tool for setting up development containers really easily.\n\n You type something to the effect of `toolbox create my-project-container`, and you have a place where you can `sudo` without password, install whatever package with `dnf`, just trash the place. The containers use your real home directory, can access USB devices, and other things that just work. If anything goes wrong, you can just create a new container and start over.\n\n## Toolbx\n\nI set up toolboxes for a few projects to test the waters:\n\n- `www`: This website\n- `_hyperscript`: The hypermedia programming language\n- `this-week-in-htmx`: The weekly blog that I was running late on at the time. Sorry...\n\nGreat, I'm all set up!\n\nSo... How do I develop in here?\n\nSome DDGing led me to the amazing [`toolbox-vscode`] script. It gives you a script that you can place into `~/.local/bin/code`. The first time you run it, it sets up everything for connecting to the container via VSCode's remote feature, and launches it. The setup needs to be performed once per container, which wasn't the most convenient, but oh well.\n\n## In which I have to have my GUIs\n\nPreviously, I would launch VSCode and pick my project from the Open Recent menu. The flow of\n\n- opening a terminal\n- entering the toolbox\n- entering the project folder\n- code .\n- now I can code, but I'm left with a useless terminal open\n\nwas far too janky. What I wanted was:\n\n- launch an app\n- pick my project from a list\n- VSCode is open to the right toolbox and project directory, and the list is out of my way\n\nAfter some relearning Bash and overengineering later, I have a script in my hands.\n\nvstlbx\n\n ~~~ bash\n #!/usr/bin/env bash\n\n # Depends on: bash zenity\n\n set -e\n\n Title=\"VS Toolbx\"\n Text=\"Select a container to open in VS Code:\"\n\n ## list-containers > containers\n list-containers() {\n \ttoolbox list --containers | tail -n +2 | tr -s ' +' \"\\t\" | cut -f 2\n }\n\n ## containers | user-pick-container > container\n user-pick-container() {\n \tzenity \\\n \t\t--title \"$Title\" \\\n \t\t--text \"$Text\" \\\n \t\t--list \\\n \t\t--column 'Name' \\\n \t\t--hide-header \\\n \t\t2>/dev/null\n }\n\n ## get-project-dir container > project\n get-project-dir() {\n \tif [ \"$1\" == \"hyperscript\" ]; then\n \t\techo \"$HOME/Projects/_hyperscript\"\n \telse\n \t\techo \"$HOME/Projects/$1\"\n \tfi\n }\n\n ## run-container container\n run-container() {\n \ttoolbox run --container \"$1\" -- $(which code) $(get-project-dir \"$1\")\n }\n\n ## run-ui\n run-ui() {\n \tcontainer=$(list-containers | user-pick-container)\n \trun-container \"$container\"\n }\n\n install-desktop-file() {\n \tdesktop_file=\"$HOME/.local/share/applications/com.dz4k.vstlbx.desktop\"\n \tcat <<-EOF >\"$desktop_file\"\n \t\t[Desktop Entry]\n \t\tType=Application\n \t\tName[en_US]=VS/Toolbx\n \t\tCategories=Development;\n \t\tX-GNOME-FullName[en_US]=VS/Toolbx\n \t\tComment[en_US.UTF-8]=Attach VSCode to toolboxes\n \t\tNoDisplay=false\n \t\tExec=/var/home/deniz/Applications/vstlbx\n \t\tPath=.\n \t\tTerminal=false\n \t\tX-GNOME-UsesNotifications=false\n \t\tStartupWMClass=zenity\n \t\tName[en_US.UTF-8]=VS/Toolbx\n \t\tX-GNOME-FullName[en_US.UTF-8]=VS/Toolbx\n \tEOF\n }\n\n if [ \"$#\" == 0 ]; then\n \trun-ui\n \texit 0\n fi\n\n while [ \"$#\" -gt 0 ]; do\n \tcase \"$1\" in\n \t\t'install-desktop')\n \t\t\tinstall-desktop-file\n \t\t;;\n \t\t'container')\n \t\t\trun-container \"$2\"\n \t\t\tshift\n \t\t;;\n \t\t'ui')\n \t\t\trun-ui\n \t\t;;\n \tesac\n \tshift\n done\n ~~~\n\n who needs Gists anyway\n\n\n\nHere's what the UI looks like:\n\n![A dialog with a list of container names: fedora-toolbox-35, hyperscript, this=week-in-htmx, www](/assets/photos/vstlbx.png)\n\nI'm still getting myself set up, but I'm happy that I figured this part out early on.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/sprinkle-sharing/","title":"Sprinkle Sharing","content_html":"\n\n\n\n\n\nSprinkle Sharing\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nSprinkle Sharing\n\n\n\n \n \n \n
Sprinkle Sharing
\n \n\n \n \n
This post is directly from my notes, with no edits.
\n \n\n \n
\n
When people talk about code sharing between server and client, the usual suspects are Node.js and sharing model classes. However, there's often good reason to duplicate these.\n
A far more interesting type of code sharing to me is eliminating this duplication:\n
When you are writing a server-driven web app with \"sprinkles\" of JS, you want to have interactive components, but also deliver usable HTML to non-JS-enabled1 clients. This means you are essentially writing a component with the first render and subsequent updates are written in different languages -- HTML then JS. How to make this nicer? (Existing answers follow)\n
Alpine and similar
\n
Write both in one language: \"HTML with JS inline in special attributes\".\n
React and similar
\n
Write both in one language: \"JS optionally with JSX\". Hard to set up sprinkle style, but wasn't this how it was originally created to be used?\n
\n
\"Non-JS-enabled\" includes not only browsers where the user turned off JS, but also times when the JS didn't load, or errored due to use of unsupported modern features.\n
\n
\n\n \n\n \n \n\n\n","content_text":"
When people talk about code sharing between server and client, the usual suspects are Node.js and sharing model classes. However, there's often good reason to duplicate these.\n\n
A far more interesting type of code sharing to me is eliminating this duplication:\n\n
When you are writing a server-driven web app with \"sprinkles\" of JS, you want to have interactive components, but also deliver usable HTML to non-JS-enabled1 clients. This means you are essentially writing a component with the first render and subsequent updates are written in different languages -- HTML then JS. How to make this nicer? (Existing answers follow)\n\n
Alpine and similar
\n\n
Write both in one language: \"HTML with JS inline in special attributes\".\n\n
React and similar
\n\n
Write both in one language: \"JS optionally with JSX\". Hard to set up sprinkle style, but wasn't this how it was originally created to be used?\n\n
\n
\"Non-JS-enabled\" includes not only browsers where the user turned off JS, but also times when the JS didn't load, or errored due to use of unsupported modern features.\n
\n\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/sokaktaki-ankara/","title":"Sokaktaki Ankara: Tabela Tasarım Yarışması","content_html":"\n\n\n\n\n\nSokaktaki Ankara: Tabela Tasarım Yarışması\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \t\n \n \n \n\nSokaktaki Ankara: Tabela Tasarım Yarışması\n\n\n\n \n \n \n
Ankara Büyükşehir Belediyesi sokak tabelalarının yenilenmesi için yarışma düzenledi. Halk oylamasına sunulmak üzere üç tasarım seçildi. Siz de Başkent Mobil uygulamasının Söz Hakkı bölümünden oy verebilirsiniz.
\n
Ben oyumu çoktan Eser A için kullandım. Büyük yazı kullanılmasını, metro, otobüs durağı gibi yerlerin gösterilmesini ve mimari eser künyelerinin çizim içermesini beğendim. Eser B’nin fazla dikkat çektiğini ve modası geçecek tasarım ögeleri kullandığını düşünüyorum. Eser C ise gereksiz öğelerle dolu: kimsenin göremeyeceği küçük haritalar ve kocaman “ankara” yazısı.\nEser C’deki gibi bir harita, Legible London tarzı bir haritada çok daha kullanışlı olabilir.
\n\n \n\n \n \n\n\n","content_text":"**:** [Kırmızı kazandı! (twitter)](https://twitter.com/ankarabbld/status/1433505785573777414)\n\nAnkara Büyükşehir Belediyesi sokak tabelalarının yenilenmesi için [yarışma][] düzenledi. Halk oylamasına sunulmak üzere üç tasarım seçildi. Siz de Başkent Mobil uygulamasının Söz Hakkı bölümünden oy verebilirsiniz.\n\nBen oyumu çoktan Eser A için kullandım. Büyük yazı kullanılmasını, metro, otobüs durağı gibi yerlerin gösterilmesini ve mimari eser künyelerinin çizim içermesini beğendim. Eser B'nin fazla dikkat çektiğini ve modası geçecek tasarım ögeleri kullandığını düşünüyorum. Eser C ise gereksiz öğelerle dolu: kimsenin göremeyeceği küçük haritalar ve kocaman \"ankara\" yazısı.\n:sidenote[Eser C'deki gibi bir harita, [Legible London][] tarzı bir haritada çok daha kullanışlı olabilir.]\n\n:: fig [![](<%= it.photo.src %>)] (<%= it.photo.src %> \"Eser A sokak tabelası.\")\n\n[Yarışma şartnamesinde][şartname] tabelaların İşçi Blokları Mahallesi, Gazi Mustafa Kemal Bulvarı, Balıkçı Caddesi, Alâ Sokak, 1923. Sokak ile test edilmesi söylenmiş. Bence [Bangabandhu Şeyh Mucibur Rahman Bulvarı][BŞM Rahman]da eklenmeliydi.\n\n[yarışma]: https://sokaktakiankara.ankara.bel.tr/\n[Legible London]: https://en.wikipedia.org/wiki/Legible_London\n[şartname]: https://sokaktakiankara.ankara.bel.tr/sartnameekler/tabelafontyarismasartnamesi.pdf\n[BŞM Rahman]: https://www.openstreetmap.org/way/25211791\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/ank-tabela-a.jpg","date_published":"undefined"},{"id":"/2021/kalama-lakimosa/","title":"kalama [_la_a_kute_ijo_moli_o_sona_a]","content_html":"\n\n\n\n\n\nkalama [_la_a_kute_ijo_moli_o_sona_a]\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nkalama [_la_a_kute_ijo_moli_o_sona_a]\n\n\n\n \n \n \n
kalama [_la_a_kute_ijo_moli_o_sona_a]
\n \n\n \n \n \n\n \n
\n
tenpo ni la pilin li telo: \njan ni li kama tan ma anpa: \nsewi li lawa e ona pakala.
\n
sewi o pona e ona. \njan Jesu wawa o \npana e lape tawa ona.
\n
\n\n \n\n \n \n\n\n","content_text":"tenpo ni la pilin li telo: \\\njan ni li kama tan ma anpa: \\\nsewi li lawa e ona pakala.\n\nsewi o pona e ona. \\\njan Jesu wawa o \\\npana e lape tawa ona.\n\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/hyperscript-event-delegation/","title":"Event Delegation in _hyperscript","content_html":"\n\n\n\n\n\nEvent Delegation in _hyperscript\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nEvent Delegation in _hyperscript\n\n\n\n \n \n \n
Event Delegation in _hyperscript
\n \n\n \n \n \n\n \n
\n
This is how you do it:
\n
on click\n\ttell the closest <li/> to the target\n\t\tremove yourself\n\t\t-- do more stuff...\n\t\t-- "you" refers to the clicked list item\n
\n
Or more concisely:
\n
on click tell closest <li/> to target\n\tremove yourself\n
\n
on click tell closest <li/> to target\n\tremove yourself\n
\n\n
I’ve seen some people use a pattern like this:
\n
<ul>\n\t{% for item in items %}\n\t\t<li _="on click remove me">{{ item }}</li>\n\t{% endfor %}\n</ul>\n
\n
This is convenient to write if you have a server-side templating system, but\nhas a few issues:
\n
\n
The code needs to be parsed N times where N is the number of items.
\n
The resulting HTML is bloated.
\n
If you add more items client-side, you need to repeat the code there.
\n
\n
The pattern for resolving this is called event delegation. Here’s\nhow you might do it in JavaScript:
\n
ul.addEventListener('click', e => {\n\tconst li = e.target.closest('li')\n\tif (!li) return\n\tli.remove()\n})\n
\n
We add a single event listener to the enclosing list, which finds the item\nthat was clicked and manipulates it.
\n
In _hyperscript, the tell command allows us to manipulate an\nelement other than me conveniently, by changing the implicit\ntarget from me to you, which refers to the “element\nbeing told”.
\n
\n\n \n\n \n \n \n\n\n","content_text":"This is how you do it:\n\n```hyperscript\non click\n\ttell the closest to the target\n\t\tremove yourself\n\t\t-- do more stuff...\n\t\t-- \"you\" refers to the clicked list item\n```\n\nOr more concisely:\n\n```hyperscript\non click tell closest to target\n\tremove yourself\n```\n\n```hyperscript\non click tell closest <li/> to target\n\tremove yourself\n```\n\n---\n\nI've seen some people use a pattern like this:\n\n```html\n
\n\t{% for item in items %}\n\t\t
{{ item }}
\n\t{% endfor %}\n
\n```\n\nThis is convenient to write if you have a server-side templating system, but\nhas a few issues:\n\n * The code needs to be parsed N times where N is the number of items.\n * The resulting HTML is bloated.\n * If you add more items client-side, you need to repeat the code there.\n\nThe pattern for resolving this is called event delegation. Here's\nhow you might do it in JavaScript:\n\n```javascript\nul.addEventListener('click', e => {\n\tconst li = e.target.closest('li')\n\tif (!li) return\n\tli.remove()\n})\n```\n\nWe add a single event listener to the enclosing list, which finds the item\nthat was clicked and manipulates it.\n\nIn _hyperscript, the tell command allows us to manipulate an\nelement other than me conveniently, by changing the implicit\ntarget from me to you, which refers to the \"element\nbeing told\".\n\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/hypelet/","title":"Hypelet","content_html":"\n\n\n\n\n\nHypelet\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nHypelet\n\n\n\n \n \n \n
Hypelet
\n \n\n \n \n \n\n \n
\n
I made a tool to make bookmarklets in _hyperscript. You just write some code in the box and drag the bookmarklet into your bookmarks toolbar. Hypelet injects glue code to load hyperscript dynamically and run your code. You can get a permalink to share your bookmarklet.
Here’s the code for a bookmarklet to get the RSS feed of a page: Get RSS – Hypelet
\n
\n
\n\n \n\n \n \n \n\n\n","content_text":"I made a tool to make bookmarklets in [_hyperscript](//hyperscript.org). You just write some code in the box and drag the bookmarklet into your bookmarks toolbar. Hypelet injects glue code to load hyperscript dynamically and run your code. You can get a permalink to share your bookmarklet.\n\n- Here's Hypelet: [Hypelet](//hypelet.dz4k.com)\n- Here's the code for a bookmarklet to get the RSS feed of a page: [Get RSS -- Hypelet][get-rss]\n\n[get-rss]: https://hypelet.dz4k.com/#%7B%22hs%22%3A%22get%20the%20href%20of%20the%20first%20%3C%5Brel%3Dfeed%5D%2C%20%5Btype%5E%3D%5C%22application%2Frss%2Bxml%5C%22%5D%2F%3E%5Cncall%20alert(it)%22%2C%22name%22%3A%22get%20rss%20feed%22%7D\n","url":"https://denizaksimsek.com/undefined","summary":"I made a tool to make bookmarklets in _hyperscript.","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/the-implementation-of-hdb/","title":"The Implementation of HDB, the _hyperscript debugger","content_html":"\n\n\n\n\n\nThe Implementation of HDB, the _hyperscript debugger\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nThe Implementation of HDB, the _hyperscript debugger\n\n\n\n \n \n \n
The Implementation of HDB, the _hyperscript debugger
\n \n\n \n \n \n\n \n
\n \n\n
Update : HDB has evolved since this post was written. Though it works mostly the same way, there have been fixes and a UI redesign. Check the _hyperscript repo for the up-to-date Code:
\n
The 0.0.6 release of the _hyperscript hypertext UI scripting language introduces HDB, an interactive debugging environment. In this article I discuss how the hyper-flexible hyperscript runtime allowed me to implement the first release of HDB with ease. But first, I will introduce you to what HDB is like:
\n
The (Un)finished Product
\n
The breakpoint statement stops execution and launches the HDB UI.
In the hyperscript runtime (which is a tree walking interpreter), each command has an execute() method which either returns the next command to be executed, or a Promise thereof. The execute method for the breakpoint command creates an HDB environment and assigns it to the global scope (usually window):
\n\n
var hdb = new HDB(ctx, runtime, this);\nwindow.hdb = hdb;\n
\n\n
The HDB object keeps hold of the current command and context as we step through. (The context is the object holding the local variables for the hyperscript code, and some other things the runtime keeps track of). We call its break() method:
There are a few things to unpack here. We call self.ui() to start the UI, which we’ll get to later. Remember how a command can return the next method to execute as a promise? The break method resolves after the internal event bus receives a "continue" event, whether by the user pressing “Continue” or simply reaching the end of the debugged Code:
\n
The “context switch” is the dirtiest part of it all. Because we can step out of functions, we might finish debugging session with a different context than before. In this case, we just wipe the old context and copy the current context variables over. Honestly, I thought I’d have to do a lot more of this kind of thing.
\n
Speaking of stepping out of functions…
\n
Stepping Over and Out
\n
Firstly, if self.cmd is null, then the previous command was the last one, so we just stop the debug process:
If not, then we do a little dance to execute the current command and get the next one:
\n\n
var result = self.cmd && self.cmd.type === 'breakpointCommand' ?\n\tself.runtime.findNext(self.cmd, self.ctx) :\n\tself.runtime.unifiedEval(self.cmd, self.ctx);\n
\n\n
We perform a useless check that I forgot to take out (self.cmd &&). Then, we special-case the breakpoint command itself and don’t execute it (nested debug sessions don’t end well…), instead finding the subsequent command ourselves with the runtime.findNext() in hyperscript core. Otherwise, we can execute the current command.
\n
Once we have our command result, we can step onto it:
If we returned from a function, we step out of it (discussed below). Otherwise, if the command returned a Promise, we await the next command, set cmd to it, notify the event bus and log it with some fancy styles. If the result was synchronous and is a HALT; we stop debugging (as I write this, I’m realizing I should’ve called continueExec() here). Finally, we commit the kind of code duplication hyperscript is meant to help you avoid, to handle a synchronous result.
\n
To step out, we first get our hands on the context from which we were called:
Turns out _hyperscript function calls already keep hold of the caller context (callingCommand was added by me though). After we change context, we do something a little odd:
Why do we call findNext twice? Consider the following hyperscript code:
\n\n
transition 'color' to darkgray\nset name to getName()\nlog the name\n
\n\n
We can’t execute the command to set name until we have the name, so when getName() is called, the current command is still set to the transition. We call findNext once to find the set, and again to find the log.
\n
Finally, we’re done stepping out:
\n\n
self.bus.dispatchEvent(new Event('step'))\n
\n\n
HDB UI
\n
What did I use to make the UI for the hyperscript debugger? Hyperscript, of course!
\n\n
<div class="hdb" _="--\n\ton load or step from hdb.bus send update to me\n\ton continue from hdb.bus remove #hyperscript-hdb-ui-wrapper-">\n
\n\n
There are a lot of elements listening to load or step from hdb.bus, so I consolidated them under update from .hdb. #hyperscript-hdb-ui-wrapper- is the element whose Shadow DOM this UI lives in — using shadow DOM to isolate the styling of the panel cost me later on, as you’ll see.
\n\n
We define some functions.
\n\n
def highlightDebugCode\n\tset start to hdb.cmd.startToken.start\n\tset end_ to hdb.cmd.endToken.end\n\tset src to hdb.cmd.programSource\n\tset beforeCmd to escapeHTML(src.substring(0, start))\n\tset cmd to escapeHTML(src.substring(start, end_))\n\tset afterCmd to escapeHTML(src.substring(end_))\n\treturn beforeCmd+"<u class='current'>"+cmd+"</u>"+afterCmd\nend\n
\n\n
Now, I wasn’t aware that we had template literals in hyperscript at this point, so that’s for the next release. The escapeHTML helper might disappoint some:
And we have the most broken part of HDB, the prettyPrint function. If you know how to do this better, feel free to send a PR.
\n
Having defined our functions we have a simple toolbar and then the eval panel:
\n\n
<form class="eval-form" _="on submit\n\tcall event.preventDefault()\n\tget the first <input/> in me\n\tcall _hyperscript(its.value, hdb.ctx)\n\tcall prettyPrint(it)\n\tput it into the <output/> in me">\n\n\t\t<input type="text" id="eval-expr" placeholder="e.g. target.innerText">\n\t\t<button type="submit">Go</button>\n\t\t<output id="eval-output"><em>The value will show up here</em></output>\n
\n\n
Why do I use weird selectors like <input/> in me when these elements have good IDs? Because #eval-expr in hyperscript uses document.querySelector, which doesn’t reach Shadow DOM.
\n\n
A panel to show the code being debugged:
\n\n
<h3 _="on update from hdbUI\n\t\tput 'Debugging <code>'+hdb.cmd.parent.displayName+'</code>' into me"></h3>\n<div class="code-container">\n\t<pre class="code" _="on update from hdbUI\n\t\t\t\t\t\t\tif hdb.cmd.programSource\n\t\t\t\t\t\t\t\tput highlightDebugCode() into my.innerHTML\n\t\t\t\t\t\t\t\tscrollIntoView({ block: 'nearest' }) the\n\t\t\t\t\t\t\t\tfirst .current in me"></pre>\n</div>\n
\n\n\n
Finally, a context panel that shows the local variables.
\n\n
<dl class="context" _="--\n\ton update from hdbUI\n\t\tset my.innerHTML to ''\n\t\trepeat for var in Object.keys(hdb.ctx) if var != 'meta'\n\t\t\tget '<dt>'+var+'<dd>'+prettyPrint(hdb.ctx[var])\n\t\t\tput it at end of me\n\t\tend\n\ton click\n\t\tget closest <dt/> to target\n\t\tlog hdb.ctx[its.innerText]"></dl>\n
\n\n
That loop could definitely be cleaner. You can see the hidden feature where you can click a variable name to log it to the console (useful if you don’t want to rely on my super-buggy pretty printer).
\n
Some CSS later, we’re done with the UI! To avoid CSS interference from the host page, we create a wrapper and put our UI in its shadow DOM:
In just 360 lines, we have a basic debugger. This speaks volumes to the flexibility of the hyperscript runtime, and I hope HDB serves as an example of what’s possible with the hyperscript extension API. Like the rest of hyperscript, it’s in early stages of development — feedback and contributors are always welcome!
\n
\n\n \n\n \n \n \n\n\n","content_text":"\n\n\n**Update :** HDB has evolved since this post was written. Though it works mostly the same way, there have been fixes and a UI redesign. Check [the _hyperscript repo][] for the up-to-date Code:\n\nThe 0.0.6 release of the [_hyperscript] hypertext UI scripting language introduces HDB, an interactive debugging environment. In this article I discuss how the hyper-flexible hyperscript runtime allowed me to implement the first release of HDB with ease. But first, I will introduce you to what HDB is like:\n\n## The (Un)finished Product\n\nThe `breakpoint` statement stops execution and launches the HDB UI.\n\n::: fig (\"Demo: The breakpoint command\")\n\n:::\n\nYou can set breakpoints conditionally:\n\n::: fig (\"Demo: Conditional breakpoints\")\n\n\n\n\n\n:::\n\n## Implementation\n\nHDB lives in a [single JavaScript file][hdb-src].\n\n### Turning the keys\n\nIn the hyperscript runtime (which is a tree walking interpreter), each command has an `execute()` method which either returns the next command to be executed, or a `Promise` thereof. The execute method for the breakpoint command creates an HDB environment and assigns it to the global scope (usually `window`):\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L20 \"hdb.js ln. 20\")\n~~~js\nvar hdb = new HDB(ctx, runtime, this);\nwindow.hdb = hdb;\n~~~\n:::\n\nThe `HDB` object keeps hold of the current command and context as we step through. (The context is the object holding the local variables for the hyperscript code, and some other things the runtime keeps track of). We call its `break()` method:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L35 \"hdb.js ln. 35\")\n~~~js\nHDB.prototype.break = function(ctx) {\n\tvar self = this;\n\tconsole.log(\"%c=== HDB///_hyperscript/debugger ===\", headingStyle);\n\tself.ui();\n\treturn new Promise(function (resolve, reject) {\n\t\tself.bus.addEventListener(\"continue\", function () {\n\t\t\tif (self.ctx !== ctx) {\n\t\t\t\t// Context switch\n\t\t\t\tfor (var attr in ctx) {\n\t\t\t\t\tdelete ctx[attr];\n\t\t\t\t}\n\t\t\t\tObject.assign(ctx, self.ctx);\n\t\t\t}\n\t\t\tdelete window.hdb;\n\t\t\tresolve(self.runtime.findNext(self.cmd, self.ctx));\n\t\t}, { once: true });\n\t})\n}\n~~~\n:::\n\nThere are a few things to unpack here. We call `self.ui()` to start the UI, which we'll get to later. Remember how a command can return the next method to execute as a promise? The break method resolves after the [internal event bus][] receives a `\"continue\"` event, whether by the user pressing \"Continue\" or simply reaching the end of the debugged Code:\n\nThe \"context switch\" is the dirtiest part of it all. Because we can step out of functions, we might finish debugging session with a different context than before. In this case, we just wipe the old context and copy the current context variables over. Honestly, I thought I'd have to do a lot more of this kind of thing.\n\nSpeaking of stepping out of functions...\n\n### Stepping Over and Out\n\nFirstly, if self.cmd is null, then the previous command was the last one, so we just stop the debug process:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L58 \"hdb.js ln. 58\")\n~~~js\nHDB.prototype.stepOver = function() {\n\tvar self = this;\n\tif (!self.cmd) return self.continueExec();\n~~~\n:::\n\nIf not, then we do a little dance to execute the current command and get the next one:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L61 \"hdb.js ln. 61\")\n~~~js\nvar result = self.cmd && self.cmd.type === 'breakpointCommand' ?\n\tself.runtime.findNext(self.cmd, self.ctx) :\n\tself.runtime.unifiedEval(self.cmd, self.ctx);\n~~~\n:::\n\nWe perform a useless check that I forgot to take out (`self.cmd &&`). Then, we special-case the `breakpoint` command itself and don't execute it (nested debug sessions don't end well...), instead finding the subsequent command ourselves with the `runtime.findNext()` in hyperscript core. Otherwise, we can execute the current command.\n\nOnce we have our command result, we can step onto it:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L61 \"hdb.js ln. 64\")\n~~~js\nif (result.type === \"implicitReturn\") return self.stepOut();\nif (result && result.then instanceof Function) {\n\treturn result.then(function (next) {\n\t\tself.cmd = next;\n\t\tself.bus.dispatchEvent(new Event(\"step\"));\n\t\tself.logCommand();\n\t})\n} else if (result.halt_flag) {\n\tthis.bus.dispatchEvent(new Event(\"continue\"));\n} else {\n\tself.cmd = result;\n\tself.bus.dispatchEvent(new Event(\"step\"));\n\tthis.logCommand();\n}\n~~~\n:::\n\nIf we returned from a function, we step out of it (discussed below). Otherwise, if the command returned a Promise, we await the next command, set `cmd` to it, notify the event bus and log it with some fancy styles. If the result was synchronous and is a [HALT][]; we stop debugging (as I write this, I'm realizing I should've called [`continueExec()`][continue-exec] here). Finally, we commit the kind of code duplication hyperscript is meant to help you avoid, to handle a synchronous result.\n\nTo step out, we first get our hands on the context from which we were called:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L80 \"hdb.js ln. 80\")\n~~~js\nHDB.prototype.stepOut = function() {\n\tvar self = this;\n\tif (!self.ctx.meta.caller) return self.continueExec();\n\tvar callingCmd = self.ctx.meta.callingCommand;\n\tvar oldMe = self.ctx.me;\n\tself.ctx = self.ctx.meta.caller;\n~~~\n:::\n\nTurns out _hyperscript function calls already keep hold of the caller context (`callingCommand` was added by me though). After we change context, we do something a little odd:\n\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L92 \"hdb.js ln. 92\")\n~~~js\nself.cmd = self.runtime.findNext(callingCmd, self.ctx);\nself.cmd = self.runtime.findNext(self.cmd, self.ctx);\n~~~\n:::\n\nWhy do we call `findNext` twice? Consider the following hyperscript code:\n\n::: fig\n~~~hyperscript\ntransition 'color' to darkgray\nset name to getName()\nlog the name\n~~~\n:::\n\nWe can't execute the command to set `name` until we have the name, so when `getName()` is called, the current command is still set to the `transition`. We call `findNext` once to find the `set`, and again to find the `log`.\n\nFinally, we're done stepping out:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L95 \"hdb.js ln. 95\")\n~~~js\nself.bus.dispatchEvent(new Event('step'))\n~~~\n:::\n\n### HDB UI\n\nWhat did I use to make the UI for the hyperscript debugger? Hyperscript, of course!\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L107 \"hdb.js ln. 107\")\n~~~html\n
\n~~~\n:::\n\nThere are a lot of elements listening to `load or step from hdb.bus`, so I consolidated them under `update from .hdb`. `#hyperscript-hdb-ui-wrapper-` is the element whose Shadow DOM this UI lives in --- using shadow DOM to isolate the styling of the panel cost me later on, as you'll see.\n\n-------------\n\nWe define some functions.\n\n::: fig(https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L112 \"hdb.js ln. 112\")\n~~~hyperscript\ndef highlightDebugCode\n\tset start to hdb.cmd.startToken.start\n\tset end_ to hdb.cmd.endToken.end\n\tset src to hdb.cmd.programSource\n\tset beforeCmd to escapeHTML(src.substring(0, start))\n\tset cmd to escapeHTML(src.substring(start, end_))\n\tset afterCmd to escapeHTML(src.substring(end_))\n\treturn beforeCmd+\"\"+cmd+\"\"+afterCmd\nend\n~~~\n:::\n\nNow, I wasn't aware that we had [template literals][] in hyperscript at this point, so that's for the next release. The `escapeHTML` helper might disappoint some:\n\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L122 \"hdb.js ln. 122\")\n~~~hyperscript\ndef escapeHTML(unsafe)\n\tjs(unsafe) return unsafe\n\t\t.replace(/&/g, \"&\")\n\t\t.replace(//g, \">\")\n\t\t.replace(/\\\\x22/g, \""\")\n\t\t.replace(/\\\\x27/g, \"'\") end\n\treturn it\nend\n~~~\n:::\n\nUnfortunately, hyperscript's regex syntax isn't decided yet.\n\n------------\n\nAnd we have the most broken part of HDB, the prettyPrint function. If you know how to do this better, feel free to send a PR.\n\nHaving defined our functions we have a simple toolbar and then the **eval panel**:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L158 \"hdb.js ln. 158\")\n~~~html\n in me\n\tcall _hyperscript(its.value, hdb.ctx)\n\tcall prettyPrint(it)\n\tput it into the in me\">\n\n\t\t\n\t\t\n\t\t\n~~~\n:::\n\nWhy do I use weird selectors like ` in me` when these elements have good IDs? Because `#eval-expr` in hyperscript uses `document.querySelector`, which doesn't reach Shadow DOM.\n\n------------\n\nA panel to show the code being debugged:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L170 \"hdb.js ln. 170\")\n~~~html\n
'+hdb.cmd.parent.displayName+'' into me\">
\n
\n\t\n
\n~~~\n:::\n\n------------\n\nFinally, a context panel that shows the local variables.\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L186 \"hdb.js ln. 106\")\n~~~html\n
'+var+'
'+prettyPrint(hdb.ctx[var])\n\t\t\tput it at end of me\n\t\tend\n\ton click\n\t\tget closest
to target\n\t\tlog hdb.ctx[its.innerText]\">
\n~~~\n:::\n\nThat loop could definitely be cleaner. You can see the hidden feature where you can click a variable name to log it to the console (useful if you don't want to rely on my super-buggy pretty printer).\n\nSome CSS later, we're done with the UI! To avoid CSS interference from the host page, we create a wrapper and put our UI in its shadow DOM:\n\n::: fig (https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L350 \"hdb.js ln. 350\")\n~~~js\nHDB.prototype.ui = function () {\n\tvar node = document.createElement('div');\n\tvar shadow = node.attachShadow({ mode: 'open' });\n\tnode.style = 'all: initial';\n\tnode.id = 'hyperscript-hdb-ui-wrapper-';\n\tshadow.innerHTML = ui;\n\tdocument.body.appendChild(node);\n\twindow.hdbUI = shadow.querySelector('.hdb');\n\t_hyperscript.processNode(hdbUI);\n}\n~~~\n:::\n\n## The End\n\nIn just 360 lines, we have a basic debugger. This speaks volumes to the flexibility of the hyperscript runtime, and I hope HDB serves as an example of what's possible with the hyperscript extension API. Like the rest of hyperscript, it's in early stages of development --- feedback and contributors are always welcome!\n\n[_hyperscript]: https://hyperscript.org\n[the _hyperscript repo]: https://github.com/bigskysoftware/_hyperscript\n[hdb-src]: https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js\n[continue-exec]: https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L54\n[HALT]: https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/core.js#L1221\n[template literals]: https://hyperscript.org/expressions/string/\n[internal event bus]: https://github.com/bigskysoftware/_hyperscript/blob/7740c7eccfe3fe4f09443ec0adb961c72eb27a7b/src/lib/hdb.js#L10\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2021/contrast-black-and-white/","title":"Colors That Contrast With Both Black And White","content_html":"\n\n\n\n\n\nColors That Contrast With Both Black And White\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nColors That Contrast With Both Black And White\n\n\n\n \n \n \n
to the target\n\t\t\t\tset #selected-color's innerText to the target's innerText\n\t\t\t\tadd {'--color': the target's innerText} to the #selected-color\n\t\t\t\ttake .active\n\t\t\">\n\t\t\t\t\t
#006AFF\t\t\t\t\t
#006CFF\t\t\t\t\t
#006DFA\t\t\t\t\t
#006DF5\t\t\t\t\t
#006FF0\t\t\t\t\t
#0070F5\t\t\t\t\t
#0071F0\t\t\t\t\t
#0071EB\t\t\t\t\t
#0072EB\t\t\t\t\t
#0072E6\t\t\t\t\t
#0073E1\t\t\t\t\t
#0075E1\t\t\t\t\t
#0075DC\t\t\t\t\t
#0075D7\t\t\t\t\t
#0077D7\t\t\t\t\t
#0078D2\t\t\t\t\t
#0079D2\t\t\t\t\t
#0078C8\t\t\t\t\t
#0079C8\t\t\t\t\t
#0079C3\t\t\t\t\t
#007BC3\t\t\t\t\t
#007CBE\t\t\t\t\t
#007CB9\t\t\t\t\t
#007CB4\t\t\t\t\t
#007CAF\t\t\t\t\t
#007EAF\t\t\t\t\t
#007DAA\t\t\t\t\t
#007EA5\t\t\t\t\t
#0080A5\t\t\t\t\t
#0080A0\t\t\t\t\t
#007F9B\t\t\t\t\t
#00829B\t\t\t\t\t
#008196\t\t\t\t\t
#008191\t\t\t\t\t
#00818C\t\t\t\t\t
#00838C\t\t\t\t\t
#008387\t\t\t\t\t
#008382\t\t\t\t\t
#00837D\t\t\t\t\t
#00857D\t\t\t\t\t
#008578\t\t\t\t\t
#008573\t\t\t\t\t
#00846E\t\t\t\t\t
#00866E\t\t\t\t\t
#008669\t\t\t\t\t
#008664\t\t\t\t\t
#00855F\t\t\t\t\t
#00855A\t\t\t\t\t
#00875A\t\t\t\t\t
#008755\t\t\t\t\t
#008750\t\t\t\t\t
#00864B\t\t\t\t\t
#00884B\t\t\t\t\t
#008741\t\t\t\t\t
#008941\t\t\t\t\t
#00883C\t\t\t\t\t
#008737\t\t\t\t\t
#008732\t\t\t\t\t
#008932\t\t\t\t\t
#00882D\t\t\t\t\t
#008928\t\t\t\t\t
#008823\t\t\t\t\t
#008A23\t\t\t\t\t
#008A1E\t\t\t\t\t
#008919\t\t\t\t\t
#008814\t\t\t\t\t
#008A14\t\t\t\t\t
#008A0F\t\t\t\t\t
#00890A\t\t\t\t\t
#008805\t\t\t\t\t
#008800\t\t\t\t\t
#008A00\t\t\t\t\t
#056AFF\t\t\t\t\t
#056CFF\t\t\t\t\t
#056DFA\t\t\t\t\t
#056DF5\t\t\t\t\t
#056FF0\t\t\t\t\t
#0570F5\t\t\t\t\t
#0571F0\t\t\t\t\t
#0571EB\t\t\t\t\t
#0573EB\t\t\t\t\t
#0573E6\t\t\t\t\t
#0573E1\t\t\t\t\t
#0575E1\t\t\t\t\t
#0575DC\t\t\t\t\t
#0575D7\t\t\t\t\t
#0577D7\t\t\t\t\t
#0578D2\t\t\t\t\t
#0578CD\t\t\t\t\t
#0579C8\t\t\t\t\t
#0579C3\t\t\t\t\t
#057BC3\t\t\t\t\t
#057BBE\t\t\t\t\t
#057CB9\t\t\t\t\t
#057CB4\t\t\t\t\t
#057EB4\t\t\t\t\t
#057EAF\t\t\t\t\t
#057DAA\t\t\t\t\t
#057FAA\t\t\t\t\t
#0580A5\t\t\t\t\t
#0580A0\t\t\t\t\t
#057F9B\t\t\t\t\t
#05819B\t\t\t\t\t
#058296\t\t\t\t\t
#058191\t\t\t\t\t
#058391\t\t\t\t\t
#05838C\t\t\t\t\t
#058387\t\t\t\t\t
#058282\t\t\t\t\t
#05837D\t\t\t\t\t
#05857D\t\t\t\t\t
#058478\t\t\t\t\t
#058473\t\t\t\t\t
#058673\t\t\t\t\t
#05856E\t\t\t\t\t
#058469\t\t\t\t\t
#058564\t\t\t\t\t
#058764\t\t\t\t\t
#05865F\t\t\t\t\t
#05865A\t\t\t\t\t
#058655\t\t\t\t\t
#058855\t\t\t\t\t
#058850\t\t\t\t\t
#05874B\t\t\t\t\t
#058646\t\t\t\t\t
#058741\t\t\t\t\t
#058941\t\t\t\t\t
#05883C\t\t\t\t\t
#058737\t\t\t\t\t
#058732\t\t\t\t\t
#058932\t\t\t\t\t
#05882D\t\t\t\t\t
#058828\t\t\t\t\t
#058823\t\t\t\t\t
#058A23\t\t\t\t\t
#058A1E\t\t\t\t\t
#058919\t\t\t\t\t
#058814\t\t\t\t\t
#058A14\t\t\t\t\t
#058A0F\t\t\t\t\t
#05890A\t\t\t\t\t
#058805\t\t\t\t\t
#058800\t\t\t\t\t
#058A00\t\t\t\t\t
#0A6AFF\t\t\t\t\t
#0A6CFF\t\t\t\t\t
#0A6DFA\t\t\t\t\t
#0A6DF5\t\t\t\t\t
#0A6EF0\t\t\t\t\t
#0A70F5\t\t\t\t\t
#0A71F0\t\t\t\t\t
#0A71EB\t\t\t\t\t
#0A73EB\t\t\t\t\t
#0A73E6\t\t\t\t\t
#0A73E1\t\t\t\t\t
#0A75E1\t\t\t\t\t
#0A75DC\t\t\t\t\t
#0A75D7\t\t\t\t\t
#0A76D2\t\t\t\t\t
#0A78D2\t\t\t\t\t
#0A78CD\t\t\t\t\t
#0A78C8\t\t\t\t\t
#0A79C3\t\t\t\t\t
#0A7BC3\t\t\t\t\t
#0A7BBE\t\t\t\t\t
#0A7BB9\t\t\t\t\t
#0A7BB4\t\t\t\t\t
#0A7DB4\t\t\t\t\t
#0A7CAF\t\t\t\t\t
#0A7DAA\t\t\t\t\t
#0A7FAA\t\t\t\t\t
#0A7FA5\t\t\t\t\t
#0A7EA0\t\t\t\t\t
#0A81A0\t\t\t\t\t
#0A809B\t\t\t\t\t
#0A8096\t\t\t\t\t
#0A8091\t\t\t\t\t
#0A8291\t\t\t\t\t
#0A828C\t\t\t\t\t
#0A8287\t\t\t\t\t
#0A8487\t\t\t\t\t
#0A8382\t\t\t\t\t
#0A827D\t\t\t\t\t
#0A857D\t\t\t\t\t
#0A8478\t\t\t\t\t
#0A8373\t\t\t\t\t
#0A846E\t\t\t\t\t
#0A866E\t\t\t\t\t
#0A8569\t\t\t\t\t
#0A8564\t\t\t\t\t
#0A855F\t\t\t\t\t
#0A875F\t\t\t\t\t
#0A865A\t\t\t\t\t
#0A8755\t\t\t\t\t
#0A8650\t\t\t\t\t
#0A8850\t\t\t\t\t
#0A874B\t\t\t\t\t
#0A8746\t\t\t\t\t
#0A8741\t\t\t\t\t
#0A873C\t\t\t\t\t
#0A8737\t\t\t\t\t
#0A8937\t\t\t\t\t
#0A8832\t\t\t\t\t
#0A882D\t\t\t\t\t
#0A8728\t\t\t\t\t
#0A8928\t\t\t\t\t
#0A8823\t\t\t\t\t
#0A891E\t\t\t\t\t
#0A8919\t\t\t\t\t
#0A8814\t\t\t\t\t
#0A880F\t\t\t\t\t
#0A8A0F\t\t\t\t\t
#0A890A\t\t\t\t\t
#0A8805\t\t\t\t\t
#0A8800\t\t\t\t\t
#0A8A00\t\t\t\t\t
#0F6AFF\t\t\t\t\t
#0F6CFA\t\t\t\t\t
#0F6DFF\t\t\t\t\t
#0F6EFA\t\t\t\t\t
#0F6EF5\t\t\t\t\t
#0F6FF5\t\t\t\t\t
#0F70F0\t\t\t\t\t
#0F70EB\t\t\t\t\t
#0F72EB\t\t\t\t\t
#0F73E6\t\t\t\t\t
#0F73E1\t\t\t\t\t
#0F74E1\t\t\t\t\t
#0F74DC\t\t\t\t\t
#0F76DC\t\t\t\t\t
#0F76D7\t\t\t\t\t
#0F77D2\t\t\t\t\t
#0F77CD\t\t\t\t\t
#0F79CD\t\t\t\t\t
#0F7AC8\t\t\t\t\t
#0F7AC3\t\t\t\t\t
#0F7ABE\t\t\t\t\t
#0F7CBE\t\t\t\t\t
#0F7CB9\t\t\t\t\t
#0F7BB4\t\t\t\t\t
#0F7DB4\t\t\t\t\t
#0F7DAF\t\t\t\t\t
#0F7DAA\t\t\t\t\t
#0F7FAA\t\t\t\t\t
#0F7FA5\t\t\t\t\t
#0F7FA0\t\t\t\t\t
#0F7F9B\t\t\t\t\t
#0F819B\t\t\t\t\t
#0F8296\t\t\t\t\t
#0F8191\t\t\t\t\t
#0F818C\t\t\t\t\t
#0F8187\t\t\t\t\t
#0F8387\t\t\t\t\t
#0F8382\t\t\t\t\t
#0F827D\t\t\t\t\t
#0F8378\t\t\t\t\t
#0F8578\t\t\t\t\t
#0F8473\t\t\t\t\t
#0F856E\t\t\t\t\t
#0F8469\t\t\t\t\t
#0F8669\t\t\t\t\t
#0F8564\t\t\t\t\t
#0F865F\t\t\t\t\t
#0F855A\t\t\t\t\t
#0F875A\t\t\t\t\t
#0F8755\t\t\t\t\t
#0F8750\t\t\t\t\t
#0F864B\t\t\t\t\t
#0F884B\t\t\t\t\t
#0F8846\t\t\t\t\t
#0F8741\t\t\t\t\t
#0F873C\t\t\t\t\t
#0F8737\t\t\t\t\t
#0F8937\t\t\t\t\t
#0F8832\t\t\t\t\t
#0F882D\t\t\t\t\t
#0F8728\t\t\t\t\t
#0F8928\t\t\t\t\t
#0F8823\t\t\t\t\t
#0F881E\t\t\t\t\t
#0F8819\t\t\t\t\t
#0F8814\t\t\t\t\t
#0F880F\t\t\t\t\t
#0F8A0F\t\t\t\t\t
#0F890A\t\t\t\t\t
#0F8805\t\t\t\t\t
#0F8800\t\t\t\t\t
#0F8A00\t\t\t\t\t
#146AFF\t\t\t\t\t
#146CFA\t\t\t\t\t
#146DFF\t\t\t\t\t
#146DF5\t\t\t\t\t
#146EF0\t\t\t\t\t
#146FF5\t\t\t\t\t
#1470F0\t\t\t\t\t
#1470EB\t\t\t\t\t
#1472EB\t\t\t\t\t
#1473E6\t\t\t\t\t
#1473E1\t\t\t\t\t
#1475E1\t\t\t\t\t
#1475DC\t\t\t\t\t
#1476DC\t\t\t\t\t
#1475D2\t\t\t\t\t
#1477D7\t\t\t\t\t
#1476CD\t\t\t\t\t
#1478CD\t\t\t\t\t
#1477C8\t\t\t\t\t
#147AC8\t\t\t\t\t
#1479C3\t\t\t\t\t
#1479BE\t\t\t\t\t
#147BBE\t\t\t\t\t
#147AB9\t\t\t\t\t
#147DB9\t\t\t\t\t
#147CB4\t\t\t\t\t
#147DAF\t\t\t\t\t
#147DAA\t\t\t\t\t
#147FAA\t\t\t\t\t
#147FA5\t\t\t\t\t
#147EA0\t\t\t\t\t
#1480A0\t\t\t\t\t
#14819B\t\t\t\t\t
#148096\t\t\t\t\t
#148091\t\t\t\t\t
#148291\t\t\t\t\t
#14828C\t\t\t\t\t
#148287\t\t\t\t\t
#148282\t\t\t\t\t
#14827D\t\t\t\t\t
#14847D\t\t\t\t\t
#148478\t\t\t\t\t
#148473\t\t\t\t\t
#14836E\t\t\t\t\t
#14866E\t\t\t\t\t
#148569\t\t\t\t\t
#148464\t\t\t\t\t
#14855F\t\t\t\t\t
#14875F\t\t\t\t\t
#14865A\t\t\t\t\t
#148655\t\t\t\t\t
#148550\t\t\t\t\t
#14864B\t\t\t\t\t
#14884B\t\t\t\t\t
#148746\t\t\t\t\t
#148741\t\t\t\t\t
#14863C\t\t\t\t\t
#148737\t\t\t\t\t
#148937\t\t\t\t\t
#148832\t\t\t\t\t
#14882D\t\t\t\t\t
#148728\t\t\t\t\t
#148723\t\t\t\t\t
#148923\t\t\t\t\t
#14881E\t\t\t\t\t
#148819\t\t\t\t\t
#148714\t\t\t\t\t
#148914\t\t\t\t\t
#14890F\t\t\t\t\t
#14890A\t\t\t\t\t
#148800\t\t\t\t\t
#148A00\t\t\t\t\t
#1969FF\t\t\t\t\t
#196BFA\t\t\t\t\t
#196CFF\t\t\t\t\t
#196EFA\t\t\t\t\t
#196EF5\t\t\t\t\t
#196FF0\t\t\t\t\t
#1970F0\t\t\t\t\t
#1970EB\t\t\t\t\t
#1971E6\t\t\t\t\t
#1972E6\t\t\t\t\t
#1972E1\t\t\t\t\t
#1974E1\t\t\t\t\t
#1975DC\t\t\t\t\t
#1976DC\t\t\t\t\t
#1975D2\t\t\t\t\t
#1977D7\t\t\t\t\t
#1976CD\t\t\t\t\t
#1978CD\t\t\t\t\t
#1977C8\t\t\t\t\t
#197AC8\t\t\t\t\t
#1979C3\t\t\t\t\t
#1979BE\t\t\t\t\t
#197BBE\t\t\t\t\t
#197BB9\t\t\t\t\t
#197CB4\t\t\t\t\t
#197CAF\t\t\t\t\t
#197CAA\t\t\t\t\t
#197EAA\t\t\t\t\t
#197DA5\t\t\t\t\t
#197EA0\t\t\t\t\t
#1980A0\t\t\t\t\t
#19809B\t\t\t\t\t
#198096\t\t\t\t\t
#198091\t\t\t\t\t
#19808C\t\t\t\t\t
#19828C\t\t\t\t\t
#198187\t\t\t\t\t
#198182\t\t\t\t\t
#198382\t\t\t\t\t
#19837D\t\t\t\t\t
#198278\t\t\t\t\t
#198478\t\t\t\t\t
#198573\t\t\t\t\t
#19846E\t\t\t\t\t
#198569\t\t\t\t\t
#198464\t\t\t\t\t
#198664\t\t\t\t\t
#19865F\t\t\t\t\t
#19865A\t\t\t\t\t
#198555\t\t\t\t\t
#198550\t\t\t\t\t
#198750\t\t\t\t\t
#19884B\t\t\t\t\t
#198746\t\t\t\t\t
#198641\t\t\t\t\t
#19863C\t\t\t\t\t
#19883C\t\t\t\t\t
#198837\t\t\t\t\t
#198832\t\t\t\t\t
#19872D\t\t\t\t\t
#198728\t\t\t\t\t
#198928\t\t\t\t\t
#198923\t\t\t\t\t
#19881E\t\t\t\t\t
#198719\t\t\t\t\t
#198714\t\t\t\t\t
#198914\t\t\t\t\t
#19880F\t\t\t\t\t
#19880A\t\t\t\t\t
#198705\t\t\t\t\t
#198700\t\t\t\t\t
#198900\t\t\t\t\t
#1E69FF\t\t\t\t\t
#1E6BFA\t\t\t\t\t
#1E6CFF\t\t\t\t\t
#1E6DFA\t\t\t\t\t
#1E6DF5\t\t\t\t\t
#1E6EF0\t\t\t\t\t
#1E6FF5\t\t\t\t\t
#1E70F0\t\t\t\t\t
#1E70E6\t\t\t\t\t
#1E72EB\t\t\t\t\t
#1E72E6\t\t\t\t\t
#1E73E1\t\t\t\t\t
#1E74E1\t\t\t\t\t
#1E75DC\t\t\t\t\t
#1E75D7\t\t\t\t\t
#1E76D2\t\t\t\t\t
#1E76CD\t\t\t\t\t
#1E78CD\t\t\t\t\t
#1E79C8\t\t\t\t\t
#1E79C3\t\t\t\t\t
#1E79BE\t\t\t\t\t
#1E7BBE\t\t\t\t\t
#1E7CB9\t\t\t\t\t
#1E7CB4\t\t\t\t\t
#1E7DB4\t\t\t\t\t
#1E7EAF\t\t\t\t\t
#1E7DAA\t\t\t\t\t
#1E7DA5\t\t\t\t\t
#1E7FA5\t\t\t\t\t
#1E80A0\t\t\t\t\t
#1E7F9B\t\t\t\t\t
#1E7F96\t\t\t\t\t
#1E8091\t\t\t\t\t
#1E8291\t\t\t\t\t
#1E818C\t\t\t\t\t
#1E8287\t\t\t\t\t
#1E8182\t\t\t\t\t
#1E8382\t\t\t\t\t
#1E837D\t\t\t\t\t
#1E8378\t\t\t\t\t
#1E8373\t\t\t\t\t
#1E8573\t\t\t\t\t
#1E856E\t\t\t\t\t
#1E8469\t\t\t\t\t
#1E8464\t\t\t\t\t
#1E8664\t\t\t\t\t
#1E865F\t\t\t\t\t
#1E855A\t\t\t\t\t
#1E8555\t\t\t\t\t
#1E8550\t\t\t\t\t
#1E8750\t\t\t\t\t
#1E864B\t\t\t\t\t
#1E8646\t\t\t\t\t
#1E8641\t\t\t\t\t
#1E8841\t\t\t\t\t
#1E873C\t\t\t\t\t
#1E8737\t\t\t\t\t
#1E8632\t\t\t\t\t
#1E8832\t\t\t\t\t
#1E882D\t\t\t\t\t
#1E8828\t\t\t\t\t
#1E8723\t\t\t\t\t
#1E8923\t\t\t\t\t
#1E891E\t\t\t\t\t
#1E8819\t\t\t\t\t
#1E8714\t\t\t\t\t
#1E870F\t\t\t\t\t
#1E890F\t\t\t\t\t
#1E880A\t\t\t\t\t
#1E8705\t\t\t\t\t
#1E8700\t\t\t\t\t
#1E8900\t\t\t\t\t
#2369FF\t\t\t\t\t
#236AFA\t\t\t\t\t
#236CFA\t\t\t\t\t
#236DFA\t\t\t\t\t
#236EF5\t\t\t\t\t
#236EF0\t\t\t\t\t
#236EEB\t\t\t\t\t
#2370F0\t\t\t\t\t
#2371EB\t\t\t\t\t
#2371E1\t\t\t\t\t
#2373E6\t\t\t\t\t
#2372DC\t\t\t\t\t
#2374E1\t\t\t\t\t
#2375DC\t\t\t\t\t
#2374D2\t\t\t\t\t
#2376D7\t\t\t\t\t
#2376D2\t\t\t\t\t
#2377CD\t\t\t\t\t
#2377C8\t\t\t\t\t
#2378C3\t\t\t\t\t
#2378BE\t\t\t\t\t
#2379BE\t\t\t\t\t
#2379B9\t\t\t\t\t
#237BB9\t\t\t\t\t
#237AB4\t\t\t\t\t
#237BAF\t\t\t\t\t
#237CAF\t\t\t\t\t
#237DAA\t\t\t\t\t
#237DA5\t\t\t\t\t
#237FA5\t\t\t\t\t
#237FA0\t\t\t\t\t
#237F9B\t\t\t\t\t
#237F96\t\t\t\t\t
#237F91\t\t\t\t\t
#238191\t\t\t\t\t
#23828C\t\t\t\t\t
#238187\t\t\t\t\t
#238182\t\t\t\t\t
#23817D\t\t\t\t\t
#23837D\t\t\t\t\t
#238378\t\t\t\t\t
#238373\t\t\t\t\t
#23836E\t\t\t\t\t
#238369\t\t\t\t\t
#238569\t\t\t\t\t
#238464\t\t\t\t\t
#23845F\t\t\t\t\t
#23865F\t\t\t\t\t
#23855A\t\t\t\t\t
#238555\t\t\t\t\t
#238550\t\t\t\t\t
#23854B\t\t\t\t\t
#23874B\t\t\t\t\t
#238646\t\t\t\t\t
#238641\t\t\t\t\t
#23863C\t\t\t\t\t
#23883C\t\t\t\t\t
#238837\t\t\t\t\t
#238732\t\t\t\t\t
#23872D\t\t\t\t\t
#238628\t\t\t\t\t
#238828\t\t\t\t\t
#238823\t\t\t\t\t
#23871E\t\t\t\t\t
#238719\t\t\t\t\t
#238714\t\t\t\t\t
#238914\t\t\t\t\t
#23890F\t\t\t\t\t
#23880A\t\t\t\t\t
#238705\t\t\t\t\t
#238700\t\t\t\t\t
#238900\t\t\t\t\t
#2868FF\t\t\t\t\t
#286BFF\t\t\t\t\t
#286BFA\t\t\t\t\t
#286CF5\t\t\t\t\t
#286DF5\t\t\t\t\t
#286DF0\t\t\t\t\t
#286EEB\t\t\t\t\t
#2870F0\t\t\t\t\t
#2871EB\t\t\t\t\t
#2871E6\t\t\t\t\t
#2872E6\t\t\t\t\t
#2872DC\t\t\t\t\t
#2874DC\t\t\t\t\t
#2874D2\t\t\t\t\t
#2876D7\t\t\t\t\t
#2876D2\t\t\t\t\t
#2876CD\t\t\t\t\t
#2876C8\t\t\t\t\t
#2878C8\t\t\t\t\t
#2879C8\t\t\t\t\t
#2879C3\t\t\t\t\t
#2879BE\t\t\t\t\t
#2879B9\t\t\t\t\t
#287AB4\t\t\t\t\t
#287CB4\t\t\t\t\t
#287CAF\t\t\t\t\t
#287CAA\t\t\t\t\t
#287EAA\t\t\t\t\t
#287EA5\t\t\t\t\t
#287EA0\t\t\t\t\t
#287E9B\t\t\t\t\t
#287E96\t\t\t\t\t
#288096\t\t\t\t\t
#288191\t\t\t\t\t
#28808C\t\t\t\t\t
#288087\t\t\t\t\t
#288287\t\t\t\t\t
#288182\t\t\t\t\t
#28817D\t\t\t\t\t
#28837D\t\t\t\t\t
#288378\t\t\t\t\t
#288273\t\t\t\t\t
#288473\t\t\t\t\t
#28846E\t\t\t\t\t
#288469\t\t\t\t\t
#288464\t\t\t\t\t
#28835F\t\t\t\t\t
#28855F\t\t\t\t\t
#28855A\t\t\t\t\t
#288455\t\t\t\t\t
#288450\t\t\t\t\t
#288650\t\t\t\t\t
#28864B\t\t\t\t\t
#288646\t\t\t\t\t
#288541\t\t\t\t\t
#28853C\t\t\t\t\t
#28873C\t\t\t\t\t
#288637\t\t\t\t\t
#288732\t\t\t\t\t
#28862D\t\t\t\t\t
#288628\t\t\t\t\t
#288828\t\t\t\t\t
#288723\t\t\t\t\t
#28871E\t\t\t\t\t
#288619\t\t\t\t\t
#288614\t\t\t\t\t
#288814\t\t\t\t\t
#28870F\t\t\t\t\t
#28870A\t\t\t\t\t
#288605\t\t\t\t\t
#288600\t\t\t\t\t
#288800\t\t\t\t\t
#2D68FF\t\t\t\t\t
#2D6AFF\t\t\t\t\t
#2D6AFA\t\t\t\t\t
#2D6CFA\t\t\t\t\t
#2D6CF0\t\t\t\t\t
#2D6EF5\t\t\t\t\t
#2D6EF0\t\t\t\t\t
#2D6FEB\t\t\t\t\t
#2D70EB\t\t\t\t\t
#2D71E6\t\t\t\t\t
#2D72E6\t\t\t\t\t
#2D73E1\t\t\t\t\t
#2D73DC\t\t\t\t\t
#2D73D7\t\t\t\t\t
#2D74D2\t\t\t\t\t
#2D76D2\t\t\t\t\t
#2D76CD\t\t\t\t\t
#2D76C8\t\t\t\t\t
#2D77C3\t\t\t\t\t
#2D79C3\t\t\t\t\t
#2D79BE\t\t\t\t\t
#2D7AB9\t\t\t\t\t
#2D7BB9\t\t\t\t\t
#2D7BB4\t\t\t\t\t
#2D7BAF\t\t\t\t\t
#2D7DAF\t\t\t\t\t
#2D7CAA\t\t\t\t\t
#2D7DA5\t\t\t\t\t
#2D7CA0\t\t\t\t\t
#2D7EA0\t\t\t\t\t
#2D7E9B\t\t\t\t\t
#2D7E96\t\t\t\t\t
#2D8096\t\t\t\t\t
#2D8091\t\t\t\t\t
#2D7F8C\t\t\t\t\t
#2D8087\t\t\t\t\t
#2D8287\t\t\t\t\t
#2D8182\t\t\t\t\t
#2D827D\t\t\t\t\t
#2D8178\t\t\t\t\t
#2D8378\t\t\t\t\t
#2D8473\t\t\t\t\t
#2D836E\t\t\t\t\t
#2D8269\t\t\t\t\t
#2D8364\t\t\t\t\t
#2D8564\t\t\t\t\t
#2D845F\t\t\t\t\t
#2D845A\t\t\t\t\t
#2D8455\t\t\t\t\t
#2D8655\t\t\t\t\t
#2D8650\t\t\t\t\t
#2D854B\t\t\t\t\t
#2D8446\t\t\t\t\t
#2D8746\t\t\t\t\t
#2D8641\t\t\t\t\t
#2D853C\t\t\t\t\t
#2D8537\t\t\t\t\t
#2D8737\t\t\t\t\t
#2D8632\t\t\t\t\t
#2D862D\t\t\t\t\t
#2D8628\t\t\t\t\t
#2D8623\t\t\t\t\t
#2D8823\t\t\t\t\t
#2D871E\t\t\t\t\t
#2D8719\t\t\t\t\t
#2D8614\t\t\t\t\t
#2D8814\t\t\t\t\t
#2D880F\t\t\t\t\t
#2D870A\t\t\t\t\t
#2D8605\t\t\t\t\t
#2D8600\t\t\t\t\t
#2D8800\t\t\t\t\t
#3267FF\t\t\t\t\t
#3269FA\t\t\t\t\t
#326AF5\t\t\t\t\t
#326CFA\t\t\t\t\t
#326CF5\t\t\t\t\t
#326DF5\t\t\t\t\t
#326DEB\t\t\t\t\t
#326FEB\t\t\t\t\t
#3270EB\t\t\t\t\t
#3271E6\t\t\t\t\t
#3271E1\t\t\t\t\t
#3272DC\t\t\t\t\t
#3272D7\t\t\t\t\t
#3274D7\t\t\t\t\t
#3275D7\t\t\t\t\t
#3276D2\t\t\t\t\t
#3276CD\t\t\t\t\t
#3275C8\t\t\t\t\t
#3277C8\t\t\t\t\t
#3277C3\t\t\t\t\t
#3279C3\t\t\t\t\t
#3279BE\t\t\t\t\t
#3278B9\t\t\t\t\t
#327AB9\t\t\t\t\t
#327BB4\t\t\t\t\t
#327BAF\t\t\t\t\t
#327CAA\t\t\t\t\t
#327BA5\t\t\t\t\t
#327DA5\t\t\t\t\t
#327DA0\t\t\t\t\t
#327D9B\t\t\t\t\t
#327F9B\t\t\t\t\t
#327F96\t\t\t\t\t
#327E91\t\t\t\t\t
#327F8C\t\t\t\t\t
#32818C\t\t\t\t\t
#328087\t\t\t\t\t
#328182\t\t\t\t\t
#32807D\t\t\t\t\t
#328178\t\t\t\t\t
#328378\t\t\t\t\t
#328273\t\t\t\t\t
#32826E\t\t\t\t\t
#32846E\t\t\t\t\t
#328469\t\t\t\t\t
#328364\t\t\t\t\t
#32835F\t\t\t\t\t
#32835A\t\t\t\t\t
#32855A\t\t\t\t\t
#328455\t\t\t\t\t
#328550\t\t\t\t\t
#32844B\t\t\t\t\t
#328446\t\t\t\t\t
#328646\t\t\t\t\t
#328541\t\t\t\t\t
#32853C\t\t\t\t\t
#32873C\t\t\t\t\t
#328737\t\t\t\t\t
#328632\t\t\t\t\t
#32852D\t\t\t\t\t
#328528\t\t\t\t\t
#328728\t\t\t\t\t
#328723\t\t\t\t\t
#32861E\t\t\t\t\t
#328519\t\t\t\t\t
#328514\t\t\t\t\t
#328714\t\t\t\t\t
#32870F\t\t\t\t\t
#32870A\t\t\t\t\t
#328605\t\t\t\t\t
#328600\t\t\t\t\t
#328800\t\t\t\t\t
#3766FF\t\t\t\t\t
#3769FF\t\t\t\t\t
#3769FA\t\t\t\t\t
#376AFA\t\t\t\t\t
#376BF5\t\t\t\t\t
#376BF0\t\t\t\t\t
#376DF0\t\t\t\t\t
#376DEB\t\t\t\t\t
#376EE6\t\t\t\t\t
#3770E6\t\t\t\t\t
#3770E1\t\t\t\t\t
#3772E1\t\t\t\t\t
#3772DC\t\t\t\t\t
#3771D7\t\t\t\t\t
#3774D7\t\t\t\t\t
#3774D2\t\t\t\t\t
#3775CD\t\t\t\t\t
#3775C8\t\t\t\t\t
#3777C8\t\t\t\t\t
#3778C3\t\t\t\t\t
#3778BE\t\t\t\t\t
#3778B9\t\t\t\t\t
#377AB9\t\t\t\t\t
#3779B4\t\t\t\t\t
#377BB4\t\t\t\t\t
#377BAF\t\t\t\t\t
#377BAA\t\t\t\t\t
#377BA5\t\t\t\t\t
#377DA5\t\t\t\t\t
#377DA0\t\t\t\t\t
#377C9B\t\t\t\t\t
#377E9B\t\t\t\t\t
#377F96\t\t\t\t\t
#377E91\t\t\t\t\t
#377E8C\t\t\t\t\t
#37808C\t\t\t\t\t
#378087\t\t\t\t\t
#378082\t\t\t\t\t
#37807D\t\t\t\t\t
#378078\t\t\t\t\t
#378278\t\t\t\t\t
#378273\t\t\t\t\t
#37826E\t\t\t\t\t
#378169\t\t\t\t\t
#378264\t\t\t\t\t
#378464\t\t\t\t\t
#37835F\t\t\t\t\t
#37835A\t\t\t\t\t
#37855A\t\t\t\t\t
#378455\t\t\t\t\t
#378450\t\t\t\t\t
#37834B\t\t\t\t\t
#378446\t\t\t\t\t
#378646\t\t\t\t\t
#378541\t\t\t\t\t
#37853C\t\t\t\t\t
#378437\t\t\t\t\t
#378432\t\t\t\t\t
#378632\t\t\t\t\t
#37852D\t\t\t\t\t
#378528\t\t\t\t\t
#378728\t\t\t\t\t
#378723\t\t\t\t\t
#37861E\t\t\t\t\t
#378519\t\t\t\t\t
#378514\t\t\t\t\t
#378714\t\t\t\t\t
#37860F\t\t\t\t\t
#37860A\t\t\t\t\t
#378505\t\t\t\t\t
#378500\t\t\t\t\t
#378700\t\t\t\t\t
#3C66FF\t\t\t\t\t
#3C68FF\t\t\t\t\t
#3C68FA\t\t\t\t\t
#3C69F5\t\t\t\t\t
#3C6AF0\t\t\t\t\t
#3C6CF5\t\t\t\t\t
#3C6CEB\t\t\t\t\t
#3C6DEB\t\t\t\t\t
#3C6FEB\t\t\t\t\t
#3C6FE6\t\t\t\t\t
#3C70E6\t\t\t\t\t
#3C70E1\t\t\t\t\t
#3C71DC\t\t\t\t\t
#3C71D7\t\t\t\t\t
#3C73D7\t\t\t\t\t
#3C74D2\t\t\t\t\t
#3C74CD\t\t\t\t\t
#3C76CD\t\t\t\t\t
#3C76C8\t\t\t\t\t
#3C77C8\t\t\t\t\t
#3C76BE\t\t\t\t\t
#3C78BE\t\t\t\t\t
#3C78B9\t\t\t\t\t
#3C79B4\t\t\t\t\t
#3C79AF\t\t\t\t\t
#3C7BAF\t\t\t\t\t
#3C7BAA\t\t\t\t\t
#3C7AA5\t\t\t\t\t
#3C7CA5\t\t\t\t\t
#3C7DA0\t\t\t\t\t
#3C7D9B\t\t\t\t\t
#3C7D96\t\t\t\t\t
#3C7D91\t\t\t\t\t
#3C7F91\t\t\t\t\t
#3C7F8C\t\t\t\t\t
#3C7E87\t\t\t\t\t
#3C8087\t\t\t\t\t
#3C8182\t\t\t\t\t
#3C807D\t\t\t\t\t
#3C8078\t\t\t\t\t
#3C8073\t\t\t\t\t
#3C8273\t\t\t\t\t
#3C826E\t\t\t\t\t
#3C8169\t\t\t\t\t
#3C8369\t\t\t\t\t
#3C8364\t\t\t\t\t
#3C835F\t\t\t\t\t
#3C825A\t\t\t\t\t
#3C8255\t\t\t\t\t
#3C8455\t\t\t\t\t
#3C8350\t\t\t\t\t
#3C834B\t\t\t\t\t
#3C854B\t\t\t\t\t
#3C8546\t\t\t\t\t
#3C8441\t\t\t\t\t
#3C833C\t\t\t\t\t
#3C8437\t\t\t\t\t
#3C8637\t\t\t\t\t
#3C8532\t\t\t\t\t
#3C852D\t\t\t\t\t
#3C8428\t\t\t\t\t
#3C8628\t\t\t\t\t
#3C8623\t\t\t\t\t
#3C851E\t\t\t\t\t
#3C8419\t\t\t\t\t
#3C8414\t\t\t\t\t
#3C8614\t\t\t\t\t
#3C870F\t\t\t\t\t
#3C860A\t\t\t\t\t
#3C8505\t\t\t\t\t
#3C8500\t\t\t\t\t
#3C8700\t\t\t\t\t
#4165FF\t\t\t\t\t
#4167FA\t\t\t\t\t
#4168FF\t\t\t\t\t
#4168F5\t\t\t\t\t
#416AF5\t\t\t\t\t
#416BF5\t\t\t\t\t
#416CF0\t\t\t\t\t
#416CE6\t\t\t\t\t
#416EEB\t\t\t\t\t
#416FE6\t\t\t\t\t
#416FE1\t\t\t\t\t
#4170DC\t\t\t\t\t
#4171DC\t\t\t\t\t
#4171D7\t\t\t\t\t
#4173D7\t\t\t\t\t
#4173D2\t\t\t\t\t
#4173CD\t\t\t\t\t
#4175CD\t\t\t\t\t
#4175C8\t\t\t\t\t
#4174C3\t\t\t\t\t
#4177C3\t\t\t\t\t
#4176BE\t\t\t\t\t
#4176B9\t\t\t\t\t
#4178B9\t\t\t\t\t
#4179B9\t\t\t\t\t
#4178AF\t\t\t\t\t
#417AAF\t\t\t\t\t
#4179A5\t\t\t\t\t
#417AA5\t\t\t\t\t
#417AA0\t\t\t\t\t
#417CA0\t\t\t\t\t
#417C9B\t\t\t\t\t
#417C96\t\t\t\t\t
#417C91\t\t\t\t\t
#417E91\t\t\t\t\t
#417F8C\t\t\t\t\t
#417E87\t\t\t\t\t
#418087\t\t\t\t\t
#418082\t\t\t\t\t
#417F7D\t\t\t\t\t
#417F78\t\t\t\t\t
#418178\t\t\t\t\t
#418173\t\t\t\t\t
#41806E\t\t\t\t\t
#418069\t\t\t\t\t
#418269\t\t\t\t\t
#418364\t\t\t\t\t
#41825F\t\t\t\t\t
#41815A\t\t\t\t\t
#418255\t\t\t\t\t
#418455\t\t\t\t\t
#418450\t\t\t\t\t
#41834B\t\t\t\t\t
#418346\t\t\t\t\t
#418341\t\t\t\t\t
#41833C\t\t\t\t\t
#41853C\t\t\t\t\t
#418537\t\t\t\t\t
#418432\t\t\t\t\t
#41842D\t\t\t\t\t
#418328\t\t\t\t\t
#418528\t\t\t\t\t
#418523\t\t\t\t\t
#41841E\t\t\t\t\t
#418419\t\t\t\t\t
#418619\t\t\t\t\t
#418614\t\t\t\t\t
#41850F\t\t\t\t\t
#41850A\t\t\t\t\t
#418405\t\t\t\t\t
#418400\t\t\t\t\t
#418600\t\t\t\t\t
#4664FF\t\t\t\t\t
#4665FA\t\t\t\t\t
#4667FA\t\t\t\t\t
#4668FA\t\t\t\t\t
#4668F5\t\t\t\t\t
#4669F0\t\t\t\t\t
#466AEB\t\t\t\t\t
#466BEB\t\t\t\t\t
#466BE6\t\t\t\t\t
#466DE6\t\t\t\t\t
#466DE1\t\t\t\t\t
#466FE1\t\t\t\t\t
#466FDC\t\t\t\t\t
#4670D7\t\t\t\t\t
#4671D7\t\t\t\t\t
#4671D2\t\t\t\t\t
#4672D2\t\t\t\t\t
#4673CD\t\t\t\t\t
#4674CD\t\t\t\t\t
#4673C3\t\t\t\t\t
#4674C3\t\t\t\t\t
#4676C3\t\t\t\t\t
#4676BE\t\t\t\t\t
#4676B9\t\t\t\t\t
#4678B9\t\t\t\t\t
#4678B4\t\t\t\t\t
#4677AF\t\t\t\t\t
#467AAF\t\t\t\t\t
#4679AA\t\t\t\t\t
#467AA5\t\t\t\t\t
#4679A0\t\t\t\t\t
#467CA0\t\t\t\t\t
#467B9B\t\t\t\t\t
#467C96\t\t\t\t\t
#467B91\t\t\t\t\t
#467E91\t\t\t\t\t
#467D8C\t\t\t\t\t
#467D87\t\t\t\t\t
#467D82\t\t\t\t\t
#467F82\t\t\t\t\t
#46807D\t\t\t\t\t
#467F78\t\t\t\t\t
#468073\t\t\t\t\t
#467F6E\t\t\t\t\t
#467F69\t\t\t\t\t
#468169\t\t\t\t\t
#468164\t\t\t\t\t
#46805F\t\t\t\t\t
#46815A\t\t\t\t\t
#46835A\t\t\t\t\t
#468355\t\t\t\t\t
#468250\t\t\t\t\t
#46824B\t\t\t\t\t
#46844B\t\t\t\t\t
#468446\t\t\t\t\t
#468341\t\t\t\t\t
#46833C\t\t\t\t\t
#468237\t\t\t\t\t
#468332\t\t\t\t\t
#468532\t\t\t\t\t
#46852D\t\t\t\t\t
#468428\t\t\t\t\t
#468423\t\t\t\t\t
#46831E\t\t\t\t\t
#468319\t\t\t\t\t
#468519\t\t\t\t\t
#468514\t\t\t\t\t
#46840F\t\t\t\t\t
#46840A\t\t\t\t\t
#468305\t\t\t\t\t
#468300\t\t\t\t\t
#468500\t\t\t\t\t
#4B63FF\t\t\t\t\t
#4B65FF\t\t\t\t\t
#4B66FA\t\t\t\t\t
#4B66F5\t\t\t\t\t
#4B68F5\t\t\t\t\t
#4B68F0\t\t\t\t\t
#4B69EB\t\t\t\t\t
#4B6BF0\t\t\t\t\t
#4B6CEB\t\t\t\t\t
#4B6CE6\t\t\t\t\t
#4B6DE1\t\t\t\t\t
#4B6DDC\t\t\t\t\t
#4B6ED7\t\t\t\t\t
#4B70DC\t\t\t\t\t
#4B6FD2\t\t\t\t\t
#4B70D2\t\t\t\t\t
#4B72D2\t\t\t\t\t
#4B73CD\t\t\t\t\t
#4B74C8\t\t\t\t\t
#4B74C3\t\t\t\t\t
#4B75BE\t\t\t\t\t
#4B75B9\t\t\t\t\t
#4B77B9\t\t\t\t\t
#4B77B4\t\t\t\t\t
#4B77AF\t\t\t\t\t
#4B79AF\t\t\t\t\t
#4B79AA\t\t\t\t\t
#4B78A5\t\t\t\t\t
#4B79A0\t\t\t\t\t
#4B7BA0\t\t\t\t\t
#4B7B9B\t\t\t\t\t
#4B7A96\t\t\t\t\t
#4B7B91\t\t\t\t\t
#4B7D91\t\t\t\t\t
#4B7D8C\t\t\t\t\t
#4B7C87\t\t\t\t\t
#4B7C82\t\t\t\t\t
#4B7E82\t\t\t\t\t
#4B7E7D\t\t\t\t\t
#4B7D78\t\t\t\t\t
#4B8078\t\t\t\t\t
#4B7F73\t\t\t\t\t
#4B7F6E\t\t\t\t\t
#4B816E\t\t\t\t\t
#4B8169\t\t\t\t\t
#4B8064\t\t\t\t\t
#4B805F\t\t\t\t\t
#4B825F\t\t\t\t\t
#4B825A\t\t\t\t\t
#4B8155\t\t\t\t\t
#4B8150\t\t\t\t\t
#4B8350\t\t\t\t\t
#4B834B\t\t\t\t\t
#4B8246\t\t\t\t\t
#4B8241\t\t\t\t\t
#4B813C\t\t\t\t\t
#4B843C\t\t\t\t\t
#4B8337\t\t\t\t\t
#4B8332\t\t\t\t\t
#4B822D\t\t\t\t\t
#4B8228\t\t\t\t\t
#4B8428\t\t\t\t\t
#4B8423\t\t\t\t\t
#4B831E\t\t\t\t\t
#4B8319\t\t\t\t\t
#4B8214\t\t\t\t\t
#4B8514\t\t\t\t\t
#4B840F\t\t\t\t\t
#4B840A\t\t\t\t\t
#4B8305\t\t\t\t\t
#4B8300\t\t\t\t\t
#4B8500\t\t\t\t\t
#5064FF\t\t\t\t\t
#5064FA\t\t\t\t\t
#5063FA\t\t\t\t\t
#5066FA\t\t\t\t\t
#5066F5\t\t\t\t\t
#5068F5\t\t\t\t\t
#5068F0\t\t\t\t\t
#5069EB\t\t\t\t\t
#5069E6\t\t\t\t\t
#506BE6\t\t\t\t\t
#506BE1\t\t\t\t\t
#506DE1\t\t\t\t\t
#506DDC\t\t\t\t\t
#506DD7\t\t\t\t\t
#506FD7\t\t\t\t\t
#506ED2\t\t\t\t\t
#5071D2\t\t\t\t\t
#5071CD\t\t\t\t\t
#5072C8\t\t\t\t\t
#5072C3\t\t\t\t\t
#5073BE\t\t\t\t\t
#5075BE\t\t\t\t\t
#5076B9\t\t\t\t\t
#5076B4\t\t\t\t\t
#5075AF\t\t\t\t\t
#5078AF\t\t\t\t\t
#5077AA\t\t\t\t\t
#5077A5\t\t\t\t\t
#5079A5\t\t\t\t\t
#507AA0\t\t\t\t\t
#50799B\t\t\t\t\t
#507996\t\t\t\t\t
#507B96\t\t\t\t\t
#507B91\t\t\t\t\t
#507A8C\t\t\t\t\t
#507D8C\t\t\t\t\t
#507C87\t\t\t\t\t
#507C82\t\t\t\t\t
#507C7D\t\t\t\t\t
#507E7D\t\t\t\t\t
#507F78\t\t\t\t\t
#507E73\t\t\t\t\t
#507F6E\t\t\t\t\t
#507E69\t\t\t\t\t
#507E64\t\t\t\t\t
#508064\t\t\t\t\t
#50805F\t\t\t\t\t
#507F5A\t\t\t\t\t
#50815A\t\t\t\t\t
#508155\t\t\t\t\t
#508050\t\t\t\t\t
#50804B\t\t\t\t\t
#50824B\t\t\t\t\t
#508246\t\t\t\t\t
#508141\t\t\t\t\t
#50813C\t\t\t\t\t
#50833C\t\t\t\t\t
#508337\t\t\t\t\t
#508232\t\t\t\t\t
#50822D\t\t\t\t\t
#508128\t\t\t\t\t
#508328\t\t\t\t\t
#508323\t\t\t\t\t
#50821E\t\t\t\t\t
#508219\t\t\t\t\t
#508419\t\t\t\t\t
#508414\t\t\t\t\t
#50830F\t\t\t\t\t
#50830A\t\t\t\t\t
#508205\t\t\t\t\t
#508200\t\t\t\t\t
#508400\t\t\t\t\t
#5560FF\t\t\t\t\t
#5562FA\t\t\t\t\t
#5563FF\t\t\t\t\t
#5564F5\t\t\t\t\t
#5565FA\t\t\t\t\t
#5567F5\t\t\t\t\t
#5567F0\t\t\t\t\t
#5568F0\t\t\t\t\t
#5568E6\t\t\t\t\t
#556AEB\t\t\t\t\t
#556AE1\t\t\t\t\t
#556BE1\t\t\t\t\t
#556CDC\t\t\t\t\t
#556CD7\t\t\t\t\t
#556DD7\t\t\t\t\t
#556DD2\t\t\t\t\t
#556FD2\t\t\t\t\t
#5570D2\t\t\t\t\t
#5571CD\t\t\t\t\t
#5572C8\t\t\t\t\t
#5572C3\t\t\t\t\t
#5573BE\t\t\t\t\t
#5573B9\t\t\t\t\t
#5574B4\t\t\t\t\t
#5574AF\t\t\t\t\t
#5576AF\t\t\t\t\t
#5575AA\t\t\t\t\t
#5577AA\t\t\t\t\t
#5577A5\t\t\t\t\t
#5579A5\t\t\t\t\t
#5579A0\t\t\t\t\t
#55799B\t\t\t\t\t
#557996\t\t\t\t\t
#557B96\t\t\t\t\t
#557B91\t\t\t\t\t
#557B8C\t\t\t\t\t
#557A87\t\t\t\t\t
#557B82\t\t\t\t\t
#557D82\t\t\t\t\t
#557D7D\t\t\t\t\t
#557D78\t\t\t\t\t
#557D73\t\t\t\t\t
#557D6E\t\t\t\t\t
#557D69\t\t\t\t\t
#557F69\t\t\t\t\t
#557E64\t\t\t\t\t
#557E5F\t\t\t\t\t
#55805F\t\t\t\t\t
#55805A\t\t\t\t\t
#557F55\t\t\t\t\t
#557F50\t\t\t\t\t
#558150\t\t\t\t\t
#55814B\t\t\t\t\t
#558046\t\t\t\t\t
#558041\t\t\t\t\t
#55803C\t\t\t\t\t
#55823C\t\t\t\t\t
#558237\t\t\t\t\t
#558132\t\t\t\t\t
#55812D\t\t\t\t\t
#558028\t\t\t\t\t
#558328\t\t\t\t\t
#558223\t\t\t\t\t
#55811E\t\t\t\t\t
#558119\t\t\t\t\t
#558319\t\t\t\t\t
#558314\t\t\t\t\t
#55820F\t\t\t\t\t
#55820A\t\t\t\t\t
#558105\t\t\t\t\t
#558100\t\t\t\t\t
#558300\t\t\t\t\t
#5A60FF\t\t\t\t\t
#5A61FA\t\t\t\t\t
#5A63FF\t\t\t\t\t
#5A62F5\t\t\t\t\t
#5A65F5\t\t\t\t\t
#5A64F0\t\t\t\t\t
#5A66F0\t\t\t\t\t
#5A66EB\t\t\t\t\t
#5A67E6\t\t\t\t\t
#5A69EB\t\t\t\t\t
#5A6AE6\t\t\t\t\t
#5A6AE1\t\t\t\t\t
#5A6BDC\t\t\t\t\t
#5A6BD7\t\t\t\t\t
#5A6DD7\t\t\t\t\t
#5A6CD2\t\t\t\t\t
#5A6ED2\t\t\t\t\t
#5A6FCD\t\t\t\t\t
#5A6FC8\t\t\t\t\t
#5A70C3\t\t\t\t\t
#5A72C3\t\t\t\t\t
#5A73BE\t\t\t\t\t
#5A73B9\t\t\t\t\t
#5A73B4\t\t\t\t\t
#5A75B4\t\t\t\t\t
#5A75AF\t\t\t\t\t
#5A76AF\t\t\t\t\t
#5A77AA\t\t\t\t\t
#5A76A5\t\t\t\t\t
#5A76A0\t\t\t\t\t
#5A78A0\t\t\t\t\t
#5A799B\t\t\t\t\t
#5A7896\t\t\t\t\t
#5A7891\t\t\t\t\t
#5A7A91\t\t\t\t\t
#5A7A8C\t\t\t\t\t
#5A7A87\t\t\t\t\t
#5A7A82\t\t\t\t\t
#5A7A7D\t\t\t\t\t
#5A7C7D\t\t\t\t\t
#5A7C78\t\t\t\t\t
#5A7B73\t\t\t\t\t
#5A7E73\t\t\t\t\t
#5A7D6E\t\t\t\t\t
#5A7D69\t\t\t\t\t
#5A7C64\t\t\t\t\t
#5A7F64\t\t\t\t\t
#5A7E5F\t\t\t\t\t
#5A7E5A\t\t\t\t\t
#5A7E55\t\t\t\t\t
#5A7E50\t\t\t\t\t
#5A8050\t\t\t\t\t
#5A804B\t\t\t\t\t
#5A8046\t\t\t\t\t
#5A7F41\t\t\t\t\t
#5A7F3C\t\t\t\t\t
#5A813C\t\t\t\t\t
#5A8137\t\t\t\t\t
#5A8032\t\t\t\t\t
#5A802D\t\t\t\t\t
#5A822D\t\t\t\t\t
#5A8128\t\t\t\t\t
#5A8023\t\t\t\t\t
#5A801E\t\t\t\t\t
#5A821E\t\t\t\t\t
#5A8219\t\t\t\t\t
#5A8114\t\t\t\t\t
#5A810F\t\t\t\t\t
#5A800A\t\t\t\t\t
#5A8005\t\t\t\t\t
#5A8205\t\t\t\t\t
#5A8200\t\t\t\t\t
#5F5FFA\t\t\t\t\t
#5F60FF\t\t\t\t\t
#5F61FA\t\t\t\t\t
#5F61F5\t\t\t\t\t
#5F64F5\t\t\t\t\t
#5F63F5\t\t\t\t\t
#5F65F0\t\t\t\t\t
#5F66F0\t\t\t\t\t
#5F68EB\t\t\t\t\t
#5F67E6\t\t\t\t\t
#5F68E1\t\t\t\t\t
#5F69E1\t\t\t\t\t
#5F69DC\t\t\t\t\t
#5F6CDC\t\t\t\t\t
#5F6BD7\t\t\t\t\t
#5F6DD7\t\t\t\t\t
#5F6DD2\t\t\t\t\t
#5F6ED2\t\t\t\t\t
#5F6DC8\t\t\t\t\t
#5F6FC8\t\t\t\t\t
#5F6FC3\t\t\t\t\t
#5F71C3\t\t\t\t\t
#5F71BE\t\t\t\t\t
#5F71B9\t\t\t\t\t
#5F73B9\t\t\t\t\t
#5F73B4\t\t\t\t\t
#5F73AF\t\t\t\t\t
#5F75AF\t\t\t\t\t
#5F75AA\t\t\t\t\t
#5F76AA\t\t\t\t\t
#5F75A0\t\t\t\t\t
#5F759B\t\t\t\t\t
#5F779B\t\t\t\t\t
#5F7796\t\t\t\t\t
#5F7996\t\t\t\t\t
#5F7991\t\t\t\t\t
#5F798C\t\t\t\t\t
#5F7887\t\t\t\t\t
#5F7982\t\t\t\t\t
#5F7B82\t\t\t\t\t
#5F7B7D\t\t\t\t\t
#5F7B78\t\t\t\t\t
#5F7A73\t\t\t\t\t
#5F7B6E\t\t\t\t\t
#5F7B69\t\t\t\t\t
#5F7D69\t\t\t\t\t
#5F7D64\t\t\t\t\t
#5F7C5F\t\t\t\t\t
#5F7C5A\t\t\t\t\t
#5F7C55\t\t\t\t\t
#5F7E55\t\t\t\t\t
#5F7E50\t\t\t\t\t
#5F7D4B\t\t\t\t\t
#5F7D46\t\t\t\t\t
#5F8046\t\t\t\t\t
#5F7F41\t\t\t\t\t
#5F7F3C\t\t\t\t\t
#5F7E37\t\t\t\t\t
#5F7E32\t\t\t\t\t
#5F7E2D\t\t\t\t\t
#5F802D\t\t\t\t\t
#5F7F28\t\t\t\t\t
#5F7F23\t\t\t\t\t
#5F8123\t\t\t\t\t
#5F811E\t\t\t\t\t
#5F8019\t\t\t\t\t
#5F8014\t\t\t\t\t
#5F800F\t\t\t\t\t
#5F7F0A\t\t\t\t\t
#5F7F05\t\t\t\t\t
#5F8105\t\t\t\t\t
#5F8100\t\t\t\t\t
#645DFF\t\t\t\t\t
#645EFA\t\t\t\t\t
#6460FF\t\t\t\t\t
#6460FA\t\t\t\t\t
#6462F5\t\t\t\t\t
#6463F0\t\t\t\t\t
#6464F0\t\t\t\t\t
#6464EB\t\t\t\t\t
#6464E6\t\t\t\t\t
#6466E6\t\t\t\t\t
#6466E1\t\t\t\t\t
#6468E1\t\t\t\t\t
#6468DC\t\t\t\t\t
#646ADC\t\t\t\t\t
#646AD7\t\t\t\t\t
#646BD2\t\t\t\t\t
#646CD2\t\t\t\t\t
#646DCD\t\t\t\t\t
#646ECD\t\t\t\t\t
#646DC3\t\t\t\t\t
#646FC3\t\t\t\t\t
#6470C3\t\t\t\t\t
#646FB9\t\t\t\t\t
#6470B9\t\t\t\t\t
#6472B9\t\t\t\t\t
#6473B4\t\t\t\t\t
#6472AF\t\t\t\t\t
#6472AA\t\t\t\t\t
#6474AA\t\t\t\t\t
#6475A5\t\t\t\t\t
#6475A0\t\t\t\t\t
#64749B\t\t\t\t\t
#64779B\t\t\t\t\t
#647696\t\t\t\t\t
#647791\t\t\t\t\t
#64778C\t\t\t\t\t
#64798C\t\t\t\t\t
#647987\t\t\t\t\t
#647882\t\t\t\t\t
#64787D\t\t\t\t\t
#647A7D\t\t\t\t\t
#647B78\t\t\t\t\t
#647B73\t\t\t\t\t
#647A6E\t\t\t\t\t
#647A69\t\t\t\t\t
#647C69\t\t\t\t\t
#647C64\t\t\t\t\t
#647C5F\t\t\t\t\t
#647B5A\t\t\t\t\t
#647B55\t\t\t\t\t
#647D55\t\t\t\t\t
#647D50\t\t\t\t\t
#647D4B\t\t\t\t\t
#647C46\t\t\t\t\t
#647F46\t\t\t\t\t
#647D41\t\t\t\t\t
#647D3C\t\t\t\t\t
#647D37\t\t\t\t\t
#647F37\t\t\t\t\t
#647F32\t\t\t\t\t
#647E2D\t\t\t\t\t
#647E28\t\t\t\t\t
#647E23\t\t\t\t\t
#648023\t\t\t\t\t
#64801E\t\t\t\t\t
#647F19\t\t\t\t\t
#647F14\t\t\t\t\t
#647F0F\t\t\t\t\t
#647E0A\t\t\t\t\t
#647E05\t\t\t\t\t
#648005\t\t\t\t\t
#648000\t\t\t\t\t
#695BFF\t\t\t\t\t
#695CFA\t\t\t\t\t
#695EFF\t\t\t\t\t
#695EF5\t\t\t\t\t
#6960F5\t\t\t\t\t
#6961F5\t\t\t\t\t
#6962F0\t\t\t\t\t
#6961EB\t\t\t\t\t
#6964EB\t\t\t\t\t
#6964E6\t\t\t\t\t
#6964E1\t\t\t\t\t
#6966E1\t\t\t\t\t
#6966DC\t\t\t\t\t
#6968DC\t\t\t\t\t
#6969D7\t\t\t\t\t
#6969D2\t\t\t\t\t
#696AD2\t\t\t\t\t
#696BCD\t\t\t\t\t
#696BC8\t\t\t\t\t
#696EC8\t\t\t\t\t
#696EC3\t\t\t\t\t
#696DBE\t\t\t\t\t
#6970BE\t\t\t\t\t
#6970B9\t\t\t\t\t
#696FB4\t\t\t\t\t
#6970AF\t\t\t\t\t
#6972AF\t\t\t\t\t
#6972AA\t\t\t\t\t
#6972A5\t\t\t\t\t
#6972A0\t\t\t\t\t
#6974A0\t\t\t\t\t
#69749B\t\t\t\t\t
#697496\t\t\t\t\t
#697696\t\t\t\t\t
#697691\t\t\t\t\t
#69768C\t\t\t\t\t
#69788C\t\t\t\t\t
#697887\t\t\t\t\t
#697782\t\t\t\t\t
#69777D\t\t\t\t\t
#697778\t\t\t\t\t
#697978\t\t\t\t\t
#697973\t\t\t\t\t
#69796E\t\t\t\t\t
#697B6E\t\t\t\t\t
#697B69\t\t\t\t\t
#697B64\t\t\t\t\t
#697A5F\t\t\t\t\t
#697A5A\t\t\t\t\t
#697A55\t\t\t\t\t
#697C55\t\t\t\t\t
#697B50\t\t\t\t\t
#697B4B\t\t\t\t\t
#697D4B\t\t\t\t\t
#697D46\t\t\t\t\t
#697D41\t\t\t\t\t
#697C3C\t\t\t\t\t
#697C37\t\t\t\t\t
#697C32\t\t\t\t\t
#697E32\t\t\t\t\t
#697E2D\t\t\t\t\t
#697D28\t\t\t\t\t
#697D23\t\t\t\t\t
#697C1E\t\t\t\t\t
#697E1E\t\t\t\t\t
#697E19\t\t\t\t\t
#697E14\t\t\t\t\t
#697D0F\t\t\t\t\t
#697D0A\t\t\t\t\t
#697D05\t\t\t\t\t
#697F05\t\t\t\t\t
#697F00\t\t\t\t\t
#6E59FF\t\t\t\t\t
#6E5AFF\t\t\t\t\t
#6E5BFA\t\t\t\t\t
#6E5CF5\t\t\t\t\t
#6E5EF0\t\t\t\t\t
#6E5FF5\t\t\t\t\t
#6E60F0\t\t\t\t\t
#6E61E6\t\t\t\t\t
#6E62EB\t\t\t\t\t
#6E63E6\t\t\t\t\t
#6E64E1\t\t\t\t\t
#6E65DC\t\t\t\t\t
#6E65D7\t\t\t\t\t
#6E66D7\t\t\t\t\t
#6E68D7\t\t\t\t\t
#6E68D2\t\t\t\t\t
#6E69CD\t\t\t\t\t
#6E6BCD\t\t\t\t\t
#6E6AC8\t\t\t\t\t
#6E6AC3\t\t\t\t\t
#6E6DC3\t\t\t\t\t
#6E6DBE\t\t\t\t\t
#6E6CB9\t\t\t\t\t
#6E6FB9\t\t\t\t\t
#6E6FB4\t\t\t\t\t
#6E6EAF\t\t\t\t\t
#6E6FAA\t\t\t\t\t
#6E71AA\t\t\t\t\t
#6E71A5\t\t\t\t\t
#6E73A5\t\t\t\t\t
#6E73A0\t\t\t\t\t
#6E749B\t\t\t\t\t
#6E7396\t\t\t\t\t
#6E7391\t\t\t\t\t
#6E7691\t\t\t\t\t
#6E768C\t\t\t\t\t
#6E7587\t\t\t\t\t
#6E7582\t\t\t\t\t
#6E757D\t\t\t\t\t
#6E777D\t\t\t\t\t
#6E7778\t\t\t\t\t
#6E7773\t\t\t\t\t
#6E7973\t\t\t\t\t
#6E796E\t\t\t\t\t
#6E7969\t\t\t\t\t
#6E7964\t\t\t\t\t
#6E785F\t\t\t\t\t
#6E7B5F\t\t\t\t\t
#6E7B5A\t\t\t\t\t
#6E7A55\t\t\t\t\t
#6E7A50\t\t\t\t\t
#6E7A4B\t\t\t\t\t
#6E7A46\t\t\t\t\t
#6E7C46\t\t\t\t\t
#6E7C41\t\t\t\t\t
#6E7C3C\t\t\t\t\t
#6E7A37\t\t\t\t\t
#6E7D37\t\t\t\t\t
#6E7D32\t\t\t\t\t
#6E7D2D\t\t\t\t\t
#6E7C28\t\t\t\t\t
#6E7C23\t\t\t\t\t
#6E7C1E\t\t\t\t\t
#6E7E1E\t\t\t\t\t
#6E7D19\t\t\t\t\t
#6E7C14\t\t\t\t\t
#6E7E14\t\t\t\t\t
#6E7D0F\t\t\t\t\t
#6E7C0A\t\t\t\t\t
#6E7C05\t\t\t\t\t
#6E7E05\t\t\t\t\t
#6E7E00\t\t\t\t\t
#7357FF\t\t\t\t\t
#7358FF\t\t\t\t\t
#735AFA\t\t\t\t\t
#735BF5\t\t\t\t\t
#735CF5\t\t\t\t\t
#735CF0\t\t\t\t\t
#735EF5\t\t\t\t\t
#7360F0\t\t\t\t\t
#735FE6\t\t\t\t\t
#7361E6\t\t\t\t\t
#7362E6\t\t\t\t\t
#7363E1\t\t\t\t\t
#7362DC\t\t\t\t\t
#7365DC\t\t\t\t\t
#7366DC\t\t\t\t\t
#7367D7\t\t\t\t\t
#7367D2\t\t\t\t\t
#7368D2\t\t\t\t\t
#7367C8\t\t\t\t\t
#7369C8\t\t\t\t\t
#736BC8\t\t\t\t\t
#736ABE\t\t\t\t\t
#736CBE\t\t\t\t\t
#736DBE\t\t\t\t\t
#736CB4\t\t\t\t\t
#736EB4\t\t\t\t\t
#736EAF\t\t\t\t\t
#7370AF\t\t\t\t\t
#7370AA\t\t\t\t\t
#7370A5\t\t\t\t\t
#736FA0\t\t\t\t\t
#7372A0\t\t\t\t\t
#73729B\t\t\t\t\t
#737296\t\t\t\t\t
#737291\t\t\t\t\t
#73728C\t\t\t\t\t
#73758C\t\t\t\t\t
#737487\t\t\t\t\t
#737482\t\t\t\t\t
#73747D\t\t\t\t\t
#73777D\t\t\t\t\t
#737678\t\t\t\t\t
#737673\t\t\t\t\t
#73766E\t\t\t\t\t
#737669\t\t\t\t\t
#737869\t\t\t\t\t
#737864\t\t\t\t\t
#73785F\t\t\t\t\t
#73775A\t\t\t\t\t
#737A5A\t\t\t\t\t
#737A55\t\t\t\t\t
#737A50\t\t\t\t\t
#73794B\t\t\t\t\t
#737846\t\t\t\t\t
#737B46\t\t\t\t\t
#737A41\t\t\t\t\t
#737A3C\t\t\t\t\t
#737A37\t\t\t\t\t
#737A32\t\t\t\t\t
#737C32\t\t\t\t\t
#737B2D\t\t\t\t\t
#737B28\t\t\t\t\t
#737B23\t\t\t\t\t
#737A1E\t\t\t\t\t
#737A19\t\t\t\t\t
#737A14\t\t\t\t\t
#737C14\t\t\t\t\t
#737C0F\t\t\t\t\t
#737C0A\t\t\t\t\t
#737C05\t\t\t\t\t
#737A00\t\t\t\t\t
#737D00\t\t\t\t\t
#7855FF\t\t\t\t\t
#7856FA\t\t\t\t\t
#7858FA\t\t\t\t\t
#7859FA\t\t\t\t\t
#785AF5\t\t\t\t\t
#785BF0\t\t\t\t\t
#785CEB\t\t\t\t\t
#785EF0\t\t\t\t\t
#785DE6\t\t\t\t\t
#785FE1\t\t\t\t\t
#7861E6\t\t\t\t\t
#7861E1\t\t\t\t\t
#7862E1\t\t\t\t\t
#7864DC\t\t\t\t\t
#7864D7\t\t\t\t\t
#7863D2\t\t\t\t\t
#7864CD\t\t\t\t\t
#7866CD\t\t\t\t\t
#7868CD\t\t\t\t\t
#7867C3\t\t\t\t\t
#7868C3\t\t\t\t\t
#7869BE\t\t\t\t\t
#7869B9\t\t\t\t\t
#786BB9\t\t\t\t\t
#786CB9\t\t\t\t\t
#786BAF\t\t\t\t\t
#786DAF\t\t\t\t\t
#786DAA\t\t\t\t\t
#786DA5\t\t\t\t\t
#786FA5\t\t\t\t\t
#786FA0\t\t\t\t\t
#786F9B\t\t\t\t\t
#786F96\t\t\t\t\t
#787196\t\t\t\t\t
#787191\t\t\t\t\t
#78718C\t\t\t\t\t
#787187\t\t\t\t\t
#787487\t\t\t\t\t
#787382\t\t\t\t\t
#78727D\t\t\t\t\t
#78757D\t\t\t\t\t
#787578\t\t\t\t\t
#787473\t\t\t\t\t
#78746E\t\t\t\t\t
#78776E\t\t\t\t\t
#787669\t\t\t\t\t
#787664\t\t\t\t\t
#78755F\t\t\t\t\t
#78785F\t\t\t\t\t
#78785A\t\t\t\t\t
#787855\t\t\t\t\t
#787650\t\t\t\t\t
#787950\t\t\t\t\t
#78794B\t\t\t\t\t
#787946\t\t\t\t\t
#787941\t\t\t\t\t
#78773C\t\t\t\t\t
#787A3C\t\t\t\t\t
#787A37\t\t\t\t\t
#787A32\t\t\t\t\t
#78792D\t\t\t\t\t
#787928\t\t\t\t\t
#787823\t\t\t\t\t
#787B23\t\t\t\t\t
#787A1E\t\t\t\t\t
#787919\t\t\t\t\t
#787914\t\t\t\t\t
#78790F\t\t\t\t\t
#78790A\t\t\t\t\t
#787B0A\t\t\t\t\t
#787B05\t\t\t\t\t
#787B00\t\t\t\t\t
#7D53FF\t\t\t\t\t
#7D55FA\t\t\t\t\t
#7D56F5\t\t\t\t\t
#7D58FA\t\t\t\t\t
#7D58F5\t\t\t\t\t
#7D59F5\t\t\t\t\t
#7D5AF0\t\t\t\t\t
#7D5BEB\t\t\t\t\t
#7D5BE6\t\t\t\t\t
#7D5DE6\t\t\t\t\t
#7D5EE1\t\t\t\t\t
#7D5EDC\t\t\t\t\t
#7D60E1\t\t\t\t\t
#7D60D7\t\t\t\t\t
#7D61D2\t\t\t\t\t
#7D62D2\t\t\t\t\t
#7D65D2\t\t\t\t\t
#7D63CD\t\t\t\t\t
#7D66CD\t\t\t\t\t
#7D65C3\t\t\t\t\t
#7D66C3\t\t\t\t\t
#7D67BE\t\t\t\t\t
#7D69BE\t\t\t\t\t
#7D69B9\t\t\t\t\t
#7D69B4\t\t\t\t\t
#7D6BB4\t\t\t\t\t
#7D6CAF\t\t\t\t\t
#7D6CAA\t\t\t\t\t
#7D6BA5\t\t\t\t\t
#7D6EA5\t\t\t\t\t
#7D6EA0\t\t\t\t\t
#7D6E9B\t\t\t\t\t
#7D6E96\t\t\t\t\t
#7D6E91\t\t\t\t\t
#7D7191\t\t\t\t\t
#7D718C\t\t\t\t\t
#7D7087\t\t\t\t\t
#7D7082\t\t\t\t\t
#7D7382\t\t\t\t\t
#7D737D\t\t\t\t\t
#7D7278\t\t\t\t\t
#7D7273\t\t\t\t\t
#7D7573\t\t\t\t\t
#7D746E\t\t\t\t\t
#7D7369\t\t\t\t\t
#7D7364\t\t\t\t\t
#7D7664\t\t\t\t\t
#7D765F\t\t\t\t\t
#7D765A\t\t\t\t\t
#7D7555\t\t\t\t\t
#7D7550\t\t\t\t\t
#7D754B\t\t\t\t\t
#7D774B\t\t\t\t\t
#7D7646\t\t\t\t\t
#7D7641\t\t\t\t\t
#7D763C\t\t\t\t\t
#7D7637\t\t\t\t\t
#7D7937\t\t\t\t\t
#7D7832\t\t\t\t\t
#7D772D\t\t\t\t\t
#7D792D\t\t\t\t\t
#7D7928\t\t\t\t\t
#7D7923\t\t\t\t\t
#7D791E\t\t\t\t\t
#7D7919\t\t\t\t\t
#7D7914\t\t\t\t\t
#7D780F\t\t\t\t\t
#7D770A\t\t\t\t\t
#7D790A\t\t\t\t\t
#7D7805\t\t\t\t\t
#7D7700\t\t\t\t\t
#7D7A00\t\t\t\t\t
#8250FF\t\t\t\t\t
#8251FA\t\t\t\t\t
#8253FF\t\t\t\t\t
#8254FA\t\t\t\t\t
#8255F5\t\t\t\t\t
#8255F0\t\t\t\t\t
#8258F5\t\t\t\t\t
#8257F0\t\t\t\t\t
#8258EB\t\t\t\t\t
#825AE6\t\t\t\t\t
#825BE6\t\t\t\t\t
#825CE1\t\t\t\t\t
#825DE1\t\t\t\t\t
#825EDC\t\t\t\t\t
#825FD7\t\t\t\t\t
#8260D7\t\t\t\t\t
#8261D2\t\t\t\t\t
#8263D2\t\t\t\t\t
#8264CD\t\t\t\t\t
#8264C8\t\t\t\t\t
#8263C3\t\t\t\t\t
#8265C3\t\t\t\t\t
#8266C3\t\t\t\t\t
#8265B9\t\t\t\t\t
#8268B9\t\t\t\t\t
#8268B4\t\t\t\t\t
#8268AF\t\t\t\t\t
#826AAF\t\t\t\t\t
#826BAA\t\t\t\t\t
#826BA5\t\t\t\t\t
#826BA0\t\t\t\t\t
#826B9B\t\t\t\t\t
#826E9B\t\t\t\t\t
#826E96\t\t\t\t\t
#826D91\t\t\t\t\t
#826D8C\t\t\t\t\t
#826F8C\t\t\t\t\t
#826F87\t\t\t\t\t
#826E82\t\t\t\t\t
#827182\t\t\t\t\t
#82717D\t\t\t\t\t
#827178\t\t\t\t\t
#827173\t\t\t\t\t
#82716E\t\t\t\t\t
#827169\t\t\t\t\t
#827469\t\t\t\t\t
#827464\t\t\t\t\t
#82745F\t\t\t\t\t
#82735A\t\t\t\t\t
#827355\t\t\t\t\t
#827555\t\t\t\t\t
#827550\t\t\t\t\t
#82744B\t\t\t\t\t
#827446\t\t\t\t\t
#827441\t\t\t\t\t
#827741\t\t\t\t\t
#82763C\t\t\t\t\t
#827537\t\t\t\t\t
#827532\t\t\t\t\t
#82752D\t\t\t\t\t
#827528\t\t\t\t\t
#827828\t\t\t\t\t
#827723\t\t\t\t\t
#82761E\t\t\t\t\t
#82781E\t\t\t\t\t
#827719\t\t\t\t\t
#827614\t\t\t\t\t
#82750F\t\t\t\t\t
#82780F\t\t\t\t\t
#82780A\t\t\t\t\t
#827805\t\t\t\t\t
#827800\t\t\t\t\t
#874DFF\t\t\t\t\t
#874FFF\t\t\t\t\t
#8750FF\t\t\t\t\t
#8751FA\t\t\t\t\t
#8752F5\t\t\t\t\t
#8754F0\t\t\t\t\t
#8755EB\t\t\t\t\t
#8756F0\t\t\t\t\t
#8757F0\t\t\t\t\t
#8758EB\t\t\t\t\t
#8758E6\t\t\t\t\t
#8759E1\t\t\t\t\t
#875BE1\t\t\t\t\t
#875CDC\t\t\t\t\t
#875DDC\t\t\t\t\t
#875ED7\t\t\t\t\t
#875ED2\t\t\t\t\t
#8760D2\t\t\t\t\t
#875FC8\t\t\t\t\t
#8762CD\t\t\t\t\t
#8761C3\t\t\t\t\t
#8762C3\t\t\t\t\t
#8762BE\t\t\t\t\t
#8765BE\t\t\t\t\t
#8765B9\t\t\t\t\t
#8765B4\t\t\t\t\t
#8765AF\t\t\t\t\t
#8766AA\t\t\t\t\t
#8768AA\t\t\t\t\t
#8768A5\t\t\t\t\t
#8768A0\t\t\t\t\t
#876BA0\t\t\t\t\t
#876B9B\t\t\t\t\t
#876B96\t\t\t\t\t
#876D96\t\t\t\t\t
#876D91\t\t\t\t\t
#876C8C\t\t\t\t\t
#876C87\t\t\t\t\t
#876F87\t\t\t\t\t
#876F82\t\t\t\t\t
#876F7D\t\t\t\t\t
#876F78\t\t\t\t\t
#876E73\t\t\t\t\t
#877173\t\t\t\t\t
#87716E\t\t\t\t\t
#877069\t\t\t\t\t
#877064\t\t\t\t\t
#877364\t\t\t\t\t
#87725F\t\t\t\t\t
#87725A\t\t\t\t\t
#877155\t\t\t\t\t
#877455\t\t\t\t\t
#877350\t\t\t\t\t
#87734B\t\t\t\t\t
#877346\t\t\t\t\t
#877241\t\t\t\t\t
#877541\t\t\t\t\t
#87743C\t\t\t\t\t
#877437\t\t\t\t\t
#877432\t\t\t\t\t
#87742D\t\t\t\t\t
#877328\t\t\t\t\t
#877628\t\t\t\t\t
#877523\t\t\t\t\t
#87731E\t\t\t\t\t
#87761E\t\t\t\t\t
#877619\t\t\t\t\t
#877614\t\t\t\t\t
#87760F\t\t\t\t\t
#87760A\t\t\t\t\t
#877605\t\t\t\t\t
#877600\t\t\t\t\t
#8C4AFF\t\t\t\t\t
#8C4CFF\t\t\t\t\t
#8C4DFA\t\t\t\t\t
#8C4EF5\t\t\t\t\t
#8C4FF5\t\t\t\t\t
#8C50F0\t\t\t\t\t
#8C52F5\t\t\t\t\t
#8C54F0\t\t\t\t\t
#8C55EB\t\t\t\t\t
#8C56EB\t\t\t\t\t
#8C56E6\t\t\t\t\t
#8C58E1\t\t\t\t\t
#8C58DC\t\t\t\t\t
#8C59DC\t\t\t\t\t
#8C5AD7\t\t\t\t\t
#8C5BD7\t\t\t\t\t
#8C5CD2\t\t\t\t\t
#8C5DD2\t\t\t\t\t
#8C5ECD\t\t\t\t\t
#8C5FCD\t\t\t\t\t
#8C60C8\t\t\t\t\t
#8C61C8\t\t\t\t\t
#8C61BE\t\t\t\t\t
#8C63BE\t\t\t\t\t
#8C64B9\t\t\t\t\t
#8C63B4\t\t\t\t\t
#8C64AF\t\t\t\t\t
#8C64AA\t\t\t\t\t
#8C66AA\t\t\t\t\t
#8C66A5\t\t\t\t\t
#8C66A0\t\t\t\t\t
#8C69A0\t\t\t\t\t
#8C699B\t\t\t\t\t
#8C6996\t\t\t\t\t
#8C6B96\t\t\t\t\t
#8C6B91\t\t\t\t\t
#8C6B8C\t\t\t\t\t
#8C6B87\t\t\t\t\t
#8C6B82\t\t\t\t\t
#8C6B7D\t\t\t\t\t
#8C6E7D\t\t\t\t\t
#8C6E78\t\t\t\t\t
#8C6D73\t\t\t\t\t
#8C6D6E\t\t\t\t\t
#8C706E\t\t\t\t\t
#8C6F69\t\t\t\t\t
#8C6F64\t\t\t\t\t
#8C6E5F\t\t\t\t\t
#8C715F\t\t\t\t\t
#8C715A\t\t\t\t\t
#8C7155\t\t\t\t\t
#8C7050\t\t\t\t\t
#8C704B\t\t\t\t\t
#8C7046\t\t\t\t\t
#8C7346\t\t\t\t\t
#8C7241\t\t\t\t\t
#8C723C\t\t\t\t\t
#8C7237\t\t\t\t\t
#8C7232\t\t\t\t\t
#8C712D\t\t\t\t\t
#8C742D\t\t\t\t\t
#8C7328\t\t\t\t\t
#8C7223\t\t\t\t\t
#8C721E\t\t\t\t\t
#8C7219\t\t\t\t\t
#8C7214\t\t\t\t\t
#8C720F\t\t\t\t\t
#8C750F\t\t\t\t\t
#8C740A\t\t\t\t\t
#8C7305\t\t\t\t\t
#8C7200\t\t\t\t\t
#8C7500\t\t\t\t\t
#9147FF\t\t\t\t\t
#9149FA\t\t\t\t\t
#914AF5\t\t\t\t\t
#914BF5\t\t\t\t\t
#914DFA\t\t\t\t\t
#914EF5\t\t\t\t\t
#914FF5\t\t\t\t\t
#9150F0\t\t\t\t\t
#9151EB\t\t\t\t\t
#9153E6\t\t\t\t\t
#9154E6\t\t\t\t\t
#9155E1\t\t\t\t\t
#9156DC\t\t\t\t\t
#9157DC\t\t\t\t\t
#9158D7\t\t\t\t\t
#9159D7\t\t\t\t\t
#915AD2\t\t\t\t\t
#915BD2\t\t\t\t\t
#915BCD\t\t\t\t\t
#915DCD\t\t\t\t\t
#915EC8\t\t\t\t\t
#915DBE\t\t\t\t\t
#915EBE\t\t\t\t\t
#9160BE\t\t\t\t\t
#9160B9\t\t\t\t\t
#9160B4\t\t\t\t\t
#9163B4\t\t\t\t\t
#9163AF\t\t\t\t\t
#9164AA\t\t\t\t\t
#9164A5\t\t\t\t\t
#9164A0\t\t\t\t\t
#91649B\t\t\t\t\t
#91669B\t\t\t\t\t
#916596\t\t\t\t\t
#916896\t\t\t\t\t
#916891\t\t\t\t\t
#91688C\t\t\t\t\t
#916887\t\t\t\t\t
#916B87\t\t\t\t\t
#916A82\t\t\t\t\t
#916A7D\t\t\t\t\t
#916A78\t\t\t\t\t
#916D78\t\t\t\t\t
#916D73\t\t\t\t\t
#916D6E\t\t\t\t\t
#916C69\t\t\t\t\t
#916C64\t\t\t\t\t
#916F64\t\t\t\t\t
#916E5F\t\t\t\t\t
#916E5A\t\t\t\t\t
#916E55\t\t\t\t\t
#916E50\t\t\t\t\t
#916E4B\t\t\t\t\t
#916E46\t\t\t\t\t
#917146\t\t\t\t\t
#917041\t\t\t\t\t
#91703C\t\t\t\t\t
#917037\t\t\t\t\t
#916F32\t\t\t\t\t
#916F2D\t\t\t\t\t
#91722D\t\t\t\t\t
#917128\t\t\t\t\t
#917023\t\t\t\t\t
#91701E\t\t\t\t\t
#917019\t\t\t\t\t
#917014\t\t\t\t\t
#917314\t\t\t\t\t
#91730F\t\t\t\t\t
#91720A\t\t\t\t\t
#917105\t\t\t\t\t
#917000\t\t\t\t\t
#917300\t\t\t\t\t
#9643FF\t\t\t\t\t
#9645FA\t\t\t\t\t
#9647FF\t\t\t\t\t
#9648FA\t\t\t\t\t
#9649F5\t\t\t\t\t
#964AF0\t\t\t\t\t
#964BEB\t\t\t\t\t
#964DF0\t\t\t\t\t
#964EEB\t\t\t\t\t
#964FEB\t\t\t\t\t
#964FE6\t\t\t\t\t
#9650E1\t\t\t\t\t
#9651DC\t\t\t\t\t
#9653DC\t\t\t\t\t
#9653D7\t\t\t\t\t
#9656DC\t\t\t\t\t
#9655D2\t\t\t\t\t
#9657D2\t\t\t\t\t
#9658CD\t\t\t\t\t
#9659CD\t\t\t\t\t
#965AC8\t\t\t\t\t
#965CC8\t\t\t\t\t
#965ABE\t\t\t\t\t
#965CBE\t\t\t\t\t
#965EBE\t\t\t\t\t
#965EB4\t\t\t\t\t
#965EAF\t\t\t\t\t
#965FAF\t\t\t\t\t
#9661AF\t\t\t\t\t
#9660A5\t\t\t\t\t
#9661A5\t\t\t\t\t
#9664A5\t\t\t\t\t
#9663A0\t\t\t\t\t
#96639B\t\t\t\t\t
#966396\t\t\t\t\t
#966696\t\t\t\t\t
#966691\t\t\t\t\t
#96678C\t\t\t\t\t
#966687\t\t\t\t\t
#966682\t\t\t\t\t
#966982\t\t\t\t\t
#966A7D\t\t\t\t\t
#966978\t\t\t\t\t
#966973\t\t\t\t\t
#96686E\t\t\t\t\t
#966969\t\t\t\t\t
#966C69\t\t\t\t\t
#966B64\t\t\t\t\t
#966B5F\t\t\t\t\t
#966B5A\t\t\t\t\t
#966B55\t\t\t\t\t
#966E55\t\t\t\t\t
#966D50\t\t\t\t\t
#966D4B\t\t\t\t\t
#966D46\t\t\t\t\t
#966C41\t\t\t\t\t
#966F41\t\t\t\t\t
#966F3C\t\t\t\t\t
#966F37\t\t\t\t\t
#966F32\t\t\t\t\t
#966E2D\t\t\t\t\t
#966E28\t\t\t\t\t
#966D23\t\t\t\t\t
#967023\t\t\t\t\t
#966F1E\t\t\t\t\t
#967019\t\t\t\t\t
#967014\t\t\t\t\t
#96700F\t\t\t\t\t
#966F0A\t\t\t\t\t
#966F05\t\t\t\t\t
#966E00\t\t\t\t\t
#967100\t\t\t\t\t
#9B3EFF\t\t\t\t\t
#9B41FA\t\t\t\t\t
#9B42FA\t\t\t\t\t
#9B44FF\t\t\t\t\t
#9B45F5\t\t\t\t\t
#9B46F0\t\t\t\t\t
#9B47F0\t\t\t\t\t
#9B49F5\t\t\t\t\t
#9B4AF0\t\t\t\t\t
#9B4BEB\t\t\t\t\t
#9B4CEB\t\t\t\t\t
#9B4DE6\t\t\t\t\t
#9B4EE1\t\t\t\t\t
#9B4FDC\t\t\t\t\t
#9B50DC\t\t\t\t\t
#9B52D7\t\t\t\t\t
#9B51D2\t\t\t\t\t
#9B53D2\t\t\t\t\t
#9B54CD\t\t\t\t\t
#9B55CD\t\t\t\t\t
#9B57CD\t\t\t\t\t
#9B58C8\t\t\t\t\t
#9B57BE\t\t\t\t\t
#9B58BE\t\t\t\t\t
#9B5ABE\t\t\t\t\t
#9B5AB4\t\t\t\t\t
#9B5CB4\t\t\t\t\t
#9B5EB4\t\t\t\t\t
#9B5CAA\t\t\t\t\t
#9B5EAA\t\t\t\t\t
#9B5EA5\t\t\t\t\t
#9B60A5\t\t\t\t\t
#9B60A0\t\t\t\t\t
#9B5F9B\t\t\t\t\t
#9B6096\t\t\t\t\t
#9B6296\t\t\t\t\t
#9B6191\t\t\t\t\t
#9B6591\t\t\t\t\t
#9B648C\t\t\t\t\t
#9B6587\t\t\t\t\t
#9B6482\t\t\t\t\t
#9B647D\t\t\t\t\t
#9B677D\t\t\t\t\t
#9B6778\t\t\t\t\t
#9B6773\t\t\t\t\t
#9B666E\t\t\t\t\t
#9B6769\t\t\t\t\t
#9B6A69\t\t\t\t\t
#9B6964\t\t\t\t\t
#9B6A5F\t\t\t\t\t
#9B695A\t\t\t\t\t
#9B6955\t\t\t\t\t
#9B6950\t\t\t\t\t
#9B694B\t\t\t\t\t
#9B6C4B\t\t\t\t\t
#9B6B46\t\t\t\t\t
#9B6C41\t\t\t\t\t
#9B6B3C\t\t\t\t\t
#9B6B37\t\t\t\t\t
#9B6A32\t\t\t\t\t
#9B6D32\t\t\t\t\t
#9B6E2D\t\t\t\t\t
#9B6D28\t\t\t\t\t
#9B6D23\t\t\t\t\t
#9B6C1E\t\t\t\t\t
#9B6C19\t\t\t\t\t
#9B6B14\t\t\t\t\t
#9B6E14\t\t\t\t\t
#9B6E0F\t\t\t\t\t
#9B6D0A\t\t\t\t\t
#9B6E05\t\t\t\t\t
#9B6E00\t\t\t\t\t
#A03AFF\t\t\t\t\t
#A03CFA\t\t\t\t\t
#A03EFA\t\t\t\t\t
#A03FFF\t\t\t\t\t
#A040FA\t\t\t\t\t
#A041F5\t\t\t\t\t
#A043F0\t\t\t\t\t
#A045F5\t\t\t\t\t
#A046F0\t\t\t\t\t
#A047F0\t\t\t\t\t
#A048EB\t\t\t\t\t
#A049E6\t\t\t\t\t
#A04AE1\t\t\t\t\t
#A04BE1\t\t\t\t\t
#A04DDC\t\t\t\t\t
#A04EDC\t\t\t\t\t
#A04ED7\t\t\t\t\t
#A050D7\t\t\t\t\t
#A051D2\t\t\t\t\t
#A053D2\t\t\t\t\t
#A053CD\t\t\t\t\t
#A053C3\t\t\t\t\t
#A056C8\t\t\t\t\t
#A055BE\t\t\t\t\t
#A056B9\t\t\t\t\t
#A058B9\t\t\t\t\t
#A05AB9\t\t\t\t\t
#A058AF\t\t\t\t\t
#A05BAF\t\t\t\t\t
#A05CAF\t\t\t\t\t
#A05BA5\t\t\t\t\t
#A05DA5\t\t\t\t\t
#A05EA0\t\t\t\t\t
#A05E9B\t\t\t\t\t
#A05E96\t\t\t\t\t
#A06196\t\t\t\t\t
#A06191\t\t\t\t\t
#A0618C\t\t\t\t\t
#A0638C\t\t\t\t\t
#A06182\t\t\t\t\t
#A06482\t\t\t\t\t
#A0647D\t\t\t\t\t
#A06478\t\t\t\t\t
#A06373\t\t\t\t\t
#A06673\t\t\t\t\t
#A0666E\t\t\t\t\t
#A06569\t\t\t\t\t
#A06564\t\t\t\t\t
#A0655F\t\t\t\t\t
#A0685F\t\t\t\t\t
#A0685A\t\t\t\t\t
#A06755\t\t\t\t\t
#A06750\t\t\t\t\t
#A0674B\t\t\t\t\t
#A06746\t\t\t\t\t
#A06A46\t\t\t\t\t
#A06A41\t\t\t\t\t
#A0693C\t\t\t\t\t
#A06937\t\t\t\t\t
#A06932\t\t\t\t\t
#A0682D\t\t\t\t\t
#A06828\t\t\t\t\t
#A06B28\t\t\t\t\t
#A06C23\t\t\t\t\t
#A06B1E\t\t\t\t\t
#A06B19\t\t\t\t\t
#A06A14\t\t\t\t\t
#A06A0F\t\t\t\t\t
#A0690A\t\t\t\t\t
#A06905\t\t\t\t\t
#A06C05\t\t\t\t\t
#A06C00\t\t\t\t\t
#A534FF\t\t\t\t\t
#A536FA\t\t\t\t\t
#A538FA\t\t\t\t\t
#A539F5\t\t\t\t\t
#A53BF5\t\t\t\t\t
#A53CF5\t\t\t\t\t
#A53EF0\t\t\t\t\t
#A53FEB\t\t\t\t\t
#A541F0\t\t\t\t\t
#A542F0\t\t\t\t\t
#A543EB\t\t\t\t\t
#A545E6\t\t\t\t\t
#A546E1\t\t\t\t\t
#A547E1\t\t\t\t\t
#A548DC\t\t\t\t\t
#A548D7\t\t\t\t\t
#A54AD7\t\t\t\t\t
#A54CD2\t\t\t\t\t
#A54CCD\t\t\t\t\t
#A54ECD\t\t\t\t\t
#A550CD\t\t\t\t\t
#A551CD\t\t\t\t\t
#A552C8\t\t\t\t\t
#A552BE\t\t\t\t\t
#A553BE\t\t\t\t\t
#A555BE\t\t\t\t\t
#A556B9\t\t\t\t\t
#A556B4\t\t\t\t\t
#A558B4\t\t\t\t\t
#A558AF\t\t\t\t\t
#A559AA\t\t\t\t\t
#A559A5\t\t\t\t\t
#A559A0\t\t\t\t\t
#A55A9B\t\t\t\t\t
#A55A96\t\t\t\t\t
#A55C96\t\t\t\t\t
#A55C91\t\t\t\t\t
#A55C8C\t\t\t\t\t
#A55F8C\t\t\t\t\t
#A55F87\t\t\t\t\t
#A55E82\t\t\t\t\t
#A55F7D\t\t\t\t\t
#A5627D\t\t\t\t\t
#A56378\t\t\t\t\t
#A56273\t\t\t\t\t
#A5636E\t\t\t\t\t
#A56369\t\t\t\t\t
#A56264\t\t\t\t\t
#A5625F\t\t\t\t\t
#A5665F\t\t\t\t\t
#A5655A\t\t\t\t\t
#A56555\t\t\t\t\t
#A56550\t\t\t\t\t
#A5654B\t\t\t\t\t
#A56446\t\t\t\t\t
#A56541\t\t\t\t\t
#A5653C\t\t\t\t\t
#A5683C\t\t\t\t\t
#A56837\t\t\t\t\t
#A56832\t\t\t\t\t
#A5672D\t\t\t\t\t
#A56728\t\t\t\t\t
#A56723\t\t\t\t\t
#A5661E\t\t\t\t\t
#A56619\t\t\t\t\t
#A56614\t\t\t\t\t
#A5660F\t\t\t\t\t
#A5690F\t\t\t\t\t
#A5690A\t\t\t\t\t
#A56805\t\t\t\t\t
#A56600\t\t\t\t\t
#A56A00\t\t\t\t\t
#AA2EFF\t\t\t\t\t
#AA31FA\t\t\t\t\t
#AA33FF\t\t\t\t\t
#AA34FA\t\t\t\t\t
#AA35F5\t\t\t\t\t
#AA37FA\t\t\t\t\t
#AA38FA\t\t\t\t\t
#AA3AF0\t\t\t\t\t
#AA3BEB\t\t\t\t\t
#AA3DEB\t\t\t\t\t
#AA3DE6\t\t\t\t\t
#AA3FE1\t\t\t\t\t
#AA41EB\t\t\t\t\t
#AA42E6\t\t\t\t\t
#AA43E1\t\t\t\t\t
#AA45E1\t\t\t\t\t
#AA46DC\t\t\t\t\t
#AA46D2\t\t\t\t\t
#AA49D7\t\t\t\t\t
#AA49CD\t\t\t\t\t
#AA4AC8\t\t\t\t\t
#AA4CC8\t\t\t\t\t
#AA4DC8\t\t\t\t\t
#AA4FC8\t\t\t\t\t
#AA50C3\t\t\t\t\t
#AA4FB9\t\t\t\t\t
#AA51B9\t\t\t\t\t
#AA53B9\t\t\t\t\t
#AA52AF\t\t\t\t\t
#AA53AA\t\t\t\t\t
#AA55AA\t\t\t\t\t
#AA55A5\t\t\t\t\t
#AA57A5\t\t\t\t\t
#AA58A0\t\t\t\t\t
#AA589B\t\t\t\t\t
#AA5896\t\t\t\t\t
#AA5B96\t\t\t\t\t
#AA598C\t\t\t\t\t
#AA5C8C\t\t\t\t\t
#AA5B87\t\t\t\t\t
#AA5E87\t\t\t\t\t
#AA5E82\t\t\t\t\t
#AA5F7D\t\t\t\t\t
#AA5F78\t\t\t\t\t
#AA5F73\t\t\t\t\t
#AA5E6E\t\t\t\t\t
#AA616E\t\t\t\t\t
#AA6169\t\t\t\t\t
#AA6164\t\t\t\t\t
#AA615F\t\t\t\t\t
#AA615A\t\t\t\t\t
#AA6155\t\t\t\t\t
#AA6150\t\t\t\t\t
#AA614B\t\t\t\t\t
#AA644B\t\t\t\t\t
#AA6446\t\t\t\t\t
#AA6441\t\t\t\t\t
#AA643C\t\t\t\t\t
#AA6437\t\t\t\t\t
#AA6332\t\t\t\t\t
#AA632D\t\t\t\t\t
#AA662D\t\t\t\t\t
#AA6628\t\t\t\t\t
#AA6623\t\t\t\t\t
#AA661E\t\t\t\t\t
#AA6619\t\t\t\t\t
#AA6514\t\t\t\t\t
#AA640F\t\t\t\t\t
#AA670F\t\t\t\t\t
#AA670A\t\t\t\t\t
#AA6705\t\t\t\t\t
#AA6700\t\t\t\t\t
#AF25FF\t\t\t\t\t
#AF29FF\t\t\t\t\t
#AF2BFF\t\t\t\t\t
#AF2CFF\t\t\t\t\t
#AF2DF5\t\t\t\t\t
#AF30F0\t\t\t\t\t
#AF31FA\t\t\t\t\t
#AF32F5\t\t\t\t\t
#AF34F0\t\t\t\t\t
#AF36EB\t\t\t\t\t
#AF37EB\t\t\t\t\t
#AF38E6\t\t\t\t\t
#AF3BEB\t\t\t\t\t
#AF3BE1\t\t\t\t\t
#AF3EE6\t\t\t\t\t
#AF3FE1\t\t\t\t\t
#AF40E1\t\t\t\t\t
#AF42DC\t\t\t\t\t
#AF43D7\t\t\t\t\t
#AF44D7\t\t\t\t\t
#AF44D2\t\t\t\t\t
#AF47D2\t\t\t\t\t
#AF48CD\t\t\t\t\t
#AF47C3\t\t\t\t\t
#AF49C3\t\t\t\t\t
#AF4BC3\t\t\t\t\t
#AF4CBE\t\t\t\t\t
#AF4EBE\t\t\t\t\t
#AF4DB4\t\t\t\t\t
#AF4EAF\t\t\t\t\t
#AF50AF\t\t\t\t\t
#AF52AF\t\t\t\t\t
#AF52AA\t\t\t\t\t
#AF54A5\t\t\t\t\t
#AF529B\t\t\t\t\t
#AF549B\t\t\t\t\t
#AF5496\t\t\t\t\t
#AF5796\t\t\t\t\t
#AF5791\t\t\t\t\t
#AF578C\t\t\t\t\t
#AF598C\t\t\t\t\t
#AF5782\t\t\t\t\t
#AF5A82\t\t\t\t\t
#AF5A7D\t\t\t\t\t
#AF5A78\t\t\t\t\t
#AF5B73\t\t\t\t\t
#AF5B6E\t\t\t\t\t
#AF5B69\t\t\t\t\t
#AF5B64\t\t\t\t\t
#AF5F64\t\t\t\t\t
#AF5F5F\t\t\t\t\t
#AF5E5A\t\t\t\t\t
#AF5E55\t\t\t\t\t
#AF5E50\t\t\t\t\t
#AF5E4B\t\t\t\t\t
#AF5E46\t\t\t\t\t
#AF6246\t\t\t\t\t
#AF6241\t\t\t\t\t
#AF623C\t\t\t\t\t
#AF6237\t\t\t\t\t
#AF6132\t\t\t\t\t
#AF622D\t\t\t\t\t
#AF6228\t\t\t\t\t
#AF6223\t\t\t\t\t
#AF621E\t\t\t\t\t
#AF6219\t\t\t\t\t
#AF6114\t\t\t\t\t
#AF600F\t\t\t\t\t
#AF640F\t\t\t\t\t
#AF640A\t\t\t\t\t
#AF6405\t\t\t\t\t
#AF6400\t\t\t\t\t
#B41AFF\t\t\t\t\t
#B41EFA\t\t\t\t\t
#B420FF\t\t\t\t\t
#B422FF\t\t\t\t\t
#B424FA\t\t\t\t\t
#B426F5\t\t\t\t\t
#B428FA\t\t\t\t\t
#B429FA\t\t\t\t\t
#B42BF0\t\t\t\t\t
#B42CF0\t\t\t\t\t
#B42EEB\t\t\t\t\t
#B42FF5\t\t\t\t\t
#B431F0\t\t\t\t\t
#B432EB\t\t\t\t\t
#B434E1\t\t\t\t\t
#B436E1\t\t\t\t\t
#B437DC\t\t\t\t\t
#B439DC\t\t\t\t\t
#B43AD7\t\t\t\t\t
#B43CD7\t\t\t\t\t
#B43DD7\t\t\t\t\t
#B43FD2\t\t\t\t\t
#B440D2\t\t\t\t\t
#B441CD\t\t\t\t\t
#B443CD\t\t\t\t\t
#B443C3\t\t\t\t\t
#B444BE\t\t\t\t\t
#B447C3\t\t\t\t\t
#B448BE\t\t\t\t\t
#B447B4\t\t\t\t\t
#B44AB4\t\t\t\t\t
#B44AAF\t\t\t\t\t
#B44BAA\t\t\t\t\t
#B44EAF\t\t\t\t\t
#B44FAA\t\t\t\t\t
#B450A5\t\t\t\t\t
#B44E9B\t\t\t\t\t
#B4519B\t\t\t\t\t
#B4539B\t\t\t\t\t
#B45291\t\t\t\t\t
#B45591\t\t\t\t\t
#B4568C\t\t\t\t\t
#B45482\t\t\t\t\t
#B4547D\t\t\t\t\t
#B4577D\t\t\t\t\t
#B45678\t\t\t\t\t
#B45773\t\t\t\t\t
#B4586E\t\t\t\t\t
#B45B6E\t\t\t\t\t
#B45864\t\t\t\t\t
#B45C64\t\t\t\t\t
#B45C5F\t\t\t\t\t
#B45D5A\t\t\t\t\t
#B45C55\t\t\t\t\t
#B45D50\t\t\t\t\t
#B45C4B\t\t\t\t\t
#B45D46\t\t\t\t\t
#B45D41\t\t\t\t\t
#B45C3C\t\t\t\t\t
#B45D37\t\t\t\t\t
#B45D32\t\t\t\t\t
#B45D2D\t\t\t\t\t
#B45D28\t\t\t\t\t
#B45D23\t\t\t\t\t
#B45E1E\t\t\t\t\t
#B45E19\t\t\t\t\t
#B45E14\t\t\t\t\t
#B45E0F\t\t\t\t\t
#B45D0A\t\t\t\t\t
#B45D05\t\t\t\t\t
#B46105\t\t\t\t\t
#B46100\t\t\t\t\t
#B903FF\t\t\t\t\t
#B90AFF\t\t\t\t\t
#B90DFA\t\t\t\t\t
#B910FA\t\t\t\t\t
#B912FA\t\t\t\t\t
#B915FA\t\t\t\t\t
#B917FA\t\t\t\t\t
#B919FF\t\t\t\t\t
#B91BF5\t\t\t\t\t
#B91DF5\t\t\t\t\t
#B91FF5\t\t\t\t\t
#B921F0\t\t\t\t\t
#B923EB\t\t\t\t\t
#B925F5\t\t\t\t\t
#B926EB\t\t\t\t\t
#B929F0\t\t\t\t\t
#B92AF0\t\t\t\t\t
#B92CE6\t\t\t\t\t
#B92DE6\t\t\t\t\t
#B930E6\t\t\t\t\t
#B931E6\t\t\t\t\t
#B933E1\t\t\t\t\t
#B934DC\t\t\t\t\t
#B936DC\t\t\t\t\t
#B938D7\t\t\t\t\t
#B939D7\t\t\t\t\t
#B93BD2\t\t\t\t\t
#B93BC8\t\t\t\t\t
#B93EC8\t\t\t\t\t
#B93FC8\t\t\t\t\t
#B93FBE\t\t\t\t\t
#B942BE\t\t\t\t\t
#B942B4\t\t\t\t\t
#B944B4\t\t\t\t\t
#B946B4\t\t\t\t\t
#B947AF\t\t\t\t\t
#B947A5\t\t\t\t\t
#B94AAA\t\t\t\t\t
#B94BA5\t\t\t\t\t
#B94CA0\t\t\t\t\t
#B94D9B\t\t\t\t\t
#B94E96\t\t\t\t\t
#B95096\t\t\t\t\t
#B95191\t\t\t\t\t
#B9528C\t\t\t\t\t
#B95082\t\t\t\t\t
#B95382\t\t\t\t\t
#B9547D\t\t\t\t\t
#B95578\t\t\t\t\t
#B95573\t\t\t\t\t
#B9566E\t\t\t\t\t
#B95669\t\t\t\t\t
#B95764\t\t\t\t\t
#B9585F\t\t\t\t\t
#B9585A\t\t\t\t\t
#B95955\t\t\t\t\t
#B95950\t\t\t\t\t
#B95B4B\t\t\t\t\t
#B95B46\t\t\t\t\t
#B95B41\t\t\t\t\t
#B95C3C\t\t\t\t\t
#B95832\t\t\t\t\t
#B9592D\t\t\t\t\t
#B95928\t\t\t\t\t
#B95923\t\t\t\t\t
#B95A1E\t\t\t\t\t
#B95A19\t\t\t\t\t
#B95A14\t\t\t\t\t
#B95B0F\t\t\t\t\t
#B95D0A\t\t\t\t\t
#B95E05\t\t\t\t\t
#B95E00\t\t\t\t\t
#BE01FA\t\t\t\t\t
#BE03F5\t\t\t\t\t
#BE05F5\t\t\t\t\t
#BE06FF\t\t\t\t\t
#BE08F5\t\t\t\t\t
#BE0CF0\t\t\t\t\t
#BE0DFA\t\t\t\t\t
#BE0FF5\t\t\t\t\t
#BE11FA\t\t\t\t\t
#BE13F5\t\t\t\t\t
#BE16F5\t\t\t\t\t
#BE17F5\t\t\t\t\t
#BE19F5\t\t\t\t\t
#BE1BF0\t\t\t\t\t
#BE1DEB\t\t\t\t\t
#BE1FEB\t\t\t\t\t
#BE21F0\t\t\t\t\t
#BE23E1\t\t\t\t\t
#BE25EB\t\t\t\t\t
#BE27E6\t\t\t\t\t
#BE29E6\t\t\t\t\t
#BE2AE1\t\t\t\t\t
#BE2CDC\t\t\t\t\t
#BE2EDC\t\t\t\t\t
#BE30DC\t\t\t\t\t
#BE31CD\t\t\t\t\t
#BE33CD\t\t\t\t\t
#BE34CD\t\t\t\t\t
#BE36CD\t\t\t\t\t
#BE38C8\t\t\t\t\t
#BE3AC8\t\t\t\t\t
#BE3BBE\t\t\t\t\t
#BE3DBE\t\t\t\t\t
#BE3DB4\t\t\t\t\t
#BE3EB4\t\t\t\t\t
#BE41B4\t\t\t\t\t
#BE43B4\t\t\t\t\t
#BE42A5\t\t\t\t\t
#BE44A5\t\t\t\t\t
#BE46A5\t\t\t\t\t
#BE48A0\t\t\t\t\t
#BE499B\t\t\t\t\t
#BE4891\t\t\t\t\t
#BE498C\t\t\t\t\t
#BE4A87\t\t\t\t\t
#BE4C87\t\t\t\t\t
#BE4D82\t\t\t\t\t
#BE5082\t\t\t\t\t
#BE517D\t\t\t\t\t
#BE5073\t\t\t\t\t
#BE506E\t\t\t\t\t
#BE5169\t\t\t\t\t
#BE5164\t\t\t\t\t
#BE525F\t\t\t\t\t
#BE535A\t\t\t\t\t
#BE5455\t\t\t\t\t
#BE5550\t\t\t\t\t
#BE564B\t\t\t\t\t
#BE5746\t\t\t\t\t
#BE5841\t\t\t\t\t
#BE583C\t\t\t\t\t
#BE5432\t\t\t\t\t
#BE552D\t\t\t\t\t
#BE5528\t\t\t\t\t
#BE5623\t\t\t\t\t
#BE561E\t\t\t\t\t
#BE5719\t\t\t\t\t
#BE5814\t\t\t\t\t
#BE580F\t\t\t\t\t
#BE590A\t\t\t\t\t
#BE5905\t\t\t\t\t
#BE5A00\t\t\t\t\t
#C301F0\t\t\t\t\t
#C303EB\t\t\t\t\t
#C305F0\t\t\t\t\t
#C307EB\t\t\t\t\t
#C309EB\t\t\t\t\t
#C30BEB\t\t\t\t\t
#C30DEB\t\t\t\t\t
#C30FE6\t\t\t\t\t
#C311F0\t\t\t\t\t
#C313EB\t\t\t\t\t
#C314EB\t\t\t\t\t
#C316EB\t\t\t\t\t
#C318EB\t\t\t\t\t
#C31AE1\t\t\t\t\t
#C31CE1\t\t\t\t\t
#C31EDC\t\t\t\t\t
#C320D7\t\t\t\t\t
#C321D7\t\t\t\t\t
#C323D7\t\t\t\t\t
#C325D2\t\t\t\t\t
#C327D2\t\t\t\t\t
#C328CD\t\t\t\t\t
#C32BD7\t\t\t\t\t
#C32CC8\t\t\t\t\t
#C32EC8\t\t\t\t\t
#C32FC8\t\t\t\t\t
#C332C8\t\t\t\t\t
#C334C8\t\t\t\t\t
#C335C8\t\t\t\t\t
#C335B9\t\t\t\t\t
#C337B9\t\t\t\t\t
#C338B9\t\t\t\t\t
#C339AF\t\t\t\t\t
#C33DB4\t\t\t\t\t
#C33CAA\t\t\t\t\t
#C33EAA\t\t\t\t\t
#C340A5\t\t\t\t\t
#C342A5\t\t\t\t\t
#C342A0\t\t\t\t\t
#C3439B\t\t\t\t\t
#C34496\t\t\t\t\t
#C34591\t\t\t\t\t
#C3468C\t\t\t\t\t
#C3488C\t\t\t\t\t
#C34782\t\t\t\t\t
#C3487D\t\t\t\t\t
#C34B7D\t\t\t\t\t
#C34C78\t\t\t\t\t
#C34A6E\t\t\t\t\t
#C34A69\t\t\t\t\t
#C34B64\t\t\t\t\t
#C34F64\t\t\t\t\t
#C34F5F\t\t\t\t\t
#C34F5A\t\t\t\t\t
#C35055\t\t\t\t\t
#C35050\t\t\t\t\t
#C3514B\t\t\t\t\t
#C35246\t\t\t\t\t
#C35241\t\t\t\t\t
#C3523C\t\t\t\t\t
#C35337\t\t\t\t\t
#C35332\t\t\t\t\t
#C3532D\t\t\t\t\t
#C35428\t\t\t\t\t
#C35423\t\t\t\t\t
#C3551E\t\t\t\t\t
#C35619\t\t\t\t\t
#C35514\t\t\t\t\t
#C3550F\t\t\t\t\t
#C3550A\t\t\t\t\t
#C35505\t\t\t\t\t
#C35600\t\t\t\t\t
#C801E6\t\t\t\t\t
#C803E1\t\t\t\t\t
#C805DC\t\t\t\t\t
#C807E6\t\t\t\t\t
#C809E1\t\t\t\t\t
#C80BE1\t\t\t\t\t
#C80CE6\t\t\t\t\t
#C80EE1\t\t\t\t\t
#C810E1\t\t\t\t\t
#C812DC\t\t\t\t\t
#C814D7\t\t\t\t\t
#C816E1\t\t\t\t\t
#C817E1\t\t\t\t\t
#C819DC\t\t\t\t\t
#C81BD7\t\t\t\t\t
#C81DD2\t\t\t\t\t
#C81ED2\t\t\t\t\t
#C820D2\t\t\t\t\t
#C822C8\t\t\t\t\t
#C823C8\t\t\t\t\t
#C826D2\t\t\t\t\t
#C826C3\t\t\t\t\t
#C828BE\t\t\t\t\t
#C829BE\t\t\t\t\t
#C82BBE\t\t\t\t\t
#C82CBE\t\t\t\t\t
#C82EBE\t\t\t\t\t
#C830BE\t\t\t\t\t
#C832BE\t\t\t\t\t
#C832AF\t\t\t\t\t
#C834AF\t\t\t\t\t
#C836AF\t\t\t\t\t
#C835A5\t\t\t\t\t
#C838A5\t\t\t\t\t
#C83BAA\t\t\t\t\t
#C83BA0\t\t\t\t\t
#C83A96\t\t\t\t\t
#C83D9B\t\t\t\t\t
#C83E96\t\t\t\t\t
#C83F91\t\t\t\t\t
#C84191\t\t\t\t\t
#C8428C\t\t\t\t\t
#C84182\t\t\t\t\t
#C84382\t\t\t\t\t
#C84682\t\t\t\t\t
#C84478\t\t\t\t\t
#C84573\t\t\t\t\t
#C8456E\t\t\t\t\t
#C84569\t\t\t\t\t
#C84869\t\t\t\t\t
#C84B69\t\t\t\t\t
#C8495F\t\t\t\t\t
#C84C5F\t\t\t\t\t
#C84955\t\t\t\t\t
#C84D55\t\t\t\t\t
#C84E50\t\t\t\t\t
#C84A46\t\t\t\t\t
#C84F46\t\t\t\t\t
#C84F41\t\t\t\t\t
#C84F3C\t\t\t\t\t
#C85037\t\t\t\t\t
#C84F32\t\t\t\t\t
#C84F2D\t\t\t\t\t
#C85028\t\t\t\t\t
#C85023\t\t\t\t\t
#C84F1E\t\t\t\t\t
#C84F19\t\t\t\t\t
#C85014\t\t\t\t\t
#C8510F\t\t\t\t\t
#C8510A\t\t\t\t\t
#C85205\t\t\t\t\t
#C85200\t\t\t\t\t
#CD01D7\t\t\t\t\t
#CD03D7\t\t\t\t\t
#CD05D2\t\t\t\t\t
#CD06DC\t\t\t\t\t
#CD08D2\t\t\t\t\t
#CD09CD\t\t\t\t\t
#CD0BD7\t\t\t\t\t
#CD0DD2\t\t\t\t\t
#CD0FD2\t\t\t\t\t
#CD11C8\t\t\t\t\t
#CD12D2\t\t\t\t\t
#CD14CD\t\t\t\t\t
#CD16CD\t\t\t\t\t
#CD18C8\t\t\t\t\t
#CD19C3\t\t\t\t\t
#CD1BC3\t\t\t\t\t
#CD1CC3\t\t\t\t\t
#CD1DBE\t\t\t\t\t
#CD1FBE\t\t\t\t\t
#CD22C8\t\t\t\t\t
#CD23C3\t\t\t\t\t
#CD25C3\t\t\t\t\t
#CD26C3\t\t\t\t\t
#CD26B4\t\t\t\t\t
#CD28AF\t\t\t\t\t
#CD2AAF\t\t\t\t\t
#CD2BAF\t\t\t\t\t
#CD2CAF\t\t\t\t\t
#CD2FAF\t\t\t\t\t
#CD31AF\t\t\t\t\t
#CD30A5\t\t\t\t\t
#CD32A5\t\t\t\t\t
#CD329B\t\t\t\t\t
#CD35A0\t\t\t\t\t
#CD3596\t\t\t\t\t
#CD399B\t\t\t\t\t
#CD368C\t\t\t\t\t
#CD3A91\t\t\t\t\t
#CD3C91\t\t\t\t\t
#CD3B87\t\t\t\t\t
#CD3B82\t\t\t\t\t
#CD3B7D\t\t\t\t\t
#CD3E7D\t\t\t\t\t
#CD417D\t\t\t\t\t
#CD3F73\t\t\t\t\t
#CD3F6E\t\t\t\t\t
#CD426E\t\t\t\t\t
#CD4064\t\t\t\t\t
#CD4569\t\t\t\t\t
#CD4664\t\t\t\t\t
#CD435A\t\t\t\t\t
#CD4355\t\t\t\t\t
#CD4350\t\t\t\t\t
#CD434B\t\t\t\t\t
#CD464B\t\t\t\t\t
#CD4646\t\t\t\t\t
#CD4641\t\t\t\t\t
#CD453C\t\t\t\t\t
#CD4537\t\t\t\t\t
#CD4B37\t\t\t\t\t
#CD4B32\t\t\t\t\t
#CD4A2D\t\t\t\t\t
#CD4A28\t\t\t\t\t
#CD4A23\t\t\t\t\t
#CD4A1E\t\t\t\t\t
#CD4919\t\t\t\t\t
#CD4914\t\t\t\t\t
#CD490F\t\t\t\t\t
#CD480A\t\t\t\t\t
#CD4D0A\t\t\t\t\t
#CD4D05\t\t\t\t\t
#CD4D00\t\t\t\t\t
#D201C8\t\t\t\t\t
#D203C8\t\t\t\t\t
#D205BE\t\t\t\t\t
#D206CD\t\t\t\t\t
#D207CD\t\t\t\t\t
#D208C3\t\t\t\t\t
#D20AC3\t\t\t\t\t
#D20CC3\t\t\t\t\t
#D20EBE\t\t\t\t\t
#D20FB9\t\t\t\t\t
#D211C3\t\t\t\t\t
#D212C3\t\t\t\t\t
#D214C3\t\t\t\t\t
#D216BE\t\t\t\t\t
#D217BE\t\t\t\t\t
#D219B9\t\t\t\t\t
#D21BB4\t\t\t\t\t
#D21CB4\t\t\t\t\t
#D21DB4\t\t\t\t\t
#D21FAF\t\t\t\t\t
#D220AA\t\t\t\t\t
#D221AA\t\t\t\t\t
#D222A5\t\t\t\t\t
#D224AA\t\t\t\t\t
#D226A5\t\t\t\t\t
#D225A0\t\t\t\t\t
#D228A5\t\t\t\t\t
#D229A0\t\t\t\t\t
#D22BA5\t\t\t\t\t
#D22DA5\t\t\t\t\t
#D22C96\t\t\t\t\t
#D22F9B\t\t\t\t\t
#D23096\t\t\t\t\t
#D23091\t\t\t\t\t
#D23291\t\t\t\t\t
#D2338C\t\t\t\t\t
#D2358C\t\t\t\t\t
#D23587\t\t\t\t\t
#D2347D\t\t\t\t\t
#D23478\t\t\t\t\t
#D23678\t\t\t\t\t
#D23A7D\t\t\t\t\t
#D2376E\t\t\t\t\t
#D2396E\t\t\t\t\t
#D23B6E\t\t\t\t\t
#D23B69\t\t\t\t\t
#D23B64\t\t\t\t\t
#D23E64\t\t\t\t\t
#D23B5A\t\t\t\t\t
#D23E5A\t\t\t\t\t
#D23E55\t\t\t\t\t
#D24155\t\t\t\t\t
#D23D4B\t\t\t\t\t
#D2414B\t\t\t\t\t
#D24046\t\t\t\t\t
#D24446\t\t\t\t\t
#D24441\t\t\t\t\t
#D23F37\t\t\t\t\t
#D24437\t\t\t\t\t
#D24432\t\t\t\t\t
#D2432D\t\t\t\t\t
#D24128\t\t\t\t\t
#D24123\t\t\t\t\t
#D24723\t\t\t\t\t
#D2461E\t\t\t\t\t
#D24519\t\t\t\t\t
#D24414\t\t\t\t\t
#D2430F\t\t\t\t\t
#D2410A\t\t\t\t\t
#D2470A\t\t\t\t\t
#D24705\t\t\t\t\t
#D24700\t\t\t\t\t
#D701AF\t\t\t\t\t
#D702B9\t\t\t\t\t
#D704AF\t\t\t\t\t
#D705B9\t\t\t\t\t
#D707B4\t\t\t\t\t
#D708AF\t\t\t\t\t
#D70AB4\t\t\t\t\t
#D70BAF\t\t\t\t\t
#D70DAA\t\t\t\t\t
#D70EAA\t\t\t\t\t
#D710B4\t\t\t\t\t
#D711AF\t\t\t\t\t
#D712AA\t\t\t\t\t
#D714AA\t\t\t\t\t
#D715AA\t\t\t\t\t
#D716A0\t\t\t\t\t
#D717A0\t\t\t\t\t
#D718A0\t\t\t\t\t
#D71BAF\t\t\t\t\t
#D71CA5\t\t\t\t\t
#D71EAA\t\t\t\t\t
#D71FAA\t\t\t\t\t
#D721A5\t\t\t\t\t
#D722A5\t\t\t\t\t
#D72091\t\t\t\t\t
#D72291\t\t\t\t\t
#D72491\t\t\t\t\t
#D72591\t\t\t\t\t
#D72691\t\t\t\t\t
#D72891\t\t\t\t\t
#D72991\t\t\t\t\t
#D72782\t\t\t\t\t
#D72A87\t\t\t\t\t
#D72D8C\t\t\t\t\t
#D72B7D\t\t\t\t\t
#D73087\t\t\t\t\t
#D72D78\t\t\t\t\t
#D72F78\t\t\t\t\t
#D73178\t\t\t\t\t
#D73173\t\t\t\t\t
#D7316E\t\t\t\t\t
#D7336E\t\t\t\t\t
#D7356E\t\t\t\t\t
#D73364\t\t\t\t\t
#D73769\t\t\t\t\t
#D7355F\t\t\t\t\t
#D7375F\t\t\t\t\t
#D73455\t\t\t\t\t
#D73755\t\t\t\t\t
#D73650\t\t\t\t\t
#D73950\t\t\t\t\t
#D7394B\t\t\t\t\t
#D73C4B\t\t\t\t\t
#D73841\t\t\t\t\t
#D7373C\t\t\t\t\t
#D73A3C\t\t\t\t\t
#D73937\t\t\t\t\t
#D73832\t\t\t\t\t
#D73C32\t\t\t\t\t
#D73B2D\t\t\t\t\t
#D7402D\t\t\t\t\t
#D73F28\t\t\t\t\t
#D73E23\t\t\t\t\t
#D73D1E\t\t\t\t\t
#D73C19\t\t\t\t\t
#D73A14\t\t\t\t\t
#D74014\t\t\t\t\t
#D73E0F\t\t\t\t\t
#D73D0A\t\t\t\t\t
#D73C05\t\t\t\t\t
#D73B00\t\t\t\t\t
#D74100\t\t\t\t\t
#DC00AF\t\t\t\t\t
#DC029B\t\t\t\t\t
#DC039B\t\t\t\t\t
#DC0596\t\t\t\t\t
#DC06A0\t\t\t\t\t
#DC07A0\t\t\t\t\t
#DC089B\t\t\t\t\t
#DC0A9B\t\t\t\t\t
#DC0B96\t\t\t\t\t
#DC0C91\t\t\t\t\t
#DC0EA5\t\t\t\t\t
#DC0FA0\t\t\t\t\t
#DC10A0\t\t\t\t\t
#DC119B\t\t\t\t\t
#DC1291\t\t\t\t\t
#DC138C\t\t\t\t\t
#DC16A0\t\t\t\t\t
#DC1587\t\t\t\t\t
#DC189B\t\t\t\t\t
#DC199B\t\t\t\t\t
#DC1991\t\t\t\t\t
#DC1B96\t\t\t\t\t
#DC1D96\t\t\t\t\t
#DC1D91\t\t\t\t\t
#DC1C7D\t\t\t\t\t
#DC1D7D\t\t\t\t\t
#DC1E7D\t\t\t\t\t
#DC1F78\t\t\t\t\t
#DC217D\t\t\t\t\t
#DC2482\t\t\t\t\t
#DC2582\t\t\t\t\t
#DC2478\t\t\t\t\t
#DC2678\t\t\t\t\t
#DC256E\t\t\t\t\t
#DC2978\t\t\t\t\t
#DC2669\t\t\t\t\t
#DC2664\t\t\t\t\t
#DC2B6E\t\t\t\t\t
#DC2B69\t\t\t\t\t
#DC295F\t\t\t\t\t
#DC295A\t\t\t\t\t
#DC2B5A\t\t\t\t\t
#DC2A55\t\t\t\t\t
#DC2E5A\t\t\t\t\t
#DC305A\t\t\t\t\t
#DC2D50\t\t\t\t\t
#DC2F50\t\t\t\t\t
#DC3150\t\t\t\t\t
#DC3450\t\t\t\t\t
#DC3046\t\t\t\t\t
#DC2F41\t\t\t\t\t
#DC3241\t\t\t\t\t
#DC313C\t\t\t\t\t
#DC343C\t\t\t\t\t
#DC373C\t\t\t\t\t
#DC3637\t\t\t\t\t
#DC3532\t\t\t\t\t
#DC3832\t\t\t\t\t
#DC372D\t\t\t\t\t
#DC3628\t\t\t\t\t
#DC3323\t\t\t\t\t
#DC311E\t\t\t\t\t
#DC361E\t\t\t\t\t
#DC3419\t\t\t\t\t
#DC3214\t\t\t\t\t
#DC3814\t\t\t\t\t
#DC350F\t\t\t\t\t
#DC320A\t\t\t\t\t
#DC380A\t\t\t\t\t
#DC3605\t\t\t\t\t
#DC3400\t\t\t\t\t
#DC3A00\t\t\t\t\t
#E10096\t\t\t\t\t
#E1027D\t\t\t\t\t
#E1037D\t\t\t\t\t
#E10491\t\t\t\t\t
#E1058C\t\t\t\t\t
#E10687\t\t\t\t\t
#E10782\t\t\t\t\t
#E1087D\t\t\t\t\t
#E10A82\t\t\t\t\t
#E1097D\t\t\t\t\t
#E10C8C\t\t\t\t\t
#E10C87\t\t\t\t\t
#E10E82\t\t\t\t\t
#E10E78\t\t\t\t\t
#E10F78\t\t\t\t\t
#E10F73\t\t\t\t\t
#E11073\t\t\t\t\t
#E11487\t\t\t\t\t
#E11587\t\t\t\t\t
#E1157D\t\t\t\t\t
#E1167D\t\t\t\t\t
#E11882\t\t\t\t\t
#E11982\t\t\t\t\t
#E1197D\t\t\t\t\t
#E11B7D\t\t\t\t\t
#E11B78\t\t\t\t\t
#E11C78\t\t\t\t\t
#E11964\t\t\t\t\t
#E11A64\t\t\t\t\t
#E11D69\t\t\t\t\t
#E11F6E\t\t\t\t\t
#E11B5A\t\t\t\t\t
#E11E5F\t\t\t\t\t
#E12269\t\t\t\t\t
#E11F5A\t\t\t\t\t
#E12364\t\t\t\t\t
#E1225A\t\t\t\t\t
#E12155\t\t\t\t\t
#E12150\t\t\t\t\t
#E12455\t\t\t\t\t
#E12655\t\t\t\t\t
#E12755\t\t\t\t\t
#E12750\t\t\t\t\t
#E12850\t\t\t\t\t
#E1284B\t\t\t\t\t
#E12746\t\t\t\t\t
#E12641\t\t\t\t\t
#E12841\t\t\t\t\t
#E12D46\t\t\t\t\t
#E12C41\t\t\t\t\t
#E12837\t\t\t\t\t
#E12A37\t\t\t\t\t
#E12932\t\t\t\t\t
#E12F37\t\t\t\t\t
#E12E32\t\t\t\t\t
#E12C2D\t\t\t\t\t
#E12B28\t\t\t\t\t
#E12823\t\t\t\t\t
#E12B23\t\t\t\t\t
#E1291E\t\t\t\t\t
#E12D1E\t\t\t\t\t
#E12919\t\t\t\t\t
#E12F19\t\t\t\t\t
#E12A14\t\t\t\t\t
#E13114\t\t\t\t\t
#E12D0F\t\t\t\t\t
#E1280A\t\t\t\t\t
#E12F0A\t\t\t\t\t
#E12A05\t\t\t\t\t
#E13005\t\t\t\t\t
#E12C00\t\t\t\t\t
#E13200\t\t\t\t\t
#E6007D\t\t\t\t\t
#E60173\t\t\t\t\t
#E60264\t\t\t\t\t
#E6025F\t\t\t\t\t
#E6035F\t\t\t\t\t
#E6046E\t\t\t\t\t
#E60564\t\t\t\t\t
#E60550\t\t\t\t\t
#E60773\t\t\t\t\t
#E6075F\t\t\t\t\t
#E6075A\t\t\t\t\t
#E60A6E\t\t\t\t\t
#E6095F\t\t\t\t\t
#E6095A\t\t\t\t\t
#E60950\t\t\t\t\t
#E60D6E\t\t\t\t\t
#E60C5F\t\t\t\t\t
#E60D5A\t\t\t\t\t
#E60C50\t\t\t\t\t
#E60C4B\t\t\t\t\t
#E60C46\t\t\t\t\t
#E60F55\t\t\t\t\t
#E60E4B\t\t\t\t\t
#E60F4B\t\t\t\t\t
#E61150\t\t\t\t\t
#E60F46\t\t\t\t\t
#E61046\t\t\t\t\t
#E6124B\t\t\t\t\t
#E61555\t\t\t\t\t
#E61655\t\t\t\t\t
#E61241\t\t\t\t\t
#E61446\t\t\t\t\t
#E61850\t\t\t\t\t
#E6133C\t\t\t\t\t
#E61746\t\t\t\t\t
#E6153C\t\t\t\t\t
#E61D50\t\t\t\t\t
#E61332\t\t\t\t\t
#E61432\t\t\t\t\t
#E61D46\t\t\t\t\t
#E61C41\t\t\t\t\t
#E61937\t\t\t\t\t
#E61A37\t\t\t\t\t
#E62041\t\t\t\t\t
#E62141\t\t\t\t\t
#E61E37\t\t\t\t\t
#E6223C\t\t\t\t\t
#E61E32\t\t\t\t\t
#E62337\t\t\t\t\t
#E62132\t\t\t\t\t
#E61923\t\t\t\t\t
#E61E28\t\t\t\t\t
#E6242D\t\t\t\t\t
#E62228\t\t\t\t\t
#E61719\t\t\t\t\t
#E61D1E\t\t\t\t\t
#E61A19\t\t\t\t\t
#E61C19\t\t\t\t\t
#E61F19\t\t\t\t\t
#E61B14\t\t\t\t\t
#E62519\t\t\t\t\t
#E6190F\t\t\t\t\t
#E61C0F\t\t\t\t\t
#E6200F\t\t\t\t\t
#E6250F\t\t\t\t\t
#E61E0A\t\t\t\t\t
#E6240A\t\t\t\t\t
#E61C05\t\t\t\t\t
#E62205\t\t\t\t\t
#E61A00\t\t\t\t\t
#E62000\t\t\t\t\t
#E62700\t\t\t\t\t
#EB0050\t\t\t\t\t
#EB0037\t\t\t\t\t
#EB001E\t\t\t\t\t
#EB014B\t\t\t\t\t
#EB0137\t\t\t\t\t
#EB0128\t\t\t\t\t
#EB034B\t\t\t\t\t
#EB0232\t\t\t\t\t
#EB0228\t\t\t\t\t
#EB044B\t\t\t\t\t
#EB043C\t\t\t\t\t
#EB032D\t\t\t\t\t
#EB0114\t\t\t\t\t
#EB0646\t\t\t\t\t
#EB063C\t\t\t\t\t
#EB0428\t\t\t\t\t
#EB031E\t\t\t\t\t
#EB0214\t\t\t\t\t
#EB0841\t\t\t\t\t
#EB062D\t\t\t\t\t
#EB0732\t\t\t\t\t
#EB0523\t\t\t\t\t
#EB0A3C\t\t\t\t\t
#EB0314\t\t\t\t\t
#EB0A37\t\t\t\t\t
#EB0932\t\t\t\t\t
#EB0A32\t\t\t\t\t
#EB0D3C\t\t\t\t\t
#EB0B32\t\t\t\t\t
#EB0E3C\t\t\t\t\t
#EB0F3C\t\t\t\t\t
#EB020A\t\t\t\t\t
#EB0B28\t\t\t\t\t
#EB0D2D\t\t\t\t\t
#EB040F\t\t\t\t\t
#EB0B23\t\t\t\t\t
#EB0D28\t\t\t\t\t
#EB0819\t\t\t\t\t
#EB1232\t\t\t\t\t
#EB0B1E\t\t\t\t\t
#EB122D\t\t\t\t\t
#EB132D\t\t\t\t\t
#EB0D1E\t\t\t\t\t
#EB1023\t\t\t\t\t
#EB1123\t\t\t\t\t
#EB0A14\t\t\t\t\t
#EB050A\t\t\t\t\t
#EB0E19\t\t\t\t\t
#EB0C14\t\t\t\t\t
#EB1019\t\t\t\t\t
#EB0A0F\t\t\t\t\t
#EB1219\t\t\t\t\t
#EB1319\t\t\t\t\t
#EB080A\t\t\t\t\t
#EB1619\t\t\t\t\t
#EB1314\t\t\t\t\t
#EB0505\t\t\t\t\t
#EB1614\t\t\t\t\t
#EB120F\t\t\t\t\t
#EB0705\t\t\t\t\t
#EB170F\t\t\t\t\t
#EB0905\t\t\t\t\t
#EB0100\t\t\t\t\t
#EB0C05\t\t\t\t\t
#EB1005\t\t\t\t\t
#EB1305\t\t\t\t\t
#EB0300\t\t\t\t\t
#EB0600\t\t\t\t\t
#EB0B00\t\t\t\t\t
#EB0F00\t\t\t\t\t
#EB1400\t\t\t\t\t
#EB1800\t\t\t\n
\n
\n\n \n\n \n \n\n\n","content_text":"\n\n\n\n
\n\tSelect a color...\n
\n\n
\n\t
to the target\n\t\t\t\tset #selected-color's innerText to the target's innerText\n\t\t\t\tadd {'--color': the target's innerText} to the #selected-color\n\t\t\t\ttake .active\n\t\t\">\n\t\t<% for (const color of colors) { %>\n\t\t\t
\" title=\"<%= color %>\"><%= color %>\n\t\t<% } %>\n\t\n
\n\n \n\n \n \n\n\n","content_text":"[![<%= it.photo.alt %>](<%= it.photo.src %>){data-img-color-scheme=light}](<%= it.photo.src %>)\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/hyperscript-machine.jpg","date_published":"undefined"},{"id":"/2021/hyperscript-wait-for/","title":"Repost: \"hyperscript 0.0.4 beta is going to be out soon...\"","content_html":"\n\n\n\n\n\nRepost: "hyperscript 0.0.4 beta is going to be out soon..."\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nRepost: "hyperscript 0.0.4 beta is going to be out soon..."\n\n\n\n \n \n \n
Repost: "hyperscript 0.0.4 beta is going to be out soon..."
\n<div _=\"on click add .fade then wait for transitionend then remove\">\n This is a notice. Click to dismiss.\n </div>\n
\n
\n
\n\n \n\n \n \n\n\n","content_text":"
\nhyperscript 0.0.4 beta is going to be out soon\n\na sneak peek:\n\nthe wait command can now pause evaluation until an event is received\n\nhere a class is added, hyperscript waits for the transition to end, then the\nelement is removed\n\nfeature suggested by @DenizAksimsek\n\n
\n<div _=\"on click add .fade then wait for transitionend then remove\">\n This is a notice. Click to dismiss.\n </div>\n
Completing HTML with arbitrary events, replacing fragments instead of the whole page
\n
Your code runs on the server, which you trust
\n
htmx allows for locality of behavior
\n
\n
Consult your doctor to find out if htmx is right for you. Side effects may include arguing about REST on HN.
\n\n\n\nTranscript\n
The year is 2040.
\n
htmx is a W3C recommendation and _hyperscript is an ECMA standard. War has long ceased, API churn is nought but a distant memory.
\n\n
\n
\n\n \n\n \n \n\n\n","content_text":"![Hypertext Man!](/assets/htmx-doodles/hypertext-man.jpeg){data-img-color-scheme=light}\n\n--------------------------------------------------------------------------------\n\n![On HTMX (see transcript)](/assets/htmx-doodles/consult-your-doctor.jpeg){data-img-color-scheme=light}\n\nTranscript\n\n### Server-Side App\n\n-\tFull-page reloads\n-\tHTML only has GET and POST methods\n-\t...and only link clicks & form submissions\n\n### Single-Page App\n\n-\tReinvent the accessible web\n-\tNeed big frameworks or complex code\n-\tProbably need a server anyway for SSR\n-\tThe client is untrueted\n\n### Progressively Enhanced App\n\n-\tTight coupling between server & client code\n-\tBehavior is scattered\n\n### htmx\n\n-\tCompleting HTML with arbitrary events, replacing fragments instead of the whole page\n-\tYour code runs on the server, which you trust\n-\thtmx allows for **locality of behavior**\n\nConsult your doctor to find out if htmx is right for you. Side effects may include arguing about REST on HN.\n\n\n\n--------------------------------------------------------------------------------\n\n![2040 (See transcript)](/assets/htmx-doodles/2040.jpeg){data-img-color-scheme=light}\n\nTranscript\n\nThe year is 2040.\n\nhtmx is a W3C recommendation and _hyperscript is an ECMA standard. War has long ceased, API churn is nought but a distant memory.\n\n\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/htmx-doodles/hypertext-man.jpeg","date_published":"undefined"},{"id":"/2021/js-iota/","title":"Iota (from Golang) in JavaScript","content_html":"\n\n\n\n\n\nIota (from Golang) in JavaScript\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nIota (from Golang) in JavaScript\n\n\n\n \n \n \n
Initially I wasn’t going to bring Go into this at all. However, it turns out enum is a reserved word in JS, so I went with iota for the name of the function, and felt the need to explain it.
\n
Go doesn’t have enums, but an unusual keyword iota:
\n
type Direction int\nconst (\n\tNorth Direction = iota\n\tEast\n\tSouth\n\tWest\n)\n
\n
There’s something subtle going on here. The iota relies on a few Go features:
\n
\n
When multiple const declarations are grouped together, the right hand side is implicitly repeated
\n
Iota is incremented every time it is evaluated, and reset with each const
\n
\n
My JavaScript shorthand is nowhere near as magical… but it does make use of proxies.
\n
\n
function iota(start = 0) {\n\tlet count = start\n\treturn new Proxy({}, {\n\t\tget(o, prop) {\n\t\t\tif (prop in o) return o[prop]\n\t\t\telse return o[prop] = count++\n\t\t}\n\t})\n}\n\nconst { north, east, south, west } = iota()\nconsole.log(north)\n
\n
\n
So, is this function any good?
\n
For one, it lacks some of Go’s iota capabilities — you can’t create bitmasks with this the way you would in Go with 1 << iota. We could augment it a bit by accepting a callback:
\n
function iota(cb = (i => i)) {\n\tlet count = 0\n\treturn new Proxy({}, {\n\t\tget(o, prop) {\n\t\t\tif (prop in o) return o[prop]\n\t\t\telse return o[prop] = cb(count++)\n\t\t}\n\t})\n}\n\n// flag bits\nconst { hasPermissionFlag, userModeFlag, useLegacyProtocolFlag } = iota(i => 1 << i)\nconst hasPermission = options & hasPermissionFlag\n
\n
I don’t think bitmasks are very common at all in JavaScript code, though.
\n
A more significant setback is that you can’t get a list of all the enum values — nothing we can’t fix:
\n
function iota(start = 0) {\n\tlet count = start\n\tlet firstProp = true\n\n\treturn new Proxy({}, {\n\t\tget(o, prop) {\n\t\t\tif (firstProp) {\n\t \t\t\tfirstProp = false\n\t \t\t\treturn { // Enum descriptor\n\t\t\t\t\tget values() { return o }\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prop in o) return o[prop]\n\t\t\telse return o[prop] = count++\n\t\t}\n\t})\n}\n\nconst { Direction, north, east, south, west } = iota()\nconsole.log(Direction)\n
\n
This is open for extension — we could add more methods on the enum description such as converting the integer value of a Direction to its name, or validating a Direction that we parsed from a config file.
\n
I might have a metaprogramming addiction.
\n
\n\n \n\n \n \n \n\n\n","content_text":"([Skip to code](#the-code))\n\n## Enums in Javascript\n\nCurrently, the ways we create enums include\n-\tString literals (see `addEventListener`), which can be typed with TypeScript, but look a bit ugly\n\t~~~ts\n\ttype Direction = 'north' | 'east' | 'south' | 'west'\n\t~~~\n\n-\tTypeScript enums\n\t~~~ts\n\tenum Direction { north, east, south, west }\n\t~~~\n\n-\tInteger constants, IMO your best option if you're not using TypeScript\n\t~~~js\n\tconst Directions = { north: 0, east: 1, south: 2, west: 3 }\n\t~~~\n\n## Enums in Go\n\n Initially I wasn't going to bring Go into this at all. However, it turns out `enum` is a reserved word in JS, so I went with `iota` for the name of the function, and felt the need to explain it.\n\n_Go_ doesn't have enums, but an unusual keyword `iota`:\n\n~~~go\ntype Direction int\nconst (\n\tNorth Direction = iota\n\tEast\n\tSouth\n\tWest\n)\n~~~\n\nThere's something subtle going on here. The iota relies on a few Go features:\n-\tWhen multiple const declarations are grouped together, the right hand side is implicitly repeated\n-\tIota is incremented every time it is evaluated, and reset with each const\n\nMy JavaScript shorthand is nowhere near as magical... but it does make use of proxies.\n\n
\n\n~~~js\nfunction iota(start = 0) {\n\tlet count = start\n\treturn new Proxy({}, {\n\t\tget(o, prop) {\n\t\t\tif (prop in o) return o[prop]\n\t\t\telse return o[prop] = count++\n\t\t}\n\t})\n}\n\nconst { north, east, south, west } = iota()\nconsole.log(north)\n~~~\n\n
\n\nSo, is this function any good?\n\nFor one, it lacks some of Go's `iota` capabilities --- you can't create bitmasks with this the way you would in Go with `1 << iota`. We could augment it a bit by accepting a callback:\n\n~~~js\nfunction iota(cb = (i => i)) {\n\tlet count = 0\n\treturn new Proxy({}, {\n\t\tget(o, prop) {\n\t\t\tif (prop in o) return o[prop]\n\t\t\telse return o[prop] = cb(count++)\n\t\t}\n\t})\n}\n\n// flag bits\nconst { hasPermissionFlag, userModeFlag, useLegacyProtocolFlag } = iota(i => 1 << i)\nconst hasPermission = options & hasPermissionFlag\n~~~\n\nI don't think bitmasks are very common at all in JavaScript code, though.\n\nA more significant setback is that you can't get a list of all the enum values --- nothing we can't fix:\n\n~~~js\nfunction iota(start = 0) {\n\tlet count = start\n\tlet firstProp = true\n\n\treturn new Proxy({}, {\n\t\tget(o, prop) {\n\t\t\tif (firstProp) {\n\t \t\t\tfirstProp = false\n\t \t\t\treturn { // Enum descriptor\n\t\t\t\t\tget values() { return o }\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prop in o) return o[prop]\n\t\t\telse return o[prop] = count++\n\t\t}\n\t})\n}\n\nconst { Direction, north, east, south, west } = iota()\nconsole.log(Direction)\n~~~\n\nThis is open for extension --- we could add more methods on the enum description such as converting the integer value of a Direction to its name, or validating a Direction that we parsed from a config file.\n\nI might have a metaprogramming addiction.\n\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/coffeescript-frontmatter/","title":"Eleventy + Markdown + CoffeeScript = ❤","content_html":"\n\n\n\n\n\nEleventy + Markdown + CoffeeScript = ❤\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nEleventy + Markdown + CoffeeScript = ❤\n\n\n\n \n \n \n
Eleventy + Markdown + CoffeeScript = ❤
\n \n\n \n \n \n\n \n
\n
I’ve started using CoffeeScript instead of YAML for frontmatter, and it works like a dream. Endorsed by Zach Leatherman.
\n
Markdown with Frontmatter
\n
As far as I know, Jekyll is the origin of using a YAML block at the top of a\nMarkdown file for metadata. It’s not hard to imagine why this became popular —\nassociating prose with data is a common use case, and though they have their\nissues, both Markdown and YAML look pretty.* “It looks pretty” is\noften what people really mean when they call something “human-readable”.
\n
Eleventy Frontmatter
\n
Eleventy uses frontmatter blocks (delimited by ---) for all kinds of files. Markdown posts, HTML partials and Nunjucks/EJS/Liquid/… templates can all have them. The data in the frontmatter can then be used in templates. In the following, title is not a reserved name:
\n
---\ntitle: 'A Blog Post'\n---\n\n# {title}\n\nLorem ipsum dolor sit amet...\n\n
\n
We could have used name, heading or kdsad983erj33.
\n\n
Eleventy’s “Computed Data” feature relies on functions in the frontmatter. As YAML doesn’t have functions, you are expected to use JS (well, you can use template strings I guess…):
\n
---js\n{\n title: "My page title",\n eleventyComputed: {\n currentDate: () => new Date().toLocaleString()\n }\n}\n---\n<!doctype html>\n<html>\n--- … -->\n<body>\n <p>This website was last generated on {{ currentDate }}</p>\n <!-- … -->\n
\n
Computed data is cool. Among other things, it allows me to move logic away from my templates and express it in an actual programming language. However JS frontmatter is not very pretty, and I don’t want to convert my whole frontmatter just for one function.
\n
If only there was a language that had the expressive power of JS, and the visually clean data notation of YAML…
\n
CoffeeScript All The Time!
\n
CoffeeScript is actually mentioned in the GitHub repo for gray-matter, the library Eleventy uses to parse frontmatter. Compared to YAML, it’s not much more verbose:
\n
\n\n
---\ntitle: Street sign in İstanbul\ndate: 2020-10-10 19:27:39\ntags: [place, design]\nphoto: /photos/img02.jpeg\ntürkçe: /2020/istanbul-street-sign/\n---\nYAML\n
\n
---\ntitle: 'Street sign in İstanbul'\ndate: '2020-10-10T19:27:39+03:00'\ntags: ['place', 'design']\nphoto: '/photos/img02.jpeg'\ntürkçe: '/2020/istanbul-street-sign/'\n---\nCoffeeScript\n
\n
\n
The CoffeeScript code above is actually fully YAML-compatible! This keeps my templates portable. And with computed data:
\n
---\nlayout: 'layout'\neleventyComputed:\n\tsyndicationLinks: (data) ->\n\t\tDEV: data.devToSyndication[data.page.url]\n---\n\n<article class="h-entry">\n\t<!-- ... -->\n\t{%for silo, link in syndicationLinks%}\n\t\t<a class="u-syndication" href="{{link}}">{{silo}}</a>\n\t\t{%if not loop.last%} | {%endif%}\n\t{%endfor%}\n
\n
I think that computed frontmatter gives a nice balance of logic-less* and\nlogic-full templates. Logicless templates: For people who will never\nneed to make an HTML monthly calendar!
\n
\n\n \n\n \n \n \n\n\n","content_text":"I've started using CoffeeScript instead of YAML for frontmatter, and it works like a dream. [Endorsed by Zach Leatherman][endorsed].\n\n## Markdown with Frontmatter\n\nAs far as I know, Jekyll is the origin of using a YAML block at the top of a\nMarkdown file for metadata. It's not hard to imagine why this became popular ---\nassociating prose with data is a common use case, and though they have their\nissues, both Markdown and YAML look pretty.* :sidenote[\"It looks pretty\" is \noften what people really mean when they call something \"human-readable\".]\n\n## Eleventy Frontmatter\n\nEleventy uses frontmatter blocks (delimited by `---`) for all kinds of files. Markdown posts, HTML partials and Nunjucks/EJS/Liquid/... templates can all have them. The data in the frontmatter can then be used in templates. In the following, `title` is not a reserved name:\n\n~~~\n---\ntitle: 'A Blog Post'\n---\n\n# {title}\n\nLorem ipsum dolor sit amet...\n\n~~~\n\nWe could have used `name`, `heading` or `kdsad983erj33`.\n\n---\n\nEleventy's [\"Computed Data\"][computed-data-docs] feature relies on functions in the frontmatter. As YAML doesn't have functions, you are expected to use JS (well, you can use template strings I guess...):\n\n~~~html\n---js\n{\n title: \"My page title\",\n eleventyComputed: {\n currentDate: () => new Date().toLocaleString()\n }\n}\n---\n\n\n--- … -->\n\n
This website was last generated on {{ currentDate }}
\n \n~~~\n\nComputed data is cool. Among other things, it allows me to move logic away from my templates and express it in an actual programming language. However JS frontmatter is not very pretty, and I don't want to convert my whole frontmatter just for one function.\n\nIf only there was a language that had the expressive power of JS, and the visually clean data notation of YAML...\n\n## CoffeeScript All The Time!\n\nCoffeeScript is actually mentioned in the GitHub repo for `gray-matter`, the library Eleventy uses to parse frontmatter. Compared to YAML, it's not much more verbose:\n\n
\n\n\n\n~~~\n---\ntitle: Street sign in İstanbul\ndate: 2020-10-10 19:27:39\ntags: [place, design]\nphoto: /photos/img02.jpeg\ntürkçe: /2020/istanbul-street-sign/\n---\nYAML\n~~~\n\n~~~\n---\ntitle: 'Street sign in İstanbul'\ndate: '2020-10-10T19:27:39+03:00'\ntags: ['place', 'design']\nphoto: '/photos/img02.jpeg'\ntürkçe: '/2020/istanbul-street-sign/'\n---\nCoffeeScript\n~~~\n\n
\n\nThe CoffeeScript code above is actually fully YAML-compatible! This keeps my templates portable. And with computed data:\n\n~~~liquid\n---\nlayout: 'layout'\neleventyComputed:\n\tsyndicationLinks: (data) ->\n\t\tDEV: data.devToSyndication[data.page.url]\n---\n\n\n\t\n\t{%for silo, link in syndicationLinks%}\n\t\t{{silo}}\n\t\t{%if not loop.last%} | {%endif%}\n\t{%endfor%}\n~~~\n\nI think that computed frontmatter gives a nice balance of logic-less* and\nlogic-full templates. :sidenote[Logicless templates: For people who will never\nneed to make an HTML monthly calendar!]\n\n[endorsed]: https://twitter.com/zachleat/status/1340057504567488513\n[computed-data-docs]:\thttps://www.11ty.dev/docs/data-computed/\n[js-frontmatter-docs]:\thttps://www.11ty.dev/docs/data-frontmatter/#javascript-front-matter\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/istanbul-sokak-tabelasi/","title":"İstanbul'da bir sokak tabelası","content_html":"\n\n\n\n\n\nİstanbul'da bir sokak tabelası\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \t\n \n \n \n\nİstanbul'da bir sokak tabelası\n\n\n\n \n \n \n
Ordu’daki tabelanın olduğu yazıda İstanbul’a yolum düşerse oradakilerin resmini paylaşırım diye yazmıştım. Başka bir şey dileseymişim.
\n
\n
Pandemi yüzünden İstanbul’da gezemedim ama bu tabelaları gerçekte görme fırsatım oldu. Özel tasarım Kent yazıtipi ve ilçe renk kodlarını biliyordum ama tabelaların kabartmalı olduğu fotoğraflarda belli olmuyor.
\n
Bu tabelalar direk üzerinde ama bir çoğu bina duvarları üzerindeydi. Ben şahsen bunun tabelaları bulmayı zorlaştırdığını düşünüyorum. En azından Samsun’daki gibi ağaçlara çakmıyorlar.
\n
\n\n \n\n \n \n\n\n","content_text":"[Ordu'daki tabelanın olduğu yazıda][ordu-street-sign] İstanbul'a yolum düşerse oradakilerin resmini paylaşırım diye yazmıştım. Başka bir şey dileseymişim.\n\n[![<%= it.photo.alt %>](<%= it.photo.src %>)](<%= it.photo.src %>)\n\nPandemi yüzünden İstanbul'da gezemedim ama bu tabelaları gerçekte görme fırsatım oldu. Özel tasarım _Kent_ yazıtipi ve ilçe renk kodlarını biliyordum ama tabelaların kabartmalı olduğu fotoğraflarda belli olmuyor.\n\nBu tabelalar direk üzerinde ama bir çoğu bina duvarları üzerindeydi. Ben şahsen bunun tabelaları bulmayı zorlaştırdığını düşünüyorum. En azından Samsun'daki gibi ağaçlara çakmıyorlar.\n\n[ordu-street-sign]:\t\t/2020/ordu-street-sign/\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/IMG20201007085906-02.jpeg","date_published":"undefined"},{"id":"/2020/istanbul-street-sign/","title":"Street sign in İstanbul","content_html":"\n\n\n\n\n\nStreet sign in İstanbul\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \t\n \n \n \n\nStreet sign in İstanbul\n\n\n\n \n \n \n
I mentioned these signs in my post about the ones in Ordu and said I’d post a picture if I ever went to İstanbul. I think I just wasted my wish.
\n
\n
While I didn’t get to explore İstanbul due to the pandemic, I had an opportunity to see one of these for myself, with the custom-made Kent typeface and the district color codes (as you can see, I was in the lime green Çekmeköy district). When I saw one IRL, I realized that the letters are embossed — this doesn’t show through in photos.
\n
Although these two signs are on a post, many were on the sides of buildings. I don’t like this much as it makes them harder to find. At least they don’t nail them to trees like in Samsun though.
\n
\n\n \n\n \n \n\n\n","content_text":"I mentioned these signs in [my post about the ones in Ordu][ordu-street-sign] and said I'd post a picture if I ever went to İstanbul. I think I just wasted my wish.\n\n[![<%= it.photo.alt %>](<%= it.photo.src %>)](<%= it.photo.src %>)\n\nWhile I didn't get to explore İstanbul due to the pandemic, I had an opportunity to see one of these for myself, with the custom-made _Kent_{lang=tr} typeface and the district color codes (as you can see, I was in the lime green Çekmeköy district). When I saw one IRL, I realized that the letters are embossed --- this doesn't show through in photos.\n\nAlthough these two signs are on a post, many were on the sides of buildings. I don't like this much as it makes them harder to find. At least they don't nail them to trees like in Samsun though.\n\n[ordu-street-sign]:\t\t/2020/ordu-street-sign/\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/IMG20201007085906-02.jpeg","date_published":"undefined"},{"id":"/2020/devto-syndication-links/","title":"Add Syndication Links On Your Personal Site Using Dev.to API","content_html":"\n\n\n\n\n\nAdd Syndication Links On Your Personal Site Using Dev.to API\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nAdd Syndication Links On Your Personal Site Using Dev.to API\n\n\n\n \n \n \n
Add Syndication Links On Your Personal Site Using Dev.to API
\n \n\n \n \n \n\n \n
\n
I recently started using the RSS publishing option to syndicate posts from my personal site to DEV. This allows people to post comments under my posts, many of which might contain useful info. To allow any readers to easily discover and participate in these discussions, I’ve added links to the dev.to copies under my posts.
I could, of course, add these links manually whenever I post, but being armed with such a powerful static site generator as Eleventy, I couldn’t possibly not automate it.
\n
The API and the Data File
\n
Eleventy users will be aware of how easy it is to gather all kinds of data from various APIs and put it in your site, all statically without client-side code. Our task here is exceptionally simple: Pick out the url and canonical_url properties for each article, and create a mapping from the latter to the former.
{%if devToSyndication[page.url]%}\n<section class="syndication-links">\nThis article is syndicated to <a class="u-syndication"\n href="{{devToSyndication[page.url]}}">DEV</a>, where you can comment on it.\n</section>\n{%endif%}\n
\n
Small problem: the page.url property Eleventy provides us is a relative URL, whereas the URLs we got from DEV are absolute.
\n
Sounds like a job for the URL class!
\n
function makeRelativeUrl(url) {\n\tconst urlObj = new URL(url)\n\t// you might want to append url.search and url.hash too\n // but it's unlikely, and a small amount of tech debt is\n // good for the soul\n\treturn urlObj.pathname\n}\n\n...\n({canonical_url, url}) => [makeRelativeUrl(canonical_url), url])\n
\n
Now you should see links on any post that is syndicated to DEV.
\n\n \n\n \n \n \n\n\n","content_text":"I recently started using the [RSS publishing][rsspub] option to syndicate posts from my personal site to DEV. This allows people to post comments under my posts, many of which might contain useful info. To allow any readers to easily discover and participate in these discussions, I've added links to the dev.to copies under my posts.\n\n([Skip to code](#the-code))\n\nI could, of course, add these links manually whenever I post, but being armed with such a powerful static site generator as Eleventy, I couldn't possibly _not_ automate it.\n\n## The API and the Data File\n\nEleventy users will be aware of how easy it is to gather all kinds of data from various APIs and put it in your site, all statically without client-side code. Our task here is exceptionally simple: Pick out the `url` and `canonical_url` properties for each article, and create a mapping from the latter to the former.\n\n~~~js\nconst fetch = require('node-fetch')\n\nmodule.exports = fetch('https://dev.to/api/articles?username=dza')\n .then(res => res.json())\n .then(articles => articles.map(\n ({canonical_url, url}) => [canonical_url, url]))\n .then(Object.fromEntries)\n~~~\n\n**Note:** If you are copy-and-pasting this code, make sure to replace `dza` with your own dev.to username.\n\nThis will give us an object like this:\n\n~~~json\n{\n\t\"https://www.denizaksimsek.com/2020/css-additional-box-shadow/\":\n\t \"https://dev.to/dza/css-adding-additional-box-shadows-2lob\",\n\t...\n}\n~~~\n\nNow let's try using it in our templates:\n\n~~~liquid\n{%if devToSyndication[page.url]%}\n\nThis article is syndicated to DEV, where you can comment on it.\n\n{%endif%}\n~~~\n\nSmall problem: the `page.url` property Eleventy provides us is a relative URL, whereas the URLs we got from DEV are absolute.\n\nSounds like a job for the `URL` class!\n\n~~~js\nfunction makeRelativeUrl(url) {\n\tconst urlObj = new URL(url)\n\t// you might want to append url.search and url.hash too\n // but it's unlikely, and a small amount of tech debt is\n // good for the soul\n\treturn urlObj.pathname\n}\n\n...\n({canonical_url, url}) => [makeRelativeUrl(canonical_url), url])\n~~~\n\nNow you should see links on any post that is syndicated to DEV.\n\n## Appendix: The Final Data File {#the-code}\n\n~~~js\nconst fetch = require('node-fetch')\n\nfunction makeRelativeUrl(url) {\n\tconst urlObj = new URL(url)\n\treturn urlObj.pathname\n}\n\nmodule.exports = fetch('https://dev.to/api/articles?username=dza')\n .then(res => res.json())\n .then(articles => articles.map(\n ({canonical_url, url}) => [makeRelativeUrl(canonical_url), url]))\n .then(Object.fromEntries)\n~~~\n\n[rsspub]: https://dev.to/settings/publishing-from-rss\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/cobanli-pier/","title":"Çobanlı Pier, Samsun, Turkey","content_html":"\n\n\n\n\n\nÇobanlı Pier, Samsun, Turkey\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \t\n \n \n \n\nÇobanlı Pier, Samsun, Turkey\n\n\n\n \n \n \n
Çobanlı Pier, Samsun, Turkey
\n \n\n \n \n \n\n \n
\n
Nothing gets me quite like city lights reflecting off water. Though it’s usually rainwater on asphalt.
\n
\n
\n\n \n\n \n \n\n\n","content_text":"Nothing gets me quite like city lights reflecting off water. Though it's usually rainwater on asphalt.\n\n[![<%= it.photo.alt %>](<%= it.photo.src %>)](<%= it.photo.src %>)\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/IMG20200913191508.jpg","date_published":"undefined"},{"id":"/2020/ordu-street-sign/","title":"A street sign in Ordu","content_html":"\n\n\n\n\n\nA street sign in Ordu\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \t\n \n \n \n\nA street sign in Ordu\n\n\n\n \n \n \n
A street sign in Ordu
\n \n\n \n \n \n\n \n
\n
\n
Street sign in Ordu. The layout seems inspired by street signs in İstanbul, but those are red and lack a garish logo at the bottom, instead featuring the names and color codes of the districts of İstanbul. I should post a photo if I end up going there for some reason. Update 06/01/2021: I did!
\n
\n\n \n\n \n \n\n\n","content_text":"[![<%= it.photo.alt %>](<%= it.photo.src %>)](<%= it.photo.src %>)\n\nStreet sign in Ordu. The layout seems inspired by street signs in İstanbul, but those are red and lack a garish logo at the bottom, instead featuring the names and color codes of the districts of İstanbul. I should post a photo if I end up going there for some reason. Update 06/01/2021: [I did!](https://denizaksimsek.com/2020/istanbul-street-sign/)\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/IMG20200903164220.jpeg","date_published":"undefined"},{"id":"/2020/ardesen-rize-tr/","title":"Ardeşen, Rize, Turkey","content_html":"\n\n\n\n\n\nArdeşen, Rize, Turkey\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \t\n \n \n \n\nArdeşen, Rize, Turkey\n\n\n\n \n \n \n
Ardeşen, Rize, Turkey
\n \n\n \n \n \n\n \n
\n
A few pics from there.
\n
\n
\n
\n
\n\n \n\n \n \n\n\n","content_text":"A few pics from there.\n\n[![<%= it.photo.alt %>](<%= it.photo.src %>)](<%= it.photo.src %>)\n\n[![The dark clouds are painted yellow by the sun, the sea is set ablaze](/assets/photos/IMG20200902180736.jpg)](/assets/photos/IMG20200902180736.jpg)\n\n[![The beach is covered in rocks as far as the eyes can see, and even further](/assets/photos/IMG20200902184220.jpg)](/assets/photos/IMG20200902184220.jpg)\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/assets/photos/IMG20200825184721.jpg","date_published":"undefined"},{"id":"/2020/css-additional-box-shadow/","title":"CSS — Adding Additional Box Shadows","content_html":"\n\n\n\n\n\nCSS — Adding Additional Box Shadows\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nCSS — Adding Additional Box Shadows\n\n\n\n \n \n \n
CSS — Adding Additional Box Shadows
\n \n\n \n \n \n\n \n
\n
When you want to add a box shadow to an element, but don’t want to override any it might already have. (Jump to code)
\n
Less-than-amazing solutions
\n
We could copy the box-shadow property from the element in question, paste it and append our additional shadow at the end. Of course, this requires us to know the box-shadow on the target element, which might not always be possible (say, making a reusable .highlight-glow class).
One drawback is that we cannot use this technique in several classes and apply them to one element. We can solve this problem when parent-var() is a thing in CSS — if it already is by the time you read this post, do let me know!
\n
\n\n \n\n \n \n \n\n\n","content_text":"When you want to add a box shadow to an element, but don't want to override any it might already have. ([Jump to code](#the-code))\n\n## Less-than-amazing solutions\n\nWe could copy the `box-shadow` property from the element in question, paste it and append our additional shadow at the end. Of course, this requires us to know the box-shadow on the target element, which might not always be possible (say, making a reusable `.highlight-glow` class).\n\n[StackOverflow says to put the shadow on an absolutely-positioned pseudo-element](stackoverflow-says). This leaves us with a similar problem to the one we started with --- the element in question might already have styles on the `::before` or `::after` that conflicts with ours.\n\n## My solution {#the-code}\n\nUse CSS variables to apply box shadows.\n\n~~~css\n.shadowy-figure {\n --box-shadow: .5em .5em 1em #333;\n box-shadow: var(--box-shadow);\n}\n~~~\n\nLater on, you can tack things on at the end of this variable, like so:\n\n~~~css\n.highlight {\n box-shadow: var(--box-shadow), 0 0 .1em #fff inset;\n}\n~~~\n\nOne drawback is that we cannot use this technique in several classes and apply them to one element. We can solve this problem when [`parent-var()`](parent-var) is a thing in CSS --- if it already is by the time you read this post, do let me know!\n\n[stackoverflow-says]: https://stackoverflow.com/a/11486224\n[parent-var]: https://lists.w3.org/Archives/Public/www-style/2012Aug/0891.html\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/instant-edit-11ty/","title":"Tip: Instantly Edit Your Eleventy Site on Github","content_html":"\n\n\n\n\n\nTip: Instantly Edit Your Eleventy Site on Github\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nTip: Instantly Edit Your Eleventy Site on Github\n\n\n\n \n \n \n
Tip: Instantly Edit Your Eleventy Site on Github
\n \n\n \n \n \n\n \n
\n
You’re looking at the blog post you made yesterday, when suddenly a typo catches your eye. What is the fastest way to fix it? (Skip to code).
\n
Note: This tip assumes you use GitHub. It could likely be adapted easily for other Git providers.
\n
Add the following to your base layout (note the {{}} and replace <username>/<repo> with the repo for the site):
\n
<script>\n addEventListener('keyup', e => {\n if (e.shiftKey === true) {\n switch (e.keyCode) {\n case 69: // E\n window.location = 'https://github.com/<username>/<repo>/edit/main/{{page.inputPath}}'\n break\n }\n }\n })\n</script>\n
\n
When you press Shift+E, the GitHub editor will open to the current page! The switch statement is there because I used to have a few more hotkeys.
\n
\n\n \n\n \n \n \n\n\n","content_text":"You're looking at the blog post you made yesterday, when suddenly a typo catches your eye. What is the fastest way to fix it? ([Skip to code](#the-code)).\n\n**Note:** This tip assumes you use GitHub. It could likely be adapted easily for other Git providers.\n\nAdd the following to your base layout (note the `{{}}` and replace `/` with the repo for the site):\n\n~~~html\n\n~~~\n\nWhen you press Shift+E, the GitHub editor will open to the current page! The switch statement is there because I used to have a few more hotkeys.\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/11ty-inline-google-fonts/","title":"Eleventy — Dynamically Inlining Google Fonts","content_html":"\n\n\n\n\n\nEleventy — Dynamically Inlining Google Fonts\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nEleventy — Dynamically Inlining Google Fonts\n\n\n\n \n \n \n
Eleventy — Dynamically Inlining Google Fonts
\n \n\n \n \n \n\n \n
\n \n
Update : I have learned since writing this post that this is a bad idea, since Google Fonts will serve different CSS based on the browser. If you want fast loading, vendor your fonts and use <link rel=preload>.
\n\n
All in the name of Lighthouse scores.
\n
When you add Google Fonts to your website by copying the link from the fonts.google.com website, you create a request chain. That is, after loading the HTML of your page, the browser then needs to request a bit of CSS from Google, and only then can it start loading the fonts themselves. A simple solution to this is to copy the CSS returned by Google and paste it into a <style> element in your page. However, I like to change fonts quite frequently, and I’d like to automate this process. This is easy with Eleventy.
\n
A JavaScript data file
\n
We simply fetch the CSS at build time.
\n
// _data/googleFontsStylesheet.js\n\nconst fetch = require('node-fetch')\n\nconst url = 'the URL in the Google Fonts stylesheet link href'\n\nmodule.exports = fetch(url).then(res => res.text())\n
\n\n \n\n \n \n \n\n\n","content_text":"::: Warning :::\n**Update :** I have learned since writing this post that this is a bad idea, since Google Fonts will serve different CSS based on the browser. If you want fast loading, vendor your fonts and use ``{.language-html}.\n:::::::::::::::\n\nAll in the name of Lighthouse scores.\n\nWhen you add Google Fonts to your website by copying the link from the fonts.google.com website, you create a request chain. That is, after loading the HTML of your page, the browser then needs to request a bit of CSS from Google, and only then can it start loading the fonts themselves. A simple solution to this is to copy the CSS returned by Google and paste it into a `\n~~~\n\nEnjoy your improved Lighthouse scores!\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/11ty-layout-as-partial/","title":"Eleventy — Using A Layout As A Partial (The Most Useful Things...)","content_html":"\n\n\n\n\n\nEleventy — Using A Layout As A Partial (The Most Useful Things...)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nEleventy — Using A Layout As A Partial (The Most Useful Things...)\n\n\n\n \n \n \n
Eleventy — Using A Layout As A Partial (The Most Useful Things...)
\n \n\n \n \n \n\n \n
\n \n
Update 2021-02-08: This article mentions things about my website that are no longer true. The technique explained, however, still works fine.
\n\n
On this website, I have both a Notes page and pages for each individual note. I wanted to use the same template for both, but I ran into an issue: accessing frontmatter data.
\n
In Eleventy, frontmatter data for the current page is merged into the data cascade and made available on the template global scope, whereas collection items have a data property. This made it hard to write templates that work with both the page object and collection items.
\n
Solution
\n\n
\n
[…] the most useful things are usually cloaked in an air of nonchalance, even in documentation.
The solution to my problem was right there in the Eleventy docs, staring at me, its description phrased such that it couldn’t possibly be of use to anyone.
\n\n
\n
Also getCollectionItem
\n
For completeness, a getCollectionItem filter is also included that fetches the current page from a collection.
When using note.njk as a partial, the caller assigns the variable note. When using it as a layout, no such variable will exist and the default (d()) will be used… The beauty of this configuration is that in both situations, item will be a collection item with a data property.
\n
One caveat is that because I’m using this as a partial, I can’t use frontmatter, and therefore can’t set a layout for my layout (maybe I could use template data files…). Instead, I use Nunjucks’ builtin template inheritance.
\n\n \n\n \n \n \n\n\n","content_text":"::: Warning ::: \n**Update 2021-02-08:** This article mentions things about my website that are no longer true. The technique explained, however, still works fine.\n:::::::::::::::\n\nOn this website, I have both a Notes page and pages for each individual note. I wanted to use the same template for both, but I ran into an issue: accessing frontmatter data.\n\nIn Eleventy, frontmatter data for the current page is merged into the [data cascade][] and made available on the template global scope, whereas collection items have a `data` property. This made it hard to write templates that work with both the `page` object and collection items.\n\n## Solution\n\n::: fig\n> [...] the most useful things are usually cloaked in an air of nonchalance, even in documentation.\n\n\n\t— YouTube user\n\tBantu Tu,\n\tcommenting on\n\tMissing Semester: Lecture 3: Editors (vim) (2020)\n\t\n\n:::\n\nThe solution to my problem was right there in the Eleventy docs, staring at me, its description phrased such that it couldn't possibly be of use to anyone.\n\n::: fig\n> ### Also `getCollectionItem`\n>\n> For completeness, a `getCollectionItem` filter is also included that fetches the current page from a collection.\n\n— Eleventy docs\n:::\n\nWith this filter, all my problems were solved. I prepended the following to my `note.njk` template (similarly for `post.njk`):\n\n~~~liquid\n{%set item = note | d(collections.note | getCollectionItem(page))%}\n~~~\n\nWhen using `note.njk` as a partial, the caller assigns the variable `note`. When using it as a layout, no such variable will exist and the default (`d()`) will be used.. The beauty of this configuration is that in both situations, `item` will be a collection item with a `data` property.\n\nOne caveat is that because I'm using this as a partial, I can't use frontmatter, and therefore can't set a layout for my layout (maybe I could use template data files...). Instead, I use Nunjucks' builtin [template inheritance][].\n\n~~~liquid\n{%if not note%}\n{%extends \"base.njk\"%}\n{%endif%}\n...\n{%block content%}\n{%set item = note | d(collections.note | getCollectionItem(page))%}\n...\n{%endblock%}\n~~~\n\n[data cascade]: https://www.11ty.dev/docs/data-cascade/\n[Bantu Tu]: https://www.youtube.com/channel/UCjknfwYaYZvv94AjL10NO0Q\n[missing-semester]: https://www.youtube.com/watch?v=a6Q8Na575qc\n[Eleventy docs]: https://www.11ty.dev/docs/filters/collection-items/#also-getcollectionitem\n[also-getcollectionitem]: https://www.11ty.dev/docs/filters/collection-items/\\#also-getcollectionitem\n[template inheritance]: https://mozilla.github.io/nunjucks/templating.html#template-inheritance\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"},{"id":"/2020/stationery-i-like/","title":"Stationery I like","content_html":"\n\n\n\n\n\nStationery I like\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n\nStationery I like\n\n\n\n \n \n \n
Stationery I like
\n \n\n \n \n \n\n \n
\n
Reviews for things I used, and a wishlist I try to keep small.
Great paper for the price — takes well to many pens. Subtle, sparse dot grid. Considerate design with lovely page size (bit wider than A5). Velvety cover does not go well with greasy hands. Most of the cover designs are not my style.
These are how you know it’s Back To School season in Turkey. As far as I can find, the only place you can get these is A-101 (TR supermarket chain). It takes well to a lot of pens — the paper quality is amazing for the price. The plain design is quite nice in my opinion, with vibrant colors or plain black/dark blue options available. I shouldn’t praise them too much, lest they become more expensive…
\n\n \n\n \n \n\n\n","content_text":"Reviews for things I used, and a wishlist I try to keep small.\n\n## Things I have used\n\n\n### [Uni-ball Air Micro --- Rollerball Pen](https://www.uniball.com.tr/urunler/roller/uniball-air/uba-188-m)\n\nHas a tip made of some kind of plastic, super smooth to write, deep black ink with shading effect. The Micro ones have a nicer looking design.\n\n### [Iggy Stationery Thin Notebooks](https://www.studioiggy.com/collections/i%CC%87nce-defterler)\n\nGreat paper for the price --- takes well to many pens. Subtle, sparse dot grid. Considerate design with lovely page size (bit wider than A5). Velvety cover does not go well with greasy hands. Most of the cover designs are not my style.\n\n### [Globox Leather Design Notebooks](http://www.smartofis.com.tr/kagit-grubu/Suni-deri-not-defteri)\n\nThese are how you know it's Back To School season in Turkey. As far as I can find, the only place you can get these is A-101 (TR supermarket chain). It takes well to a lot of pens --- the paper quality is amazing for the price. The plain design is quite nice in my opinion, with vibrant colors or plain black/dark blue options available. I shouldn't praise them too much, lest they become more expensive...\n\n \n\n## Things I want (curse you, JetPens)\n\n\n### Pen\n\n- [Pilot Multi Ball](https://www.jetpens.com/Pilot-Multi-Ball-Rollerball-Pen-Fine-Black/pd/2760)\n- [Kuretake Fudegokochi Brush Pen](https://www.jetpens.com/Kuretake-Fudegokochi-Brush-Pen-Extra-Fine-Black/pd/2659)\n- [Pentel Artist Brush Sign Pen](https://www.wellappointeddesk.com/2019/11/pen-review-pentel-artist-brush-sign-pen/)\n\n### Notebooks\n\n- [Sorta Notebinder](https://www.sorta.la/)\n\n### Pen Cases\n\n- [Sonic Sma Sta Standing Pen Case](https://www.jetpens.com/Sonic-Sma-Sta-Standing-Pen-Cases/ct/4885)\n- [Lihit Lab Smart Fit Carrying Pouch --- A6](https://www.wellappointeddesk.com/2019/03/review-lihit-lab-smart-fit-carrying-pouch-a6/)\n- [Nakabayashi Lifestyle Tool Wall Box](https://www.jetpens.com/Nakabayashi-Lifestyle-Tool-Wall-Box-S-Kraft/pd/22304)\n\n### Miscellaneous\n\n- [Raymay Pencut Mini Scissors](https://www.jetpens.com/Raymay-Pencut-Mini-Scissors/ct/1623)\n","url":"https://denizaksimsek.com/undefined","image":"https://denizaksimsek.com/undefined","date_published":"undefined"}]}