iohes [per diem]
jewelryphotospolskiper diemabout
the studio of Donovan Howe

November 2019

11/3/19: Exploring the jQuery contains() and closest() methods to clean up our table.
As of today our table matches conjugation table at

Here is where the stuff goes5
Next step: Merging the JS we are using to parse the Wiktionary API info for a specific entry and combining it with our local table generator.

October 2019

10/28/19: string.includes() to test if the template we're testing has adverbial participles, impersonal past, verbal noun, etc. Gently reminded that when testing equivalency, "=" does not equal "==" does not equal "===".

10/27/19: A little progress on assigning variable values from a string.

10/21/19: In our sample word (pomóc), there are no inflections listed for "passive adjectival participle", "impersonal past", or "verbal noun". We need to remove those entries from our template table by hiding those rows or by filling those entries with blanks.

If we don't define missing variables, our script will FAIL.

Here is where the stuff goes4

Next time: clearing out the suffixes left over in the {{{pp|pp2|ip|vn}}} entries, and figuring out the rules for applying the {{{altpasttense}}} entry.

10/20/19: Updating our script to apply globally:
.then((data) => data.replace(/{{{1\}}}/g,pl1))

Here is where the stuff goes3

Next time: what do we do with the {{{pp|pp2|ip|vn}}} entries?

10/19/19/, iii: Now we want to combine our Wiktionary fetch with our table:


Here is where the stuff goes2

Up next - getting our script to replace all of the "{{{3}}}'s", dealing with the "{{{pp}}}'s, etc.

10/19/19, ii: How do I load the contents of a text file into a javascript variable?

This article will help us in the future: Body.text()
Today, we're using the Fetch API: Fetch API

