A => .gitignore +8 -0
@@ 1,8 @@
+public/
+*.log
+*.iso*
+*.bz2
+content/gallery/*/
+layouts/partials/webring-out.html
+layouts/partials/webring-out.html
+Makefile
A => LICENSE +378 -0
@@ 1,378 @@
+All code (any source code or scripts) on this repository is licensed under
+BSD-2 Clause license, unless stated otherwise. License code is included below.
+
+ BSD 2-Clause License
+
+ Copyright (c) 2020, Humaid AlQassimi. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+All content (Markdown files, images, videos, etc) on this repository is
+licensed under the CC BY-SA 4.0, unless stated otherwise. License code is
+included below.
+
+ By exercising the Licensed Rights (defined below), You accept and agree
+ to be bound by the terms and conditions of this Creative Commons
+ Attribution-ShareAlike 4.0 International Public License ("Public
+ License"). To the extent this Public License may be interpreted as a
+ contract, You are granted the Licensed Rights in consideration of Your
+ acceptance of these terms and conditions, and the Licensor grants You
+ such rights in consideration of benefits the Licensor receives from
+ making the Licensed Material available under these terms and
+ conditions.
+
+
+ Section 1 -- Definitions.
+
+ a. Adapted Material means material subject to Copyright and Similar
+ Rights that is derived from or based upon the Licensed Material
+ and in which the Licensed Material is translated, altered,
+ arranged, transformed, or otherwise modified in a manner requiring
+ permission under the Copyright and Similar Rights held by the
+ Licensor. For purposes of this Public License, where the Licensed
+ Material is a musical work, performance, or sound recording,
+ Adapted Material is always produced where the Licensed Material is
+ synched in timed relation with a moving image.
+
+ b. Adapter's License means the license You apply to Your Copyright
+ and Similar Rights in Your contributions to Adapted Material in
+ accordance with the terms and conditions of this Public License.
+
+ c. BY-SA Compatible License means a license listed at
+ creativecommons.org/compatiblelicenses, approved by Creative
+ Commons as essentially the equivalent of this Public License.
+
+ d. Copyright and Similar Rights means copyright and/or similar rights
+ closely related to copyright including, without limitation,
+ performance, broadcast, sound recording, and Sui Generis Database
+ Rights, without regard to how the rights are labeled or
+ categorized. For purposes of this Public License, the rights
+ specified in Section 2(b)(1)-(2) are not Copyright and Similar
+ Rights.
+
+ e. Effective Technological Measures means those measures that, in the
+ absence of proper authority, may not be circumvented under laws
+ fulfilling obligations under Article 11 of the WIPO Copyright
+ Treaty adopted on December 20, 1996, and/or similar international
+ agreements.
+
+ f. Exceptions and Limitations means fair use, fair dealing, and/or
+ any other exception or limitation to Copyright and Similar Rights
+ that applies to Your use of the Licensed Material.
+
+ g. License Elements means the license attributes listed in the name
+ of a Creative Commons Public License. The License Elements of this
+ Public License are Attribution and ShareAlike.
+
+ h. Licensed Material means the artistic or literary work, database,
+ or other material to which the Licensor applied this Public
+ License.
+
+ i. Licensed Rights means the rights granted to You subject to the
+ terms and conditions of this Public License, which are limited to
+ all Copyright and Similar Rights that apply to Your use of the
+ Licensed Material and that the Licensor has authority to license.
+
+ j. Licensor means the individual(s) or entity(ies) granting rights
+ under this Public License.
+
+ k. Share means to provide material to the public by any means or
+ process that requires permission under the Licensed Rights, such
+ as reproduction, public display, public performance, distribution,
+ dissemination, communication, or importation, and to make material
+ available to the public including in ways that members of the
+ public may access the material from a place and at a time
+ individually chosen by them.
+
+ l. Sui Generis Database Rights means rights other than copyright
+ resulting from Directive 96/9/EC of the European Parliament and of
+ the Council of 11 March 1996 on the legal protection of databases,
+ as amended and/or succeeded, as well as other essentially
+ equivalent rights anywhere in the world.
+
+ m. You means the individual or entity exercising the Licensed Rights
+ under this Public License. Your has a corresponding meaning.
+
+
+ Section 2 -- Scope.
+
+ a. License grant.
+
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+
+ a. reproduce and Share the Licensed Material, in whole or
+ in part; and
+
+ b. produce, reproduce, and Share Adapted Material.
+
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with
+ its terms and conditions.
+
+ 3. Term. The term of this Public License is specified in Section
+ 6(a).
+
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in
+ all media and formats whether now known or hereafter created,
+ and to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including
+ technical modifications necessary to circumvent Effective
+ Technological Measures. For purposes of this Public License,
+ simply making modifications authorized by this Section 2(a)
+ (4) never produces Adapted Material.
+
+ 5. Downstream recipients.
+
+ a. Offer from the Licensor -- Licensed Material. Every
+ recipient of the Licensed Material automatically
+ receives an offer from the Licensor to exercise the
+ Licensed Rights under the terms and conditions of this
+ Public License.
+
+ b. Additional offer from the Licensor -- Adapted Material.
+ Every recipient of Adapted Material from You
+ automatically receives an offer from the Licensor to
+ exercise the Licensed Rights in the Adapted Material
+ under the conditions of the Adapter's License You apply.
+
+ c. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section 3(a)(1)(A)(i).
+
+ b. Other rights.
+
+ 1. Moral rights, such as the right of integrity, are not
+ licensed under this Public License, nor are publicity,
+ privacy, and/or other similar personality rights; however, to
+ the extent possible, the Licensor waives and/or agrees not to
+ assert any such rights held by the Licensor to the limited
+ extent necessary to allow You to exercise the Licensed
+ Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this
+ Public License.
+
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society
+ under any voluntary or waivable statutory or compulsory
+ licensing scheme. In all other cases the Licensor expressly
+ reserves any right to collect such royalties.
+
+
+ Section 3 -- License Conditions.
+
+ Your exercise of the Licensed Rights is expressly made subject to the
+ following conditions.
+
+ a. Attribution.
+
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+
+ a. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if
+ designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of
+ warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+
+ b. indicate if You modified the Licensed Material and
+ retain an indication of any previous modifications; and
+
+ c. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section 3(a)(1)(A) to the extent
+ reasonably practicable.
+
+ b. ShareAlike.
+
+ In addition to the conditions in Section 3(a), if You Share
+ Adapted Material You produce, the following conditions also apply.
+
+ 1. The Adapter's License You apply must be a Creative Commons
+ license with the same License Elements, this version or
+ later, or a BY-SA Compatible License.
+
+ 2. You must include the text of, or the URI or hyperlink to, the
+ Adapter's License You apply. You may satisfy this condition
+ in any reasonable manner based on the medium, means, and
+ context in which You Share Adapted Material.
+
+ 3. You may not offer or impose any additional or different terms
+ or conditions on, or apply any Effective Technological
+ Measures to, Adapted Material that restrict exercise of the
+ rights granted under the Adapter's License You apply.
+
+
+ Section 4 -- Sui Generis Database Rights.
+
+ Where the Licensed Rights include Sui Generis Database Rights that
+ apply to Your use of the Licensed Material:
+
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+ to extract, reuse, reproduce, and Share all or a substantial
+ portion of the contents of the database;
+
+ b. if You include all or a substantial portion of the database
+ contents in a database in which You have Sui Generis Database
+ Rights, then the database in which You have Sui Generis Database
+ Rights (but not its individual contents) is Adapted Material,
+
+ including for purposes of Section 3(b); and
+ c. You must comply with the conditions in Section 3(a) if You Share
+ all or a substantial portion of the contents of the database.
+
+ For the avoidance of doubt, this Section 4 supplements and does not
+ replace Your obligations under this Public License where the Licensed
+ Rights include other Copyright and Similar Rights.
+
+
+ Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+ a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+ EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+ AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+ IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+ WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+ ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+ KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+ ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+ b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+ TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+ NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+ INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+ COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+ USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+ DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+ IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+ c. The disclaimer of warranties and limitation of liability provided
+ above shall be interpreted in a manner that, to the extent
+ possible, most closely approximates an absolute disclaimer and
+ waiver of all liability.
+
+
+ Section 6 -- Term and Termination.
+
+ a. This Public License applies for the term of the Copyright and
+ Similar Rights licensed here. However, if You fail to comply with
+ this Public License, then Your rights under this Public License
+ terminate automatically.
+
+ b. Where Your right to use the Licensed Material has terminated under
+ Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the
+ violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any
+ right the Licensor may have to seek remedies for Your violations
+ of this Public License.
+
+ c. For the avoidance of doubt, the Licensor may also offer the
+ Licensed Material under separate terms or conditions or stop
+ distributing the Licensed Material at any time; however, doing so
+ will not terminate this Public License.
+
+ d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+ License.
+
+
+ Section 7 -- Other Terms and Conditions.
+
+ a. The Licensor shall not be bound by any additional or different
+ terms or conditions communicated by You unless expressly agreed.
+
+ b. Any arrangements, understandings, or agreements regarding the
+ Licensed Material not stated herein are separate from and
+ independent of the terms and conditions of this Public License.
+
+
+ Section 8 -- Interpretation.
+
+ a. For the avoidance of doubt, this Public License does not, and
+ shall not be interpreted to, reduce, limit, restrict, or impose
+ conditions on any use of the Licensed Material that could lawfully
+ be made without permission under this Public License.
+
+ b. To the extent possible, if any provision of this Public License is
+ deemed unenforceable, it shall be automatically reformed to the
+ minimum extent necessary to make it enforceable. If the provision
+ cannot be reformed, it shall be severed from this Public License
+ without affecting the enforceability of the remaining terms and
+ conditions.
+
+ c. No term or condition of this Public License will be waived and no
+ failure to comply consented to unless expressly agreed to by the
+ Licensor.
+
+ d. Nothing in this Public License constitutes or may be interpreted
+ as a limitation upon, or waiver of, any privileges and immunities
+ that apply to the Licensor or You, including from the legal
+ processes of any jurisdiction or authority.
A => archetypes/default.md +6 -0
@@ 1,6 @@
+---
+title: "{{ replace .Name "-" " " | title }}"
+date: {{ .Date }}
+draft: true
+---
+
A => config.toml +85 -0
@@ 1,85 @@
+baseURL = "https://humaidq.ae/"
+languageCode = "en-us"
+title = "Humaid AlQassimi's Website"
+theme = "humaidq-theme"
+preserveTaxonomyNames = true
+pygmentsUseClasses = true
+pygmentsCodeFences = true
+enableGitInfo = true
+disableHugoGeneratorInject = true
+#canonifyURLs = true
+[Params]
+ images = ["img/me.jpg"]
+ ISO8601 = "2006-01-02T15:04:05GMT"
+ profilePicEnabled = true
+
+sectionPagesMenu = "main"
+
+paginate = 5
+paginatePath = ""
+
+[privacy]
+ [privacy.disqus]
+ disable = true
+ [privacy.googleAnalytics]
+ disable = true
+ [privacy.instagram]
+ disable = true
+ [privacy.twitter]
+ disable = true
+ [privacy.vimeo]
+ disable = true
+ [privacy.youtube]
+ disable = true
+
+[menu]
+ [[menu.main]]
+ identifier = "home"
+ name = "Home"
+ url = "/"
+ weight = 10
+ [[menu.main]]
+ identifier = "now"
+ name = "Now"
+ url = "/now/"
+ weight = 11
+ [[menu.main]]
+ identifier = "projects"
+ name = "Projects"
+ url = "/projects/"
+ weight = 20
+ [[menu.main]]
+ identifier = "blog"
+ name = "Blog"
+ url = "/blog/"
+ weight = 30
+ [[menu.main]]
+ identifier = "gallery"
+ name = "Gallery"
+ url = "/gallery/"
+ weight = 40
+ [[menu.main]]
+ identifier = "xmath-pp"
+ url = "/xmath-pp/"
+ weight = -100
+ [[menu.main]]
+ identifier = "contribution"
+ url = "/contribution/"
+ weight = -100
+
+[taxonomies]
+# license = "license"
+ location = "location"
+# language = "language"
+
+[blackfriday]
+ hrefTargetBlank = true
+ noreferrerLinks = true
+
+[markup]
+ [markup.tableOfContents]
+ startLevel = 3
+ [markup.goldmark]
+ [markup.goldmark.renderer]
+ unsafe = true
+ xHTML = true
A => content/_index.md +30 -0
@@ 1,30 @@
+---
+title: "Home"
+description: "An Emirati who likes writing open-source software."
+menu: projects
+---
+
+Welcome to my personal website. You can find my open-source projects, blog,
+gallery, and other works on this website.
+
+I like writing minimalist software which solves problems. Most of my projects
+are written in [Go](https://golang.org), and I am always trying to learn new
+things.
+
+## My top projects
+
+Here are some projects I am proud of.
+
+- [Neat Note](/projects/neatnote): a website for students to share resources,
+ notes, and start discussions. With [Lobsters](https://lobste.rs)-like voting
+ system on posts.
+- [Learning Bot](/projects/learning-bot/): a GitLab bot for providing
+ programming advice for university students.
+- [godoc2markdown](/projects/godoc2markdown/): a program which converts Go Doc
+ output to Markdown.
+
+## Contact
+
+Email me and introduce yourself. My email is public<span style="display:none;"> (REMOVE THIS) </span>@humaidq.<span style="display:none;"> (deletethis) </span>ae, and I respond to all emails.
+
+My PGP key is [`C4350A2D`](/contact/pgp.txt), which I also use to sign commits.
A => content/blog/_index.md +4 -0
@@ 1,4 @@
+---
+title: Blog
+description: "Humaid's blog on computer and technology related topics"
+---
A => content/blog/best-articles-2018.md +24 -0
@@ 1,24 @@
+---
+title: "Best articles I read in 2018"
+date: 2019-01-08
+---
+
+I have read many great articles related to programming and Computer
+Science in 2018, I have gathered articles which I enjoyed most. Some of
+these are articles are over a decade old, but I find it essential
+that every programmer or computer scientist reads these articles.
+<!--more-->
+- How To Become A Hacker by Eric Raymond - http://www.catb.org/~esr/faqs/hacker-howto.html
+- A lightning talk by Gary Bernhardt - https://www.destroyallsoftware.com/talks/wat
+- Beating the averages by Paul Graham - http://www.paulgraham.com/avg.html
+- Revenge of the nerds by Paul Graham - http://www.paulgraham.com/icad.html
+- The Hundred-Year Language by Paul Graham - http://www.paulgraham.com/hundred.html
+- The perils of JavaSchools by Joel Spolsky - https://www.joelonsoftware.com/2005/12/29/the-perils-of-javaschools-2/
+- How Lisp Became God's Own Programming Language by Sinclair Target - https://twobithistory.org/2018/10/14/lisp.html
+- Stop writing code by Emily Maier - https://emilymaier.net/words/stop-writing-code/
+- How to Design for the Modern Web by Casper Beyer - https://medium.com/commitlog/how-to-design-for-the-modern-web-52eaa926bae2
+- Dos and don'ts on designing for accessibility by Karwai Pun - https://accessibility.blog.gov.uk/2016/09/02/dos-and-donts-on-designing-for-accessibility/
+- tour-de-babel by Steve Yegge - https://sites.google.com/site/steveyegge2/tour-de-babel
+- Why WhatsApp Only Needs 50 Engineers for Its 900M Users by Cade Metz - https://www.wired.com/2015/09/whatsapp-serves-900-million-users-50-engineers/
+- On the usefulness of Linux by my professor, Jamie - http://gabbay.org.uk/blog/interrogated.html
+
A => content/blog/gopher.md +17 -0
@@ 1,17 @@
+---
+title: "My Gopher Site"
+date: 2019-11-06
+---
+
+A Gopher version of my website is available! You can access it by visiting
+<gopher://humaidq.ae> with a browser that supports it, such as [lynx]. Or
+alternatively, view the site with [Floodgap](https://gopher.floodgap.com/gopher/gw?humaidq.ae)
+on a modern browser. This is how it looks with lynx:
+
+
+
+In the future, I may extend it to be a closer copy of my current website, and
+to include the blog, projects, among other things.
+
+[lynx]: https://lynx.browser.org/
A => content/blog/gopher/gopher.png +0 -0
A => content/blog/hall-of-fame.md +41 -0
@@ 1,41 @@
+---
+title: "My favourite software"
+date: 2019-08-12
+Summary: "This is a list of software which improved the way I used my computer,
+the list includes software for backing up, text editing and document
+processing, Linux/Unix utilities and programs, and desktop environment and
+applications."
+---
+
+This is a list of software which improved the way I use my computer.
+
+**Backing up**
+
+> I use [Borg](https://www.borgbackup.org/) which allows me to efficiently
+> backup my files, it supports encryption and deduplication of files, allowing
+> me to use a fraction of space compared to a traditional method.
+
+**Text editing & document processing**
+
+> I use [neovim](https://neovim.io/) because it is fast, minimal and just works.
+> Editors like VS Code and Atom sucks, a text editor shouldn't be using
+> 500-700MB of RAM to open a small text file.
+
+> I usually write my notes and reports in Markdown, which is then converted to
+> PDF (through LaTeX) with [pandoc](https://pandoc.org/). [LaTeX](https://www.latex-project.org/)
+> is used when I need more control over the document.
+
+**Linux/Unix utilities and programs**
+
+- [maim](https://github.com/naelstrof/maim): a simple command-line based screenshot program.
+- [zsh](http://zsh.sourceforge.net/)/[Oh My Zsh](https://ohmyz.sh/): my favourite shell environment setup.
+- [sxiv](https://github.com/muennich/sxiv): a perfect, minimal image viewer.
+- [zathura](https://pwmt.org/projects/zathura/): a light PDF viewer which uses Vi keyboard shortcuts.
+- [Claws Mail](https://www.claws-mail.org/): a mail client which is lightweight and delightful to use.
+
+**Desktop environment**
+
+- My window manager is dwm, modified to support volume, brightness, display and
+ pomodoro (`spt`) support, and theme colour changed. I like the way dwm
+ arranges windows (compared to i3wm).
+- My terminal emulator is st, which seems to just work well.
A => content/blog/kudu-two-year.md +91 -0
@@ 1,91 @@
+---
+title: "System76 Kudu4: After two years"
+date: 2019-11-16
+---
+
+Two years and three months ago, I have purchased the [Kudu4 laptop] from
+[System76], which is essentially a rebranded [Clevo] N870HZ laptop for Linux. I have enjoyed
+using the laptop so far, and it has gone through a lot of use and abuse,
+especially with my rough handling of my laptop in my backpack.
+The laptop stood well in the past two years in most aspects, the build quality
+is solid (although heavy). I am surprised that the keyboard has almost no wear
+(no shine whatsoever), and the keyboard is still as great to use since when I
+first got it. And the same could be said with the touchpad.
+
+There are a few aspects which I did not like about the laptop, such as the
+speaker sound quality, which is really bad compared to other devices I use.
+As well as the fans, which make whining sounds randomly when idle, and it
+sounds like a plane which is about to takeoff when doing any intensive task
+(such as browsing).
+
+A year and a half after using my laptop as a daily driver, I have noticed that
+the screen started acting up. Sometimes, the screen would be black and I have to
+close the lid and open it again. At first I thought it was an issue with my
+system, but it soon started to get worse. Random artifacts started to appear on
+the screen as I used it, and it started to occur more often over time.
+
+
+
+This would get worse as I use my laptop often as I go to my different lectures,
+opening and closing my laptop lid while I take my laptop out of my backpack.
+
+After contacting System76's support, and going through and diagnosing the
+issue, they have suggested that it may be either an issue with LCD panel or the
+LCD cable. Reseating the LCD cable didn't help much, so I had them ship me
+an LCD cable. It costed me $103.10 USD (out of which, $30 is cable cost, $54 is
+diagnostics fee, and rest is shipping), I found the $54 diagnostics fee a bit
+ridiculous.
+
+While waiting for the LCD cable shipment to arrive, the screen completely gave
+up. The cable eventually arrived, and I got it replaced. But getting the cable
+to go through the hinges was one of the most difficult thing I have done (maybe
+I'm doing it wrong?). Here's a picture of the old cable:
+
+
+
+----
+
+After replacing the cable 6 months ago, I haven't experienced any problems with
+the screen. Except that the cable for the Webcam and Mic seem to have a
+similar issues, where the camera feed goes black whenever I move the screen. So
+I am expecting the screen cable would end up disintegrating again in about a
+year if I continue to use the laptop in the same way I did the past two years.
+
+The battery life is really inadequate with this laptop, it would barely last 5 hours
+from full charge, which is a problem especially that not all lecture theatres
+have sockets for charging. I didn't realise this was really bad until I have
+seen how long other laptops can last, which is about as double. When
+purchasing the laptop, I have opted in buying an extra battery, but I haven't
+been using it as I don't want to be carrying the extra load. But it has been
+useful as the lithium-ion battery's capacity has degraded drastically over
+time.
+
+Other than that, the laptop is a solid computer (albeit the headache-inducing
+fan). And months after receiving the laptop, System76 issued a firmware update
+to disable Intel's
+Management Engine (ME) which is notoriously known about its security flaws and
+vulnerabilities[^1]. This made me feel like the computer is safer, although I am
+not sure whether it actually made a difference (other than the performance
+sacrifice).
+
+----
+
+This model of the laptop is no longer sold since late 2018, there are newer
+model laptops on the website which I found although nice, they aren't as
+aesthetically pleasing as the Kudu.
+
+I have recently ordered a ThinkPad T590 to replace my current laptop (which has
+yet to arrive), while I am giving the Kudu to a family member,
+where it would (hopefully) not get as much abuse as it does currently, and live
+a longer and happy life. ThinkPads have a reputation of durability, and they
+are certified for use in the International Space Station[^2], which I think is
+cool. I wouldn't have ordered a new laptop if the System76 laptop was more
+reliable, it is sad that I wouldn't be using this laptop as long as I wanted.
+
+[^1]: [Security vulnerabilities of the Intel Management Engine](https://en.wikipedia.org/wiki/Intel_Management_Engine#Security_vulnerabilities), Wikipedia
+[^2]: [IBM ThinkPads in space](https://www.ibm.com/ibm/history/exhibits/space/space_thinkpad.html), IBM Archives
+
+[Kudu4 laptop]: https://web.archive.org/web/20171130005456/https://system76.com/laptops/kudu
+[System76]: https://system76.com
+[Clevo]: https://web.archive.org/web/20170417013400/http://www.clevo.com.tw/clevo_prodetail.asp?id=1017&lang=en
A => content/blog/kudu-two-year/artifacts.jpg +0 -0
A => content/blog/kudu-two-year/old-cable.jpg +0 -0
A => content/blog/own-distro-p1.md +306 -0
@@ 1,306 @@
+---
+title: "Building your own Linux distribution (part 1, Xubuntu)"
+date: 2020-05-01
+---
+
+
+In this post we will cover how to build your own derivative based on any Linux
+distribution, but we will be using Xubuntu 20.04 in this post as an example.
+I'll not cover how to make your own Linux distribution from scratch, if you
+want to do that check out [Linux From Scratch] \(or [tldrlfs]). There are many
+ways to customise a Linux distribution, in this post we will only cover one
+way, which is by customising the live CD.
+
+Some of the reasons why you might want to create your own Linux distribution are:
+
+- For having a system customised to your liking whenever you need to reformat
+ your computer, and having a post-installation script is just boring.
+- You are at a company/school/organisation and you have to have applications
+ setup in a specific way (and preseeding the installer is not enough).
+- Create a modern version of [Hannah Montana Linux].
+- You are bored due to the quarantine and want to do something.
+
+I assume that you will be sensible and responsible to the distribution you are
+willing to fork, and to its community. Ubuntu owns the trademark to their
+names, so you cannot use their trademark in your derivative[^1]. Be sure to
+familiarise yourself with the policy and guidelines of the distribution you are
+willing to use.
+
+### Prerequisites
+
+It is important to know which kind of distribution you are deriving from, some
+distributions such as Arch Linux are bootstrapped using their package manager.
+This requires you to create your own mirror with your own version of the `base`
+package. Newer distributions have build scripts available which allows you to
+customise the installation image[^2]. Modifying these distributions ISO files
+will only change the live CD environment, which may not be what you want.
+
+Our focus is customising Xubuntu 20.04, as Ubuntu and Ubuntu-based
+distributions are easy to customise. The Ubuntu installer uses the ISO files,
+so the customisations made to the ISO image will be applied to the installed
+system. Before we continue, make sure you have the following packages on your
+system: `proot`, `squashfs-tools`, `rsync`, `qemu`, and `xorriso`. We can then
+[download the Xubuntu ISO](http://xubuntu.org/getxubuntu/) we want to
+customise. There are many Ubuntu-specific parts in the following scripts, I'll
+note these so you may adapt it to whatever distribution your are customising.
+
+### Writing the scripts
+
+We will be automating building our distribution in a shell script, this makes
+building our derivative reproducible. So let's start with a basic script called
+`build.sh`.
+
+```sh
+#!/bin/sh
+
+# We define the global variables
+BASEDIR=`pwd` # this is the base working directory, in case we need to go back to it
+MOUNT="mnt" # this is the mount directory for the ISO file
+EXTRACT="extract-cd" # this is where the ISO will be extracted to
+CHROOT="edit" # this is where the root partition (squashfs) will be extracted to
+ORIG_FILE="xubuntu-20.04-desktop-amd64.iso" # this is the file we will be customising
+DIST_NAME="pinguOS"
+DIST_FILE="$DIST_NAME-$(date +%Y%m%d).iso" # this is the final file
+
+# We make sure that the ISO file exists before we continue
+if [ ! -f $ORIG_FILE ]; then
+ echo "The file ${ORIG_FILE} doesn't exist. Be sure to download it first."
+ exit
+fi
+
+# We clean up the files from previous runs
+rm -rf $CHROOT $EXTRACT $MOUNT
+
+# Now we run the scripts
+. ./scripts/extract.sh
+. ./scripts/customise.sh
+. ./scripts/build.sh
+```
+
+In our shell script, we are splitting the process in three steps.
+
+- extract: We extract the contents of the ISO file.
+- customise: We modify the extracted contents to our liking.
+- build: We build a new ISO file based on the changes we have made.
+
+#### Extracting the ISO
+
+Let's start with `./scripts/extract.sh`.
+
+```sh
+# We make the mount directory and mount the ISO to it
+mkdir $MOUNT $EXTRACT
+mount -o loop xubuntu-18.04.1-desktop-amd64.iso $MOUNT
+# Now we copy the ISO contents to our extract directory
+rsync --exclude=/casper/filesystem.squashfs -a ${MOUNT}/ $EXTRACT
+# The filesystem is in a read-only compressed filesystem which we need to extract
+unsquashfs mnt/casper/filesystem.squashfs
+mv squashfs-root $CHROOT
+# We can now unmount and delete that directory
+umount $MOUNT
+rm -rf $MOUNT
+```
+
+**Note:** With other distributions you may have to slightly tweak the code
+above, files such as `filesystem.squash` may be somewhere else with another
+name.
+
+#### Customising the files
+
+This should extract the root file system in the directory `./edit`. At this
+stage we can run `chroot` on our `./edit` directory, but we usually need to
+`mount --bind` our system directories such as `/dev`, `/proc`, `/sys`, and
+other files so the programs run properly in the `chroot` environment[^3]. To
+simplify this, we are going to use [PRoot]. Let's write `./scripts/customise.sh`.
+
+```sh
+proot \
+ -R ${PWD}/${CHROOT}/ \
+ -w / \
+ -b /proc/ \
+ -b /dev/ \
+ -b /sys/ \
+ -b /etc/resolv.conf \
+ -0 \
+ /bin/bash
+```
+
+PRoot will also automatically mount/unmount these directories (defined with
+`-b`) in our chroot environment when we are done with it, which reduces the
+hassle of manually mounting and unmounting these directories. We can now test
+it out by running our build script as root.
+
+```sh
+# sh ./build.sh
+```
+
+
+
+As you see in the screenshot, we get a prompt. This is the Xubuntu 20.04
+environment which we can interact with and modify the system to our liking.
+
+Let's do something really simple, and add a hello world text file on the
+desktop. On Linux, there is a directory called `/etc/skel` which contains
+files that are automatically copied to new users on the system. Let's append
+this to `./scripts/customise.sh`.
+
+```sh
+mkdir ${CHROOT}/etc/skel/Desktop
+echo "Welcome to my Linux distribution" > ${CHROOT}/etc/skel/Desktop/hello.txt
+```
+
+We'll add upon this file later to further customise our distribution, let's now
+focus on building our new ISO image.
+
+#### Building the new ISO file
+
+Let's write `./scripts/build.sh`.
+
+```sh
+# we have to update the manifest file to contain the latest list of packages.
+chmod +w $EXTRACT/casper/filesystem.manifest
+proot \
+ -R ${PWD}/${CHROOT}/ \
+ -w / \
+ -b /proc/ \
+ -b /dev/ \
+ -b /sys/ \
+ -0 \
+ dpkg-query -W --showformat='${Package} ${Version}\n' > $EXTRACT/casper/filesystem.manifest
+cp $EXTRACT/casper/filesystem.manifest $EXTRACT/casper/filesystem.manifest-desktop
+# we have to make a new squashfs compressed filesystem based on the changes we did
+mksquashfs $CHROOT $EXTRACT/casper/filesystem.squashfs
+# we put the size of the filesystem for casper
+printf $(du -sx --block-size=1 edit | cut -f1) > $EXTRACT/casper/filesystem.size
+# we also have to update the md5sum list of the files
+cd $EXTRACT
+rm md5sum.txt
+find -type f -print0 | xargs -0 md5sum | grep -v isolinux/boot.cat > md5sum.txt
+# now build the ISO
+xorriso -as mkisofs \
+ -r -V "$DIST_NAME amd64" \
+ --protective-msdos-label \
+ -b isolinux/isolinux.bin \
+ -no-emul-boot -boot-load-size 4 -boot-info-table \
+ --grub2-boot-info --grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
+ --efi-boot "boot/grub/efi.img" -efi-boot-part --efi-boot-image \
+ -o ../$DIST_FILE .
+cd $BASEDIR
+```
+
+**Note:** We do generate some files like the md5sum of the files, and the
+package listing. Some of these are based on Ubuntu's live CD customisation
+guide and other sources[^4].
+
+We can now try to build again, and try to boot it using `qemu`.
+
+```sh
+# sh ./build.sh
+...
+$ qemu-system-x86_64 -m 2G -cdrom pinguOS-<date>.iso
+```
+
+
+
+Violà!
+
+#### Further customisations
+
+There are still Xubuntu/Ubuntu branding which we have to change if we want to
+redistribute our new fork. So let's try to replace the branding with ours by
+adding the following to the `./scripts/customise.sh` file.
+
+```sh
+sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/isolinux/txt.cfg
+sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/boot/grub/grub.cfg
+sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/boot/grub/loopback.cfg
+sed -i -e 's/Xubuntu 20.04 LTS "Focal Fossa"/'$DIST_NAME'/g' $EXTRACT/README.diskdefines
+sed -i -e 's/Xubuntu/'$DIST_NAME'/g' $EXTRACT/boot/grub/grub.cfg
+rm $EXTRACT/.disk/release_notes_url
+echo -n "$DIST_NAME - Release amd64 (`date +%Y%m%d`)" > $EXTRACT/.disk/info
+echo '$DIST_NAME \n \l' > $CHROOT/etc/issue
+echo '$DIST_NAME' > $CHROOT/etc/issue.net
+echo > $CHROOT/etc/legal
+
+# The lsb-release file
+cat <<EOF> $CHROOT/etc/lsb-release
+DISTRIB_ID=Ubuntu
+DISTRIB_RELEASE=$(date +%Y%m%d)
+DISTRIB_CODENAME=focal
+DISTRIB_DESCRIPTION="$DIST_NAME"
+EOF
+
+# The os-release file
+cat <<EOF> $CHROOT/etc/os-release
+NAME="$DIST_NAME"
+VERSION="$(date +%Y%m%d)"
+ID=ubuntu
+ID_LIKE=debian
+PRETTY_NAME="$DIST_NAME"
+VERSION_ID="$(date +%Y%m%d)"
+HOME_URL="https://humaidq.ae/blog"
+VERSION_CODENAME=focal
+UBUNTU_CODENAME=focal
+EOF
+```
+
+The `sed` commands basically does search and replace in the given files. And
+other files such as the `/etc/issue` we completely overwrite. That's most of
+the files we need to modify. Now we might want to install our own packages or
+run other commands. Let's modify the `proot` command at the top of the
+`./scripts/customise.sh` script.
+
+```sh
+proot \
+ -R ${PWD}/${CHROOT}/ \
+ -w / \
+ -b /proc/ \
+ -b /dev/ \
+ -b /sys/ \
+ -b /etc/resolv.conf \
+ -0 \
+ /bin/bash <<EOF
+
+export HOME=/root
+export LC_ALL=C
+
+apt update
+apt upgrade -y --allow-downgrades
+
+# TODO: You might want to install/purge packages here, or add your PPA.
+# You might want to remove the plymouth branded boot screen too.
+
+
+apt autoremove --purge -y
+
+EOF
+```
+
+Other places of interest may be:
+
+- `/usr/lib/ubiquity`: Installer Python source
+- `/usr/share/ubiquity-slideshow`: Installer slideshow files
+- `/etc/update-motd.d`: System message of the day
+
+The possibilities are endless.
+
+In the second part of this blog series we will be creating our custom
+Raspbian Lite image, which is slightly different as we are dealing with an
+image file with partitions rather than an ISO file.
+
+[Linux From Scratch]: http://www.linuxfromscratch.org/lfs/
+[tldrlfs]: https://github.com/Sweets/tldrlfs
+[Hannah Montana Linux]: http://hannahmontana.sourceforge.net/
+[PRoot]: https://proot-me.github.io/
+
+[^1]: Check Ubuntu's [DerivativeDistroHowto wiki page](https://wiki.ubuntu.com/DerivativeDistroHowto#Trademarks),
+ it contains examples of some things you should and shouldn't do.
+[^2]: For example Alpine's [abuild](https://git.alpinelinux.org/abuild/) or
+ Void's [void-mklive](https://github.com/void-linux/void-mklive).
+[^3]: We mount these so that the applications which rely on the existence of
+ these directories can work in the chroot environment.
+[^4]: You can go into more detail at Ubuntu's [LiveCDCustomisation wiki page](https://help.ubuntu.com/community/LiveCDCustomization),
+ but some information might be outdated. I have also learned from reading
+ [Pop!\_OS ISO production](https://github.com/pop-os/iso) source code, which
+ filled some gaps.
A => content/blog/own-distro-p1/desktop.png +0 -0
A => content/blog/own-distro-p1/output.png +0 -0
A => content/blog/qnap.md +56 -0
@@ 1,56 @@
+---
+title: "Installing Linux on my QNAP TS-459"
+date: 2020-04-28
+draft: true
+---
+
+About four years ago I got the QNAP TS-459 as a NAS so I can store family
+pictures and backups of our devices. It came with QNAP QTS, which is the NAS
+user interface. I came across many issues with the responsiveness of this UI,
+as it tries to replicate a desktop environment with windows (as in panes, not
+the operating system). This UI is sometimes slow, confusing to navigate as I
+have to learn yet another interface, and has bugs (such as when the backup
+program wizard always hangs).
+
+I wished to have a standard Linux system which I can operate, rather than using
+this interface with their proprietary software.
+
+Recently, one of the four hard drives on the RAID5 array failed, and it isn't
+long until failures pile up. This is when I regretted having a ClamAV scan run
+every week, which was very pointless and wreckful to the wear and tear of the
+drives.
+
+The drives installed were 5TB Seagate Enterprise Capacity 3.5 HDD (v4), and
+since it is a bad idea to keep using these drives, I am ordering new ones after
+installing Linux on the machine. Luckily, the manufacturer did not disable the
+BIOS, and allows users to boot from a USB for recovery[^1]. I am a big fan of
+[Void Linux] as it is simple to use and fast, the [runit] init scheme allows me
+to define services as simple shell scripts, rather than INI files[^2].
+
+Luckily the NAS drive has an HDMI output for the media center. Pressing `Del`
+while booting the system loads the BIOS, where I could specify the boot order.
+Unfortunately, I was not able to find the key which opens the boot menu
+directly, and the BIOS doesn't allow me to boot directly to a device. So I set
+the USB device to have priority over the internal flash storage.
+
+After booting Void Linux, I found three partitions on the system. These show on
+Void as:
+
+- `/dev/loop1` (730M): This is where the root parition of the system is stored.
+- `/dev/loop2`: This contains an archive of the firmware, which I assume is
+ used for a firmware reset.
+- `/dev/sdb` (429M): This contains the boot loader.
+
+On the QNAP wiki, it shows these drives appear as `/dev/mtdblock{1,2,3}` (as in
+Memory Technology Devices). I am clueless to why two of the devices
+automatically load as loop devices.
+
+
+[^1]: QNAP also provides a wiki page on [booting a recovery disk](https://wiki.qnap.com/wiki/Firmware_Recovery#Instructions_for_NAS_Recovery)
+ and [installing Debian](https://wiki.qnap.com/wiki/Debian_Installation_On_QNAP)
+ on their systems.
+[^2]: systemd uses INI files for configuration, which I find less
+ comprehensible compared to a simple shell script.
+
+[Void Linux]: https://voidlinux.org/
+[runit]: http://smarden.org/runit/
A => content/blog/status-update-1.md +63 -0
@@ 1,63 @@
+---
+title: Status update, October 2019
+date: 2019-10-19
+---
+
+A lot has been happening the last month, we have started working on the
+largest group software development project at the University. We are a team
+of six people, and have decided to choose [Go](/languages/go/) as our language
+of choice for the implementation of the smart home system we are building.
+
+We have spend the first couple of weeks setting up the group in [GitLab] and
+get continuous integration running (so we can have LaTeX PDF builds, and wiki
+site deployed automatically). While setting up all the documentation for the
+team and project, and specifying the software development process of the team,
+we realised that there is no simple way and neat way to generate a Go project
+documentation automatically -- something like JavaDoc or Doxygen. Using the
+`go doc -all` command to generate documentation isn't great, as it simply
+dumps the documentation in plain text, with no option to change the format.
+
+Some solutions I have found on the Internet is to run the `godoc` server
+(which is what hosts Go's project homepage), then to use `wget` to download
+the HTML pages. The downside of this process is:
+
+1. Customising the template or layout of the pages is difficult, requiring
+you to fork the project and change many lines of code.
+2. The project has to be located in the `GOPATH`, otherwise it will not be
+detected. Our project is usually hosted outside of the `GOPATH`, as we are
+using Go modules.
+
+I tried to find a documentation generator, and sadly Doxygen doesn't support
+Go -- which may be a good thing (some project members simply didn't like the
+style of it). And we cannot use the [GoDoc] website as the projects are hosted
+on a private GitLab group.[^1]
+
+After some more searching, I found a project called [godoc2md] by Dave Cheney,
+which promised to do exactly what I have wanted to do. After trying to get it
+compiled and running, I have encountered many compilation errors, mostly due to
+changes to the GoDoc package which the project depends on. So this seems like a
+dead end.
+
+I have noticed the output of `go doc -all` is easily parsable, different lines
+are formatted differently, which allows me to easily identify which section of
+the documentation is a function declaration, description, etc. With this I can
+write a simple program, using some regular expressions to detect different
+parts and format them correspondingly. And [godoc2markdown] is born, although
+it has some quirks which I am ironing out as the project progresses.
+
+I'll leave you with a picture of a project I have been working on, more details
+to be released soon.
+
+
+
+That's all for this month!
+
+[^1]: As we aren't allowed to post the project source publicly until the end of the course.
+
+[GoDoc]: https://godoc.org/
+[godoc2md]: https://github.com/davecheney/godoc2md
+[godoc2markdown]: /projects/godoc2markdown/
+[GitLab]: https://gitlab.com
+
A => content/blog/status-update-1/notes-overflow-alpha.png +0 -0
A => content/blog/welcome.md +45 -0
@@ 1,45 @@
+---
+title: My new website & blog
+date: 2018-07-23
+---
+Welcome to my newly designed website, which includes a Git projects page, a blog, a gallery and my contact information.
+The website used to run on a web server which I wrote using the Go programming language, and had a login page with GitHub
+authentication. But I do not have a reason anymore to have a dynamic website[^1], it is possible to have a website which is
+static and be able to host all the content I need. The website you are accessing now is a static website generated using an
+amazing generator called [Hugo]. This helps me focus more on the content of the website rather than maintaining the web server code.
+
+### The changes in the redesign
+The previous website used Bootstrap, a bunch of JavaScript libraries and a couple of fonts. This makes my simple website heavy.
+In my redesigned website, all the CSS is written minimally to keep the website simple and fast.
+
+The new redesign is over a thousand times lighter than my older version (when loading a page), but contains more content
+than my older website. It seems like everyday websites are "upgrading" their website design to make it heavier to load, which
+is a bad trend. I would like to prove that it is possible to have a light website without compromising content and design.
+
+### My new projects page
+GitHub used to be where all my open-source projects are hosted, and I was using their services as early as 2013. It was the perfect
+place to host my projects and to collaborate. However when Microsoft bought GitHub in June 2017[^2], I immediately moved away. Microsoft
+waged a war against Linux and the open-source software movement in the past[^3], which caused my distrust in the company.
+~~Self-hosting my own repositories seems like a better option for me, even though it is not the perfect solution to the problem.~~
+I have migrated all my git repositories to [SourceHut] which is a great and
+powerful alternative.
+
+### The gallery
+I have deleted my Instagram account over a month ago, as the service is becoming more "Facebook". Instagram used to be a good place to
+host pictures years ago. With my new website generated with Hugo, I am able to easily create a gallery and host pictures on my website.
+This allows me to categorise and tag my pictures any way I want, license my pictures under a Creative Commons license, and even allow
+people to download the full image file -- something I cannot do using Instagram. Having everything hosted on my website allows more control
+on how the content is displayed and presented.
+
+### The blog and other posts
+I always wanted to have a blog, but I was not satisfied with all the solutions available and I didn't have enough time to make a proper solution.
+Hugo solves this problem, all my website is written in either Markdown or Emacs org-mode -- including my blog. This makes managing the content on
+my entire site easier. Now my projects are categorised depending on the
+language used and license, and implementing that was trivial with Hugo.
+
+
+[Hugo]: https://gohugo.io/
+[SourceHut]: https://sourcehut.org
+[^1]: As in [server-side dynamic web pages](https://en.wikipedia.org/wiki/Dynamic_web_page)
+[^2]: You can find more information about the acquisition at [The GitHub Blog](https://blog.github.com/2018-06-04-github-microsoft/)
+[^3]: There is a good web page explaining this on [cosmicpenguin.com](https://web.archive.org/web/20190412193814/http://www.cosmicpenguin.com/linux/MICROSOFTS_WAR_AGAINST_LINUX.html)
A => content/blog/yubi.md +38 -0
@@ 1,38 @@
+---
+title: "Setting up a Yubikey on Void Linux"
+date: 2020-06-03
+draft: true
+---
+
+I recently got a [Yubikey], which is a hardware authentication device. It has
+multiple functions, the Yubikey 4 has two slots which you can configure.
+Getting the device to work on Void Linux wasn't obvious, this is a simple guide
+on how to get a Yubikey working on [Void Linux].
+
+First you need to install `dbus`, `eudevd`, and `elogind` if you haven't
+installed it yet.
+
+```sh
+# xbps-install -Sy dbus eudevd elogind
+``
+
+You have to enable those services.
+
+``sh
+# ln -s /etc/sv/{dbus,eudevd,elogind} /var/service/
+``
+
+Now you need to install Yubikey packages:
+
+```sh
+# xbps-install -Sy u2f-hidraw-policy ykpers ykpers-gui
+```
+
+Now you'll have to restart your system. You can then plug in your key, and run
+the `ykpers-gui` utility (or `ykpers` if you prefer the command-line).
+
+The [Arch Wiki Yubikey article](https://wiki.archlinux.org/index.php/Yubikey)
+has detailed examples on how you could setup your key.
+
+[Yubikey]: https://en.wikipedia.org/wiki/YubiKey
+[Void Linux]: https://voidlinux.org/
A => content/contact/pgp.txt +63 -0
@@ 1,63 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBFuFw44BEACRFq6haZtCTQ4GmNEQmrjJwv5eqvYNLkZlarD8iaj3wxw5w7Gz
+hqkkjCYfY57cyrjAF9TrtHzijVtflbEMo+Ju3hAeLfZqgdLPTMUMPjMmXugdsENH
+IprBrVaK75+C5brd5JHeM1VqjEHVT75NkWx5aDhZQxU9AmCbSH4LqWSi6PcTkX6O
+s9GvxxjVNn/ofTdkQJjLluu/3nfXT/+9P2CtdOzVenAcOiRYwmSHtKCWjTJwVlWz
+LJmpXAA/sXLeruGr10ybyd0F5Lx4r9yAgi+GO4bn5fTFCAGh6+sq//kVJp2FyOg0
+9BtEog60TYBQGrEel2fEbDyyKXeX0z/EIRU96S0RII7WC4VeE9gSnzxREKWmAkcz
+u2roPxaD+ghaNAEfX/45SoBy1uVFU3NulWECrH7+H3+FWgj/VtNPgkq/TC3qhPLQ
+UralBpSHy9kVQUMbF25HxNyWaxXFFOcVS9GvuudEcRXpesZqXGtuPIOiH3fcu/Tu
+Gfzwef31GQVwBAmjTbG80pIIhM++XGZ8QblDO0wMhuuXPIkfGrtYgq4nYnbbUli7
+dhKhbjZcOzIiDyi2eGJ288FYD6bVbHhPTwl5IINts+ifTTgp0MzQ2UmCTM8EiArV
+j74PANJDLm1SDXiNKeer5W6NIOOuktw00jkOLsIAylqg+DjEBVWDHPqCDQARAQAB
+tCBIdW1haWQgQWxRYXNzaW1pIDxtZUBodW1haWRxLmFlPokCOAQTAQIAIgUCW4XD
+jgIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQB9U1vMQ1Ci11eA//ZwvJ
+PGnBPKMLRFncsuFakHPkd9BjlJRM5YcVm2W2bQngSTiqYgV2bINF3cSV6o+PkXah
+mohsx0lv7048j4UIC2qIgJV+14iVY/5borcCnWUlmzPLKO1qwF8F9ihcu6szxGZU
+af60AFtoLa7rTBCXGk3m2yBg/Us6uyTr38OdGPhOhHuBpwNN6QYRDQK6HBKGePDT
+98KA3T7hORWcmS0SYNz5tBhtjpRo8uSQyA59Wl90oNaOTTTRpCYYyctzhvUqJ3di
+S4wFSprba3p3i+rBsjnlOwbBZ2rDTToS3OVCZvWB7rn6QDfQPQV/zLZO/xTWViPs
+Z2jqVJFn7dRzmNEz1JK/T5/WlGbIm9xfhMtlLZpSdk0Wauzi/1FPVZcSA5PXvdHL
+DUIe1ul13pjRTdI/EubfHu+BU5t1NTNe1chwTiGV/3hmb4Q1ujEBNFUGnpXjr72x
+itqOEMKTbepqvYbU7ETdCsJAFYiBZrhSkuyz3roxgT711lL1UcWtYdzSpQb/3Wgn
+OIbqDhZ/lUYwzxMc8Vll1TJDk2uOwSDJaJ3DwbpzV7D49SXFAuRTmytxC2kxezuz
+ylhWwL8Xd0Z4gt0UG2wIIukCtbCfB7PycxkA4ogJv2hxA/mpRXK7BbTOb5ylUXY/
+0Ofpw6N13WB/haIfW1y7+EaUKNN1X08OG6HXwIG0IUh1bWFpZCBBbFFhc3NpbWkg
+PGdpdEBodW1haWRxLmFlPokCOAQTAQIAIgUCXkP/TwIbAwYLCQgHAwIGFQgCCQoL
+BBYCAwECHgECF4AACgkQB9U1vMQ1Ci3+Xw//a33thoRCyAXkN7tN1xWyKl4+JCxc
+fzimTBrltpPhKtP4Y7yo6TFqfiBm2z93bJwnXyySfGFvKkOIv1y6RkXX3kNuyM4t
+/Jm5RkxK5MsgIo/X5yft9In+FBNMsQiA6KY6aMuWV1rvY35HlkC0aexwjqbKqAPl
+IcS1keudTgnBAF9PYRPS3LwfJkrIFEgPAabR2SLZyJ3kGTVdJCUXcuRH/6FaCGD/
+7pficXNYh+RfxE/rxbKtnDXNcJixnyK2PBh7FvQUz386uKiMcpQLC9gdhgzoSwak
+jvsjyp4+VVnz9EDXiJR01VW9iJk6eJa6DmydzdsoHE/4XTEwOoBvYxTpTZy7he85
++4MFgpz2+OV9rnsiDtWOf28GfCGG8TJkpu1In1SX9SK2vvlRrN3U+LL0ylSYD+kT
+NVJVa+sfwsjuy6WVZjy4G0AcKnihlQghSVdOwxvr20dC+oMc3ycZ4eZevBAXQbKw
+7/fAtT8y53Tzgfd6U+bfMr7DBE5el4ovnHA4IRmGG/uxkJTJdNIAZomAVp7AVmjp
+jsTBnxJh66XBpvr+rssGixJ8Pht+MD18yA6OBEhsloMiEEnccLlu8XMtii0p6rZb
+JZIr9JewuqPh7enlOL5CbL9IGAuJ70GhGykKb86GMqDAH2EskxDH30ahFDOnJfJO
+RrlFSq22aw2O4+q5Ag0EW4XDjgEQAL/tVaQ+C/92um+0TBo8D4K6uCdAahwGFL11
+JrxirUsrud2eupLFVKzguXshtXykH18YGO21aDHQMegUmOjhRJylFeGuNTxYyHz1
+fxtTV0TCG5JIk+0I7XX4LY7VBD6Ms+9CHHHS78AW0wE5Xl9nrTyAs9ymIkAOWCAz
+97lnKcqle0okWcvTCok9357708NE5rywhYWma/JiVKmAe6rUqkUnOOnpuewILrQb
+uOM2Rw2tuQz2b1Bk6AAopGEL3DPd6TnInXA4JL+AmJQ+P363gTr7D1J5yTZrueL7
+fuuH+VWs1NychqJkOmYCNVsUaGeH1EEGth2NJ4e4t5yCNpns4yPfqVUDQKWOpL4j
+A0iXX4Y1UmFh84CM1dym9eYCF2MTmDmy/pl7XzyfSZ7qHu4BiR/3P/v/B0JkA3bM
+O3z9BID4XqnBQ/GsKqm99FUTgK9mQdXOKDAZ8vr2Lu7UBiNSllzp2ZA8QYNBbhos
+8BDODaXSuHoNOAw162ojz6eX53sY8/PcqL6obyivIJ/YmdCFxzjjTc/FXH1w3w/K
+MSxHjT2MX/2LoV8C5o0pH+CymRBAuC6iDQCQTlqLkkC13DWt/KthBVTJ6MYpiQvy
+wpNoGPuewF/yqQ19cDHqLpuotcjqh7w1yEqL+YenjFWWPMU6Wzggyz/9+LdsVXde
+hVPlDrQtABEBAAGJAh8EGAECAAkFAluFw44CGwwACgkQB9U1vMQ1Ci1FrQ/9GOco
+cJdUNOGdY1Q0jxYpm8CNtnbZCqGMOnnGWHqDPKJZ+yoty14wCrrQImnYypE/V9S5
+40S7OOupLSAVgCaf6EqV6BFv03swogbhzIdTXjeIZ9bghQWYet9TLFkmK5TeqfgL
+65ivFNxowRw1YHw8Vf75+P9HROeAvrA1J5+KkWLmP22BBwwNSEEfXXmG1A5/uCjt
+92tT4D7WHZ/fUW/HPzhscJ3eeY5+m6Ifgc4LAEs/eIp30htQdMISFlrv4NBpIBxi
+dXFqn9ksRB/iHeR0CROjwXAMxgHHEg5T7UqoW0Z2K06DXut+L42nzwpNrYU7vM2d
+Vz6pdcEzGBcoPVLzi97jmFKOef6O6Lra8AWxr/+v1hXg735xKPN137JR7d/Zfzh1
+VG6HUVf6ITv5ZLKzGlZ4UD2sECwb700UMQ7/HxzPszQ/IsiCoqWnvMuyfxJ5E4p/
+DSDB0/bQI88oubUe/1kV4XO7frevMEwn6/TX9q0D8ynVu7VPbXTHPhInFMK0aYkU
+Czd0W0/Jvyq5pZMk2dW5b3soI/DBahxryzYl0dH239/R6kkPWISnn+qwRN1JvB9Z
+zj4PCC6GiMizIqdYIjpnfaOLtxmymle1K+24hia9ATA/GxVEsPV+SkE+kn1uYBLG
+fyU5GBw/k58LkEPzAmhkqF0O9vl8qtnGIe0K84o=
+=WTxG
+-----END PGP PUBLIC KEY BLOCK-----
A => content/contribution/_index.md +23 -0
@@ 1,23 @@
+---
+title: Contribution Guide
+description: "Guide on contributing to my projects"
+---
+
+To contribute to any of my projects, be sure to familiarise yourself
+with [git](https://git-scm.com/) as this is what the projects use
+for [version control](https://en.wikipedia.org/wiki/Version_control).
+
+Once you are familiar with git and have commited your changes. Make
+sure git is setup to send patches by email, check out this tutorial
+for an interactive guide on setting up email with git!
+
+<https://git-send-email.io/>
+
+Make sure to send the patch to the appropriate mailing list, as
+listed on the project's page. **Note:** Sending patches using your
+email client or other means than `git send-email` will break your
+patches, making it difficult to apply!
+
+Contribution is highly appreciated!
+
+You can view other guides below.
A => content/contribution/c-contribution.md +9 -0
@@ 1,9 @@
+---
+title: Contribution Guidelines for C projects
+BackNav: 1
+---
+
+Read [Rob Pike's Notes on Programming in
+C](http://doc.cat-v.org/bell_labs/pikestyle).
+
+Be sure not to include binary blobs with your commit.
A => content/contribution/code-of-conduct.md +59 -0
@@ 1,59 @@
+---
+title: Code of Conduct
+BackNav: 1
+---
+
+All projects (including mailing lists) follow [The Lunduke Code of Conduct](http://lunduke.com/pages/codeofconduct/).
+
+Below is the complete text of the Code of Conduct.
+
+## The Lunduke Code of Conduct
+
+Be Excellent to Each Other.
+
+
+### FAQ
+
+Q: Wait. That's it?
+
+A: Yup.
+
+Q: But... but... it's only 5 words!
+
+A: It is? Cool!
+
+Q: Isn't that too short to be a viable Code of Conduct?
+
+A: Nah.
+
+Q: It's too vague! How would you enforce this?!?
+
+A: By being excellent to each other.
+
+Q: What if someone violates this Code of Conduct?
+
+A: I trust you to figure it out.
+
+Q: What if someone talks about politics I disagree with?!?!!?
+
+A: I know a guy who votes for Papa Smurf in every Presidential election. He's a pretty cool dude.
+
+Q: I'm super angry about something! And a person likes the thing making me angry! What do I do?
+
+A: I dunno. Try *hugs*?
+
+Q: Are virtual hugs (such as "*hugs*" and animated .GIFs of teddy bears hugging) excellent?
+
+A: Most excellent.
+
+Q: Huh. Seems so simple!
+
+A: I know, right?
+
+Q: I like you!
+
+A: I like you, too!
+
+
+
+The Lunduke Code of Conduct is free for you to use however you like. I [Bryan Lunduke] kinda just copied it from Bill & Ted's Excellent Adventure, anyway.
A => content/contribution/go-contribution.md +16 -0
@@ 1,16 @@
+---
+title: Contribution Guidelines for Go projects
+BackNav: 1
+---
+
+Make sure to run '`go fmt ./...`' in the project's root
+directory before committing your changes. This formats
+your code according to Go's formatting style automatically.
+
+Many of the Go projects hosted have a `Makefile` which automatically
+does the formatting, so you should make sure to run `make` before committing,
+making sure the project is formatted properly, and the tests/build are
+successful.
+
+Be sure to document exported variables and functions, so documentation could
+be generated.
A => content/contribution/mailing.md +16 -0
@@ 1,16 @@
+---
+title: Mailing list guide
+BackNav: 1
+---
+
+When sending emails in the mailing list, make sure that;
+
+
+- your emails are plain text, HTML emails are rejected by the server
+- when you reply, cut parts which you are not directly responding to
+- the lines in your email does not exceed 72 characters
+- if you use PGP, attach your PGP signature instead of including it inline
+
+
+
+_This is a tl;dr of the mailing list ettiquette found [here](https://man.sr.ht/lists.sr.ht/etiquette.md)._
A => content/gallery-faq.md +35 -0
@@ 1,35 @@
+---
+title: Gallery FAQ
+---
+
+[Go back to the gallery](/gallery)
+
+### Are the pictures downloaded from the web?
+
+No, I have took all of the pictures and released them under a
+creative commons license.
+
+### Which camera do you use?
+
+I use my Samsung Galaxy Note 8 to take all of the photos.
+
+### Why don't you use something like Instagram or Flickr?
+
+These services do not fit my need, Instagram by Facebook is a
+social media platform which compresses images to a lower quality
+and doesn't provide an option to download them. While Flickr
+started deleting pictures of non-paying users, requiring them
+to pay an expensive subscription[^1].
+
+It makes more sense to self-host my gallery than to rely on a
+service that can shut down my account or delete my images at any point.
+
+### Why are faces blurred?
+
+According to UAE laws, you need consent before taking a picture of someone. So
+all pictures of faces are blurred.
+
+If you have a problem in any of the photos in my gallery, contact me
+via my email: me @ this domain and I'll do my best to resolve the issue.
+
+[^1]: <https://www.theguardian.com/technology/2018/nov/02/flickr-delete-millions-photos-reduce-allowance-free-users>
A => content/gallery/_index.md +11 -0
@@ 1,11 @@
+---
+title: "Gallery"
+description: "Random pictures around the world"
+---
+
+Welcome to my gallery! Here is where I post high-resolution (uncompressed) travel pictures.
+All photos are released under a Creative Commons license, which
+means you can reuse the pictures as long as you link back and it is not for commercial purposes.
+
+> [Frequently Asked Questions](/gallery-faq)
+
A => content/gallery/apply-rot.sh +4 -0
@@ 1,4 @@
+#!/bin/sh
+cd $1
+mogrify -auto-orient *.jpg
+
A => content/gallery/artis-zoo.md +13 -0
@@ 1,13 @@
+---
+title: Artis Royal Zoo
+date: 2019-08-22
+license: CC-BY-NC-SA-4.0
+location: ["Amsterdam", "Netherlands"]
+lat: 52.366111
+lon: 4.916667
+---
+
+My visit to the Artis Royal Zoo, which is
+founded in 1838 and has some 900 animal species.
+It is one of the oldest zoos of Europe.
+
A => content/gallery/edinburgh-citycentre.md +12 -0
@@ 1,12 @@
+---
+title: Visiting Edinburgh for the first time
+date: 2018-07-16
+license: CC-BY-NC-SA-4.0
+location: ["Edinburgh", "United Kingdom"]
+lat: 55.9514
+lon: -3.2001
+---
+
+Edinburgh is the capital city of Scotland, which is a country on the northern
+part of the United Kingdom. I took these pictures when visiting Edinburgh for
+the first time.
A => content/gallery/holyrood.md +11 -0
@@ 1,11 @@
+---
+title: Over the cliffs of Holyrood Park
+date: 2018-07-23
+license: CC-BY-NC-SA-4.0
+location: ["Holyrood Park", "Edinburgh", "United Kingdom"]
+lat: 55.9496
+lon: -3.1714
+---
+
+Holyrood Park is a public royal park in central Edinburgh. In this gallery, you
+will see pictures of Arthur's Seat and a view of the city from the edge of the cliffs.
A => content/gallery/hortus-botanicus.md +12 -0
@@ 1,12 @@
+---
+title: Hortus Botanicus (botanical garden)
+date: 2019-08-28
+license: CC-BY-NC-SA-4.0
+location: ["Amsterdam", "Netherlands"]
+lat: 52.3668
+lon: 4.9079
+---
+
+My visit to the botanical garden in Amsterdam, which was
+established in 1638. The garden has a cafe which uses some
+ingredients from the garden.
A => content/gallery/make-thumbs.sh +7 -0
@@ 1,7 @@
+#!/bin/bash
+cd $1
+mkdir thumbs
+for filename in *.jpg; do
+ convert -define jpeg:size=720x400 $filename \
+ -thumbnail '720x400>' thumbs/$filename
+done
A => content/gallery/morning-heriot-watt.md +11 -0
@@ 1,11 @@
+---
+title: Early Morning at Heriot-Watt University
+date: 2018-10-08
+license: CC-BY-NC-SA-4.0
+location: ["Heriot-Watt University", "Edinburgh", "United Kingdom"]
+lat: 55.9110702
+lon: -3.3188644
+---
+
+These pictures were taking at Heriot-Watt University Edinburgh (Riccarton)
+campus at 7am (before sunrise).
A => content/gallery/optimise.sh +3 -0
@@ 1,3 @@
+#!/bin/bash
+cd $1
+jpegoptim *.jpg
A => content/gallery/rijksmuseum.md +10 -0
@@ 1,10 @@
+---
+title: Rijksmuseum (Dutch National Museum)
+date: 2019-08-18
+license: CC-BY-NC-SA-4.0
+location: ["Amsterdam", "Netherlands"]
+lat: 52.36
+lon: 4.885278
+---
+
+My visit to the Rijksmuseum in Amsterdam.
A => content/gallery/stedelijk.md +11 -0
@@ 1,11 @@
+---
+title: Stedelijk Museum Amsterdam (contemporary arts museum)
+date: 2019-08-20
+license: CC-BY-NC-SA-4.0
+location: ["Amsterdam", "Netherlands"]
+lat: 52.358056
+lon: 4.879722
+---
+
+My visit to the Stedelijk Museum Amsterdam, which displays modern
+and contemporary arts.
A => content/now/_index.md +15 -0
@@ 1,15 @@
+---
+title: What I'm Doing Now
+---
+
+*This is a [now page](https://nownownow.com/about), which is where I write a
+summary of what I am doing right now.*
+
+**Last updated:** 15th May 2020
+
+I'm currently a Computer Science student at Heriot-Watt University, stuck at
+home working on internships, enjoying my last summer break of my undergraduate
+study. All the work done during my current internships will be released under
+an open-source license, more details coming soon.
+
+I also try to manage my time and work on my existing open-source projects.
A => content/projects/4DG.md +59 -0
@@ 1,59 @@
+---
+title: 4DG
+GitURL: _4dg
+section: "Web Applications"
+MailingList: general
+License: "GPL-3.0-only"
+Language: Go
+date: 2018-05-16
+GoDoc: true
+HasBuilds: true
+Screenshot: "4DG.gif"
+Description: "A 4D movie scripting program which runs on a Raspberry Pi using GPIO."
+Usability: 1
+---
+
+### 1. Purpose
+
+
+The goal of this program is to allow anyone to create a 4D movie script. When run on a Raspberry Pi, the program will allow you to control Raspberry Pi's GPIO pins.
+
+The program can be controlled using a web interface, and is written in Go.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go
+- Git
+
+A Raspberry Pi is also preferred, otherwise the program would
+run in simulation mode.
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi, and is distributed under
+the GPLv3.
+
+
+### 4. Download and install
+
+```sh
+$ go get -u git.sr.ht/~humaid/_4dg
+$ go install git.sr.ht/~humaid/_4dg
+```
+
+### 5. Usage
+If running on a Raspberry Pi, the program should run as
+root, otherwise GPIO couldn't be accessed.
+
+```sh
+$ _4dg run
+```
+
+### 6. To-Do
+
+- [ ] Unit testing
+- [ ] Finish player interface
+- [ ] Add different position format
+
A => content/projects/CowChina.md +78 -0
@@ 1,78 @@
+---
+title: CowChina
+GitURL: cowchina
+MailingList: general
+section: "Command-line Tools"
+License: MIT
+Language: Go
+date: 2017-05-28
+GoDoc: true
+HasBuilds: true
+Description: "CowChina is a logger for a variant of Spades called Hokm. It detects invalid moves (cheating) and winners."
+Usability: 2
+---
+
+### 1. Description
+CowChina is a logger for a variant of the Spades playing card game. It logs the moves, invalid cards (cheating) and winners.
+
+This could only be used with our variant of Spades, called Hokm.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go
+- Git
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi, and is distributed
+under the MIT license.
+
+
+### 4. Download and install
+
+```sh
+$ go get -u git.sr.ht/~humaid/cowchina
+$ go install git.sr.ht/~humaid/cowchina
+```
+
+### 5. Usage
+
+To run the program:
+```sh
+$ cowchina
+```
+
+To begin, the names of the four players, the
+highest bid, bidding suit chosen, and highest bidding team is
+entered.
+
+Then the each card is inputed. Below is a cheat sheet of possible
+inputs.
+
+#### 5.1. Input cheat sheet
+
+| Input | Description |
+| ---- | ----- |
+| `ca` | Ace of Clubs |
+| `da` | Ace of Diamonds |
+| `ha` | Ace of Hearts |
+| `sa` | Ace of Spades |
+| `c{6-9}` | Clubs 6 to 9 |
+| `s{6-9}` | Diamonds 6 to 9 |
+| `h{6-9}` | Hearts 6 to 9 |
+| `s{6-9}` | Spades 6 to 9 |
+| `c{j,q,k}` | Clubs {jack, queen, king} |
+| `d{j,q,k}` | Diamonds {jack, queen, king} |
+| `h{j,q,k}` | Hearts {jack, queen, king} |
+| `s{j,q,k}` | Spades {jack, queen, king} |
+| `z` | Black Joker |
+| `x` | Red Joker |
+| `{enter}` | PASS |
+| `{tab}` | Go back **(TODO)** |
+| `:<id>` | Jump to player **(TODO)** |
+
+
+
+
A => content/projects/G1MDecompiler.md +49 -0
@@ 1,49 @@
+---
+title: G1M Decompiler
+GitURL: g1mdecompiler
+section: "Command-line Tools"
+MailingList: general
+License: MIT
+Language: Go
+date: 2017-04-26
+GoDoc: true
+HasBuilds: true
+Description: "A simple Casio Basic decoder for '.g1m' files generated by Casio calculators."
+Usability: 3
+---
+
+### 1. Purpose
+The goal of G1M Decompiler is to allow programmers to decode Casio Basic's "`.g1m`"
+file into a readable text similarly what is shown on the calculator. I have
+created this because the only available program to read G1M (Casio Basic) files
+does not run on Linux, and there is no way to read the files.
+
+This is a one-way converter, and not all symbols are supported by this program (most
+common symbols are).
+
+### 2. Requirements
+
+The following packages must be installed on your system
+
+- Go
+- Git
+
+You also need a Casio Basic file to decode.
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi, and is distributed under
+the MIT license.
+
+### 4. Download and install
+
+```sh
+$ go get -u git.sr.ht/~humaid/g1mdecompiler
+$ go install git.sr.ht/~humaid/g1mdecompiler
+```
+
+### 5. Usage
+The program outputs the decoded program to standard output.
+```sh
+$ g1mdecompiler [file] > [output]
+```
A => content/projects/JukeboxHopperMod.md +46 -0
@@ 1,46 @@
+---
+title: 'Jukebox Hopper Mod'
+GitURL: jukeboxhopper
+MailingList: general
+section: "Games"
+License: None
+Language: Java
+date: 2018-12-17
+Screenshot: "JukeboxHopperMod.gif"
+Description: "A simple Minecraft mod which allows you to use hoppers to insert records into jukeboxes."
+Usability: 4
+---
+
+### 1. Description
+
+
+This is a simple Minecraft mod which allows players to use
+a hopper to insert a record into a Jukebox.
+
+### 2. Requirements
+
+Requirements of using this mod:
+
+- [Mod Coder Pack](https://minecraft.gamepedia.com/Programs_and_editors/Mod_Coder_Pack) for 1.12
+- [Minecraft](https://minecraft.net) 1.12
+- Java 8
+
+### 3. Installation
+
+1. Copy the `src` directory into your MCP workspace.
+2. Locate the method `transferItemsOut()` in `net.minecraft.tileentity`.
+3. Add the following snippet at the beginning of the method:
+
+```java
+// Make sure to import the package
+if(JukeboxHopperMod.canTransferRecord(this)){
+ JukeboxHopperMod.transferRecord(this);
+ return true;
+}
+```
+
+You should be able to have compile and run the game.
+
+This is tested to work with Minecraft 1.12, it is possible to use
+this mod with other versions but may require some alternations
+to the code.
A => content/projects/Questions.md +77 -0
@@ 1,77 @@
+---
+title: Question (.NET)
+GitURL: question
+section: "Libraries"
+License: MIT
+Language: dotNET
+date: 2015-02-10
+NotAccepting: true
+Description: "A library of classes which allows you to create questions easily for Console Applications."
+Usability: 4
+---
+
+### 1. Description
+
+Question is a simple class which allows you to create a questionaire in C#.NET or VB.NET.
+This is done as a school project in early 2015, and is released under the MIT license.
+
+### 2. Requirements
+
+This software might require proprietary software to run, which I no longer use. It may be possible to use Mono Runtime.
+
+### 3. Usage
+
+#### 3.1 Visual Basic
+
+```basic
+' Clone the object
+Dim MyQuestion As Question
+
+' Initialize
+MyQuestion = New Question(
+1, ' Question number/ID, will be displayed to user
+"What is CIL?", ' The Question
+"Code Intermedia Language", ' Option A
+"Common Interface Locale", ' Option B
+"Common Intermediate Language", ' Option C (Correct answer)
+"Common Integer Language", ' Option D
+Question.QuestionOption.C) ' The correct answer (In the case, C)
+
+' Display the question
+MyQuestion.Run()
+
+' Check if the user passed that question
+If MyQuestion.Passed Then
+ Console.WriteLine("Good job!")
+Else
+ Console.WriteLine("You could do better next time!")
+End If
+```
+#### 3.2 C Sharp
+
+```c#
+// Clone the object
+Question myQuestion;
+
+// Initialize
+myQuestion = new Question(
+ 1, // Question number/ID, will be displayed to user
+ "What is CIL?", // The Question
+ "Code Intermedia Language", // Option A
+ "Common Interface Locale", // Option B
+ "Common Intermediate Language", // Option C (Correct answer)
+ "Common Integer Language", // Option D
+ Question.QuestionOption.C); // The correct answer (In this case, C)
+
+// Display the question
+myQuestion.Run();
+
+// Check if the user passed that question
+if (myQuestion.passed())
+{
+ Console.WriteLine("Good Job!");
+}
+else {
+ Console.WriteLine("You could do better next time!");
+}
+```
A => content/projects/SpongePluginsArchive.md +20 -0
@@ 1,20 @@
+---
+title: Sponge Plugins Archive
+GitURL: SpongePluginsArchive
+section: "Games"
+License: MIT
+Language: Java
+date: 2016-05-31
+NotAccepting: true
+Description: "Archive repository of my Sponge plugins."
+Usability: 4
+---
+This is an archive repository to my three old Sponge plugins, which I am sure no longer works in the current version of Sponge server.
+
+This repository includes;
+
+- PlayerLogger: A simple Sponge plugin which logs player events.
+- ChatLimiter: A simple Sponge plugin which allows you to limit the rate of chat messages and commands.
+- SignColours: A simple plugin that colours signs with permissions.
+
+All of which are released under the MIT license. The code was last updated in 2015.
A => content/projects/WhatsMorse.md +50 -0
@@ 1,50 @@
+---
+title: WhatsMorse
+GitURL: whatsmorse
+MailingList: general
+section: "Web Applications"
+License: MIT
+Language: Go
+date: 2018-01-06
+site: https://morse.hmksq.ae
+GoDoc: true
+HasBuilds: true
+Screenshot: "WhatsMorse.gif"
+Description: "A morse code web messaging application written in a two-hour hackaton."
+Usability: 4
+---
+### 1. Description
+
+
+WhatsMorse is a web messaging application which translates all your messages to morse code written in a two hour ["Stupid" Hackathon by Transcend](https://www.meetup.com/transcenddubai/events/245505285/) in January of 2018.
+The goal of the hackathon was to create something useless (can be anything, not limited to computer software).
+
+The web app can be accessed from the URL of the project above.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go
+- Git
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi, and is distributed
+under the MIT license.
+
+### 4. Download and install
+
+```sh
+$ go get -u git.sr.ht/~humaid/whatsmorse
+$ go install git.sr.ht/~humaid/whatsmorse
+```
+
+### 5. Usage
+To run the web app, `$PORT` must be set in the enviornment.
+```sh
+$ export PORT=8080
+$ whatsmorse
+```
+The web app will be accessible at `http://localhost:8080`.
+
A => content/projects/XMath.md +31 -0
@@ 1,31 @@
+---
+title: XMath
+section: "Mobile Applications"
+date: 2017-12-06
+site: https://play.google.com/store/apps/details?id=appinventor.ai_humaid_andr.XMath&hl=en_US
+Description: "A tiny learning management system for Android."
+Usability: 3
+---
+
+This is a coursework project for the Interactive System (F27IS) course at Heriot-Watt
+University. This Android application is made using MIT App Inventor 2, and below
+is the description of the application as published on the Google Play Store.
+
+Download the App Inventor file: [`XMath.aia`](XMath.aia) *(160K)*
+
+----------
+
+XMath is a tiny learning management system application for Android, it helps
+teachers and tutors to setup mathematical questions. The questions can be setup
+and solved on the same device, or can be setup over Bluetooth so that the
+instructor could beam the questions to students devices. And then students can
+send back the answers to the instructor's device.
+
+The application has two accounts, a student's account and an instructor's
+account. The instructor is able to set up the quiz and review the answers
+Student are able to solve the quiz if it is set up. And the instructor has
+options to host a Bluetooth server for devices setup on Bluetooth mode.
+
+You can have up to ten times tables questions (for historical reasons). And the
+instructor is required to set up a new quiz each time a quiz is finished, or
+receive the quiz over Bluetooth if it is setup on Bluetooth mode.
A => content/projects/_index.md +11 -0
@@ 1,11 @@
+---
+title: Projects
+description: "A list of my open-source projects"
+---
+Below is a list of my projects, most of which are released under
+an open-source license. Usage and installation instructions are included
+in each of the projects page.
+
+Check out the [contribution guide](/contribution).
+Contribution is welcome and accepted. If you use any of my projects,
+I wish to hear what you think of it.
A => content/projects/bmo.md +47 -0
@@ 1,47 @@
+---
+title: bmo Robot Animations
+section: "Others"
+GitURL: bmo
+Language: PHP
+License: None
+date: 2018-11-12
+GoDoc: false
+NotAccepting: true
+Description: "Robot's face animations for Interaction Design expo project."
+---
+
+### Description
+
+This repository contains the files used in our Interaction Design expo
+project, where BMO (Best Medical Operator) is a medicine dispensing
+robot for the elderly. It also has a simple PHP application to allow
+the "wizard" to control the robot's facial expression.
+
+Images and animations are created using GIMP.
+
+Below is a list of BMO's facial expression images and animations.
+
+#### sleeping.gif
+
+
+#### straightface.png
+
+
+#### simplesmile.png
+
+
+#### simplesmileblink.gif
+
+
+#### happy.png
+
+
+#### happyblink.gif
+
+
+#### blushing.gif
+
+
+#### worried.png
+
+
A => content/projects/bmo/blushing.gif +0 -0
A => content/projects/bmo/happy.png +0 -0
A => content/projects/bmo/happyblink.gif +0 -0
A => content/projects/bmo/simplesmile.png +0 -0
A => content/projects/bmo/simplesmileblink.gif +0 -0
A => content/projects/bmo/sleeping.gif +0 -0
A => content/projects/bmo/straightface.png +0 -0
A => content/projects/bmo/worried.png +0 -0
A => content/projects/cloudflare-ddns-client.md +40 -0
@@ 1,40 @@
+---
+title: Cloudflare DDNS Client
+GitURL: cloudflare-ddns-client
+section: "Command-line Tools"
+MailingList: general
+License: BSD-2-Clause
+Language: Go
+date: 2020-06-10
+GoDoc: false
+IssueTracker: false
+Description: "A simple Cloudflare Dynamic DNS Client."
+Usability: 4
+---
+
+### 1. Description
+
+This is a simple Cloudflare Dynamic DNS client, which updates a record to the
+current public IP address. I have created this as I couldn't find a very simple
+solution to this very simple problem.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go *(tested with 1.14)*
+
+### 3. Installation and Usage
+
+```
+$ go install git.sr.ht/~humaid/cloudflare-ddns-client
+$ export APIKey=<API KEY here>
+$ export Zone=<Zone ID here>
+$ export RecordName=<Full record name here, e.g. foo.example.com>
+$ cloudflare-ddns-client
+```
+
+You will have to [create an API token](https://dash.cloudflare.com/profile/api-tokens)
+which has the permission to edit zone DNS (`Zone.DNS`).
+
+This program will check every minute unless interrupted.
A => content/projects/f27wd-cw2-nonamewebteam.md +10 -0
@@ 1,10 @@
+---
+title: F27WD Coursework 2 Submission
+GitURL: f27wd-cw2-nonamewebteam
+License: None
+Language: PHP
+date: 2018-03-25
+NotAccepting: true
+Description: "Heriot-Watt University F27WD CW2 Submission"
+hidden: true
+---
A => content/projects/ff-format-patch.md +95 -0
@@ 1,95 @@
+---
+title: Fast-Forward with steps formatting
+GitURL: ff-format-patch
+section: "Command-line Tools"
+MailingList: general
+License: "GPL-2.0-or-later"
+Language: C
+date: 2019-10-24
+IssueTracker: true
+Description: "A patch for FF v2.3 to allow steps to be formatted for humans."
+Usability: 4
+---
+
+### 1. Description
+
+This is a patch for [Fast-Forward](https://fai.cs.uni-saarland.de/hoffmann/ff.html)
+which allows the steps to be formatted in a human-readable way, by providing a
+'format file' as a parameter.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Unix patch utility
+- GNU Make
+- A C compiler (defaults to gcc)
+- GNU Bison
+- flex
+
+This patch is written for FF v2.3, and will probably not work with later
+versions.
+
+### 3. Copying and contributing
+
+Fast-Forward is released under the GNU General Public License version 2 or
+later, and so is the patch.
+
+### 4. Downloading and patching
+
+- [`steps-format-v1.patch`](steps-format-v1.patch) *(12K)*
+- [`FF-v2.3.tgz`](https://fai.cs.uni-saarland.de/hoffmann/ff/FF-v2.3.tgz)
+ *(72K)*
+
+Extract FF, and copy the patch file in the extracted directory. Then run the
+following command to apply the patch and compile:
+
+```sh
+$ patch < steps-format-v1.patch
+$ make
+```
+Then you will have a binary with the patch.
+
+### 5. Example Usage
+
+The patch adds an additional parameter `-h` to the program, which allows you
+to pass a 'format file.' For example:
+
+```sh
+$ ./ff -o domain.pddl -f prob.pddl -h problem-format.txt
+```
+
+And let's say we have a particular `personWalk` action:
+```lisp
+(:action personWalk
+ :parameters
+ (?from - room
+ ?to - room
+ ?person - person)
+```
+To format the output of this action, we can add the following to our format
+file:
+```text
+PERSONWALK $2 walks from the $0 to the $1
+```
+Now that we run the command, we should get:
+```text
+[...]
+ff: found legal plan as follows
+
+step 0: PERSONWALK HUMAID walks from the KITCHEN to the LIVING-ROOM
+[...]
+```
+
+### 6. Binary builds
+
+Binary compiled and linked on `Linux kudu 4.19.0-6-amd64 #1 SMP Debian
+4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux`. Should work on most modern
+Linux x86_64 glibc systems.
+
+- [`ff`](ff) *(936K)*
+
+### 7. Change log
+
+- v0.1 *(Oct 24 2019)*
+ - Initial release
A => content/projects/ff-format-patch/ff +0 -0
A => content/projects/ff-format-patch/steps-format-v1.patch +288 -0
@@ 1,288 @@
+diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/ff.h FF-v2.3-step-format/ff.h
+--- FF-v2.3/ff.h 2016-10-04 12:31:46.000000000 +0100
++++ FF-v2.3-step-format/ff.h 2019-10-24 11:36:39.523041142 +0100
+@@ -357,6 +357,7 @@
+ char path[MAX_LENGTH];
+ char ops_file_name[MAX_LENGTH];
+ char fct_file_name[MAX_LENGTH];
++ char format_file_name[MAX_LENGTH];
+ int display_info;
+ int debug;
+
+diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/format.c FF-v2.3-step-format/format.c
+--- FF-v2.3/format.c 1970-01-01 01:00:00.000000000 +0100
++++ FF-v2.3-step-format/format.c 2019-10-24 11:36:39.523041142 +0100
+@@ -0,0 +1,82 @@
++#include "format.h"
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++
++StepFormatNode * headStepFormat;
++StepFormatNode * tailStepFormat;
++
++void addStepFormat(StepFormat *format) {
++ if (format == NULL)
++ return;
++
++ StepFormatNode *newNode = malloc(sizeof(StepFormatNode));
++ newNode->node = format;
++ newNode->next = NULL;
++
++ if (tailStepFormat == NULL) {
++ tailStepFormat = newNode;
++ headStepFormat = newNode;
++ } else {
++ tailStepFormat->next = newNode;
++ tailStepFormat = newNode;
++ }
++}
++
++StepFormat * getAction(char *name) {
++ if (headStepFormat == NULL || name == NULL)
++ return NULL;
++
++ StepFormatNode * tempNode = headStepFormat;
++ while(tempNode != NULL) {
++ if(strcmp(name, tempNode->node->actionName)==0) {
++ return tempNode->node;
++ }
++ tempNode = tempNode->next;
++ }
++ return NULL;
++}
++
++int loadFormatFile(FILE *f) {
++ headStepFormat = NULL;
++ tailStepFormat = NULL;
++ char last[128];
++ size_t charPointer = 0;
++ int formatsCount = 0;
++
++ char ch = getc(f);
++ while (ch != EOF) {
++ if (ch != '\n') {
++ if (charPointer < sizeof(last)){
++ last[charPointer++] = ch;
++ }
++ } else {
++ if(charPointer < sizeof(last))
++ last[charPointer] = '\0';
++
++ if(charPointer >0) {
++ StepFormat *newFormat = malloc(sizeof(StepFormat));
++ memset(newFormat, '\0', sizeof(StepFormat));
++ // Get the action name and format
++ char *ptr = strtok(last, " ");
++ char * actionName = malloc(sizeof(last));
++ strcpy(actionName, ptr);
++ newFormat->actionName = actionName;
++ size_t size = strnlen(actionName, sizeof(last));
++ ptr = ptr +size;
++ ptr++;
++ char * stepFormat = malloc(sizeof(last));
++ strcpy(stepFormat, ptr);
++ newFormat->stepFormat = stepFormat;
++ // Add to linked list
++ addStepFormat(newFormat);
++ formatsCount++;
++ //printf("action: %s\n", newFormat->actionName);
++ //printf("format: %s\n", newFormat->stepFormat);
++ }
++ charPointer = 0;
++ }
++ ch = getc(f);
++ }
++ return formatsCount;
++}
+diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/format.h FF-v2.3-step-format/format.h
+--- FF-v2.3/format.h 1970-01-01 01:00:00.000000000 +0100
++++ FF-v2.3-step-format/format.h 2019-10-24 11:36:39.523041142 +0100
+@@ -0,0 +1,18 @@
++#include <stdio.h>
++
++typedef struct StepFormat StepFormat;
++typedef struct StepFormatNode StepFormatNode;
++
++struct StepFormat {
++ char *actionName;
++ char *stepFormat;
++};
++
++struct StepFormatNode {
++ StepFormat *node;
++ StepFormatNode *next;
++};
++
++void addStepFormat(StepFormat * format);
++int loadFormatFile(FILE *f);
++StepFormat * getAction(char *name);
+diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/main.c FF-v2.3-step-format/main.c
+--- FF-v2.3/main.c 2015-11-05 08:59:14.000000000 +0000
++++ FF-v2.3-step-format/main.c 2019-10-24 11:36:39.523041142 +0100
+@@ -73,7 +73,7 @@
+
+ #include "relax.h"
+ #include "search.h"
+-
++#include "format.h"
+
+
+
+@@ -493,6 +493,8 @@
+ /* same for fct file
+ */
+ char fct_file[MAX_LENGTH] = "";
++
++ char format_file[MAX_LENGTH] = "";
+
+ struct tms start, end;
+
+@@ -532,7 +534,14 @@
+ */
+ sprintf(ops_file, "%s%s", gcmd_line.path, gcmd_line.ops_file_name);
+ sprintf(fct_file, "%s%s", gcmd_line.path, gcmd_line.fct_file_name);
++ printf("file: %s\n", gcmd_line.format_file_name);
++ if (gcmd_line.format_file_name[0] != '\0') {
++ printf("ff: loading custom format file...\n");
++ sprintf(format_file, "%s%s", gcmd_line.path, gcmd_line.format_file_name);
++ FILE *f = fopen(gcmd_line.format_file_name, "r");
+
++ printf("ff: loaded formats for %d actions!\n", loadFormatFile(f));
++ }
+
+ /* parse the input files
+ */
+@@ -832,7 +841,8 @@
+ printf("\nOPTIONS DESCRIPTIONS\n\n");
+ printf("-p <str> path for operator and fact file\n");
+ printf("-o <str> operator file name\n");
+- printf("-f <str> fact file name\n\n");
++ printf("-f <str> fact file name\n");
++ printf("-h <str> format file name\n\n");
+ printf("-i <num> run-time information level( preset: 1 )\n");
+ printf(" 0 only times\n");
+ printf(" 1 problem name, planning process infos\n");
+@@ -893,6 +903,7 @@
+
+ memset(gcmd_line.ops_file_name, 0, MAX_LENGTH);
+ memset(gcmd_line.fct_file_name, 0, MAX_LENGTH);
++ memset(gcmd_line.format_file_name, 0, MAX_LENGTH);
+ memset(gcmd_line.path, 0, MAX_LENGTH);
+
+ while ( --argc && ++argv ) {
+@@ -919,6 +930,9 @@
+ case 'd':
+ sscanf( *argv, "%d", &gcmd_line.debug );
+ break;
++ case 'h':
++ strncpy( gcmd_line.format_file_name, *argv, MAX_LENGTH );
++ break;
+ default:
+ printf( "\nff: unknown option: %c entered\n\n", option );
+ return FALSE;
+diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/output.c FF-v2.3-step-format/output.c
+--- FF-v2.3/output.c 2016-10-04 12:31:46.000000000 +0100
++++ FF-v2.3-step-format/output.c 2019-10-24 11:36:39.523041142 +0100
+@@ -57,7 +57,7 @@
+ #include "ff.h"
+
+ #include "output.h"
+-
++#include "format.h"
+
+
+
+@@ -729,14 +729,75 @@
+ !a->pseudo_action ) {
+ printf("REACH-GOAL");
+ } else {
+- printf("%s", a->name );
+- for ( i = 0; i < a->num_name_vars; i++ ) {
+- printf(" %s", gconstants[a->name_inst_table[i]]);
+- }
++ StepFormat *format = getAction(a->name);
++ printf("%s", a->name );
++ if (format != NULL) {
++ char *formatted = malloc(sizeof(char)*256);
++ char *repChar = malloc(sizeof(char)*12);
++ strcpy(formatted, format->stepFormat);
++ for ( i = 0; i < a->num_name_vars; i++ ) {
++ sprintf(repChar, "$%d", i);
++ formatted = str_replace(formatted, repChar,
++ gconstants[a->name_inst_table[i]]);
++ }
++ printf(" %s", formatted);
++ free(repChar);
++ } else {
++ for ( i = 0; i < a->num_name_vars; i++ ) {
++ printf(" %s", gconstants[a->name_inst_table[i]]);
++ }
++ }
+ }
+
+ }
+
++// from: https://stackoverflow.com/a/779960
++// You must free the result if result is non-NULL.
++char *str_replace(char *orig, char *rep, char *with) {
++ char *result; // the return string
++ char *ins; // the next insert point
++ char *tmp; // varies
++ int len_rep; // length of rep (the string to remove)
++ int len_with; // length of with (the string to replace rep with)
++ int len_front; // distance between rep and end of last rep
++ int count; // number of replacements
++
++ // sanity checks and initialization
++ if (!orig || !rep)
++ return NULL;
++ len_rep = strlen(rep);
++ if (len_rep == 0)
++ return NULL; // empty rep causes infinite loop during count
++ if (!with)
++ with = "";
++ len_with = strlen(with);
++
++ // count the number of replacements needed
++ ins = orig;
++ for (count = 0; tmp = strstr(ins, rep); ++count) {
++ ins = tmp + len_rep;
++ }
++
++ tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
++
++ if (!result)
++ return NULL;
++
++ // first time through the loop, all the variable are set correctly
++ // from here on,
++ // tmp points to the end of the result string
++ // ins points to the next occurrence of rep in orig
++ // orig points to the remainder of orig after "end of rep"
++ while (count--) {
++ ins = strstr(orig, rep);
++ len_front = ins - orig;
++ tmp = strncpy(tmp, orig, len_front) + len_front;
++ tmp = strcpy(tmp, with) + len_with;
++ orig += len_front + len_rep; // move to next "end of rep"
++ }
++ strcpy(tmp, orig);
++ return result;
++}
+
+
+
+diff -ur --exclude makefile --exclude ff --new-file FF-v2.3/output.h FF-v2.3-step-format/output.h
+--- FF-v2.3/output.h 2010-06-21 09:38:27.000000000 +0100
++++ FF-v2.3-step-format/output.h 2019-10-24 11:36:39.523041142 +0100
+@@ -77,7 +77,7 @@
+ void print_Fact( Fact *f );
+ void print_ft_name( int index );
+ void print_op_name( int index );
+-
++char *str_replace(char *orig, char *rep, char *with);
+
+
+ void print_plan( void );
+
A => content/projects/godoc2markdown.md +60 -0
@@ 1,60 @@
+---
+title: godoc2markdown
+GitURL: godoc2markdown
+section: "Command-line Tools"
+License: BSD-2-Clause
+Language: Go
+date: 2019-10-11
+GoDoc: true
+LatestVersion: v0.1
+HasBuilds: true
+MailingList: general
+IssueTracker: true
+Description: "A program which converts Go Doc output to Markdown."
+Usability: 3
+---
+
+### 1. Description
+
+This is a simple Unix-like tool which allows you to pipe the output of `go doc`
+to generate Markdown.
+
+The purpose of this tool is to allow private Go projects generate Markdown
+documentation, where websites like [GoDoc](https://godoc.org) has no access
+to the repository.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go
+- Git
+- GNU Make
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi,
+and is distributed under the BSD 2 Clause license.
+
+### 4. Download and install
+
+```sh
+$ git clone https://git.sr.ht/~humaid/godoc2markdown
+$ cd godoc2markdown
+$ make install
+```
+
+### 5. Example Usage
+
+If you want to generate a Markdown of the package in the current directory,
+and save it to a file, you can run.
+
+```sh
+$ go doc -all . | godoc2markdown > DOCUMENTATION.md
+```
+
+### 6. Change log
+
+- v0.1 *(Oct 11 2019)*
+ - Initial release
+
A => content/projects/hmsh.md +50 -0
@@ 1,50 @@
+---
+title: hmsh
+GitURL: hmsh-go
+section: "Command-line Tools"
+MailingList: general
+License: BSD-2-Clause
+Language: Go
+date: 2019-04-13
+GoDoc: true
+HasBuilds: true
+IssueTracker: true
+LatestVersion: v0.2
+Description: "Humaid's un-POSIX-compliant shell."
+Usability: 2
+---
+
+### 1. Description
+
+hmsh is a very minimal shell, it still doesn't support all built-in shell commands.
+
+This program is rewritten in Go in September 2019, you can still find the old C source at
+[git.sr.ht/~humaid/hmsh](https://git.sr.ht/~humaid/hmsh).
+
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- go
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi,
+and is distributed under the BSD 2 Clause license.
+
+### 4. Download and compile
+
+```sh
+$ git clone git.sr.ht/~humaid/hmsh-go
+$ cd hmsh-go
+$ go build
+```
+
+### 5. Change log
+
+- v0.1 *(Apr 14 2019)*
+ - Initial release.
+- v0.2 *(Sep 15 2019)*
+ - Rewrite in Go.
+
A => content/projects/horse-site.md +23 -0
@@ 1,23 @@
+---
+title: Horse Riding Scheduler
+date: 2018-08-01
+section: "Web Applications"
+site: https://haro.team
+proprietary: true
+Description: "A web application for Equestrian Clubs to manage daily schedule of trainers and riders."
+draft: true
+---
+
+This is a web application for equestrian clubs to manage their daily schedule of trainers and riders. It
+allows the club to keep track of the horses and riders, generate reports and print formatted schedules.
+This project is written by me and my peers from university as a part of a small web development team.
+
+The goal of this application is to make it easier for clubs to manage schedules using a modern web-based
+solution, which is fast and reliable, and can run on any browser. Our focus is on making the app easy-to-use
+and platform-independent but remain still as powerful as traditional schedule management software.
+
+Team members who are involved in this project:
+
+- Humaid (me)
+- Akilan Selvacoumar ([website](http://akilan.io))
+- Rikesh Makwana ([website](http://rikeshmm.com))
A => content/projects/hstatus.md +62 -0
@@ 1,62 @@
+---
+title: hstatus
+GitURL: hstatus
+section: "Others"
+License: BSD-2-Clause
+Language: Rust
+date: 2020-04-12
+LatestVersion: v0.1
+HasBuilds: true
+MailingList: general
+IssueTracker: false
+Description: "A dwm status monitor updater with multiple timezones and COVID19 stats."
+Usability: 4
+---
+
+### 1. Description
+
+hstatus is a simple dwm status monitor updater. It currently includes:
+
+- Multiple timezones (Local and UK time, using [chrono])
+- Battery status
+- Load status
+- COVID19 status (with [caching], updates every 6 hours)
+
+The reason for creating this project was to learn [Rust].
+
+[chrono]: https://crates.io/crates/chrono
+[caching]: https://crates.io/crates/cached
+[Rust]: https://www.rust-lang.org/
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Rust and Cargo
+- Git
+- libX11-devel
+- dwm _(obviously)_
+
+And if you decide to keep the COVID19 status:
+
+- libressl-devel (or your system's equivalent)
+- curl
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi,
+and is distributed under the BSD 2 Clause license.
+
+### 4. Download and build
+
+```sh
+$ git clone https://git.sr.ht/~humaid/hstatus
+$ cd hstatus
+$ cargo build
+```
+
+### 6. Change log
+
+- v0.1 *(Apr 12 2020)*
+ - Initial release
+
A => content/projects/iglu.md +90 -0
@@ 1,90 @@
+---
+title: iglü
+section: "Others"
+date: 2020-04-23
+site: https://github.com/Nacdlow
+Description: "A smart home system of the future (group project)."
+Usability: 4
+---
+
+### What is this?
+
+[**Check out our documentary (YouTube)**](https://www.youtube.com/watch?v=KMfItuTf2jQ)
+
+As a part of a two-semester long Software Engineering project at Heriot-Wat
+University, we (a group of six students) have been asked to create a fictitious
+software engineering company which is building a smart home system of the
+future to a client. During the 7 months we have built:
+
+- A smart home system with a [plugin API (over RPC)](https://github.com/hashicorp/go-plugin)
+ as a responsive (progressive) web application.
+ - Includes a simulation module for testing.
+- A Minecraft server ([Spigot]) plugin for testing and demonstrating the
+ smart home system on an environment which we can control. Hooked using our
+ plugin API.
+- An internal wiki with training/learning material, log and recording of
+ meetings, style guides, member roles, research and brainstorming, etc.
+- A tool to allow us to generate Markdown documentation based on `go doc`, as
+ no good solution exists.
+- A custom DNS server which allows us to have specific responses to specific
+ domains (for testing on mobile devices).
+- A testing payments gateway with [Stripe].
+- A custom Raspbian distribution for use with our Raspberry Pi (enclosed in our
+ custom 3D-printed case), this enables iglü as a system service, and adds
+ debugging functionality (Ethernet gadget, serial console, pre-setup WPA2
+ Enterprise with wpa\_supplicant, etc).
+- A plugin packager (with GUI) which speeds up cross-compiling, compressing and
+ packaging plugins directly for the marketplace.
+- A marketplace website, generated with a static website generator ([Hugo]).
+
+### What tools were used?
+
+The core parts of the project (such as the web application server and plugin
+API) is written in [Go], but other languages have been used in different parts
+of the project, such as Java for the Minecraft plugin, [LaTeX] for
+collaborating on requirements specifications. Getting the e-ink display to work
+required us to modify the [Waveshare driver](https://github.com/waveshare/e-Paper)
+so we can display the output upside-down, which was a bit tricky. The program
+to update the e-ink display was written in Python.
+
+We even used tools such as [Adobe XD] for prototyping and usability testing,
+[Tinkercad] for creating the iglü case which was 3D printed (thanks to
+Edinburgh Hacklab). Other tools used were GIMP, Adobe Lightroom, Photoshop,
+After Effects, Premiere Pro, and Illustrator, these were used in making
+graphics, banners, logos, promotional video and other forms of artwork. We are
+lucky to have a group with a diverse range of skills.
+
+### Our group
+
+The group consists of:
+
+- [Alakbar Zeynalzade]\: Reporter and Organisational Manager
+- [Amaanullah Akram]\: Organisational and Technical Manager
+- [Humaid AlQassimi]\: Leader and Technical Manager
+- [Mark S Bird]\: Liaison
+- [Numan Ali]\: Technical Manager
+- [Ruaridh Mollica]\: Organisational Manager
+
+
+### Open-sourcing
+
+The projects are still pending to be released under an open-source license.
+
+The projects' source code can be found on our [GitHub organisation](https://github.com/Nacdlow).
+
+[Alakbar Zeynalzade]: https://www.linkedin.com/in/alakbarzeynalzade/
+[Amaanullah Akram]: https://www.linkedin.com/in/amaanakram/
+[Humaid AlQassimi]: https://humaidq.ae
+[Mark S Bird]: https://www.linkedin.com/in/mark-bird-/
+[Numan Ali]: https://github.com/n-ali1
+[Ruaridh Mollica]: https://www.linkedin.com/in/ruaridhmollica/
+
+[LaTeX]: https://www.latex-project.org/
+[Adobe XD]: https://www.adobe.com/products/xd.html
+[Spigot]: https://www.spigotmc.org/wiki/about-spigot/
+[Hugo]: https://gohugo.io
+[Go]: https://go.dev
+[Tinkercad]: https://www.tinkercad.com/
+[Stripe]: https://stripe.com/
+
+[AGPL license]: https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)
A => content/projects/learning-bot.md +34 -0
@@ 1,34 @@
+---
+title: Learning Bot
+date: 2019-06-04
+section: "Web Applications"
+site: https://github.com/peergramming/learning-bot
+Description: "A GitLab bot for providing programming advice based on code repair tools."
+Language: Go
+License: AGPL-3.0-only
+Usability: 4
+---
+
+### Overview
+
+The aim of this project is to create a GitLab bot which would download students
+code and generate a report containing advice on repairing issues found in the source code.
+
+This project is developed as an internship project at Heriot-Watt University.
+
+### Description
+
+This program uses [checkstyle] list the issues found in the students' code. The
+program parses that output and generates a report, posting it in the GitLab
+issue tracker of that project.
+
+Configuration is simple, and no database is required (when using SQLite). A bot
+user has to be created first on GitLab, and it must be added to the Learning
+Bot configuration.
+
+The Learning Bot checks multiple repositories concurrently, and the maximum
+number of workers can be defined in the configuration file.
+
+More details on setting up is available on the [GitHub project page](https://github.com/peergramming/learning-bot).
+
+[checkstyle]: https://checkstyle.org/
A => content/projects/neatnote.md +128 -0
@@ 1,128 @@
+---
+title: Neat Note
+GitURL: neatnote
+MailingList: general
+section: "Web Applications"
+License: AGPL-3.0-only
+Language: Go
+date: 2019-12-29
+GoDoc: true
+HasBuilds: true
+IssueTracker: true
+Description: "A Lobsters-like web app for university students to post notes and question."
+LatestVersion: v0.3.3
+Usability: 4
+---
+### 1. Description
+
+This is a web app which allows students to share their lecture notes, helpful
+resources, start discussions, or ask questions. This site is separated into
+different sections for different courses.
+
+Users are authenticated by emailing the users a one-time password to their
+university email address, which also confirms that they are either students or
+faculty of that university.
+
+Markdown, HTML, and LaTeX are supported in comments and posts, so students are
+able to write notes in any way they are comfortable with. [goldmark] is used
+for rendering Markdown, and [bluemonday] sanitizes the output which includes
+user added HTML. LaTeX is rendered using [MathJax] on the client side.
+
+Users are able to upvote posts, and posts with more upvotes (called iota), will
+appear on top. This is somewhat similar to upvoting in Hacker News or Reddit,
+which many are familiar with.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go *(tested with 1.13)*
+- Git
+- GNU Make
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi, and is distributed under the
+AGPL 3.0 only license. This means if you make your
+own fork of this app, you must release its source to its users under the
+same license.
+
+### 4. Downloading and running
+
+```sh
+$ git clone https://git.sr.ht/~humaid/neatnote
+$ cd neatnote
+$ make
+```
+
+### 5. Setup & Usage
+Running the web server will automatically generate a configuration file
+(`config.toml`) if it is not yet created.
+```sh
+$ ./neatnote run
+```
+The program will exit when run for the first time, prompting you to configure
+the program. Check out the [configuration documentation](https://godoc.org/git.sr.ht/~humaid/neatnote/modules/settings#DatabaseConfiguration).
+
+If you are using the MySQL driver you must create a table with the same name as
+the user. You will have to also add the `session` table:
+
+```sql
+CREATE TABLE `session` (
+ `key` CHAR(16) NOT NULL,
+ `data` BLOB,
+ `expiry` INT(11) UNSIGNED NOT NULL,
+ PRIMARY KEY (`key`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+```
+
+You should then run the web server again, and login with your account. You can
+set your account as admin by running the following command:
+```sh
+$ ./neatnote set-admin admin@example.com
+```
+
+You may revoke the admin status by using the `--status false` flag.
+
+The last thing to do is to add the courses needed on the web interface, using
+the admin account.
+
+### 6. Change log
+
+- v0.3.3 *(Feb 10 2020)*
+ - Fixes [a security issue](https://lists.sr.ht/~humaid/general/%3C20200210185437.338764ef%40serow%3E).
+- v0.3.2 *(Jan 13 2020)*
+ - Nicely format blockquotes and code blocks.
+ - Make badge radio button labels clickable in the profile.
+ - Fix issues with transparent images in dark mode and large images in
+ mobile view.
+- v0.3.1 *(Jan 12 2020)*
+ - Rename login validation to verification.
+ - Show badges in the registered users listing in admin dashboard.
+ - Show comments in request data, and hide empty fields.
+- v0.3 *(Jan 12 2020)*
+ - Add an admin dashboard, with option to suspend and view users.
+ - Add lite/print page for posts.
+ - Mobile friendlyness and dark theme improvements.
+ - Redirect for mismatching post/course ID.
+ - Other styling tweaks.
+ - Other templating and routing improvements.
+- v0.2 *(Jan 11 2020)*
+ - Revamp design to be more modern.
+ - Moved access control and context initialisation to middlewares to reduce
+ code duplication.
+ - Other improvements and bug fixes.
+- v0.1.1 *(Jan 10 2020)*
+ - Fixed bug where posts don't load for non-logged in users.
+- v0.1.0 *(Jan 9 2020)*
+ - Initial release.
+ - Has basic features such as:
+ - Authentication.
+ - Posting, editing posts and comments.
+ - Deleting posts and comments (admin).
+ - Voting and sorting.
+ - Badges, display names, anonymous posting.
+
+[goldmark]: https://github.com/yuin/goldmark
+[bluemonday]: https://github.com/microcosm-cc/bluemonday
+[MathJax]: https://www.mathjax.org/
A => content/projects/ns2-trace-go.md +74 -0
@@ 1,74 @@
+---
+title: NS2 Trace File Analysis Tool
+GitURL: ns2-trace-go
+MailingList: general
+section: "Web Applications"
+License: AGPL-3.0-only
+Language: Go
+date: 2019-11-24
+site: https://ns2.humaidq.ae
+GoDoc: true
+HasBuilds: true
+LatestVersion: v0.1
+IssueTracker: true
+Screenshot: "ns2-analysis.png"
+Description: "A trace analysis web app for Network Simulator 2 (ns2) trace files"
+Usability: 3
+draft: true
+---
+### 1. Description
+
+
+This web application allows you to analyse [trace files](http://nile.wpi.edu/NS/analysis.html)
+generated by [ns2](https://www.isi.edu/nsnam/ns/) (Network Simulator 2). It
+will generate the following:
+
+- Jitter graphs for all segments of the network
+- Number of:
+ - Received packets
+ - Dropped packets
+ - Lost packets.
+ - Collisions in the network
+ - Average hops
+ - Total active nodes
+ - Trace file entries (which are `tcp`, `udp`, or `cbr`)
+- Average delay
+- Total bandwidth used
+- Total network time
+- Network throughput
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go
+- Git
+
+You also need to have a trace file so use on the web application.
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi, and is distributed under the
+AGPL 3.0 only license. This means if you make your
+own version of this tool, you must release its source under the same license.
+
+### 4. Downloading and building
+
+```sh
+$ git clone https://git.sr.ht/~humaid/ns2-trace-go
+$ cd ns2-trace-go
+$ go build *.go
+```
+
+### 5. Usage
+You can optionally set the port, by setting the `PORT` environment variable.
+```sh
+$ ns2-trace-go
+```
+By default, it will use port `:4000`.
+
+### 6. Change log
+
+- v0.1 *(26 Nov 2019)*
+ - Initial release
A => content/projects/oww-prot.md +33 -0
@@ 1,33 @@
+---
+title: The Oww Protocol
+date: 2019-12-15
+Description: "A joke application protocol allowing users to send \"Oww\" messages to the server."
+---
+
+As the Great [Akilan](https://akilan.io) always said... "Oww". This protocol
+allows people to post message on a messaging board "the Oww board".
+
+There are two methods in this protocol. You can either:
+
+- Post a message in the following format:
+ `<Name>: Oww <optional message>`
+ e.g.
+ `Humaid: Oww that's cool`
+
+ All messages must start with "Oww" (case-insensitive), and the server should
+ always respond with an `Oww` if the request is successful.
+- Read the Oww board:
+ `Owws`
+
+
+You can give it a try if you have the `nc` (netcat) tool installed.
+
+```sh
+$ echo "Naeem: Oww" | nc humaidq.ae 1999
+$ echo "Owws" | nc humaidq.ae 1999
+```
+
+### Server Information
+
+The server is implemented in [Go](https://golang.org), you can [view the source
+here](https://git.sr.ht/~humaid/oww-prot/tree/master/main.go).
A => content/projects/pew-pew-shooter.md +49 -0
@@ 1,49 @@
+---
+title: "Pew Pew Shooter: Return of the Pews"
+GitURL: pew-pew-shooter
+section: "Games"
+License: GPL-3.0-only
+Language: Lua
+date: 2019-07-09
+LatestVersion: v0.2.1
+Description: "A programming-themed space shooter game written in Lua with LÖVE framework."
+Usability: 3
+---
+
+### 1. Description
+
+Pew Pew Shooter is a programming-themed space shooter game which allows you to
+shoot code and errors to enemies.
+
+This game is developed by me and [Abdelrahman Elkabbany](https://github.com/a9800)
+as to learn a new language and framework.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Git
+- Lua
+- LOVE *(tested with 0.9.1 and 11.2)*
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi and Abdelrahman Elkabbany,
+and is distributed under the GPL 3.0 license.
+
+### 4. Download and running
+
+```sh
+$ git clone https://git.sr.ht/~humaid/pew-pew-shooter
+$ cd pew-pew-shooter
+$ love .
+```
+## 5. Change log
+
+- v0.2.1 *(Aug 26 2019)*
+ - Added license file
+- v0.2 *(Aug 26 2019)*
+ - Randomise enemies/bullets images.
+ - Add pew sounds..
+- v0.1 *(Jul 9 2019)*
+ - Initial release.
A => content/projects/pomodoro.md +57 -0
@@ 1,57 @@
+---
+title: Pomodoro
+GitURL: c-pomodoro
+section: "Command-line Tools"
+MailingList: general
+License: BSD-2-Clause
+Language: C
+date: 2019-04-07
+GoDoc: false
+IssueTracker: true
+LatestVersion: v0.1
+Description: "A suckless pomodoro application written in C."
+Usability: 1
+draft: true
+---
+
+### 1. Description
+
+This is a suckless pomodoro command-line application I created, as I couldn't
+find any good pomodoro command-line application.
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- tcc (you need to modify Makefile to use a different compiler)
+- make
+- git
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi,
+and is distributed under the BSD 2 Clause license.
+
+### 4. Download and make
+
+```sh
+$ git clone git.sr.ht/~humaid/c-pomodoro
+$ cd c-pomodoro
+$ make all
+```
+
+### 5. Usage
+
+```sh
+$ ./pomodoro
+```
+
+### 6. Configuration
+
+To configure the timing, you have to modify the values in the header file
+`pomodoro.h`, and recompile.
+
+### 7. Change log
+
+- v0.1 *(Apr 7 2019)*
+ - Initial release
A => content/projects/screenshots/4DG.gif +0 -0
A => content/projects/screenshots/4DG.png +0 -0
A => content/projects/screenshots/JukeboxHopperMod.gif +0 -0
A => content/projects/screenshots/JukeboxHopperMod.png +0 -0
A => content/projects/screenshots/WhatsMorse.gif +0 -0
A => content/projects/screenshots/WhatsMorse.png +0 -0
A => content/projects/screenshots/ns2-analysis.png +0 -0
A => content/projects/screenshots/yabfig.jpg +0 -0
A => content/projects/shopsheet.md +64 -0
@@ 1,64 @@
+---
+title: ShopSheet
+GitURL: shopsheet
+MailingList: general
+Section: "Web Applications"
+License: AGPL-3.0-only
+Language: Go
+date: 2019-06-30
+GoDoc: true
+LatestVersion: v0.1
+HasBuilds: true
+Description: "An instant ecommerce website generator based on a spreadsheet file."
+Usability: 3
+---
+
+### 1. Description
+
+ShopSheet is a web app written in Go that converts a spreadsheet file
+into an ecommerce website instantly.
+
+This web app is developed by me and [Akilan Selvacoumar](https://akilan.io)
+as a challenge, we ended up implementing a working app in six hours.
+
+We chose this idea to tackle as a challenge because it solves a problem,
+most people know how to use and are familiar with using spreadsheets, so why not build
+an ecommerce website generator based on spreadsheets?
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go *(tested with 1.12)*
+- Git
+- LibreOffice *(program uses `soffice` to convert spreadsheets to csv files)*
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi and Akilan Selvacoumar,
+and is distributed under the AGPL 3.0 license.
+
+### 4. Download and install
+
+```sh
+$ go get -u git.sr.ht/~humaid/shopsheet
+$ go install git.sr.ht/~humaid/shopsheet
+```
+
+### 5. Usage
+
+Run with `go run main.go`.
+
+### 6. Change log
+
+- v0.1 *(Jun 30 2019)*
+ - Initial release
+
+### 7. To-do
+
+- [ ] Deploy to Heroku
+- [ ] Use [X]ORM
+- [ ] Template changes/fixes
+ - [ ] Clear cart when changing sites
+ - [ ] Allow custom templates
+ - [ ] Show add to cart confirmation
A => content/projects/sifrOS.md +57 -0
@@ 1,57 @@
+---
+title: sifrOS
+GitURL: sifros-mklive
+section: "Others"
+MailingList: general
+License: BSD-2-Clause
+Language: Bash
+date: 2018-06-22
+Description: "A secure and minimal Linux distribution."
+Usability: 2
+---
+
+### 1. Purpose
+The goal of sifrOS is to be a Linux distribution (based on
+[Void](https://voidlinux.org)) with more secure default configuration.
+
+Documentation of installation and configuration is planned.
+
+**Note**: This is not maintained and not very usable of yet. There are future
+plans in making this a more installable system.
+
+#### 1.1. Features and Goals
+
+- Few pre-installed packages (~130)
+- Uses minimal software, such as;
+ - musl (libc) instead of glibc ([comparison](https://www.etalabs.net/compare_libcs.html))
+ - runit instead of systemd
+ - [xbps](https://github.com/void-linux/xbps)
+- A clear and easy to follow documentation, that explains; *(TODO)*
+ - installation (with btrfs + LUKS full-disk encryption)
+ - setting up networking and ntp
+ - setting up a desktop environment (xorg, dwm, st)
+
+### 2. Requirements for building
+
+The following packages must be installed on your system.
+
+- xbps
+- xbps-reconfigure
+- qemu-user-static
+- squashfs-tools
+- xorriso
+
+### 3. Copying and contributing
+
+This is a fork of [Void Linux live image maker](github.com/void-linux/void-mklive)
+which is written by Juan RP, Dave Elusive and
+[Void contributors](https://github.com/orgs/void-linux/people) and is distributed
+under the BSD 2 Clause license.
+
+### 4. Building
+
+To build a sifrOS iso, run build script as root.
+
+```sh
+# ./build-sifrOS.sh
+```
A => content/projects/xmath/XMath.aia +0 -0
A => content/projects/yabfig.md +106 -0
@@ 1,106 @@
+---
+title: yabfig
+GitURL: yabfig
+section: "Command-line Tools"
+MailingList: general
+License: BSD-2-Clause
+Language: Go
+date: 2019-03-08
+GoDoc: true
+LatestVersion: v0.3
+HasBuilds: true
+Screenshot: "yabfig.jpg"
+Description: "A simple BF interpreter, debugger and linter written in Go."
+Usability: 4
+---
+
+### 1. Description
+
+
+yabfig is a [BF](https://en.wikipedia.org/wiki/brainfuck)
+interpreter written in Go. It has also been extended to lint
+code (by removing un-interpreted characters) and to include a gdb-style
+interpreter.
+
+
+
+### 2. Requirements
+
+The following packages must be installed on your system.
+
+- Go *(tested with 1.12)*
+- Git
+
+### 3. Copying and contributing
+
+This program is written by Humaid AlQassimi,
+and is distributed under the BSD 2 Clause license.
+
+### 4. Download and install
+
+```sh
+$ go get -u git.sr.ht/~humaid/yabfig
+$ go install git.sr.ht/~humaid/yabfig
+```
+
+### 5. Usage
+
+```sh
+Usage: yabfig [option] <file>
+Options:
+ -lint Lint (format) a Brainfuck file by removing spaces and non-instruction characters and output it to standard output.
+ -debug Run an interactive gdb-style debugger.
+```
+To run the example program `hello-world.bf`:
+```sh
+$ yabfig programs/hello-world.bf
+```
+Using the debugger to set breakpoints:
+```sh
+$ yabfig -debug programs/hello-world.bf
+yabfig debugger for Brainfuck.
+Commands are similar to gdb, type "help" for a list of compatible commands.
+(yabfig-dbg) help
+List of commands:
+
+run -- Run the program
+print [pos] -- Print value at memory position
+next [count] -- Execute next instruction[s]
+jump [pos] -- Jump to a program position and resume
+break [pos] -- Add breakpoint at program position
+clear [pos] -- Delete breakpoint at program position
+watch [n = x] -- Set watchpoint when memory position n is x
+kill -- Kill program execution
+(yabfig-dbg) b 98
+Breakpoint #1 at position 98
+(yabfig-dbg) b 102
+Breakpoint #2 at position 102
+(yabfig-dbg) b 106
+Breakpoint #3 at position 106
+(yabfig-dbg) r
+Running program: programs/hello-world.bf
+Hello WorldBreakpoint hit at position 98
+(yabfig-dbg) c
+!Breakpoint hit at position 102
+(yabfig-dbg) c
+
+Breakpoint hit at position 106
+(yabfig-dbg) c
+Program exited
+(yabfig-dbg)
+```
+
+### 6. Change log
+
+- v0.1 *(Mar 8 2019)*
+ - Initial release
+- v0.2 *(Mar 18 2019)*
+ - Added linter
+ - Added unit tests
+ - Interpreter as a struct with methods
+- v0.2.1 *(Mar 18 2019)*
+ - Add GoDoc
+ - Move Interpreter to a separate package
+- v0.3 *(Mar 22 2019)*
+ - Add a simple gdb-style debugger
+ - Improve interpreter functions
A => content/xmath-pp/_index.md +21 -0
@@ 1,21 @@
+---
+title: XMath Privacy Policy
+date: 2017-12-05
+---
+
+XMath does not collect or transmit any personal information.
+
+The student and instructor names are stored on the device locally, and is not transmitted over the Internet.
+
+The instructor name and the student's answers may be transmitted over Bluetooth.
+
+Music is downloaded from incompetech servers (when played), they may log connections.
+
+The application does not contain advertising or analytics.
+
+*rev 0 - 5 Dec 2017*
+
+---
+
+This is the privacy policy of an Android application made for a course in my first year of university.
+You can download the application on the [Play Store](https://play.google.com/store/apps/details?id=appinventor.ai_humaid_andr.XMath&hl=en_US) ([project page](/projects/xmath)).
A => static/favicon.png +0 -0
A => static/humans.txt +3 -0
@@ 1,3 @@
+/* SITE */
+Generator: Hugo <https://gohugo.io>
+Software: neovim, rsync, apache, gnu make, tdewolff's minify, git
A => static/img/me-2020-fulldef.jpg +0 -0
A => static/img/me-2020.jpg +0 -0
A => static/pkg.go.dev-reference-blue.svg +1 -0
@@ 1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="134" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="134" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h71v20H0z"/><path fill="#007ec6" d="M71 0h63v20H71z"/><path fill="url(#b)" d="M0 0h134v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="365" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">pkg.go.dev</text><text x="365" y="140" transform="scale(.1)" textLength="610">pkg.go.dev</text><text x="1015" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">reference</text><text x="1015" y="140" transform="scale(.1)" textLength="530">reference</text></g> </svg>
A => static/robots.txt +3 -0
@@ 1,3 @@
+# robots.txt for https://humaidq.ae
+Sitemap: https://humaidq.ae/sitemap.xml
+
A => themes/humaidq-theme/archetypes/default.md +4 -0
@@ 1,4 @@
+---
+title: ''
+date: ''
+---
A => themes/humaidq-theme/layouts/404.html +1 -0
@@ 1,1 @@
+404<
\ No newline at end of file
A => themes/humaidq-theme/layouts/_default/list.html +11 -0
@@ 1,11 @@
+{{ partial "header.html" . }}
+{{if not .IsHome }}<h2>{{ .Title }}</h2>{{end}}
+{{if and (.IsHome) ($.Site.Params.profilePicEnabled) }}<img
+src="/img/me-2020.jpg" class="me" alt="A picture of Humaid smiling, not
+ while looking at the camera. Possibly in a discussion with people
+ off-screen." />{{end}}
+{{ .Content }}
+{{if not .IsHome }}<ul>
+ {{ range .Data.Pages }}<li><a href="{{ .URL }}">{{ .Title }}</a></li>{{ end }}
+</ul>{{ end }}
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/layouts/_default/single.html +5 -0
@@ 1,5 @@
+{{ partial "header.html" . }}
+{{ if .Params.BackNav }}<p><a href="{{ .Parent.Permalink }}">< Go back</a></p>{{ end }}
+<h2>{{ .Title }}</h2>
+{{.Content}}
+{{ partial "footer.html" . }}
A => +9 -0
@@ 1,9 @@
{{ if or (.Paginator.HasPrev) (.Paginator.HasNext)}}<hr />{{end}}
{{ if gt (.Paginator.TotalPages) 0 }}<p class="center-text">Page {{.Paginator.PageNumber}} of {{.Paginator.TotalPages}}</p>{{end}}
{{ if .Paginator.HasPrev }}
<a rel="prev" href="{{.Paginator.Prev.URL}}">< Previous</a>
{{ end }}
{{ if .Paginator.HasNext }}
<a rel="next" class="right-text" href="{{.Paginator.Next.URL}}">Next ></a>
{{ end }}
{{ if or (.Paginator.HasPrev) (.Paginator.HasNext)}}<br />{{end}}
A => themes/humaidq-theme/layouts/blog/list.html +13 -0
@@ 1,13 @@
+{{ partial "header.html" . }}
+<h2>{{ .Title }} <small><a href="{{ "blog/index.xml" | absURL }}">(rss)</a></small></h2>
+{{ .Content }}
+{{if not .IsHome }}
+ {{ range (where .Data.Pages "Section" "!=" "") }}
+ <div class="entry"><span class="date">{{ .Date.Format "2 Jan 2006" }}</span>
+ <a href="{{ .URL }}">{{ .Title }}</a>
+ <div class="meta"><p>{{.Summary}}</p></div></div>
+ {{ end }}
+
+{{ end }}
+{{ partial "webring-out.html"}}
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/layouts/blog/single.html +14 -0
@@ 1,14 @@
+{{ partial "header.html" . }}
+<p><a href="{{ .Parent.Permalink }}">< Go back</a></p>
+<h2>{{ .Title }}</h2>
+<p>{{ dateFormat "Jan 2, 2006" .Params.date }} · {{.ReadingTime}} min read</p>
+<div class="blog">
+ {{.Content}}
+<hr>
+<p>Would like to comment on the blog post? Feel free to
+<a href="mailto:~humaid/general@lists.sr.ht?Subject=Re: {{.Title}}">start a discussion</a> on my
+<a href="https://lists.sr.ht/~humaid/general" target="_blank">public general mailing list</a>.</p>
+</div>
+
+{{ partial "webring-out.html"}}
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/layouts/gallery/list.html +12 -0
@@ 1,12 @@
+{{ partial "header.html" . }}
+<h2>{{ .Title }}</h2>
+{{ .Content }}
+{{if not .IsHome }}
+ {{ range (where .Data.Pages "Section" "!=" "") }}
+ <div class="entry"><span class="date">{{ .Date.Format "2 Jan 2006" }}</span>
+ <a href="{{ .URL }}">{{ .Title }}</a>
+ <div class="meta"><p>{{.Summary}}</p></div></div>
+ {{ end }}
+
+{{ end }}
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/layouts/gallery/single.html +21 -0
@@ 1,21 @@
+{{ partial "header.html" . }}
+<h1>{{ .Title }}</h1>
+<p><a href="{{ .Parent.Permalink }}">< Go back</a></p>
+<div class="meta">
+<p>Date: {{ dateFormat "Monday, 2 January 2006" .Params.date }}</p>
+ <p>Licensed under: {{ .Params.License }}</p>
+ <p>Location: {{ range .Params.location }}<a href="{{ "/location/" | relLangURL }}{{ . | urlize }}">{{ . }}</a> {{ end }}</p>
+ <p>Coordinates: <a href="https://mapper.acme.com/?ll={{.Params.lat}},{{.Params.lon}}&z=19&t=M&marker0={{.Params.lat}},{{.Params.lon}},{{.Title}}">{{.Params.lat}},{{.Params.lon}}</a></p>
+</div>
+{{.Content}}
+{{- $path := print "content/gallery/" $.File.TranslationBaseName -}}
+{{- $files := readDir $path -}}
+
+<div class="gal">
+ {{- range $files }}{{if not (eq .Name "thumbs")}}<a href="{{ .Name }}"><img src="thumbs/{{ .Name }}" alt="An image of {{$.Title}}" /></a>
+{{end}}{{- end }}
+</div>
+
+
+
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/layouts/language/list.html +10 -0
@@ 1,10 @@
+{{ partial "header.html" . }}
+{{if not .Params.top}}<p><a href="/language">< View languages</a></p>{{end}}
+<h2>{{ .Title }}</h2>
+{{ .Content }}
+{{if not .Params.top}}<p>{{ if .Params.LanguageURL }}Learn more about this language <a href="{{ .Params.LanguageURL }}">on Wikipedia</a>. {{ end }}Below is a list of projects which use this programming language.</p>{{ end }}
+{{if not .IsHome }}<ul>
+ {{ range .Data.Pages }}<li><a href="{{ .URL }}">{{ .Title }}</a></li>
+ {{ end }}
+</ul>{{ end }}
+{{ partial "footer.html" . }}
A => +14 -0
@@ 1,14 @@
</div>
</main>
<div class="footer">
<p>Copyright © 2013-2020 Humaid AlQassimi</p>
<p>The content of this site is CC BY-SA 4.0. The code of this site
is BSD 2-Clause.
<a target="sitesource" href="https://git.sr.ht/~humaid/humaidq.ae/tree/master/LICENSE">View license file</a></p>
{{if $.GitInfo }}
<p>Build <a target="sitesource" href="https://git.sr.ht/~humaid/humaidq.ae">{{$.GitInfo.AbbreviatedHash}}</a></p>
<!--<small>This page is last modified on
{{dateFormat "Jan 2, 2006" $.GitInfo.AuthorDate}}</small>-->{{end}}
</div>
</body>
</html>
A => +28 -0
@@ 1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="Cache-control" content="public">
<meta name="viewport" content="width=device-width, initial-scale=1" />
{{ range .AlternativeOutputFormats -}}
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{ end -}}
{{if .Site.IsServer}}<link rel="stylesheet" href="{{ "/css/main.css" | relURL }}" />{{else}}<link rel="stylesheet" href="{{ "/css/main.min.css" | relURL }}?v=4" />{{end}}
{{if eq .Type "blog"}}<link rel="stylesheet" href="{{ "/css/webring.min.css" | relURL }}" />{{end}}
<title>{{if .Title}}{{ .Title }} - {{end}}Humaid AlQassimi</title>
{{if .Description}}<meta name="description" content="{{.Description}}" />{{else if .Summary}}
<meta name="description" content="{{.Summary}}" />{{end}}
<meta property="og:site_name" content="Humaid AlQassimi's site" />
<meta property="og:image" content="{{.Site.BaseURL}}img/me-2020.jpg" />
<link rel="icon" type="image/jpeg" href="/favicon.png?v=2" />
</head>
<body>
<header>
<h1 class="title">Humaid AlQassimi</h1>
</header>
<nav class="nav">
{{ $currentPage := . }}{{ range .Site.Menus.main }}{{ if not (eq .Name "") }}<a href="{{.URL | absLangURL }}" class="nav-item{{if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} active{{ end }}">{{.Name}}</a>
{{ end }}{{ end }}
</nav>
<main>
<div class="content">
A => themes/humaidq-theme/layouts/projects/list.html +12 -0
@@ 1,12 @@
+{{ partial "header.html" . }}
+<h2>{{ .Title }}</h2>
+{{ .Content }}
+{{if not .IsHome }}
+{{ range .Pages.GroupByParam "Section" }}
+<h3>{{.Key}}</h3>
+{{ range .Pages }}<div class="entry"><b><a href="{{ .URL }}">{{ .Title }}</a></b>
+{{ if .Params.LatestVersion }}<small>({{.Params.LatestVersion}})</small>{{end}}{{if .Params.Language}} {{.Params.Language}}{{end}}
+<div class="meta">
+{{if .Params.Description}}<p>{{.Params.Description}}</p>{{end}}
+</div></div>{{ end }}{{ end }}{{ end }}
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/layouts/projects/single.html +29 -0
@@ 1,29 @@
+{{ partial "header.html" . }}
+<p><a href="{{ .Parent.Permalink }}">< Go back</a></p>
+<h2>{{ .Title }}</h2>
+<div class="meta">
+ {{if .Params.GitURL}}<p>Clone with HTTPS:
+ <a href="https://git.sr.ht/~humaid/{{ .Params.GitURL }}" rel="noreferrer" target="_blank">https://git.sr.ht/~humaid/{{ .Params.GitURL }}</a></p>{{end}}
+ {{if .Params.Language}}<p>Written in {{.Params.Language}}{{if .Params.License}}, licensed under
+ the <a href="https://spdx.org/licenses/{{.Params.License}}.html" target="_blank" rel="noreferrer noopener">{{.Params.License}}</a> license{{end}}{{end}}
+ {{if .Params.NotAccepting }}<p><b>Notice:</b> This project is not accepting any contributions.</p>{{end}}
+ {{if .Params.Site }}<p>Project URL: <a href="{{.Params.Site}}" rel="noreferrer" target="_blank">{{.Params.Site}}</a></p>{{end}}
+ {{if .Params.Proprietary}}<p><b>Notice:</b> The source of this project is not publicly available.</p>{{end}}
+ {{if .Params.MailingList}}<p>Mailing list: <a href="mailto:~humaid/{{.Params.MailingList}}@lists.sr.ht" target="_blank">~humaid/{{.Params.MailingList}}@lists.sr.ht</a>
+ (<a href="mailto:~humaid/{{.Params.MailingList}}+subscribe@lists.sr.ht?subject=subscribe&body=subscribe%20me">subscribe</a>, <a href="https://lists.sr.ht/~humaid/{{.Params.MailingList}}" rel="noreferrer" target="_blank">archive</a>)</p>{{end}}
+ {{if .Params.IssueTracker }}<p>Issue tracker: <a href="https://todo.sr.ht/~humaid/{{.Params.GitURL}}">view tickets</a> (<a href="mailto:~humaid/{{.Params.GitURL}}@todo.sr.ht">submit ticket via email</a>)</p>{{end}}
+ <p>{{if .Params.GoDoc }}<a href="https://pkg.go.dev/git.sr.ht/~humaid/{{.Params.GitURL }}{{if .Params.LatestVersion}}@{{ .Params.LatestVersion}}{{end}}?tab=doc"
+ target="_blank">
+ <img src="/pkg.go.dev-reference-blue.svg"
+ alt="pkg.go.dev reference"/></a>{{end}}
+ {{if .Params.HasBuilds}}<a href="https://builds.sr.ht/~humaid/{{.Params.GitURL}}?" rel="noreferrer" target="_blank"><img src="https://builds.sr.ht/~humaid/{{.Params.GitURL}}.svg" alt="builds.sr.ht status" /></a>{{end}}
+ </p>
+</div>
+<aside>
+ <header>
+ <h2>Table of Contents</h2>
+ </header>
+ {{.TableOfContents}}
+</aside>
+{{.Content}}
+{{ partial "footer.html" . }}
A => themes/humaidq-theme/static/css/main.css +190 -0
@@ 1,190 @@
+/* Page style */
+html {
+ overflow-y: scroll;
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: "Source Sans Pro", "Lucidia Grande", "Segoe UI", "Roboto", sans-serif;
+ font-size: 14pt;
+ line-height: 1.4;
+ background-color: #fff;
+ max-width: 1250px;
+ margin: 0 auto;
+}
+
+/* Typography */
+h1, h2, h3, h4, h5, h6 {
+ color: #333;
+ margin: 10px 0;
+ line-height: 1;
+}
+
+.title {
+ font-size: 2.5rem;
+ text-align: center;
+ margin-top: 30px;
+ margin-bottom: 30px;
+ padding: 0 30px;
+}
+
+a {
+ color: #052ba0;
+}
+
+.entry {
+ display: block;
+ width: 100%;
+ padding: 5px 15px;
+}
+
+.entry a {
+ color: #0b47bf;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+.meta a {
+ padding: 0;
+}
+
+.meta p {
+ margin: 0 0 0 25px;
+}
+
+.content {
+ padding: 20px 30px;
+}
+
+.footer {
+ padding: 1rem;
+ text-align: center;
+ color: #2f2f2f;
+}
+
+.footer p {
+ margin: 5px;
+}
+
+/* Images and Gallery */
+img {
+ max-width: 100%;
+}
+
+.me {
+ width: 200px;
+ float:right;
+ border-radius: 20px;
+ margin: 20px;
+}
+
+.gal {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ grid-gap: 10px;
+}
+
+.gal img {
+ max-width: 95%;
+ max-height: 220px;
+}
+
+/* Code blocks */
+pre code {
+ display: inline-block;
+ padding: 3.5px;
+ font-size: .8em;
+ border-radius: 2px;
+ white-space: pre-wrap;
+}
+
+code {
+ font-family: "SFMono-Regular","Menlo","Consolas","Liberation Mono","Courier New",monospace;
+ font-size: .9em;
+}
+
+aside {
+ border: 2px solid #777;
+ background-color: #eee;
+ padding: .5em 2.5em;
+ max-width: 400px;
+ float: right;
+ margin: 10px 0;
+}
+
+aside ul {
+ padding-left: 1em;
+}
+
+/* Responsiveness */
+@media only screen and (max-width: 780px) {
+ .gal {
+ grid-template-columns: none;
+ }
+ .gal img {
+ display: block;
+ max-height: 100%;
+ margin-left: auto;
+ margin-right: auto;
+ }
+ body {
+ font-size: 1.1em;
+ }
+ .me {
+ width: 100px;
+ }
+ aside {
+ float: none;
+ }
+}
+
+@media only screen and (min-width: 960px) {
+ .blog {
+ padding: 0 10%;
+ }
+}
+
+/* Navigation bar */
+.nav {
+ overflow: hidden;
+ text-align: center;
+ padding-bottom: 1rem;
+ border-bottom: 2px solid #4f4f4f;
+}
+
+.nav-item {
+ text-decoration: none;
+ font-weight: bold;
+ padding: .5em;
+ margin: 3px;
+ font-size: 1.4rem;
+}
+
+.nav-item:hover {
+ text-decoration: underline;
+ color: #000;
+}
+
+.nav-item:focus {
+ outline: none;
+}
+
+@media (prefers-color-scheme: dark) {
+ body {
+ background-color: #202125;
+ color: #cfcfcf;
+ }
+ h1, h2, h3, h4, h5, h6, .footer {
+ color: #ccc;
+ }
+ a, .entry a {
+ color: #6b96db;
+ }
+ a:hover, .nav-item:hover {
+ color: #ccc;
+ }
+ aside {
+ border: 2px solid #000;
+ background-color: #222;
+ }
+}
A => themes/humaidq-theme/static/css/main.min.css +1 -0
@@ 1,1 @@
+html{overflow-y:scroll;scroll-behavior:smooth}body{font-family:source sans pro,lucidia grande,segoe ui,roboto,sans-serif;font-size:14pt;line-height:1.4;background-color:#fff;max-width:1250px;margin:0 auto}h1,h2,h3,h4,h5,h6{color:#333;margin:10px 0;line-height:1}.title{font-size:2.5rem;text-align:center;margin-top:30px;margin-bottom:30px;padding:0 30px}a{color:#052ba0}.entry{display:block;width:100%;padding:5px 15px}.entry a{color:#0b47bf;font-weight:700;text-decoration:none}.meta a{padding:0}.meta p{margin:0 0 0 25px}.content{padding:20px 30px}.footer{padding:1rem;text-align:center;color:#2f2f2f}.footer p{margin:5px}img{max-width:100%}.me{width:200px;float:right;border-radius:20px;margin:20px}.gal{display:grid;grid-template-columns:repeat(3,1fr);grid-gap:10px}.gal img{max-width:95%;max-height:220px}pre code{display:inline-block;padding:3.5px;font-size:.8em;border-radius:2px;white-space:pre-wrap}code{font-family:sfmono-regular,menlo,consolas,liberation mono,courier new,monospace;font-size:.9em}aside{border:2px solid #777;background-color:#eee;padding:.5em 2.5em;max-width:400px;float:right;margin:10px 0}aside ul{padding-left:1em}@media only screen and (max-width:780px){.gal{grid-template-columns:none}.gal img{display:block;max-height:100%;margin-left:auto;margin-right:auto}body{font-size:1.1em}.me{width:100px}aside{float:none}}@media only screen and (min-width:960px){.blog{padding:0 10%}}.nav{overflow:hidden;text-align:center;padding-bottom:1rem;border-bottom:2px solid #4f4f4f}.nav-item{text-decoration:none;font-weight:700;padding:.5em;margin:3px;font-size:1.4rem}.nav-item:hover{text-decoration:underline;color:#000}.nav-item:focus{outline:none}@media(prefers-color-scheme:dark){body{background-color:#202125;color:#cfcfcf}h1,h2,h3,h4,h5,h6,.footer{color:#ccc}a,.entry a{color:#6b96db}a:hover,.nav-item:hover{color:#ccc}aside{border:2px solid #000;background-color:#222}}<
\ No newline at end of file
A => themes/humaidq-theme/static/css/normalize-8.0.1.min.css +1 -0
@@ 1,1 @@
+/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}<
\ No newline at end of file
A => themes/humaidq-theme/static/css/webring.css +40 -0
@@ 1,40 @@
+.webring {
+ margin-top:3rem
+}
+.webring .articles {
+ display:flex;
+ flex-wrap:wrap;
+ margin:-.5rem
+}
+.webring .title {
+ font-size: 1.5rem;
+ margin:0
+}
+.webring .article {
+ flex:1 1 0;
+ display:flex;
+ flex-direction:column;
+ margin:.5rem;
+ padding:.5rem;
+ background:#eee;
+ min-width:10rem;
+ border-radius:6px
+}
+.webring .summary {
+ font-size:.8rem;
+ flex:1 1 0
+}
+.webring .attribution {
+ text-align:right;
+ font-size:.8rem;
+ color:#555
+}
+@media (prefers-color-scheme: dark) {
+ .webring .article {
+ background-color: #222;
+ border: 1px solid #000;
+ }
+ .webring .attribution {
+ color: #eee;
+ }
+}
A => themes/humaidq-theme/static/css/webring.min.css +1 -0
@@ 1,1 @@
+.webring{margin-top:3rem}.webring .articles{display:flex;flex-wrap:wrap;margin:-.5rem}.webring .title{font-size:1.5rem;margin:0}.webring .article{flex:1 1 0;display:flex;flex-direction:column;margin:.5rem;padding:.5rem;background:#eee;min-width:10rem;border-radius:6px}.webring .summary{font-size:.8rem;flex:1 1 0}.webring .attribution{text-align:right;font-size:.8rem;color:#555}@media(prefers-color-scheme:dark){.webring .article{background-color:#222;border:1px solid #000}.webring .attribution{color:#eee}}<
\ No newline at end of file
A => themes/humaidq-theme/theme.toml +15 -0
@@ 1,15 @@
+# theme.toml template for a Hugo theme
+# See https://github.com/gohugoio/hugoThemes#themetoml for an example
+
+name = "Humaidq Theme"
+license = "MIT"
+licenselink = "https://humaidq.ae"
+description = ""
+homepage = "https://humaidq.ae"
+tags = []
+features = []
+min_version = "0.41"
+
+[author]
+ name = "Humaid"
+ homepage = "https://humaidq.ae"
A => usability.txt +6 -0
@@ 1,6 @@
+Each project usability can be divided into these sections:
+- 0: Completely unusable
+- 1: Barely usable. May have severe bugs, or might not work out of the box.
+- 2: Somewhat usable. May work out of the box, but has some issues.
+- 3: Very usable. Works well, but you may stumble upon some issues.
+- 4: "Production-ready".
A => webring-in.html +23 -0
@@ 1,23 @@
+<section class="webring">
+ <h3>Articles from blogs I follow around the net</h3>
+ <p><small>These articles do not represent my opinions or views.</small></p>
+ <section class="articles">
+ {{range .Articles}}
+ <div class="article">
+ <h4 class="title">
+ <a href="{{.Link}}" target="_blank" rel="noopener noreferrer">{{.Title}}</a>
+ </h4>
+ <p class="summary">{{.Summary}}</p>
+ <small class="source">
+ via <a href="{{.SourceLink}}">{{.SourceTitle}}</a>
+ </small>
+ <small class="date">{{.Date | date}}</small>
+ </div>
+ {{end}}
+ </section>
+ <p class="attribution">
+ Generated by
+ <a href="https://git.sr.ht/~sircmpwn/openring" target="_blank"
+ rel="noopener noreferrer">openring</a>
+ </p>
+</section>