JJJ's Blog

  • WordPress
  • GitHub
  • Twitter/X
  • WordCamp Chicago 2016

    This weekend I’ll be driving down to WordCamp Chicago in my BRZ. It’s about 2 hours total from home to hotel, and I could use a playlist for the drive there and back.

    I’ll be in Chicago chatting about the differences between BuddyPress and bbPress, and I’ll probably talk a bit about Prince, too. I’m on stage at 3pm, and I’d love it if you stopped by to say hi. πŸ’œ

    JJJ

    April 29, 2016
    WordCamp
  • global__r – errors in logs

    If you’re using WordPress Multisite in a highly scalable environment using HyperDB or LudicrousDB, you may have seen global__r errors in your logs.

    Can't select global__r... yada yada yada

    https://twitter.com/jason_conroy/status/523701743415083008

    The “global” part of “global__r” comes from these database drop-ins defaulting to a “global” dataset if nothing is found or explicitly passed in. The “__r” part comes from looking at databases intended for reading — databases designated as slaves (vs. master databases intended for writing “__w”).

    So if a SELECT query is failing, why would that be?

    The first and most logical reason is that the database is down. Check to make sure it’s not by attempting to communicate with the database directly via whatever you are most comfortable with (command line, SequalPRO, etc…)

    The second most logical reason is that your web server (powering the PHP part of your application) is unable to reach your database server. Check to make sure fail2ban or some other firewall utility hasn’t erroneously blocked things, and then try to manually ping & connect the two servers together to ensure you receive a good response.

    2020 update: when updating from MariaDB 10.3 to 10.5, my bind-addressΒ configuration was reset to 127.0.0.1Β causing remote connections to be denied, landing me back at my own blog post looking for answers.

    The final and less obvious reason this will occur, is harder to track down, and I think might be the source of your error log entries if everything else checks out and you’ve made it to this blog post after scouring the web for answers.

    There are two queries that run inside of upgrade_network() and populate_options() respectfully, that try to delete all of the transients for a specific site and a specific network. These two queries are unlikely to get caught by the matching regex used to map database table names to what HyperDB or LudicrousDB use to route queries to their respective servers. They look something like this:

    DELETE a, b FROM $wpdb->options a, $wpdb->options b

    and

    DELETE a, b FROM $wpdb->sitemeta a, $wpdb->sitemeta b

    If you search all of WordPress, these are the only two places raw queries like this are done, and they’re only ran under specific conditions where WordPress is cleaning up after itself during a database upgrade. This means the conditions are perfect for a surprise entry in your error logs once in a blue moon when you aren’t hand-holding a huge WordPress multisite/multi-network database upgrade.

    How do we prevent these, and what’s the repercussion? The solution is probably a regex fix upstream to these plugins and/or WordPress’s WPDB base class to properly match these queries. The repercussion is transients that don’t get deleted, which isn’t usually a huge problem unless it causes the database upgrade to continuously run; if that was the case, you’d have lots of entries in your error logs.

    I have a hunch this issue is exacerbated by object caching plugins that store transients in memory and not in the database. In these types of installations, these raw queries are trying to delete data that never would have been there in the first place.

    I’ve also been staring at this code back and forth for a few weeks now, and while there are a lot of moving parts, I haven’t identified any data corruption or loss issues, and these queries are properly escaped and prepared, so it’s unlikely HyperDB or LudicrousDB would introduce anything that might be harmful to existing data.

    If you have these issues, hopefully this helps you isolate the root cause to identify whether this is a configuration issue, a caching issue, a communication issue, or an issue with the database itself. If you have more info, I’d love to hear about it in the comments below. <3

    JJJ

    March 26, 2016
    WordPress
    global__r, HyperDB, LudicrousDB
  • Mother Nature's Toolbox Must Be Heavy

    Running npm install for WordPress is a terrifying experience. It installs so many libraries and dependencies, it would take a lifetime to learn them all. If you’ve never had the pleasure, here’s what it looks like today:

    WordPress@4.5.0 /Users/johnjamesjacoby/Work/VVV/www/wordpress-develop
    β”œβ”€β”¬ autoprefixer@6.1.2
    β”‚ β”œβ”€β”€ browserslist@1.0.1
    β”‚ β”œβ”€β”€ caniuse-db@1.0.30000384
    β”‚ β”œβ”€β”€ num2fraction@1.2.2
    β”‚ β”œβ”€β”¬ postcss@5.0.14
    β”‚ β”‚ β”œβ”€β”€ js-base64@2.1.9
    β”‚ β”‚ β”œβ”€β”€ source-map@0.5.3
    β”‚ β”‚ └─┬ supports-color@3.1.2
    β”‚ β”‚   └── has-flag@1.0.0
    β”‚ └── postcss-value-parser@3.2.3
    β”œβ”€β”¬ grunt@0.4.5
    β”‚ β”œβ”€β”€ async@0.1.22
    β”‚ β”œβ”€β”€ coffee-script@1.3.3
    β”‚ β”œβ”€β”€ colors@0.6.2
    β”‚ β”œβ”€β”€ dateformat@1.0.2-1.2.3
    β”‚ β”œβ”€β”€ eventemitter2@0.4.14
    β”‚ β”œβ”€β”€ exit@0.1.2
    β”‚ β”œβ”€β”¬ findup-sync@0.1.3
    β”‚ β”‚ β”œβ”€β”¬ glob@3.2.11
    β”‚ β”‚ β”‚ └── minimatch@0.3.0
    β”‚ β”‚ └── lodash@2.4.2
    β”‚ β”œβ”€β”€ getobject@0.1.0
    β”‚ β”œβ”€β”¬ glob@3.1.21
    β”‚ β”‚ β”œβ”€β”€ graceful-fs@1.2.3
    β”‚ β”‚ └── inherits@1.0.2
    β”‚ β”œβ”€β”¬ grunt-legacy-log@0.1.3
    β”‚ β”‚ β”œβ”€β”¬ grunt-legacy-log-utils@0.1.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ lodash@2.4.2
    β”‚ β”‚ β”‚ └── underscore.string@2.3.3
    β”‚ β”‚ β”œβ”€β”€ lodash@2.4.2
    β”‚ β”‚ └── underscore.string@2.3.3
    β”‚ β”œβ”€β”€ hooker@0.2.3
    β”‚ β”œβ”€β”€ iconv-lite@0.2.11
    β”‚ β”œβ”€β”¬ js-yaml@2.0.5
    β”‚ β”‚ └─┬ argparse@0.1.16
    β”‚ β”‚   β”œβ”€β”€ underscore@1.7.0
    β”‚ β”‚   └── underscore.string@2.4.0
    β”‚ β”œβ”€β”€ lodash@0.9.2
    β”‚ β”œβ”€β”¬ minimatch@0.2.14
    β”‚ β”‚ β”œβ”€β”€ lru-cache@2.7.3
    β”‚ β”‚ └── sigmund@1.0.1
    β”‚ β”œβ”€β”¬ nopt@1.0.10
    β”‚ β”‚ └── abbrev@1.0.7
    β”‚ β”œβ”€β”€ rimraf@2.2.8
    β”‚ β”œβ”€β”€ underscore.string@2.2.1
    β”‚ └── which@1.0.9
    β”œβ”€β”¬ grunt-browserify@4.0.1
    β”‚ β”œβ”€β”€ async@0.9.2
    β”‚ β”œβ”€β”¬ browserify@11.2.0
    β”‚ β”‚ β”œβ”€β”€ assert@1.3.0
    β”‚ β”‚ β”œβ”€β”¬ browser-pack@5.0.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ combine-source-map@0.6.1
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ convert-source-map@1.1.3
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ inline-source-map@0.5.0
    β”‚ β”‚ β”‚ β”‚ β”‚ └── source-map@0.4.4
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ lodash.memoize@3.0.4
    β”‚ β”‚ β”‚ β”‚ └── source-map@0.4.4
    β”‚ β”‚ β”‚ └── umd@3.0.1
    β”‚ β”‚ β”œβ”€β”€ browser-resolve@1.11.0
    β”‚ β”‚ β”œβ”€β”¬ browserify-zlib@0.1.4
    β”‚ β”‚ β”‚ └── pako@0.2.8
    β”‚ β”‚ β”œβ”€β”¬ buffer@3.6.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ base64-js@0.0.8
    β”‚ β”‚ β”‚ β”œβ”€β”€ ieee754@1.1.6
    β”‚ β”‚ β”‚ └── isarray@1.0.0
    β”‚ β”‚ β”œβ”€β”€ builtins@0.0.7
    β”‚ β”‚ β”œβ”€β”€ commondir@0.0.1
    β”‚ β”‚ β”œβ”€β”¬ concat-stream@1.4.10
    β”‚ β”‚ β”‚ β”œβ”€β”€ readable-stream@1.1.13
    β”‚ β”‚ β”‚ └── typedarray@0.0.6
    β”‚ β”‚ β”œβ”€β”¬ console-browserify@1.1.0
    β”‚ β”‚ β”‚ └── date-now@0.1.4
    β”‚ β”‚ β”œβ”€β”€ constants-browserify@0.0.1
    β”‚ β”‚ β”œβ”€β”¬ crypto-browserify@3.11.0
    β”‚ β”‚ β”‚ β”œβ”€β”¬ browserify-cipher@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ browserify-aes@1.0.5
    β”‚ β”‚ β”‚ β”‚ β”‚ └── buffer-xor@1.0.3
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ browserify-des@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ des.js@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚   └── minimalistic-assert@1.0.0
    β”‚ β”‚ β”‚ β”‚ └── evp_bytestokey@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”¬ browserify-sign@4.0.0
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ bn.js@4.6.2
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ browserify-rsa@4.0.0
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ elliptic@6.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ brorand@1.0.5
    β”‚ β”‚ β”‚ β”‚ β”‚ └── hash.js@1.0.3
    β”‚ β”‚ β”‚ β”‚ └─┬ parse-asn1@5.0.0
    β”‚ β”‚ β”‚ β”‚   └── asn1.js@4.3.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ create-ecdh@4.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”¬ create-hash@1.1.2
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ cipher-base@1.0.2
    β”‚ β”‚ β”‚ β”‚ └── ripemd160@1.0.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ create-hmac@1.1.4
    β”‚ β”‚ β”‚ β”œβ”€β”¬ diffie-hellman@5.0.0
    β”‚ β”‚ β”‚ β”‚ └── miller-rabin@4.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ pbkdf2@3.0.4
    β”‚ β”‚ β”‚ β”œβ”€β”€ public-encrypt@4.0.0
    β”‚ β”‚ β”‚ └── randombytes@2.0.1
    β”‚ β”‚ β”œβ”€β”€ defined@1.0.0
    β”‚ β”‚ β”œβ”€β”€ deps-sort@1.3.9
    β”‚ β”‚ β”œβ”€β”€ domain-browser@1.1.7
    β”‚ β”‚ β”œβ”€β”¬ duplexer2@0.0.2
    β”‚ β”‚ β”‚ └── readable-stream@1.1.13
    β”‚ β”‚ β”œβ”€β”€ events@1.0.2
    β”‚ β”‚ β”œβ”€β”¬ glob@4.5.3
    β”‚ β”‚ β”‚ └── minimatch@2.0.10
    β”‚ β”‚ β”œβ”€β”¬ has@1.0.1
    β”‚ β”‚ β”‚ └── function-bind@1.0.2
    β”‚ β”‚ β”œβ”€β”€ htmlescape@1.1.0
    β”‚ β”‚ β”œβ”€β”€ https-browserify@0.0.1
    β”‚ β”‚ β”œβ”€β”€ inherits@2.0.1
    β”‚ β”‚ β”œβ”€β”¬ insert-module-globals@6.6.3
    β”‚ β”‚ β”‚ β”œβ”€β”€ is-buffer@1.1.1
    β”‚ β”‚ β”‚ └─┬ lexical-scope@1.2.0
    β”‚ β”‚ β”‚   └── astw@2.0.0
    β”‚ β”‚ β”œβ”€β”€ isarray@0.0.1
    β”‚ β”‚ β”œβ”€β”¬ JSONStream@1.0.7
    β”‚ β”‚ β”‚ β”œβ”€β”€ jsonparse@1.2.0
    β”‚ β”‚ β”‚ └── through@2.3.8
    β”‚ β”‚ β”œβ”€β”¬ labeled-stream-splicer@1.0.2
    β”‚ β”‚ β”‚ └─┬ stream-splicer@1.3.2
    β”‚ β”‚ β”‚   └── readable-stream@1.1.13
    β”‚ β”‚ β”œβ”€β”¬ module-deps@3.9.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ detective@4.3.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ readable-stream@1.1.13
    β”‚ β”‚ β”‚ └─┬ stream-combiner2@1.0.2
    β”‚ β”‚ β”‚   └─┬ through2@0.5.1
    β”‚ β”‚ β”‚     β”œβ”€β”€ readable-stream@1.0.33
    β”‚ β”‚ β”‚     └── xtend@3.0.0
    β”‚ β”‚ β”œβ”€β”€ os-browserify@0.1.2
    β”‚ β”‚ β”œβ”€β”¬ parents@1.0.1
    β”‚ β”‚ β”‚ └── path-platform@0.11.15
    β”‚ β”‚ β”œβ”€β”€ path-browserify@0.0.0
    β”‚ β”‚ β”œβ”€β”€ process@0.11.2
    β”‚ β”‚ β”œβ”€β”€ punycode@1.4.0
    β”‚ β”‚ β”œβ”€β”€ querystring-es3@0.2.1
    β”‚ β”‚ β”œβ”€β”¬ read-only-stream@1.1.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ readable-stream@1.1.13
    β”‚ β”‚ β”‚ └─┬ readable-wrap@1.0.0
    β”‚ β”‚ β”‚   └── readable-stream@1.1.13
    β”‚ β”‚ β”œβ”€β”¬ readable-stream@2.0.5
    β”‚ β”‚ β”‚ β”œβ”€β”€ core-util-is@1.0.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ process-nextick-args@1.0.6
    β”‚ β”‚ β”‚ └── util-deprecate@1.0.2
    β”‚ β”‚ β”œβ”€β”¬ shasum@1.0.2
    β”‚ β”‚ β”‚ β”œβ”€β”¬ json-stable-stringify@0.0.1
    β”‚ β”‚ β”‚ β”‚ └── jsonify@0.0.0
    β”‚ β”‚ β”‚ └── sha.js@2.4.4
    β”‚ β”‚ β”œβ”€β”€ shell-quote@0.0.1
    β”‚ β”‚ β”œβ”€β”€ stream-browserify@2.0.1
    β”‚ β”‚ β”œβ”€β”¬ stream-http@1.7.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ builtin-status-codes@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ foreach@2.0.5
    β”‚ β”‚ β”‚ β”œβ”€β”€ indexof@0.0.1
    β”‚ β”‚ β”‚ └── object-keys@1.0.9
    β”‚ β”‚ β”œβ”€β”€ string_decoder@0.10.31
    β”‚ β”‚ β”œβ”€β”¬ subarg@1.0.0
    β”‚ β”‚ β”‚ └── minimist@1.2.0
    β”‚ β”‚ β”œβ”€β”¬ syntax-error@1.1.4
    β”‚ β”‚ β”‚ └── acorn@1.2.2
    β”‚ β”‚ β”œβ”€β”¬ through2@1.1.1
    β”‚ β”‚ β”‚ └── readable-stream@1.1.13
    β”‚ β”‚ β”œβ”€β”€ timers-browserify@1.4.2
    β”‚ β”‚ β”œβ”€β”€ tty-browserify@0.0.0
    β”‚ β”‚ β”œβ”€β”¬ url@0.10.3
    β”‚ β”‚ β”‚ β”œβ”€β”€ punycode@1.3.2
    β”‚ β”‚ β”‚ └── querystring@0.2.0
    β”‚ β”‚ β”œβ”€β”€ util@0.10.3
    β”‚ β”‚ β”œβ”€β”€ vm-browserify@0.0.4
    β”‚ β”‚ └── xtend@4.0.1
    β”‚ β”œβ”€β”¬ glob@5.0.15
    β”‚ β”‚ β”œβ”€β”¬ inflight@1.0.4
    β”‚ β”‚ β”‚ └── wrappy@1.0.1
    β”‚ β”‚ β”œβ”€β”¬ minimatch@3.0.0
    β”‚ β”‚ β”‚ └─┬ brace-expansion@1.1.2
    β”‚ β”‚ β”‚   β”œβ”€β”€ balanced-match@0.3.0
    β”‚ β”‚ β”‚   └── concat-map@0.0.1
    β”‚ β”‚ β”œβ”€β”€ once@1.3.3
    β”‚ β”‚ └── path-is-absolute@1.0.0
    β”‚ β”œβ”€β”€ lodash@3.10.1
    β”‚ β”œβ”€β”€ resolve@1.1.6
    β”‚ └─┬ watchify@3.6.1
    β”‚   β”œβ”€β”¬ anymatch@1.3.0
    β”‚   β”‚ β”œβ”€β”€ arrify@1.0.1
    β”‚   β”‚ └─┬ micromatch@2.3.7
    β”‚   β”‚   β”œβ”€β”¬ arr-diff@2.0.0
    β”‚   β”‚   β”‚ └── arr-flatten@1.0.1
    β”‚   β”‚   β”œβ”€β”€ array-unique@0.2.1
    β”‚   β”‚   β”œβ”€β”¬ braces@1.8.3
    β”‚   β”‚   β”‚ β”œβ”€β”¬ expand-range@1.8.1
    β”‚   β”‚   β”‚ β”‚ └─┬ fill-range@2.2.3
    β”‚   β”‚   β”‚ β”‚   β”œβ”€β”€ is-number@2.1.0
    β”‚   β”‚   β”‚ β”‚   β”œβ”€β”€ isobject@2.0.0
    β”‚   β”‚   β”‚ β”‚   β”œβ”€β”€ randomatic@1.1.5
    β”‚   β”‚   β”‚ β”‚   └── repeat-string@1.5.2
    β”‚   β”‚   β”‚ β”œβ”€β”€ preserve@0.2.0
    β”‚   β”‚   β”‚ └── repeat-element@1.1.2
    β”‚   β”‚   β”œβ”€β”€ expand-brackets@0.1.4
    β”‚   β”‚   β”œβ”€β”¬ extglob@0.3.1
    β”‚   β”‚   β”‚ β”œβ”€β”¬ ansi-green@0.1.1
    β”‚   β”‚   β”‚ β”‚ └── ansi-wrap@0.1.0
    β”‚   β”‚   β”‚ └── success-symbol@0.1.0
    β”‚   β”‚   β”œβ”€β”€ filename-regex@2.0.0
    β”‚   β”‚   β”œβ”€β”€ is-extglob@1.0.0
    β”‚   β”‚   β”œβ”€β”€ kind-of@3.0.2
    β”‚   β”‚   β”œβ”€β”€ normalize-path@2.0.1
    β”‚   β”‚   β”œβ”€β”¬ object.omit@2.0.0
    β”‚   β”‚   β”‚ β”œβ”€β”¬ for-own@0.1.3
    β”‚   β”‚   β”‚ β”‚ └── for-in@0.1.4
    β”‚   β”‚   β”‚ └── is-extendable@0.1.1
    β”‚   β”‚   β”œβ”€β”¬ parse-glob@3.0.4
    β”‚   β”‚   β”‚ β”œβ”€β”€ glob-base@0.3.0
    β”‚   β”‚   β”‚ └── is-dotfile@1.0.2
    β”‚   β”‚   └─┬ regex-cache@0.4.2
    β”‚   β”‚     β”œβ”€β”€ is-equal-shallow@0.1.3
    β”‚   β”‚     └── is-primitive@2.0.0
    β”‚   β”œβ”€β”¬ browserify@12.0.1
    β”‚   β”‚ β”œβ”€β”¬ browser-pack@6.0.1
    β”‚   β”‚ β”‚ └─┬ combine-source-map@0.7.1
    β”‚   β”‚ β”‚   β”œβ”€β”€ inline-source-map@0.6.1
    β”‚   β”‚ β”‚   └── source-map@0.4.2
    β”‚   β”‚ β”œβ”€β”€ concat-stream@1.5.1
    β”‚   β”‚ β”œβ”€β”€ constants-browserify@1.0.0
    β”‚   β”‚ β”œβ”€β”€ deps-sort@2.0.0
    β”‚   β”‚ β”œβ”€β”€ duplexer2@0.1.4
    β”‚   β”‚ β”œβ”€β”€ events@1.1.0
    β”‚   β”‚ β”œβ”€β”¬ glob@5.0.15
    β”‚   β”‚ β”‚ └── minimatch@3.0.0
    β”‚   β”‚ β”œβ”€β”€ insert-module-globals@7.0.1
    β”‚   β”‚ β”œβ”€β”¬ labeled-stream-splicer@2.0.0
    β”‚   β”‚ β”‚ └── stream-splicer@2.0.0
    β”‚   β”‚ β”œβ”€β”¬ module-deps@4.0.5
    β”‚   β”‚ β”‚ └── stream-combiner2@1.1.1
    β”‚   β”‚ β”œβ”€β”€ read-only-stream@2.0.0
    β”‚   β”‚ β”œβ”€β”€ shell-quote@1.4.3
    β”‚   β”‚ β”œβ”€β”€ stream-http@2.0.2
    β”‚   β”‚ └─┬ url@0.11.0
    β”‚   β”‚   └── punycode@1.3.2
    β”‚   β”œβ”€β”¬ chokidar@1.4.2
    β”‚   β”‚ β”œβ”€β”€ async-each@0.1.6
    β”‚   β”‚ β”œβ”€β”¬ fsevents@1.0.6
    β”‚   β”‚ β”‚ └─┬ node-pre-gyp@0.6.17
    β”‚   β”‚ β”‚   β”œβ”€β”¬ mkdirp@0.5.1
    β”‚   β”‚ β”‚   β”‚ └── minimist@0.0.8
    β”‚   β”‚ β”‚   β”œβ”€β”¬ nopt@3.0.6
    β”‚   β”‚ β”‚   β”‚ └── abbrev@1.0.7
    β”‚   β”‚ β”‚   β”œβ”€β”¬ npmlog@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ ansi@0.3.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ are-we-there-yet@1.0.4
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ delegates@0.1.0
    β”‚   β”‚ β”‚   β”‚ β”‚ └─┬ readable-stream@1.1.13
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ core-util-is@1.0.2
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ isarray@0.0.1
    β”‚   β”‚ β”‚   β”‚ β”‚   └── string_decoder@0.10.31
    β”‚   β”‚ β”‚   β”‚ └─┬ gauge@1.2.2
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”€ has-unicode@1.0.1
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”¬ lodash.pad@3.1.1
    β”‚   β”‚ β”‚   β”‚   β”‚ β”œβ”€β”€ lodash._basetostring@3.0.1
    β”‚   β”‚ β”‚   β”‚   β”‚ └─┬ lodash._createpadding@3.6.1
    β”‚   β”‚ β”‚   β”‚   β”‚   └── lodash.repeat@3.0.1
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”€ lodash.padleft@3.1.1
    β”‚   β”‚ β”‚   β”‚   └── lodash.padright@3.1.1
    β”‚   β”‚ β”‚   β”œβ”€β”¬ rc@1.1.5
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ ini@1.3.4
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ minimist@1.2.0
    β”‚   β”‚ β”‚   β”‚ └── strip-json-comments@1.0.4
    β”‚   β”‚ β”‚   β”œβ”€β”¬ request@2.67.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ aws-sign2@0.6.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ bl@1.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ └─┬ readable-stream@2.0.4
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ core-util-is@1.0.2
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ inherits@2.0.1
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ isarray@0.0.1
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ string_decoder@0.10.31
    β”‚   β”‚ β”‚   β”‚ β”‚   └── util-deprecate@1.0.2
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ caseless@0.11.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ combined-stream@1.0.5
    β”‚   β”‚ β”‚   β”‚ β”‚ └── delayed-stream@1.0.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ extend@3.0.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ forever-agent@0.6.1
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ form-data@1.0.0-rc3
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ har-validator@2.0.3
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”¬ chalk@1.1.1
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”€ ansi-styles@2.1.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”¬ has-ansi@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”‚ └── ansi-regex@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”€ strip-ansi@3.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ └── supports-color@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”¬ commander@2.9.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ └── graceful-readlink@1.0.1
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”¬ is-my-json-valid@2.12.3
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”€ generate-function@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”¬ generate-object-property@1.2.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”‚ └── is-property@1.0.2
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”€ jsonpointer@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ └── xtend@4.0.1
    β”‚   β”‚ β”‚   β”‚ β”‚ └─┬ pinkie-promise@2.0.0
    β”‚   β”‚ β”‚   β”‚ β”‚   └── pinkie@2.0.1
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ hawk@3.1.2
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ boom@2.10.1
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ cryptiles@2.0.5
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ hoek@2.16.3
    β”‚   β”‚ β”‚   β”‚ β”‚ └── sntp@1.0.9
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ http-signature@1.1.0
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ assert-plus@0.1.5
    β”‚   β”‚ β”‚   β”‚ β”‚ β”œβ”€β”¬ jsprim@1.2.2
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”€ extsprintf@1.0.2
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ β”œβ”€β”€ json-schema@0.2.2
    β”‚   β”‚ β”‚   β”‚ β”‚ β”‚ └── verror@1.3.6
    β”‚   β”‚ β”‚   β”‚ β”‚ └─┬ sshpk@1.7.0
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ asn1@0.2.3
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ assert-plus@0.2.0
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ ecc-jsbn@0.1.1
    β”‚   β”‚ β”‚   β”‚ β”‚   β”œβ”€β”€ jodid25519@1.0.2
    β”‚   β”‚ β”‚   β”‚ β”‚   └── jsbn@0.1.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ is-typedarray@1.0.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ isstream@0.1.2
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ json-stringify-safe@5.0.1
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ node-uuid@1.4.7
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ oauth-sign@0.8.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ qs@5.2.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ stringstream@0.0.5
    β”‚   β”‚ β”‚   β”‚ └── tough-cookie@2.2.1
    β”‚   β”‚ β”‚   β”œβ”€β”¬ rimraf@2.4.4
    β”‚   β”‚ β”‚   β”‚ └─┬ glob@5.0.15
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”¬ inflight@1.0.4
    β”‚   β”‚ β”‚   β”‚   β”‚ └── wrappy@1.0.1
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”€ inherits@2.0.1
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”¬ minimatch@3.0.0
    β”‚   β”‚ β”‚   β”‚   β”‚ └─┬ brace-expansion@1.1.1
    β”‚   β”‚ β”‚   β”‚   β”‚   └── concat-map@0.0.1
    β”‚   β”‚ β”‚   β”‚   β”œβ”€β”¬ once@1.3.3
    β”‚   β”‚ β”‚   β”‚   β”‚ └── wrappy@1.0.1
    β”‚   β”‚ β”‚   β”‚   └── path-is-absolute@1.0.0
    β”‚   β”‚ β”‚   β”œβ”€β”€ semver@5.1.0
    β”‚   β”‚ β”‚   β”œβ”€β”¬ tar@2.2.1
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ block-stream@0.0.8
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ fstream@1.0.8
    β”‚   β”‚ β”‚   β”‚ └── inherits@2.0.1
    β”‚   β”‚ β”‚   └─┬ tar-pack@3.1.0
    β”‚   β”‚ β”‚     β”œβ”€β”€ debug@0.7.4
    β”‚   β”‚ β”‚     β”œβ”€β”¬ fstream-ignore@1.0.3
    β”‚   β”‚ β”‚     β”‚ └─┬ minimatch@3.0.0
    β”‚   β”‚ β”‚     β”‚   └─┬ brace-expansion@1.1.1
    β”‚   β”‚ β”‚     β”‚     └── concat-map@0.0.1
    β”‚   β”‚ β”‚     β”œβ”€β”€ graceful-fs@4.1.2
    β”‚   β”‚ β”‚     β”œβ”€β”¬ readable-stream@1.0.33
    β”‚   β”‚ β”‚     β”‚ β”œβ”€β”€ core-util-is@1.0.2
    β”‚   β”‚ β”‚     β”‚ β”œβ”€β”€ inherits@2.0.1
    β”‚   β”‚ β”‚     β”‚ β”œβ”€β”€ isarray@0.0.1
    β”‚   β”‚ β”‚     β”‚ └── string_decoder@0.10.31
    β”‚   β”‚ β”‚     └── rimraf@2.2.8
    β”‚   β”‚ β”œβ”€β”€ glob-parent@2.0.0
    β”‚   β”‚ β”œβ”€β”¬ is-binary-path@1.0.1
    β”‚   β”‚ β”‚ └── binary-extensions@1.4.0
    β”‚   β”‚ β”œβ”€β”€ is-glob@2.0.1
    β”‚   β”‚ └─┬ readdirp@2.0.0
    β”‚   β”‚   β”œβ”€β”€ graceful-fs@4.1.2
    β”‚   β”‚   └── minimatch@2.0.10
    β”‚   β”œβ”€β”¬ outpipe@1.1.1
    β”‚   β”‚ └─┬ shell-quote@1.4.3
    β”‚   β”‚   β”œβ”€β”€ array-filter@0.0.1
    β”‚   β”‚   β”œβ”€β”€ array-map@0.0.0
    β”‚   β”‚   └── array-reduce@0.0.0
    β”‚   └── through2@2.0.0
    β”œβ”€β”€ grunt-contrib-clean@0.6.0
    β”œβ”€β”¬ grunt-contrib-compress@0.14.0
    β”‚ β”œβ”€β”¬ archiver@0.16.0
    β”‚ β”‚ β”œβ”€β”€ async@1.4.2
    β”‚ β”‚ β”œβ”€β”€ buffer-crc32@0.2.5
    β”‚ β”‚ β”œβ”€β”¬ glob@5.0.15
    β”‚ β”‚ β”‚ └── minimatch@3.0.0
    β”‚ β”‚ β”œβ”€β”¬ lazystream@0.1.0
    β”‚ β”‚ β”‚ └── readable-stream@1.0.33
    β”‚ β”‚ β”œβ”€β”€ lodash@3.10.1
    β”‚ β”‚ β”œβ”€β”€ readable-stream@1.0.33
    β”‚ β”‚ β”œβ”€β”¬ tar-stream@1.2.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ bl@1.0.0
    β”‚ β”‚ β”‚ └── end-of-stream@1.1.0
    β”‚ β”‚ └─┬ zip-stream@0.6.0
    β”‚ β”‚   β”œβ”€β”¬ compress-commons@0.3.0
    β”‚ β”‚   β”‚ β”œβ”€β”¬ crc32-stream@0.3.4
    β”‚ β”‚   β”‚ β”‚ └── readable-stream@1.0.33
    β”‚ β”‚   β”‚ β”œβ”€β”€ node-int64@0.4.0
    β”‚ β”‚   β”‚ └── readable-stream@1.0.33
    β”‚ β”‚   β”œβ”€β”€ lodash@3.10.1
    β”‚ β”‚   └── readable-stream@1.0.33
    β”‚ β”œβ”€β”¬ chalk@1.1.1
    β”‚ β”‚ β”œβ”€β”€ ansi-styles@2.1.0
    β”‚ β”‚ β”œβ”€β”€ escape-string-regexp@1.0.4
    β”‚ β”‚ β”œβ”€β”¬ has-ansi@2.0.0
    β”‚ β”‚ β”‚ └── ansi-regex@2.0.0
    β”‚ β”‚ β”œβ”€β”€ strip-ansi@3.0.0
    β”‚ β”‚ └── supports-color@2.0.0
    β”‚ └─┬ pretty-bytes@2.0.1
    β”‚   β”œβ”€β”€ get-stdin@4.0.1
    β”‚   β”œβ”€β”¬ meow@3.7.0
    β”‚   β”‚ β”œβ”€β”¬ camelcase-keys@2.0.0
    β”‚   β”‚ β”‚ └── camelcase@2.0.1
    β”‚   β”‚ β”œβ”€β”€ decamelize@1.1.2
    β”‚   β”‚ β”œβ”€β”¬ loud-rejection@1.2.0
    β”‚   β”‚ β”‚ └── signal-exit@2.1.2
    β”‚   β”‚ β”œβ”€β”€ map-obj@1.0.1
    β”‚   β”‚ β”œβ”€β”¬ normalize-package-data@2.3.5
    β”‚   β”‚ β”‚ β”œβ”€β”€ hosted-git-info@2.1.4
    β”‚   β”‚ β”‚ β”œβ”€β”¬ is-builtin-module@1.0.0
    β”‚   β”‚ β”‚ β”‚ └── builtin-modules@1.1.1
    β”‚   β”‚ β”‚ └─┬ validate-npm-package-license@3.0.1
    β”‚   β”‚ β”‚   β”œβ”€β”¬ spdx-correct@1.0.2
    β”‚   β”‚ β”‚   β”‚ └── spdx-license-ids@1.1.0
    β”‚   β”‚ β”‚   └─┬ spdx-expression-parse@1.0.2
    β”‚   β”‚ β”‚     └── spdx-exceptions@1.0.4
    β”‚   β”‚ β”œβ”€β”¬ read-pkg-up@1.0.1
    β”‚   β”‚ β”‚ β”œβ”€β”¬ find-up@1.1.0
    β”‚   β”‚ β”‚ β”‚ └── path-exists@2.1.0
    β”‚   β”‚ β”‚ └─┬ read-pkg@1.1.0
    β”‚   β”‚ β”‚   β”œβ”€β”¬ load-json-file@1.1.0
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”€ graceful-fs@4.1.2
    β”‚   β”‚ β”‚   β”‚ β”œβ”€β”¬ parse-json@2.2.0
    β”‚   β”‚ β”‚   β”‚ β”‚ └─┬ error-ex@1.3.0
    β”‚   β”‚ β”‚   β”‚ β”‚   └── is-arrayish@0.2.1
    β”‚   β”‚ β”‚   β”‚ └── pify@2.3.0
    β”‚   β”‚ β”‚   └─┬ path-type@1.1.0
    β”‚   β”‚ β”‚     └── graceful-fs@4.1.2
    β”‚   β”‚ β”œβ”€β”¬ redent@1.0.0
    β”‚   β”‚ β”‚ β”œβ”€β”¬ indent-string@2.1.0
    β”‚   β”‚ β”‚ β”‚ └─┬ repeating@2.0.0
    β”‚   β”‚ β”‚ β”‚   └── is-finite@1.0.1
    β”‚   β”‚ β”‚ └── strip-indent@1.0.1
    β”‚   β”‚ └── trim-newlines@1.0.0
    β”‚   └── number-is-nan@1.0.0
    β”œβ”€β”¬ grunt-contrib-concat@0.5.1
    β”‚ β”œβ”€β”¬ chalk@0.5.1
    β”‚ β”‚ β”œβ”€β”€ ansi-styles@1.1.0
    β”‚ β”‚ β”œβ”€β”¬ has-ansi@0.1.0
    β”‚ β”‚ β”‚ └── ansi-regex@0.2.1
    β”‚ β”‚ β”œβ”€β”€ strip-ansi@0.3.0
    β”‚ β”‚ └── supports-color@0.2.0
    β”‚ └─┬ source-map@0.3.0
    β”‚   └── amdefine@1.0.0
    β”œβ”€β”¬ grunt-contrib-copy@0.8.2
    β”‚ └── file-sync-cmp@0.1.1
    β”œβ”€β”¬ grunt-contrib-cssmin@0.14.0
    β”‚ β”œβ”€β”¬ clean-css@3.4.9
    β”‚ β”‚ β”œβ”€β”¬ commander@2.8.1
    β”‚ β”‚ β”‚ └── graceful-readlink@1.0.1
    β”‚ β”‚ └── source-map@0.4.4
    β”‚ └─┬ maxmin@1.1.0
    β”‚   β”œβ”€β”€ figures@1.4.0
    β”‚   β”œβ”€β”€ gzip-size@1.0.0
    β”‚   └── pretty-bytes@1.0.4
    β”œβ”€β”¬ grunt-contrib-imagemin@1.0.0
    β”‚ β”œβ”€β”€ async@0.9.2
    β”‚ β”œβ”€β”€ gulp-rename@1.2.2
    β”‚ β”œβ”€β”¬ imagemin@4.0.0
    β”‚ β”‚ β”œβ”€β”¬ buffer-to-vinyl@1.1.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ file-type@3.4.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ uuid@2.0.1
    β”‚ β”‚ β”‚ └─┬ vinyl@1.1.0
    β”‚ β”‚ β”‚   β”œβ”€β”€ clone@1.0.2
    β”‚ β”‚ β”‚   β”œβ”€β”€ clone-stats@0.0.1
    β”‚ β”‚ β”‚   └── replace-ext@0.0.1
    β”‚ β”‚ β”œβ”€β”¬ imagemin-gifsicle@4.2.0
    β”‚ β”‚ β”‚ β”œβ”€β”¬ gifsicle@3.0.3
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ bin-build@2.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ archive-type@3.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ decompress@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ decompress-tar@3.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-tar@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ object-assign@2.1.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ strip-dirs@1.1.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-natural-number@2.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── sum-up@1.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ through2@0.6.5
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── readable-stream@1.0.33
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ vinyl@0.4.6
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── clone@0.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ decompress-tarbz2@3.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-bzip2@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ object-assign@2.1.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ seek-bzip@1.0.5
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ through2@0.6.5
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── readable-stream@1.0.33
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ vinyl@0.4.6
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── clone@0.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ decompress-targz@3.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-gzip@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ object-assign@2.1.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ through2@0.6.5
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── readable-stream@1.0.33
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ vinyl@0.4.6
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── clone@0.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ decompress-unzip@3.4.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-zip@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ stat-mode@0.2.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ through2@2.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ yauzl@2.4.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └─┬ fd-slicer@1.0.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚     └── pend@1.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ stream-combiner2@1.1.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── duplexer2@0.1.4
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── vinyl-assign@1.2.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ download@4.4.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ caw@1.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ get-proxy@1.0.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ rc@0.5.5
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ deep-extend@0.2.11
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ minimist@0.0.10
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── strip-json-comments@0.1.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-obj@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── object-assign@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ filenamify@1.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ filename-reserved-regex@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ strip-outer@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── trim-repeated@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ got@5.3.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ create-error-class@2.0.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── capture-stack-trace@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-plain-obj@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-redirect@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ lowercase-keys@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ node-status-codes@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ timed-out@2.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ unzip-response@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ url-parse-lax@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── prepend-http@1.0.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ gulp-decompress@1.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ gulp-util@3.0.7
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ array-differ@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ array-uniq@1.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ beeper@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ dateformat@1.0.12
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”¬ fancy-log@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ └── dateformat@1.0.12
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”¬ gulplog@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ └── glogg@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”¬ has-gulplog@0.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ └── sparkles@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ lodash._reescape@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ lodash._reevaluate@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ lodash._reinterpolate@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”¬ lodash.template@3.6.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”€ lodash._basecopy@3.0.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”€ lodash._basevalues@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”€ lodash._isiterateecall@3.0.9
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”€ lodash.escape@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”¬ lodash.keys@3.1.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ lodash._getnative@3.9.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”‚ β”œβ”€β”€ lodash.isarguments@3.0.4
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”‚ └── lodash.isarray@3.0.4
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”€ lodash.restparam@3.6.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”‚ └── lodash.templatesettings@3.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ multipipe@0.1.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ object-assign@3.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ through2@2.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── vinyl@0.5.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ is-url@1.2.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ read-all-stream@3.0.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ pinkie-promise@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── pinkie@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ stream-combiner2@1.1.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── duplexer2@0.1.4
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ ware@1.3.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └─┬ wrap-fn@0.1.4
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚     └── co@3.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ exec-series@1.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── async-each-series@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ url-regex@3.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚   └── ip-regex@1.0.3
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ bin-wrapper@3.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ bin-check@2.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── executable@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ bin-version-check@2.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ bin-version@1.0.4
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └─┬ find-versions@1.2.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚   └── semver-regex@1.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ semver@4.3.6
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── semver-truncate@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ lazy-req@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”‚ └── os-filter-obj@1.0.3
    β”‚ β”‚ β”‚ β”‚ └─┬ logalot@2.1.0
    β”‚ β”‚ β”‚ β”‚   └─┬ squeak@1.3.0
    β”‚ β”‚ β”‚ β”‚     β”œβ”€β”€ console-stream@0.1.1
    β”‚ β”‚ β”‚ β”‚     └─┬ lpad-align@1.1.0
    β”‚ β”‚ β”‚ β”‚       β”œβ”€β”€ longest@1.0.1
    β”‚ β”‚ β”‚ β”‚       └── lpad@2.0.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ is-gif@1.0.0
    β”‚ β”‚ β”‚ └─┬ through2@0.6.5
    β”‚ β”‚ β”‚   └── readable-stream@1.0.33
    β”‚ β”‚ β”œβ”€β”¬ imagemin-jpegtran@4.3.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ is-jpg@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ jpegtran-bin@3.0.6
    β”‚ β”‚ β”‚ └── through2@2.0.0
    β”‚ β”‚ β”œβ”€β”¬ imagemin-optipng@4.3.0
    β”‚ β”‚ β”‚ β”œβ”€β”¬ exec-buffer@2.0.1
    β”‚ β”‚ β”‚ β”‚ └── tempfile@1.1.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ is-png@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ optipng-bin@3.0.4
    β”‚ β”‚ β”‚ └─┬ through2@0.6.5
    β”‚ β”‚ β”‚   └── readable-stream@1.0.33
    β”‚ β”‚ β”œβ”€β”¬ imagemin-svgo@4.2.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ is-svg@1.1.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ svgo@0.6.1
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ coa@1.0.1
    β”‚ β”‚ β”‚ β”‚ β”‚ └── q@1.4.1
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ colors@1.1.2
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ csso@1.4.4
    β”‚ β”‚ β”‚ β”‚ β”‚ └── clap@1.0.10
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ js-yaml@3.4.6
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ argparse@1.0.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ lodash@3.10.1
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── sprintf-js@1.0.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ esprima@2.7.1
    β”‚ β”‚ β”‚ β”‚ β”‚ └── inherit@2.2.2
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sax@1.1.4
    β”‚ β”‚ β”‚ β”‚ └── whet.extend@0.9.9
    β”‚ β”‚ β”‚ └── through2@2.0.0
    β”‚ β”‚ β”œβ”€β”€ optional@0.1.3
    β”‚ β”‚ β”œβ”€β”¬ stream-combiner2@1.1.1
    β”‚ β”‚ β”‚ └── duplexer2@0.1.4
    β”‚ β”‚ └─┬ vinyl-fs@2.2.1
    β”‚ β”‚   β”œβ”€β”¬ duplexify@3.4.2
    β”‚ β”‚   β”‚ └── end-of-stream@1.0.0
    β”‚ β”‚   β”œβ”€β”¬ glob-stream@5.3.1
    β”‚ β”‚   β”‚ β”œβ”€β”¬ glob@5.0.15
    β”‚ β”‚   β”‚ β”‚ └── minimatch@3.0.0
    β”‚ β”‚   β”‚ β”œβ”€β”¬ ordered-read-streams@0.3.0
    β”‚ β”‚   β”‚ β”‚ └── is-stream@1.0.1
    β”‚ β”‚   β”‚ β”œβ”€β”¬ through2@0.6.5
    β”‚ β”‚   β”‚ β”‚ └── readable-stream@1.0.33
    β”‚ β”‚   β”‚ β”œβ”€β”¬ to-absolute-glob@0.1.1
    β”‚ β”‚   β”‚ β”‚ └── extend-shallow@2.0.1
    β”‚ β”‚   β”‚ └── unique-stream@2.2.0
    β”‚ β”‚   β”œβ”€β”€ graceful-fs@4.1.2
    β”‚ β”‚   β”œβ”€β”¬ gulp-sourcemaps@1.6.0
    β”‚ β”‚   β”‚ β”œβ”€β”€ graceful-fs@4.1.2
    β”‚ β”‚   β”‚ └── through2@2.0.0
    β”‚ β”‚   β”œβ”€β”€ is-valid-glob@0.3.0
    β”‚ β”‚   β”œβ”€β”€ merge-stream@1.0.0
    β”‚ β”‚   β”œβ”€β”¬ strip-bom@2.0.0
    β”‚ β”‚   β”‚ └── is-utf8@0.2.1
    β”‚ β”‚   β”œβ”€β”¬ strip-bom-stream@1.0.0
    β”‚ β”‚   β”‚ └── first-chunk-stream@1.0.0
    β”‚ β”‚   β”œβ”€β”€ through2@2.0.0
    β”‚ β”‚   └─┬ through2-filter@2.0.0
    β”‚ β”‚     └── through2@2.0.0
    β”‚ └── pretty-bytes@1.0.4
    β”œβ”€β”¬ grunt-contrib-jshint@0.11.3
    β”‚ └─┬ jshint@2.8.0
    β”‚   β”œβ”€β”¬ cli@0.6.6
    β”‚   β”‚ └─┬ glob@3.2.11
    β”‚   β”‚   └── minimatch@0.3.0
    β”‚   β”œβ”€β”¬ htmlparser2@3.8.3
    β”‚   β”‚ β”œβ”€β”€ domelementtype@1.3.0
    β”‚   β”‚ β”œβ”€β”€ domhandler@2.3.0
    β”‚   β”‚ β”œβ”€β”¬ domutils@1.5.1
    β”‚   β”‚ β”‚ └─┬ dom-serializer@0.1.0
    β”‚   β”‚ β”‚   β”œβ”€β”€ domelementtype@1.1.3
    β”‚   β”‚ β”‚   └── entities@1.1.1
    β”‚   β”‚ β”œβ”€β”€ entities@1.0.0
    β”‚   β”‚ └── readable-stream@1.1.13
    β”‚   β”œβ”€β”€ lodash@3.7.0
    β”‚   β”œβ”€β”€ minimatch@2.0.10
    β”‚   β”œβ”€β”€ shelljs@0.3.0
    β”‚   └── strip-json-comments@1.0.4
    β”œβ”€β”¬ grunt-contrib-qunit@0.7.0
    β”‚ └─┬ grunt-lib-phantomjs@0.6.0
    β”‚   β”œβ”€β”¬ phantomjs@1.9.19
    β”‚   β”‚ β”œβ”€β”€ adm-zip@0.4.4
    β”‚   β”‚ β”œβ”€β”¬ fs-extra@0.23.1
    β”‚   β”‚ β”‚ β”œβ”€β”€ graceful-fs@4.1.2
    β”‚   β”‚ β”‚ └── jsonfile@2.2.3
    β”‚   β”‚ β”œβ”€β”€ kew@0.4.0
    β”‚   β”‚ β”œβ”€β”¬ md5@2.0.0
    β”‚   β”‚ β”‚ β”œβ”€β”€ charenc@0.0.1
    β”‚   β”‚ β”‚ β”œβ”€β”€ crypt@0.0.1
    β”‚   β”‚ β”‚ └── is-buffer@1.0.2
    β”‚   β”‚ β”œβ”€β”¬ npmconf@2.1.1
    β”‚   β”‚ β”‚ β”œβ”€β”€ nopt@3.0.6
    β”‚   β”‚ β”‚ └── semver@4.3.6
    β”‚   β”‚ β”œβ”€β”€ progress@1.1.8
    β”‚   β”‚ β”œβ”€β”¬ request@2.42.0
    β”‚   β”‚ β”‚ β”œβ”€β”€ aws-sign2@0.5.0
    β”‚   β”‚ β”‚ β”œβ”€β”¬ bl@0.9.4
    β”‚   β”‚ β”‚ β”‚ └── readable-stream@1.0.33
    β”‚   β”‚ β”‚ β”œβ”€β”€ caseless@0.6.0
    β”‚   β”‚ β”‚ β”œβ”€β”€ hawk@1.1.1
    β”‚   β”‚ β”‚ β”œβ”€β”€ mime-types@1.0.2
    β”‚   β”‚ β”‚ β”œβ”€β”€ oauth-sign@0.4.0
    β”‚   β”‚ β”‚ └── qs@1.2.2
    β”‚   β”‚ └─┬ request-progress@0.3.1
    β”‚   β”‚   └── throttleit@0.0.2
    β”‚   β”œβ”€β”€ semver@1.0.14
    β”‚   └─┬ temporary@0.0.8
    β”‚     └── package@1.0.1
    β”œβ”€β”¬ grunt-contrib-uglify@0.10.1
    β”‚ β”œβ”€β”¬ chalk@1.0.0
    β”‚ β”‚ β”œβ”€β”¬ has-ansi@1.0.3
    β”‚ β”‚ β”‚ └── ansi-regex@1.1.1
    β”‚ β”‚ β”œβ”€β”€ strip-ansi@2.0.1
    β”‚ β”‚ └── supports-color@1.3.1
    β”‚ β”œβ”€β”€ lodash@3.2.0
    β”‚ β”œβ”€β”¬ maxmin@1.0.1
    β”‚ β”‚ └── pretty-bytes@1.0.4
    β”‚ β”œβ”€β”¬ uglify-js@2.5.0
    β”‚ β”‚ β”œβ”€β”€ async@0.2.10
    β”‚ β”‚ β”œβ”€β”€ uglify-to-browserify@1.0.2
    β”‚ β”‚ └─┬ yargs@3.5.4
    β”‚ β”‚   β”œβ”€β”€ camelcase@1.2.1
    β”‚ β”‚   β”œβ”€β”€ window-size@0.1.0
    β”‚ β”‚   └── wordwrap@0.0.2
    β”‚ └── uri-path@1.0.0
    β”œβ”€β”¬ grunt-contrib-watch@0.6.1
    β”‚ β”œβ”€β”€ async@0.2.10
    β”‚ β”œβ”€β”¬ gaze@0.5.2
    β”‚ β”‚ └─┬ globule@0.1.0
    β”‚ β”‚   └── lodash@1.0.2
    β”‚ β”œβ”€β”€ lodash@2.4.2
    β”‚ └─┬ tiny-lr-fork@0.0.5
    β”‚   β”œβ”€β”€ debug@0.7.4
    β”‚   β”œβ”€β”€ faye-websocket@0.4.4
    β”‚   β”œβ”€β”¬ noptify@0.0.3
    β”‚   β”‚ └── nopt@2.0.0
    β”‚   └── qs@0.5.6
    β”œβ”€β”€ grunt-includes@0.5.2
    β”œβ”€β”¬ grunt-jsvalidate@0.2.2
    β”‚ └── esprima@1.0.4
    β”œβ”€β”€ grunt-legacy-util@0.2.0
    β”œβ”€β”¬ grunt-patch-wordpress@0.3.0
    β”‚ β”œβ”€β”¬ inquirer@0.2.5
    β”‚ β”‚ β”œβ”€β”€ async@0.2.10
    β”‚ β”‚ β”œβ”€β”¬ cli-color@0.2.3
    β”‚ β”‚ β”‚ β”œβ”€β”€ es5-ext@0.9.2
    β”‚ β”‚ β”‚ └─┬ memoizee@0.2.6
    β”‚ β”‚ β”‚   β”œβ”€β”€ event-emitter@0.2.2
    β”‚ β”‚ β”‚   └── next-tick@0.1.0
    β”‚ β”‚ β”œβ”€β”€ lodash@1.2.1
    β”‚ β”‚ └── mute-stream@0.0.3
    β”‚ β”œβ”€β”¬ request@2.27.0
    β”‚ β”‚ β”œβ”€β”€ aws-sign@0.3.0
    β”‚ β”‚ β”œβ”€β”€ cookie-jar@0.3.0
    β”‚ β”‚ β”œβ”€β”€ forever-agent@0.5.2
    β”‚ β”‚ β”œβ”€β”¬ form-data@0.1.4
    β”‚ β”‚ β”‚ β”œβ”€β”€ async@0.9.2
    β”‚ β”‚ β”‚ └─┬ combined-stream@0.0.7
    β”‚ β”‚ β”‚   └── delayed-stream@0.0.5
    β”‚ β”‚ β”œβ”€β”¬ hawk@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ boom@0.4.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ cryptiles@0.2.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ hoek@0.9.1
    β”‚ β”‚ β”‚ └── sntp@0.2.4
    β”‚ β”‚ β”œβ”€β”¬ http-signature@0.10.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ asn1@0.1.11
    β”‚ β”‚ β”‚ β”œβ”€β”€ assert-plus@0.1.5
    β”‚ β”‚ β”‚ └── ctype@0.5.3
    β”‚ β”‚ β”œβ”€β”€ json-stringify-safe@5.0.1
    β”‚ β”‚ β”œβ”€β”€ mime@1.2.11
    β”‚ β”‚ β”œβ”€β”€ node-uuid@1.4.7
    β”‚ β”‚ β”œβ”€β”€ oauth-sign@0.3.0
    β”‚ β”‚ β”œβ”€β”€ qs@0.6.6
    β”‚ β”‚ └── tunnel-agent@0.3.0
    β”‚ β”œβ”€β”€ underscore@1.5.2
    β”‚ └── underscore.string@2.3.3
    β”œβ”€β”¬ grunt-postcss@0.7.1
    β”‚ β”œβ”€β”€ diff@2.2.1
    β”‚ └── es6-promise@3.0.2
    β”œβ”€β”¬ grunt-rtlcss@1.6.0
    β”‚ └─┬ rtlcss@1.7.2
    β”‚   β”œβ”€β”¬ findup@0.1.5
    β”‚   β”‚ └── commander@2.1.0
    β”‚   β”œβ”€β”¬ mkdirp@0.5.0
    β”‚   β”‚ └── minimist@0.0.8
    β”‚   └── strip-json-comments@1.0.4
    β”œβ”€β”¬ grunt-sass@1.1.0
    β”‚ β”œβ”€β”¬ each-async@1.1.1
    β”‚ β”‚ β”œβ”€β”€ onetime@1.1.0
    β”‚ β”‚ └── set-immediate-shim@1.0.1
    β”‚ β”œβ”€β”¬ node-sass@3.4.2
    β”‚ β”‚ β”œβ”€β”€ async-foreach@0.1.3
    β”‚ β”‚ β”œβ”€β”¬ cross-spawn@2.1.4
    β”‚ β”‚ β”‚ β”œβ”€β”¬ cross-spawn-async@2.1.6
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ lru-cache@4.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ pseudomap@1.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ └── yallist@2.0.0
    β”‚ β”‚ β”‚ β”‚ └─┬ which@1.2.1
    β”‚ β”‚ β”‚ β”‚   └─┬ is-absolute@0.1.7
    β”‚ β”‚ β”‚ β”‚     └── is-relative@0.1.3
    β”‚ β”‚ β”‚ └─┬ spawn-sync@1.0.15
    β”‚ β”‚ β”‚   └── os-shim@0.1.3
    β”‚ β”‚ β”œβ”€β”¬ glob@5.0.15
    β”‚ β”‚ β”‚ └── minimatch@3.0.0
    β”‚ β”‚ β”œβ”€β”¬ mkdirp@0.5.1
    β”‚ β”‚ β”‚ └── minimist@0.0.8
    β”‚ β”‚ β”œβ”€β”€ nan@2.1.0
    β”‚ β”‚ β”œβ”€β”¬ node-gyp@3.2.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ fstream@1.0.8
    β”‚ β”‚ β”‚ β”‚ └── graceful-fs@4.1.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ graceful-fs@4.1.2
    β”‚ β”‚ β”‚ β”œβ”€β”€ minimatch@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ nopt@3.0.6
    β”‚ β”‚ β”‚ β”œβ”€β”¬ npmlog@1.2.1
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ansi@0.3.0
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ are-we-there-yet@1.0.5
    β”‚ β”‚ β”‚ β”‚ β”‚ └── delegates@0.1.0
    β”‚ β”‚ β”‚ β”‚ └─┬ gauge@1.2.2
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ has-unicode@1.0.1
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”¬ lodash.pad@3.1.1
    β”‚ β”‚ β”‚ β”‚   β”‚ β”œβ”€β”€ lodash._basetostring@3.0.1
    β”‚ β”‚ β”‚ β”‚   β”‚ └─┬ lodash._createpadding@3.6.1
    β”‚ β”‚ β”‚ β”‚   β”‚   └── lodash.repeat@3.0.1
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ lodash.padleft@3.1.1
    β”‚ β”‚ β”‚ β”‚   └── lodash.padright@3.1.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ osenv@0.1.3
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ os-homedir@1.0.1
    β”‚ β”‚ β”‚ β”‚ └── os-tmpdir@1.0.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ path-array@1.0.0
    β”‚ β”‚ β”‚ β”‚ └── array-index@0.1.1
    β”‚ β”‚ β”‚ β”œβ”€β”€ semver@5.1.0
    β”‚ β”‚ β”‚ └─┬ tar@2.2.1
    β”‚ β”‚ β”‚   └── block-stream@0.0.8
    β”‚ β”‚ β”œβ”€β”¬ npmconf@2.1.2
    β”‚ β”‚ β”‚ β”œβ”€β”¬ config-chain@1.1.9
    β”‚ β”‚ β”‚ β”‚ └── proto-list@1.2.4
    β”‚ β”‚ β”‚ β”œβ”€β”€ ini@1.3.4
    β”‚ β”‚ β”‚ β”œβ”€β”€ nopt@3.0.6
    β”‚ β”‚ β”‚ β”œβ”€β”€ semver@4.3.6
    β”‚ β”‚ β”‚ └── uid-number@0.0.5
    β”‚ β”‚ β”œβ”€β”¬ request@2.67.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ aws-sign2@0.6.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ caseless@0.11.0
    β”‚ β”‚ β”‚ β”œβ”€β”¬ combined-stream@1.0.5
    β”‚ β”‚ β”‚ β”‚ └── delayed-stream@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ extend@3.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ forever-agent@0.6.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ form-data@1.0.0-rc3
    β”‚ β”‚ β”‚ β”‚ └── async@1.5.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ har-validator@2.0.3
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ commander@2.9.0
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ is-my-json-valid@2.12.3
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ generate-function@2.0.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ generate-object-property@1.2.0
    β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ └── is-property@1.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ └── jsonpointer@2.0.0
    β”‚ β”‚ β”‚ β”‚ └─┬ pinkie-promise@2.0.0
    β”‚ β”‚ β”‚ β”‚   └── pinkie@2.0.1
    β”‚ β”‚ β”‚ β”œβ”€β”¬ hawk@3.1.2
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ boom@2.10.1
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ cryptiles@2.0.5
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ hoek@2.16.3
    β”‚ β”‚ β”‚ β”‚ └── sntp@1.0.9
    β”‚ β”‚ β”‚ β”œβ”€β”¬ http-signature@1.1.0
    β”‚ β”‚ β”‚ β”‚ β”œβ”€β”¬ jsprim@1.2.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ extsprintf@1.0.2
    β”‚ β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ json-schema@0.2.2
    β”‚ β”‚ β”‚ β”‚ β”‚ └── verror@1.3.6
    β”‚ β”‚ β”‚ β”‚ └─┬ sshpk@1.7.2
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ asn1@0.2.3
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ assert-plus@0.2.0
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ dashdash@1.11.0
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ ecc-jsbn@0.1.1
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ jodid25519@1.0.2
    β”‚ β”‚ β”‚ β”‚   β”œβ”€β”€ jsbn@0.1.0
    β”‚ β”‚ β”‚ β”‚   └── tweetnacl@0.13.3
    β”‚ β”‚ β”‚ β”œβ”€β”€ is-typedarray@1.0.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ isstream@0.1.2
    β”‚ β”‚ β”‚ β”œβ”€β”¬ mime-types@2.1.9
    β”‚ β”‚ β”‚ β”‚ └── mime-db@1.21.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ oauth-sign@0.8.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ qs@5.2.0
    β”‚ β”‚ β”‚ β”œβ”€β”€ stringstream@0.0.5
    β”‚ β”‚ β”‚ β”œβ”€β”€ tough-cookie@2.2.1
    β”‚ β”‚ β”‚ └── tunnel-agent@0.4.2
    β”‚ β”‚ └─┬ sass-graph@2.0.1
    β”‚ β”‚   β”œβ”€β”¬ glob@5.0.15
    β”‚ β”‚   β”‚ └── minimatch@3.0.0
    β”‚ β”‚   β”œβ”€β”€ lodash@3.10.1
    β”‚ β”‚   └─┬ yargs@3.31.0
    β”‚ β”‚     β”œβ”€β”¬ cliui@3.1.0
    β”‚ β”‚     β”‚ └── wrap-ansi@1.0.0
    β”‚ β”‚     β”œβ”€β”¬ os-locale@1.4.0
    β”‚ β”‚     β”‚ └─┬ lcid@1.0.0
    β”‚ β”‚     β”‚   └── invert-kv@1.0.0
    β”‚ β”‚     β”œβ”€β”¬ string-width@1.0.1
    β”‚ β”‚     β”‚ β”œβ”€β”€ code-point-at@1.0.0
    β”‚ β”‚     β”‚ └── is-fullwidth-code-point@1.0.0
    β”‚ β”‚     β”œβ”€β”€ window-size@0.1.4
    β”‚ β”‚     └── y18n@3.2.0
    β”‚ └── object-assign@4.0.1
    └─┬ matchdep@1.0.0
      β”œβ”€β”¬ findup-sync@0.3.0
      β”‚ └─┬ glob@5.0.15
      β”‚   └── minimatch@3.0.0
      β”œβ”€β”¬ globule@0.2.0
      β”‚ β”œβ”€β”¬ glob@3.2.11
      β”‚ β”‚ └── minimatch@0.3.0
      β”‚ β”œβ”€β”€ lodash@2.4.2
      β”‚ └── minimatch@0.2.14
      └── stack-trace@0.0.9
    

    And this is just for WordPress core; it doesn’t include the tools we use for BuddyPress or bbPress.

    I don’t like this. I don’t like not knowing what these tools do or why they’re necessary. It feels like having one-thousand hammers instead of drill-bits and screwdrivers and power-tools. It’s not immediately obvious what the return on learning each or any of these unique tools is.

    And when a tool becomes obsolete or out-of-date, the rabbit hole is full of eels:

    npm WARN deprecated lodash@0.9.2: lodash@<2.0.0 is no longer maintained. Upgrade to lodash@^3.0.0
    npm WARN deprecated npmconf@2.1.1: this package has been reintegrated into npm and is now out of date with respect to npm
    npm WARN deprecated lodash@1.0.2: lodash@<2.0.0 is no longer maintained. Upgrade to lodash@^3.0.0
    npm WARN deprecated lodash@1.2.1: lodash@<2.0.0 is no longer maintained. Upgrade to lodash@^3.0.0
    npm WARN deprecated npmconf@2.1.2: this package has been reintegrated into npm and is now out of date with respect to npm
    npm WARN deprecated lodash@2.4.2: lodash@<3.0.0 is no longer maintained. Upgrade to lodash@^3.0.0.
    n
    

    These relatively helpful messages may be outside of your control. They might be directly your fault. They might be globally installed modules or locally installed ones. Upgrading might be good for WordPress but break everything else you work on without warning.

    Here’s usually what happens:

    • Something in the mystery toolbox breaks and complains about it
    • Try to upgrade the broken tool according to the feedback message(s)
    • The tool is still broken
    • Delete the entire `node_modules` directory and `npm install` again
    • Fixed!

    Now, I understand what’s going on here is a miracle of modern software engineering. An enormous amount of automation is going on here, and the fact it actually works most of the time I’ll consider another closely coupled miracle. It still feels like there must be a better way, even though I can’t claim the fame of knowing right now what that might actually be.

    I get that this is all awesome. I get that this process, and having & using these tools, is better than smashing things with rocks and hoping for the best. I get that a ton of work has gone into making this as seamless and wrinkle-free as possible.

    I accept it, and work with it, and try not to think about it, but the trend of installing and trusting hundreds of tiny unknown libraries feels a little too organic and alive for a man-made computing machine. Like millions of nerve-endings and neurons and vessels and muscles working in unison to blink your eyes and sip on some coffee, the line between being a software developer or a software doctor is an increasingly jagged one.

    If we aren’t careful, we’ll end up as lost amongst our own creations as we are inside of mother nature’s.

    JJJ

    January 7, 2016
    Rants, Opinion, Software, WordPress
  • The NSA's Guidelines for Implementation of REST

    NSA REST

    Direct LinkΒ andΒ Mirrored Here,Β from March 25, 2011:

    The key point to remember is that in order to ensure that an operation / implementation is RESTful, these methods must be used as they were defined in RFC 2616, the HTTP 1.1 specification. If implementations abuse these methods, they not only depart from RESTful behavior, but also jeopardize the application’s ability to interoperate with other RESTful capabilities.

    JJJ

    November 6, 2015
    WordPress
    REST
  • Chosen & Pretty Filters

    In the past month I’ve released two WordPress plugins that I think ended up complementing each other rather nicely:

    • WP Chosen
    • WP Pretty Filters

    Together they make filtering posts in WordPress a much nicer experience:

    Chosen + Pretty Filters

    If you’re a plugin author that’s bundling the Chosen library or doing something interesting with post filters, I hope you’llΒ consider referring your users to installΒ these instead.

    Good plugins areΒ small, purposeful, and they naturally blend into WordPress like bananas in a smoothie, but when you bundle libraries inside your large plugin, you willΒ collide with other plugins thatΒ use that same library, and WordPress just isn’t designed to handle this very well quiteΒ yet.

    Chances are, your plugin works greatΒ without Chosen. Users can still drop down a select box and type in it to find what they’re looking for, it’s just not a fancy experience. If you think your users would enjoy a fancy experience, maybe consider pointing them to WP Chosen instead, and update your plugin to support it and avoidΒ the additional support burden while you’re at it.

    P.S. All sites on Flox.io now have both of these active by default. <3

    JJJ

    November 6, 2015
    WordPress
    Plugins, Chosen, Pretty Filters
  • Meet Stuttter

    Stuttter, like WordPress on the surface, is both product and organization.

    Spiritually itΒ is a conduit for rethinking WordPress from the outside in. It’s a way to independently test the waters for what we can do with it, without deviating from it’s history, beauty, charm, andΒ chutzpah.

    For me, it’s an empty canvas for code, and a place to create without prohibition.Β For everyone else, hopefully it’s a bunch of little widgets and do-dads that areΒ valuable enough to maybe consider sponsoring or paying for.

    The name comes from what happens when I’m nervous, which doesn’t happen very frequently. I struggle to find the sequence of words that I think will most quickly bring calm, so I stumble and stammer for a bit until I find my stride. (Someone I adore, who does this quite endearingly, is Elon Musk.)

    There is aΒ brief period of excitement while ideas are unraveling, and that’s what Stuttter represents.

    Like how auto-makers take off-the-shelf componentsΒ and wrap them to design next-generation vehicles; how architects take pre-existing materials and specifications and add their flair and signature; how Apple, Adobe, and Automattic leverage open-source libraries to create beautiful software experiences; Stuttter is howΒ IΒ identifyΒ uniquely powerful aspects ofΒ open-source GPL friendly software, and extract them into neatlyΒ packaged design implementations for WordPress.

    Right now, you can follow Stuttter on GitHub, Flox, WordPress.org, and Packagist, until we get some websites up.Β Here are the first pass logo and icon, if you’re interested in using them:stuttter

    stuttter-circle

    JJJ

    October 16, 2015
    Software, WordPress
  • LoopConf

    I’m going to say, with emphasis, what I think everyone is probably thinking…

    LoopConf is what you wish most WordCamps were

    Here’s my gist:

    • Live streaming quality was excellent, because a professional crew was on-tap to handle all of it
    • The logistical planning of the entire conference felt very smooth – almost invisible, really
    • VendorΒ tables were in a single isle, making them impossible to miss and easily approachable because they needed to be constantly staffed
    • Speaker quality was excellent, and I predict we will see a few presentations remixed and repackaged by others for WordCamps this year and next
    • I never want to follow John O’Nolan (of Ghost fame)Β in a speaker lineup ever again – he is a well-prepared stage performer with relatable personality and charisma, and will easily make you second guess your own experience &Β abilities
    • Andy Nacin’s talk was revealing, and even still, is only really half of the story
    • Jeremy Felt is much more comfortable on stage than he used to be, and his Multisite presentation was spot on
    • So many mentions of the REST API, but not a lot of truly practical usages yet – everyoneΒ isΒ buildingΒ WordPress minusΒ WordPressΒ instead of replacing existing piecemeal AJAXΒ calls or iteratively improving WordPress itself

    Full disclosure: after O’Nolan’s talk, the reality of being the last session of an intense 3 day conference became very apparent, so I trimmed 10 slides from my presentation talking about code and stuck to the high-level overview of my perspective ofΒ what building (and maintaining) big plugins is like and means to me.

    It didn’t help either thatΒ vendors started breaking down their tables & displays in the middle of the talk before mine. It confirmed my suspicions that at least some people were ready to be done with the event, and demotivated me enough to cut my talk a few minutes short so everyone could call LoopConf done-done and move on to reflecting rather than ingesting. I know some events penalize vendors for this, and I’m not exactly endorsing that, but I can say in my experience that it certainly influenced my mood on stage.

    Going back to the WordCamp vs. LoopConf angle, I like that WordCamps are casual and inviting, and I like that conferences like LoopConf and the WordPress.com VIP Workshop strive to achieve something more professional. I think there will be some WordCamps that try to upgrade themselves to compete, and others that will purposely stay intimate and niche. And I love that event planners have the freedom to choose what they think is best for their audiences, and that attendees are able to tweak their own experiences within the WordPress specificΒ conference space.

    LoopConf in general was superΒ great event. It felt well executed, with plenty to do, learn, and accomplish afterwards. I hope I’m invited back next year to go more in-depth about something niche and interesting happening in the WordPress community, and if so, that I don’t end up following that O’Nolan chap again.

    P.S. – here’s the recording of my talk, if you’re interested

    JJJ

    May 14, 2015
    BuddyPress, Opinion, bbPress
    LoopConf
  • WordPress is a Conduit

    WordPress is a Conduit

    When people talk about WordPress, they call it various things:

    • Blogging software
    • A content management system
    • An application framework

    In the past, I’ve gone on the record and called it something even bigger, but noneΒ of these descriptions truly accurately describe what WordPress actually is, at least to an ever-increasing number of people.

    WordPress, the software, is a conduit for creativity, discussion, and innovation. You are introduced to it in such a simple way, but it’s potential is immediately recognizable so you can’t help but tinker with it and wonder what else it’s capable of.

    WordPress.org, the website, is a conduit for discovery, a beacon in the fog, and ultimately the preferred outlet for tinkerers like myself. In my opinion, this isΒ the single most important part of the entire system – the kingpin keeping all of it together that without it would all fall down (hat-tip to the GPL, also.)

    WordPress.com, the anti-social network, is a conduit for writing, and a way to be introduced to the great suite of software Automattic produces to help makeΒ online publishingΒ a more enjoyable experience.

    WordPress, all of it, drawsΒ you in and funnels you through it’s finely tuned interface, introducing you back to yourself in a way that’s intentionally intimate and private, provoking you to invent something great and inviting you to learn more about what both you and it are capable of together.

    I’ve experienced no other software and no other community with such an immense, almost gravitational pull. Once I was in, all I could do was orbit and enjoy the view from as many perspectives as I could. From inside Automattic and WordPress.com; from inside 10up and client services; from helping improve WordPress.org; to starting my own journey with Flox – WordPress was there, making sure I knew everything was going to be alright, and helping me discover where I can best fit and why.

    WordPress is a conduit for positivity, for enabling greatness, and for generating joy. To everyone who has contributed influence to the WordPress community, working tirelessly to keep it’s spirit shimmering, thank you for your immense passion, intense attention to detail, and for allowing me to float along and be helpful where I’m able.

    JJJ

    April 17, 2015
    WordPress
  • "I’m too busy"

    TL;DR – If you ping me directly for help with something, you will probably get it.

    BuddyPress & bbPress recently switched from IRC to Slack for real time synchronous communication. Philosophically, I prefer the openness of IRC, but I do appreciate how convenient Slack is for everyone, and it’s anecdotally a more inviting and active environment & experience. For some, Slack might actually be overly convenient to the point of annoying or obtrusive, but I think like any communication tool, it requires a bit of wrangling and tuning to suit your needs.

    What won’t happen, in Slack or otherwise, is any response from me that boils down to “I’m too busy” even if it’s true.

    Let’s imagine that I am actually too busy to help you; you still won’t hear me say so. Instead, you’ll get any number of differentΒ replies that are considerate of you and your time:

    • “I’d love to help but won’t be able to for X number of hours.”
    • “Sorry; I have a bunch of things going on and won’t be able to get to this for a while.”
    • “I took a quick look and found this; check it out and let me know how it goes.”
    • “I can’t help right now, but maybe Frank is around and can take a look with you.”

    MyΒ emphasis is on being polite and considerate of how the recipient could perceive my attitude & demeanor, and making sure to convey genuine concern for their situationΒ even if it does notΒ directly influence my life or priorities in any way.

    Conversely, when I reach out to ask for help, it’s only because I’ve reached a point where it is no longer efficient or appropriateΒ to continue on my own; I’ve done everything I am aware of and is in my scope of influence to do, and for any number of reasons I’m choosing to include someone else into my situation.

    One place this happens quite frequently is WordPress Trac. As an example, let’s again imagine that I’m working onΒ BuddyPress or bbPress, and I believe I’ve identified a bug in WordPress core. There’s a priority-ordered list of things I’ll go through before I include anyone else into my problem:

    • Run the PHPUnit tests to ensure I didn’t break something on my own
    • Duplicate the bug in a completely vanilla installation without any modifications
    • Confirm bug is real
    • Attempt to fix bug in WordPress core codebase by modifying as few lines as possible
    • Test and retest fix to confirm results, and confirm PHPUnit tests still pass
    • Search the internet for anyone else with this problem, and drill down into any relevant results to learn as much as I can about what anyone else is experiencing
    • Search WordPress Trac for any existing tickets related to any surrounding code, usually by searching for function or method names, variables, component names, etc…

    All this, and no one else but me has any idea I’ve been hunting down Carmen Sandiego for the past hour or two. What happens next generally depends on the severity of the issue, and whether or not I feel comfortable pinging someone directly and risk interrupting whatever they’re working on for a consult. In my experience, anytime theΒ urgency and prioritization of two separate parties converges, it requires even more clear & concise communication than normal. IfΒ someone gets frustrated by beingΒ interrupted, or you haven’t come fully prepared, the person(s) you ping are not going to be receptive now, and will be less receptive in the future.

    Even after all of this research, preparation, and with years of experience doing this in a professional setting, it still isn’t easy, and positive & productive results are not guaranteed. I think if you value other people’s time more than your own, do your due-diligence, and are considerate of how your interruptions may impact their lives, you will generally get the same in return. And if you’re always constantly too busy to be interrupted (to the point of forgetting to be polite about it) it might not be the outside world and their lack of so-and-so that’s the problem.

    JJJ

    March 4, 2015
    BuddyPress, WordPress
    Communication, Consideration, Process
  • January thoughts, BuddyPress 2.2

    With each new software release that I’m fortunate enough to contribute to, I usually take some time (or lots of time) to reflect on a few different things that I think are critical to the project and myself:

    • What went right?
    • What went wrong?
    • What did I learn?
    • What can I do better?

    With BuddyPress 2.2 imminent, here’s a brain-dump of my random and unrelated thoughts for January 2015, in no particular order:

    • Significant improvements have been made to cache-coverage, but many more are necessary, and some of our existing implementations are not ideal.
    • User statuses areΒ pretty messy. A user’s status is a numeric value in the users database table, and there is no API in WordPress for interacting with it. Just like post statuses, anyone concerned with workflow (or activation flow in this case) is pretty much on their own.
    • The Member Type APIΒ is sweet, and I’m excited to see how developers use it. Hopefully I get to use it myself soon.
    • It seems like each ticket takes longer to test, confirm, fix, patch, and push.
    • How strictly do we enforce cache coverage, unit-test overage, inline documentation coverage, and all of the other nuances? I fear we are over-complicating each others lives with anti-progress and slowly forgetting what made BuddyPress fun to work on in the first place.
    • I need to write more unit tests.
    • I need to increase cache coverage.
    • I need to write more inline documenta… Ehh…Β maybe I’m okay here.
    • I sure wish PHPUnit wereΒ faster and easier to run. Netbeans has decent integration, but I haven’t figured out how to efficiently implement it into my workflow.
    • It’s been really great not juggling immense client and customer expectations in January, thanks to the funders of my recent IndieGogo campaign.
    • The old BuddyPress Default and Legacy templates are starting to look really out-of-date to me now. I wish we didn’t have so many templates to style and that creating themes was easier.
    • I continue to struggle with the cost of switching contexts during the day, between writing code, impromptu meetings, and random pings. Working nights used to help with this, and I need to come up with a healthy plan to improve my ability to come back to things once I switch away from them. I feel like I used to be better at this when I was younger.
    • That squirrel outside my window is looking pretty well fed considering it’s January.
    • I bought too much Lego over Christmas.
    • I need to take more small breaks and be more physically active during the day.
    • I need to prioritize blogging.
    • I need a nap, and it’s only 11am.
    • BuddyPress 2.2 is going to be sweet.
    • Boone did a really good job juggling both WordPress and BuddyPress core development. Note: be more like Boone, at least in this capacity (I don’t think I can eat that much pizza anymore.)
    • I’m excited for a vacation my wife and I are planning in March to celebrate our wedding anniversary. It will probably be much needed by then.
    • I broke my ankle 1 year ago, and it’s still not quite right. Likely won’t ever be the same I suppose. Guess I’ll never play the piano again.
    • Penny (our new rescue puppy) tested positive for heart-worm. Poor thing. Hopefully it’s not too bad and we get her all fixed up.
    • You are great. <3

    JJJ

    January 24, 2015
    BuddyPress, Software, Crowd Funding
Previous Page
1 2 3 4 5 … 7
Next Page

Proudly Powered by WordPress