The easiest solution for us was:
 .then(response => response.text())
 .then((data) => {
   plConjAp = data;

function XMLHTTPrequest() {
  document.getElementById("HereIsWhereTheStuffGoes").innerHTML = plConjAp;

Let's test it out, trying to call /InflectionTables/pl-conj-ap.html:
Here is where the stuff goes!

10/19/19: Can we set up our parser to redirect to the infinitive form of a verb, or the uninflected form of a noun or adjective?

Generally, there are two cases in Wiktionary for conjugated entries:
1. Example: "rozumiem" - the word has its own page that explains the inflection.

* {{pl-IPA}}

{{head|pl|verb form}}

# {{inflection of|pl|rozumieć||1|s|pres}}
#: {{ux|pl|'''Rozumiem'''.|I see. / I understand.|inline=1}}

2. There is no entry for the inflection, but the Wiktionary search finds the inflection in a different page:
See for API usage. Subscribe to the mediawiki-api-announce mailing list at <> for notice of API deprecations and breaking changes.

Instead of leaning on redirects, we'll utilize "Słownik", the example dictionary we're putting together, to bubble up to the uninflected form of the word. This gives us an opportunity to learn new inflections when we find gaps in dictionary.

10/18/19: What options do we have when doesn't have an inflection table for a word, like podawać?

We can call!|revid&origin=*&page=podawa%C4%87 returns:

{{odmiana-czasownik-polski | dokonany=nie | koniugacja=IX | robię=podaję | robi=podaje | robią=podają | robiłem=podawałem | robił=podawał | robiła=podawała | robili=podawali | robiono=podawano | rób=podawaj | robiąc=podając | robiony=podawany | robieni=podawani | robienie=podawanie }}

10/15/19: As we test more cases for our JS/Wiktionary parser, we're finding more exceptions:

Example: Drugi

1. Multiple languages listed - parser must find "Polish"
2. Entry uses "Declension" instead of "Conjugation" - parser must find "====" instead of a section header
3. Entry uses template pl-decl-adj-i - need to add additional table template

That works for entries that are relatively uncluttered, but what about a page like "To" that has entries for 42 languages, contains additional organizational tags, and has entries for both the pronoun "To" and the adverb "To"?

1. Parser must find "==Polish==" first
2. Parser must pull all available definition options and create a selection dialogue for the user - parser needs to find all entries like ===Pronoun=== and ===Adverb=== and perform additional parsing

#2 requires a degree of familiarity with the intended grammar. For now, we'll focus on conjugation/declension entries and as we explore more, maybe we can find a good solution to reduce the number of times the user has to make a choice.

10/13/19: How does our Javascript script find the definition in a Wiktionary article?

var str = document.getElementById("demo").innerHTML;
var n0 = str.indexOf("#");
var n1 = str.indexOf("#",n0+1);
var res = str.slice(n0,n1)

The string seaches for the first "#", and then the next "#" (by starting 1 character after first "#".)

Additional parameters replace extra characters and additional stuff people put in entries with blanks. This are for English Wiktionary entries, and is something I update as I find more weird stuff that people have inserted in the definitions.

.replace(/[|]/g," ")
.replace("===Etymology 2===","")
.replace("lb en","")
.replace(" en-",", ")
.replace("informal pejorative","")

I'll continue using pomóc as our test example to extract the entries that fit into Template:pl-conj-ap.

Template:pl-conj-ap uses the following variables:


There are eight mandatory arguments:
infinitive |
first person singular future tense |
third person singular future tense |
third person plural future tense |
third person singular past tense |
third person singular past tense, feminine, without -ła |
third person plural past tense, masculine, without -li |
second person singular imperative |

There are seven optional arguments:
pp= past adjectival participle, without y (must be combined with pp2)
pp2= past adjectival participle, masculine-personal plural
ap= anterior adverbial participle
ip= impersonal past
vn= verbal noun
imp2= second imperative form (2nd person singular)
altpasttense= third-person masculine singular past form without ł

Searching for "pomóc" returns:

Wikimedia color templates are here: Help:Using colours

Here's that table from the template page.

    singular plural
person m f n m pers m anim or m inan or n or f
infinitive {{{1}}}
future tense 1st {{{2}}} {{{3}}}my
2nd {{{3}}}sz {{{3}}}cie
3rd {{{3}}} {{{4}}}
past tense 1st {{{5}}}łem {{{6}}}łam {{{7}}}liśmy {{{6}}}łyśmy
2nd {{{5}}}łeś {{{6}}}łaś {{{7}}}liście {{{6}}}łyście
3rd {{{5}}}ł {{{6}}}ła {{{6}}}ło {{{7}}}li {{{6}}}ły
conditional 1st {{{5}}}łbym {{{6}}}łabym {{{7}}}libyśmy {{{6}}}łybyśmy
2nd {{{5}}}łbyś {{{6}}}łabyś {{{7}}}libyście {{{6}}}łybyście
3rd {{{5}}}łby {{{6}}}łaby {{{6}}}łoby {{{7}}}liby {{{6}}}łyby
imperative 1st niech {{{2}}} {{{8}}}my
2nd {{{8}}} {{{8}}}cie
3rd niech {{{3}}} niech {{{4}}}
passive adjectival participle {{{pp}}}y {{{pp}}}a {{{pp}}}e {{{pp2}}} {{{pp}}}e
anterior adverbial participle {{{ap}}}
impersonal past {{{ip}}}
verbal noun {{{vn}}}

We're looking to format this information like this (Możesz mi pomóc?):
Możesz mi pomóc
    singular plural
person m f n m pers m anim or m inan or n or f
infinitive {{{1}}}
future tense 1st {{{2}}} {{{3}}}my
2nd {{{3}}}sz {{{3}}}cie
3rd {{{3}}} {{{4}}}
past tense 1st {{{5}}}łem {{{6}}}łam {{{7}}}liśmy {{{6}}}łyśmy
2nd {{{5}}}łeś {{{6}}}łaś {{{7}}}liście {{{6}}}łyście
3rd {{{5}}}ł {{{6}}}ła {{{6}}}ło {{{7}}}li {{{6}}}ły
conditional 1st {{{5}}}łbym {{{6}}}łabym {{{7}}}libyśmy {{{6}}}łybyśmy
2nd {{{5}}}łbyś {{{6}}}łabyś {{{7}}}libyście {{{6}}}łybyście
3rd {{{5}}}łby {{{6}}}łaby {{{6}}}łoby {{{7}}}liby {{{6}}}łyby
imperative 1st niech {{{2}}} {{{8}}}my
2nd {{{8}}} {{{8}}}cie
3rd niech {{{3}}} niech {{{4}}}
passive adjectival participle {{{pp}}}y {{{pp}}}a {{{pp}}}e {{{pp2}}} {{{pp}}}e
anterior adverbial participle {{{ap}}}
impersonal past {{{ip}}}
verbal noun {{{vn}}}
More formatting next time!

10/12/19: How does our Wiktionary "GET" request work? (all referenced content in this post is by

Let's stick the API sandbox here so we don't lose it!"GET", "|revid&origin=*&page=" + wikiword, true);

This retrieves the following information (example page "pomóc"):



* {{pl-IPA}}
* {{audio|Pl-pomóc.ogg|audio|lang=pl}}


# to [[help]]
#: {{ux|pl|Możesz mi '''pomóc'''?|t=Can you help me?}}


===Further reading===
* {{R:PWN}}

The following code attempts to parse out everything between the two #hashtags except for the definition:

var str = document.getElementById("demo").innerHTML;
var n0 = str.indexOf("#");
var n1 = str.indexOf("#",n0+1);
var res = str.slice(n0,n1)
.replace(/[|]/g," ")
.replace("===Etymology 2===","")
.replace("lb en","")
.replace(" en-",", ")
.replace("informal pejorative","")

There are these nifty conjugation tables in the Wiktionary articles we want to capture:

The mediawiki page suggests if we want table data, we should fetch the specific section number and parse the table using Python.

So what is happening on the back end? Wiktionary has templates set up for each conjugational archetype, such as Template:pl-conj-ap

Those templates look like this:

There are lots of these templates for Polish entries:

Category:Polish adjective inflection-table templates
{{pl-decl-adj-auto}} - automatic declension table, covers most cases
{{pl-decl-adj}} - manual table for irregular adjectives
{{pl-decl-phrase}} - adjectival phrase

Category:Polish noun inflection-table templates
Masculine nouns
{{pl-decl-noun-m-in|wieczo|r|u|wieczór}} – inanimate
{{pl-decl-noun-m-an|ku|r}} – animate
{{pl-decl-noun-m-pr|nauczycie|l|nauczyciele}} – personal ending in consonants, -a, -y, -i; parameters specify consonant-final declension when used
Feminine nouns
{{pl-decl-noun-f|kro|w|genp=krów}} – ending in -a, -ia, -ni and consonants
{{pl-decl-noun-f-adj|teściowa}} – nouns that inflect like adjectives, e.g. many of those ending in -owa
Neuter nouns
{{pl-decl-noun-n|łóż|k|łóżek}} – ending in -o, -e, -ę, -mię, -um; parameters specify -o declension when used
{{pl-decl-noun-n-adj|młode}} – nouns that inflect like adjectives
Highly irregular nouns
Fully generic templates
{{pl-decl-noun-pl}} – plurale tantum
{{pl-decl-noun-sing}} – singulare tantum
{{pl-decl-phrase}} – noun phrase
{{pl-decl-generic}} – declension by cases with arbitrary column headers, useful for some pronouns

Category:Polish numeral inflection-table templates

Category:Polish verb inflection-table templates
Generic templates
Imperfective verbs
{{pl-conj-ai-am,asz|naciąg|pp}} — naciągać
{{pl-conj-ai-uję|oszuk|pp|alt=i}} — oszukiwać
{{pl-conj-ai-yć|kojarz|pp}} — kojarzyć
Perfective verbs
{{pl-conj-ap-am,asz|oszuk|pp}} — oszukać
{{pl-conj-ap-uję|oprac|pp}} — opracować
{{pl-conj-ap-nąć|nadepn|pp}} — nadepnąć
Defective and irregular verbs
{{pl-conj-defective}} — można, wiadomo
{{pl-conj-być}} — być
{{pl-conj-powinienem}} — powinienem

More strategy next time!

September 2019

9/14/19: Interesting photogrammetry technique video for ReCap.

What is...ReCap Photo?

ReCap Photo is photogrammetry software that uses a cloud rendering model for end users to generate models based on their photographs.

Tested a bottle of Kuretake ink using 38 photos of a bottle on a turntable. Generating a render using 20 to 300 photos costs $12. Fortunately you get a few "cloud credits" for free when you start a trial.

If you get an error, you're not charged cloud credits.

What makes photos good for photogrammetry?

Practice makes...:

Thank you EXPORT LAYERS (for GIMP), you are the plugin of the week.


9/2/19: More Fusion tutorials with Lars Christiensen:

11. Holes and threads
12. Crazy straws, sculpt, alt+click for additional faces, coil, shell
13. Logo sketching
14. Model holes in a pipe at an angle, plane at angle, rectangular pattern
15. How to model snap rings for 3D printing
16. Bring Excel into Fusion 360
17. How to model a violin shape - sculpting, merge edges
18. Better workflow with Fusion Team
19. Knife handle with sculpt
20. Another twisted metal - sweep tool

9/1/19: More Fusion tutorials with Lars Christiensen:

1. Music Pegs - Sketch, arcs, rotate, mirror, cut via extrude
2. Milling - Contour selection
3. Spray Nozzle - Sketch, rotate, create form, symmetry, edit form, fillet.
4. Better Split Body - Extrude to create a new body, split body to separate from original.
5. Understand Z vs Y
6. How to model a drain grate - canvas, calibrate, align, arc, dimensioning, mirrors, hole, countersink.
7. UI updates
8. Maybe your models are too complex
9. CAM for 4th axis
10. How to solve a complex - coincidents

August 2019

8/22/19: Tutorials with Lars Christensen:
Fusion 360 Tutorial — 5 Things Beginners Want to Know about Fusion 360
Lars' rules for parametric modeling:
1. Always start with a 2D sketch that you will extrude into 3D space
2. You're always sketching on a plane or a face
3. Always tie your initial sketch to the origin
4. Fully define your sketches/relations/dimensions
Fusion 360 Tutorial: Get a Grip on Components, Bodies & Assemblies
1. When you extrude a sketch, it becomes a body, which lives within a component.
2. Components have joints for movement
3. You can take bodies inside of components, and turn them into their own components
3 Things I Wish I Knew when I First Started using Fusion 360

8/22/19: Let's learn some more Fusion 360:

Tutorials with Lars Christensen:
Fusion 360 Tutorial for Absolute Beginners — Part 1
Fusion 360 Tutorial for Absolute Beginners — Part 2
Fusion 360 Tutorial for Absolute Beginners — Part 3

8/12/19: What are...plants?

We got some plant friends! Let's meet them:

Velvet Calathea = Calathea rufibarba, needs diffused light, damp soil. Wipe leaves of dust. Fuzzy!!!

Ripple Peperomia = Peperomia caperata, tolerates shade, water when soil is almost dry.

Green Congo Philodendron = aka Imperial Green Philodendron, tolerates shade, likes moist soil. Poisonous! Don't eat this, brother.

Hoya = Hoya carnosa, indirect light, water when top 1/2 of soil is dry.

Succulents = Zebra Haworthia (Haworthia fasciata) and ???, tolerates shade, soak soil and allow to dry before watering again.

July 2019

7/26/19: If you are thinking about making any brass rings, they do this:

7/20/19: Back from Shapeways - our frigatebirds, this time in silver. The model details were abstracted to allow for casting.

7/15/19: Making a hole in a solid in f360 is one billion times less complicated than in Blender.

7/12/19: Reminded to add a query string after my .css to refresh when making big updates.

Also, more Fusion 360 tutorials.

7/11/19: What is Fusion 360?

F360 is team- and project-based CAD/CAM software.

F360 is not happy with my (lack of) graphics card:

Following tutorials here:

7/9/19: Try again, sez Shapeways (unsupported walls should be ≥0.6mm for silver):

7/6/19: Test back from Shapeways, ring sizes are 5.5:

7/1/19: Dziś jest poniedziałek, cześć!

Tutorials for sewing on a button: Part 1 Part 2

June 2019

6/29/19: Dziś jest sobota, dwudziesty dziewiąty.

6/27/19: Let's try again:

6/26/19: Remember to:
1. Apply rotation and scale
2. Dynotopo
3. Subdivide the model for good sculpting
4. Stay below 100k faces
5. Scale the thickness of your parts evenly to avoid rework



ALT + C = Mesh from Curve in Blender
SHIFT + C = Center camera on object
Preliminary sketch:

6/22/19, iii: Why are all my Android Studio project files red? One of these reasons:

6/22/19, ii: Kotlin sesh ix.

Extension Function in Kotlin
1. You can extend a type and a class without having to inherit from it
2. this refers to the instance of the object on which we are operating
3. If you make an extended function that has the same name as a member function, the member function will always take preference
4. Extension functions are statically resolved

Interoperability with Java
1. You can use property access directly without get/set
2. You can call Java from Kotlin
3. Even if you're in a Java class, IntelliJ will allow you to access Java conventions, not Kotlin conventions
4. @JvmField annotates Kotlin code to access a property as if we were accessing a field in Java
5. @JvmOverloads creates overloaded versions of functions
6. @JvmName allows us to change the name of a member function when it is called from Java
7. FileName.functionName will allow you to call a Kotlin function in Java
8. Using @file:JvmName will allow you to define a UtilityClass to call the function in Java as well
9. There are not extension functions in Java

Kotlin standard library and working with collections
1. Lists, Arrays, Maps, Sets, HashMap, HashSet, etc...
2. CTRL + B will allow you to go to the Declarations for a term
3. There are helper functions for mutable interfaces and for immutable interfaces
Filtering, Mapping and Flatmapping in Kotlin
1. The goal is to made the code more clear
2. .map allows you to map one collection with certain values into another collection
3. .flatMap allows you to apply a function to a collection of collections and flattens it to one collection

Lazy evaluation and sequences with Kotlin
1. Lazy evaluation oinly evaluates things as it needs them

String Extensions in Kotlin
1. There are lots of string extensions in the standard Kotlin library
2. Sequences are the equivalent of Java Streams

Build Tools in Kotlin
1. Kotlin can be used with a variety of tools: Command Line, Ant, IntelliJ IDEA, Eclipse, Maven, Gradle

6/22/19: Kotlin sesh viii.

Working with exceptions
1. A checked exception is [...] exery time a method throws a non-runtime exception, it has to declare it
2. A throwable is the base class of exceptions
3. finally{} finalizes even if an exception is thrown
4. try{} catch blocks can be treated as expressions and return values
5. Exception in thread "main" input.txt (The system cannot find the file specified) is caused by [...] the file not being directly under the project folder

Declaring constants
1. Constants can be declared at the top level
2. It would be nice to group constants into an object that represents the value
3. Top-level properties can make it difficult to track where things are

Annotations in Kotlin and summary
1. Kotlin supports annotations
2. Annotations are prefixed by the @ sign
3. Smart casting can save on boilerplate code
4. Tuples are restricted in Kotlin to pairs and triples
5. Value deconstruction allows for better semantics
6. In Kotlin, there are no checked exceptions
7. Constants can be objects or top-level properties

Higher order functions in Kotlin
1. Higher order functions take another function as a parameter, or return a function
2. In Kotlin you can reference a function by using ::theNameOfTheFunction

Lambda expressions in Kotlin
1. Lambda expressions allow you to not declare the function header, and just declare the body
2. The parameters of a lambda expression do not have to specify types
3. If the only parameter of a function is another function, it does not need ()'s
4. An anonymous function is a function with no name

Closures in Kotlin
1. Closures allow you to access values outside of an expression

6/21/19: Polish keyboard shortcuts:

Kotlin sesh vii.

Type casting in Kotlin
1. Smart casting in IntelliJ casts a type to another type when appropriate

Tuples and Deconstructing Values
1. Tuples are pairs, triples [...]
2. Data classes can be used instead of tuples
3. Data classes Pair and Triple can be used for this

6/19/19: Kotlin sesh vi.

A brief look at generics in Kotlin
1. Generic classes take a type parameter that varies
2. The convention is to use a single letter to represent type parameters

Null safety
1. Nulls == "billion dollar mistake"
2. Kotlin is "null safe"
3. In Kotlin by default, types cannot be null
4. You can declare variables as nullable
5. If you add a question mark to a type (e.g. String?), that variable can now hold a null value
6. Error:(10, 24) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
7. The Elvis operator is the safe operator
8. ?. says if the value is not null, then invoke the method. If it is null, then don't do it
9. !!. is a non-null asserted call

6/18/19: Kotlin sesh v.

Interfaces in Kotlin
1. An interface is like a contract
2. You cannot maintain state in an interface, with an abstract class you can
3. We cannot have a class that inherits from two base classes; we can have a class that inherits from a single base class and inherits multiple interfaces
4. Kotlin has a single inheritance model
5. Interfaces can have properties
6. Property interfaces are not allowed to have initializers because they cannot maintain state
7. You can provide getters and setters in interfaces
8. In interfaces you can override implementations
9. You can also override member functions that have default implementations
10. When you are implementing multiple interfaces, and these have default implementations for methods that are called the same, you can refer to them by using super (and the notation we're going to use for generics)

6/17/19: Kotlin sesh iv.

Objects in Kotlin
1. We can an object without it being an instance of a specific class
2. Declaring an object with a name is enough to implement the "singleton pattern"
2a. The "singleton pattern" is a software design pattern that resticts the instantiation of a class to one "single" instance (thanks Wikipedia)

Inheritance in Kotlin
1. The base class for all classes is Any() 2. CTRL + Q brings up quick documentation
3. In Kotlin, by default all types are final (cannot be inherited from)
4. If we want to use the constructor for the base class, we can use super()
5. There is a final modifier in Kotlin that indicates any open member function cannot be overwritten

Abstract classes in Kotlin
1. Abstract classes are classes in which we cannot create an instance
2. Abstract classes differ from base classes in that we can have abstract members
3. Not every member of an abstract class needs to be abstract

6/16/19, ii: Learning Kotlin, sesh iii.

Enum classes in Kotlin
1. An eunm class that has a list of enums and also properties/functions requires a ; after the enum list

6/16/19: Learning Kotlin with Hadi Hariri, sesh ii.

Classes in Kotlin:
1. You can create secondary constructors beyond the init{} block
2. Kotlin provides default getters and setters and we can provide custom getters and setters
3. ALT + ENTER (IntelliJ IDEA) allows you to define an undefined variable or value as a constructor parameter or local variable
4. In Kotlin there are no fields, but there is a backing field for every property

Member functions in Kotlin:
1. Classes can have functions...

Visibility Modifiers in Kotlin:
1. In Kotlin the default visibility modifier is public
2. There are 4 visibility modifiers: public (default); private (available inside file containing declaration); internal (anywhere in the same module); protected (same as private and subclass)

Kotlin data classes:
1. ALT + ENTER (IntelliJ IDEA) also allows you to automatically create the getters and setters for vars and vals
2. "We've got a whole bunch of these.....BEANS"
3. The data class modifier provides the functionality of toString(), hashcode and equals
4. CTRL + D (IntelliJ IDEA) duplicates a line or selection

6/14/19: Learning Kotlin with Hadi Hariri. Also, the IntelliJ IDEA.

Also: Kotlin conventions. Which of course start with Java conventions:
1. Lower camelCase for names
2. Types in Uppercase
3. Methods and properties in lower camelCase
4. Semicolons are optional
5. Packages follow reverse notation
6. Multiple classes per file allowed
7. Packages do not have to, but should follow file names

Also, additional learnings:
1. Kotlin can infer variable types
2. val creates an immutable variable, var creates a mutable variable
3. In Kotlin, everything is an object
4. 10L is a long; 100F is a float; 0x0F is hex, 0xb01 declares a binary - combining inference with literal constants
5. You can have multiple fun main() per package, but they each have to be in their own separate file
6. .. is an operator overloader for rangeTo and downTo
7. Kotlin can break and continue from a loop
8. You can enable font ligatures in IntelliJ via Settings>Editor>Font>Enable font ligatures and changing the font to a ligature-supporting font such as Fira Code
9. Certain functions (e.g. println()) are implicitly imported
10. You can import [...].* to import everything that is part of a package
11. You can import [...].someUtility as someAdditionalFunction (i.e. you can rename you functions at the time of import)
12. Kotlin treats functions as first-class citizens

Moving on to functions in Kotlin...
1. There is type inference for return types
2. Kotlin has the ability to have default parameters and avoid overloads in classes (in Java there are no default parameters
3. Named parameters allow for default values in any location, can change the order in which we pass in parameters
4. Kotlin can have functions with an undefined number of parameters
5. * is the "spread operator"
6. By default, the return type is Unit, equivalent to void
7. Single value expressions don't need the function block

Moving on to classes in Kotlin:
1. Kotlin doesn't have the concept of fields; you can only declare properties
2. You can initialize values directly when you call the constructor
3. init is the initialization block for a class

6/12/19: Staring down the horde of resources here:

6/11/19: Version control, Git! Git installer has a lot of questions. Also, GitHub, master, branches, pull requests, desktop client.

6/9/19, iii: Drag and drop example (Java), with lots of good bonus stuff. Gradients, shapes, corners:

Drag and drop example (Kotlin):

6/8/19, ii: Borders in GridLayout:

Also: styling GridLayout (borders via themes/styles

6/8/19: I crashed my app into bridge. I watched, I let it burn:
2019-06-08 04:06:45.631 18203-18203/com.example.wordbow E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.wordbow, PID: 18203
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.wordbow/com.example.wordbow.DisplayMessageActivity}: android.view.InflateException: Binary XML file line #22: column indices (start + span) mustn't exceed the column count.

Also, borders in GridView:

Also, the difference between GridView and GridLayout:

6/7/19: Removing the application title bar, android:statusBarColor. Commenting out blocks in Android Studio (CTRL+SHIFT+/)

Good article on GridLayout here:

Also, Logcat:

6/6/19: [...].setSpan(ForegroundColorSpan(Color.rgba(alpha, red, blue, green)),char start,char end,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

6/5/19: Thank you to this YT video for being coherent enough to get a spannable string working from scratch:

6/4/19: CDATA:

Also, styles being overridden when declared multiple times in a textView.

Also, back to:

6/3/19: Color opacity in hex notation.

Also: LinearLayout.
To which Google says, use ConstraintLayout:
Also, barriers:

Also, should probably be building this around the drag and drop functionality:

6/1/19, ii: Strings! And, spannable strings:

6/1/19: Thank you android:layout_span, you are the field related to TableRow.LayoutParams class of the week.

Also: screen compatibility overview, density independence, dp, sp. You can take my raster graphics from me when you find me in hell:

Also, changing the app launcher icon. Anrdoid Studio has an easy mode: rclick>App>New>Image Asset:

Also: "How do I disable orientation change on Android?":

MAY 2019

5/31/19: Tables:
Works as promised, required only modification to the single Activity.xml we were working on.

Also, styling Android tables and styles.xml:

5/30/19: Prepping CSV, adding to app>src>main>res>raw.

5/28/19: Aluminum ring is back from Shapeways. Needs some reshaping:

5/27/19: Let's do some animation:

Also: rclick > Go to XML

Also: xmlns = XML Namespace

5/26/19 ii: Polished:

5/26/19: It is pronounced cot-lynn. Also: Google Fonts for Android:
Also: refactoring:
Also: rclick > "Show Baseline".

5/25/19: Today's lesson:

Next lesson:

Also, Kotlin koans:

5/23/19: We got our first Shapeways aluminum project back. Here it is as shipped:

Material Dimensions Weight
AlSi10Mg Alloy 69mm x 29mm x 22mm 15.92g

Material: I printed this in Shapeways' Aluminum option (this is a Renishaw selective laser melting process). Now polishing time.

5/21/19: Android Studio UI.

5/20/19: Return to Android Studio. Android Studio, 1M updates, Developer Mode, USB Debugging.

Next lesson:

Also: REALLY EXCITED that the Google Ngram data is available under Creative Commons:

Also: Interesting link on utilizing the Ngram site to fetch data:

5/17/19: When you forget you scaled your model 200%, you get a bone crown for your tomato friends:

5/9/10: Hypothesis - my 3D modeling will be faster to make if I focus on generative rather than destructive modeling. Unlike the real world, it is faster and more mesh-friendly to create and extrude volumes than it is to cut and re-manifoldize them.

5/7/19: Edges: ☑ bridged; Faces: ☑ poked

Also: File > User Preferences > Interface > "Rotate Around Selection".

5/5/19: How do we reduce the cost of printing multiple copies of a ring on Shapeways?

Shapeways suggests "Looping", "Sintershelling" or spruing, with the caveat that spruing leads to lots of production failures:

The community sez: basically the same thing, +sprue @ 2mm min. Thread comes with a pricing chart for one of the SW plastic options:

+Note, Blender starts to chug around 200k faces on this machine:

5/4/19: Looking for ways to reduce the cost of a printing. Printing our 4/27/19 model in silver with Shapeways is $300+. For a test, just the beak(s):

This is a problem for us - silver is relatively cheap - $0.48/g today (our truncated model would use 26.04g of Ag) but SW is charging a large markup on machine space and "support structure".

Requested a quote from an NYC printing/casting house.

APRIL 2019

4/28/19: Frequent offender: Always apply rotation and scale before doing anything transformative in Blender. Print3D toolbok will give you selection option in Edit Mode.

4/27/19: First sculpted Shapeways print:

4/18/19: New addition to the gallery:

Also, fixing sculpt symmetry via Apply Rotation and Scale.

4/16/19: New stones:

Size Cut Grade Mohs AGTA Code
White Sapphire 4mm Context n/a 9 (SYN) SYNTHETIC

4/15/19: Return from mental vacation. In our CSS, having "height=100%" prevents border-radius from applying to video. Also, "back" buttons over gallery images.

4/6/19: Non-manifold figures. Also, custom orientations (CTRL+ALT+SPACE), transform orientation.

4/5/19: Fifth iteration:

4/4/19: First iteration:

Second iteration:

Third iteration:

Extruding before transform yields knife edges.

4/3/19: Learning new selection modalities in Blender. Checker deselect. Gemstone modeling.

4/2/19: Addition to gallery.

4/1/19: Addition to gallery.

MARCH 2019

3/31/19: Thought this was going to look cool - closer to angry ramen.

Calming down the noodles:

Threw this sketch in Shapeways for a price check. Just a little too big to print in wax for casting.

3/30/19: Iterating.

3/26/19: Fun with grids.

3/24/19: Moving more stuff around. Revisiting

3/23/19: Blender rendering to frames, Compositor, node editor. Make sure "Sequencer" is turned off in the Post Processing options under the Scene tab to get the Compositor output. Good starting link here:

3/20/19: Moving stuff around.

3/19/19: Sketching with thermoplastic.

3/18/19: Good post on making a band shape in Blender:

Subsurf modifier quickly flattening my processor. Blender does not have a recovery option if you didn't save.

3/17/19: What shape are your fingers?

Rings are almost always circular, however, your fingers are not. If you look at an MRI cross-section of your fingers, they are closer to tapered squircles, moreso when pressed against a flat surface.

There is already a popular shank type called a "Euro" shank, with a squircled bottom to prevent rings from rotating.

3/16/19: We got more gemstones. Let's learn about them!

Left to right:

Size Cut Grade Mohs AGTA Code
Black Tourmalinated Quartz 6mm Round n/a 7 (N) NOT ENHANCED
Copper Rutilated Quartz 2mm Round n/a 7 (N) NOT ENHANCED
Quartz 12mm Round AAA 7 (N) NOT ENHANCED

What is...
Tourmalinated = Having inclusions of tourmaline, a crystalline boron siliate mineral
Rutilated = Having inclusions of enclosed rutile needles
Rutile = A black or reddish-brown titanium dioxide mineral

"Copper rutilated" means the rutile is copper in color, not that the inclusions are made of copper.

Also, moving back to Namecheap from Cloudflare for DNS.

Also, new start, let's go. Some rules for myself:
1. All images < 100 KB
2. Use text rather than images
3. Use CSS rather than JS


3/13/19: How to imply geometric order when yielding multiple transformations around a circle?

3/12/19: Started working on lazy loading. What we're loading on this page is tons of images and about a dozen .js scripts.

3/11/19: Cloudflare.

Info on SSL mismatching:

3/10/19: Changing the scale in Blender to see more significant digits:

Also, a new star patten:

3/9/19, ii: Model back from Shapeways:

Here is the original model:

Shapeways said the model geometry was too weak and gave us a "LET US FIX IT" option. What did they do?
1. Bumped the ring thickness from 1mm to ~1.8mmm

I'm a bit disappointed with the result. The printing/casting/finishing process also:
2. Whanged the top-right quadrant out of round
3. Twisted the ring geometry out of the xy plane

3/9/19: Sapphires ready to set (don't eat these):

3/7/19: If you sell fine jewelry, your website has to look like this:

EXCEPT Harry Winston, who tastefully offset their menu:

3/6/19: Practice stamping.

3/5/19: Get outta here with that sharp geometry, sez Shapeways:

Shapeways will not let us "Print It Anyways" as a silver casting:

Let's see if they will print it unpolished. On the re-order, the only finish option is "natural". That is some impressive UI/CX/CSR interaction:

3/3/19, ii:

3/3/19: Going under the bit:

3/2/19, ii: Video editing in Blender? The ffmpeg encoding line we need to convert an .mkv file to a .mp4 is:
ffmpeg -i blenderfile.mkv -vcodec copy -acodec copy blenderfile.mp4

3/2/19: Merge at center (ALT+M), Array modifier.

Getting here:
1. Generate module
2. Array
3. Simple Deform>Twist
4.Apply rotation/scale
5.Generate bezier cirle
6. Simple deform>Bend
7. Remove Doubles>Increase Merge Distance

3/1/19: Looking inside our model:

1. Got some non-manifold geometry as a result of sculpting
2. Did not do a good job creating internal spaces to reduce printable volume


2/28/19: Returning Fristaden Labs centigram scale. Build quality seems off, backlight doesn't line up with branding, and out of the box the 500g calibration mass registered as 500.40g. Also, looking at costs for printing our raven skull. At scale, it will be several hundred dollars; 50% scale is $70-140 depending on material.

2/27/19: Finances.

2/26/19: More feedback from Shapeways:

Also, Salesforce'ing. Lightning is kind of kloodgey.

2/25/19: Bool Tool!!

Also, driving myself crazy thinking non-linked objects were linked because proportional editing was on.


2/24/19: Many of the Blender operations I use generate non-manifold topology. Learning to make the model manifold as we go, then detail flood fill, then sculpt.

2/23/19: Select linked (CTRL+L). Modeling this is feeling like drawing with a concrete block.

Also, vertex groups, shape key sculpting, sculpt brushes, clay strips, crease, pinch, smooth. Sculpt mode is affected by scaling, which is quickly fixed with Apple Rotation and Scale (CTRL+A).
Also, Detail Flood Fill approximates the mesh with close-to-regular triangles.

2/22/19: We got some gemstones. Let's learn about them:

Clockwise from top:

Size Cut Grade Mohs AGTA Code
Yellow Sapphire 2mm Round AAA 9 (N) NOT ENHANCED
White Sapphire 2mm Round AAA 9 (H) HEATING
Fire Citrine 3mm Round AA 7 (H) HEATING
Pink Sapphire 2mm Round AA 9 (H) HEATING

What is...?
GRADE: This is a classification based on the color, clarity, cut and carat weight of the stone. The scale used for gem-grade sapphires goes B-A-AA-AAA. The GIA does not officially grade colored stones, and different sources differ on what each grade represents in terms of the rarity of the stone. This site has some interesting information:
The GIA reviews citrine quality factors here:
AGTA Code: These are the American Gem Trade Association codes to describe any treatment process other than cutting and polishing. Great explainer here:

2/20/19: GET OUTTA HERE WITH THAT WEAK GEOMETRY, shapeways sez (again):

Here is the geometry:

What will Shapeways do?

2/19/19: Backups.

2/17/19: Sort of...

Adding an empty set of axes to use as the origin of a modifier:


Also, apply rotation and scale (SHIFT+A) [...] eventually...

Also, select linked flat faces (SHIFT+CTRL+ALT+F). The 2mm stones we want to set have a depth of about 1.54mm.

2/16/19: Section image updates.

2/15/19: Cleaning polishing medium out of Shapeways sample.

2/14/19: Looking at printing studs, no soldering required.

2/12/19: Repeat history (Shift+R). If you upload a non-Boolean object to Shapeways, their modeler can gently nudge your geometry around until it makes sense to it. Shapeways conservatively estimating 27 day lead time to ship on our next silver piece.


Also, align camera to active face (Shift+NUM7). Techniques for planarizing nonplanar faces. Loop cut + triangulate works!

2/10/19: Decimate modifier.

2/9/19: More sculpting, shrinkwrapping an outline mesh onto a sculpted geometry. Also, Circle Select (C), unhide all (ALT+H). Considering the idea that any 2 dimensional shape can be tessellated in 3 dimensions. Applications of hyperbolic geometry.

2/8/19: Branding.

2/7/19: Proportional editing, Projected (O), connected (ALT+O).

2/6/19: Grease pencil, convert to geometry. Curve display options. Open/close a cyclic curve (ALT+C).

2/5/19: Sculpt mode, dynamic topology, detail size, mirror sculpt, matcap.

2/4/19: Good post on differences between UV and ICO spheres halfway down this page:
Also, "Draw All Edges" option on the Object tab.

2/3/19: Some real-world modeling.

2/2/19: Some light site redesign.


1/31/19: Blender Freestyle SVG Export, looking at hot foil stamping.

1/27/19: Working on removing doubles earlier in the modeling process. Reducing internal edges seems to help Blender's automatic processes work better. Also, curve from mesh (ALT+C), plane locking (SHIFT+[axis]), align view to edge (SHIFT+NUM7), Boolean intersections...more like boo-lean intersections. Taking internet advice and modeling those intersections by hand.

1/19/19: Set origin (Ctrl+Shift+Alt+C).

1/18/19: Limit selection to visible for face cleanup. Fighting with overlapping faces where quads intersect triangles.

1/16/19: Pivot point.

1/15/19: Beveling vertexes (Ctrl+Shift+B) and edge loops.

1/13/19: Selecting edge loops in Blender (alt+RMB) is going to save us a million, billion years in cleanup. Today, we venture into...3D

Thank you linked flat faces (Shift+Ctrl+Alt+F) also.

1/12/19, ii: Lighting.

1/12/19: Paths.

1/11/19: Angle shot.

1/10/19: Reflectors.

1/9/19: Still shots again, with white reflectors:

1/8/19: Trying to get more life into these still shots:

1/7/19: Exploring the "floating" jewelry photo style:

1/5/19: Enjoying the layout of Boucheron's site:

1/4/19: .sidenavCalendar was hiding 2019 through the overflow-x property. Fixed, and we move on.

1/3/19: Little bit of jQuery to update image size on index.html. Switched background repeat from round round to repeat; background-attachment now fixed.


12/31/18: Little bit of JS updating in the Dictionary.

12/28/18: Drilling tiny holes using tiny drill bits.

12/25/18: More more more d3.js (click the grid).


12/24/18: More more d3.js, modulo, filtering.

12/23/18: Breaking in my drill bits.

12/21/18, ii: More d3.js.

12/21/18: Google Search console sez:

What is...Google Search Console?

GSC is another set of tools from the Goog to assess site performance.

My best guess is that on slow loads, the CSS loads before the JS formatting and makes the page load in a format Google doesn't like.

Also, revisiting our d3.js code. Time to update that syntax to comply with (5.7.0)!

12/19/18: Tessellating?

12/18/18: Deferring images, base 64 images. References:

12/17/18: More looking at async and defer tags. What is...webpagetest?

We got an F ):
Also, cache control, URL fingerprinting.
Implementing content caching.

NOW what are we doing wrong?

Also, compressing a few more .pngs.

12/16/18, ii: Moving a jquery calls to 3.3.1. Issues with async tag loading jquery inconsistently.

12/16/18: What is...pngquant?

One of the things that is probably crashing Google PageSpeed Insights is our massive image library. Let's dive in, using one of the GUI distributions of pngquant, PNGoo.

The goal here is to take our most egregious assets and see how far we can compress them. One of the original goals for this site was to move away from the kind of automatic compression that Tumblr was providing, giving us the ability to host large, print-quality scans and pictures. This has proven to be both:
a) Unnecessary (this website is never used that way)
b) Costly for our render time
Here's our biggest image asset:

That's a huge savings, but this is still a massive image hosted in the middle of a blog post.
The last step I'm going to take is to scale the PNGoo output in GIMP and recompress.
Original file size: 2827 KB
Final file size: 356 KB
Side note: There was going to be another image at the end of this post using Snipping Tool (I am a lazy man) to compare image quality between pre-compressed and post-compressed images. Normally, Snipping Tool captures are pretty small, but this one was more than 3 MB! Maybe ST automatically adjusts quality based on the source image? Regardless...

We're up to a 77, boys! DECENT

Here are the next GPSI opportunities:

12/15/18: Eventually got GPSI to finish yesterday, landing us in the 60's. Adding .mp4's back in, might have been Namecheap issues at 5AM.

Did you know? Site speed affects your Google ad ranking:
(Also: minification, GZIP, bit depth, delta encoding, switching from .png to .jpeg for our utility photos, automating image optimization, pngquant, ImageOptim, lazysizes.)

12/14/18: Converting site .gifs to .mp4s. Getting time_outs from Google Insights.

Taking out links to external images not hosted by our site. Get that green lock back!!

Also: Fixing the poster placeholder links in our video tags, cleaning up errors in .svg and older posts.
Commenting out our video links, no change.
Deleting .mp4s, no change.

12/13/18: What is...Google PageSpeed Insights, and why does it hate me?

So let's look at some articles, starting with:

Let's try it:

The needed ffmpeg syntax for me was: "ffmpeg -i input.gif -c:v libx264 -strict -2 -preset slow -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -f mp4 output.mp4"

Original .gif @ 1,772 KB
Converted .mp4 @ 140 KB
Heck yes!

12/12/18: More GA (Google Analytics). Our page load time is slow - let's try to get that down. We should be hosting thumbnail-sized versions of our large .pngs and splitting the Per Diem site out into quarters or months.

12/11/18: 404 page!
(404 pages require absolute paths for links and JS)

12/10/18: We had a little spike in our traffic recently. What is...bounce rate?

Bounce rate = A single-page session on your site

In the last 7 days, we got most of our referrals from "99 reasons for seo"

OK...what pages are they visiting?

That is not a subdirectory that exists on my website. What's going on?

Probably, referral spam. Some interesting writing on the subject:

12/09/18: Finalizing hardware and programming on TFT ornament.

12/08/18, ii:

12/08/18: Tessellating!

12/05/18: Enjoyed this overview of tessellations on the sphere:
Also, new CSS: hyphens: auto.
Also, self-referencing tessellations:



11/29/18: Assembling our TFT module (step-up power supply + Nano + TFT + on/off button.)

11/27/18: Mounting on/off button.

11/25/18: Thermoplastic. Lessons:
1. Do not handle with heat-conductive tongs, thermoplastic will form a symbiotic relationship with the tongs, making it impossible to remove.
2. This stuff is really easy to work with, but will bind to rough surfaces.
3. Thermoplastic is soft enough when cool to mark with your fingernail, but hard enough to cut a clean, faceted face into.

11/24/18, ii: Auto-power off based on this circuit:
What is the catch? This circuit bypasses the voltage regulator on the Arduino. sez:

5V. This pin outputs a regulated 5V from the regulator on the board. The board can be supplied with power either from the DC power jack (7 - 12V), the USB connector (5V), or the VIN pin of the board (7-12V). Supplying voltage via the 5V or 3.3V pins bypasses the regulator, and can damage your board. We don't advise it."

Next time: deepSleep().

11/24/18: What is an...AMX3d Lilypad Power Supply?

This supply is supposed to take any input from 1.2V-5V (such as an AAA battery) and output 5V. How does it do this? Let's take a look at the components: (I couldn't find the AMX3d schematic, here is the Sparkfun version:

A boost converter (or step-up converter) is based around an inductor. When a power supply is connected to the circuit, a magnetic field is created. When the power supply is disconnected, the magnetic field collapses and creates a voltage in the circuit. This voltage can be higher than the applied voltage.

If you add a capacitor to the circuit, you can increase the voltage every cycle. A MOSFET or other switching transistor can be used to do this automatically.
Here is visual walkthrough:

11/23/18: Blender Freestyle tutorials for "blueprints" (or an artistic approximation.)
Good walkthrough here:

11/22/18: Working with Adafruit TFT library. (Also, OBS for desktop recording.)

11/21/18: Working towards a pushbutton Arduino power on/timed shutoff. What is a...

MOSFET = Metal-oxide-semiconductor field-effect transistor with an insulated gate whose voltage determines the conductivity of the device

(Also, troubleshooting UNO that couldn't download from the Arduino IDE. If your Arduino case is constantly pushing down the reset button then it will not work.) :|

11/20/18: What Adafruit 1.44" TFT?

Vin = Power in (3-5V DC)
3.3V = 3.3V out
GND = Ground
CLK = SPI clock input pin
MISO = SPI Master In Slave Out pin (used for the SD card)
MOSI = SPI Master Out Slave In pin (sends data to the SD card and/or TFT)
TFT_CS = TFT SPI chip select pin
RST = TFT reset pin (connect to ground to reset the TFT)
D/C - TFT SPI data/command selector pin
Card_CS = SD card chip select (to read from the SD card)
Lite = PWM input for the backlight control. (default high = backlight on)
(Pulled from the excellent documentation by Adafruit:

Upside-down demo:

11/19/18: Changing some functions to not run every loop(), ISRs. Learned that the blocking function in our code is the Adafruit display library taking a measurable amount of time to refresh the screen. Only updating the display when an input changes.

11/18/18: Realized that if our microstepping is based on delayMicroseconds(), and we have 3 motors, the speed setting of each motor will affect all 3. Rewrote microstepping code based on micros().

11/16/18: Arduinos can only do one thing at a time. What is the right solution for 3 motors with external speed controls, a display, and an ultrasonic sensor? This is an interesting thread:

11/15/18: Examining options for mounting components.

11/14/18: Cleaning up motor code.

11/13/18: Firing our ultrasonic sensor ever 12 seconds with delay() was preventing other inputs. Using millis() and micros(). What is...?
millis() = Returns the number of milliseconds since the Arduino program was started.

(Also, classes, constructors. Next time - non-blocking stepper control.)

11/12/18: What is a SainSmart HC-SR04 ultrasonic randing detector?

The Trig pin is used to trigger a soundwave, the Echo pin waits for the soundwave to start and stop. This time is then converted into distance using the speed of sound (340 m/s).

What is...?
pulseIn(pin, value, timeout(optional)) = This Arduino IDE function reads a pulse duration. If the value is set to HIGH, pulseIn() waits for the pin to go from LOW to HIGH and back to LOW.

On our next show, replacing delay()...Thanks to for the excellent tutorial!

11/11/18: Our Shapeways battery holder-holder arrived:

I designed this to hold 3 of these 4xAA holders: The material is 1mm thick all around.

The box is flexible, once the battery holders are in there it feels very solid.

At $32.33 with shipping, I could have done a better job reducing the amount of material used to print (cutting the top half of this off wouldn't sacrifice much structural integrity.) Printed using the Shapeways "versatile plastic" material.

(Also testing rocker switches.) (Also buttons and state machines.) What is a...
Pull Down Resistor = A resistor used to hold the logic signal near zero volts when no other active device is connected.

11/10/18: Back up and running with A4988 replacements. Blew one up by connecting our Vmotor supply to the logic power rails.

Decided to get fancy and make a separate Nano-based A4988 tester board. Nano no longer recognized, possibly caused by using an external power source with the Nano. There are MASSIVE amounts of troubleshooting suggestions for this. Verbose output in the Arduino IDE, FT_PROG, CDMUNINSTALLER. Tried soldering together GRD and TEST on the Arduino FTDI chip per internet suggestion.

Using our Arduino Uno as an ISP. What is...
ISP = In-circuit Serial Programmer

1 million Arduino threads later -- pulling eject to get a go bagel.

11/9/18: Taking about 100 lines of code out of our Arduino sketch by defining a custom function. Checking out Shapeways store setup.

11/8/18: Setting up our oscilloscope. Probe compensation adjustment. What is a...
BNC Connector = Bayonet Neil-Concelman connector, a quick connect radio frequency connector for coaxial cable.

11/7/18: Software tweaks. Somehow caused a short back through the USB-B connector on our Arduino Mega to the Dell WD15 dock it was connected to. What was the issue?

One of our A4988 drivers has a short somewhere. We saw the same thing out of the box with a few of the other drivers. What could the cause be?
1. Heatsinks that overhang components causing a short
2. LC voltage spikes, causing issues for the ceramic capacitors on the A4988

Plugging the A4988 driver into our Arduino power rail causes flickering on our OLED before triggering the Arduino auto-shutdown.

Resolution: Will be powering the Arduino from a 9V battery, USB connection only when reprogramming. Will return in the future to see if we can better diagnose our component failure.

Thanks to Pololu for the LC voltage spike article:

11/6/18: Rotary encoder + OLED + stepper. Using the rotary encoders pauses the digital output to the steppers. Controlling forwards and backwards with encoders.

11/5/18: Identifying capacitor polarity (or non-polarity). Increasing serial speed. Tweaking arduino encoder code. The rotary encoder works better, but not at high rotation speeds. Incrementing by multiples. Capping motor limit at +-100%

11/4/18: Rotary encoder + 128x64 OLED.
These encoders have a lot of "bounce", meaning when you turn them, the reading you get back is not always accurate. This is minimalized when turning the knobs slowly.

11/3/18: Testing KY-040 rotary encoder.

11/2/18: Are loose wires making you weird and splenetic?

Here are DonoPont cable managers:

In your favorite 2.54mm pin pitch!

Easy to cut into your needed number of clips.

Now you are less haunted Go away voices! Ha ha ha (:

(Also, turning our HTTPS redirect back on.)

11/1/18: Firing up our little OLED display. What are these pins...?
SCL Pin = Clock Line
SDA Pin = Data Line
They let us communicate with I2C/TWI devices. What are...?
I2C = Inter-Integrated Circuit, pronounced I-squared-C, is a synchronous, multi-master, multi-slave, packet switched, single-ended, serial computer bus [...] It is widely used for attaching lower-speed peripheral ICs to processors and microcontrollers in short-distance, intra-board communication.
(thanks Wikipedia,
TWI = Two Wire Interface, similar to and compatible with I2C

We are starting with the I2C scanner here:
I2C scanner sez:

We are using the following libraries:
Adafruit SSD1306 library
Adafruit GFX library


Thank you to Jean0x7BE for the very good tutorial!


10/31/18: Always sad to see a mouse go, moved on to my second Logitech G502 (always RIP G9X from college). This G502 lasted about 29 months before succumbing to the well-documented Logitech left-click misfires.
Microstepping on the A4988.

10/30/18: When the power is out, LEDs make it possible.

10/29/18: Modeling a box for our 4xAA battery holders. Probably spent too much money on Shapeways having solid walls all around. Next time, mesh.

10/28/18: Multiple motors at once with speed control.

Plus, structural improvements to our motor base.

Desoldered the very loud buzzer from my Aroma rice cooker so I don't wake my girlfriend when I cook in the morning. Success! Could not fix the fact that it is an atrocious rice cooker.

10/27/18: Checking the permutations of coil ordering on our Nema 17 motor. Making a safety clip for our 16V power source so I don't short anything else. Motor working. What was wrong?
1. Delay between high/low pulses to the driver were too short (doubled from .5ms to 1ms)
2. Was pairing coil wires incorrectly.

Also: Stabbed to Death by Header Pins (sharp ouch)

Do all of our motors work? Yes.
Do all of our A4988's work? No, 1 doesn't do anything and 1 causes our Arduino to auto-shutdown.

10/26/18: Current limiting.

10/25/18: Powering up our Nema 17 motor. Directly measuring the current of our 12xAA stack caused a happy curl of smoke. Why?
Today made possible by our Fluke 117 not setting us on fire. Thanks, Fluke!

10/24/18: Why doesn't our 4xAA clip generate a voltage? If only our battery was a little longer...

Battery clip goes under the knife, there we go, now we've got 16V.

10/23/18: We submitted our DonoPont clip for production in 3 materials. Shapeways sez: partially rejected.

Material Min Supported Wall Thickness Min Unsupported Wall Thickness Order Status
Fine Detail Plastic
(Resin-based Acrylic Plastic)
0.3 mm 0.6 mm Processing
Professional Plastic
(HP Nylon Plastic PA12)
0.4 mm 0.5 mm In Production
Versatile Plastic
(Nylon Plastic PA12)
0.7 mm 0.7 mm Cancelled

Why didn't Shapeways reject all 3? Once more unto the breach, dear friends.

10/22/18: Blender wire clip to fit cables in a DuPont connector.

10/21/18: Learning to make DuPont connectors. Doing it upside-down the first 4 times proved highly ineffective.

Plus, looking inside one of these Nema 17 steppers, because the wire colors were in different orders on different units.

10/20/18: Tweaking spherebot base.

10/19/18: Calibrating spherebot.

10/18/18: Buck converter, tiny screwdrivers.

10/17/18: Quick maths. For our 80mm sphere project, the wheel contact points should be 60mm apart.

10/16/18: More component organization. Portrait of a screwdriver as a boy.

10/15/18: Relearning Arduino syntax.

10/14/18, ii: First test transmissions. Hello! Even with modules close together transmission is erratic. Destroyed LED ):

10/14/18: What is? A Longruner NRF24L01 transceiver module?

MISO = Master In/Slave Out
SCK = Serial Clock
CE = Chip Enable
GND = Ground
IRQ = Interrupt Request
MOSI = Master Out/Slave In
CSN = Chip Select Not
VCC = Voltage at the Common Collector (1.9-3.6V)
Thanks to for the excellent tutorial.

10/13/18: The warning diagrams from this JHD659 LCD module are amazing

Plus, loops, delays and reversing.


10/11/18: More component organization.

10/10/18: Multifunction component tester assembly, component organization.

10/09/18: Soldering our BNO055 9-DOF sensor. Adafruit libraries, Processing, rotating a cube.

10/08/18: Researching motor couplings.

10/07/18: LTspice! Setting up an IR breakbeam sensor on the Arduino. Ordered an Elisona Nano, arrived with a big blob of solder between the D2 and D3 pins. Initial googling doesn't reveal any obvious reason why, removed.

10/06/18: What is? An L298N shield? It is...

a high voltage, high current dual full-bridge driver designed to accept standard TTL logic levels and drive inductive loads such as relays, solenoids, DC and stepping motors."

Full-bridge driver = An H-bridge
H-bridge = An electronic circuit that switches the polarity of a voltage applied to a load
TTL = Transistor-transistor logic; transistors perform both the logic function and the amplifying function
Inductive load = Loads that resist changes in current (e.g. electric motors)
Relay = An electrically operated switch
Solenoid = An electromagnet whose purpose is to generate a controlled magnetic field
This is what an H-bridge does:
This is an inexpensive way to control multiple motors through an Arduino.

10/05/18: Shapeways project #2 arrived! Wax printed and cast in bronze.

10/03/18: More soldering tutorials.

10/02/18: Soldering tutorials. First solder joints!

10/01/18: Thinking about UV mapping, and ways of splitting a sphere.


9/30/18: Arrays, knife cuts, measuring tools in Blender.

9/29/18: Looking at these clever patterns for bending cut geometries aka kerf cuts, living hinges, sninges.

9/28/18: Raspberry Pi camera, CSI, Python 3, ribbon cable origami.

9/26/18: RDWorks, Learning Lab, Lightburn, living hinges.

9/25/18: Parametric modeling, arrays, ODS.

9/23/18: Testing some examples from the RFID library located here

9/22/18, iii: RC522, Arduino.

IRQ = Interrupt Request (Triggers an interrupt)
NSS = Slave Select (Pin the master can use to enable and disable devices)
SCK = Serial Clock (Synchronizes data transmission generated by the master)
MOSI = Master Out Slave In (The master line for sending data to the peripherals)
MISO = Master In Slave Out (The slave line for sending data to the master)
GND = Ground
RST = Reset
VCC = Positive voltage (3.3 Volts in this case)
Thanks to for definitions.

9/22/18, ii: 2nd model submitted for printing at Shapeways.

9/22/18: More 3D cleanup. Disconnected edges in several places. Subdividing edges for easier and more logical curve mapping.

9/20/18: Reworking our next mesh.

9/19/18: Raspberry Pi 3B+ (day 3), GPIO IN, buttons.
(Raspberry Pi is a trademark of the Raspberry Pi Foundation)

9/18/18: Raspberry Pi 3B+ (day 2), GPIO, Python 2, blinking LED.
(Raspberry Pi is a trademark of the Raspberry Pi Foundation)

9/17/18: Raspberry Pi 3B+ (day 1), heatsinks, NOOBS, Raspbian.
(Raspberry Pi is a trademark of the Raspberry Pi Foundation)

9/16/18: Carboard prototyping.

9/15/18: What shape is my wrist?

Our Shapeways model was approximately wrist-shaped, but it sat awkwardly, sticking out too much on the sides. I took it to the vise to figure out what felt right. It needed to be about 5mm taller and less rounded. The vise did crack the part in several places, but only on the edges where the metal is 1mm thick. In the redesign, I'll be looking at making the sides flatter and focus on advantages we can press in an asymmetrical design.

9/14/18: What shape is your wrist? It depends on whether your wrist is supinated, pronated, or in between. Your wrist is controlled by the motion of the two bones of the forearm, the radius (closer to your thumb) and the ulna (the "outside" of your wrist).

As you rotate your wrist, not only is the skin sliding over these bones, the muscles and connective tissue underneath change shape as well. A wide bangle (like the below) that fits snugly will have to accomodate a dynamic geometry in order to feel comfortable.

9/13/18: Arduino projects (15/15), optocouplers.

9/12/18: Arduino projects (14/15), Processing.

9/11/18: Arduino projects (13/15), capacitance.

9/10/18: Arduino projects (12/15), Piezo as sensor.

9/9/18, ii: We got our first Shapeways project back. Here it is as shipped (including residual manufacturing greebuloid material):

Density Yield Strength
Tuna Noodle Casserole 0.93 g/cm³ Pretty weak
AlSi10Mg Aluminum 2.68 g/cm³ 206-264 MPa
420SS/Bronze Matrix 7.86 g/cm³ 455 MPa
Sterling Silver 10.26 g/cm³ 100 MPa
18 Kt Yellow Gold 15.10 g/cm³ 250 MPa

Material: I printed this in Shapeways' 420SS/bronze option, 60% steel/40% bronze (this is an ExOne binder jetting/sintering/bronze infiltration process). The material is 8.45x more dense than tuna noodle casserole, according to this food density reference.

Accuracy: The model was submitted with a Z-height of 25.4mm. Caliper sez: 24.33mm. A 4.2% difference isn't a lot, but if we were making rings, that's more than an entire ring size. I'm only investigating the Z-height of the part, since I started testing the XY elasticity immediately out of the box.

Finish and color: The surface shows some pitting, similar to sand-casted materials. The pitted areas are a little warmer in color. The consistency of the material color is good throughout the part. According to the manufacturing process specs, the material is polished through tumbling, which might explain the bits of material left in the negative spaces. The finished part has parallel brush strokes on some of the large flat faces.

Overall: The finished part looks good and retained the detail of the original model well. With some iteration and experimentation on the surface finish, this could be a viable manufacturing option for someone without casting equipment.

9/9/18: Arduino projects (9/15), DC motor, external power, transistors, diodes.
Arduino project (10/15), integrated circuits (IC), H-bridges.
Arduino projects (11/15), LCD.

9/8/18, ii: Arduino projects (5/15), Servo motor, header pins, capacitors.
Arduino project (6/15), piezo.
Arduino project (7/15) Buttons in parallel.
Arduino project (8/15) Tilt sensor, millis().

9/8/18: Arduino projects (4/15), Pulse Width Modulation (PWM), phototransistors.

9/7/18, ii: Arduino projects (3/15), analog pins.

9/7/18: Arduino projects (2/15), digital pins.

9/6/18: Arduino projects (1/15), resistors. Red for power! Black for ground! Resistors are reversible. V=I*R

9/5/18: Arduino, diode, anode (+) --▷|-- cathode (-), H bridge, optocoupler, mosfet, platform assembly.

9/4/18: New day, new mesh.

9/3/18: Arduino IDE, sketches.


8/31/18: Moving from Portland, OR to Columbus, OH. How'd we do?
Miles: 2475
Fuel Consumed: 1458.65 lbs
MPG: 10.52 (Vehicle: GMC Savana Hicube)
States: 9 (OR, ID, UT, WY, NE, IA, MO, IL, OH)

8/30/18: Proportional editing!

8/27/18: Resubmitting updated design to Shapeways.

8/26/18: Joining objects, again (CTRL+J), Inset (I). Bevel (B).

8/25/18: Unpacked. Don't bring that weak geometry, sez Shapeways:
N panel, face area.

8/14/18: Gravity, rigid bodies, center of mass.

8/13/18: Figuring how to use knife project for rings.

8/12/18: More SVG manipulation in Blender.

8/11/18, ii: Importing SVGs, working with curves, exporting image strips.

8/11/18: Fly mode (Shift+F)! User Preferences:Auto Depth, Zoom to Mouse Position. First model submitted to Shapeways! Cooking my laptop, playing with shaders without a proper GPU.

8/10/18: Knife project, circles, curve modifier to wrap around an axis.

8/9/18: Remember to join your faces (CTRL+J) if you want to manipulate a plane as a single mesh! (Shift + Z) to move only on the XY plane.

8/8/18: MeshLab! Netfabb! Shapeways upload tool, material comparison.

8/7/18: Extruding for texture, materials, lightning. Mesh:cleanup tools.

8/6/18: Assigning to groups, materials. Losing undo history by switching between edit/object mode.

8/5/18: Modeling a cuff.

(Also || Snap to grid:increment, specials:remove doubles. Bezier circle, modifier:curve. Origin:origin to 3D cursor, origin:geometry to origin.)

8/4/18: Blender, modifier:solidify, modifier:simple deform, edge split, Sverchok, modifier:wireframe, edge slide, face tools:poke;fill;triangles to quads(alt+J),...load factory settings...deleting startup.blend...

8/3/18: Blender tutorials (x/41), vertex groups, keyframes, timeline, dopesheet, graph editor, select by trait, loose geometry, STL checks, tessellating meshes.

8/2/18: Blender tutorials (x/41), tracking constraints, rigging (again), modifier stacks, inverse kinematics.

8/1/18: Blender tutorials (x/41), sampling, rigging, parenting, null objects, armature, object constraints.

JULY 2018

7/31/18: Blender tutorials (x/41), shaders, cycles, node interface, Voronoi textures, light sources, fil/key/back lights, non-photorealistic shading, render output.

7/30/18: Blender tutorials (14/41), primitives, hiding/layers, interface. A weeping cobalt cube. Nurbs. A dirty chair.

7/29/18: Shapeways/Blender, normals facing out, no internal geometry, non-manifold geometry, Blender tutorials (3/41).

7/28/18: Tessellating [...]

7/25/18: Adding anchors for DPD entries.

7/24/18: Based on your location in Portland, OR, which Blue Star Donuts is closest? Here's a handy map generated with d3-voronoi, based on this example by Mike Bostock.

7/22/18: Enjoying these factorization diagrams by Brent Yorgey. How do you quickly identify an 11-sided, 13-sided, or 17-sided shape? Probably best to switch from a real representation to a symbolic one. Periodicity (by Jason Davies) or color gradients (by Nicholas Rougeux) might help. (side topics: Shadow DOM! +referencing SVG externally.)

7/21/18: SVG'ifying the hexes. (2018-12-14 svg code redacted due to errors)

7/20/18: Also, use single quotes if you need double quotes inside a string.


7/18/18: .last(), .remove(), transform: perspective.

7/17/18: Hexes! If you use JS to target a class, you must then specify which element in the array you want to modify.

7/16/18: Adjusting sidenav animation size.

7/15/18: SVG animation for IOHES sidenav.

7/14/18: Canvas animation, event listeners.

7/13/18, ii: For fun, let's take a look at relative frequencies of the first letters of words in the English language (top) versus the Dictionary of the Damned (bottom) as of today...(ignoring that there are no æ words in Peter Norvig's data.)

English DD
Favorite Letter T (15.978%) A and C (10.588%)
Average word length 5.1 6.4

What does it mean? The Dictionary of the Damned has a weird fascination with words that start with C (and is unimpressed by words that start with T [3.529% of the DD]).

+Google Analytics!

7/13/18: Spline interpolation with cubic bezier curves. Renaming <canvas> elements.

7/12/18: Standalone DD DoD page.

7/9/18: GIMP can export GIFs?

Fixing the DD's hidden sidenav pointer-event issue.

7/8/18: More CSS animation fiddles.

7/7/18: Frame-by-frame animation in CSS.

7/6/18: While loops, .firstChild, removeChild. SCSS!

7/5/18: MDN bouncing ball demo, object building.

7/4/18: Kinematics, dynamics. Did I know? You can declare arbitrary elements in HTML, like new friends <ball> and <square>:     !!! This bit of code causes these animations to restart after 400ms: document.body.innerHTML = document.body.innerHTML.replace('✪', ' ')}), 400).

7/3/18: Did you know? GIMP can export paths to SVG. Using inline SVG to replace little icons.

7/2/18: R, RStudio, ggplot2. This development environment alludes to the mythological idea of a World Package that supports the earth a single scatterplot on its back. It suggests that this package rests on the back of an even larger turtle package, which itself is part of a column of increasingly large packages that continues indefinitely.

7/1/18: Reformatting pt.ii. If you want to be the cool guy with visibility:none elements in your hidden sidebar, if they invisibly overlap your body's <a> elements, you will no longer be the cool guy.

JUNE 2018

6/30/18: Reformatting for better visibility.

6/28/18: Sticky footers, with and without flex layouts.

6/27/18: Formatting, standardizing pages.

6/26/18: First appearance of Wordbow. Header/footer bars to indicate the start and end of the content. More content filtering based on media width.

6/25/18: Tweaking the timing of synchronous js scripting.

6/24/18: PerDiem date key using d3.js, reformatting, reorganizing.

6/23/18: PHP (again), cURL, Uptimerobot API.

6/22/18: Uptimerobot!

6/21/18: Animations and d3.js.

6/20/18: More d3.js foolin'. setTimeout(), promises.

6/19/18: More d3.js formatting.

6/18/18: If you leave a script src= in your body with no valid target, nothing will happen. If you forget that script has a valid target locally but not on your website, your website may have ghosts. Email.

6/17/18: "About" link. HTTPS!

6/14/18: Did you know? "Damn" comes from the Latin damnum, "loss, damage".

6/12/18: If you tell your tr's and th's to have different hover events, Chrome will interpolate the results.

6/11/18: Sticky headers.

6/9/18: Looking at museum websites, Chase and Sketches sidenav index.

6/8/18: Revisiting our friend :active, thanks to friend of the show JRB.

6/8/18: Line breaks, block styling.

6/7/18: Colors, borders, bookmarks. :target, smooth scrolling to anchors. Now tracking number of Æ entries in the DD.

6/6/18: Styling tables (again). Content inserted with CSS cannot have events attached to the pseudo element.

6/5/18: Tooltips and visualizing bigrams.

6/4/18: Animation in d3.js, maths, bubble packing, stems and leaves.

6/3/18: d3.max(). Debugging and eating tasty NaN.

6/2/18: More adventures in d3, counting days, ranges.

6/1/18: Increasing data density.

MAY 2018

5/31/18: Month labels.

5/30/18: Colors, positioning.

5/29/18: Migrating between versions of D3.js.

5/28/18: Poking at

5/27/18: D3.js! (Today's post brought to you by best-in-class CSS color #blanchedalmond)

5/20/18: Adventures in offscreen rendering.

5/19/18: Cleaning up, first appearance of adverbs in the DD.

APRIL 2018

4/21/18: InDesign.

4/14/18: Quote from Albrecht Durer's "Of the Just Shaping of Letters" (1525): "For it is the easiest thing in the world for the Arts to be lost and perish; but only with difficulty, and after long time & pains are they resuscitated."

4/7/18: Toning up the site background. Thinking about majuscule and minsicule.

4/4/18: Toning down the site background.

MARCH 2018

3/31/18: Photoshop trial. The hardest part of GIMP, is letting go. Also Javascript key codes.

3/30/18: Math.random(), Crypto.getRandomValues().

3/26/18: SOWPODS search now looks only for whole words, not parts of words.

3/25/18: Notepad++, for when you need to quickly edit 250k lines simultaneously.

3/24/18: Reminder that "=" assigns a value, "==" checks equivalence, "===" checks equivalence and types. Word boundary associations.

3/23/18: Arrow functions!

3/22/18: fetch, readAsText, more SOWPODS.

3/17/18, iii: Definitions by

3/17/18, ii: When there is only one single-line text input field in a form, pressing enter will submit the form. If you have two separate functions in one script, they do not share variables.

3/17/18: Regex, str.replace, str.slice., Wikimedia API only needs origin=*.

3/16/18: Looking at XML, jQuery.parseXML()

3/15/18: More MediaWiki API!

3/13/18: .text(), .change().

3/12/18: Creative Commons licensing, first JSON script. SOWPODS word lists are possibly free to use? Query/parse of Wiktionary content.

3/11/18: Back to JSON and AJAX.

3/11/18: SPARQL, WDQS, MediaWiki API vs Wikidata Query Service, REST, API sandbox and etiquette.

3/9/18, ii: Wiktionary API!

3/9/18: Android user interfaces. Did you know? Android is a multi-user Linux system in which each app is a different user.

3/8/18: Kotlin? Lambda functions?

3/6/18: First Android virtualization, JMC, Netbeans. Oracle concepts overview: you are a blue square going 18mph, changing gears, with seborrhoeic dermatitis.

3/4/18: Android SDK, JDK, Java overview. Jimmy's got a bad case of the gradles.

3/3/18: Password protecting subdirectories through .htaccess and cPanel.

3/2/18, ii: Updating Chase.html gallery. Removed direct link to img source.

3/2/18: Tweaking intermediary gallery. Display "initial" is not your css's initial.

3/1/18: If you don't terminate a comment at the end of a script your js will FAIL! Fie upon your syntax highlighting for making you think you could get away with that applesauce!


2/28/18: Working on intermediary frame for pictures to display additional info before link to full size image.

2/26/18: Same-origin policy, scheme/host/port tuples, CORS, iframes.

2/25/18: Still occasionally getting loading error for previews on main page. Implemented one-time reload with a hash.

2/24/18: Twilio, Python, Heroku, SendGrid, Donocorp acquires first TFN. Meta descriptions. First appearance of Donocorp in the canon.

2/23/18: Fixing horizontal scrollbar on small screen width, thank you overflow-x, overflow-y. Will-change for sidebar smoothies.

2/20/18: Adjusting footer image, prep for About page.

2/18/18: "Back to top" link, setting up email. Iohes appears in Google search!


2/14/18: Logo design.

2/13/18: Considering the viability of an svg/js tracker, margin adjustments. Using a callback in DD graph instead of two parallel funcitons. Firing a blank js function will prevent the following js function from running.

2/12/18: Switching to a sidenav that doesn't push content, eliminating the 50px mini sidebar. Using a callback in DPD js instead of two parallel functions.

2/11/18: Web dev tools, consoles, debuggers. Smaller image sizes under x screen width. Removing borders from main page sections. Nth-child, nth-of-type selectors to create "lite" version of main page. Hiding elements on all pages under x screen width for any content that isn't meaningful when small.

2/10/18, ii: Learning about: Loading messages, SSL certificates. Cleaning up hr and SubmitDD js. CDN fallback/jquery fallback. Taking out body onload()s. Updating to jquery 3.3.1. Removing redundant jquery.

2/10/18: Favicons! Cleaning up directories. Removing body:before to fix loading on mobile. Real resized thumbnails for faster image loading.

2/9/18: Live! (nameservers, robots.txt, index.html, cpanel, .htaccess, title, looking into js inconsistencies)

2/8/18: Formatting DD entries, standardizing date format. Switching from visibility:hidden to display:none to fix formatting. Switching from lt() selector to gt() for main page to select intended elements. lt() and gt() didn't solve counting issue, moving td class to tr, updating DDForm js. Adding links back to jewelry and sketch pages. Adding additional classes to images for easier scripting.

2/7/18: Changing background color on .load using .css, updating js for DD form. Alt. sidenav format that doesn't push content; this doesn't work well with the 2-stage navbar in place. First use of .toLowerCase to match case for variables. Using tr:first, td:lt(6) instead of tr:first, tr:last in main page table loader fixes issue of graph counting the loaded dictionary entry as part of the graph.

2/6/18: Letting the div determine the width of canvas graphs to fix scaling issues, cleaning up margins, using css to hide table columns when screen width is smaller. Body onresize is a slow function. Once page is long enough for a scrollbar, width of page is shifted the width of the scrollbar, deemed nonissue. For now using html overflow-y: scroll to keep scrollbar always visible.

2/5/18: Getting out of div hell, switching grid from fixed to auto-fill.

2/4/18: Return of the chasing hammer icon, prepping for mobile.

2/3/18, ii: Removing noise from main page, clarifying naviation. Adding a bottom navbar link, but not, because it adds length to the page.

2/3/18: Using placeholders to diagnose .load issue, nesting .attr inside of .load function to fix inconsistent image loading, preparing formatting for content.

2/2/18: Lining up main page JS, more CSS classes and ids, DPD graph updates are now automated instead of hard-coded.

2/1/18: Parsing HTML, a billion answers to loading an img src from another page.


1/31/18: .attr, inserting src instead of loading the entire image.

1/30/18: CSS grid.

1/29/18: Re-examining Sketches.html CSS to line up better (moving from a flow to a tabular format).

1/28/18, ii: Converting dates to ISO 8601 format, Math(), js functions for returning the date, difference between today's date and most recent update.

1/28/18: Inserting most recent update into the main page, tr:first, tr:last., coping with inconsistent date documentation.

1/27/18, ii: Formatting main page, canvas padding, DD cleanup + reordering. .load() is depricated, replacing with .ready for one script.

1/27/18: thead, tbody, DD search formatting. If you have your css defined twice in the stylesheet your singular efforts will be WASTED. Using .getscript() to load js after $(function()).

1/26/18: .load(), .hide(), pulling graphs into iohes.html, DD is now searchable.

1/25/18: $(document).ready(function) is $(function), linting redundancies, subaxes, dblclick(), but also not to prevent intersection of click() and doubleclick().

1/24/18: Filter:grayscale, JS manipulations of pseudo-elements, figuring out what is between head and body, bar graph. Who is AJAX?

1/23/18: Canvas, graphing, svg, JSON. If the script is in the head, and the section elements are in the body, then they don't exist when the script runs.

1/22/18: Alphabet counter for DD, JS arrays.

1/21/18: Inserting HTML through JS, learnin' about security holes. /*comment syntax in CSS is different than html >:|*/

1/20/18: Cleaning, site background, jewelry mascot, less code on each page = more pages of code. DpD counter.

1/18/18: Added separate page for jewelry, sidebar spacing, cleaning up Sketches.html.

1/17/18: More cleanup, looking at options for main page. The devil told me to add sound, and I said no. (Also removed the dotted border around links.)

1/16/18: Replacing chunky js blocks with external scripts external .css, @import, Sublime keyboard shortucts.

1/15/18: ID ≠ Id. Animation pause when sidebar is open.

1/14/18: JS animations, pause, additional access points to sidenav.

1/13/18: Atom: high 5 down low too slow. Back to Sublime.

1/12/18: Update: FF57 has shape-outside turned off by default. Spirits crushed. Text re-rectangulated.

1/12/18: Shape-outside, shape-image-threshold, floats!

1/11/18: Quartering pages, typewriter effect.

1/10/18: Main page updates!

1/7/18: Updates, looking back upon the code of a madman.


(whole month): Little progress. Snow, rum.


11/25/17: Taking a look at GSAP.

11/23/17: Coordinate systems.

11/22/17: SVG.

11/21/17: More clip paths! Inkscape!

11/19/17: AHK, formatting dates for lists.

11/18/17: Clip paths!

11/13/17: Slideshows.

11/11/17: Standardizing subpages.

11/10/17: Clickable backgrounds.

11/7/17: Color schema.

11/6/17: Small aesthetic adjustments.

11/4/17: Making "terrible use of Javascript" (i.e. performing sorting tasks on the front end).

11/3/17: Hiding unused elements.

11/2/17: Color schemes and JS scope fixes.

11/1/17: Color schemes.


10/31/17: Cycling image galleries, .appendChild(), predictable directory structure to solve without a server-side solution.

10/30/17: Amounts of .getElementById.

10/29/17: Did you know double borders have to be at least 3px or they render as a single border?

10/28/17: Forms!

10/27/17: Thinking about depth perception, displaying 2d photos of a 3d object in a layered environment.

10/26/17: Flex setup for images to replace tumblr format.

10/25/17: Cleaning up headers, breaks.

10/24/17: Dictionary can count nouns, verbs and adjectives. Go verbs!

10/23/17: WAMP, every Visual C++ library ever, phpMyAdmin, PHP loaders, [...]

10/22/17: If you try to call two Javascript functions simultaneously and the first one doesn't exist, it will call neither of them!

10/21/17: Caliper!

10/20/17: Jquery for window size, margin:auto doesn't transition.

10/19/17: Did you know? ID selectors are case-sensitive. __ /\ \__ ___ __ __ \ \ ,_\ /' _ `\ /'__`\ /'__`\ \ \ \/ /\ \/\ \/\ __//\ \L\.\_\ \ \_ \ \_\ \_\ \____\ \__/.\_\\ \__\ \/_/\/_/\/____/\/__/\/_/ \/__/

10/18/17: Using the sidenav to cover content when open

10/17/17: Tables, styling, sorting.

10/16/17: Sublime, Sublime packages, flex boxes, style sheets.

10/15/17: Inline elements obey neither man nor code

10/14/17: Javascript counter, and the website can count to 2 <tremble>

10/13/17: Linting unusued resources, white-space for the sidenav.

10/12/17: Icons, resizing, reorganizing.

10/11/17: Icons, vertical-text.

10/10/17: Icons, blinky.

10/9/17: Icons, line quality.

10/8/17: Icons, not building features no one is asking for.

10/7/17: Javascript, sidebars, breaking everything.

10/6/17: ♩ More containers than A.P. Møller-Maersk, nothing in English rhymes with -Maersk ♫

10/5/17: No I wil NOT optimize this experience for mobile, college auditorium projector and eigenharp. If you are viewing this in anything other than 1024x768 click HERE (and find yourself one of them fancy websites).

10/4/17: I was going to make a classy website but I have RETHOUGHT MY STRATEGY

10/3/17: Thank you overflow: hidden, you are the PROPERTY OF THE WEEK

10/2/17: Quick Synfig detour for .gif'ing. If this grilled cheese rotates at less than 60fps the whole site gets rehosted on Tripod.

10/1/17: Quick animation detour before we head back to reality.


9/30/27: Purchased hosting. Purchased hosting again after going through the limitations of Weebly's content editor. Pouring out a <cold> one for signup fees >:|

9/29/17: All previews now done in-browser. Free as in bird = Finer sidebar?

9/28/17: "Containers" to split background content from foreground, disappearing placeholder text. Yes Satan I can make the text rotate but how do I get the baby to DANCE?

9/27/17: Divs, z-./, image filters, did I crash Atom? Old men tell a tale...

9/26/17: First hover animation. Crashed Atom. HTML Preview ≠ my friend :|

9/25/17: First animated element. Crashed Atom. HTML Preview ≠ Ferrari 308.

9/24/17: Changelog created. Crashed Atom. Free as in beer = Fear bee risen.

9/23/17: Registered domain. Installed Atom. The wise man looked through the eye of the Froot Loop, and gave us syntax highlighting.