[
  {
    "path": ".eslintrc.yml",
    "content": "env:\n  es6: true\n  node: true\nextends: 'eslint:recommended'\nrules:\n  # indent:\n  #   - error\n  #   - 4\n  linebreak-style:\n    - error\n    - unix\n  quotes:\n    - error\n    - single\n  semi:\n    - error\n    - always\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n\n* text=auto\n*.js text eol=lf\n*.json text eol=lf\n\n# Standard to msysgit\n\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n\n# Git LFS\n\n*.ai filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\ndoc/\ndocs/\nlocal/\nnpm-debug.log\n*.map\n\n# Emacs detritus\n# -*- mode: gitignore; -*-\n*~\n\\#*\\#\n/.emacs.desktop\n/.emacs.desktop.lock\n*.elc\nauto-save-list\ntramp\n.\\#*\n\n# Org-mode\n.org-id-locations\n*_archive\n\n# flymake-mode\n*_flymake.*\n\n# eshell files\n/eshell/history\n/eshell/lastdir\n\n# elpa packages\n/elpa/\n\n# reftex files\n*.rel\n\n# AUCTeX auto folder\n/auto/\n\n# cask packages\n.cask/\n"
  },
  {
    "path": ".npmignore",
    "content": "assets/\ntest/\ndoc/\n.travis.yml\n.eslintrc.yml\nGruntfile.js\n.gitattributes\nROADMAP.md\nBUILDING.md\nCONTRIBUTING.md\nCHANGELOG.md\nFAQ.md\n*.map\n"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: required\nbefore_install:\n  # Prevents a shared object .so error when running wkhtmltopdf on certain\n  # platforms (e.g., vanilla Ubuntu 16.04 LTS). Not necessary on current Travis.\n  # - sudo apt-get install libxrender1\ninstall:\n  # Install & link HackMyResume\n  - npm install && npm link\n  # Download and extract the latest wkhtmltopdf binaries\n  - mkdir tmp && wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz -O tmp/wk.tar.xz\n  - tar -xf tmp/wk.tar.xz -C ./tmp\n  # Copy wkhtmltopdf binaries to /usr/bin (also makes them path-accessible)\n  - sudo cp -R ./tmp/wkhtmltox/bin/* /usr/bin/\n  # Now you can invoke \"wkhtmltopdf\" and \"wkhtmltoimage\" safely in tests.\n  - wkhtmltopdf -V\n  - wkhtmltoimage -V\nlanguage: node_js\nnode_js:\n  - \"6\"\n  - \"7\"\n  - \"8\"\n  - \"9\"\n  - \"lts/*\"\n"
  },
  {
    "path": "BUILDING.md",
    "content": "Building\n========\n\n*See [CONTRIBUTING.md][contrib] for more information on contributing to the\nHackMyResume or FluentCV projects.*\n\nHackMyResume is a standard Node.js command line app implemented in a mix of\nCoffeeScript and JavaScript. Setting up a build environment is easy:\n\n\n## Prerequisites ##\n\n1. OS: Linux, OS X, or Windows\n\n2. Install [Node.js][node] and [Grunt][grunt].\n\n\n## Set up a build environment ###\n\n1. Fork [hacksalot/HackMyResume][hmr] to your GitHub account.\n\n2. Clone your fork locally.\n\n3. From within the top-level HackMyResume folder, run `npm install` to install\nproject dependencies.\n\n4. Create a new branch, based on the latest HackMyResume `dev` branch, to\ncontain your work.\n\n5. Run `npm link` in the HackMyResume folder so that the `hackmyresume` command\nwill reference your local installation (you may need to\n`npm uninstall -g hackmyresume` first).\n\n## Making changes\n\n1. HackMyResume sources live in the [`/src`][src] folder.\n\n2. When you're ready to submit your changes, run `grunt test` to run the HMR\ntest suite. Fix any errors that occur.\n\n3. Commit and push your changes.\n\n4. Submit a pull request targeting the HackMyResume `dev` branch.\n\n\n[node]: https://nodejs.org/en/\n[grunt]: http://gruntjs.com/\n[hmr]: https://github.com/hacksalot/HackMyResume\n[src]: https://github.com/hacksalot/HackMyResume/tree/master/src\n[contrib]: https://github.com/hacksalot/HackMyResume/blob/master/CONTRIBUTING.md\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "CHANGELOG\n=========\n\n## v1.9.0-beta\n\n*Welcome to the first new version of HackMyResume in over a year. The purpose of\nthis release is to gather feature enhancements and bug fixes collected over the\npast 18 months as we reorganize, rebrand, and prepare for the 2.0 release.*\n\n### Added\n\n- Support for **private resume fields**. Mark any non-leaf node in your resume\nJSON with the `private` property and it will be omitted from outbound resumes.\n\n    ```json\n    \"employment\": {\n      \"history\": [\n        {\n          \"employer\": \"Acme Real Estate\"\n        },\n        {\n          \"employer\": \"Area 51 Alien Research Laboratory\",\n          \"private\": true\n        },\n        {\n          \"employer\": \"H&R Block\"\n        }\n      ]\n    }\n    ```\n- Support for **PDF generation through WeasyPrint** in addition to the\nexisting support for wkhtmltopdf and PhantomJS.\n\n- Theme authors can now develop and package **custom Handlebars theme helpers**\nvia the `helpers` key of the `theme.json` file (FRESH themes only) (#158).\n\n- Help system has been updated with a `HELP` command and dedicated help pages\nfor each command.\n\n- Theme authors can **relocate theme assets** with the `baseFolder` property in\nthe FRESH `theme.json`.\n\n- HackMyResume will now **validate the options file** (if any) loaded with `-o`\nor `--options` and warn the user if necessary.\n\n- Ability to **disable Handlebars encoding/escaping** of resume fields with\n`--no-escape`.\n\n- Introduced the [fresh-test-themes][ftt] project as a repository for simple,\ntest-only resume themes in the FRESH format.\n\n### Changed\n\n- Dropped support for Node 4 and 5. HackMyResume officially runs on Node 6+.\n\n- The FRESCA project has been renamed to [fresh-resume-schema][fresca]. FRESCA\nis still the nickname.\n\n- The HackMyResume web page has moved to https://fluentdesk.com/hackmyresume.\n\n### Fixed\n\n- Fixed an issue that would cause the `convert` command to detect the inbound\nresume type (FRESH or JRS) incorrectly (#162).\n\n- Fixed an issue where generating new JRS resumes would cause a `null` or\n`undefined` error (#165).\n\n- Fixed an issue preventing mixed-case themes from being loaded (#172).\n\n- Fixed an issue requiring JSON Resume themes contain `json-resume-theme` in the\ntheme path (#173).\n\n- Fixed an issue that would cause strange `@@@@` characters to appear in\ngenerated resumes (#207, #168, #198).\n\n- Fixed an issue that would cause resume generation to hang after a JSON Resume\nthemed resume was generated (#182).\n\n- Fixed an issue that would cause nothing to be generated for Markdown (.md)\nformats (#179).\n\n- Fixed an issue that would prevent a JRS resume from being converted to FRESH\nvia the `convert` command (#180).\n\n- Fixed an issue that would cause broken styling for JSON Resume themes (#155).\n\n### Internal\n\n- Tests: fixed resume duration tests (#181).\n\n- Style: move to\n\n## v1.8.0\n\n### Added\n\n- Updated `Awesome` theme to latest version of [Awesome-CV][acv].\n\n- Introduced new theme helpers: `pad`, `date`.\n\n### Fixed\n\n- Fixed an issue where the `Awesome` theme wouldn't correctly generate LaTeX\noutputs (#138).\n\n- Emit a line number for syntax errors around embedded newlines in JSON strings\n(#137).\n\n- Fix several PDF / PNG generation errors (#132, others).\n\n- Display a more helpful error message when attempting to generate a PDF or PNG\non a machine where PhantomJS and/or wkhtmltopdf are either not installed or\nnot path-accessible.\n\n- Fixed an issue that would cause long-running PDF/PNG generation to fail in\ncertain environments.\n\n- Fixed an issue involving an unhelpful spawn-related exception (#136).\n\n### Internal\n\n- JSHint will no longer gripe at the use of `== null` and `!= null` in\nCoffeeScript transpilation.\n\n- Introduced [template-friendly Awesome-CV fork][awefork] to isolate template\nexpansion logic & provide better durability for HackMyResume's `awesome` theme.\n\n- Fixed a couple temporary regressions (#139, #140) on the dev branch.\n\n- Additional tests.\n\n- Minor breaking HackMyResume API changes.\n\n## v1.7.4\n\n### Added\n\n- [Build instructions](https://github.com/hacksalot/HackMyResume/blob/master/BUILDING.md).\n\n### Changed\n\n- More precise date handling.\n\n### Fixed\n\n- Issue with incomplete PDF generation (#127).\n\n- Issue with building JSON Resume themes (#128).\n\n- Issue with generating `.json` output format by itself (#97).\n\n## v1.7.3\n\n### Fixed\n\n- Issue with generated PDFs being chopped off and displaying a mysterious sequence of numbers of unknown and possibly alien origin (#127).\n\n- Unsightly border on Modern:PDF.\n\n- Modern|Positive:PDF formats now correctly reference their PDF-specific CSS files.\n\n- `Incorrect helper use` warning in Positive:DOC.\n\n## v1.7.2\n\n### Changed\n\n- Interim release supporting FluentCV Desktop.\n\n### Internal\n\n- Moved [HackMyCore](https://github.com/hacksalot/HackMyCore) dependency to\nsubmodule.\n\n## v1.7.1\n\n### Changed\n\n- Caffeinate. CoffeeScript now used throughout\n[HackMyResume](https://github.com/hacksalot/HackMyResume) and\n[HackMyCore](https://github.com/hacksalot/HackMyCore); generated JavaScript\nlives in `/dist`.\n\n### Fixed\n\n- Issue with generating a single PDF with the `.pdf` extension (#99).\n\n## v1.7.0\n\n### Changed\n\n- [Internal] Relocated HMR processing code to the\n[HackMyCore](https://github.com/hacksalot/HackMyCore) project. Shouldn't affect\nnormal use.\n\n## v1.6.0\n\n### Major Improvements\n\n- Better consistency and coverage for all FRESH resumes and themes ([#45][i45]).\n\n- Initial support for overridable fonts in FRESH themes. Like a particular\ntheme, but want to change the typography? The specific fonts used by a theme\ncan now be overridden by the user. (FRESH themes only).\n\n- New resume sections! Support for `projects` and `affiliation` resume sections\nfor technical and creative projects and memberships / clubs / associations,\nrespectively ([#92][i92]).\n\n- New command! `PEEK` at any arbitrary field or entry on your `.json` resume.\n\n### Added\n\n- Improved handling of start and end dates on `employment`, `projects`,\n`education`, and other sections with start/end dates.\n\n- Support for an `.ignore` property on any FRESH or JSON Resume section or field.\nIgnored properties will be treated by HackMyResume as if they weren't present.\n\n- Emit extended status and error info with the `--debug` or `-d` switch.\n\n- The `-o` or `--options` switch can now handle either the path to a **JSON\nsettings file** or **raw JSON/JavaScript**. Since the JSON double quote syntax\nis a bit cumbersome from the command line, HackMyResume accepts regular\nJavaScript object literal syntax:\n\n        hackmyresume build resume.json -o \"{ theme: 'compact', silent: 'true' }\"\n\n- Ability to disable sorting of resume sections (employments, projects, etc.)\nwith the `--no-sort` option. HMR will respect the order of items as they appear\nin your resume `.json` file.\n\n- Improvements to the starter resume emitted by `hackmyresume new`.\n\n- Theme Authoring: Annotated the HTML and MS Word (XML) formats of the Modern\ntheme for FRESH theme authors.\n\n- Theme Authoring: Support for templatized CSS files in FRESH themes. CSS files\nare now expanded via Handlebars or Underscore prior to copying to the\ndestination.\n\n- Added CHANGELOG.md (this file).\n\n### Changed\n\n- Rewrote the HackMyResume man/help page.\n\n- Minor incremental updates to the [FRESCA][fresca] schema.\n\n- PDF generation now uses asynchronous `spawn()` which has better compatibility\nwith old or boutique versions of Node.js.\n\n- Refactored colors in HackMyResume output. Errors will now display as red,\nwarnings as yellow, successful operations as green, and informational messages\nas cyan.\n\n- Theme messages and usage tips will no longer display during resume generation\nby default. Use the `--tips` option to view them.\n\n- The `--no-tips` option (default: false) has been replaced with the `--tips`\noption, also defaulting to false.\n\n- Removed the `hello-world` theme from the [prebuilt themes][themes] that ship\nwith HackMyResume. It can be installed separately from NPM:\n\n  ```bash\n  npm install fresh-theme-hello-world\n  hackmyresume resume.json -t node_modules/fresh-theme-hello-world\n  ```\n\n- sd\n\n### Fixed\n\n- PDF generation issues on older versions of Node.\n\n- Stack traces not being emitted correctly.\n\n- Missing `speaking` section will now appear on generated resumes ([#101][i101]).\n\n- Incomplete `education` details will now appear on generated resumes ([#65][i65]).\n\n- Missing employment end date being interpreted as \"employment ends today\"\n([#84][i84]).\n\n- Merging multiple source resumes during `BUILD` sometimes fails.\n\n- Document `--pdf` flag in README ([#111][i111]).\n\n### Internal\n\n- Logging messages have been moved out of core HackMyResume code ahead of\nlocalization support.\n\n- All HackMyResume console output is described in `msg.yml`.\n\n- Relaxed pure JavaScript requirement. CoffeeScript will now start appearing\nin HackMyResume and FluentCV sources!\n\n- Additional tests.\n\n## v1.5.2\n\n### Fixed\n\n- Tweak stack trace under `--debug`.\n\n## v1.5.1\n\n### Added\n\n- Preliminary support for `-d` or `--debug` flag. Forces HackMyResume to emit a stack trace under error conditions.\n\n## v1.5.0\n\n### Added\n\n- HackMyResume now supports **CLI-based generation of PDF formats across multiple engines (Phantom, wkhtmltopdf, etc)**. Instead of talking to these engines over a programmatic API, as in prior versions, HackMyResume 1.5+ speaks to them over the same command-line interface (CLI) you'd use if you were using these tools directly.\n\n- HackMyResume will now (attempt to) **generate a PDF output for JSON Resume themes** (in addition to HTML).\n\n- Minor README and FAQ additions.\n\n### Changed\n\n- **Cleaner, quicker installs**. Installing HackMyResume with `npm install hackmyresume -g` will no longer trigger a lengthy, potentially error-prone install for Phantom.js and/or wkhtmltopdf for PDF support. Instead, users can install these engines externally and HMR will use them when present.\n\n- Minor error handling improvements.\n\n### Fixed\n\n- Fixed an error with generating specific formats with the `BUILD` command (#97).\n\n- Fixed numerous latent/undocumented bugs and glitches.\n\n## v1.4.2\n\n### Added\n\n- Introduced [FAQ](https://github.com/hacksalot/HackMyResume/blob/master/FAQ.md).\n- Additional README notes.\n\n## v1.4.1\n\n### Added\n\n- `hackmyresume new` now generates a [valid starter resume with sample data](https://github.com/fluentdesk/fresh-resume-starter).\n\n### Fixed\n\n- Fixed warning message when `hackmyresume new` is run without a filename.\n\n## v1.4.0\n\n### Added\n\n- **\"Projects\" support**: FRESH resumes and themes can now store and display\nopen source, commercial, private, personal, and creative projects.\n- **New command: ANALYZE**. Inspect your resume for gaps, keyword counts, and other metrics. (Experimental.)\n- **Side-by-side PDF generation** with Phantom and wkhtmltopdf. Use the `--pdf` or `-p` flag to pick between `phantom` and `wkhtmltopdf` generation.\n- **Disable PDF generation** with the `--pdf none` switch.\n- **Inherit formats between themes**. Themes can now inherit formats (Word, HTML, .txt, etc.) from other themes. (FRESH themes only.)\n- **Rename resume sections** to different languages or wordings.\n- **Specify complex options via external file**. Use with the `-o` or `--opts` option.\n- **Disable colors** with the `--no-color` flag.\n- **Theme messages and usage tips** instructions will now appear in the default HackMyResume output for the `build` command. Run `hackmyresume build resume.json -t awesome` for an example. Turn off with the `--no-tips` flag.\n- **Treat validation errors as warnings** with the `--assert` switch (VALIDATE command only).\n\n### Fixed\n\n- Fixed a minor glitch in the FRESCA schema.\n- Fixed encoding issues in the `Highlights` section of certain resumes.\n- Fix behavior of `-s` and `--silent` flags.\n\n### Changed\n\n- PDF generation now defaults to Phantom for all platforms, with `wkhtmltopdf`\naccessible with `--pdf wkhtmltopdf`.\n- Resumes are now validated, by default, prior to generation. This\nbehavior can be disabled with the `--novalidate` or `--force` switch.\n- Syntax errors in source FRESH and JSON Resumes are now captured for all\ncommands.\n- Minor updates to README.\n- Most themes now inherit Markdown and Plain Text formats from the **Basis**\ntheme.\n\n### Internal\n\n- Switched from color to chalk.\n- Command invocations now handled through commander.js.\n- Improved FRESH theme infrastructure (more partials, more DRY).\n\n## v1.3.1\n\n### Added\n\n- Add additional Travis badges.\n\n### Fixed\n\n- Fix extraneous console log output when generating a FRESH theme to MS Word.\n- Fix Travis tests on `dev`.\n\n## v1.3.0\n\n### Added\n\n- **Local generation of JSON Resume themes**. To use a JSON Resume theme, first install it with `npm install jsonresume-theme-[blah]` (most JSON Resume themes are on NPM). Then pass it into HackMyResume via the `-t` parameter:\n\n    `hackmyresume BUILD resume.json TO out/somefile.all -t node_modules/jsonresume-theme-classy`\n- **Better Markdown support.** HackMyResume will start flowing basic Markdown styles to JSON Resume (HTML) themes. FRESH's existing Markdown support has also been improved.\n- **.PNG output formats** will start appearing in themes that declare an HTML output.\n- **Tweak CSS embedding / linking via the --css option** (`<style></style>` vs `<link>`). Only works for HTML (or HTML-driven) formats of FRESH themes. Use `--css=link` to link in CSS assets and `--css=embed` to embed the styles in the HTML document. For example `hackmyresume BUILD resume.json TO out/resume.all --css=link`.\n- **Improved Handlebars/Underscore helper support** for FRESH themes. Handlebars themes can access helpers via `{{helperName}}`. Underscore themes can access helpers via the `h` object.\n\n### Changed\n\n- **Distinguish between validation errors and syntax errors** when validating a FRESH or JRS resume with `hackmyresume validate <blah>`.\n- **Emit line and column info** for syntax errors during validation of FRESH and JRS resumes.\n- **FRESH themes now embed CSS into HTML formats by default** so that the HTML resume output doesn't have an external CSS file dependency by default. Users can specify normal linked stylesheets by setting `--css=link`.\n- **Renamed fluent-themes repo to fresh-themes** in keeping with the other parts of the project.\n\n### Fixed\n\n- Fix various encoding errors in MS Word outputs.\n- Fix assorted FRESH-to-JRS and JRS-to-FRESH conversion glitches.\n- Fix error when running HMR with no parameters.\n- Other minor fixes.\n\n## v1.3.0-beta\n\n- Numerous changes supporting v1.3.0.\n\n## v1.2.2\n\n### Fixed\n\n- Various in-passing fixes.\n\n## v1.2.1\n\n### Fixed\n\n- Fix `require('FRESCA')` error.\n- Fix `.history` and `.map` errors on loading incomplete or empty JRS resumes.\n\n### Added\n\n- Better test coverage of incomplete/empty resumes.\n\n## v1.2.0\n\n### Fixed\n\n- Fixed the `new` command: Generate a new FRESH-format resume with `hackmyresume new resume.json` or a new JSON Resume with `hackmyresume new resume.json -f jrs`.\n\n### Added\n\n- Introduced CLI tests.\n\n## v1.1.0\n\n### Fixed\n\n- MS Word formats: Fixed skill coloring/level bug.\n\n### Changed\n\n- Make the `TO` keyword optional. If no `TO` keyword is specified (for the `build` and `convert` commands), HMR will assume the last file passed in is the desired output file. So these are equivalent:\n\n    ```shell\n    hackmyresume BUILD resume.json TO out/resume.all\n    hackmyresume BUILD resume.json out/resume.all\n    ```\n\n    `TO` only needs to be included if you have multipled output files:\n\n    ```shell\n     hackmyresume BUILD resume.json TO out1.doc out2.html out3.tex\n    ```\n\n## v1.0.1\n\n### Fixed\n\n- Correctly generate MS Word hyperlinks from Markdown source data.\n\n## v1.0.0\n\n- Initial public 1.0 release.\n\n[i45]: https://github.com/hacksalot/HackMyResume/issues/45\n[i65]: https://github.com/hacksalot/HackMyResume/issues/65\n[i84]: https://github.com/hacksalot/HackMyResume/issues/84\n[i92]: https://github.com/hacksalot/HackMyResume/issues/92\n[i101]: https://github.com/hacksalot/HackMyResume/issues/101\n[i111]: https://github.com/hacksalot/HackMyResume/issues/111\n[fresca]: https://github.com/fresh-standard/fresh-resume-schema\n[themes]: https://github.com/fresh-standard/fresh-themes\n[awefork]: https://github.com/fluentdesk/Awesome-CV\n[acv]: https://github.com/posquit0/Awesome-CV\n[ftt]: https://github.com/fresh-standard/fresh-test-themes\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing\n============\n\n*Note: HackMyResume is also available as [FluentCV][fcv]. Contributors are\ncredited in both.*\n\n## How To Contribute\n\n*See [BUILDING.md][building] for instructions on setting up a HackMyResume\ndevelopment environment.*\n\n1. Optional: [**open an issue**][iss] identifying the feature or bug you'd like\nto implement or fix. This step isn't required — you can start hacking away on\nHackMyResume without clearing it with us — but helps avoid duplication of work\nand ensures that your changes will be accepted once submitted.\n2. **Fork and clone** the HackMyResume project.\n3. Ideally, **create a new feature branch** (eg, `feat/new-awesome-feature` or\nsimilar; call it whatever you like) to perform your work in.\n4. **Install dependencies** by running `npm install` in the top-level\nHackMyResume folder.\n5. Make your **commits** as usual.\n6. **Verify** your changes locally with `grunt test`.\n7. **Push** your commits.\n7. **Submit a pull request** from your feature branch to the HackMyResume `dev`\nbranch.\n8. We'll typically **respond** within 24 hours.\n9. Your awesome changes will be **merged** after verification.\n\n## Project Maintainers\n\nHackMyResume is currently maintained by [hacksalot][ha] with assistance from\n[tomheon][th] and our awesome [contributors][awesome]. Please direct all official\nor internal inquiries to:\n\n```\nadmin@fluentdesk.com\n```\n\nYou can reach hacksalot directly at:\n\n```\nhacksalot@indevious.com\n```\n\nThanks for your interest in the HackMyResume project.\n\n[fcv]: https://github.com/fluentdesk/fluentcv\n[flow]: https://guides.github.com/introduction/flow/\n[iss]: https://github.com/hacksalot/HackMyResume/issues\n[ha]: https://github.com/hacksalot\n[th]: https://github.com/tomheon\n[awesome]: https://github.com/hacksalot/HackMyResume/graphs/contributors\n[building]: https://github.com/hacksalot/HackMyResume/blob/master/BUILDING.md\n"
  },
  {
    "path": "FAQ.md",
    "content": "Frequently Asked Questions (FAQ)\n================================\n\n## How do I get started with HackMyResume?\n\n1. Install with NPM: `[sudo] npm install hackmyresume -g`.\n\n2. Create a new resume with: `hackmyresume NEW <resume-name>.json`.\n\n3. Test with `hackmyresume BUILD <resume-name>.json`. Look in the `out/` folder.\n\n4. Play around with different themes with the `-t` or `--theme` parameter.\nYou can use any [FRESH](https://github.com/fluentdesk/fresh-themes) or\n[JSON Resume](https://jsonresume.org/themes) theme. The latter have to be\ninstalled first.\n\n## What is FRESH?\n\nFRESH is the **F**luent **R**esume and **E**mployment **S**ystem for **H**umans.\nIt's an open-source, user-first workflow, schema, and set of practices for\ntechnical candidates and recruiters.\n\n## What is FRESCA?\n\nThe **F**RESH **R**esume and **E**mployment **SC**hem**A**&mdash;an open-source,\nJSON-driven schema for resumes, CVs, and other employment artifacts. FRESCA is\nthe recommended schema/format for FRESH, with optional support for JSON Resume.\n\n## What is JSON Resume?\n\nAn [open resume standard](http://jsonresume.org/themes/) sponsored by Hired.com.\nLike FRESCA, JSON Resume is JSON-driven and open-source. Unlike FRESCA, JSON\nResume targets a worldwide audience where FRESCA is optimized for technical\ncandidates.\n\n## Should I use the FRESH or JSON Resume format/schema for my resume?\n\nBoth! The workflow we like to use:\n\n1. Create a resume in FRESH format for tooling and analysis.\n2. Convert it to JSON Resume format for additional themes/tools.\n3. Maintain both versions.\n\nBoth formats are open-source and both formats are JSON-driven. FRESH was\ndesigned as a universal container format and superset of existing formats, where\nthe JSON Resume format is intended for a generic audience.\n\n## How do I use a FRESH theme?\n\nSeveral FRESH themes come preinstalled with HackMyResume; others can be\ninstalled from NPM and GitHub.\n\n### To use a preinstalled FRESH theme:\n\n1. Pass the theme name into HackMyResume via the `--theme` or `-t` parameter:\n\n    ```bash\n    hackmyresume build resume.json --theme compact\n    ```\n\n### To use an external FRESH theme:\n\n1. Install the theme locally. The easiest way to do that is with NPM.\n\n    ```bash\n    npm install fresh-theme-underscore\n    ```\n\n2. Pass the theme folder into HackMyResume:\n\n    ```bash\n    hackmyresume BUILD resume.json --theme node_modules/fresh-theme-underscore\n    ```\n\n3. Check your output folder. It's best to view HTML formats over a local web\nserver connection.\n\n## How do I use a JSON Resume theme?\n\nJSON Resume (JRS) themes can be installed from NPM and GitHub and passed into\nHackMyResume via the `--theme` or `-t` parameter.\n\n1. Install the theme locally. The easiest way to do that is with NPM.\n\n    ```bash\n    npm install jsonresume-theme-classy\n    ```\n\n2. Pass the theme folder path into HackMyResume:\n\n    ```bash\n    hackmyresume BUILD resume.json --theme node_modules/jsonresume-theme-classy\n    ```\n\n3. Check your output folder. It's best to view HTML formats over a local web\nserver connection.\n\n## Should I keep my resume in version control?\n\nAbsolutely! As text-based, JSON-driven documents, both FRESH and JSON Resume are\nideal candidates for version control. Future versions of HackMyResume will have\nthis functionality built in.\n\n## Can I change the default section titles (\"Employment\", \"Skills\", etc.)?\n\nIf you're using a FRESH theme, yes. First, create a HackMyResume options file\nmapping resume sections to your preferred section title:\n\n```javascript\n// myoptions.json\n{\n  \"sectionTitles\": {\n    \"employment\": \"empleo\",\n    \"skills\": \"habilidades\",\n    \"education\": \"educación\"\n  }\n}\n```\n\nThen, pass the options file into the `-o` or `--opts` parameter:\n\n```bash\nhackmyresume BUILD resume.json -o myoptions.json\n```\n\nThis ability is currently only supported for FRESH resume themes.\n\n## How does resume merging work?\n\nResume merging is a way of storing your resume in separate files that\nHackMyResume will merge into a single \"master\" resume file prior to generating\nspecific output formats like HTML or PDF. It's a way of producing flexible,\nconfigurable, targeted resumes with minimal duplication.\n\nFor example, a software developer who moonlights as a game programmer might\ncreate three FRESH or JRS resumes at different levels of specificity:\n\n- **generic.json**: A generic technical resume, suitable for all audiences.\n- **game-developer.json**: Overrides and amendments for game developer\npositions.\n- **blizzard.json**: Overrides and amendments specific to a hypothetical\nposition at Blizzard.\n\nIf you run `hackmyresume BUILD generic.json TO out/resume.all`, HMR will\ngenerate all available output formats for the `generic.json` as usual. But if\nyou instead run...\n\n```bash\nhackmyresume BUILD generic.json game-developer.json TO out/resume.all\n```\n\n...HackMyResume will notice that multiple source resumes were specified and\nmerge `game-developer.json` onto `generic.json` before generating, yielding a\nresume that's more suitable for game-developer-related positions.\n\nYou can take this a step further. Let's say you want to do a targeted resume\nsubmission to a game developer position at Blizzard, and `blizzard.json`\ncontains the edits and revisions you'd like to show up in the targeted resume.\nIn that case, merge again! Feed all three resumes to HackMyResume, in order\nfrom most generic to most specific, and HMR will merge them all prior to\ngenerating the final output format(s) for your resume.\n\n```bash\n# Merge blizzard.json onto game-developer.json onto generic.json, then build\nhackmyresume BUILD generic.json game-developer.json blizzard.json TO out/resume.all\n```\n\nThere's no limit to the number of resumes you can merge this way.\n\nYou can also divide your resume into files containing different sections:\n\n- **resume-a.json**: Contains `info`, `employment`, and `summary` sections.\n- **resume-b.json**: Contains all other sections except `references`.\n- **references.json**: Contains the private `references` section.\n\nUnder that scenario, `hackmyresume BUILD resume-a.json resume-b.json` would\n\n\n## The HackMyResume terminal color scheme is giving me a headache. Can I disable it?\n\nYes. Use the `--no-color` option to disable terminal colors:\n\n`hackmyresume <somecommand> <someoptions> --no-color`\n\n## What's the difference between a FRESH theme and a JSON Resume theme?\n\nFRESH themes are multiformat (HTML, Word, PDF, etc.) and required to support\nMarkdown formatting, configurable section titles, and various other features.\n\nJSON Resume themes are typically HTML-driven, but capable of expansion to other\nformats through tools. JSON Resume themes don't support Markdown natively, but\nHMR does its best to apply your Markdown, when present, to any JSON Resume\nthemes it encounters.\n\n## Do I have to have a FRESH resume to use a FRESH theme or a JSON Resume to use a JSON Resume theme?\n\nNo. You can mix and match FRESH and JRS-format themes freely. HackMyResume will\nperform the necessary conversions on the fly.\n\n## Can I build my own custom FRESH theme?\n\nYes. The easiest way is to copy an existing FRESH theme, like `modern` or\n`compact`, and make your changes there. You can test your theme with:\n\n```bash\nhackmyresume build resume.json --theme path/to/my/theme/folder\n```\n\n## Can I build my own custom JSON Resume theme?\n\nYes. The easiest way is to copy an existing JSON Rsume theme and make your\nchanges there. You can test your theme with:\n\n```bash\nhackmyresume build resume.json --theme path/to/my/theme/folder\n```\n\n## Can I build my own tools / services / apps / websites around FRESH / FRESCA?\n\nYes! FRESH/FRESCA formats are 100% open source, permissively licensed under MIT,\nand 100% free from company-specific, tool-specific, or commercially oriented\nlock-in or cruft. These are clean formats designed for users and builders.\n\n## Can I build my own tools / services / apps / websites around JSON Resume?\n\nYes! HackMyResume is not affiliated with JSON Resume, but like FRESH/FRESCA,\nJSON Resume is open-source, permissively licensed, and free of proprietary\nlock-in. See the JSON Resume website for details.\n"
  },
  {
    "path": "Gruntfile.js",
    "content": "module.exports = function (grunt) {\n\n  'use strict';\n\n  var opts = {\n\n    pkg: grunt.file.readJSON('package.json'),\n\n    simplemocha: {\n      options: {\n        globals: ['expect', 'should'],\n        timeout: 3000,\n        ignoreLeaks: false,\n        ui: 'bdd',\n        reporter: 'spec'\n      },\n      all: { src: ['test/*.js'] }\n    },\n\n    clean: {\n      test: ['test/sandbox']\n    },\n\n    eslint: {\n      target: ['Gruntfile.js', 'src/**/*.js', 'test/*.js']\n    }\n\n  };\n\n  grunt.initConfig( opts );\n  grunt.loadNpmTasks('grunt-simple-mocha');\n  grunt.loadNpmTasks('grunt-eslint');\n  grunt.loadNpmTasks('grunt-contrib-clean');\n\n  // Use 'grunt test' for local testing\n  grunt.registerTask('test', 'Test the HackMyResume application.',\n    function() {\n      grunt.task.run(['clean:test','build','eslint','simplemocha:all']);\n    }\n  );\n\n  // Use 'grunt build' to build HMR\n  grunt.registerTask('build', 'Build the HackMyResume application.',\n    function() {\n      grunt.task.run( ['eslint'] );\n    }\n  );\n\n  // Default task does everything\n  grunt.registerTask('default', [ 'test' ]);\n\n};\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License\n===============\n\nCopyright (c) 2015-2018 hacksalot (https://github.com/hacksalot)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "HackMyResume\n===\n\n[![Latest release][img-release]][latest-release]\n[![Build status (MASTER)][img-master]][travis-url-master]\n[![Build status (DEV)][img-dev]][travis-url-dev]\n[![Join the chat at https://gitter.im/hacksalot/HackMyResume][badge]][gh]\n\n*Create polished résumés and CVs in multiple formats from your command line or\nshell. Author in clean Markdown and JSON, export to Word, HTML, PDF, LaTeX,\nplain text, and other arbitrary formats. Fight the power, save trees. Compatible\nwith [FRESH][fresca] and [JRS][6] resumes.*\n\n![](assets/hmr_build.png)\n\nHackMyResume is a dev-friendly, local-only Swiss Army knife for resumes and CVs.\nUse it to:\n\n1. **Generate** HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML,\nYAML, print, smoke signal, carrier pigeon, and other arbitrary-format resumes\nand CVs, from a single source of truth&mdash;without violating DRY.\n2. **Analyze** your resume for keyword density, gaps/overlaps, and other\nmetrics.\n3. **Convert** resumes between [FRESH][fresca] and [JSON Resume][6] formats.\n4. **Validate** resumes against either format.\n\nHackMyResume is built with Node.js and runs on recent versions of OS X, Linux,\nor Windows. View the [FAQ](FAQ.md).\n\n![](assets/hmr_analyze.png)\n\n## Features\n\n- OS X, Linux, and Windows.\n- Choose from dozens of FRESH or JSON Resume themes.\n- Private, local-only resume authoring and analysis.\n- Analyze your resume for keywords, gaps, and other metrics.\n- Store your resume data as a durable, versionable JSON or YAML document.\n- Generate polished resumes in multiple formats without violating [DRY][dry].\n- Output to HTML, Markdown, LaTeX, PDF, MS Word, JSON, YAML, plain text, or XML.\n- Validate resumes against the FRESH or JSON Resume schema.\n- Support for multiple input and output resumes.\n- Convert between FRESH and JSON Resume resumes.\n- Use from your command line or [desktop][7].\n- Free and open-source through the MIT license.\n- Updated daily / weekly. Contributions are [welcome](CONTRIBUTING.md).\n\n## Install\n\nInstall the latest stable version of HackMyResume with NPM:\n\n```bash\n[sudo] npm install hackmyresume -g\n```\n\nAlternately, install the latest bleeding-edge version (updated daily):\n\n```bash\n[sudo] npm install hacksalot/hackmyresume#dev -g\n```\n\n## Installing PDF Support (optional)\n\nHackMyResume tries not to impose a specific PDF engine requirement on\nthe user, but will instead work with whatever PDF engines you have installed.\n\nCurrently, HackMyResume's PDF generation requires one of [Phantom.js][2],\n[wkhtmltopdf][3], or [WeasyPrint][11] to be installed on your system and the\ncorresponding binary to be accessible on your PATH. This is an optional\nrequirement for users who care about PDF formats. If you don't care about PDF\nformats, skip this step.\n\n## Installing Themes\n\nHackMyResume supports both [FRESH][fresh-themes] and [JSON Resume][jrst]-style\nrésumé themes.\n\n- FRESH themes currently come preinstalled with HackMyResume.\n- JSON Resume themes can be installed from NPM, GitHub, or manually.\n\nTo install a JSON Resume theme, just `cd` to the folder where you want to store\nyour themes and run one of:\n\n```bash\n# Install with NPM\nnpm install jsonresume-theme-[theme-name]\n\n# Install with GitHub\ngit clone https://github.com/[user-or-org]/[repo-name]\n```\n\nThen when you're ready to generate your resume, just reference the location of\nthe theme folder as you installed it:\n\n```bash\nhackmyresume build resume.json TO out/resume.all -t node_modules/jsonresume-theme-classy\n```\n\nNote: You can use install themes anywhere on your file system. You don't need a\npackage.json or other NPM/Node infrastructure.\n\n## Getting Started\n\nTo use HackMyResume you'll need to create a valid resume in either\n[FRESH][fresca] or [JSON Resume][6] format. Then you can start using the command\nline tool. There are five basic commands you should be aware of:\n\n- **build** generates resumes in HTML, Word, Markdown, PDF, and other formats.\nUse it when you need to submit, upload, print, or email resumes in specific\nformats.\n\n    ```bash\n    # hackmyresume build <INPUTS...> TO <OUTPUTS...> [-t THEME]\n    hackmyresume build resume.json TO out/resume.all\n    hackmyresume build r1.json r2.json TO out/rez.html out/rez.md foo/rez.all\n    ```\n\n- **new** creates a new resume in FRESH or JSON Resume format.\n\n    ```bash\n    # hackmyresume new <OUTPUTS...> [-f <FORMAT>]\n    hackmyresume new resume.json\n    hackmyresume new resume.json -f fresh\n    hackmyresume new r1.json r2.json -f jrs\n    ```\n\n- **analyze** inspects your resume for keywords, duration, and other metrics.\n\n    ```bash\n    # hackmyresume analyze <INPUTS...>\n    hackmyresume analyze resume.json\n    hackmyresume analyze r1.json r2.json\n    ```\n\n- **convert** converts your source resume between FRESH and JSON Resume\nformats. Use it to convert between the two formats to take advantage of tools\nand services.\n\n    ```bash\n    # hackmyresume convert <INPUTS...> TO <OUTPUTS...>\n    hackmyresume convert resume.json TO resume-jrs.json\n    hackmyresume convert 1.json 2.json 3.json TO out/1.json out/2.json out/3.json\n    ```\n\n- **validate** validates the specified resume against either the FRESH or JSON\nResume schema. Use it to make sure your resume data is sufficient and complete.\n\n    ```bash\n    # hackmyresume validate <INPUTS...>\n    hackmyresume validate resume.json\n    hackmyresume validate r1.json r2.json r3.json\n    ```\n\n- **peek** echoes your resume or any field, property, or object path on your\nresume to standard output.\n\n    ```bash\n    # hackmyresume peek <INPUTS...> [OBJECT-PATH]\n    hackmyresume peek rez.json # Echo the whole resume\n    hackmyresume peek rez.json info.brief # Echo the \"info.brief\" field\n    hackmyresume peek rez.json employment.history[1] # Echo the 1st job\n    hackmyresume peek rez.json rez2.json info.brief # Compare value\n    ```    \n\n## Supported Output Formats\n\nHackMyResume supports these output formats:\n\nOutput Format | Ext | Notes\n------------- | --- | -----\nHTML | .html | A standard HTML 5 + CSS resume format that can be viewed in a browser, deployed to a website, etc.\nMarkdown | .md | A structured Markdown document that can be used as-is or used to generate HTML.\nLaTeX | .tex | A structured LaTeX document (or collection of documents) that can be processed with pdflatex, xelatex, and similar tools.\nMS Word | .doc | A Microsoft Word office document (XML-driven; WordProcessingML).\nAdobe Acrobat (PDF) | .pdf | A binary PDF document driven by an HTML theme (through wkhtmltopdf).\nplain text | .txt | A formatted plain text document appropriate for emails or copy-paste.\nJSON | .json | A JSON representation of the resume.\nYAML | .yml | A YAML representation of the resume.\nRTF | .rtf | Forthcoming.\nTextile | .textile | Forthcoming.\nimage | .png, .bmp | Forthcoming.\n\n## Use\n\nAssuming you've got a JSON-formatted resume handy, generating resumes in\ndifferent formats and combinations is easy. Just run:\n\n```bash\nhackmyresume build <inputs> to <outputs> [-t theme].\n```\n\nWhere `<INPUTS>` is one or more .json resume files, separated by spaces;\n`<OUTPUTS>` is one or more destination resumes, and `<THEME>` is the desired\ntheme (default to Modern). For example:\n\n```bash\n# Generate all resume formats (HTML, PDF, DOC, TXT, YML, etc.)\nhackmyresume build resume.json TO out/resume.all -t modern\n\n# Generate a specific resume format\nhackmyresume build resume.json TO out/resume.html\nhackmyresume build resume.json TO out/resume.pdf\nhackmyresume build resume.json TO out/resume.md\nhackmyresume build resume.json TO out/resume.doc\nhackmyresume build resume.json TO out/resume.json\nhackmyresume build resume.json TO out/resume.txt\nhackmyresume build resume.json TO out/resume.yml\n\n# Specify 2 inputs and 3 outputs\nhackmyresume build in1.json in2.json TO out.html out.doc out.pdf\n```\n\nYou should see something to the effect of:\n\n```\n*** HackMyResume v1.4.0 ***\nReading JSON resume: foo/resume.json\nApplying MODERN Theme (7 formats)\nGenerating HTML resume: out/resume.html\nGenerating TXT resume: out/resume.txt\nGenerating DOC resume: out/resume.doc\nGenerating PDF resume: out/resume.pdf\nGenerating JSON resume: out/resume.json\nGenerating MARKDOWN resume: out/resume.md\nGenerating YAML resume: out/resume.yml\n```\n\n## Advanced\n\n### Applying a theme\n\nHackMyResume can work with any FRESH or JSON Resume theme (the latter must be\ninstalled first). To specify a theme when generating your resume, use the `-t`\nor `--theme` parameter:\n\n```bash\nhackmyresume build resume.json TO out/rez.all -t [theme]\n```\n\nThe `[theme]` parameter can be the name of a predefined theme OR the path to any\nFRESH or JSON Resume theme folder:\n\n```bash\nhackmyresume build resume.json TO out/rez.all -t modern\nhackmyresume build resume.json TO OUT.rez.all -t ../some-folder/my-custom-theme/\nhackmyresume build resume.json TO OUT.rez.all -t node_modules/jsonresume-theme-classy\n```\n\nFRESH themes are currently pre-installed with HackMyResume. JSON Resume themes\ncan be installed prior to use:\n\n```bash\n# Install a JSON Resume theme into a local node_modules subfolder:\nnpm install jsonresume-theme-[name]\n# Use it with HackMyResume\nhackmyresume build resume.json -t node_modules/jsonresume-theme-[name]\n```\n\nAs of v1.6.0, available predefined FRESH themes are `positive`, `modern`,\n`compact`, `minimist`, and `hello-world`. For a list of JSON Resume themes,\ncheck the [NPM Registry](https://www.npmjs.com/search?q=jsonresume-theme).\n\n### Merging resumes\n\nYou can **merge multiple resumes together** by specifying them in order from\nmost generic to most specific:\n\n```bash\n# Merge specific.json onto base.json and generate all formats\nhackmyresume build base.json specific.json TO resume.all\n```\n\nThis can be useful for overriding a base (generic) resume with information from\na specific (targeted) resume. For example, you might override your generic\ncatch-all \"software developer\" resume with specific details from your targeted\n\"game developer\" resume, or combine two partial resumes into a \"complete\"\nresume. Merging follows conventional [extend()][9]-style behavior and there's\nno arbitrary limit to how many resumes you can merge:\n\n```bash\nhackmyresume build in1.json in2.json in3.json in4.json TO out.html out.doc\nReading JSON resume: in1.json\nReading JSON resume: in2.json\nReading JSON resume: in3.json\nReading JSON resume: in4.json\nMerging in4.json onto in3.json onto in2.json onto in1.json\nGenerating HTML resume: out.html\nGenerating WORD resume: out.doc\n```\n\n### Multiple targets\n\nYou can specify **multiple output targets** and HackMyResume will build them:\n\n```bash\n# Generate out1.doc, out1.pdf, and foo.txt from me.json.\nhackmyresume build me.json TO out1.doc out1.pdf foo.txt\n```\n\n### Using .all\n\nThe special `.all` extension tells HackMyResume to generate all supported output\nformats for the given resume. For example, this...\n\n```bash\n# Generate all resume formats (HTML, PDF, DOC, TXT, etc.)\nhackmyresume build me.json TO out/resume.all\n```\n\n..tells HackMyResume to read `me.json` and generate `out/resume.md`,\n`out/resume.doc`, `out/resume.html`, `out/resume.txt`, `out/resume.pdf`, and\n`out/resume.json`.\n\n### Building PDFs\n\n*Users who don't care about PDFs can turn off PDF generation across all themes\nand formats with the `--pdf none` switch.*\n\nHackMyResume takes a unique approach to PDF generation. Instead of enforcing\na specific PDF engine on users, HackMyResume will attempt to work with whatever\nPDF engine you have installed through the engine's command-line interface (CLI).\nCurrently that means any of...\n\n- [wkhtmltopdf][3]\n- [Phantom.js][2]\n- [WeasyPrint][11]\n\n..with support for other engines planned in the future. But for now, **one or\nmore of these engines must be installed and accessible on your PATH in order\nto generate PDF resumes with HackMyResume**. That means you should be able to\ninvoke either of these tools directly from your shell or terminal without error:\n\n```bash\nwkhtmltopdf input.html output.pdf\nphantomjs script.js input.html output.pdf\nweasyprint input.html output.pdf\n```\n\nAssuming you've installed one or both of these engines on your system, you can\ntell HackMyResume which flavor of PDF generation to use via the `--pdf` option\n(`-p` for short):\n\n```bash\nhackmyresume build resume.json TO out.all --pdf phantom\nhackmyresume build resume.json TO out.all --pdf wkhtmltopdf\nhackmyresume build resume.json TO out.all --pdf weasyprint\nhackmyresume build resume.json TO out.all --pdf none\n```\n\n### Analyzing\n\nHackMyResume can analyze your resume for keywords, employment gaps, and other\nmetrics. Run:\n\n```bash\nhackmyresume analyze <my-resume>.json\n```\n\nDepending on the HackMyResume version, you should see output similar to:\n\n\n```\n*** HackMyResume v1.6.0 ***\nReading resume: resume.json\nAnalyzing FRESH resume: resume.json\n\nSECTIONS (10):\n\n        employment:    12\n         education:     2\n           service:     1\n            skills:     8\n           writing:     1\n       recognition:     0\n            social:     4\n         interests:     2\n        references:     1\n         languages:     2\n\nCOVERAGE (61.1%):\n\n        Total Days:  6034\n          Employed:  3688\n              Gaps:     8  [31, 1065, 273, 153, 671, 61, 61, 31]\n          Overlaps:     1  [243]\n\nKEYWORDS (61):\n\n           Node.js:     6 mentions\n        JavaScript:     9 mentions\n        SQL Server:     3 mentions\n     Visual Studio:     6 mentions\n           Web API:     1 mentions\n   N-tier / 3-tier:     1 mentions\n            HTML 5:     1 mentions\n        JavaScript:     6 mentions\n               CSS:     2 mentions\nSass / LESS / SCSS:     1 mentions\n              LAMP:     3 mentions\n              WISC:     1 mentions\n              HTTP:    21 mentions\n              JSON:     1 mentions\n               XML:     2 mentions\n              REST:     1 mentions\n        WebSockets:     2 mentions\n       Backbone.js:     3 mentions\n        Angular.js:     1 mentions\n           Node.js:     4 mentions\n               NPM:     1 mentions\n             Bower:     1 mentions\n             Grunt:     2 mentions\n              Gulp:     1 mentions\n            jQuery:     2 mentions\n         Bootstrap:     3 mentions\n     Underscore.js:     1 mentions\n         PhantomJS:     1 mentions\n      CoffeeScript:     1 mentions\n            Python:    11 mentions\n              Perl:     4 mentions\n               PHP:     7 mentions\n             MySQL:    12 mentions\n        PostgreSQL:     4 mentions\n             NoSQL:     2 mentions\n            Apache:     2 mentions\n               AWS:     2 mentions\n               EC2:     2 mentions\n               RDS:     3 mentions\n                S3:     1 mentions\n             Azure:     1 mentions\n         Rackspace:     1 mentions\n               C++:    23 mentions\n            C++ 11:     1 mentions\n             Boost:     1 mentions\n             Xcode:     2 mentions\n               gcc:     1 mentions\n             OO&AD:     1 mentions\n              .NET:    20 mentions\n           Unity 5:     2 mentions\n              Mono:     3 mentions\n       MonoDevelop:     1 mentions\n           Xamarin:     1 mentions\n             TOTAL:   180 mentions\n```\n\n### Validating\n\nHackMyResume can also validate your resumes against either the [FRESH /\nFRESCA][fresca] or [JSON Resume][6] formats. To validate one or more existing\nresumes, use the `validate` command:\n\n```bash\n# Validate myresume.json against either the FRESH or JSON Resume schema.\nhackmyresume validate resumeA.json resumeB.json\n```\n\nHackMyResume will validate each specified resume in turn:\n\n```bash\n*** HackMyResume v1.6.0 ***\nValidating JSON resume: resumeA.json (INVALID)\nValidating JSON resume: resumeB.json (VALID)\n```\n\n### Converting\n\nHackMyResume can convert between the [FRESH][fresca] and [JSON Resume][6]\nformats. Just run:\n\n```bash\nhackmyresume convert <INPUTS> <OUTPUTS>\n```\n\nwhere <INPUTS> is one or more resumes in FRESH or JSON Resume format, and\n<OUTPUTS> is a corresponding list of output file names. HackMyResume will\nautodetect the format (FRESH or JRS) of each input resume and convert it to the\nother format (JRS or FRESH).\n\n### File-based Options\n\nYou can pass options into HackMyResume via an external options or \".hackmyrc\"\nfile with the `--options` or `-o` switch:\n\n```bash\nhackmyresume build resume.json -o path/to/options.json\n```\n\nThe options file can contain any documented HackMyResume option, including\n`theme`, `silent`, `debug`, `pdf`, `css`, and other settings.\n\n```json\n{\n  \"theme\": \"compact\",\n\n  \"sectionTitles\": {\n    \"employment\": \"Work\"\n  },\n\n  \"wkhtmltopdf\": {\n    \"margin-top\": \"20mm\"\n  }\n}\n```\n\nIf an option is specified on both the command line and in an external options\nfile, the command-line option wins.\n\n```bash\n# path/to/options.json specifes the POSITIVE theme\n# -t parameter specifies the COMPACT theme\n# The -t parameter wins.\nhackmyresume build resume.json -o path/to/options.json -t compact\n> Reading resume: resume.json\n> Applying COMPACT theme (7 formats)\n```\n\n### Prettifying\n\nHackMyResume applies [js-beautify][10]-style HTML prettification by default to\nHTML-formatted resumes. To disable prettification, the `--no-prettify` or `-n`\nflag can be used:\n\n```bash\nhackmyresume build resume.json out.all --no-prettify\n```\n\n### Silent Mode\n\nUse `-s` or `--silent` to run in silent mode:\n\n```bash\nhackmyresume build resume.json -o someFile.all -s\nhackmyresume build resume.json -o someFile.all --silent\n```\n\n### Debug Mode\n\nUse `-d` or `--debug` to force HMR to emit a call stack when errors occur. In\nthe future, this option will emit detailed error logging.\n\n```bash\nhackmyresume build resume.json -d\nhackmyresume analyze resume.json --debug\n```\n\n### Disable Encoding\n\nUse the `--no-escape` option to disable encoding in Handlebars themes. Note:\nthis option has no effect for non-Handlebars themes.\n\n```bash\nhackmyresume build resume.json --no-escape\n```\n\n### Private Resume Fields\n\nHave a gig, education stint, membership, or other relevant history that you'd\nlike to hide from *most* (e.g. public) resumes but sometimes show on others? Tag it with\n`\"private\": true` to omit it from outbound generated resumes by default.\n\n\n```json\n\"employment\": {\n  \"history\": [\n    {\n      \"employer\": \"Acme Real Estate\"\n    },\n    {\n      \"employer\": \"Area 51 Alien Research Laboratory\",\n      \"private\": true\n    },\n    {\n      \"employer\": \"H&R Block\"\n    }\n  ]\n}\n```\n\nThen, when you want a copy of your resume that includes the private gig / stint\n/ etc., tell HackMyResume that it's OK to emit private fields. The way you do\nthat is with the `--private` switch.\n\n```bash\nhackmyresume build resume.json private-resume.all --private\n```\n\n\n### Custom theme helpers\n\nYou can attach your own custom Handlebars helpers to a FRESH theme with the\n`helpers` key of your theme's `theme.json` file.\n\n```js\n{\n  \"title\": \"my-cool-theme\",\n\n  // ...\n\n  \"helpers\": [\n    \"../path/to/helpers/*.js\",\n    \"some-other-helper.js\"\n  ]\n}\n```\n\nHackMyResume will attempt to load each path or glob and register any specified\nfiles with [Handlebars.registerHelper][hrh], making them available to your\ntheme.\n\n\n## Contributing\n\nHackMyResume is a community-driven free and open source project under the MIT\nLicense. Contributions are encouraged and we respond to all PRs and issues in\ntime. See [CONTRIBUTING.md][contribute] for details.\n\n## License\n\nMIT. Go crazy. See [LICENSE.md][1] for details.\n\n[1]: LICENSE.md\n[2]: http://phantomjs.org/\n[3]: http://wkhtmltopdf.org/\n[4]: https://nodejs.org/\n[5]: https://www.npmjs.com/\n[6]: http://jsonresume.org\n[7]: http://fluentcv.com\n[8]: https://youtu.be/N9wsjroVlu8\n[9]: https://api.jquery.com/jquery.extend/\n[10]: https://github.com/beautify-web/js-beautify\n[11]: http://weasyprint.org/\n[fresh]: https://github.com/fluentdesk/FRESH\n[fresca]: https://github.com/fresh-standard/fresh-resume-schema\n[dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself\n[img-release]: https://img.shields.io/github/release/hacksalot/HackMyResume.svg?label=version\n[img-master]: https://img.shields.io/travis/hacksalot/HackMyResume/master.svg\n[img-dev]: https://img.shields.io/travis/hacksalot/HackMyResume/dev.svg?label=dev\n[travis-url-master]: https://travis-ci.org/hacksalot/HackMyResume?branch=master\n[travis-url-dev]: https://travis-ci.org/hacksalot/HackMyResume?branch=dev\n[latest-release]: https://github.com/hacksalot/HackMyResume/releases/latest\n[contribute]: CONTRIBUTING.md\n[fresh-themes]: https://github.com/fluentdesk/fresh-themes\n[jrst]: https://www.npmjs.com/search?q=jsonresume-theme\n[gh]: https://gitter.im/hacksalot/HackMyResume?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n[badge]: https://badges.gitter.im/hacksalot/HackMyResume.svg\n[hrh]: http://handlebarsjs.com/reference.html#base-registerHelper\n"
  },
  {
    "path": "ROADMAP.md",
    "content": "Development Roadmap\n===================\n\n## Short-Term\n\n### FluentCV Desktop: Beta 1\n\nThe **FluentCV Desktop 1.0 beta release** will present HackMyResume\nfunctionality in a cross-platform desktop application for OS X, Linux, and\nWindows.\n\n### GitHub Integration\n\nHackMyResume will offer GitHub integration for versioned resume storage and\nretrieval via the `COMMIT` or `STORE` command(s) starting in 1.7.0 or 1.8.0.\n\n### fresh-themes 1.0.0\n\nThe **fresh-themes 1.0** release will bring 100% coverage of the FRESH and JRS\nobject models&mdash;all resume sections and fields&mdash;along with\ndocumentation, theme developer's guide, new themes, and a freeze to the FRESH\ntheme structure.\n\n### Better LaTeX support\n\nIncluding Markdown-to-LaTeX translation and more LaTeX-driven themes / formats.\n\n### StackOverflow and LinkedIn support\n\nWill start appearing in v1.7.0, with incremental improvements in 1.8.0 and\nbeyond.\n\n### Improved resume sorting and arranging\n\n**Better resume sorting** of items and sections: ascending, descending, by\ndate or other criteria ([#67][i67]).\n\n### Remote resume / theme loading\n\nSupport remote loading of themes and resumes over `http`, `https`, and\n`git://`. Enable these usage patterns:\n\n    ```bash\n    hackmyresume build https://somesite.com/my-resume.json -t informatic\n\n    hackmyresume build resume.json -t npm:fresh-theme-ergonomic\n\n    hackmyresume analyze https://github.com/foo/my-resume\n    ```\n\n### 100% code coverage\n\nShould reduce certain classes of errors and allow HMR to display a nifty 100%\ncode coverage badge.\n\n### Improved **documentation and samples**\n\nExpanded documentation and samples throughout.\n\n## Mid-Term\n\n### Cover letters and job descriptions\n\nAdd support for schema-driven **cover letters** and **job descriptions**.\n\n### Character Sheets\n\nHackMyResume 2.0 will ship with support for, yes, RPG-style character sheets.\nThis will demonstrate the tool's ability to flow arbitrary JSON to concrete\ndocument(s) and provide unique albeit niche functionality around various games\n([#117][i117]).\n\n### Rich text (.rtf) output formats\n\nBasic support for **rich text** `.rtf` output formats.\n\n### Investigate: groff support\n\nInvestigate adding [**groff**][groff] support, because that would, indeed, be\n[dope][d] ([#37][i37]).\n\n### Investigate: org-mode support\n\nInvestigate adding [**org mode**][om] support ([#38][i38]).\n\n### Investigate: Scribus\n\nInvestigate adding [**Scribus SLA**][scri] support ([#54][i54]).\n\n### Support JSON Resume 1.0.0\n\nWhen released.\n\n## Long-Term\n\n- TBD\n\n[groff]: http://www.gnu.org/software/groff/\n[om]: http://orgmode.org/\n[scri]: https://en.wikipedia.org/wiki/Scribus\n[d]: https://github.com/hacksalot/HackMyResume/issues/37#issue-123818674\n[i37]: https://github.com/hacksalot/HackMyResume/issues/37\n[i38]: https://github.com/hacksalot/HackMyResume/issues/38\n[i54]: https://github.com/hacksalot/HackMyResume/issues/54\n[i67]: https://github.com/hacksalot/HackMyResume/issues/67\n[i107]: https://github.com/hacksalot/HackMyResume/issues/107\n[i117]: https://github.com/hacksalot/HackMyResume/issues/117\n"
  },
  {
    "path": "assets/logo/hackmyresume-logo.ai",
    "content": "version https://git-lfs.github.com/spec/v1\noid sha256:a476ee59e7d86b5a7599780b5efca57ee6b6d60e1a722343277057ea793703b6\nsize 1642116\n"
  },
  {
    "path": "npm-shrinkwrap.json",
    "content": "{\n  \"name\": \"hackmyresume\",\n  \"version\": \"1.9.0-beta\",\n  \"dependencies\": {\n    \"abbrev\": {\n      \"version\": \"1.1.1\",\n      \"from\": \"abbrev@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz\",\n      \"dev\": true\n    },\n    \"acorn\": {\n      \"version\": \"5.4.1\",\n      \"from\": \"acorn@>=5.4.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/acorn/-/acorn-5.4.1.tgz\",\n      \"dev\": true\n    },\n    \"acorn-jsx\": {\n      \"version\": \"3.0.1\",\n      \"from\": \"acorn-jsx@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"acorn\": {\n          \"version\": \"3.3.0\",\n          \"from\": \"acorn@>=3.0.4 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"ajv\": {\n      \"version\": \"5.5.2\",\n      \"from\": \"ajv@>=5.3.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz\",\n      \"dev\": true\n    },\n    \"ajv-keywords\": {\n      \"version\": \"2.1.1\",\n      \"from\": \"ajv-keywords@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz\",\n      \"dev\": true\n    },\n    \"align-text\": {\n      \"version\": \"0.1.4\",\n      \"from\": \"align-text@>=0.1.3 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz\",\n      \"dependencies\": {\n        \"kind-of\": {\n          \"version\": \"3.2.2\",\n          \"from\": \"kind-of@>=3.0.2 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz\"\n        }\n      }\n    },\n    \"amdefine\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"amdefine@>=0.0.4\",\n      \"resolved\": \"https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz\"\n    },\n    \"ansi-escapes\": {\n      \"version\": \"3.0.0\",\n      \"from\": \"ansi-escapes@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz\",\n      \"dev\": true\n    },\n    \"ansi-green\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"ansi-green@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-green/-/ansi-green-0.1.1.tgz\"\n    },\n    \"ansi-regex\": {\n      \"version\": \"2.1.1\",\n      \"from\": \"ansi-regex@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz\",\n      \"dev\": true\n    },\n    \"ansi-styles\": {\n      \"version\": \"3.2.0\",\n      \"from\": \"ansi-styles@>=3.2.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz\"\n    },\n    \"ansi-wrap\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"ansi-wrap@0.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz\"\n    },\n    \"argparse\": {\n      \"version\": \"1.0.9\",\n      \"from\": \"argparse@>=1.0.7 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz\"\n    },\n    \"arr-union\": {\n      \"version\": \"3.1.0\",\n      \"from\": \"arr-union@>=3.1.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz\"\n    },\n    \"array-find-index\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"array-find-index@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"array-union\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"array-union@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"array-uniq\": {\n      \"version\": \"1.0.3\",\n      \"from\": \"array-uniq@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz\",\n      \"dev\": true\n    },\n    \"arrify\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"arrify@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"asn1\": {\n      \"version\": \"0.2.3\",\n      \"from\": \"asn1@>=0.2.3 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz\",\n      \"dev\": true\n    },\n    \"assert-plus\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"assert-plus@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"assertion-error\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"assertion-error@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"async\": {\n      \"version\": \"1.5.2\",\n      \"from\": \"async@>=1.4.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/async/-/async-1.5.2.tgz\"\n    },\n    \"async-array-reduce\": {\n      \"version\": \"0.2.1\",\n      \"from\": \"async-array-reduce@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/async-array-reduce/-/async-array-reduce-0.2.1.tgz\"\n    },\n    \"async-each\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"async-each@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz\"\n    },\n    \"asynckit\": {\n      \"version\": \"0.4.0\",\n      \"from\": \"asynckit@>=0.4.0 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz\",\n      \"dev\": true\n    },\n    \"aws-sign2\": {\n      \"version\": \"0.7.0\",\n      \"from\": \"aws-sign2@>=0.7.0 <0.8.0\",\n      \"resolved\": \"https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz\",\n      \"dev\": true\n    },\n    \"aws4\": {\n      \"version\": \"1.6.0\",\n      \"from\": \"aws4@>=1.6.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz\",\n      \"dev\": true\n    },\n    \"babel-code-frame\": {\n      \"version\": \"6.26.0\",\n      \"from\": \"babel-code-frame@>=6.22.0 <7.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"2.2.1\",\n          \"from\": \"ansi-styles@>=2.2.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz\",\n          \"dev\": true\n        },\n        \"chalk\": {\n          \"version\": \"1.1.3\",\n          \"from\": \"chalk@>=1.1.3 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"3.0.1\",\n          \"from\": \"strip-ansi@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"2.0.0\",\n          \"from\": \"supports-color@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"balanced-match\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"balanced-match@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz\"\n    },\n    \"bcrypt-pbkdf\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"bcrypt-pbkdf@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"bluebird\": {\n      \"version\": \"3.5.1\",\n      \"from\": \"bluebird@>=3.4.1 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz\"\n    },\n    \"blueimp-md5\": {\n      \"version\": \"2.10.0\",\n      \"from\": \"blueimp-md5@>=2.3.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.10.0.tgz\",\n      \"dev\": true\n    },\n    \"boom\": {\n      \"version\": \"4.3.1\",\n      \"from\": \"boom@>=4.0.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/boom/-/boom-4.3.1.tgz\",\n      \"dev\": true\n    },\n    \"brace-expansion\": {\n      \"version\": \"1.1.11\",\n      \"from\": \"brace-expansion@>=1.1.7 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz\"\n    },\n    \"browser-stdout\": {\n      \"version\": \"1.3.0\",\n      \"from\": \"browser-stdout@1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz\",\n      \"dev\": true\n    },\n    \"buffer-equal\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"buffer-equal@1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"builtin-modules\": {\n      \"version\": \"1.1.1\",\n      \"from\": \"builtin-modules@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz\",\n      \"dev\": true\n    },\n    \"caller-path\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"caller-path@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz\",\n      \"dev\": true\n    },\n    \"callsites\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"callsites@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz\",\n      \"dev\": true\n    },\n    \"camelcase\": {\n      \"version\": \"1.2.1\",\n      \"from\": \"camelcase@>=1.0.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz\",\n      \"optional\": true\n    },\n    \"camelcase-keys\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"camelcase-keys@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"camelcase\": {\n          \"version\": \"2.1.1\",\n          \"from\": \"camelcase@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"caseless\": {\n      \"version\": \"0.12.0\",\n      \"from\": \"caseless@>=0.12.0 <0.13.0\",\n      \"resolved\": \"https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz\",\n      \"dev\": true\n    },\n    \"center-align\": {\n      \"version\": \"0.1.3\",\n      \"from\": \"center-align@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz\",\n      \"optional\": true,\n      \"dependencies\": {\n        \"lazy-cache\": {\n          \"version\": \"1.0.4\",\n          \"from\": \"lazy-cache@>=1.0.3 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz\",\n          \"optional\": true\n        }\n      }\n    },\n    \"chai\": {\n      \"version\": \"4.1.2\",\n      \"from\": \"chai@*\",\n      \"resolved\": \"https://registry.npmjs.org/chai/-/chai-4.1.2.tgz\",\n      \"dev\": true\n    },\n    \"chai-as-promised\": {\n      \"version\": \"7.1.1\",\n      \"from\": \"chai-as-promised@>=7.1.1 <8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz\",\n      \"dev\": true\n    },\n    \"chalk\": {\n      \"version\": \"2.3.1\",\n      \"from\": \"chalk@>=2.3.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz\"\n    },\n    \"chardet\": {\n      \"version\": \"0.4.2\",\n      \"from\": \"chardet@>=0.4.0 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz\",\n      \"dev\": true\n    },\n    \"check-error\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"check-error@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"chownr\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"chownr@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"circular-json\": {\n      \"version\": \"0.3.3\",\n      \"from\": \"circular-json@>=0.3.1 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz\",\n      \"dev\": true\n    },\n    \"cli-cursor\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"cli-cursor@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"cli-width\": {\n      \"version\": \"2.2.0\",\n      \"from\": \"cli-width@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz\",\n      \"dev\": true\n    },\n    \"cliui\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"cliui@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz\",\n      \"optional\": true,\n      \"dependencies\": {\n        \"wordwrap\": {\n          \"version\": \"0.0.2\",\n          \"from\": \"wordwrap@0.0.2\",\n          \"resolved\": \"https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz\",\n          \"optional\": true\n        }\n      }\n    },\n    \"clone\": {\n      \"version\": \"1.0.3\",\n      \"from\": \"clone@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/clone/-/clone-1.0.3.tgz\"\n    },\n    \"clone-stats\": {\n      \"version\": \"0.0.1\",\n      \"from\": \"clone-stats@>=0.0.1 <0.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz\"\n    },\n    \"co\": {\n      \"version\": \"4.6.0\",\n      \"from\": \"co@>=4.6.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/co/-/co-4.6.0.tgz\",\n      \"dev\": true\n    },\n    \"code-point-at\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"code-point-at@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"coffeescript\": {\n      \"version\": \"1.10.0\",\n      \"from\": \"coffeescript@>=1.10.0 <1.11.0\",\n      \"resolved\": \"https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz\",\n      \"dev\": true\n    },\n    \"color-convert\": {\n      \"version\": \"1.9.1\",\n      \"from\": \"color-convert@>=1.9.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz\"\n    },\n    \"color-name\": {\n      \"version\": \"1.1.3\",\n      \"from\": \"color-name@>=1.1.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz\"\n    },\n    \"colors\": {\n      \"version\": \"1.0.3\",\n      \"from\": \"colors@1.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/colors/-/colors-1.0.3.tgz\",\n      \"dev\": true\n    },\n    \"combined-stream\": {\n      \"version\": \"1.0.5\",\n      \"from\": \"combined-stream@>=1.0.5 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz\",\n      \"dev\": true\n    },\n    \"commander\": {\n      \"version\": \"2.14.1\",\n      \"from\": \"commander@>=2.9.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-2.14.1.tgz\"\n    },\n    \"concat-map\": {\n      \"version\": \"0.0.1\",\n      \"from\": \"concat-map@0.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz\"\n    },\n    \"concat-stream\": {\n      \"version\": \"1.6.0\",\n      \"from\": \"concat-stream@>=1.4.7 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz\"\n    },\n    \"copy\": {\n      \"version\": \"0.3.1\",\n      \"from\": \"copy@>=0.3.1 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/copy/-/copy-0.3.1.tgz\"\n    },\n    \"core-util-is\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"core-util-is@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz\"\n    },\n    \"cross-spawn\": {\n      \"version\": \"5.1.0\",\n      \"from\": \"cross-spawn@>=5.1.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz\",\n      \"dev\": true\n    },\n    \"cryptiles\": {\n      \"version\": \"3.1.2\",\n      \"from\": \"cryptiles@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"boom\": {\n          \"version\": \"5.2.0\",\n          \"from\": \"boom@>=5.0.0 <6.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/boom/-/boom-5.2.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"currently-unhandled\": {\n      \"version\": \"0.4.1\",\n      \"from\": \"currently-unhandled@>=0.4.1 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz\",\n      \"dev\": true\n    },\n    \"dashdash\": {\n      \"version\": \"1.14.1\",\n      \"from\": \"dashdash@>=1.12.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz\",\n      \"dev\": true\n    },\n    \"dateformat\": {\n      \"version\": \"1.0.12\",\n      \"from\": \"dateformat@>=1.0.12 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz\",\n      \"dev\": true\n    },\n    \"debug\": {\n      \"version\": \"3.1.0\",\n      \"from\": \"debug@>=3.1.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-3.1.0.tgz\",\n      \"dev\": true\n    },\n    \"decamelize\": {\n      \"version\": \"1.2.0\",\n      \"from\": \"decamelize@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz\"\n    },\n    \"deep-eql\": {\n      \"version\": \"3.0.1\",\n      \"from\": \"deep-eql@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz\",\n      \"dev\": true\n    },\n    \"deep-is\": {\n      \"version\": \"0.1.3\",\n      \"from\": \"deep-is@>=0.1.3 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz\",\n      \"dev\": true\n    },\n    \"define-property\": {\n      \"version\": \"0.2.5\",\n      \"from\": \"define-property@>=0.2.5 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz\"\n    },\n    \"del\": {\n      \"version\": \"2.2.2\",\n      \"from\": \"del@>=2.0.2 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/del/-/del-2.2.2.tgz\",\n      \"dev\": true\n    },\n    \"delayed-stream\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"delayed-stream@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"diff\": {\n      \"version\": \"3.3.1\",\n      \"from\": \"diff@3.3.1\",\n      \"resolved\": \"https://registry.npmjs.org/diff/-/diff-3.3.1.tgz\",\n      \"dev\": true\n    },\n    \"dir-compare\": {\n      \"version\": \"1.4.0\",\n      \"from\": \"dir-compare@>=1.4.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/dir-compare/-/dir-compare-1.4.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"bluebird\": {\n          \"version\": \"3.4.1\",\n          \"from\": \"bluebird@3.4.1\",\n          \"resolved\": \"https://registry.npmjs.org/bluebird/-/bluebird-3.4.1.tgz\",\n          \"dev\": true\n        },\n        \"commander\": {\n          \"version\": \"2.9.0\",\n          \"from\": \"commander@2.9.0\",\n          \"resolved\": \"https://registry.npmjs.org/commander/-/commander-2.9.0.tgz\",\n          \"dev\": true\n        },\n        \"minimatch\": {\n          \"version\": \"3.0.2\",\n          \"from\": \"minimatch@3.0.2\",\n          \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"doctrine\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"doctrine@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"ecc-jsbn\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"ecc-jsbn@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"email-validator\": {\n      \"version\": \"1.1.1\",\n      \"from\": \"email-validator@>=1.0.7 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/email-validator/-/email-validator-1.1.1.tgz\",\n      \"dev\": true\n    },\n    \"error-ex\": {\n      \"version\": \"1.3.1\",\n      \"from\": \"error-ex@>=1.2.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz\",\n      \"dev\": true\n    },\n    \"escape-latex\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"escape-latex@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/escape-latex/-/escape-latex-1.0.0.tgz\"\n    },\n    \"escape-string-regexp\": {\n      \"version\": \"1.0.5\",\n      \"from\": \"escape-string-regexp@>=1.0.5 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz\"\n    },\n    \"eslint\": {\n      \"version\": \"4.17.0\",\n      \"from\": \"eslint@>=4.0.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint/-/eslint-4.17.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-regex\": {\n          \"version\": \"3.0.0\",\n          \"from\": \"ansi-regex@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz\",\n          \"dev\": true\n        },\n        \"esprima\": {\n          \"version\": \"4.0.0\",\n          \"from\": \"esprima@>=4.0.0 <5.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz\",\n          \"dev\": true\n        },\n        \"js-yaml\": {\n          \"version\": \"3.10.0\",\n          \"from\": \"js-yaml@>=3.9.1 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"4.0.0\",\n          \"from\": \"strip-ansi@>=4.0.0 <5.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"eslint-scope\": {\n      \"version\": \"3.7.1\",\n      \"from\": \"eslint-scope@>=3.7.1 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz\",\n      \"dev\": true\n    },\n    \"eslint-visitor-keys\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"eslint-visitor-keys@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"espree\": {\n      \"version\": \"3.5.3\",\n      \"from\": \"espree@>=3.5.2 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/espree/-/espree-3.5.3.tgz\",\n      \"dev\": true\n    },\n    \"esprima\": {\n      \"version\": \"2.7.3\",\n      \"from\": \"esprima@>=2.6.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz\",\n      \"dev\": true\n    },\n    \"esquery\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"esquery@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"esrecurse\": {\n      \"version\": \"4.2.0\",\n      \"from\": \"esrecurse@>=4.1.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz\",\n      \"dev\": true\n    },\n    \"estraverse\": {\n      \"version\": \"4.2.0\",\n      \"from\": \"estraverse@>=4.1.1 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz\",\n      \"dev\": true\n    },\n    \"esutils\": {\n      \"version\": \"2.0.2\",\n      \"from\": \"esutils@>=2.0.2 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz\",\n      \"dev\": true\n    },\n    \"eventemitter2\": {\n      \"version\": \"0.4.14\",\n      \"from\": \"eventemitter2@>=0.4.13 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz\",\n      \"dev\": true\n    },\n    \"exit\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"exit@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/exit/-/exit-0.1.2.tgz\",\n      \"dev\": true\n    },\n    \"expand-tilde\": {\n      \"version\": \"1.2.2\",\n      \"from\": \"expand-tilde@>=1.2.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz\"\n    },\n    \"extend\": {\n      \"version\": \"3.0.1\",\n      \"from\": \"extend@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/extend/-/extend-3.0.1.tgz\"\n    },\n    \"extend-shallow\": {\n      \"version\": \"2.0.1\",\n      \"from\": \"extend-shallow@>=2.0.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz\"\n    },\n    \"external-editor\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"external-editor@>=2.0.4 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"extsprintf\": {\n      \"version\": \"1.3.0\",\n      \"from\": \"extsprintf@1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz\",\n      \"dev\": true\n    },\n    \"fast-deep-equal\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"fast-deep-equal@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"fast-json-stable-stringify\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"fast-json-stable-stringify@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"fast-levenshtein\": {\n      \"version\": \"2.0.6\",\n      \"from\": \"fast-levenshtein@>=2.0.4 <2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz\",\n      \"dev\": true\n    },\n    \"figures\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"figures@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/figures/-/figures-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"file-contents\": {\n      \"version\": \"0.3.2\",\n      \"from\": \"file-contents@>=0.3.1 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/file-contents/-/file-contents-0.3.2.tgz\"\n    },\n    \"file-entry-cache\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"file-entry-cache@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"file-stat\": {\n      \"version\": \"0.2.3\",\n      \"from\": \"file-stat@>=0.2.3 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/file-stat/-/file-stat-0.2.3.tgz\"\n    },\n    \"file-sync-cmp\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"file-sync-cmp@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz\",\n      \"dev\": true\n    },\n    \"find-up\": {\n      \"version\": \"1.1.2\",\n      \"from\": \"find-up@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"path-exists\": {\n          \"version\": \"2.1.0\",\n          \"from\": \"path-exists@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"findup-sync\": {\n      \"version\": \"0.3.0\",\n      \"from\": \"findup-sync@>=0.3.0 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"glob\": {\n          \"version\": \"5.0.15\",\n          \"from\": \"glob@>=5.0.0 <5.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/glob/-/glob-5.0.15.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"flat-cache\": {\n      \"version\": \"1.3.0\",\n      \"from\": \"flat-cache@>=1.2.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz\",\n      \"dev\": true\n    },\n    \"forever-agent\": {\n      \"version\": \"0.6.1\",\n      \"from\": \"forever-agent@>=0.6.1 <0.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz\",\n      \"dev\": true\n    },\n    \"form-data\": {\n      \"version\": \"2.3.1\",\n      \"from\": \"form-data@>=2.3.1 <2.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz\",\n      \"dev\": true\n    },\n    \"fresh-jrs-converter\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"fresh-jrs-converter@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-jrs-converter/-/fresh-jrs-converter-1.0.0.tgz\"\n    },\n    \"fresh-resume-schema\": {\n      \"version\": \"1.0.0-beta\",\n      \"from\": \"fresh-resume-schema@>=1.0.0-beta <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-resume-schema/-/fresh-resume-schema-1.0.0-beta.tgz\"\n    },\n    \"fresh-resume-starter\": {\n      \"version\": \"0.3.1\",\n      \"from\": \"fresh-resume-starter@>=0.3.1 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-resume-starter/-/fresh-resume-starter-0.3.1.tgz\"\n    },\n    \"fresh-resume-validator\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"fresh-resume-validator@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-resume-validator/-/fresh-resume-validator-0.2.0.tgz\"\n    },\n    \"fresh-test-resumes\": {\n      \"version\": \"0.9.2\",\n      \"from\": \"fresh-test-resumes@>=0.9.2 <0.10.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-test-resumes/-/fresh-test-resumes-0.9.2.tgz\",\n      \"dev\": true\n    },\n    \"fresh-test-themes\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"fresh-test-themes@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-test-themes/-/fresh-test-themes-0.2.0.tgz\",\n      \"dev\": true\n    },\n    \"fresh-theme-hello-world\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"fresh-theme-hello-world@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-theme-hello-world/-/fresh-theme-hello-world-0.1.0.tgz\",\n      \"dev\": true\n    },\n    \"fresh-theme-underscore\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"fresh-theme-underscore@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-theme-underscore/-/fresh-theme-underscore-0.1.1.tgz\",\n      \"dev\": true\n    },\n    \"fresh-themes\": {\n      \"version\": \"0.17.0-beta\",\n      \"from\": \"fresh-themes@>=0.17.0-beta <0.18.0\",\n      \"resolved\": \"https://registry.npmjs.org/fresh-themes/-/fresh-themes-0.17.0-beta.tgz\"\n    },\n    \"fs-exists-sync\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"fs-exists-sync@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz\"\n    },\n    \"fs-extra\": {\n      \"version\": \"5.0.0\",\n      \"from\": \"fs-extra@>=5.0.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz\"\n    },\n    \"fs-minipass\": {\n      \"version\": \"1.2.5\",\n      \"from\": \"fs-minipass@>=1.2.3 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz\",\n      \"dev\": true\n    },\n    \"fs.realpath\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"fs.realpath@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz\"\n    },\n    \"functional-red-black-tree\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"functional-red-black-tree@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"generate-function\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"generate-function@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz\"\n    },\n    \"generate-object-property\": {\n      \"version\": \"1.2.0\",\n      \"from\": \"generate-object-property@>=1.1.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz\"\n    },\n    \"get-caller-file\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"get-caller-file@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"get-func-name\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"get-func-name@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"get-stdin\": {\n      \"version\": \"4.0.1\",\n      \"from\": \"get-stdin@>=4.0.1 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz\",\n      \"dev\": true\n    },\n    \"getobject\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"getobject@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz\",\n      \"dev\": true\n    },\n    \"getpass\": {\n      \"version\": \"0.1.7\",\n      \"from\": \"getpass@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz\",\n      \"dev\": true\n    },\n    \"glob\": {\n      \"version\": \"7.1.2\",\n      \"from\": \"glob@>=7.1.2 <8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.1.2.tgz\"\n    },\n    \"glob-parent\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"glob-parent@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz\"\n    },\n    \"global-modules\": {\n      \"version\": \"0.2.3\",\n      \"from\": \"global-modules@>=0.2.3 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz\"\n    },\n    \"global-prefix\": {\n      \"version\": \"0.1.5\",\n      \"from\": \"global-prefix@>=0.1.4 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz\"\n    },\n    \"globals\": {\n      \"version\": \"11.3.0\",\n      \"from\": \"globals@>=11.0.1 <12.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/globals/-/globals-11.3.0.tgz\",\n      \"dev\": true\n    },\n    \"globby\": {\n      \"version\": \"5.0.0\",\n      \"from\": \"globby@>=5.0.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/globby/-/globby-5.0.0.tgz\",\n      \"dev\": true\n    },\n    \"graceful-fs\": {\n      \"version\": \"4.1.11\",\n      \"from\": \"graceful-fs@>=4.1.4 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz\"\n    },\n    \"graceful-readlink\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"graceful-readlink@>=1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"gravatar\": {\n      \"version\": \"1.6.0\",\n      \"from\": \"gravatar@>=1.0.6 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/gravatar/-/gravatar-1.6.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"camelcase\": {\n          \"version\": \"3.0.0\",\n          \"from\": \"camelcase@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz\",\n          \"dev\": true\n        },\n        \"cliui\": {\n          \"version\": \"3.2.0\",\n          \"from\": \"cliui@>=3.2.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz\",\n          \"dev\": true\n        },\n        \"is-fullwidth-code-point\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"is-fullwidth-code-point@>=1.0.0 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz\",\n          \"dev\": true\n        },\n        \"string-width\": {\n          \"version\": \"1.0.2\",\n          \"from\": \"string-width@>=1.0.2 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"3.0.1\",\n          \"from\": \"strip-ansi@>=3.0.1 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz\",\n          \"dev\": true\n        },\n        \"yargs\": {\n          \"version\": \"6.6.0\",\n          \"from\": \"yargs@>=6.0.0 <7.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"growl\": {\n      \"version\": \"1.10.3\",\n      \"from\": \"growl@1.10.3\",\n      \"resolved\": \"https://registry.npmjs.org/growl/-/growl-1.10.3.tgz\",\n      \"dev\": true\n    },\n    \"grunt\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"grunt@*\",\n      \"resolved\": \"https://registry.npmjs.org/grunt/-/grunt-1.0.2.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"glob\": {\n          \"version\": \"7.0.6\",\n          \"from\": \"glob@>=7.0.0 <7.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/glob/-/glob-7.0.6.tgz\",\n          \"dev\": true\n        },\n        \"grunt-cli\": {\n          \"version\": \"1.2.0\",\n          \"from\": \"grunt-cli@>=1.2.0 <1.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-contrib-clean\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"grunt-contrib-clean@>=1.1.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"rimraf\": {\n          \"version\": \"2.6.2\",\n          \"from\": \"rimraf@>=2.5.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-contrib-coffee\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"grunt-contrib-coffee@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-2.0.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"2.2.1\",\n          \"from\": \"ansi-styles@>=2.2.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz\",\n          \"dev\": true\n        },\n        \"chalk\": {\n          \"version\": \"1.1.3\",\n          \"from\": \"chalk@>=1.1.1 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz\",\n          \"dev\": true\n        },\n        \"coffeescript\": {\n          \"version\": \"2.2.1\",\n          \"from\": \"coffeescript@>=2.0.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/coffeescript/-/coffeescript-2.2.1.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"3.0.1\",\n          \"from\": \"strip-ansi@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"2.0.0\",\n          \"from\": \"supports-color@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-contrib-copy\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"grunt-contrib-copy@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"2.2.1\",\n          \"from\": \"ansi-styles@>=2.2.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz\",\n          \"dev\": true\n        },\n        \"chalk\": {\n          \"version\": \"1.1.3\",\n          \"from\": \"chalk@>=1.1.1 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"3.0.1\",\n          \"from\": \"strip-ansi@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"2.0.0\",\n          \"from\": \"supports-color@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-eslint\": {\n      \"version\": \"20.1.0\",\n      \"from\": \"grunt-eslint@>=20.1.0 <21.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-20.1.0.tgz\",\n      \"dev\": true\n    },\n    \"grunt-known-options\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"grunt-known-options@>=1.1.0 <1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"grunt-legacy-log\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"grunt-legacy-log@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"colors\": {\n          \"version\": \"1.1.2\",\n          \"from\": \"colors@>=1.1.2 <1.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/colors/-/colors-1.1.2.tgz\",\n          \"dev\": true\n        },\n        \"lodash\": {\n          \"version\": \"3.10.1\",\n          \"from\": \"lodash@>=3.10.1 <3.11.0\",\n          \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-legacy-log-utils\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"grunt-legacy-log-utils@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"2.2.1\",\n          \"from\": \"ansi-styles@>=2.2.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz\",\n          \"dev\": true\n        },\n        \"chalk\": {\n          \"version\": \"1.1.3\",\n          \"from\": \"chalk@>=1.1.1 <1.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz\",\n          \"dev\": true\n        },\n        \"lodash\": {\n          \"version\": \"4.3.0\",\n          \"from\": \"lodash@>=4.3.0 <4.4.0\",\n          \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"3.0.1\",\n          \"from\": \"strip-ansi@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"2.0.0\",\n          \"from\": \"supports-color@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-legacy-util\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"grunt-legacy-util@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lodash\": {\n          \"version\": \"4.3.0\",\n          \"from\": \"lodash@>=4.3.0 <4.4.0\",\n          \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz\",\n          \"dev\": true\n        },\n        \"which\": {\n          \"version\": \"1.2.14\",\n          \"from\": \"which@>=1.2.1 <1.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/which/-/which-1.2.14.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"grunt-simple-mocha\": {\n      \"version\": \"0.4.1\",\n      \"from\": \"grunt-simple-mocha@*\",\n      \"resolved\": \"https://registry.npmjs.org/grunt-simple-mocha/-/grunt-simple-mocha-0.4.1.tgz\",\n      \"dev\": true\n    },\n    \"handlebars\": {\n      \"version\": \"4.0.11\",\n      \"from\": \"handlebars@>=4.0.5 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz\"\n    },\n    \"har-schema\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"har-schema@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"har-validator\": {\n      \"version\": \"5.0.3\",\n      \"from\": \"har-validator@>=5.0.3 <5.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz\",\n      \"dev\": true\n    },\n    \"has-ansi\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"has-ansi@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"has-color\": {\n      \"version\": \"0.1.7\",\n      \"from\": \"has-color@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz\"\n    },\n    \"has-flag\": {\n      \"version\": \"3.0.0\",\n      \"from\": \"has-flag@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz\"\n    },\n    \"has-glob\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"has-glob@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz\"\n    },\n    \"hawk\": {\n      \"version\": \"6.0.2\",\n      \"from\": \"hawk@>=6.0.2 <6.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz\",\n      \"dev\": true\n    },\n    \"he\": {\n      \"version\": \"1.1.1\",\n      \"from\": \"he@1.1.1\",\n      \"resolved\": \"https://registry.npmjs.org/he/-/he-1.1.1.tgz\",\n      \"dev\": true\n    },\n    \"hoek\": {\n      \"version\": \"4.2.0\",\n      \"from\": \"hoek@>=4.0.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz\",\n      \"dev\": true\n    },\n    \"homedir-polyfill\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"homedir-polyfill@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz\"\n    },\n    \"hooker\": {\n      \"version\": \"0.2.3\",\n      \"from\": \"hooker@>=0.2.3 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz\",\n      \"dev\": true\n    },\n    \"hosted-git-info\": {\n      \"version\": \"2.5.0\",\n      \"from\": \"hosted-git-info@>=2.1.4 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz\",\n      \"dev\": true\n    },\n    \"html\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"html@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/html/-/html-1.0.0.tgz\"\n    },\n    \"http-signature\": {\n      \"version\": \"1.2.0\",\n      \"from\": \"http-signature@>=1.2.0 <1.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz\",\n      \"dev\": true\n    },\n    \"iconv-lite\": {\n      \"version\": \"0.4.19\",\n      \"from\": \"iconv-lite@>=0.4.13 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz\",\n      \"dev\": true\n    },\n    \"ignore\": {\n      \"version\": \"3.3.7\",\n      \"from\": \"ignore@>=3.3.3 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz\",\n      \"dev\": true\n    },\n    \"imurmurhash\": {\n      \"version\": \"0.1.4\",\n      \"from\": \"imurmurhash@>=0.1.4 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz\",\n      \"dev\": true\n    },\n    \"indent-string\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"indent-string@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"inflight\": {\n      \"version\": \"1.0.6\",\n      \"from\": \"inflight@>=1.0.4 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz\"\n    },\n    \"inherits\": {\n      \"version\": \"2.0.3\",\n      \"from\": \"inherits@>=2.0.3 <2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz\"\n    },\n    \"ini\": {\n      \"version\": \"1.3.5\",\n      \"from\": \"ini@>=1.3.4 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ini/-/ini-1.3.5.tgz\"\n    },\n    \"inquirer\": {\n      \"version\": \"3.3.0\",\n      \"from\": \"inquirer@>=3.0.6 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-regex\": {\n          \"version\": \"3.0.0\",\n          \"from\": \"ansi-regex@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"4.0.0\",\n          \"from\": \"strip-ansi@>=4.0.0 <5.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"invert-kv\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"invert-kv@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"is-absolute\": {\n      \"version\": \"0.2.6\",\n      \"from\": \"is-absolute@>=0.2.5 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz\"\n    },\n    \"is-accessor-descriptor\": {\n      \"version\": \"0.1.6\",\n      \"from\": \"is-accessor-descriptor@>=0.1.6 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz\",\n      \"dependencies\": {\n        \"kind-of\": {\n          \"version\": \"3.2.2\",\n          \"from\": \"kind-of@>=3.0.2 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz\"\n        }\n      }\n    },\n    \"is-arrayish\": {\n      \"version\": \"0.2.1\",\n      \"from\": \"is-arrayish@>=0.2.1 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz\",\n      \"dev\": true\n    },\n    \"is-buffer\": {\n      \"version\": \"1.1.6\",\n      \"from\": \"is-buffer@>=1.1.3 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz\"\n    },\n    \"is-builtin-module\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"is-builtin-module@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"is-data-descriptor\": {\n      \"version\": \"0.1.4\",\n      \"from\": \"is-data-descriptor@>=0.1.4 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz\",\n      \"dependencies\": {\n        \"kind-of\": {\n          \"version\": \"3.2.2\",\n          \"from\": \"kind-of@>=3.0.2 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz\"\n        }\n      }\n    },\n    \"is-descriptor\": {\n      \"version\": \"0.1.6\",\n      \"from\": \"is-descriptor@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz\"\n    },\n    \"is-extendable\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"is-extendable@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz\"\n    },\n    \"is-extglob\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"is-extglob@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz\"\n    },\n    \"is-finite\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"is-finite@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"is-fullwidth-code-point\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"is-fullwidth-code-point@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"is-glob\": {\n      \"version\": \"2.0.1\",\n      \"from\": \"is-glob@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz\"\n    },\n    \"is-my-json-valid\": {\n      \"version\": \"2.17.1\",\n      \"from\": \"is-my-json-valid@>=2.12.4 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz\"\n    },\n    \"is-path-cwd\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"is-path-cwd@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"is-path-in-cwd\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"is-path-in-cwd@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"is-path-inside\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"is-path-inside@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"is-promise\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"is-promise@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"is-property\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"is-property@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz\"\n    },\n    \"is-relative\": {\n      \"version\": \"0.2.1\",\n      \"from\": \"is-relative@>=0.2.1 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz\"\n    },\n    \"is-resolvable\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"is-resolvable@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"is-typedarray\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"is-typedarray@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"is-unc-path\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"is-unc-path@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz\"\n    },\n    \"is-utf8\": {\n      \"version\": \"0.2.1\",\n      \"from\": \"is-utf8@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz\"\n    },\n    \"is-valid-glob\": {\n      \"version\": \"0.3.0\",\n      \"from\": \"is-valid-glob@>=0.3.0 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz\"\n    },\n    \"is-windows\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"is-windows@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz\"\n    },\n    \"isarray\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"isarray@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz\"\n    },\n    \"isexe\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"isexe@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz\"\n    },\n    \"isobject\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"isobject@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz\"\n    },\n    \"isstream\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"isstream@>=0.1.2 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz\",\n      \"dev\": true\n    },\n    \"js-tokens\": {\n      \"version\": \"3.0.2\",\n      \"from\": \"js-tokens@>=3.0.2 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz\",\n      \"dev\": true\n    },\n    \"js-yaml\": {\n      \"version\": \"3.5.5\",\n      \"from\": \"js-yaml@>=3.5.2 <3.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz\",\n      \"dev\": true\n    },\n    \"jsbn\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"jsbn@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"json-lint\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"json-lint@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-lint/-/json-lint-0.1.0.tgz\"\n    },\n    \"json-schema\": {\n      \"version\": \"0.2.3\",\n      \"from\": \"json-schema@0.2.3\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz\",\n      \"dev\": true\n    },\n    \"json-schema-traverse\": {\n      \"version\": \"0.3.1\",\n      \"from\": \"json-schema-traverse@>=0.3.0 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz\",\n      \"dev\": true\n    },\n    \"json-stable-stringify-without-jsonify\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"json-stable-stringify-without-jsonify@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"json-stringify-safe\": {\n      \"version\": \"5.0.1\",\n      \"from\": \"json-stringify-safe@>=5.0.1 <5.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz\",\n      \"dev\": true\n    },\n    \"jsonfile\": {\n      \"version\": \"4.0.0\",\n      \"from\": \"jsonfile@>=4.0.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz\"\n    },\n    \"jsonlint\": {\n      \"version\": \"1.6.2\",\n      \"from\": \"jsonlint@>=1.6.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.2.tgz\"\n    },\n    \"jsonpointer\": {\n      \"version\": \"4.0.1\",\n      \"from\": \"jsonpointer@>=4.0.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz\"\n    },\n    \"jsonresume-theme-boilerplate\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"jsonresume-theme-boilerplate@>=0.1.2 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonresume-theme-boilerplate/-/jsonresume-theme-boilerplate-0.1.2.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"async\": {\n          \"version\": \"0.2.10\",\n          \"from\": \"async@>=0.2.6 <0.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/async/-/async-0.2.10.tgz\",\n          \"dev\": true,\n          \"optional\": true\n        },\n        \"handlebars\": {\n          \"version\": \"2.0.0\",\n          \"from\": \"handlebars@>=2.0.0-alpha.4 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz\",\n          \"dev\": true\n        },\n        \"optimist\": {\n          \"version\": \"0.3.7\",\n          \"from\": \"optimist@>=0.3.0 <0.4.0\",\n          \"resolved\": \"https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz\",\n          \"dev\": true\n        },\n        \"source-map\": {\n          \"version\": \"0.1.43\",\n          \"from\": \"source-map@>=0.1.7 <0.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz\",\n          \"dev\": true,\n          \"optional\": true\n        },\n        \"uglify-js\": {\n          \"version\": \"2.3.6\",\n          \"from\": \"uglify-js@>=2.3.0 <2.4.0\",\n          \"resolved\": \"https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz\",\n          \"dev\": true,\n          \"optional\": true\n        }\n      }\n    },\n    \"jsonresume-theme-classy\": {\n      \"version\": \"1.0.9\",\n      \"from\": \"jsonresume-theme-classy@>=1.0.9 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonresume-theme-classy/-/jsonresume-theme-classy-1.0.9.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lodash\": {\n          \"version\": \"2.4.2\",\n          \"from\": \"lodash@>=2.4.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"jsonresume-theme-modern\": {\n      \"version\": \"0.0.18\",\n      \"from\": \"jsonresume-theme-modern@0.0.18\",\n      \"resolved\": \"https://registry.npmjs.org/jsonresume-theme-modern/-/jsonresume-theme-modern-0.0.18.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lodash\": {\n          \"version\": \"2.4.2\",\n          \"from\": \"lodash@>=2.4.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"jsonresume-theme-sceptile\": {\n      \"version\": \"1.0.5\",\n      \"from\": \"jsonresume-theme-sceptile@>=1.0.5 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsonresume-theme-sceptile/-/jsonresume-theme-sceptile-1.0.5.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"lodash\": {\n          \"version\": \"2.4.2\",\n          \"from\": \"lodash@>=2.4.1 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"jsprim\": {\n      \"version\": \"1.4.1\",\n      \"from\": \"jsprim@>=1.2.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz\",\n      \"dev\": true\n    },\n    \"JSV\": {\n      \"version\": \"4.0.2\",\n      \"from\": \"JSV@>=4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz\"\n    },\n    \"kind-of\": {\n      \"version\": \"5.1.0\",\n      \"from\": \"kind-of@>=5.0.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz\"\n    },\n    \"lazy-cache\": {\n      \"version\": \"2.0.2\",\n      \"from\": \"lazy-cache@>=2.0.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz\"\n    },\n    \"lcid\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"lcid@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"levn\": {\n      \"version\": \"0.3.0\",\n      \"from\": \"levn@>=0.3.0 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/levn/-/levn-0.3.0.tgz\",\n      \"dev\": true\n    },\n    \"load-json-file\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"load-json-file@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"lodash\": {\n      \"version\": \"4.17.5\",\n      \"from\": \"lodash@>=4.17.5 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz\"\n    },\n    \"log-ok\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"log-ok@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/log-ok/-/log-ok-0.1.1.tgz\"\n    },\n    \"longest\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"longest@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/longest/-/longest-1.0.1.tgz\"\n    },\n    \"loud-rejection\": {\n      \"version\": \"1.6.0\",\n      \"from\": \"loud-rejection@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz\",\n      \"dev\": true\n    },\n    \"lru-cache\": {\n      \"version\": \"4.1.1\",\n      \"from\": \"lru-cache@>=4.0.1 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz\",\n      \"dev\": true\n    },\n    \"map-cache\": {\n      \"version\": \"0.2.2\",\n      \"from\": \"map-cache@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz\"\n    },\n    \"map-obj\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"map-obj@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"marked\": {\n      \"version\": \"0.3.12\",\n      \"from\": \"marked@>=0.3.5 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/marked/-/marked-0.3.12.tgz\"\n    },\n    \"matched\": {\n      \"version\": \"0.4.4\",\n      \"from\": \"matched@>=0.4.1 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/matched/-/matched-0.4.4.tgz\"\n    },\n    \"meow\": {\n      \"version\": \"3.7.0\",\n      \"from\": \"meow@>=3.3.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/meow/-/meow-3.7.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"minimist\": {\n          \"version\": \"1.2.0\",\n          \"from\": \"minimist@>=1.1.3 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"mime-db\": {\n      \"version\": \"1.30.0\",\n      \"from\": \"mime-db@>=1.30.0 <1.31.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz\",\n      \"dev\": true\n    },\n    \"mime-types\": {\n      \"version\": \"2.1.17\",\n      \"from\": \"mime-types@>=2.1.17 <2.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz\",\n      \"dev\": true\n    },\n    \"mimic-fn\": {\n      \"version\": \"1.2.0\",\n      \"from\": \"mimic-fn@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz\",\n      \"dev\": true\n    },\n    \"minimatch\": {\n      \"version\": \"3.0.4\",\n      \"from\": \"minimatch@>=3.0.4 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz\"\n    },\n    \"minimist\": {\n      \"version\": \"0.0.8\",\n      \"from\": \"minimist@0.0.8\",\n      \"resolved\": \"https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz\"\n    },\n    \"minipass\": {\n      \"version\": \"2.2.1\",\n      \"from\": \"minipass@>=2.2.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/minipass/-/minipass-2.2.1.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"yallist\": {\n          \"version\": \"3.0.2\",\n          \"from\": \"yallist@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"minizlib\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"minizlib@>=1.1.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"mkdirp\": {\n      \"version\": \"0.5.1\",\n      \"from\": \"mkdirp@>=0.5.1 <0.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz\"\n    },\n    \"mocha\": {\n      \"version\": \"5.0.0\",\n      \"from\": \"mocha@*\",\n      \"resolved\": \"https://registry.npmjs.org/mocha/-/mocha-5.0.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"commander\": {\n          \"version\": \"2.11.0\",\n          \"from\": \"commander@2.11.0\",\n          \"resolved\": \"https://registry.npmjs.org/commander/-/commander-2.11.0.tgz\",\n          \"dev\": true\n        },\n        \"has-flag\": {\n          \"version\": \"2.0.0\",\n          \"from\": \"has-flag@>=2.0.0 <3.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz\",\n          \"dev\": true\n        },\n        \"supports-color\": {\n          \"version\": \"4.4.0\",\n          \"from\": \"supports-color@4.4.0\",\n          \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"moment\": {\n      \"version\": \"2.20.1\",\n      \"from\": \"moment@>=2.11.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/moment/-/moment-2.20.1.tgz\"\n    },\n    \"ms\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"ms@2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"mustache\": {\n      \"version\": \"0.8.2\",\n      \"from\": \"mustache@>=0.8.2 <0.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/mustache/-/mustache-0.8.2.tgz\",\n      \"dev\": true\n    },\n    \"mute-stream\": {\n      \"version\": \"0.0.7\",\n      \"from\": \"mute-stream@0.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz\",\n      \"dev\": true\n    },\n    \"natural-compare\": {\n      \"version\": \"1.4.0\",\n      \"from\": \"natural-compare@>=1.4.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz\",\n      \"dev\": true\n    },\n    \"nomnom\": {\n      \"version\": \"1.8.1\",\n      \"from\": \"nomnom@>=1.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz\",\n      \"dependencies\": {\n        \"ansi-styles\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"ansi-styles@>=1.0.0 <1.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz\"\n        },\n        \"chalk\": {\n          \"version\": \"0.4.0\",\n          \"from\": \"chalk@>=0.4.0 <0.5.0\",\n          \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz\"\n        },\n        \"underscore\": {\n          \"version\": \"1.6.0\",\n          \"from\": \"underscore@>=1.6.0 <1.7.0\",\n          \"resolved\": \"https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz\"\n        }\n      }\n    },\n    \"nopt\": {\n      \"version\": \"3.0.6\",\n      \"from\": \"nopt@>=3.0.6 <3.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz\",\n      \"dev\": true\n    },\n    \"normalize-package-data\": {\n      \"version\": \"2.4.0\",\n      \"from\": \"normalize-package-data@>=2.3.4 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz\",\n      \"dev\": true\n    },\n    \"number-is-nan\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"number-is-nan@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"oauth-sign\": {\n      \"version\": \"0.8.2\",\n      \"from\": \"oauth-sign@>=0.8.2 <0.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz\",\n      \"dev\": true\n    },\n    \"object-assign\": {\n      \"version\": \"4.1.1\",\n      \"from\": \"object-assign@>=4.0.1 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz\",\n      \"dev\": true\n    },\n    \"once\": {\n      \"version\": \"1.4.0\",\n      \"from\": \"once@>=1.3.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/once/-/once-1.4.0.tgz\"\n    },\n    \"onetime\": {\n      \"version\": \"2.0.1\",\n      \"from\": \"onetime@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz\",\n      \"dev\": true\n    },\n    \"optimist\": {\n      \"version\": \"0.6.1\",\n      \"from\": \"optimist@>=0.6.1 <0.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz\"\n    },\n    \"optionator\": {\n      \"version\": \"0.8.2\",\n      \"from\": \"optionator@>=0.8.2 <0.9.0\",\n      \"resolved\": \"https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"wordwrap\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"wordwrap@>=1.0.0 <1.1.0\",\n          \"resolved\": \"https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"os-homedir\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"os-homedir@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz\"\n    },\n    \"os-locale\": {\n      \"version\": \"1.4.0\",\n      \"from\": \"os-locale@>=1.4.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz\",\n      \"dev\": true\n    },\n    \"os-tmpdir\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"os-tmpdir@>=1.0.2 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"parse-filepath\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"parse-filepath@>=1.0.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz\",\n      \"dependencies\": {\n        \"is-absolute\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"is-absolute@>=1.0.0 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz\"\n        },\n        \"is-relative\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"is-relative@>=1.0.0 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz\"\n        },\n        \"is-unc-path\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"is-unc-path@>=1.0.0 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz\"\n        },\n        \"is-windows\": {\n          \"version\": \"1.0.1\",\n          \"from\": \"is-windows@>=1.0.1 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz\"\n        }\n      }\n    },\n    \"parse-json\": {\n      \"version\": \"2.2.0\",\n      \"from\": \"parse-json@>=2.2.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz\",\n      \"dev\": true\n    },\n    \"parse-passwd\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"parse-passwd@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz\"\n    },\n    \"path-exists\": {\n      \"version\": \"3.0.0\",\n      \"from\": \"path-exists@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz\"\n    },\n    \"path-is-absolute\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"path-is-absolute@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz\"\n    },\n    \"path-is-inside\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"path-is-inside@>=1.0.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"path-root\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"path-root@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz\"\n    },\n    \"path-root-regex\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"path-root-regex@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz\"\n    },\n    \"path-type\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"path-type@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"pathval\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"pathval@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"performance-now\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"performance-now@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"pify\": {\n      \"version\": \"2.3.0\",\n      \"from\": \"pify@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pify/-/pify-2.3.0.tgz\",\n      \"dev\": true\n    },\n    \"pinkie\": {\n      \"version\": \"2.0.4\",\n      \"from\": \"pinkie@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz\"\n    },\n    \"pinkie-promise\": {\n      \"version\": \"2.0.1\",\n      \"from\": \"pinkie-promise@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz\"\n    },\n    \"pluralize\": {\n      \"version\": \"7.0.0\",\n      \"from\": \"pluralize@>=7.0.0 <8.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz\",\n      \"dev\": true\n    },\n    \"prelude-ls\": {\n      \"version\": \"1.1.2\",\n      \"from\": \"prelude-ls@>=1.1.2 <1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz\",\n      \"dev\": true\n    },\n    \"printf\": {\n      \"version\": \"0.2.5\",\n      \"from\": \"printf@>=0.2.3 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/printf/-/printf-0.2.5.tgz\"\n    },\n    \"process-nextick-args\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"process-nextick-args@>=2.0.0 <2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz\"\n    },\n    \"progress\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"progress@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/progress/-/progress-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"pseudomap\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"pseudomap@>=1.0.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"punycode\": {\n      \"version\": \"1.4.1\",\n      \"from\": \"punycode@>=1.4.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz\",\n      \"dev\": true\n    },\n    \"qs\": {\n      \"version\": \"6.5.1\",\n      \"from\": \"qs@>=6.5.1 <6.6.0\",\n      \"resolved\": \"https://registry.npmjs.org/qs/-/qs-6.5.1.tgz\",\n      \"dev\": true\n    },\n    \"querystring\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"querystring@0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz\",\n      \"dev\": true\n    },\n    \"read-pkg\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"read-pkg@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz\",\n      \"dev\": true\n    },\n    \"read-pkg-up\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"read-pkg-up@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"readable-stream\": {\n      \"version\": \"2.3.4\",\n      \"from\": \"readable-stream@>=2.1.5 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz\"\n    },\n    \"recursive-readdir-sync\": {\n      \"version\": \"1.0.6\",\n      \"from\": \"recursive-readdir-sync@>=1.0.6 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz\"\n    },\n    \"redent\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"redent@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/redent/-/redent-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"repeat-string\": {\n      \"version\": \"1.6.1\",\n      \"from\": \"repeat-string@>=1.5.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz\"\n    },\n    \"repeating\": {\n      \"version\": \"2.0.1\",\n      \"from\": \"repeating@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz\",\n      \"dev\": true\n    },\n    \"replace-ext\": {\n      \"version\": \"0.0.1\",\n      \"from\": \"replace-ext@0.0.1\",\n      \"resolved\": \"https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz\"\n    },\n    \"request\": {\n      \"version\": \"2.83.0\",\n      \"from\": \"request@>=2.39.0\",\n      \"resolved\": \"https://registry.npmjs.org/request/-/request-2.83.0.tgz\",\n      \"dev\": true\n    },\n    \"require-directory\": {\n      \"version\": \"2.1.1\",\n      \"from\": \"require-directory@>=2.1.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz\",\n      \"dev\": true\n    },\n    \"require-main-filename\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"require-main-filename@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"require-uncached\": {\n      \"version\": \"1.0.3\",\n      \"from\": \"require-uncached@>=1.0.3 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz\",\n      \"dev\": true\n    },\n    \"resolve\": {\n      \"version\": \"1.1.7\",\n      \"from\": \"resolve@>=1.1.0 <1.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz\",\n      \"dev\": true\n    },\n    \"resolve-dir\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"resolve-dir@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz\"\n    },\n    \"resolve-from\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"resolve-from@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"restore-cursor\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"restore-cursor@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"resume-schema\": {\n      \"version\": \"0.0.15\",\n      \"from\": \"resume-schema@0.0.15\",\n      \"resolved\": \"https://registry.npmjs.org/resume-schema/-/resume-schema-0.0.15.tgz\",\n      \"dev\": true\n    },\n    \"right-align\": {\n      \"version\": \"0.1.3\",\n      \"from\": \"right-align@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz\",\n      \"optional\": true\n    },\n    \"rimraf\": {\n      \"version\": \"2.2.8\",\n      \"from\": \"rimraf@>=2.2.8 <2.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz\",\n      \"dev\": true\n    },\n    \"run-async\": {\n      \"version\": \"2.3.0\",\n      \"from\": \"run-async@>=2.2.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz\",\n      \"dev\": true\n    },\n    \"rx-lite\": {\n      \"version\": \"4.0.8\",\n      \"from\": \"rx-lite@>=4.0.8 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz\",\n      \"dev\": true\n    },\n    \"rx-lite-aggregates\": {\n      \"version\": \"4.0.8\",\n      \"from\": \"rx-lite-aggregates@>=4.0.8 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz\",\n      \"dev\": true\n    },\n    \"safe-buffer\": {\n      \"version\": \"5.1.1\",\n      \"from\": \"safe-buffer@>=5.1.1 <5.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz\"\n    },\n    \"semver\": {\n      \"version\": \"5.5.0\",\n      \"from\": \"semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-5.5.0.tgz\",\n      \"dev\": true\n    },\n    \"set-blocking\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"set-blocking@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"set-getter\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"set-getter@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz\"\n    },\n    \"shebang-command\": {\n      \"version\": \"1.2.0\",\n      \"from\": \"shebang-command@>=1.2.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz\",\n      \"dev\": true\n    },\n    \"shebang-regex\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"shebang-regex@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"signal-exit\": {\n      \"version\": \"3.0.2\",\n      \"from\": \"signal-exit@>=3.0.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz\",\n      \"dev\": true\n    },\n    \"simple-html-tokenizer\": {\n      \"version\": \"0.4.3\",\n      \"from\": \"simple-html-tokenizer@>=0.4.3 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.4.3.tgz\"\n    },\n    \"slash\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"slash@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slash/-/slash-1.0.0.tgz\"\n    },\n    \"slice-ansi\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"slice-ansi@1.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"sntp\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"sntp@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz\",\n      \"dev\": true\n    },\n    \"source-map\": {\n      \"version\": \"0.4.4\",\n      \"from\": \"source-map@>=0.4.4 <0.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz\"\n    },\n    \"spdx-correct\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"spdx-correct@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz\",\n      \"dev\": true\n    },\n    \"spdx-expression-parse\": {\n      \"version\": \"1.0.4\",\n      \"from\": \"spdx-expression-parse@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz\",\n      \"dev\": true\n    },\n    \"spdx-license-ids\": {\n      \"version\": \"1.2.2\",\n      \"from\": \"spdx-license-ids@>=1.0.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz\",\n      \"dev\": true\n    },\n    \"sprintf-js\": {\n      \"version\": \"1.0.3\",\n      \"from\": \"sprintf-js@>=1.0.2 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz\"\n    },\n    \"sshpk\": {\n      \"version\": \"1.13.1\",\n      \"from\": \"sshpk@>=1.7.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz\",\n      \"dev\": true\n    },\n    \"string_decoder\": {\n      \"version\": \"1.0.3\",\n      \"from\": \"string_decoder@>=1.0.3 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz\"\n    },\n    \"string-padding\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"string-padding@>=1.0.2 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/string-padding/-/string-padding-1.0.2.tgz\"\n    },\n    \"string-width\": {\n      \"version\": \"2.1.1\",\n      \"from\": \"string-width@>=2.1.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ansi-regex\": {\n          \"version\": \"3.0.0\",\n          \"from\": \"ansi-regex@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"4.0.0\",\n          \"from\": \"strip-ansi@>=4.0.0 <5.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"string.prototype.endswith\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"string.prototype.endswith@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.endswith/-/string.prototype.endswith-0.2.0.tgz\"\n    },\n    \"string.prototype.startswith\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"string.prototype.startswith@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.startswith/-/string.prototype.startswith-0.2.0.tgz\"\n    },\n    \"stringstream\": {\n      \"version\": \"0.0.5\",\n      \"from\": \"stringstream@>=0.0.5 <0.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz\",\n      \"dev\": true\n    },\n    \"strip-ansi\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"strip-ansi@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz\"\n    },\n    \"strip-bom\": {\n      \"version\": \"2.0.0\",\n      \"from\": \"strip-bom@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz\",\n      \"dev\": true\n    },\n    \"strip-bom-buffer\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"strip-bom-buffer@>=0.1.1 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-bom-buffer/-/strip-bom-buffer-0.1.1.tgz\"\n    },\n    \"strip-bom-string\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"strip-bom-string@>=0.1.2 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-0.1.2.tgz\"\n    },\n    \"strip-indent\": {\n      \"version\": \"1.0.1\",\n      \"from\": \"strip-indent@>=1.0.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz\",\n      \"dev\": true\n    },\n    \"strip-json-comments\": {\n      \"version\": \"2.0.1\",\n      \"from\": \"strip-json-comments@>=2.0.1 <2.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz\",\n      \"dev\": true\n    },\n    \"stripcolorcodes\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"stripcolorcodes@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/stripcolorcodes/-/stripcolorcodes-0.1.0.tgz\",\n      \"dev\": true\n    },\n    \"success-symbol\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"success-symbol@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/success-symbol/-/success-symbol-0.1.0.tgz\"\n    },\n    \"supports-color\": {\n      \"version\": \"5.2.0\",\n      \"from\": \"supports-color@>=5.2.0 <6.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz\"\n    },\n    \"table\": {\n      \"version\": \"4.0.2\",\n      \"from\": \"table@>=4.0.1 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/table/-/table-4.0.2.tgz\",\n      \"dev\": true\n    },\n    \"tar\": {\n      \"version\": \"4.3.3\",\n      \"from\": \"tar@*\",\n      \"resolved\": \"https://registry.npmjs.org/tar/-/tar-4.3.3.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"yallist\": {\n          \"version\": \"3.0.2\",\n          \"from\": \"yallist@>=3.0.2 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"tarball-extract\": {\n      \"version\": \"0.0.3\",\n      \"from\": \"tarball-extract@0.0.3\",\n      \"resolved\": \"https://registry.npmjs.org/tarball-extract/-/tarball-extract-0.0.3.tgz\",\n      \"dev\": true\n    },\n    \"text-table\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"text-table@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz\",\n      \"dev\": true\n    },\n    \"through\": {\n      \"version\": \"2.3.8\",\n      \"from\": \"through@>=2.3.6 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/through/-/through-2.3.8.tgz\",\n      \"dev\": true\n    },\n    \"through2\": {\n      \"version\": \"2.0.3\",\n      \"from\": \"through2@>=2.0.1 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/through2/-/through2-2.0.3.tgz\"\n    },\n    \"tmp\": {\n      \"version\": \"0.0.33\",\n      \"from\": \"tmp@>=0.0.33 <0.0.34\",\n      \"resolved\": \"https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz\",\n      \"dev\": true\n    },\n    \"to-file\": {\n      \"version\": \"0.2.0\",\n      \"from\": \"to-file@>=0.2.0 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/to-file/-/to-file-0.2.0.tgz\",\n      \"dependencies\": {\n        \"file-contents\": {\n          \"version\": \"0.2.4\",\n          \"from\": \"file-contents@>=0.2.4 <0.3.0\",\n          \"resolved\": \"https://registry.npmjs.org/file-contents/-/file-contents-0.2.4.tgz\",\n          \"dependencies\": {\n            \"lazy-cache\": {\n              \"version\": \"0.2.7\",\n              \"from\": \"lazy-cache@>=0.2.3 <0.3.0\",\n              \"resolved\": \"https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz\"\n            }\n          }\n        },\n        \"file-stat\": {\n          \"version\": \"0.1.3\",\n          \"from\": \"file-stat@>=0.1.0 <0.2.0\",\n          \"resolved\": \"https://registry.npmjs.org/file-stat/-/file-stat-0.1.3.tgz\",\n          \"dependencies\": {\n            \"lazy-cache\": {\n              \"version\": \"0.2.7\",\n              \"from\": \"lazy-cache@>=0.2.3 <0.3.0\",\n              \"resolved\": \"https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz\"\n            }\n          }\n        }\n      }\n    },\n    \"to-object-path\": {\n      \"version\": \"0.3.0\",\n      \"from\": \"to-object-path@>=0.3.0 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz\",\n      \"dependencies\": {\n        \"kind-of\": {\n          \"version\": \"3.2.2\",\n          \"from\": \"kind-of@>=3.0.2 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz\"\n        }\n      }\n    },\n    \"tough-cookie\": {\n      \"version\": \"2.3.3\",\n      \"from\": \"tough-cookie@>=2.3.3 <2.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz\",\n      \"dev\": true\n    },\n    \"traverse\": {\n      \"version\": \"0.6.6\",\n      \"from\": \"traverse@>=0.6.6 <0.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz\"\n    },\n    \"trim-newlines\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"trim-newlines@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"tunnel\": {\n      \"version\": \"0.0.2\",\n      \"from\": \"tunnel@0.0.2\",\n      \"resolved\": \"https://registry.npmjs.org/tunnel/-/tunnel-0.0.2.tgz\",\n      \"dev\": true\n    },\n    \"tunnel-agent\": {\n      \"version\": \"0.6.0\",\n      \"from\": \"tunnel-agent@>=0.6.0 <0.7.0\",\n      \"resolved\": \"https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz\",\n      \"dev\": true\n    },\n    \"tweetnacl\": {\n      \"version\": \"0.14.5\",\n      \"from\": \"tweetnacl@>=0.14.0 <0.15.0\",\n      \"resolved\": \"https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz\",\n      \"dev\": true,\n      \"optional\": true\n    },\n    \"type-check\": {\n      \"version\": \"0.3.2\",\n      \"from\": \"type-check@>=0.3.2 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz\",\n      \"dev\": true\n    },\n    \"type-detect\": {\n      \"version\": \"4.0.8\",\n      \"from\": \"type-detect@>=4.0.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz\",\n      \"dev\": true\n    },\n    \"typedarray\": {\n      \"version\": \"0.0.6\",\n      \"from\": \"typedarray@>=0.0.6 <0.0.7\",\n      \"resolved\": \"https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz\"\n    },\n    \"uglify-js\": {\n      \"version\": \"2.8.29\",\n      \"from\": \"uglify-js@>=2.6.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz\",\n      \"optional\": true,\n      \"dependencies\": {\n        \"source-map\": {\n          \"version\": \"0.5.7\",\n          \"from\": \"source-map@>=0.5.1 <0.6.0\",\n          \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz\",\n          \"optional\": true\n        }\n      }\n    },\n    \"uglify-to-browserify\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"uglify-to-browserify@>=1.0.0 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz\",\n      \"optional\": true\n    },\n    \"unc-path-regex\": {\n      \"version\": \"0.1.2\",\n      \"from\": \"unc-path-regex@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz\"\n    },\n    \"underscore\": {\n      \"version\": \"1.8.3\",\n      \"from\": \"underscore@>=1.8.3 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz\"\n    },\n    \"underscore.string\": {\n      \"version\": \"3.2.3\",\n      \"from\": \"underscore.string@>=3.2.3 <3.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz\",\n      \"dev\": true\n    },\n    \"universalify\": {\n      \"version\": \"0.1.1\",\n      \"from\": \"universalify@>=0.1.0 <0.2.0\",\n      \"resolved\": \"https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz\"\n    },\n    \"uri-path\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"uri-path@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"util-deprecate\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"util-deprecate@>=1.0.1 <1.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz\"\n    },\n    \"uuid\": {\n      \"version\": \"3.2.1\",\n      \"from\": \"uuid@>=3.1.0 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz\",\n      \"dev\": true\n    },\n    \"validate-npm-package-license\": {\n      \"version\": \"3.0.1\",\n      \"from\": \"validate-npm-package-license@>=3.0.1 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz\",\n      \"dev\": true\n    },\n    \"verror\": {\n      \"version\": \"1.10.0\",\n      \"from\": \"verror@1.10.0\",\n      \"resolved\": \"https://registry.npmjs.org/verror/-/verror-1.10.0.tgz\",\n      \"dev\": true\n    },\n    \"vinyl\": {\n      \"version\": \"1.2.0\",\n      \"from\": \"vinyl@>=1.1.1 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz\"\n    },\n    \"wget\": {\n      \"version\": \"0.0.1\",\n      \"from\": \"wget@*\",\n      \"resolved\": \"https://registry.npmjs.org/wget/-/wget-0.0.1.tgz\",\n      \"dev\": true\n    },\n    \"which\": {\n      \"version\": \"1.3.0\",\n      \"from\": \"which@>=1.2.12 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/which/-/which-1.3.0.tgz\"\n    },\n    \"which-module\": {\n      \"version\": \"1.0.0\",\n      \"from\": \"which-module@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz\",\n      \"dev\": true\n    },\n    \"window-size\": {\n      \"version\": \"0.1.0\",\n      \"from\": \"window-size@0.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz\",\n      \"optional\": true\n    },\n    \"word-wrap\": {\n      \"version\": \"1.2.3\",\n      \"from\": \"word-wrap@>=1.1.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz\"\n    },\n    \"wordwrap\": {\n      \"version\": \"0.0.3\",\n      \"from\": \"wordwrap@>=0.0.2 <0.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz\"\n    },\n    \"wrap-ansi\": {\n      \"version\": \"2.1.0\",\n      \"from\": \"wrap-ansi@>=2.0.0 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"is-fullwidth-code-point\": {\n          \"version\": \"1.0.0\",\n          \"from\": \"is-fullwidth-code-point@>=1.0.0 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz\",\n          \"dev\": true\n        },\n        \"string-width\": {\n          \"version\": \"1.0.2\",\n          \"from\": \"string-width@>=1.0.1 <2.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz\",\n          \"dev\": true\n        },\n        \"strip-ansi\": {\n          \"version\": \"3.0.1\",\n          \"from\": \"strip-ansi@>=3.0.1 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"wrappy\": {\n      \"version\": \"1.0.2\",\n      \"from\": \"wrappy@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz\"\n    },\n    \"write\": {\n      \"version\": \"0.2.1\",\n      \"from\": \"write@>=0.2.1 <0.3.0\",\n      \"resolved\": \"https://registry.npmjs.org/write/-/write-0.2.1.tgz\",\n      \"dev\": true\n    },\n    \"xml-escape\": {\n      \"version\": \"1.1.0\",\n      \"from\": \"xml-escape@>=1.0.0 <2.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/xml-escape/-/xml-escape-1.1.0.tgz\"\n    },\n    \"xtend\": {\n      \"version\": \"4.0.1\",\n      \"from\": \"xtend@>=4.0.1 <4.1.0\",\n      \"resolved\": \"https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz\"\n    },\n    \"y18n\": {\n      \"version\": \"3.2.1\",\n      \"from\": \"y18n@>=3.2.1 <4.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz\",\n      \"dev\": true\n    },\n    \"yallist\": {\n      \"version\": \"2.1.2\",\n      \"from\": \"yallist@>=2.1.2 <3.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz\",\n      \"dev\": true\n    },\n    \"yamljs\": {\n      \"version\": \"0.3.0\",\n      \"from\": \"yamljs@>=0.3.0 <0.4.0\",\n      \"resolved\": \"https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz\"\n    },\n    \"yargs\": {\n      \"version\": \"3.10.0\",\n      \"from\": \"yargs@>=3.10.0 <3.11.0\",\n      \"resolved\": \"https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz\",\n      \"optional\": true\n    },\n    \"yargs-parser\": {\n      \"version\": \"4.2.1\",\n      \"from\": \"yargs-parser@>=4.2.0 <5.0.0\",\n      \"resolved\": \"https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"camelcase\": {\n          \"version\": \"3.0.0\",\n          \"from\": \"camelcase@>=3.0.0 <4.0.0\",\n          \"resolved\": \"https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz\",\n          \"dev\": true\n        }\n      }\n    },\n    \"z-schema\": {\n      \"version\": \"2.4.10\",\n      \"from\": \"z-schema@>=2.4.8 <2.5.0\",\n      \"resolved\": \"https://registry.npmjs.org/z-schema/-/z-schema-2.4.10.tgz\",\n      \"dev\": true\n    }\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"hackmyresume\",\n  \"version\": \"1.9.0-beta\",\n  \"description\": \"Generate polished résumés and CVs in HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, YAML, smoke signal, and carrier pigeon.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/hacksalot/HackMyResume.git\"\n  },\n  \"scripts\": {\n    \"test\": \"grunt clean:test && mocha --exit\",\n    \"grunt\": \"grunt\"\n  },\n  \"keywords\": [\n    \"resume\",\n    \"CV\",\n    \"portfolio\",\n    \"employment\",\n    \"career\",\n    \"Markdown\",\n    \"JSON\",\n    \"Word\",\n    \"PDF\",\n    \"YAML\",\n    \"HTML\",\n    \"LaTeX\",\n    \"CLI\",\n    \"Handlebars\",\n    \"Underscore\",\n    \"template\"\n  ],\n  \"author\": \"hacksalot <hacksalot@indevious.com> (https://github.com/hacksalot)\",\n  \"contributors\": [\n    \"aruberto (https://github.com/aruberto)\",\n    \"daniele-rapagnani (https://github.com/daniele-rapagnani)\",\n    \"jjanusch (https://github.com/driftdev)\",\n    \"robertmain (https://github.com/robertmain)\",\n    \"tomheon (https://github.com/tomheon)\",\n    \"zhuangya (https://github.com/zhuangya)\",\n    \"hacksalot <hacksalot@indevious.com> (https://github.com/hacksalot)\"\n  ],\n  \"license\": \"MIT\",\n  \"preferGlobal\": \"true\",\n  \"bugs\": {\n    \"url\": \"https://github.com/hacksalot/HackMyResume/issues\"\n  },\n  \"bin\": {\n    \"hackmyresume\": \"src/cli/index.js\"\n  },\n  \"main\": \"src/index.js\",\n  \"homepage\": \"https://github.com/hacksalot/HackMyResume\",\n  \"dependencies\": {\n    \"chalk\": \"^2.3.1\",\n    \"commander\": \"^2.9.0\",\n    \"copy\": \"^0.3.1\",\n    \"escape-latex\": \"^1.0.0\",\n    \"extend\": \"^3.0.0\",\n    \"fresh-jrs-converter\": \"^1.0.0\",\n    \"fresh-resume-schema\": \"^1.0.0-beta\",\n    \"fresh-resume-starter\": \"^0.3.1\",\n    \"fresh-resume-validator\": \"^0.2.0\",\n    \"fresh-themes\": \"^0.17.0-beta\",\n    \"fs-extra\": \"^5.0.0\",\n    \"glob\": \"^7.1.2\",\n    \"handlebars\": \"^4.0.5\",\n    \"html\": \"^1.0.0\",\n    \"is-my-json-valid\": \"^2.12.4\",\n    \"json-lint\": \"^0.1.0\",\n    \"jsonlint\": \"^1.6.2\",\n    \"lodash\": \"^4.17.5\",\n    \"marked\": \"^0.3.5\",\n    \"mkdirp\": \"^0.5.1\",\n    \"moment\": \"^2.11.1\",\n    \"parse-filepath\": \"^1.0.2\",\n    \"path-exists\": \"^3.0.0\",\n    \"pinkie-promise\": \"^2.0.0\",\n    \"printf\": \"^0.2.3\",\n    \"recursive-readdir-sync\": \"^1.0.6\",\n    \"simple-html-tokenizer\": \"^0.4.3\",\n    \"slash\": \"^1.0.0\",\n    \"string-padding\": \"^1.0.2\",\n    \"string.prototype.endswith\": \"^0.2.0\",\n    \"string.prototype.startswith\": \"^0.2.0\",\n    \"traverse\": \"^0.6.6\",\n    \"underscore\": \"^1.8.3\",\n    \"word-wrap\": \"^1.1.0\",\n    \"xml-escape\": \"^1.0.0\",\n    \"yamljs\": \"^0.3.0\"\n  },\n  \"devDependencies\": {\n    \"chai\": \"*\",\n    \"chai-as-promised\": \"^7.1.1\",\n    \"dir-compare\": \"^1.4.0\",\n    \"fresh-test-resumes\": \"^0.9.2\",\n    \"fresh-test-themes\": \"^0.2.0\",\n    \"fresh-theme-underscore\": \"^0.1.1\",\n    \"grunt\": \"*\",\n    \"grunt-contrib-clean\": \"^1.1.0\",\n    \"grunt-contrib-coffee\": \"^2.0.0\",\n    \"grunt-contrib-copy\": \"^1.0.0\",\n    \"grunt-eslint\": \"^20.1.0\",\n    \"grunt-simple-mocha\": \"*\",\n    \"jsonresume-theme-boilerplate\": \"^0.1.2\",\n    \"jsonresume-theme-classy\": \"^1.0.9\",\n    \"jsonresume-theme-modern\": \"0.0.18\",\n    \"jsonresume-theme-sceptile\": \"^1.0.5\",\n    \"mocha\": \"*\",\n    \"stripcolorcodes\": \"^0.1.0\"\n  }\n}\n"
  },
  {
    "path": "src/cli/analyze.hbs",
    "content": "\n{{style \"SECTIONS (\" \"bold\"}}{{style totals.numSections \"white\" }}{{style \")\" \"bold\"}}\n\n        employment:     {{v totals.totals.employment \"-\" 2 \"bold\" }}\n          projects:     {{v totals.totals.projects \"-\" 2 \"bold\" }}\n         education:     {{v totals.totals.education \"-\" 2 \"bold\" }}\n           service:     {{v totals.totals.service \"-\" 2 \"bold\" }}\n            skills:     {{v totals.totals.skills \"-\" 2 \"bold\" }}\n           writing:     {{v totals.totals.writing \"-\" 2 \"bold\" }}\n          speaking:     {{v totals.totals.speaking \"-\" 2 \"bold\" }}\n           reading:     {{v totals.totals.reading \"-\" 2 \"bold\" }}\n            social:     {{v totals.totals.social \"-\" 2 \"bold\" }}\n        references:     {{v totals.totals.references \"-\" 2 \"bold\" }}\n      testimonials:     {{v totals.totals.testimonials \"-\" 2 \"bold\" }}\n         languages:     {{v totals.totals.languages \"-\" 2 \"bold\" }}\n         interests:     {{v totals.totals.interests \"-\" 2 \"bold\" }}\n\n{{style \"COVERAGE (\" \"bold\"}}{{style coverage.pct \"white\"}}{{style \")\" \"bold\"}}\n\n        Total Days:  {{v coverage.duration.total \"-\" 5 \"bold\" }}\n          Employed:  {{v coverage.duration.work \"-\" 5 \"bold\" }}\n              Gaps:  {{v coverage.gaps.length \"-\" 5 \"bold\" }}  [{{#if coverage.gaps.length }}{{#each coverage.gaps }}{{#unless @first}} {{/unless}}{{gapLength duration }}{{/each}}{{/if}}]\n          Overlaps:  {{v coverage.overlaps.length \"-\" 5 \"bold\" }}  [{{#if coverage.overlaps.length }}{{#each coverage.overlaps }}{{#unless @first}} {{/unless}}{{gapLength duration }}{{/each}}{{/if}}]\n\n{{style \"KEYWORDS (\" \"bold\"}}{{style keywords.length \"white\" }}{{style \")\" \"bold\"}}\n\n{{#each keywords }}{{{pad name 18}}}:  {{v count \"-\" 5 \"bold\"}} mention{{#isPlural count}}s{{/isPlural}}\n{{/each}}\n    -------------------------------\n{{v keywords.length \"0\" 9 \"bold\"}} {{style \"KEYWORDS\" \"bold\"}}   {{v keywords.totalKeywords \"0\" 5 \"bold\"}} {{style \"mentions\" \"bold\"}}\n"
  },
  {
    "path": "src/cli/error.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nError-handling routines for HackMyResume.\n@module cli/error\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst HMSTATUS = require('../core/status-codes');\nconst FS = require('fs');\nconst PATH = require('path');\nconst WRAP = require('word-wrap');\nconst M2C = require('../utils/md2chalk');\nconst chalk = require('chalk');\nconst extend = require('extend');\nconst printf = require('printf');\nconst SyntaxErrorEx = require('../utils/syntax-error-ex');\nrequire('string.prototype.startswith');\n\n\n\n/** Error handler for HackMyResume. All errors are handled here.\n@class ErrorHandler */\nmodule.exports = {\n\n  init( debug, assert, silent ) {\n    this.debug = debug;\n    this.assert = assert;\n    this.silent = silent;\n    this.msgs = require('./msg').errors;\n    return this;\n  },\n\n  err( ex, shouldExit ) {\n\n    // Short-circuit logging output if --silent is on\n    let stack;\n    const o = this.silent ? function() {} : _defaultLog;\n\n    // Special case; can probably be removed.\n    if (ex.pass) { throw ex; }\n\n    // Load error messages\n    this.msgs = this.msgs || require('./msg').errors;\n\n    // Handle packaged HMR exceptions\n    if (ex.fluenterror) {\n\n      // Output the error message\n      const objError = assembleError.call(this, ex);\n      o( this[ `format_${objError.etype}` ]( objError.msg ));\n\n      // Output the stack (sometimes)\n      if (objError.withStack) {\n        stack = ex.stack || (ex.inner && ex.inner.stack);\n        stack && o( chalk.gray( stack ) );\n      }\n\n      // Quit if necessary\n      if (shouldExit || ex.exit) {\n        if (this.debug) {\n          o(chalk.cyan(`Exiting with error code ${ex.fluenterror.toString()}`));\n        }\n        if (this.assert) {\n          ex.pass = true;\n          throw ex;\n        }\n        return process.exit(ex.fluenterror);\n      }\n\n    // Handle raw exceptions\n    } else {\n      o(ex);\n      const stackTrace = ex.stack || (ex.inner && ex.inner.stack);\n      if (stackTrace && this.debug) {\n        return o(M2C(ex.stack || ex.inner.stack, 'gray'));\n      }\n    }\n  },\n\n\n\n  format_error( msg ) {\n    msg = msg || '';\n    return chalk.red.bold( msg.toUpperCase().startsWith('ERROR:') ? msg : `Error: ${msg}` );\n  },\n\n\n  format_warning( brief, msg ) {\n    return chalk.yellow(brief) + chalk.yellow(msg || '');\n  },\n\n\n  format_custom( msg ) { return msg; }\n};\n\n\nvar _defaultLog = function() { return console.log.apply(console.log, arguments); }; // eslint-disable-line no-console\n\n\n\n\nvar assembleError = function( ex ) {\n\n  let se;\n  let msg = '';\n  let withStack = false;\n  let quit = false;\n  let etype = 'warning';\n  if (this.debug) { withStack = true; }\n\n  switch (ex.fluenterror) {\n\n    case HMSTATUS.themeNotFound:\n      msg = printf( M2C( this.msgs.themeNotFound.msg, 'yellow' ), ex.data);\n      break;\n\n    case HMSTATUS.copyCSS:\n      msg = M2C( this.msgs.copyCSS.msg, 'red' );\n      quit = false;\n      break;\n\n    case HMSTATUS.resumeNotFound:\n      //msg = M2C( this.msgs.resumeNotFound.msg, 'yellow' );\n      msg += M2C(FS.readFileSync(\n        PATH.resolve(__dirname, `help/${ex.verb}.txt`), 'utf8' ), 'white', 'yellow');\n      break;\n\n    case HMSTATUS.missingCommand:\n      // msg = M2C( this.msgs.missingCommand.msg + \" (\", 'yellow');\n      // msg += Object.keys( FCMD.verbs ).map( (v, idx, ar) ->\n      //   return ( if idx == ar.length - 1 then chalk.yellow('or ') else '') +\n      //     chalk.yellow.bold(v.toUpperCase());\n      // ).join( chalk.yellow(', ')) + chalk.yellow(\").\\n\\n\");\n\n      msg += M2C(FS.readFileSync(\n        PATH.resolve(__dirname, 'help/use.txt'), 'utf8' ), 'white', 'yellow');\n      break;\n\n    case HMSTATUS.invalidCommand:\n      msg = printf( M2C( this.msgs.invalidCommand.msg, 'yellow'), ex.attempted );\n      break;\n\n    case HMSTATUS.resumeNotFoundAlt:\n      msg = M2C( this.msgs.resumeNotFoundAlt.msg, 'yellow' );\n      break;\n\n    case HMSTATUS.inputOutputParity:\n      msg = M2C( this.msgs.inputOutputParity.msg );\n      break;\n\n    case HMSTATUS.createNameMissing:\n      msg = M2C( this.msgs.createNameMissing.msg );\n      break;\n\n    case HMSTATUS.pdfGeneration:\n      msg = M2C( this.msgs.pdfGeneration.msg, 'bold' );\n      if (ex.inner) { msg += chalk.red(`\\n${ex.inner}`); }\n      quit = false;\n      etype = 'error';\n      break;\n\n    case HMSTATUS.invalid:\n      msg = M2C( this.msgs.invalid.msg, 'red' );\n      etype = 'error';\n      break;\n\n    case HMSTATUS.generateError:\n      msg = (ex.inner && ex.inner.toString()) || ex;\n      quit = false;\n      etype = 'error';\n      break;\n\n    case HMSTATUS.fileSaveError:\n      msg = printf( M2C( this.msgs.fileSaveError.msg ), (ex.inner || ex).toString() );\n      etype = 'error';\n      quit = false;\n      break;\n\n    case HMSTATUS.invalidFormat:\n      ex.data.forEach( function(d) {\n        return msg += printf( M2C( this.msgs.invalidFormat.msg, 'bold' ),\n          ex.theme.name.toUpperCase(), d.format.toUpperCase());\n      }\n      , this);\n      break;\n\n    case HMSTATUS.missingParam:\n      msg = printf(M2C( this.msgs.missingParam.msg ), ex.expected, ex.helper);\n      break;\n\n    case HMSTATUS.invalidHelperUse:\n      msg = printf( M2C( this.msgs.invalidHelperUse.msg ), ex.helper );\n      if (ex.error) {\n        msg += `\\n--> ${assembleError.call( this, extend( true, {}, ex, {fluenterror: ex.error} )).msg}`;\n      }\n        //msg += printf( '\\n--> ' + M2C( this.msgs.invalidParamCount.msg ), ex.expected );\n      quit = false;\n      etype = 'warning';\n      break;\n\n    case HMSTATUS.notOnPath:\n      msg = printf( M2C(this.msgs.notOnPath.msg, 'bold'), ex.engine);\n      quit = false;\n      etype = 'error';\n      break;\n\n    case HMSTATUS.readError:\n      if (!ex.quiet) {\n        // eslint-disable-next-line no-console\n        console.error(printf( M2C(this.msgs.readError.msg, 'red'), ex.file));\n      }\n      msg = ex.inner.toString();\n      etype = 'error';\n      break;\n\n    case HMSTATUS.mixedMerge:\n      msg = M2C(this.msgs.mixedMerge.msg);\n      quit = false;\n      break;\n\n    case HMSTATUS.invokeTemplate:\n      msg = M2C(this.msgs.invokeTemplate.msg, 'red');\n      msg += M2C( `\\n${WRAP(ex.inner.toString(), { width: 60, indent: '   ' })}`, 'gray' );\n      etype = 'custom';\n      break;\n\n    case HMSTATUS.compileTemplate:\n      etype = 'error';\n      break;\n\n    case HMSTATUS.themeLoad:\n      msg = M2C( printf( this.msgs.themeLoad.msg, ex.attempted.toUpperCase() ), 'red');\n      if (ex.inner && ex.inner.fluenterror) {\n        msg += M2C('\\nError: ', 'red') + assembleError.call( this, ex.inner ).msg;\n      }\n      quit = true;\n      etype = 'custom';\n      break;\n\n    case HMSTATUS.parseError:\n      if (SyntaxErrorEx.is(ex.inner)) {\n        // eslint-disable-next-line no-console\n        console.error(printf( M2C(this.msgs.readError.msg, 'red'), ex.file ));\n        se = new SyntaxErrorEx(ex, ex.raw);\n        if ((se.line != null) && (se.col != null)) {\n          msg = printf(M2C( this.msgs.parseError.msg[0], 'red' ), se.line, se.col);\n        } else if (se.line != null) {\n          msg = printf(M2C( this.msgs.parseError.msg[1], 'red' ), se.line);\n        } else {\n          msg = M2C(this.msgs.parseError.msg[2], 'red');\n        }\n      } else if (ex.inner && (ex.inner.line != null) && (ex.inner.col != null)) {\n        msg = printf( M2C( this.msgs.parseError.msg[0], 'red' ), ex.inner.line, ex.inner.col);\n      } else {\n        msg = ex;\n      }\n      etype = 'error';\n      break;\n\n    case HMSTATUS.createError:\n      // inner.code could be EPERM, EACCES, etc\n      msg = printf(M2C( this.msgs.createError.msg ), ex.inner.path);\n      etype = 'error';\n      break;\n\n    case HMSTATUS.validateError:\n      msg = printf(M2C( this.msgs.validateError.msg ), ex.inner.toString());\n      etype = 'error';\n      break;\n\n    case HMSTATUS.invalidOptionsFile:\n      msg = M2C(this.msgs.invalidOptionsFile.msg[0]);\n      if (SyntaxErrorEx.is(ex.inner)) {\n        // eslint-disable-next-line no-console\n        console.error(printf( M2C(this.msgs.readError.msg, 'red'), ex.file ));\n        se = new SyntaxErrorEx(ex, ex.raw);\n        if ((se.line != null) && (se.col != null)) {\n          msg += printf(M2C( this.msgs.parseError.msg[0], 'red' ), se.line, se.col);\n        } else if (se.line != null) {\n          msg += printf(M2C( this.msgs.parseError.msg[1], 'red' ), se.line);\n        } else {\n          msg += M2C(this.msgs.parseError.msg[2], 'red');\n        }\n      } else if (ex.inner && (ex.inner.line != null) && (ex.inner.col != null)) {\n        msg += printf( M2C( this.msgs.parseError.msg[0], 'red' ), ex.inner.line, ex.inner.col);\n      } else {\n        msg += ex;\n      }\n      msg += this.msgs.invalidOptionsFile.msg[1];\n      etype = 'error';\n      break;\n\n    case HMSTATUS.optionsFileNotFound:\n      msg = M2C( this.msgs.optionsFileNotFound.msg );\n      etype = 'error';\n      break;\n\n    case HMSTATUS.unknownSchema:\n      msg = M2C( this.msgs.unknownSchema.msg[0] );\n      //msg += \"\\n\" + M2C( @msgs.unknownSchema.msg[1], 'yellow' )\n      etype = 'error';\n      break;\n\n    case HMSTATUS.themeHelperLoad:\n      msg = printf(M2C( this.msgs.themeHelperLoad.msg ), ex.glob);\n      etype = 'error';\n      break;\n\n    case HMSTATUS.invalidSchemaVersion:\n      msg = printf(M2C( this.msgs.invalidSchemaVersion.msg ), ex.data);\n      etype = 'error';\n      break;\n  }\n\n  return {\n    msg,              // The error message to display\n    withStack,  // Whether to include the stack\n    quit,\n    etype\n  };\n};\n"
  },
  {
    "path": "src/cli/help/analyze.txt",
    "content": "**analyze** | Analyze a resume for statistical insight\n\nUsage:\n\n   **hackmyresume ANALYZE <resume>**\n\n   The ANALYZE command evaluates the specified resume(s) for\n   coverage, duration, gaps, keywords, and other metrics.\n\n   This command can be run against multiple resumes. Each\n   will be analyzed in turn.\n\nParameters:\n\n   **<resume>**\n\n      Path to a FRESH or JRS resume. Multiple resumes can be\n      specified, separated by spaces.\n\n      hackmyresume ANALYZE resume.json\n      hackmyresume ANALYZE r1.json r2.json r3.json\n\nOptions:\n\n   **None.**\n"
  },
  {
    "path": "src/cli/help/build.txt",
    "content": "**build** | Generate themed resumes in multiple formats\n\nUsage:\n\n   **hackmyresume BUILD <resume> TO <target> [--theme]**\n      **[--pdf] [--no-escape] [--private]**\n\n   The BUILD command generates themed resumes and CVs in\n   multiple formats. Use it to create outbound resumes in\n   specific formats such HTML, MS Word, and PDF.\n\nParameters:\n\n   **<resume>**\n\n      Path to a FRESH or JRS resume (*.json) containing your\n      resume data. Multiple resumes may be specified.\n\n      If multiple resumes are specified, they will be merged\n      into a single resume prior to transformation.\n\n   **<target>**\n\n      Path to the desired output resume. Multiple resumes\n      may be specified. The file extension will determine\n      the format.\n\n         .all        Generate all supported formats\n         .html       HTML 5\n         .doc        MS Word\n         .pdf        Adobe Acrobat PDF\n         .txt        plain text\n         .md         Markdown\n         .png        PNG Image\n         .latex      LaTeX\n\n      Note: not all formats are supported by all themes!\n      Check the theme's documentation for details or use\n      the .all extension to build all available formats.\n\nOptions:\n\n   **--theme -t <theme-name-or-path>**\n\n      Path to a FRESH or JSON Resume theme OR the name of a\n      built-in theme. Valid theme names are 'modern',\n      'positive', 'compact', 'awesome', and 'basis'.\n\n   **--pdf -p <engine>**\n\n      Specify the PDF engine to use. Legal values are\n      'none', 'wkhtmltopdf', 'phantom', or 'weasyprint'.\n\n   **--no-escape**\n\n      Disable escaping / encoding of resume data during\n      resume generation. Handlebars themes only.\n\n   **--private**\n\n      Include resume fields marked as private.\n\nNotes:\n\nThe BUILD command can be run against multiple source as well\nas multiple target resumes. If multiple source resumes are\nprovided, they will be merged into a single source resume\nbefore generation. If multiple output resumes are provided,\neach will be generated in turn.\n"
  },
  {
    "path": "src/cli/help/convert.txt",
    "content": "**convert** | Convert resumes between FRESH and JRS formats\n\nUsage:\n\n   **hackmyresume CONVERT <resume> TO <target> [--format]**\n\n   The CONVERT command converts one or more resume documents\n   between the FRESH Resume Schema and JSON Resume formats.\n\nParameters:\n\n   **<resume>**\n\n      Path to a FRESH or JRS resume. Multiple resumes can be\n      specified.\n\n   **<targets>**\n\n      The path of the converted resume. Multiple resumes can\n      be specified, one per provided input resume.\n\nOptions:\n\n   **--format -f <fmt>**\n\n      The desired format for the new resume(s). Valid values\n      are 'FRESH', 'JRS', or, to target the latest edge\n      version of the JSON Resume Schema, 'JRS@1'.\n\n      If this parameter is omitted, the destination format\n      will be inferred from the source resume's format. If\n      the source format is FRESH, the destination format\n      will be JSON Resume, and vice-versa.\n"
  },
  {
    "path": "src/cli/help/help.txt",
    "content": "**help** | View help on a specific HackMyResume command\n\nUsage:\n\n   **hackmyresume HELP [<command>]**\n\n   The HELP command displays help information for a specific\n   HackMyResume command, including the HELP command itself.\n\nParameters:\n\n   **<command>**\n\n      The HackMyResume command to view help information for.\n      Must be BUILD, NEW, CONVERT, ANALYZE, VALIDATE, PEEK,\n      or HELP.\n\n         hackmyresume help convert\n         hackmyresume help help\n\nOptions:\n\n   **None.**\n"
  },
  {
    "path": "src/cli/help/new.txt",
    "content": "**new** | Create a new FRESH or JRS resume document\n\nUsage:\n\n   **hackmyresume NEW <fileName> [--format]**\n\n   The NEW command generates a new resume document in FRESH\n   or JSON Resume format. This document can serve as an\n   official source of truth for your resume and career data\n   as well an input to tools like HackMyResume.\n\nParameters:\n\n   **<fileName>**\n\n      The filename (relative or absolute path) of the resume\n      to be created. Multiple resume paths can be specified,\n      and each will be created in turn.\n\n         hackmyresume NEW resume.json\n         hackmyresume NEW r1.json foo/r2.json ../r3.json\n\nOptions:\n\n   **--format -f <fmt>**\n\n      The desired format for the new resume(s). Valid values\n      are 'FRESH', 'JRS', or, to target the latest edge\n      version of the JSON Resume Schema, 'JRS@1'.\n"
  },
  {
    "path": "src/cli/help/peek.txt",
    "content": "**peek** | View portions of a resume from the command line\n\nUsage:\n\n   **hackmyresume PEEK <resume> <at>**\n\n   The PEEK command displays a specific piece or part of the\n   resume without requiring the resume to be opened in an\n   editor.\n\nParameters:\n\n   **<resume>**\n\n     Path to a FRESH or JRS resume. Multiple resumes can be\n     specified, separated by spaces.\n\n         hackmyresume PEEK r1.json r2.json r3.json \"employment.history[2]\"\n\n   **<at>**\n\n      The resume property or field to be displayed. Can be\n      any valid resume path, for example:\n\n         education[0]\n         info.name\n         employment.history[3].start\n\nOptions:\n\n   **None.**\n"
  },
  {
    "path": "src/cli/help/use.txt",
    "content": "**HackMyResume** | A Swiss Army knife for resumes and CVs\n\nUsage:\n\n   **hackmyresume [--version] [--help] [--silent] [--debug]**\n      **[--options] [--no-colors] <command> [<args>]**\n\nCommands: (type \"hackmyresume help COMMAND\" for details)\n\n   **BUILD**         Build your resume to the destination format(s).\n   **ANALYZE**       Analyze your resume for keywords, gaps, and metrics.\n   **VALIDATE**      Validate your resume for errors and typos.\n   **NEW**           Create a new resume in FRESH or JSON Resume format.\n   **CONVERT**       Convert your resume between FRESH and JSON Resume.\n   **PEEK**          View a specific field or element on your resume.\n   **HELP**          View help on a specific HackMyResume command.\n\nCommon Tasks:\n\n   Generate a resume in a specific format (HTML, Word, PDF, etc.)\n\n      **hackmyresume build rez.json to out/rez.html**\n      **hackmyresume build rez.json to out/rez.doc**\n      **hackmyresume build rez.json to out/rez.pdf**\n      **hackmyresume build rez.json to out/rez.txt**\n      **hackmyresume build rez.json to out/rez.md**\n      **hackmyresume build rez.json to out/rez.png**\n      **hackmyresume build rez.json to out/rez.tex**\n\n   Build a resume to ALL available formats:\n\n      **hackmyresume build rez.json to out/rez.all**\n\n   Build a resume with a specific theme:\n\n      **hackmyresume build rez.json to out/rez.all -t themeName**\n\n   Create a new empty resume:\n\n      **hackmyresume new rez.json**\n\n   Convert a resume between FRESH and JRS formats:\n\n      **hackmyresume convert rez.json converted.json**\n\n   Analyze a resume for important metrics\n\n      **hackmyresume analyze rez.json**\n\n   Find more resume themes:\n\n      **https://www.npmjs.com/search?q=jsonresume-theme**\n      **https://www.npmjs.com/search?q=fresh-theme**\n      **https://github.com/fresh-standard/fresh-themes**\n\n   Validate a resume's structure and syntax:\n\n      **hackmyresume validate resume.json**\n\n   View help on a specific command:\n\n      **hackmyresume help [build|convert|new|analyze|validate|peek|help]**\n\n   Submit a bug or request:\n\n      **https://githut.com/hacksalot/HackMyResume/issues**\n\nHackMyResume is free and open source software published\nunder the MIT license. For more information, visit the\nHackMyResume website or GitHub project page.\n"
  },
  {
    "path": "src/cli/help/validate.txt",
    "content": "**validate** | Validate a resume for correctness\n\nUsage:\n\n   **hackmyresume VALIDATE <resume> [--assert]**\n\n   The VALIDATE command validates a FRESH or JRS document\n   against its governing schema, verifying that the resume\n   is correctly structured and formatted.\n\nParameters:\n\n   **<resume>**\n\n      Path to a FRESH or JRS resume. Multiple resumes can be\n      specified.\n\n         hackmyresume ANALYZE resume.json\n         hackmyresume ANALYZE r1.json r2.json r3.json\n\nOptions:\n\n   **--assert -a**\n\n      Tell HackMyResume to return a non-zero process exit\n      code if a resume fails to validate.\n"
  },
  {
    "path": "src/cli/index.js",
    "content": "#! /usr/bin/env node\n\n\n\n/**\nCommand-line interface (CLI) for HackMyResume.\n@license MIT. See LICENSE.md for details.\n@module index.js\n*/\n\n\n\ntry {\n\n  require('./main')( process.argv );\n\n}\ncatch( ex ) {\n\n  require('./error').err( ex, true );\n\n}\n"
  },
  {
    "path": "src/cli/main.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the `main` function.\n@module cli/main\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst HMR = require('../index');\nconst PKG = require('../../package.json');\nconst FS = require('fs');\nconst EXTEND = require('extend');\nconst chalk = require('chalk');\nconst PATH = require('path');\nconst HMSTATUS = require('../core/status-codes');\nconst safeLoadJSON = require('../utils/safe-json-loader');\n//StringUtils = require '../utils/string.js'\nconst _ = require('underscore');\nconst OUTPUT = require('./out');\nconst PAD = require('string-padding');\nconst { Command } = require('commander');\nconst M2C = require('../utils/md2chalk');\nconst printf = require('printf');\nconst _opts = { };\nconst _title = chalk.white.bold(`\\n*** HackMyResume v${PKG.version} ***`);\nconst _out = new OUTPUT( _opts );\nconst _err = require('./error');\nlet _exitCallback = null;\n\n\n\n/*\nA callable implementation of the HackMyResume CLI. Encapsulates the command\nline interface as a single method accepting a parameter array.\n@alias module:cli/main.main\n@param rawArgs {Array} An array of command-line parameters. Will either be\nprocess.argv (in production) or custom parameters (in test).\n*/\nmodule.exports = function( rawArgs, exitCallback ) {\n\n  const initInfo = initialize( rawArgs, exitCallback );\n  if (initInfo === null) {\n    return;\n  }\n\n  const { args } = initInfo;\n\n  // Create the top-level (application) command...\n  const program = new Command('hackmyresume')\n    .version(PKG.version)\n    .description(chalk.yellow.bold('*** HackMyResume ***'))\n    .option('-s --silent', 'Run in silent mode')\n    .option('--no-color', 'Disable colors')\n    .option('--color', 'Enable colors')\n    .option('-d --debug', 'Enable diagnostics', false)\n    .option('-a --assert', 'Treat warnings as errors', false)\n    .option('-v --version', 'Show the version')\n    .allowUnknownOption();\n  program.jsonArgs = initInfo.options;\n\n  // Create the NEW command\n  program\n    .command('new')\n    .arguments('<sources...>')\n    .option('-f --format <fmt>', 'FRESH or JRS format', 'FRESH')\n    .alias('create')\n    .description('Create resume(s) in FRESH or JSON RESUME format.')\n    .action((function( sources ) {\n      execute.call( this, sources, [], this.opts(), logMsg);\n    })\n  );\n\n  // Create the VALIDATE command\n  program\n    .command('validate')\n    .arguments('<sources...>')\n    .description('Validate a resume in FRESH or JSON RESUME format.')\n    .action(function(sources) {\n      execute.call( this, sources, [], this.opts(), logMsg);\n    });\n\n  // Create the CONVERT command\n  program\n    .command('convert')\n    .description('Convert a resume to/from FRESH or JSON RESUME format.')\n    .option('-f --format <fmt>', 'FRESH or JRS format and optional version', undefined)\n    .action(function() {\n      const x = splitSrcDest.call( this );\n      execute.call( this, x.src, x.dst, this.opts(), logMsg);\n    });\n\n  // Create the ANALYZE command\n  program\n    .command('analyze')\n    .arguments('<sources...>')\n    .option('--private', 'Include resume fields marked as private', false)\n    .description('Analyze one or more resumes.')\n    .action(function( sources ) {\n      execute.call( this, sources, [], this.opts(), logMsg);\n    });\n\n  // Create the PEEK command\n  program\n    .command('peek')\n    .arguments('<sources...>')\n    .description('Peek at a resume field or section')\n    //.action(( sources, sectionOrField ) ->\n    .action(function( sources ) {\n      const dst = (sources && (sources.length > 1)) ? [sources.pop()] : [];\n      execute.call( this, sources, dst, this.opts(), logMsg);\n    });\n\n  // Create the BUILD command\n  program\n    .command('build')\n    .alias('generate')\n    .option('-t --theme <theme>', 'Theme name or path')\n    .option('-n --no-prettify', 'Disable HTML prettification', true)\n    .option('-c --css <option>', 'CSS linking / embedding')\n    .option('-p --pdf <engine>', 'PDF generation engine')\n    .option('--no-sort', 'Sort resume sections by date', false)\n    .option('--tips', 'Display theme tips and warnings.', false)\n    .option('--private', 'Include resume fields marked as private', false)\n    .option('--no-escape', 'Turn off encoding in Handlebars themes.', false)\n    .description('Generate resume to multiple formats')\n    //.action(( sources, targets, options ) ->\n    .action(function() {\n      const x = splitSrcDest.call( this );\n      execute.call( this, x.src, x.dst, this.opts(), logMsg);\n    });\n\n  // Create the HELP command\n  program\n    .command('help')\n    .arguments('[command]')\n    .description('Get help on a HackMyResume command')\n    .action(function( cmd ) {\n      cmd = cmd || 'use';\n      const manPage = FS.readFileSync(\n        PATH.join(__dirname, `help/${cmd}.txt`),\n        'utf8');\n      _out.log(M2C(manPage, 'white', 'yellow.bold'));\n  });\n\n  program.parse( args );\n\n  if (!program.args.length) {\n    throw {fluenterror: 4};\n  }\n};\n\n\n\n/* Massage command-line args and setup Commander.js. */\nvar initialize = function( ar, exitCallback ) {\n\n  _exitCallback = exitCallback || process.exit;\n  const o = initOptions(ar);\n  if (o.ex) {\n    _err.init(false, true, false);\n    if( o.ex.op === 'parse' ) {\n      _err.err({\n        fluenterror: o.ex.op === 'parse' ? HMSTATUS.invalidOptionsFile : HMSTATUS.optionsFileNotFound,\n        inner: o.ex.inner,\n        quit: true\n      });\n    } else {\n      _err.err({fluenterror: HMSTATUS.optionsFileNotFound, inner: o.ex.inner, quit: true});\n    }\n    return null;\n  }\n  o.silent || logMsg( _title );\n\n  // Emit debug prelude if --debug was specified\n  if (o.debug) {\n    _out.log(chalk.cyan('The -d or --debug switch was specified. DEBUG mode engaged.'));\n    _out.log('');\n    _out.log(chalk.cyan(PAD('  Platform:',25, null, PAD.RIGHT)) + chalk.cyan.bold( process.platform === 'win32' ? 'windows' : process.platform ));\n    _out.log(chalk.cyan(PAD('  Node.js:',25, null, PAD.RIGHT)) + chalk.cyan.bold( process.version ));\n    _out.log(chalk.cyan(PAD('  HackMyResume:',25, null, PAD.RIGHT)) + chalk.cyan.bold(`v${PKG.version}` ));\n    _out.log(chalk.cyan(PAD('  FRESCA:',25, null, PAD.RIGHT)) + chalk.cyan.bold( PKG.dependencies.fresca ));\n    //_out.log(chalk.cyan(PAD('  fresh-themes:',25, null, PAD.RIGHT)) + chalk.cyan.bold( PKG.dependencies['fresh-themes'] ))\n    //_out.log(chalk.cyan(PAD('  fresh-jrs-converter:',25, null, PAD.RIGHT)) + chalk.cyan.bold( PKG.dependencies['fresh-jrs-converter'] ))\n    _out.log('');\n  }\n\n  _err.init(o.debug, o.assert, o.silent);\n\n  // Handle invalid verbs here (a bit easier here than in commander.js)...\n  if (o.verb && !HMR.verbs[ o.verb ] && !HMR.alias[ o.verb ] && (o.verb !== 'help')) {\n    _err.err({fluenterror: HMSTATUS.invalidCommand, quit: true, attempted: o.orgVerb}, true);\n  }\n\n  // Override the .missingArgument behavior\n  Command.prototype.missingArgument = function() {\n    if (this.name() !== 'help') {\n      _err.err({\n        verb: this.name(),\n        fluenterror: HMSTATUS.resumeNotFound\n      }\n        , true);\n    }\n  };\n\n  // Override the .helpInformation behavior\n  Command.prototype.helpInformation = function() {\n    const manPage = FS.readFileSync(\n      PATH.join(__dirname, 'help/use.txt'), 'utf8' );\n    return M2C(manPage, 'white', 'yellow');\n  };\n\n  return {\n    args: o.args,\n    options: o.json\n  };\n};\n\n\n\n/* Init options prior to setting up command infrastructure. */\nvar initOptions = function( ar ) {\n\n  let oJSON, oVerb;\n  oVerb;\n  let verb = '';\n  const args = ar.slice();\n  const cleanArgs = args.slice( 2 );\n  oJSON;\n\n  if (cleanArgs.length) {\n\n    // Support case-insensitive sub-commands (build, generate, validate, etc)\n    const vidx = _.findIndex(cleanArgs, v => v[0] !== '-');\n    if (vidx !== -1) {\n      oVerb = cleanArgs[ vidx ];\n      verb = (args[ vidx + 2 ] = oVerb.trim().toLowerCase());\n    }\n\n    // Remove --options --opts -o and process separately\n    const optsIdx = _.findIndex(cleanArgs, v => (v === '-o') || (v === '--options') || (v === '--opts'));\n\n    if (optsIdx !== -1) {\n      let optStr = cleanArgs[ optsIdx + 1];\n      args.splice( optsIdx + 2, 2 );\n      if (optStr && (optStr = optStr.trim())) {\n        //var myJSON = JSON.parse(optStr);\n        if( optStr[0] === '{') {\n          // TODO: remove use of evil(). - hacksalot\n          /* jshint ignore:start */\n          oJSON = eval(`(${optStr})`); // jshint ignore:line <-- no worky\n          /* jshint ignore:end */\n        } else {\n          const inf = safeLoadJSON( optStr );\n          if( !inf.ex ) {\n            oJSON = inf.json;\n          } else {\n            return inf;\n          }\n        }\n      }\n    }\n  }\n\n  // Grab the --debug flag, --silent, --assert and --no-color flags\n  const isDebug = _.some(args, v => (v === '-d') || (v === '--debug'));\n  const isSilent = _.some(args, v => (v === '-s') || (v === '--silent'));\n  const isAssert = _.some(args, v => (v === '-a') || (v === '--assert'));\n  const isMono = _.some(args, v => v === '--no-color');\n  const isNoEscape = _.some(args, v => v === '--no-escape');\n\n  return {\n    color: !isMono,\n    debug: isDebug,\n    silent: isSilent,\n    assert: isAssert,\n    noescape: isNoEscape,\n    orgVerb: oVerb,\n    verb,\n    json: oJSON,\n    args\n  };\n};\n\n\n\n/* Invoke a HackMyResume verb. */\nvar execute = function( src, dst, opts, log ) {\n\n  // Create the verb\n  const v = new (HMR.verbs[ this.name() ])();\n\n  // Initialize command-specific options\n  loadOptions.call(this, opts, this.parent.jsonArgs);\n\n  // Set up error/output handling\n  _opts.errHandler = v;\n  _out.init(_opts);\n\n  // Hook up event notifications\n  v.on('hmr:status', function() { return _out.do.apply(_out, arguments); });\n  v.on('hmr:error', function() {  return _err.err.apply(_err, arguments); });\n\n  // Invoke the verb using promise syntax\n  const prom = v.invoke.call(v, src, dst, _opts, log);\n  prom.then(executeSuccess, executeFail);\n};\n\n\n\n/* Success handler for verb invocations. Calls process.exit by default */\nvar executeSuccess = function() {};\n  // Can't call _exitCallback here (process.exit) when PDF is running in BK\n  //_exitCallback 0; return\n\n\n\n/* Failure handler for verb invocations. Calls process.exit by default */\nvar executeFail = function(err) {\n  //console.dir err\n  let finalErrorCode = -1;\n  if (err) {\n    if (err.fluenterror) {\n      finalErrorCode = err.fluenterror;\n    } else if (err.length) {\n      finalErrorCode = err[0].fluenterror;\n    } else {\n      finalErrorCode = err;\n    }\n  }\n  if (_opts.debug) {\n    const msgs = require('./msg').errors;\n    logMsg(printf(M2C( msgs.exiting.msg, 'cyan' ), finalErrorCode));\n    if (err.stack) { logMsg(err.stack); }\n  }\n  _exitCallback(finalErrorCode);\n};\n\n\n\n/*\nInitialize HackMyResume options.\nTODO: Options loading is a little hacky, for two reasons:\n  - Commander.js idiosyncracies\n  - Need to accept JSON inputs from the command line.\n*/\nvar loadOptions = function( o, cmdO ) {\n\n  // o and this.opts() seem to be the same (command-specific options)\n\n  // Load the specified options file (if any) and apply options\n  if( cmdO ) {\n    o = EXTEND(true, o, cmdO);\n  }\n\n  // Merge in command-line options\n  o = EXTEND( true, o, this.opts() );\n\n  // Kludge parent-level options until piping issue is resolved\n  if ((this.parent.silent !== undefined) && (this.parent.silent !== null)) {\n    o.silent = this.parent.silent;\n  }\n  if ((this.parent.debug !== undefined) && (this.parent.debug !== null)) {\n    o.debug = this.parent.debug;\n  }\n  if ((this.parent.assert !== undefined) && (this.parent.assert !== null)) {\n    o.assert = this.parent.assert;\n  }\n\n  if (o.debug) {\n    logMsg(chalk.cyan('OPTIONS:') + '\\n');\n    _.each(o, (val, key) =>\n      logMsg(chalk.cyan('  %s') + chalk.cyan.bold(' %s'),\n        PAD(key,22,null,PAD.RIGHT), val)\n    );\n    logMsg('');\n  }\n\n  // Cache\n  EXTEND( true, _opts, o );\n};\n\n/* Split multiple command-line filenames by the 'TO' keyword */\nvar splitSrcDest = function() {\n\n  const params = this.parent.args.filter(j => String.is(j));\n  if (params.length === 0) {\n    //tmpName = @name()\n    throw { fluenterror: HMSTATUS.resumeNotFound, verb: this.name(), quit: true };\n  }\n\n  // Find the TO keyword, if any\n  const splitAt = _.findIndex( params, p => p.toLowerCase() === 'to');\n\n  // TO can't be the last keyword\n  if ((splitAt === (params.length - 1)) && (splitAt !== -1)) {\n    logMsg(chalk.yellow('Please ') +\n      chalk.yellow.bold('specify an output file') +\n      chalk.yellow(' for this operation or ') +\n      chalk.yellow.bold('omit the TO keyword') +\n      chalk.yellow('.') );\n    return;\n  }\n\n  return {\n    src: params.slice(0, splitAt === -1 ? undefined : splitAt ),\n    dst: splitAt === -1 ? [] : params.slice( splitAt + 1 )\n  };\n};\n\n\n\n/* Simple logging placeholder. */\nvar logMsg = function() {\n  // eslint-disable-next-line no-console\n  return _opts.silent || console.log.apply( console.log, arguments );\n};\n"
  },
  {
    "path": "src/cli/msg.js",
    "content": "/**\nMessage-handling routines for HackMyResume.\n@module cli/msg\n@license MIT. See LICENSE.md for details.\n*/\n\n\nconst PATH = require('path');\nconst YAML = require('yamljs');\nmodule.exports = YAML.load(PATH.join(__dirname, 'msg.yml'));\n"
  },
  {
    "path": "src/cli/msg.yml",
    "content": "events:\n  begin:\n    msg: Invoking **%s** command.\n  beforeCreate:\n    msg: Creating new **%s** resume: **%s**\n  afterCreate:\n    msg: Creating new **%s** resume: **%s**\n  afterRead:\n    msg: Reading **%s** resume: **%s**\n  beforeTheme:\n    msg: Verifying **%s** theme.\n  afterTheme:\n    msg: Verifying outputs:  ???\n  beforeMerge:\n    msg:\n      - \"Merging **%s**\"\n      - \" onto **%s**\"\n  applyTheme:\n    msg: Applying **%s** theme (**%s** format%s)\n  afterBuild:\n    msg:\n      - \"The **%s** theme says:\"\n      - |\n          \"For best results view JSON Resume themes over a\n          local or remote HTTP connection. For example:\n\n            npm install http-server -g\n            http-server <resume-folder>\n\n          For more information, see the README.\"\n  afterGenerate:\n    msg:\n      - \" (with %s)\"\n      - \"Skipping %s resume: %s\"\n      - \"Generating **%s** resume: **%s**\"\n  beforeAnalyze:\n    msg: \"Analyzing **%s** resume: **%s**\"\n  beforeConvert:\n    msg: \"Converting **%s** (**%s**) to **%s** (**%s**)\"\n  afterValidate:\n    msg:\n      - \"Validating **%s** against the **%s** schema: \"\n      - \"VALID!\"\n      - \"INVALID\"\n      - \"BROKEN\"\n      - \"MISSING\"\n      - \"ERROR\"\n  beforePeek:\n    msg:\n      - Peeking at **%s** in **%s**\n      - Peeking at **%s**\n  afterPeek:\n    msg: \"The specified key **%s** was not found in **%s**.\"\n  afterInlineConvert:\n    msg: Converting **%s** to **%s** format.\nerrors:\n  themeNotFound:\n    msg: >\n      **Couldn't find the '%s' theme.** Please specify the name of a preinstalled\n      FRESH theme or the path to a locally installed FRESH or JSON Resume theme.\n  copyCSS:\n    msg: Couldn't copy CSS file to destination folder.\n  resumeNotFound:\n    msg: Please **feed me a resume** in FRESH or JSON Resume format.\n  missingCommand:\n    msg: Please **give me a command**\n  invalidCommand:\n    msg: Invalid command: '%s'\n  resumeNotFoundAlt:\n    msg: Please **feed me a resume** in either FRESH or JSON Resume format.\n  inputOutputParity:\n    msg: Please **specify an output file name** for every input file you wish to convert.\n  createNameMissing:\n    msg: Please **specify the filename** of the resume to create.\n  pdfGeneration:\n    msg: PDF generation failed. Make sure wkhtmltopdf is installed and accessible from your path.\n  invalid:\n    msg: Validation failed and the --assert option was specified.\n  invalidFormat:\n    msg: The **%s** theme doesn't support the **%s** format.\n  notOnPath:\n    msg: %s wasn't found on your system path or is inaccessible. PDF not generated.\n  readError:\n    msg: Reading **???** resume: **%s**\n  parseError:\n    msg:\n      - Invalid or corrupt JSON on line %s column %s.\n      - Invalid or corrupt JSON on line %s.\n      - Invalid or corrupt JSON.\n  invalidHelperUse:\n    msg: \"**Warning**: Incorrect use of the **%s** theme helper.\"\n  fileSaveError:\n    msg: An error occurred while writing %s to disk: %s.\n  mixedMerge:\n    msg: \"**Warning:** merging mixed resume types. Errors may occur.\"\n  invokeTemplate:\n    msg: \"An error occurred during template invocation.\"\n  compileTemplate:\n    msg: \"An error occurred during template compilation.\"\n  themeLoad:\n    msg: \"Applying **%s** theme (? formats)\"\n  invalidParamCount:\n    msg: \"Invalid number of parameters. Expected: **%s**.\"\n  missingParam:\n    msg: The '**%s**' parameter was needed but not supplied.\n  createError:\n    msg: Failed to create **'%s'**.\n  exiting:\n    msg: Exiting with status code **%s**.\n  validateError:\n    msg: \"An error occurred during validation:\\n%s\"\n  invalidOptionsFile:\n    msg:\n      - \"The specified options file is invalid:\\n\"\n      - \"\\nMake sure the options file contains valid JSON.\"\n  optionsFileNotFound:\n    msg: \"The specified options file is missing or inaccessible.\"\n  unknownSchema:\n    msg:\n      - \"Unknown resume schema. Did you specify a valid FRESH or JRS resume?\"\n      - |\n          At a minimum, a FRESH resume must include a \"name\" field and a \"meta\"\n          property.\n\n          \"name\": \"John Doe\",\n          \"meta\": {\n            \"format\": \"FRESH@0.1.0\"\n          }\n\n          JRS-format resumes must include a \"basics\" section with a \"name\":\n\n          \"basics\": {\n            \"name\": \"John Doe\"\n          }\n  themeHelperLoad:\n    msg: >-\n      An error occurred while attempting to load the '%s' theme helper. Is the\n      theme correctly installed?\n    dummy: dontcare\n  invalidSchemaVersion:\n    msg: \"'%s' is not recognized as a valid schema version.\"\n"
  },
  {
    "path": "src/cli/out.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nOutput routines for HackMyResume.\n@license MIT. See LICENSE.md for details.\n@module cli/out\n*/\n\n\n\nconst chalk = require('chalk');\nconst HME = require('../core/event-codes');\nconst _ = require('underscore');\nconst M2C = require('../utils/md2chalk.js');\nconst PATH = require('path');\nconst FS = require('fs');\nconst EXTEND = require('extend');\nconst HANDLEBARS = require('handlebars');\nconst YAML = require('yamljs');\nlet printf = require('printf');\nconst pad = require('string-padding');\nconst dbgStyle = 'cyan';\n\n\n\n/** A stateful output module. All HMR console output handled here. */\nclass OutputHandler {\n\n\n\n  constructor( opts ) {\n    this.init(opts);\n  }\n\n\n\n  init(opts) {\n    this.opts = EXTEND( true, this.opts || { }, opts );\n    this.msgs = YAML.load(PATH.join( __dirname, 'msg.yml' )).events;\n  }\n\n\n\n  log() {\n    printf = require('printf');\n    const finished = printf.apply( printf, arguments );\n    return this.opts.silent || console.log( finished ); // eslint-disable-line no-console\n  }\n\n\n\n  do( evt ) {\n\n    const that = this;\n    const L = function() { return that.log.apply( that, arguments ); };\n\n    switch (evt.sub) {\n\n      case HME.begin:\n        return this.opts.debug &&\n        L( M2C( this.msgs.begin.msg, dbgStyle), evt.cmd.toUpperCase() );\n\n      //when HME.beforeCreate\n        //L( M2C( this.msgs.beforeCreate.msg, 'green' ), evt.fmt, evt.file )\n        //break;\n\n      case HME.afterCreate:\n        L( M2C( this.msgs.beforeCreate.msg, evt.isError ? 'red' : 'green' ), evt.fmt, evt.file );\n        break;\n\n      case HME.beforeTheme:\n        return this.opts.debug &&\n          L( M2C( this.msgs.beforeTheme.msg, dbgStyle), evt.theme.toUpperCase() );\n\n      case HME.afterParse:\n        return L( M2C( this.msgs.afterRead.msg, 'gray', 'white.dim'), evt.fmt.toUpperCase(), evt.file );\n\n      case HME.beforeMerge:\n        var msg = '';\n        evt.f.reverse().forEach(function( a, idx ) {\n          return msg += printf( (idx === 0 ? this.msgs.beforeMerge.msg[0] : this.msgs.beforeMerge.msg[1]), a.file );\n        }\n        , this);\n        return L( M2C(msg, (evt.mixed ? 'yellow' : 'gray'), 'white.dim') );\n\n      case HME.applyTheme:\n        this.theme = evt.theme;\n        var numFormats = Object.keys( evt.theme.formats ).length;\n        return L( M2C(this.msgs.applyTheme.msg,\n          evt.status === 'error' ? 'red' : 'gray',\n          evt.status === 'error' ? 'bold' : 'white.dim'),\n          evt.theme.name.toUpperCase(),\n          numFormats, numFormats === 1 ? '' : 's' );\n\n      case HME.end:\n        if (evt.cmd === 'build') {\n          const themeName = this.theme.name.toUpperCase();\n          if (this.opts.tips && (this.theme.message || this.theme.render)) {\n            if (this.theme.message) {\n              L( M2C( this.msgs.afterBuild.msg[0], 'cyan' ), themeName );\n              return L( M2C( this.theme.message, 'white' ));\n            } else if (this.theme.render) {\n              L( M2C( this.msgs.afterBuild.msg[0], 'cyan'), themeName);\n              return L( M2C( this.msgs.afterBuild.msg[1], 'white'));\n            }\n          }\n        }\n        break;\n\n      case HME.afterGenerate:\n        var suffix = '';\n        if (evt.fmt === 'pdf') {\n          if (this.opts.pdf) {\n            if (this.opts.pdf !== 'none') {\n              suffix = printf( M2C( this.msgs.afterGenerate.msg[0], evt.error ? 'red' : 'green' ), this.opts.pdf );\n            } else {\n              L( M2C( this.msgs.afterGenerate.msg[1], 'gray' ), evt.fmt.toUpperCase(), evt.file );\n              return;\n            }\n          }\n        }\n\n        return L( M2C( this.msgs.afterGenerate.msg[2] + suffix, evt.error ? 'red' : 'green' ),\n            pad( evt.fmt.toUpperCase(),4,null,pad.RIGHT ),\n            PATH.relative( process.cwd(), evt.file ) );\n\n      case HME.beforeAnalyze:\n        return L( M2C( this.msgs.beforeAnalyze.msg, 'green' ), evt.fmt, evt.file);\n\n      case HME.afterAnalyze:\n        var { info } = evt;\n        var rawTpl = FS.readFileSync( PATH.join( __dirname, 'analyze.hbs' ), 'utf8');\n        HANDLEBARS.registerHelper( require('../helpers/console-helpers') );\n        var template = HANDLEBARS.compile(rawTpl, { strict: false, assumeObjects: false });\n        var tot = 0;\n        info.keywords.forEach(g => tot += g.count);\n        info.keywords.totalKeywords = tot;\n        var output = template( info );\n        return this.log( chalk.cyan(output) );\n\n      case HME.beforeConvert:\n        return L( M2C( this.msgs.beforeConvert.msg, evt.error ? 'red' : 'green' ),\n          evt.srcFile, evt.srcFmt, evt.dstFile, evt.dstFmt\n        );\n\n      case HME.afterInlineConvert:\n        return L( M2C( this.msgs.afterInlineConvert.msg, 'gray', 'white.dim' ),\n          evt.file, evt.fmt );\n\n      case HME.afterValidate:\n        var style = 'red';\n        var adj = '';\n        var msgs = this.msgs.afterValidate.msg;\n        switch (evt.status) {\n          case 'valid': style = 'green'; adj = msgs[1]; break;\n          case 'invalid': style = 'yellow'; adj = msgs[2]; break;\n          case 'broken': style = 'red'; adj = msgs[3]; break;\n          case 'missing': style = 'red'; adj = msgs[4]; break;\n          case 'unknown': style = 'red'; adj = msgs[5]; break;\n        }\n        evt.schema = evt.schema.replace('jars','JSON Resume').toUpperCase();\n        L(M2C( msgs[0], 'white' ) + chalk[style].bold(adj), evt.file, evt.schema);\n\n        if (evt.violations) {\n          _.each(evt.violations, function(err) {\n            L( chalk.yellow.bold('--> ') +\n               chalk.yellow(err.field.replace('data.','resume.').toUpperCase() +\n               ' ' + err.message));\n          }\n          , this);\n        }\n        return;\n\n      case HME.afterPeek:\n        var sty = evt.error ? 'red' : ( evt.target !== undefined ? 'green' : 'yellow' );\n\n        // \"Peeking at 'someKey' in 'someFile'.\"\n        if (evt.requested) {\n          L(M2C(this.msgs.beforePeek.msg[0], sty), evt.requested, evt.file);\n        } else {\n          L(M2C(this.msgs.beforePeek.msg[1], sty), evt.file);\n        }\n\n        // If the key was present, print it\n        if ((evt.target !== undefined) && !evt.error) {\n          // eslint-disable-next-line no-console\n          return console.dir( evt.target, { depth: null, colors: true } );\n\n        // If the key was not present, but no error occurred, print it\n        } else if (!evt.error) {\n          return L(M2C( this.msgs.afterPeek.msg, 'yellow'), evt.requested, evt.file);\n\n        } else if (evt.error) {\n          return L(chalk.red( evt.error.inner.inner ));\n        }\n        break;\n    }\n  }\n}\n\nmodule.exports = OutputHandler;\n"
  },
  {
    "path": "src/core/default-formats.js",
    "content": "/*\nEvent code definitions.\n@module core/default-formats\n@license MIT. See LICENSE.md for details.\n*/\n\n/** Supported resume formats. */\nmodule.exports = [\n  { name: 'html', ext: 'html', gen: new (require('../generators/html-generator'))() },\n  { name: 'txt',  ext: 'txt', gen: new (require('../generators/text-generator'))()  },\n  { name: 'doc',  ext: 'doc',  fmt: 'xml', gen: new (require('../generators/word-generator'))() },\n  { name: 'pdf',  ext: 'pdf', fmt: 'html', is: false, gen: new (require('../generators/html-pdf-cli-generator'))() },\n  { name: 'png',  ext: 'png', fmt: 'html', is: false, gen: new (require('../generators/html-png-generator'))() },\n  { name: 'md', ext: 'md', fmt: 'txt', gen: new (require('../generators/markdown-generator'))() },\n  { name: 'json', ext: 'json', gen: new (require('../generators/json-generator'))() },\n  { name: 'yml', ext: 'yml', fmt: 'yml', gen: new (require('../generators/json-yaml-generator'))() },\n  { name: 'latex', ext: 'tex', fmt: 'latex', gen: new (require('../generators/latex-generator'))() }\n];\n"
  },
  {
    "path": "src/core/default-options.js",
    "content": "/*\nEvent code definitions.\n@module core/default-options\n@license MIT. See LICENSE.md for details.\n*/\n\nmodule.exports = {\n  theme: 'modern',\n  prettify: { // ← See https://github.com/beautify-web/js-beautify#options\n    indent_size: 2,\n    unformatted: ['em','strong'],\n    max_char: 80\n  } // ← See lib/html.js in above-linked repo\n};\n    // wrap_line_length: 120, ← Don't use this\n"
  },
  {
    "path": "src/core/empty-jrs.json",
    "content": "{\n  \"basics\": {\n    \"name\": \"\",\n    \"label\": \"\",\n    \"picture\": \"\",\n    \"email\": \"\",\n    \"phone\": \"\",\n    \"degree\": \"\",\n    \"website\": \"\",\n    \"summary\": \"\",\n    \"location\": {\n      \"address\": \"\",\n      \"postalCode\": \"\",\n      \"city\": \"\",\n      \"countryCode\": \"\",\n      \"region\": \"\"\n    },\n    \"profiles\": [{\n      \"network\": \"\",\n      \"username\": \"\",\n      \"url\": \"\"\n    }]\n  },\n\n  \"work\": [{\n    \"company\": \"\",\n    \"position\": \"\",\n    \"website\": \"\",\n    \"startDate\": \"\",\n    \"endDate\": \"\",\n    \"summary\": \"\",\n    \"highlights\": [\n      \"\"\n    ]\n  }],\n\n  \"awards\": [{\n    \"title\": \"\",\n    \"date\": \"\",\n    \"awarder\": \"\",\n    \"summary\": \"\"\n  }],\n\n  \"education\": [{\n    \"institution\": \"\",\n    \"area\": \"\",\n    \"studyType\": \"\",\n    \"startDate\": \"\",\n    \"endDate\": \"\",\n    \"gpa\": \"\",\n    \"courses\": [ \"\" ]\n  }],\n\n  \"publications\": [{\n    \"name\": \"\",\n    \"publisher\": \"\",\n    \"releaseDate\": \"\",\n    \"website\": \"\",\n    \"summary\": \"\"\n  }],\n\n  \"volunteer\": [{\n    \"organization\": \"\",\n    \"position\": \"\",\n    \"website\": \"\",\n    \"startDate\": \"\",\n    \"endDate\": \"\",\n    \"summary\": \"\",\n    \"highlights\": [ \"\" ]\n  }],\n\n  \"skills\": [{\n      \"name\": \"\",\n      \"level\": \"\",\n      \"keywords\": [\"\"]\n  }]\n}\n"
  },
  {
    "path": "src/core/event-codes.js",
    "content": "/*\nEvent code definitions.\n@module core/event-codes\n@license MIT. See LICENSE.md for details.\n*/\n\n\nmodule.exports = {\n  error:            -1,\n  success:          0,\n  begin:            1,\n  end:              2,\n  beforeRead:       3,\n  afterRead:        4,\n  beforeCreate:     5,\n  afterCreate:      6,\n  beforeTheme:      7,\n  afterTheme:       8,\n  beforeMerge:      9,\n  afterMerge:       10,\n  beforeGenerate:   11,\n  afterGenerate:    12,\n  beforeAnalyze:    13,\n  afterAnalyze:     14,\n  beforeConvert:    15,\n  afterConvert:     16,\n  verifyOutputs:    17,\n  beforeParse:      18,\n  afterParse:       19,\n  beforePeek:       20,\n  afterPeek:        21,\n  beforeInlineConvert: 22,\n  afterInlineConvert: 23,\n  beforeValidate:   24,\n  afterValidate:    25,\n  beforeWrite:      26,\n  afterWrite:       27,\n  applyTheme:       28\n};\n"
  },
  {
    "path": "src/core/fluent-date.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS104: Avoid inline assignments\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nThe HackMyResume date representation.\n@license MIT. See LICENSE.md for details.\n@module core/fluent-date\n*/\n\n\n\nconst moment = require('moment');\nrequire('../utils/string');\n\n/**\nCreate a FluentDate from a string or Moment date object. There are a few date\nformats to be aware of here.\n1. The words \"Present\" and \"Now\", referring to the current date\n2. The default \"YYYY-MM-DD\" format used in JSON Resume (\"2015-02-10\")\n3. Year-and-month only (\"2015-04\")\n4. Year-only \"YYYY\" (\"2015\")\n5. The friendly HackMyResume \"mmm YYYY\" format (\"Mar 2015\" or \"Dec 2008\")\n6. Empty dates (\"\", \" \")\n7. Any other date format that Moment.js can parse from\nNote: Moment can transparently parse all or most of these, without requiring us\nto specify a date format...but for maximum parsing safety and to avoid Moment\ndeprecation warnings, it's recommended to either a) explicitly specify the date\nformat or b) use an ISO format. For clarity, we handle these cases explicitly.\n@class FluentDate\n*/\n\nclass FluentDate {\n\n  constructor(dt) {\n    this.rep = this.fmt(dt);\n  }\n\n  static isCurrent(dt) {\n    return !dt || (String.is(dt) && /^(present|now|current)$/.test(dt));\n  }\n}\n\nconst months = {};\nconst abbr = {};\nmoment.months().forEach((m,idx) => months[m.toLowerCase()] = idx+1);\nmoment.monthsShort().forEach((m,idx) => abbr[m.toLowerCase()]=idx+1);\nabbr.sept = 9;\nmodule.exports = FluentDate;\n\nFluentDate.fmt = function( dt, throws ) {\n\n  throws = ((throws === undefined) || (throws === null)) || throws;\n\n  if ((typeof dt === 'string') || dt instanceof String) {\n    dt = dt.toLowerCase().trim();\n    if (/^(present|now|current)$/.test(dt)) { // \"Present\", \"Now\"\n      return moment();\n    } else if (/^\\D+\\s+\\d{4}$/.test(dt)) { // \"Mar 2015\"\n      let left;\n      const parts = dt.split(' ');\n      const month = (months[parts[0]] || abbr[parts[0]]);\n      const temp = parts[1] + '-' + ((left = month < 10) != null ? left : `0${{month : month.toString()}}`);\n      return moment(temp, 'YYYY-MM');\n    } else if (/^\\d{4}-\\d{1,2}$/.test(dt)) { // \"2015-03\", \"1998-4\"\n      return moment(dt, 'YYYY-MM');\n    } else if (/^\\s*\\d{4}\\s*$/.test(dt)) { // \"2015\"\n      return moment(dt, 'YYYY');\n    } else if (/^\\s*$/.test(dt)) { // \"\", \" \"\n      return moment();\n    } else {\n      const mt = moment(dt);\n      if (mt.isValid()) {\n        return mt;\n      }\n      if (throws) {\n        throw 'Invalid date format encountered.';\n      }\n      return null;\n    }\n  } else {\n    if (!dt) {\n      return moment();\n    } else if (dt.isValid && dt.isValid()) {\n      return dt;\n    }\n    if (throws) {\n      throw 'Unknown date object encountered.';\n    }\n    return null;\n  }\n};\n"
  },
  {
    "path": "src/core/fresh-resume.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the FRESHResume class.\n@license MIT. See LICENSE.md for details.\n@module core/fresh-resume\n*/\n\n\n\nconst FS = require('fs');\nconst extend = require('extend');\nlet validator = require('is-my-json-valid');\nconst _ = require('underscore');\nconst __ = require('lodash');\nconst XML = require('xml-escape');\nconst MD = require('marked');\nconst CONVERTER = require('fresh-jrs-converter');\nconst JRSResume = require('./jrs-resume');\n\n\n\n/**\nA FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume\nobject is an instantiation of that JSON decorated with utility methods.\n@constructor\n*/\nclass FreshResume {// extends AbstractResume\n\n\n\n  /** Initialize the the FreshResume from JSON string data. */\n  parse( stringData, opts ) {\n    this.imp = this.imp != null ? this.imp : {raw: stringData};\n    return this.parseJSON(JSON.parse( stringData ), opts);\n  }\n\n\n\n  /**\n  Initialize the FreshResume from JSON.\n  Open and parse the specified FRESH resume. Merge the JSON object model onto\n  this Sheet instance with extend() and convert sheet dates to a safe &\n  consistent format. Then sort each section by startDate descending.\n  @param rep {Object} The raw JSON representation.\n  @param opts {Object} Resume loading and parsing options.\n  {\n    date: Perform safe date conversion.\n    sort: Sort resume items by date.\n    compute: Prepare computed resume totals.\n  }\n  */\n  parseJSON( rep, opts ) {\n\n    let scrubbed;\n    if (opts && opts.privatize) {\n      // Ignore any element with the 'ignore: true' or 'private: true' designator.\n      const scrubber = require('../utils/resume-scrubber');\n      var ret = scrubber.scrubResume(rep, opts);\n      scrubbed = ret.scrubbed;\n    }\n\n    // Now apply the resume representation onto this object\n    extend(true, this, opts && opts.privatize ? scrubbed : rep);\n\n    // If the resume has already been processed, then we are being called from\n    // the .dupe method, and there's no need to do any post processing\n    if (!(this.imp != null ? this.imp.processed : undefined)) {\n      // Set up metadata TODO: Clean up metadata on the object model.\n      opts = opts || { };\n      if ((opts.imp === undefined) || opts.imp) {\n        this.imp = this.imp || { };\n        this.imp.title = (opts.title || this.imp.title) || this.name;\n        if (!this.imp.raw) {\n          this.imp.raw = JSON.stringify(rep);\n        }\n      }\n      this.imp.processed = true;\n      // Parse dates, sort dates, and calculate computed values\n      ((opts.date === undefined) || opts.date) && _parseDates.call( this );\n      ((opts.sort === undefined) || opts.sort) && this.sort();\n      ((opts.compute === undefined) || opts.compute) && (this.computed = {\n         numYears: this.duration(),\n         keywords: this.keywords()\n      });\n    }\n\n    return this;\n  }\n\n\n\n  /** Save the sheet to disk (for environments that have disk access). */\n  save( filename ) {\n    this.imp.file = filename || this.imp.file;\n    FS.writeFileSync(this.imp.file, this.stringify(), 'utf8');\n    return this;\n  }\n\n\n\n  /**\n  Save the sheet to disk in a specific format, either FRESH or JSON Resume.\n  */\n  saveAs( filename, format ) {\n\n    // If format isn't specified, default to FRESH\n    const safeFormat = (format && format.trim()) || 'FRESH';\n\n    // Validate against the FRESH version regex\n    // freshVersionReg = require '../utils/fresh-version-regex'\n    // if (not freshVersionReg().test( safeFormat ))\n    //   throw badVer: safeFormat\n\n    const parts = safeFormat.split('@');\n\n    if (parts[0] === 'FRESH') {\n      this.imp.file = filename || this.imp.file;\n      FS.writeFileSync(this.imp.file, this.stringify(), 'utf8');\n\n    } else if (parts[0] === 'JRS') {\n      const useEdgeSchema = parts.length > 1 ? parts[1] === '1' : false;\n      const newRep = CONVERTER.toJRS(this, {edge: useEdgeSchema});\n      FS.writeFileSync(filename, JRSResume.stringify( newRep ), 'utf8');\n    } else {\n      throw {badVer: safeFormat};\n    }\n    return this;\n  }\n\n\n\n  /**\n  Duplicate this FreshResume instance.\n  This method first extend()s this object onto an empty, creating a deep copy,\n  and then passes the result into a new FreshResume instance via .parseJSON.\n  We do it this way to create a true clone of the object without re-running any\n  of the associated processing.\n  */\n  dupe() {\n    const jso = extend(true, { }, this);\n    const rnew = new FreshResume();\n    rnew.parseJSON(jso, { });\n    return rnew;\n  }\n\n\n\n  /**\n  Convert this object to a JSON string, sanitizing meta-properties along the\n  way.\n  */\n  stringify() { return FreshResume.stringify(this); }\n\n\n\n  /**\n  Create a copy of this resume in which all string fields have been run through\n  a transformation function (such as a Markdown filter or XML encoder).\n  TODO: Move this out of FRESHResume.\n  */\n  transformStrings( filt, transformer ) {\n    const ret = this.dupe();\n    const trx = require('../utils/string-transformer');\n    return trx(ret, filt, transformer);\n  }\n\n\n\n  /**\n  Create a copy of this resume in which all fields have been interpreted as\n  Markdown.\n  */\n  markdownify() {\n\n    const MDIN =  txt  => MD(txt || '' ).replace(/^\\s*<p>|<\\/p>\\s*$/gi, '');\n\n    const trx = function( key, val ) {\n      if (key === 'summary') {\n        return MD(val);\n      }\n      return MDIN(val);\n    };\n\n    return this.transformStrings(['skills','url','start','end','date'], trx);\n  }\n\n\n\n  /**\n  Create a copy of this resume in which all fields have been interpreted as\n  Markdown.\n  */\n  xmlify() {\n    const trx = (key, val) => XML(val);\n    return this.transformStrings([], trx);\n  }\n\n\n\n  /** Return the resume format. */\n  format() { return 'FRESH'; }\n\n\n\n  /**\n  Return internal metadata. Create if it doesn't exist.\n  */\n  i() { return this.imp = this.imp || { }; }\n\n\n\n  /**\n  Return a unique list of all skills declared in the resume.\n  */\n\n  // TODO: Several problems here:\n  // 1) Confusing name. Easily confused with the keyword-inspector module, which\n  // parses resume body text looking for these same keywords. This should probably\n  // be renamed.\n  //\n  // 2) Doesn't bother trying to integrate skills.list with skills.sets if they\n  // happen to declare different skills, and if skills.sets declares ONE skill and\n  // skills.list declared 50, only 1 skill will be registered.\n  //\n  // 3) In the future, skill.sets should only be able to use skills declared in\n  // skills.list. That is, skills.list is the official record of a candidate's\n  // declared skills. skills.sets is just a way of grouping those into skillsets\n  // for easier consumption.\n\n  keywords() {\n    let flatSkills = [];\n    if (this.skills) {\n      if (this.skills.sets) {\n        flatSkills = this.skills.sets.map(sk => sk.skills).reduce( (a,b) => a.concat(b));\n      } else if (this.skills.list) {\n        flatSkills = flatSkills.concat( this.skills.list.map(sk => sk.name) );\n      }\n      flatSkills = _.uniq(flatSkills);\n    }\n    return flatSkills;\n  }\n\n\n\n  /**\n  Reset the sheet to an empty state. TODO: refactor/review\n  */\n  clear( clearMeta ) {\n    clearMeta = ((clearMeta === undefined) && true) || clearMeta;\n    if (clearMeta) { delete this.imp; }\n    delete this.computed; // Don't use Object.keys() here\n    delete this.employment;\n    delete this.service;\n    delete this.education;\n    delete this.recognition;\n    delete this.reading;\n    delete this.writing;\n    delete this.interests;\n    delete this.skills;\n    return delete this.social;\n  }\n\n\n\n  /**\n  Get a safe count of the number of things in a section.\n  */\n  count( obj ) {\n    if (!obj) { return 0; }\n    if (obj.history) { return obj.history.length; }\n    if (obj.sets) { return obj.sets.length; }\n    return obj.length || 0;\n  }\n\n\n\n  /** Add work experience to the sheet. */\n  add( moniker ) {\n    const defSheet = FreshResume.default();\n    const newObject =\n      defSheet[moniker].history\n      ? extend( true, {}, defSheet[ moniker ].history[0] )\n      :\n        moniker === 'skills'\n        ? extend( true, {}, defSheet.skills.sets[0] )\n        : extend( true, {}, defSheet[ moniker ][0] );\n\n    this[ moniker ] = this[ moniker ] || [];\n    if (this[ moniker ].history) {\n      this[ moniker ].history.push(newObject);\n    } else if (moniker === 'skills') {\n      this.skills.sets.push(newObject);\n    } else {\n      this[ moniker ].push(newObject);\n    }\n    return newObject;\n  }\n\n\n\n  /**\n  Determine if the sheet includes a specific social profile (eg, GitHub).\n  */\n  hasProfile( socialNetwork ) {\n    socialNetwork = socialNetwork.trim().toLowerCase();\n    return this.social && _.some(this.social, p => p.network.trim().toLowerCase() === socialNetwork);\n  }\n\n\n\n  /** Return the specified network profile. */\n  getProfile( socialNetwork ) {\n    socialNetwork = socialNetwork.trim().toLowerCase();\n    return this.social && _.find(this.social, sn => sn.network.trim().toLowerCase() === socialNetwork);\n  }\n\n\n\n  /**\n  Return an array of profiles for the specified network, for when the user\n  has multiple eg. GitHub accounts.\n  */\n  getProfiles( socialNetwork ) {\n    socialNetwork = socialNetwork.trim().toLowerCase();\n    return this.social && _.filter(this.social, sn => sn.network.trim().toLowerCase() === socialNetwork);\n  }\n\n\n\n  /** Determine if the sheet includes a specific skill. */\n  hasSkill( skill ) {\n    skill = skill.trim().toLowerCase();\n    return this.skills && _.some(this.skills, sk =>\n      sk.keywords && _.some(sk.keywords, kw => kw.trim().toLowerCase() === skill)\n    );\n  }\n\n\n\n  /** Validate the sheet against the FRESH Resume schema. */\n  isValid() {\n    const schemaObj = require('fresh-resume-schema');\n    validator = require('is-my-json-valid');\n    const validate = validator( schemaObj, { // See Note [1].\n      formats: { date: /^\\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/ }\n    });\n    const ret = validate(this);\n    if (!ret) {\n      this.imp = this.imp || { };\n      this.imp.validationErrors = validate.errors;\n    }\n    return ret;\n  }\n\n\n\n  duration(unit) {\n    const inspector = require('../inspectors/duration-inspector');\n    return inspector.run(this, 'employment.history', 'start', 'end', unit);\n  }\n\n\n\n\n  /**\n  Sort dated things on the sheet by start date descending. Assumes that dates\n  on the sheet have been processed with _parseDates().\n  */\n  sort() {\n\n    const byDateDesc = function(a,b) {\n      if (a.safe.start.isBefore(b.safe.start)) {\n      return 1;\n      } else {  if (a.safe.start.isAfter(b.safe.start)) { return -1; } else { return 0; }  }\n    };\n\n    const sortSection = function( key ) {\n      const ar = __.get(this, key);\n      if (ar && ar.length) {\n        const datedThings = ar.filter(o => o.start);\n        return datedThings.sort( byDateDesc );\n      }\n    };\n\n    sortSection('employment.history');\n    sortSection('education.history');\n    sortSection('service.history');\n    sortSection('projects');\n\n    return this.writing && this.writing.sort(function(a, b) {\n      if (a.safe.date.isBefore(b.safe.date)) {\n      return 1;\n      } else { return ( a.safe.date.isAfter(b.safe.date) && -1 ) || 0; }\n    });\n  }\n}\n\n\n\n/**\nGet the default (starter) sheet.\n*/\nFreshResume.default = () => new FreshResume().parseJSON(require('fresh-resume-starter').fresh);\n\n\n\n/**\nConvert the supplied FreshResume to a JSON string, sanitizing meta-properties\nalong the way.\n*/\nFreshResume.stringify = function( obj ) {\n  const replacer = function( key,value ) { // Exclude these keys from stringification\n    const exKeys = ['imp', 'warnings', 'computed', 'filt', 'ctrl', 'index',\n      'safe', 'result', 'isModified', 'htmlPreview', 'display_progress_bar'];\n    if (_.some( exKeys, val => key.trim() === val)) {\n    return undefined; } else { return value; }\n  };\n  return JSON.stringify(obj, replacer, 2);\n};\n\n\n\n/**\nConvert human-friendly dates into formal Moment.js dates for all collections.\nWe don't want to lose the raw textual date as entered by the user, so we store\nthe Moment-ified date as a separate property with a prefix of .safe. For ex:\njob.startDate is the date as entered by the user. job.safeStartDate is the\nparsed Moment.js date that we actually use in processing.\n*/\nvar _parseDates = function() {\n\n  const _fmt = require('./fluent-date').fmt;\n  const that = this;\n\n  // TODO: refactor recursion\n  var replaceDatesInObject = function( obj ) {\n\n    if (!obj) { return; }\n    if (Object.prototype.toString.call( obj ) === '[object Array]') {\n      obj.forEach(elem => replaceDatesInObject( elem ));\n      return;\n    } else if (typeof obj === 'object') {\n      if (obj._isAMomentObject || obj.safe) {\n        return;\n      }\n      Object.keys( obj ).forEach(key => replaceDatesInObject(obj[key]));\n      ['start','end','date'].forEach(function(val) {\n        if ((obj[val] !== undefined) && (!obj.safe || !obj.safe[val])) {\n          obj.safe = obj.safe || { };\n          obj.safe[ val ] = _fmt(obj[val]);\n          if (obj[val] && (val === 'start') && !obj.end) {\n            obj.safe.end = _fmt('current');\n            return;\n          }\n        }\n      });\n      return;\n    }\n  };\n  Object.keys( this ).forEach(function(member) {\n    replaceDatesInObject(that[member]);\n  });\n};\n\n\n\n/** Export the Sheet function/ctor. */\nmodule.exports = FreshResume;\n\n\n\n// Note 1: Adjust default date validation to allow YYYY and YYYY-MM formats\n// in addition to YYYY-MM-DD. The original regex:\n//\n//     /^\\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}$/\n//\n"
  },
  {
    "path": "src/core/fresh-theme.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS103: Rewrite code to no longer use __guard__\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the FRESHTheme class.\n@module core/fresh-theme\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst FS = require('fs');\nconst _ = require('underscore');\nconst PATH = require('path');\nconst parsePath = require('parse-filepath');\nconst EXTEND = require('extend');\nconst HMSTATUS = require('./status-codes');\nconst loadSafeJson = require('../utils/safe-json-loader');\nconst READFILES = require('recursive-readdir-sync');\n\n\n\n/* A representation of a FRESH theme asset.\n@class FRESHTheme */\nclass FRESHTheme {\n\n  constructor() {\n    this.baseFolder = 'src';\n  }\n\n  /* Open and parse the specified theme. */\n  open( themeFolder ) {\n\n    this.folder = themeFolder;\n\n    // Set up a formats hash for the theme\n    let formatsHash = { };\n\n    // Load the theme\n    const themeFile = PATH.join(themeFolder, 'theme.json');\n    const themeInfo = loadSafeJson(themeFile);\n    if (themeInfo.ex) {\n      throw{\n        fluenterror:\n          themeInfo.ex.op === 'parse'\n          ? HMSTATUS.parseError\n          : HMSTATUS.readError,\n      inner: themeInfo.ex.inner\n      };\n    }\n\n    // Move properties from the theme JSON file to the theme object\n    EXTEND(true, this, themeInfo.json);\n\n    // Check for an \"inherits\" entry in the theme JSON.\n    if (this.inherits) {\n      const cached = { };\n      _.each(this.inherits, function(th, key) {\n        // First, see if this is one of the predefined FRESH themes. There are\n        // only a handful of these, but they may change over time, so we need to\n        // query the official source of truth: the fresh-themes repository, which\n        // mounts the themes conveniently by name to the module object, and which\n        // is embedded locally inside the HackMyResume installation.\n        // TODO: merge this code with\n        let themePath;\n        const themesObj = require('fresh-themes');\n        if (_.has(themesObj.themes, th)) {\n          themePath = PATH.join(\n            parsePath( require.resolve('fresh-themes') ).dirname,\n            '/themes/',\n            th\n          );\n        } else {\n          const d = parsePath( th ).dirname;\n          themePath = PATH.join(d, th);\n        }\n\n        cached[ th ] = cached[th] || new FRESHTheme().open( themePath );\n        return formatsHash[ key ] = cached[ th ].getFormat( key );\n      });\n    }\n\n    // Load theme files\n    formatsHash = _load.call(this, formatsHash);\n\n    // Cache\n    this.formats = formatsHash;\n\n    // Set the official theme name\n    this.name = parsePath( this.folder ).name;\n    return this;\n  }\n\n  /* Determine if the theme supports the specified output format. */\n  hasFormat( fmt ) { return _.has(this.formats, fmt); }\n\n  /* Determine if the theme supports the specified output format. */\n  getFormat( fmt ) { return this.formats[ fmt ]; }\n}\n\n\n\n/* Load and parse theme source files. */\nvar _load = function(formatsHash) {\n\n  const that = this;\n  const tplFolder = PATH.join(this.folder, this.baseFolder);\n\n  // Iterate over all files in the theme folder, producing an array, fmts,\n  // containing info for each file. While we're doing that, also build up\n  // the formatsHash object.\n  const fmts = READFILES(tplFolder).map(function(absPath) {\n    return _loadOne.call(this, absPath, formatsHash, tplFolder);\n  }\n  , this);\n\n  // Now, get all the CSS files...\n  this.cssFiles = fmts.filter(fmt => fmt && (fmt.ext === 'css'));\n\n  // For each CSS file, get its corresponding HTML file. It's possible that\n  // a theme can have a CSS file but *no* HTML file, as when a theme author\n  // creates a pure CSS override of an existing theme.\n  this.cssFiles.forEach(function(cssf) {\n    const idx = _.findIndex(fmts,  fmt  => fmt && (fmt.pre === cssf.pre) && (fmt.ext === 'html'));\n    cssf.major = false;\n    if (idx > -1) {\n      fmts[ idx ].css = cssf.data;\n      return fmts[ idx ].cssPath = cssf.path;\n    } else {\n      if (that.inherits) {\n        // Found a CSS file without an HTML file in a theme that inherits\n        // from another theme. This is the override CSS file.\n        return that.overrides = { file: cssf.path, data: cssf.data };\n      }\n    }});\n\n  // Now, save all the javascript file paths to a theme property.\n  const jsFiles = fmts.filter(fmt => fmt && (fmt.ext === 'js'));\n  this.jsFiles = jsFiles.map(jsf => jsf['path']);\n\n  return formatsHash;\n};\n\n\n/* Load a single theme file. */\nvar _loadOne = function( absPath, formatsHash, tplFolder ) {\n\n  const pathInfo = parsePath(absPath);\n  if (pathInfo.basename.toLowerCase() === 'theme.json') { return; }\n\n  const absPathSafe = absPath.trim().toLowerCase();\n  let outFmt = '';\n  let act = 'copy';\n  let isPrimary = false;\n\n  // If this is an \"explicit\" theme, all files of importance are specified in\n  // the \"transform\" section of the theme.json file.\n  if (this.explicit) {\n\n    outFmt = _.find(Object.keys( this.formats ), function( fmtKey ) {\n      const fmtVal = this.formats[ fmtKey ];\n      return _.some(fmtVal.transform, function(fpath) {\n        const absPathB = PATH.join( this.folder, fpath ).trim().toLowerCase();\n        return absPathB === absPathSafe;\n      }\n      , this);\n    }\n    , this);\n    if (outFmt) { act = 'transform'; }\n  }\n\n  if (!outFmt) {\n    // If this file lives in a specific format folder within the theme,\n    // such as \"/latex\" or \"/html\", then that format is the implicit output\n    // format for all files within the folder\n    const portion = pathInfo.dirname.replace(tplFolder,'');\n    if (portion && portion.trim()) {\n      if (portion[1] === '_') { return; }\n      const reg = /^(?:\\/|\\\\)(html|latex|doc|pdf|png|partials)(?:\\/|\\\\)?/ig;\n      const res = reg.exec( portion );\n      if (res) {\n        if (res[1] !== 'partials') {\n          outFmt = res[1];\n          if (!this.explicit) { act = 'transform'; }\n        } else {\n          this.partials = this.partials || [];\n          this.partials.push( { name: pathInfo.name, path: absPath } );\n          return null;\n        }\n      }\n    }\n  }\n\n  // Otherwise, the output format is inferred from the filename, as in\n  // compact-[outputformat].[extension], for ex, compact-pdf.html\n  if (!outFmt) {\n    const idx = pathInfo.name.lastIndexOf('-');\n    outFmt = idx === -1 ? pathInfo.name : pathInfo.name.substr(idx+1);\n    if (!this.explicit) { act = 'transform'; }\n    const defFormats = require('./default-formats');\n    isPrimary = _.some(defFormats, form => (form.name === outFmt) && (pathInfo.extname !== '.css'));\n  }\n\n  // Make sure we have a valid formatsHash\n  formatsHash[ outFmt ] = formatsHash[outFmt] || {\n    outFormat: outFmt,\n    files: []\n  };\n\n  // Move symlink descriptions from theme.json to the format\n  if (__guard__(this.formats != null ? this.formats[outFmt ] : undefined, x => x.symLinks)) {\n    formatsHash[ outFmt ].symLinks = this.formats[ outFmt ].symLinks;\n  }\n\n  // Create the file representation object\n  const obj = {\n    action: act,\n    primary: isPrimary,\n    path: absPath,\n    orgPath: PATH.relative(tplFolder, absPath),\n    ext: pathInfo.extname.slice(1),\n    title: friendlyName(outFmt),\n    pre: outFmt,\n    // outFormat: outFmt || pathInfo.name,\n    data: FS.readFileSync(absPath, 'utf8'),\n    css: null\n  };\n\n  // Add this file to the list of files for this format type.\n  formatsHash[ outFmt ].files.push( obj );\n  return obj;\n};\n\n\n\n/* Return a more friendly name for certain formats. */\nvar friendlyName = function( val ) {\n  val = (val && val.trim().toLowerCase()) || '';\n  const friendly = { yml: 'yaml', md: 'markdown', txt: 'text' };\n  return friendly[val] || val;\n};\n\n\n\nmodule.exports = FRESHTheme;\n\nfunction __guard__(value, transform) {\n  return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined;\n}\n"
  },
  {
    "path": "src/core/jrs-resume.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS206: Consider reworking classes to avoid initClass\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the JRSResume class.\n@license MIT. See LICENSE.md for details.\n@module core/jrs-resume\n*/\n\n\n\nconst FS = require('fs');\nconst extend = require('extend');\nlet validator = require('is-my-json-valid');\nconst _ = require('underscore');\nconst PATH = require('path');\nconst CONVERTER = require('fresh-jrs-converter');\n\n\n/**\nA JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object\nis an instantiation of that JSON decorated with utility methods.\n@class JRSResume\n*/\n\n\nclass JRSResume {\n\n  static initClass() {\n    /** Reset the sheet to an empty state. */\n    // clear = function( clearMeta ) {\n    //   clearMeta = ((clearMeta === undefined) && true) || clearMeta;\n    //   if (clearMeta) { delete this.imp; }\n    //   delete this.basics.computed; // Don't use Object.keys() here\n    //   delete this.work;\n    //   delete this.volunteer;\n    //   delete this.education;\n    //   delete this.awards;\n    //   delete this.publications;\n    //   delete this.interests;\n    //   delete this.skills;\n    //   return delete this.basics.profiles;\n    // };\n    // extends AbstractResume\n  }\n\n\n\n  /** Initialize the the JSResume from string. */\n  parse( stringData, opts ) {\n    this.imp = this.imp != null ? this.imp : {raw: stringData};\n    return this.parseJSON(JSON.parse( stringData ), opts);\n  }\n\n\n\n  /**\n  Initialize the JRSResume object from JSON.\n  Open and parse the specified JRS resume. Merge the JSON object model onto\n  this Sheet instance with extend() and convert sheet dates to a safe &\n  consistent format. Then sort each section by startDate descending.\n  @param rep {Object} The raw JSON representation.\n  @param opts {Object} Resume loading and parsing options.\n  {\n    date: Perform safe date conversion.\n    sort: Sort resume items by date.\n    compute: Prepare computed resume totals.\n  }\n  */\n  parseJSON( rep, opts ) {\n    let scrubbed;\n    opts = opts || { };\n    if (opts.privatize) {\n      const scrubber = require('../utils/resume-scrubber');\n      // Ignore any element with the 'ignore: true' or 'private: true' designator.\n      var ret = scrubber.scrubResume(rep, opts);\n      scrubbed = ret.scrubbed;\n    }\n\n    // Extend resume properties onto ourself.\n    extend(true, this, opts.privatize ? scrubbed : rep);\n\n    // Set up metadata\n    if (!(this.imp != null ? this.imp.processed : undefined)) {\n      // Set up metadata TODO: Clean up metadata on the object model.\n      opts = opts || { };\n      if ((opts.imp === undefined) || opts.imp) {\n        this.imp = this.imp || { };\n        this.imp.title = (opts.title || this.imp.title) || this.basics.name;\n        if (!this.imp.raw) {\n          this.imp.raw = JSON.stringify(rep);\n        }\n      }\n      this.imp.processed = true;\n    }\n    // Parse dates, sort dates, and calculate computed values\n    ((opts.date === undefined) || opts.date) && _parseDates.call( this );\n    ((opts.sort === undefined) || opts.sort) && this.sort();\n    if ((opts.compute === undefined) || opts.compute) {\n      this.basics.computed = {\n        numYears: this.duration(),\n        keywords: this.keywords()\n      };\n    }\n    return this;\n  }\n\n\n\n  /** Save the sheet to disk (for environments that have disk access). */\n  save( filename ) {\n    this.imp.file = filename || this.imp.file;\n    FS.writeFileSync(this.imp.file, this.stringify( this ), 'utf8');\n    return this;\n  }\n\n\n\n  /** Save the sheet to disk in a specific format, either FRESH or JRS. */\n  saveAs( filename, format ) {\n    if (format === 'JRS') {\n      this.imp.file = filename || this.imp.file;\n      FS.writeFileSync( this.imp.file, this.stringify(), 'utf8' );\n    } else {\n      const newRep = CONVERTER.toFRESH(this);\n      const stringRep = CONVERTER.toSTRING(newRep);\n      FS.writeFileSync(filename, stringRep, 'utf8');\n    }\n    return this;\n  }\n\n\n\n  /** Return the resume format. */\n  format() { return 'JRS'; }\n\n\n\n  stringify() { return JRSResume.stringify( this ); }\n\n\n\n  /** Return a unique list of all keywords across all skills. */\n  keywords() {\n    let flatSkills = [];\n    if (this.skills && this.skills.length) {\n      this.skills.forEach( s  => flatSkills = _.union(flatSkills, s.keywords));\n    }\n    return flatSkills;\n  }\n\n\n\n  /**\n  Return internal metadata. Create if it doesn't exist.\n  JSON Resume v0.0.0 doesn't allow additional properties at the root level,\n  so tuck this into the .basic sub-object.\n  */\n  i() {\n    return this.imp = this.imp != null ? this.imp : { };\n  }\n\n\n\n  /** Add work experience to the sheet. */\n  add( moniker ) {\n    const defSheet = JRSResume.default();\n    const newObject = extend( true, {}, defSheet[ moniker ][0] );\n    this[ moniker ] = this[ moniker ] || [];\n    this[ moniker ].push( newObject );\n    return newObject;\n  }\n\n\n\n  /** Determine if the sheet includes a specific social profile (eg, GitHub). */\n  hasProfile( socialNetwork ) {\n    socialNetwork = socialNetwork.trim().toLowerCase();\n    return this.basics.profiles && _.some(this.basics.profiles, p => p.network.trim().toLowerCase() === socialNetwork);\n  }\n\n\n\n  /** Determine if the sheet includes a specific skill. */\n  hasSkill( skill ) {\n    skill = skill.trim().toLowerCase();\n    return this.skills && _.some(this.skills, sk =>\n      sk.keywords && _.some(sk.keywords, kw => kw.trim().toLowerCase() === skill)\n    );\n  }\n\n\n\n  /** Validate the sheet against the JSON Resume schema. */\n  isValid( ) { // TODO: ↓ fix this path ↓\n    const schema = FS.readFileSync(PATH.join( __dirname, 'resume.json' ), 'utf8');\n    const schemaObj = JSON.parse(schema);\n    validator = require('is-my-json-valid');\n    const validate = validator( schemaObj, { // Note [1]\n      formats: { date: /^\\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/ }\n    });\n    const temp = this.imp;\n    delete this.imp;\n    const ret = validate(this);\n    this.imp = temp;\n    if (!ret) {\n      this.imp = this.imp || { };\n      this.imp.validationErrors = validate.errors;\n    }\n    return ret;\n  }\n\n\n\n  duration(unit) {\n    const inspector = require('../inspectors/duration-inspector');\n    return inspector.run(this, 'work', 'startDate', 'endDate', unit);\n  }\n\n\n\n  /**\n  Sort dated things on the sheet by start date descending. Assumes that dates\n  on the sheet have been processed with _parseDates().\n  */\n  sort( ) {\n\n    const byDateDesc = function(a,b) {\n      if (a.safeStartDate.isBefore(b.safeStartDate)) {\n      return 1;\n      } else { return ( a.safeStartDate.isAfter(b.safeStartDate) && -1 ) || 0; }\n    };\n\n    this.work && this.work.sort(byDateDesc);\n    this.education && this.education.sort(byDateDesc);\n    this.volunteer && this.volunteer.sort(byDateDesc);\n\n    this.awards && this.awards.sort(function(a, b) {\n      if (a.safeDate.isBefore(b.safeDate)) {\n      return 1;\n      } else { return (a.safeDate.isAfter(b.safeDate) && -1 ) || 0; }\n    });\n\n    return this.publications && this.publications.sort(function(a, b) {\n      if ( a.safeReleaseDate.isBefore(b.safeReleaseDate) ) {\n      return 1;\n      } else { return ( a.safeReleaseDate.isAfter(b.safeReleaseDate) && -1 ) || 0; }\n    });\n  }\n\n\n\n  dupe() {\n    const rnew = new JRSResume();\n    rnew.parse(this.stringify(), { });\n    return rnew;\n  }\n\n\n\n  /**\n  Create a copy of this resume in which all fields have been interpreted as\n  Markdown.\n  */\n  harden() {\n\n    const ret = this.dupe();\n\n    const HD = txt => `@@@@~${txt}~@@@@`;\n\n    // const HDIN = txt =>\n    //   //return MD(txt || '' ).replace(/^\\s*<p>|<\\/p>\\s*$/gi, '');\n    //   HD(txt)\n    // ;\n\n    const transformer = require('../utils/string-transformer');\n    return transformer(ret,\n      [ 'skills','url','website','startDate','endDate', 'releaseDate', 'date',\n      'phone','email','address','postalCode','city','country','region',\n      'safeStartDate','safeEndDate' ],\n      (key, val) => HD(val));\n  }\n}\n\nJRSResume.initClass();\n\n\n\n\n/** Get the default (empty) sheet. */\nJRSResume.default = () => new JRSResume().parseJSON(require('fresh-resume-starter').jrs);\n\n\n\n/**\nConvert this object to a JSON string, sanitizing meta-properties along the\nway. Don't override .toString().\n*/\nJRSResume.stringify = function( obj ) {\n  const replacer = function( key,value ) { // Exclude these keys from stringification\n    const temp = _.some(['imp', 'warnings', 'computed', 'filt', 'ctrl', 'index',\n      'safeStartDate', 'safeEndDate', 'safeDate', 'safeReleaseDate', 'result',\n      'isModified', 'htmlPreview', 'display_progress_bar'],\n       val  => key.trim() === val);\n    if (temp) { return undefined; } else { return value; }\n  };\n  return JSON.stringify(obj, replacer, 2);\n};\n\n\n\n/**\nConvert human-friendly dates into formal Moment.js dates for all collections.\nWe don't want to lose the raw textual date as entered by the user, so we store\nthe Moment-ified date as a separate property with a prefix of .safe. For ex:\njob.startDate is the date as entered by the user. job.safeStartDate is the\nparsed Moment.js date that we actually use in processing.\n*/\nvar _parseDates = function() {\n\n  const _fmt = require('./fluent-date').fmt;\n\n  this.work && this.work.forEach(function(job) {\n    job.safeStartDate = _fmt( job.startDate );\n    return job.safeEndDate = _fmt( job.endDate );\n  });\n  this.education && this.education.forEach(function(edu) {\n    edu.safeStartDate = _fmt( edu.startDate );\n    return edu.safeEndDate = _fmt( edu.endDate );\n  });\n  this.volunteer && this.volunteer.forEach(function(vol) {\n    vol.safeStartDate = _fmt( vol.startDate );\n    return vol.safeEndDate = _fmt( vol.endDate );\n  });\n  this.awards && this.awards.forEach(awd => awd.safeDate = _fmt( awd.date ));\n  return this.publications && this.publications.forEach(pub => pub.safeReleaseDate = _fmt( pub.releaseDate ));\n};\n\n\n\n/**\nExport the JRSResume class.\n*/\nmodule.exports = JRSResume;\n"
  },
  {
    "path": "src/core/jrs-theme.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the JRSTheme class.\n@module core/jrs-theme\n@license MIT. See LICENSE.MD for details.\n*/\n\n\n\nconst _ = require('underscore');\nconst PATH = require('path');\nconst pathExists = require('path-exists').sync;\nconst errors = require('./status-codes');\n\n\n\n/**\nThe JRSTheme class is a representation of a JSON Resume theme asset.\n@class JRSTheme\n*/\nclass JRSTheme {\n\n\n\n  /**\n  Open and parse the specified JRS theme.\n  @method open\n  */\n  open( thFolder ) {\n\n    this.folder = thFolder;\n    //const pathInfo = parsePath(thFolder);\n\n    // Open and parse the theme's package.json file\n    const pkgJsonPath = PATH.join(thFolder, 'package.json');\n    if (pathExists(pkgJsonPath)) {\n      const thApi = require(thFolder);     // Requiring the folder yields whatever the package.json's \"main\" is set to\n      const thPkg = require(pkgJsonPath);  // Get the package.json as JSON\n      this.name = thPkg.name;\n      this.render = (thApi && thApi.render) || undefined;\n      this.engine = 'jrs';\n\n      // Create theme formats (HTML and PDF). Just add the bare minimum mix of\n      // properties necessary to allow JSON Resume themes to share a rendering\n      // path with FRESH themes.\n      this.formats = {\n        html: {\n          outFormat: 'html',\n          files: [{\n            action: 'transform',\n            render: this.render,\n            primary: true,\n            ext: 'html',\n            css: null\n          }]\n        },\n        pdf: {\n          outFormat: 'pdf',\n          files: [{\n            action: 'transform',\n            render: this.render,\n            primary: true,\n            ext: 'pdf',\n            css: null\n          }]\n        }\n      };\n    } else {\n      throw {fluenterror: errors.missingPackageJSON};\n    }\n    return this;\n  }\n\n\n\n  /**\n  Determine if the theme supports the output format.\n  @method hasFormat\n  */\n  hasFormat( fmt ) {  return _.has(this.formats, fmt); }\n\n\n\n  /**\n  Return the requested output format.\n  @method getFormat\n  */\n  getFormat( fmt ) { return this.formats[ fmt ]; }\n}\n\n\nmodule.exports = JRSTheme;\n"
  },
  {
    "path": "src/core/resume-factory.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the ResumeFactory class.\n@license MIT. See LICENSE.md for details.\n@module core/resume-factory\n*/\n\n\n\nconst FS              = require('fs');\nconst HMS    = require('./status-codes');\nconst HME             = require('./event-codes');\nconst ResumeConverter = require('fresh-jrs-converter');\nconst resumeDetect    = require('../utils/resume-detector');\nrequire('string.prototype.startswith');\n\n\n\n/**\nA simple factory class for FRESH and JSON Resumes.\n@class ResumeFactory\n*/\n\nmodule.exports = {\n\n\n\n  /**\n  Load one or more resumes from disk.\n\n  @param {Object} opts An options object with settings for the factory as well\n  as passthrough settings for FRESHResume or JRSResume. Structure:\n\n      {\n        format: 'FRESH',    // Format to open as. ('FRESH', 'JRS', null)\n        objectify: true,    // FRESH/JRSResume or raw JSON?\n        inner: {            // Passthru options for FRESH/JRSResume\n          sort: false\n        }\n      }\n\n  */\n  load( sources, opts, emitter ) {\n    return sources.map( function(src) {\n      return this.loadOne( src, opts, emitter );\n    }\n    , this);\n  },\n\n\n  /** Load a single resume from disk.  */\n  loadOne( src, opts, emitter ) {\n\n    let toFormat = opts.format;     // Can be null\n\n    // Get the destination format. Can be 'fresh', 'jrs', or null/undefined.\n    toFormat && (toFormat = toFormat.toLowerCase().trim());\n\n    // Load and parse the resume JSON\n    const info = _parse(src, opts, emitter);\n    if (info.fluenterror) { return info; }\n\n    // Determine the resume format: FRESH or JRS\n    let { json } = info;\n    const orgFormat = resumeDetect(json);\n    if (orgFormat === 'unk') {\n      info.fluenterror = HMS.unknownSchema;\n      return info;\n    }\n\n    // Convert between formats if necessary\n    if (toFormat && ( orgFormat !== toFormat )) {\n      json = ResumeConverter[ `to${toFormat.toUpperCase()}` ](json);\n    }\n\n    // Objectify the resume, that is, convert it from JSON to a FRESHResume\n    // or JRSResume object.\n    let rez = null;\n    if (opts.objectify) {\n      const reqLib = `../core/${toFormat || orgFormat}-resume`;\n      const ResumeClass = require(reqLib);\n      rez = new ResumeClass().parseJSON( json, opts.inner );\n      rez.i().file = src;\n    }\n\n    return {\n      file: src,\n      json: info.json,\n      rez\n    };\n  }\n};\n\n\nvar _parse = function( fileName, opts, eve ) {\n\n  let rawData = null;\n  try {\n\n    // Read the file\n    eve && eve.stat( HME.beforeRead, { file: fileName });\n    rawData = FS.readFileSync( fileName, 'utf8' );\n    eve && eve.stat( HME.afterRead, { file: fileName, data: rawData });\n\n    // Parse the file\n    eve && eve.stat(HME.beforeParse, { data: rawData });\n    const ret = { json: JSON.parse( rawData ) };\n    const orgFormat =\n      ret.json.meta && ret.json.meta.format && ret.json.meta.format.startsWith('FRESH@')\n      ? 'fresh' : 'jrs';\n\n    eve && eve.stat(HME.afterParse, { file: fileName, data: ret.json, fmt: orgFormat });\n    return ret;\n  } catch (err) {\n    // Can be ENOENT, EACCES, SyntaxError, etc.\n    return {\n      fluenterror: rawData ? HMS.parseError : HMS.readError,\n      inner: err,\n      raw: rawData,\n      file: fileName\n    };\n  }\n};\n"
  },
  {
    "path": "src/core/resume.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"title\": \"Resume Schema\",\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"properties\": {\n    \"basics\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"label\": {\n          \"type\": \"string\",\n          \"description\": \"e.g. Web Developer\"\n        },\n        \"picture\": {\n          \"type\": \"string\",\n          \"description\": \"URL (as per RFC 3986) to a picture in JPEG or PNG format\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"description\": \"e.g. thomas@gmail.com\",\n          \"format\": \"email\"\n        },\n        \"phone\": {\n          \"type\": \"string\",\n          \"description\": \"Phone numbers are stored as strings so use any format you like, e.g. 712-117-2923\"\n        },\n        \"website\": {\n          \"type\": \"string\",\n          \"description\": \"URL (as per RFC 3986) to your website, e.g. personal homepage\",\n          \"format\": \"uri\"\n        },\n        \"summary\": {\n          \"type\": \"string\",\n          \"description\": \"Write a short 2-3 sentence biography about yourself\"\n        },\n        \"location\": {\n          \"type\": \"object\",\n          \"additionalProperties\": true,\n          \"properties\": {\n            \"address\": {\n              \"type\": \"string\",\n              \"description\": \"To add multiple address lines, use \\n. For example, 1234 Glücklichkeit Straße\\nHinterhaus 5. Etage li.\"\n            },\n            \"postalCode\": {\n              \"type\": \"string\"\n            },\n            \"city\": {\n              \"type\": \"string\"\n            },\n            \"countryCode\": {\n              \"type\": \"string\",\n              \"description\": \"code as per ISO-3166-1 ALPHA-2, e.g. US, AU, IN\"\n            },\n            \"region\": {\n              \"type\": \"string\",\n              \"description\": \"The general region where you live. Can be a US state, or a province, for instance.\"\n            }\n          }\n        },\n        \"profiles\": {\n          \"type\": \"array\",\n          \"description\": \"Specify any number of social networks that you participate in\",\n          \"additionalItems\": false,\n          \"items\": {\n            \"type\": \"object\",\n            \"additionalProperties\": true,\n            \"properties\": {\n              \"network\": {\n                \"type\": \"string\",\n                \"description\": \"e.g. Facebook or Twitter\"\n              },\n              \"username\": {\n                \"type\": \"string\",\n                \"description\": \"e.g. neutralthoughts\"\n              },\n              \"url\": {\n                \"type\": \"string\",\n                \"description\": \"e.g. http://twitter.com/neutralthoughts\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"work\": {\n      \"type\": \"array\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"type\": \"object\",\n        \"additionalProperties\": true,\n      \"properties\": {\n          \"company\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Facebook\"\n          },\n          \"position\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Software Engineer\"\n          },\n          \"website\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. http://facebook.com\",\n            \"format\": \"uri\"\n          },\n          \"startDate\": {\n            \"type\": \"string\",\n            \"description\": \"resume.json uses the ISO 8601 date standard e.g. 2014-06-29\",\n            \"format\": \"date\"\n          },\n          \"endDate\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. 2012-06-29\",\n            \"format\": \"date\"\n          },\n          \"summary\": {\n            \"type\": \"string\",\n            \"description\": \"Give an overview of your responsibilities at the company\"\n          },\n          \"highlights\": {\n            \"type\": \"array\",\n            \"description\": \"Specify multiple accomplishments\",\n            \"additionalItems\": false,\n            \"items\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Increased profits by 20% from 2011-2012 through viral advertising\"\n            }\n          }\n        }\n\n      }\n    },\n    \"volunteer\": {\n      \"type\": \"array\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"type\": \"object\",\n        \"additionalProperties\": true,\n      \"properties\": {\n          \"organization\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Facebook\"\n          },\n          \"position\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Software Engineer\"\n          },\n          \"website\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. http://facebook.com\",\n            \"format\": \"uri\"\n          },\n          \"startDate\": {\n            \"type\": \"string\",\n            \"description\": \"resume.json uses the ISO 8601 date standard e.g. 2014-06-29\",\n            \"format\": \"date\"\n          },\n          \"endDate\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. 2012-06-29\",\n            \"format\": \"date\"\n          },\n          \"summary\": {\n            \"type\": \"string\",\n            \"description\": \"Give an overview of your responsibilities at the company\"\n          },\n          \"highlights\": {\n            \"type\": \"array\",\n            \"description\": \"Specify multiple accomplishments\",\n            \"additionalItems\": false,\n            \"items\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Increased profits by 20% from 2011-2012 through viral advertising\"\n            }\n          }\n        }\n\n      }\n    },\n    \"education\": {\n      \"type\": \"array\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"type\": \"object\",\n        \"additionalProperties\": true,\n      \"properties\": {\n            \"institution\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Massachusetts Institute of Technology\"\n            },\n            \"area\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Arts\"\n            },\n            \"studyType\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Bachelor\"\n            },\n            \"startDate\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. 2014-06-29\",\n              \"format\": \"date\"\n            },\n            \"endDate\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. 2012-06-29\",\n              \"format\": \"date\"\n            },\n            \"gpa\": {\n              \"type\": \"string\",\n              \"description\": \"grade point average, e.g. 3.67/4.0\"\n            },\n            \"courses\": {\n              \"type\": \"array\",\n              \"description\": \"List notable courses/subjects\",\n              \"additionalItems\": false,\n              \"items\": {\n                \"type\": \"string\",\n                \"description\": \"e.g. H1302 - Introduction to American history\"\n              }\n            }\n          }\n\n\n      }\n    },\n    \"awards\": {\n      \"type\": \"array\",\n      \"description\": \"Specify any awards you have received throughout your professional career\",\n      \"additionalItems\": false,\n      \"items\": {\n          \"type\": \"object\",\n          \"additionalProperties\": true,\n        \"properties\": {\n            \"title\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. One of the 100 greatest minds of the century\"\n            },\n            \"date\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. 1989-06-12\",\n              \"format\": \"date\"\n            },\n            \"awarder\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Time Magazine\"\n            },\n            \"summary\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Received for my work with Quantum Physics\"\n            }\n        }\n      }\n    },\n    \"publications\": {\n      \"type\": \"array\",\n      \"description\": \"Specify your publications through your career\",\n      \"additionalItems\": false,\n      \"items\": {\n          \"type\": \"object\",\n          \"additionalProperties\": true,\n        \"properties\": {\n            \"name\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. The World Wide Web\"\n            },\n            \"publisher\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. IEEE, Computer Magazine\"\n            },\n            \"releaseDate\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. 1990-08-01\"\n            },\n            \"website\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. http://www.computer.org/csdl/mags/co/1996/10/rx069-abs.html\"\n            },\n            \"summary\": {\n              \"type\": \"string\",\n              \"description\": \"Short summary of publication. e.g. Discussion of the World Wide Web, HTTP, HTML.\"\n            }\n          }\n      }\n    },\n    \"skills\": {\n      \"type\": \"array\",\n      \"description\": \"List out your professional skill-set\",\n      \"additionalItems\": false,\n      \"items\": {\n          \"type\": \"object\",\n          \"additionalProperties\": true,\n        \"properties\": {\n            \"name\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Web Development\"\n            },\n            \"level\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Master\"\n            },\n            \"keywords\": {\n              \"type\": \"array\",\n              \"description\": \"List some keywords pertaining to this skill\",\n              \"additionalItems\": false,\n              \"items\": {\n                \"type\": \"string\",\n                \"description\": \"e.g. HTML\"\n              }\n            }\n        }\n      }\n    },\n    \"languages\": {\n      \"type\": \"array\",\n      \"description\": \"List any other languages you speak\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"type\": \"object\",\n        \"additionalProperties\": true,\n        \"properties\": {\n          \"language\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. English, Spanish\"\n          },\n          \"fluency\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Fluent, Beginner\"\n          }\n        }\n      }\n    },\n    \"interests\": {\n      \"type\": \"array\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"type\": \"object\",\n        \"additionalProperties\": true,\n      \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Philosophy\"\n          },\n          \"keywords\": {\n            \"type\": \"array\",\n            \"additionalItems\": false,\n            \"items\": {\n              \"type\": \"string\",\n              \"description\": \"e.g. Friedrich Nietzsche\"\n            }\n          }\n        }\n\n      }\n    },\n    \"references\": {\n      \"type\": \"array\",\n      \"description\": \"List references you have received\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"type\": \"object\",\n        \"additionalProperties\": true,\n      \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Timothy Cook\"\n          },\n          \"reference\": {\n            \"type\": \"string\",\n            \"description\": \"e.g. Joe blogs was a great employee, who turned up to work at least once a week. He exceeded my expectations when it came to doing nothing.\"\n          }\n        }\n\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/core/status-codes.js",
    "content": "/**\nStatus codes for HackMyResume.\n@module core/status-codes\n@license MIT. See LICENSE.MD for details.\n*/\n\n\nmodule.exports = {\n  success: 0,\n  themeNotFound: 1,\n  copyCss: 2,\n  resumeNotFound: 3,\n  missingCommand: 4,\n  invalidCommand: 5,\n  resumeNotFoundAlt: 6,\n  inputOutputParity: 7,\n  createNameMissing: 8,\n  pdfGeneration: 9,\n  missingPackageJSON: 10,\n  invalid: 11,\n  invalidFormat: 12,\n  notOnPath: 13,\n  readError: 14,\n  parseError: 15,\n  fileSaveError: 16,\n  generateError: 17,\n  invalidHelperUse: 18,\n  mixedMerge: 19,\n  invokeTemplate: 20,\n  compileTemplate: 21,\n  themeLoad: 22,\n  invalidParamCount: 23,\n  missingParam: 24,\n  createError: 25,\n  validateError: 26,\n  invalidOptionsFile: 27,\n  optionsFileNotFound: 28,\n  unknownSchema: 29,\n  themeHelperLoad: 30,\n  invalidSchemaVersion: 31\n};\n"
  },
  {
    "path": "src/generators/base-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS206: Consider reworking classes to avoid initClass\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the BaseGenerator class.\n@module generators/base-generator\n@license MIT. See LICENSE.md for details.\n*/\n\n\n/**\nThe BaseGenerator class is the root of the generator hierarchy. Functionality\ncommon to ALL generators lives here.\n*/\n\nlet BaseGenerator;\nmodule.exports = (BaseGenerator = (function() {\n  BaseGenerator = class BaseGenerator {\n    static initClass() {\n  \n      /** Status codes. */\n      this.prototype.codes = require('../core/status-codes');\n  \n      /** Generator options. */\n      this.prototype.opts = { };\n    }\n\n    /** Base-class initialize. */\n    constructor( format ) {\n      this.format = format;\n    }\n  };\n  BaseGenerator.initClass();\n  return BaseGenerator;\n})());\n"
  },
  {
    "path": "src/generators/html-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the HTMLGenerator class.\n@module generators/html-generator\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst TemplateGenerator = require('./template-generator');\nconst HTML = require('html');\nrequire('string.prototype.endswith');\n\n\n\nclass HtmlGenerator extends TemplateGenerator {\n\n  constructor() { super('html'); }\n\n  /**\n  Copy satellite CSS files to the destination and optionally pretty-print\n  the HTML resume prior to saving.\n  */\n  onBeforeSave( info ) {\n    if (info.outputFile.endsWith('.css')) {\n      return info.mk;\n    }\n    if (this.opts.prettify) {\n    return HTML.prettyPrint(info.mk, this.opts.prettify);\n    } else { return info.mk; }\n  }\n}\n\n\nmodule.exports = HtmlGenerator;\n"
  },
  {
    "path": "src/generators/html-pdf-cli-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS103: Rewrite code to no longer use __guard__\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the HtmlPdfCLIGenerator class.\n@module generators/html-pdf-generator.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst TemplateGenerator = require('./template-generator');\nconst FS = require('fs-extra');\nconst PATH = require('path');\nconst SLASH = require('slash');\nconst _ = require('underscore');\nconst HMSTATUS = require('../core/status-codes');\nconst SPAWN = require('../utils/safe-spawn');\n\n\n/**\nAn HTML-driven PDF resume generator for HackMyResume. Talks to Phantom,\nwkhtmltopdf, and other PDF engines over a CLI (command-line interface).\nIf an engine isn't installed for a particular platform, error out gracefully.\n*/\n\nclass HtmlPdfCLIGenerator extends TemplateGenerator {\n\n\n\n  constructor() { super('pdf', 'html'); }\n\n\n\n  /** Generate the binary PDF. */\n  onBeforeSave( info ) {\n    //console.dir _.omit( info, 'mk' ), depth: null, colors: true\n    if ((info.ext !== 'html') && (info.ext !== 'pdf')) { return info.mk; }\n    let safe_eng = info.opts.pdf || 'wkhtmltopdf';\n    if (safe_eng === 'phantom') { safe_eng = 'phantomjs'; }\n    if (_.has(engines, safe_eng)) {\n      this.errHandler = info.opts.errHandler;\n      engines[ safe_eng ].call(this, info.mk, info.outputFile, info.opts, this.onError);\n      return null; // halt further processing\n    }\n  }\n\n\n\n  /* Low-level error callback for spawn(). May be called after HMR process\n  termination, so object references may not be valid here. That's okay; if\n  the references are invalid, the error was already logged. We could use\n  spawn-watch here but that causes issues on legacy Node.js. */\n  onError(ex, param) {\n    __guardMethod__(param.errHandler, 'err', o => o.err(HMSTATUS.pdfGeneration, ex));\n  }\n}\n\nmodule.exports = HtmlPdfCLIGenerator;\n\n// TODO: Move each engine to a separate module\nvar engines = {\n\n\n\n  /**\n  Generate a PDF from HTML using wkhtmltopdf's CLI interface.\n  Spawns a child process with `wkhtmltopdf <source> <target>`. wkhtmltopdf\n  must be installed and path-accessible.\n  TODO: If HTML generation has run, reuse that output\n  TODO: Local web server to ease wkhtmltopdf rendering\n  */\n  wkhtmltopdf(markup, fOut, opts, on_error) {\n    // Save the markup to a temporary file\n    const tempFile = fOut.replace(/\\.pdf$/i, '.pdf.html');\n    FS.writeFileSync(tempFile, markup, 'utf8');\n\n    // Prepare wkhtmltopdf arguments.\n    let wkopts = _.extend({'margin-top': '10mm', 'margin-bottom': '10mm'}, opts.wkhtmltopdf);\n    wkopts = _.flatten(_.map(wkopts, (v, k) => [`--${k}`, v]));\n    const wkargs = wkopts.concat([ tempFile, fOut  ]);\n\n    SPAWN('wkhtmltopdf', wkargs , false, on_error, this);\n  },\n\n\n\n  /**\n  Generate a PDF from HTML using Phantom's CLI interface.\n  Spawns a child process with `phantomjs <script> <source> <target>`. Phantom\n  must be installed and path-accessible.\n  TODO: If HTML generation has run, reuse that output\n  TODO: Local web server to ease Phantom rendering\n  */\n  phantomjs( markup, fOut, opts, on_error ) {\n    // Save the markup to a temporary file\n    const tempFile = fOut.replace(/\\.pdf$/i, '.pdf.html');\n    FS.writeFileSync(tempFile, markup, 'utf8');\n    let scriptPath = PATH.relative(process.cwd(), PATH.resolve( __dirname, '../utils/rasterize.js' ));\n    scriptPath = SLASH(scriptPath);\n    const sourcePath = SLASH(PATH.relative( process.cwd(), tempFile));\n    const destPath = SLASH(PATH.relative( process.cwd(), fOut));\n    SPAWN('phantomjs', [ scriptPath, sourcePath, destPath ], false, on_error, this);\n  },\n\n  /**\n  Generate a PDF from HTML using WeasyPrint's CLI interface.\n  Spawns a child process with `weasyprint <source> <target>`. Weasy Print\n  must be installed and path-accessible.\n  TODO: If HTML generation has run, reuse that output\n  */\n  weasyprint( markup, fOut, opts, on_error ) {\n    // Save the markup to a temporary file\n    const tempFile = fOut.replace(/\\.pdf$/i, '.pdf.html');\n    FS.writeFileSync(tempFile, markup, 'utf8');\n\n    SPAWN('weasyprint', [tempFile, fOut], false, on_error, this);\n  }\n};\n\nfunction __guardMethod__(obj, methodName, transform) {\n  if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') {\n    return transform(obj, methodName);\n  } else {\n    return undefined;\n  }\n}\n"
  },
  {
    "path": "src/generators/html-png-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the HtmlPngGenerator class.\n@module generators/html-png-generator\n@license MIT. See LICENSE.MD for details.\n*/\n\n\n\nconst TemplateGenerator = require('./template-generator');\nconst FS = require('fs-extra');\nconst SLASH = require('slash');\nconst SPAWN = require('../utils/safe-spawn');\nconst PATH = require('path');\n\n\n/**\nAn HTML-based PNG resume generator for HackMyResume.\n*/\nclass HtmlPngGenerator extends TemplateGenerator {\n\n  constructor() { super('png', 'html'); }\n\n  invoke( /*rez, themeMarkup, cssInfo, opts*/ ) {}\n    // TODO: Not currently called or callable.\n\n  generate( rez, f, opts ) {\n    const htmlResults = opts.targets.filter(t => t.fmt.outFormat === 'html');\n    const htmlFile = htmlResults[0].final.files.filter(fl => fl.info.ext === 'html');\n    phantom(htmlFile[0].data, f);\n  }\n}\n\nmodule.exports = HtmlPngGenerator;\n\n/**\nGenerate a PDF from HTML using Phantom's CLI interface.\nSpawns a child process with `phantomjs <script> <source> <target>`. Phantom\nmust be installed and path-accessible.\nTODO: If HTML generation has run, reuse that output\nTODO: Local web server to ease Phantom rendering\n*/\n\nvar phantom = function( markup, fOut ) {\n\n  // Save the markup to a temporary file\n  const tempFile = fOut.replace(/\\.png$/i, '.png.html');\n  FS.writeFileSync(tempFile, markup, 'utf8');\n  const scriptPath = SLASH( PATH.relative( process.cwd(),\n    PATH.resolve( __dirname, '../utils/rasterize.js' ) ) );\n  const sourcePath = SLASH( PATH.relative( process.cwd(), tempFile) );\n  const destPath = SLASH( PATH.relative( process.cwd(), fOut) );\n  SPAWN('phantomjs', [ scriptPath, sourcePath, destPath ]);\n};\n"
  },
  {
    "path": "src/generators/json-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the JsonGenerator class.\n@module generators/json-generator\n@license MIT. See LICENSE.md for details.\n*/\n\nconst BaseGenerator = require('./base-generator');\nconst FS = require('fs');\nconst FJCV = require('fresh-jrs-converter');\n\n/** The JsonGenerator generates a FRESH or JRS resume as an output. */\n\nclass JsonGenerator extends BaseGenerator {\n\n  constructor() { super('json'); }\n\n  invoke( rez ) {\n    let altRez = FJCV[ `to${rez.format() === 'FRESH' ? 'JRS' : 'FRESH'}` ](rez);\n    return altRez = FJCV.toSTRING( altRez );\n  }\n    //altRez.stringify()\n\n  generate( rez, f ) {\n    FS.writeFileSync(f, this.invoke(rez), 'utf8');\n  }\n}\n\nmodule.exports = JsonGenerator;\n"
  },
  {
    "path": "src/generators/json-yaml-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the JsonYamlGenerator class.\n@module generators/json-yaml-generator\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst BaseGenerator = require('./base-generator');\nconst FS = require('fs');\nconst YAML = require('yamljs');\n\n\n\n/**\nJsonYamlGenerator takes a JSON resume object and translates it directly to\nJSON without a template, producing an equivalent YAML-formatted resume. See\nalso YamlGenerator (yaml-generator.js).\n*/\n\nclass JsonYamlGenerator extends BaseGenerator {\n\n  constructor() { super('yml'); }\n\n  invoke( rez/*, themeMarkup, cssInfo, opts*/ ) {\n    return YAML.stringify(JSON.parse( rez.stringify() ), Infinity, 2);\n  }\n\n  generate( rez, f/*, opts */) {\n    const data = YAML.stringify(JSON.parse( rez.stringify() ), Infinity, 2);\n    FS.writeFileSync(f, data, 'utf8');\n    return data;\n  }\n}\n\nmodule.exports = JsonYamlGenerator;\n"
  },
  {
    "path": "src/generators/latex-generator.js",
    "content": "/**\nDefinition of the LaTeXGenerator class.\n@module generators/latex-generator\n@license MIT. See LICENSE.md for details.\n*/\n\nconst TemplateGenerator = require('./template-generator');\n\n/**\nLaTeXGenerator generates a LaTeX resume via TemplateGenerator.\n*/\nclass LaTeXGenerator extends TemplateGenerator {\n\n  constructor() { super('latex', 'tex'); }\n}\n\nmodule.exports = LaTeXGenerator;\n"
  },
  {
    "path": "src/generators/markdown-generator.js",
    "content": "/**\nDefinition of the MarkdownGenerator class.\n@module generators/markdown-generator\n@license MIT. See LICENSE.md for details.\n*/\n\nconst TemplateGenerator = require('./template-generator');\n\n/**\nMarkdownGenerator generates a Markdown-formatted resume via TemplateGenerator.\n*/\nclass MarkdownGenerator extends TemplateGenerator {\n\n  constructor() { super('md', 'txt'); }\n}\n\nmodule.exports = MarkdownGenerator;\n"
  },
  {
    "path": "src/generators/template-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the TemplateGenerator class. TODO: Refactor\n@module generators/template-generator\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst FS = require('fs-extra');\nconst _ = require('underscore');\nconst MD = require('marked');\nconst XML = require('xml-escape');\nconst PATH = require('path');\nconst parsePath = require('parse-filepath');\nconst MKDIRP = require('mkdirp');\nconst BaseGenerator = require('./base-generator');\nconst EXTEND = require('extend');\n\n\n\n/**\nTemplateGenerator performs resume generation via local Handlebar or Underscore\nstyle template expansion and is appropriate for text-based formats like HTML,\nplain text, and XML versions of Microsoft Word, Excel, and OpenOffice.\n@class TemplateGenerator\n*/\n\nclass TemplateGenerator extends BaseGenerator {\n\n\n\n  /** Constructor. Set the output format and template format for this\n  generator. Will usually be called by a derived generator such as\n  HTMLGenerator or MarkdownGenerator. */\n\n  constructor( outputFormat, templateFormat/*, cssFile */) {\n    super(outputFormat);\n    this.tplFormat = templateFormat || outputFormat;\n  }\n\n\n\n  /** Generate a resume using string-based inputs and outputs without touching\n  the filesystem.\n  @method invoke\n  @param rez A FreshResume object.\n  @param opts Generator options.\n  @returns {Array} An array of objects representing the generated output\n  files. */\n\n  invoke( rez, opts ) {\n\n    opts =\n      opts\n      ? (this.opts = EXTEND( true, { }, _defaultOpts, opts ))\n      : this.opts;\n\n    // Sort such that CSS files are processed before others\n    const curFmt = opts.themeObj.getFormat( this.format );\n    curFmt.files = _.sortBy(curFmt.files, fi => fi.ext !== 'css');\n\n    // Run the transformation!\n    const results = curFmt.files.map(function( tplInfo, idx ) {\n      let trx;\n      if (tplInfo.action === 'transform') {\n        trx = this.transform(rez, tplInfo.data, this.format, opts, opts.themeObj, curFmt);\n        if (tplInfo.ext === 'css') {\n          curFmt.files[idx].data = trx;\n        } else { tplInfo.ext === 'html'; }\n      }\n          //tplInfo.css contains the CSS data loaded by theme\n          //tplInfo.cssPath contains the absolute path to the source CSS File\n      //else {}\n        // Images and non-transformable binary files\n      if (typeof opts.onTransform === 'function') {\n        opts.onTransform(tplInfo);\n      }\n      return {info: tplInfo, data: trx};\n    }\n    , this);\n\n    return {files: results};\n  }\n\n\n\n  /** Generate a resume using file-based inputs and outputs. Requires access\n  to the local filesystem.\n  @method generate\n  @param rez A FreshResume object.\n  @param f Full path to the output resume file to generate.\n  @param opts Generator options. */\n\n  generate( rez, f, opts ) {\n\n    // Prepare\n    this.opts = EXTEND(true, { }, _defaultOpts, opts);\n\n    // Call the string-based generation method\n    const genInfo = this.invoke(rez, null);\n    const outFolder = parsePath( f ).dirname;\n    const curFmt = opts.themeObj.getFormat(this.format);\n\n    // Process individual files within this format. For example, the HTML\n    // output format for a theme may have multiple HTML files, CSS files,\n    // etc. Process them here.\n    genInfo.files.forEach(function( file ) {\n\n      // console.dir _.omit(file.info,'cssData','data','css' )\n\n      // Pre-processing\n      file.info.orgPath = file.info.orgPath || '';\n      const thisFilePath =\n        file.info.primary\n        ? f\n        : PATH.join(outFolder, file.info.orgPath);\n\n      if ((file.info.action !== 'copy') && this.onBeforeSave) {\n        file.data = this.onBeforeSave({\n          theme: opts.themeObj,\n          outputFile: thisFilePath,\n          mk: file.data,\n          opts: this.opts,\n          ext: file.info.ext\n        });\n        if (!file.data) {\n          return;\n        }\n      }\n\n      // Write the file\n      if (typeof opts.beforeWrite === 'function') {\n        opts.beforeWrite({data: thisFilePath});\n      }\n      MKDIRP.sync(PATH.dirname( thisFilePath ));\n\n      if (file.info.action !== 'copy') {\n        FS.writeFileSync(thisFilePath, file.data, {encoding: 'utf8', flags: 'w'});\n      } else {\n        FS.copySync(file.info.path, thisFilePath);\n      }\n      if (typeof opts.afterWrite === 'function') {\n        opts.afterWrite({data: thisFilePath});\n      }\n\n      // Post-processing\n      if (this.onAfterSave) {\n        return this.onAfterSave({outputFile: thisFilePath, mk: file.data, opts: this.opts});\n      }\n    }\n\n    , this);\n\n    // Some themes require a symlink structure. If so, create it.\n    createSymLinks(curFmt, outFolder);\n\n    return genInfo;\n  }\n\n\n\n  /** Perform a single resume resume transformation using string-based inputs\n  and outputs without touching the local file system.\n  @param json A FRESH or JRS resume object.\n  @param jst The stringified template data\n  @param format The format name, such as \"html\" or \"latex\"\n  @param cssInfo Needs to be refactored.\n  @param opts Options and passthrough data. */\n\n  transform( json, jst, format, opts, theme, curFmt ) {\n    if (this.opts.freezeBreaks) {\n      jst = freeze(jst);\n    }\n    const eng = require(`../renderers/${theme.engine}-generator`);\n    let result = eng.generate(json, jst, format, curFmt, opts, theme);\n    if (this.opts.freezeBreaks) {\n      result = unfreeze(result);\n    }\n    return result;\n  }\n}\n\n\nmodule.exports = TemplateGenerator;\n\n\n\nvar createSymLinks = function( curFmt, outFolder ) {\n  // Some themes require a symlink structure. If so, create it.\n  if (curFmt.symLinks) {\n    Object.keys( curFmt.symLinks ).forEach(function(loc) {\n      const absLoc = PATH.join(outFolder, loc);\n      const absTarg = PATH.join(PATH.dirname(absLoc), curFmt.symLinks[loc]);\n      // Set type to 'file', 'dir', or 'junction' (Windows only)\n      const type = parsePath( absLoc ).extname ? 'file' : 'junction';\n\n      try {\n        return FS.symlinkSync(absTarg, absLoc, type);\n      } catch (err) {\n        let succeeded = false;\n        if (err.code === 'EEXIST') {\n          FS.unlinkSync(absLoc);\n          try {\n            FS.symlinkSync(absTarg, absLoc, type);\n            succeeded = true;\n          } catch (error) {\n            throw error;\n          }\n        }\n        if (!succeeded) {\n          throw err;\n        }\n      }\n    });\n    return;\n  }\n};\n\n\n/** Freeze newlines for protection against errant JST parsers. */\nvar freeze = function( markup ) {\n  markup.replace( _reg.regN, _defaultOpts.nSym );\n  return markup.replace( _reg.regR, _defaultOpts.rSym );\n};\n\n\n\n/** Unfreeze newlines when the coast is clear. */\nvar unfreeze = function( markup ) {\n  markup.replace(_reg.regSymR, '\\r');\n  return markup.replace(_reg.regSymN, '\\n');\n};\n\n\n\n/** Default template generator options. */\nvar _defaultOpts = {\n  engine: 'underscore',\n  keepBreaks: true,\n  freezeBreaks: false,\n  nSym: '&newl;', // newline entity\n  rSym: '&retn;', // return entity\n  template: {\n    interpolate: /\\{\\{(.+?)\\}\\}/g,\n    escape: /\\{\\{=(.+?)\\}\\}/g,\n    evaluate: /\\{%(.+?)%\\}/g,\n    comment: /\\{#(.+?)#\\}/g\n  },\n  filters: {\n    out( txt ) { return txt; },\n    raw( txt ) { return txt; },\n    xml( txt ) { return XML(txt); },\n    md( txt ) { return MD( txt || '' ); },\n    mdin( txt ) { return MD(txt || '' ).replace(/^\\s*<p>|<\\/p>\\s*$/gi, ''); },\n    lower( txt ) { return txt.toLowerCase(); },\n    link( name, url ) {\n      if (url) { return `<a href=\"${url}\">${name}</a>`; } else { return name; }\n    }\n  },\n  prettify: { // ← See https://github.com/beautify-web/js-beautify#options\n    indent_size: 2,\n    unformatted: ['em','strong','a'],\n    max_char: 80\n  } // ← See lib/html.js in above-linked repo\n};\n    //wrap_line_length: 120, <-- Don't use this\n\n\n\n/** Regexes for linebreak preservation. */\n/* eslint-disable no-control-regex */\nvar _reg = {\n  regN: new RegExp( '\\n', 'g' ),\n  regR: new RegExp( '\\r', 'g' ),\n  regSymN: new RegExp( _defaultOpts.nSym, 'g' ),\n  regSymR: new RegExp( _defaultOpts.rSym, 'g' )\n};\n/* eslint-enable no-control-regex */\n"
  },
  {
    "path": "src/generators/text-generator.js",
    "content": "/**\nDefinition of the TextGenerator class.\n@module generators/text-generator\n@license MIT. See LICENSE.md for details.\n*/\n\nconst TemplateGenerator = require('./template-generator');\n\n/**\nThe TextGenerator generates a plain-text resume via the TemplateGenerator.\n*/\nclass TextGenerator extends TemplateGenerator {\n  constructor() { super('txt'); }\n}\n\nmodule.exports = TextGenerator;\n"
  },
  {
    "path": "src/generators/word-generator.js",
    "content": "/*\nDefinition of the WordGenerator class.\n@module generators/word-generator\n@license MIT. See LICENSE.md for details.\n*/\n\n\nconst TemplateGenerator = require('./template-generator');\n\nclass WordGenerator extends TemplateGenerator {\n  constructor() { super('doc', 'xml'); }\n}\n\nmodule.exports = WordGenerator;\n"
  },
  {
    "path": "src/generators/xml-generator.js",
    "content": "/**\nDefinition of the XMLGenerator class.\n@license MIT. See LICENSE.md for details.\n@module generatprs/xml-generator\n*/\n\nconst BaseGenerator = require('./base-generator');\n\n/** The XmlGenerator generates an XML resume via the TemplateGenerator. */\nclass XMLGenerator extends BaseGenerator {\n  constructor() { super('xml'); }\n}\n\nmodule.exports = XMLGenerator;\n"
  },
  {
    "path": "src/generators/yaml-generator.js",
    "content": "/**\nDefinition of the YAMLGenerator class.\n@module yaml-generator.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\nconst TemplateGenerator = require('./template-generator');\n\n/**\nYamlGenerator generates a YAML-formatted resume via TemplateGenerator.\n*/\n\nclass YAMLGenerator extends TemplateGenerator {\n  constructor() { super('yml', 'yml'); }\n}\n\n\nmodule.exports = YAMLGenerator;\n"
  },
  {
    "path": "src/helpers/block-helpers.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nBlock helper definitions for HackMyResume / FluentCV.\n@license MIT. See LICENSE.md for details.\n@module helpers/generic-helpers\n*/\n\n\n\nconst LO = require('lodash');\nconst _ = require('underscore');\nrequire('../utils/string');\n\n\n\n/** Block helper function definitions. */\nmodule.exports = {\n\n\n\n  /**\n  Emit the enclosed content if the resume has a section with\n  the specified name. Otherwise, emit an empty string ''.\n  */\n\n  section( title, options ) {\n    title = title.trim().toLowerCase();\n    const obj = LO.get(this.r, title);\n    let ret = '';\n    if (obj) {\n      if (_.isArray(obj)) {\n        if (obj.length) {\n          ret = options.fn(this);\n        }\n      } else if (_.isObject(obj)) {\n        if ((obj.history && obj.history.length) || (obj.sets && obj.sets.length)) {\n            ret = options.fn(this);\n          }\n      }\n    }\n    return ret;\n  },\n\n\n\n  ifHasSkill( rez, skill, options ) {\n    const skUp = skill.toUpperCase();\n    const ret = _.some(rez.skills.list, sk => (skUp.toUpperCase() === sk.name.toUpperCase()) && sk.years\n    , this);\n    if (ret) { return options.fn(this); }\n  },\n\n\n  /**\n  Emit the enclosed content if the resume has the named\n  property or subproperty.\n  */\n\n  has( title, options ) {\n    title = title && title.trim().toLowerCase();\n    if (LO.get(this.r, title)) {\n      return options.fn(this);\n    }\n  },\n\n\n\n  /**\n  Return true if either value is truthy.\n  @method either\n  */\n  either( lhs, rhs, options ) { if (lhs || rhs) { return options.fn(this); } }\n};\n"
  },
  {
    "path": "src/helpers/console-helpers.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nGeneric template helper definitions for command-line output.\n@module console-helpers.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst PAD   = require('string-padding');\nconst LO    = require('lodash');\nconst CHALK = require('chalk');\nconst _     = require('underscore');\nrequire('../utils/string');\n\n\n\nmodule.exports = {\n\n  v( val, defaultVal, padding, style ) {\n    let retVal = ( (val === null) || (val === undefined) ) ? defaultVal : val;\n    let spaces = 0;\n    if (String.is(padding)) {\n      spaces = parseInt(padding, 10);\n      if (isNaN(spaces)) { spaces = 0; }\n    } else if (_.isNumber(padding)) {\n      spaces = padding;\n    }\n\n    if (spaces !== 0) {\n      retVal = PAD(retVal, Math.abs(spaces), null, spaces > 0 ? PAD.LEFT : PAD.RIGHT);\n    }\n\n    if (style && String.is( style )) {\n      retVal = LO.get( CHALK, style )( retVal );\n    }\n    return retVal;\n  },\n\n  gapLength(val) {\n    if (val < 35) {\n      return CHALK.green.bold(val);\n    } else if (val < 95) {\n      return CHALK.yellow.bold(val);\n    } else {\n      return CHALK.red.bold(val);\n    }\n  },\n\n  style( val, style ) {\n    return LO.get( CHALK, style )( val );\n  },\n\n  isPlural( val, options ) {\n    if (val > 1) {\n      return options.fn(this);\n    }\n  },\n\n  pad( val, spaces ) {\n    return PAD(val, Math.abs(spaces), null, spaces > 0 ? PAD.LEFT : PAD.RIGHT);\n  }\n};\n"
  },
  {
    "path": "src/helpers/generic-helpers.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nGeneric template helper definitions for HackMyResume / FluentCV.\n@license MIT. See LICENSE.md for details.\n@module helpers/generic-helpers\n*/\n\n\n\nconst MD = require('marked');\nconst H2W = require('../utils/html-to-wpml');\nconst XML = require('xml-escape');\nconst FluentDate = require('../core/fluent-date');\nconst HMSTATUS = require('../core/status-codes');\nconst moment = require('moment');\nconst FS = require('fs');\nconst LO = require('lodash');\nconst PATH = require('path');\nconst printf = require('printf');\nconst _ = require('underscore');\nrequire('../utils/string');\n\n\n\n/** Generic template helper function definitions. */\nvar GenericHelpers = (module.exports = {\n\n\n\n  /**\n  Emit a formatted string representing the specified datetime.\n  Convert the input date to the specified format through Moment.js. If date is\n  valid, return the formatted date string. If date is null, undefined, or other\n  falsy value, return the value of the 'fallback' parameter, if specified, or\n  null if no fallback was specified. If date is invalid, but not null/undefined/\n  falsy, return it as-is.\n  @param {string|Moment} datetime A date value.\n  @param {string} [dtFormat='YYYY-MM'] The desired datetime format. Must be a\n  Moment.js-compatible datetime format.\n  @param {string|Moment} fallback A fallback value to use if the specified date\n  is null, undefined, or falsy.\n  */\n  formatDate(datetime, dtFormat, fallback) {\n\n    if (datetime == null) { datetime = undefined; }\n    if (dtFormat == null) { dtFormat = 'YYYY-MM'; }\n\n    // If a Moment.js object was passed in, just call format on it\n    if (datetime && moment.isMoment(datetime)) {\n      return datetime.format(dtFormat);\n    }\n\n    if (String.is(datetime)) {\n      // If a string was passed in, convert to Moment using the 2-paramter\n      // constructor with an explicit format string.\n      let momentDate = moment(datetime, dtFormat);\n      if (momentDate.isValid()) { return momentDate.format(dtFormat); }\n\n      // If that didn't work, try again with the single-parameter constructor\n      // but this may throw a deprecation warning\n      momentDate = moment(datetime);\n      if (momentDate.isValid()) { return momentDate.format(dtFormat); }\n    }\n\n    // We weren't able to format the provided datetime. Now do one of three\n    // things.\n    //   1. If datetime is non-null/non-falsy, return it. For this helper,\n    // string date values that we can't parse are assumed to be display dates.\n    //   2. If datetime IS null or falsy, use the value from the fallback.\n    //   3. If the fallback value is specifically 'true', emit 'Present'.\n    return datetime ||\n      (typeof fallback === 'string'\n      ? fallback\n      : (fallback === true ? 'Present' : ''));\n  },\n\n\n\n  /**\n  Emit a formatted string representing the specified datetime.\n  @param {string} dateValue A raw date value from the FRESH or JRS resume.\n  @param {string} [dateFormat='YYYY-MM'] The desired datetime format. Must be\n  compatible with Moment.js datetime formats.\n  @param {string} [dateDefault=null] The default date value to use if the dateValue\n  parameter is null, undefined, or falsy.\n  */\n  date(dateValue, dateFormat, dateDefault) {\n\n    if (!dateDefault || !String.is(dateDefault)) { dateDefault = 'Current'; }\n    if (!dateFormat || !String.is(dateFormat)) { dateFormat = 'YYYY-MM'; }\n    if (!dateValue || !String.is(dateValue)) { dateValue = null; }\n    if (!dateValue) { return dateDefault; }\n\n    const reserved = ['current', 'present', 'now'];\n    const dateValueSafe = dateValue.trim().toLowerCase();\n    if (_.contains(reserved, dateValueSafe)) { return dateValue; }\n\n    const dateValueMoment = moment(dateValue, dateFormat);\n    if (dateValueMoment.isValid()) { return dateValueMoment.format(dateFormat); }\n    return dateValue;\n  },\n\n\n\n  /**\n  Given a resume sub-object with a start/end date, format a representation of\n  the date range.\n  */\n  dateRange( obj, fmt, sep, fallback ) {\n    if (!obj) { return ''; }\n    return _fromTo(obj.start, obj.end, fmt, sep, fallback);\n  },\n\n\n\n  /**\n  Format a from/to date range for display.\n  @method toFrom\n  */\n  fromTo() { return _fromTo.apply(this, arguments); },\n\n\n\n  /**\n  Return a named color value as an RRGGBB string.\n  @method toFrom\n  */\n  color( colorName, colorDefault ) {\n    // Key must be specified\n    if (!(colorName && colorName.trim())) {\n      return _reportError(HMSTATUS.invalidHelperUse,\n        {helper: 'fontList', error: HMSTATUS.missingParam, expected: 'name'});\n    } else {\n      if (!GenericHelpers.theme.colors) { return colorDefault; }\n      const ret = GenericHelpers.theme.colors[ colorName ];\n      if (!(ret && ret.trim())) {\n        return colorDefault;\n      }\n      return ret;\n    }\n  },\n\n\n\n  /**\n  Emit the size of the specified named font.\n  @param key {String} A named style from the \"fonts\" section of the theme's\n  theme.json file. For example: 'default' or 'heading1'.\n  */\n  fontSize( key, defSize/*, units*/ ) {\n\n    let ret = '';\n    const hasDef = defSize && ( String.is( defSize ) || _.isNumber( defSize ));\n\n    // Key must be specified\n    if (!(key && key.trim())) {\n      _reportError( HMSTATUS.invalidHelperUse, {\n        helper: 'fontSize', error: HMSTATUS.missingParam, expected: 'key'\n      });\n      return ret;\n\n    } else if (GenericHelpers.theme.fonts) {\n      let fontSpec = LO.get( GenericHelpers.theme.fonts, this.format + '.' + key );\n      if (!fontSpec) {\n        // Check for an \"all\" format\n        if (GenericHelpers.theme.fonts.all) {\n          fontSpec = GenericHelpers.theme.fonts.all[ key ];\n        }\n      }\n      if( fontSpec ) {\n        // fontSpec can be a string, an array, or an object\n        if( String.is( fontSpec )) {\n          // No font size was specified, only a font family.\n        } else if( _.isArray( fontSpec )) {\n          // An array of fonts were specified. Each one could be a string\n          // or an object\n          if( !String.is( fontSpec[0] )) {\n            ret = fontSpec[0].size;\n          }\n        } else {\n          // A font description object.\n          ret = fontSpec.size;\n        }\n      }\n    }\n\n    // We weren't able to lookup the specified key. Default to defFont.\n    if (!ret) {\n      if (hasDef) {\n        ret = defSize;\n      } else {\n        _reportError( HMSTATUS.invalidHelperUse, {\n          helper: 'fontSize', error: HMSTATUS.missingParam,\n          expected: 'defSize'});\n        ret = '';\n      }\n    }\n\n    return ret;\n  },\n\n\n\n  /**\n  Emit the font face (such as 'Helvetica' or 'Calibri') associated with the\n  provided key.\n  @param key {String} A named style from the \"fonts\" section of the theme's\n  theme.json file. For example: 'default' or 'heading1'.\n  @param defFont {String} The font to use if the specified key isn't present.\n  Can be any valid font-face name such as 'Helvetica Neue' or 'Calibri'.\n  */\n  fontFace( key, defFont ) {\n\n    let ret = '';\n    const hasDef = defFont && String.is( defFont );\n\n    // Key must be specified\n    if (!( key && key.trim())) {\n      _reportError( HMSTATUS.invalidHelperUse, {\n        helper: 'fontFace', error: HMSTATUS.missingParam, expected: 'key'\n      });\n      return ret;\n\n    // If the theme has a \"fonts\" section, lookup the font face.\n    } else if( GenericHelpers.theme.fonts ) {\n      let fontSpec = LO.get( GenericHelpers.theme.fonts, this.format + '.' + key);\n      if (!fontSpec) {\n        // Check for an \"all\" format\n        if (GenericHelpers.theme.fonts.all) {\n          fontSpec = GenericHelpers.theme.fonts.all[ key ];\n        }\n      }\n\n      if (fontSpec) {\n        // fontSpec can be a string, an array, or an object\n        if (String.is(fontSpec)) {\n          ret = fontSpec;\n        } else if (_.isArray(fontSpec)) {\n          // An array of fonts were specified. Each one could be a string\n          // or an object\n          ret = String.is( fontSpec[0] ) ? fontSpec[0] : fontSpec[0].name;\n        } else {\n          // A font description object.\n          ret = fontSpec.name;\n        }\n      }\n    }\n\n\n    // We weren't able to lookup the specified key. Default to defFont.\n    if (!(ret && ret.trim())) {\n      ret = defFont;\n      if (!hasDef) {\n        _reportError( HMSTATUS.invalidHelperUse, {\n          helper: 'fontFace', error: HMSTATUS.missingParam,\n          expected: 'defFont'});\n        ret = '';\n      }\n    }\n\n    return ret;\n  },\n\n\n\n  /**\n  Emit a comma-delimited list of font names suitable associated with the\n  provided key.\n  @param key {String} A named style from the \"fonts\" section of the theme's\n  theme.json file. For example: 'default' or 'heading1'.\n  @param defFontList {Array} The font list to use if the specified key isn't\n  present. Can be an array of valid font-face name such as 'Helvetica Neue'\n  or 'Calibri'.\n  @param sep {String} The default separator to use in the rendered output.\n  Defaults to \", \" (comma with a space).\n  */\n  fontList( key, defFontList, sep ) {\n\n    let ret = '';\n    const hasDef = defFontList && String.is( defFontList );\n\n    // Key must be specified\n    if (!( key && key.trim())) {\n      _reportError( HMSTATUS.invalidHelperUse, {\n        helper: 'fontList', error: HMSTATUS.missingParam, expected: 'key'\n      });\n\n    // If the theme has a \"fonts\" section, lookup the font list.\n    } else if (GenericHelpers.theme.fonts) {\n      let fontSpec = LO.get(GenericHelpers.theme.fonts, this.format + '.' + key);\n      if (!fontSpec) {\n        if (GenericHelpers.theme.fonts.all) {\n          fontSpec = GenericHelpers.theme.fonts.all[ key ];\n        }\n      }\n\n      if (fontSpec) {\n        // fontSpec can be a string, an array, or an object\n        if (String.is(fontSpec)) {\n          ret = fontSpec;\n        } else if (_.isArray(fontSpec)) {\n          // An array of fonts were specified. Each one could be a string\n          // or an object\n          fontSpec = fontSpec.map( ff  => `'${String.is( ff ) ? ff : ff.name}'`);\n          ret = fontSpec.join( sep === undefined ? ', ' : (sep || '') );\n        } else {\n          // A font description object.\n          ret = fontSpec.name;\n        }\n      }\n    }\n\n    // The key wasn't found in the \"fonts\" section. Default to defFont.\n    if (!(ret && ret.trim())) {\n      if (!hasDef) {\n        _reportError( HMSTATUS.invalidHelperUse, {\n          helper: 'fontList', error: HMSTATUS.missingParam,\n          expected: 'defFontList'});\n        ret = '';\n      } else {\n        ret = defFontList;\n      }\n    }\n\n    return ret;\n  },\n\n\n\n  /**\n  Capitalize the first letter of the word. TODO: Rename\n  @method section\n  */\n  camelCase(val) {\n    val = (val && val.trim()) || '';\n    if (val) { return (val.charAt(0).toUpperCase() + val.slice(1)); } else { return val; }\n  },\n\n\n\n  /**\n  Display a user-overridable section title for a FRESH resume theme. Use this in\n  lieue of hard-coding section titles.\n\n  Usage:\n\n      {{sectionTitle \"sectionName\"}}\n      {{sectionTitle \"sectionName\" \"sectionTitle\"}}\n\n  Example:\n\n      {{sectionTitle \"Education\"}}\n      {{sectionTitle \"Employment\" \"Project History\"}}\n\n  @param sect_name The name of the section being title. Must be one of the\n  top-level FRESH resume sections (\"info\", \"education\", \"employment\", etc.).\n  @param sect_title The theme-specified section title. May be replaced by the\n  user.\n  @method sectionTitle\n  */\n  sectionTitle( sname, stitle ) {\n\n    // If not provided by the user, stitle should default to sname. ps.\n    // Handlebars silently passes in the options object to the last param,\n    // where in Underscore stitle will be null/undefined, so we check both.\n    // TODO: not actually sure that's true, given that we _.wrap these functions\n    stitle = (stitle && String.is(stitle) && stitle) || sname;\n\n    // If there's a section title override, use it.\n    return ( this.opts.stitles &&\n      this.opts.stitles[ sname.toLowerCase().trim() ] ) ||\n      stitle;\n  },\n\n\n\n  /** Convert inline Markdown to inline WordProcessingML. */\n  wpml( txt, inline ) {\n    if (!txt) { return ''; }\n    inline = (inline && !inline.hash) || false;\n    txt = XML(txt.trim());\n    txt = inline ? MD(txt).replace(/^\\s*<p>|<\\/p>\\s*$/gi, '') : MD(txt);\n    txt = H2W( txt );\n    return txt;\n  },\n\n\n\n  /**\n  Emit a conditional link.\n  @method link\n  */\n  link( text, url ) {\n    if (url && url.trim()) { return (`<a href=\"${url}\">${text}</a>`); } else { return text; }\n  },\n\n\n\n  /**\n  Emit a conditional Markdown link.\n  @method link\n  */\n  linkMD( text, url ) {\n    if (url && url.trim()) { return (`[${text}](${url})`); } else { return text; }\n  },\n\n\n\n  /**\n  Return the last word of the specified text.\n  @method lastWord\n  */\n  lastWord( txt ) {\n    if (txt && txt.trim()) { return _.last( txt.split(' ') ); } else { return ''; }\n  },\n\n\n\n  /**\n  Convert a skill level to an RGB color triplet. TODO: refactor\n  @method skillColor\n  @param lvl Input skill level. Skill level can be expressed as a string\n  (\"beginner\", \"intermediate\", etc.), as an integer (1,5,etc), as a string\n  integer (\"1\", \"5\", etc.), or as an RRGGBB color triplet ('#C00000',\n  '#FFFFAA').\n  */\n  skillColor( lvl ) {\n    const idx = _skillLevelToIndex(lvl);\n    const skillColors = (this.theme && this.theme.palette &&\n      this.theme.palette.skillLevels) ||\n      [ '#FFFFFF', '#5CB85C', '#F1C40F', '#428BCA', '#C00000' ];\n    return skillColors[idx];\n  },\n\n\n\n  /**\n  Return an appropriate height. TODO: refactor\n  @method lastWord\n  */\n  skillHeight( lvl ) {\n    const idx = _skillLevelToIndex(lvl);\n    return ['38.25', '30', '16', '8', '0'][idx];\n  },\n\n\n\n  /**\n  Return all but the last word of the input text.\n  @method initialWords\n  */\n  initialWords( txt ) {\n    if (txt && txt.trim()) { return _.initial( txt.split(' ') ).join(' '); } else { return ''; }\n  },\n\n\n\n  /**\n  Trim the protocol (http or https) from a URL/\n  @method trimURL\n  */\n  trimURL( url ) {\n    if (url && url.trim()) { return url.trim().replace(/^https?:\\/\\//i, ''); } else { return ''; }\n  },\n\n\n\n  /**\n  Convert text to lowercase.\n  @method toLower\n  */\n  toLower( txt ) { if (txt && txt.trim()) { return txt.toLowerCase(); } else { return ''; } },\n\n\n\n  /**\n  Convert text to lowercase.\n  @method toLower\n  */\n  toUpper( txt ) { if (txt && txt.trim()) { return txt.toUpperCase(); } else { return ''; } },\n\n\n\n  /**\n  Conditional stylesheet link. Creates a link to the specified stylesheet with\n  <link> or embeds the styles inline with <style></style>, depending on the\n  theme author's and user's preferences.\n  @param url {String} The path to the CSS file.\n  @param linkage {String} The default link method. Can be either `embed` or\n  `link`. If omitted, defaults to `embed`. Can be overridden by the `--css`\n  command-line switch.\n  */\n  styleSheet( url, linkage ) {\n\n    // Establish the linkage style\n    linkage = this.opts.css || linkage || 'embed';\n\n    // Create the <link> or <style> tag\n    let ret = '';\n    if (linkage === 'link') {\n      ret = printf('<link href=\"%s\" rel=\"stylesheet\" type=\"text/css\">', url);\n    } else {\n      const rawCss = FS.readFileSync(\n        PATH.join( this.opts.themeObj.folder, '/src/', url ), 'utf8' );\n      const renderedCss = this.engine.generateSimple( this, rawCss );\n      ret = printf('<style>%s</style>', renderedCss );\n    }\n\n    // If the currently-executing template is inherited, append styles\n    if (this.opts.themeObj.inherits && this.opts.themeObj.inherits.html && (this.format === 'html')) {\n      ret +=\n      (linkage === 'link')\n      ? `<link href=\"${this.opts.themeObj.overrides.path}\" rel=\"stylesheet\" type=\"text/css\">`\n      : `<style>${this.opts.themeObj.overrides.data}</style>`;\n    }\n\n    // TODO: It would be nice to use Handlebar.SafeString here, but these\n    // are supposed to be generic helpers. Provide an equivalent, or expose\n    // it when Handlebars is the chosen engine, which is most of the time.\n    return ret;\n  },\n\n\n\n  /**\n  Perform a generic comparison.\n  See: http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates\n  @method compare\n  */\n  compare(lvalue, rvalue, options) {\n    if (arguments.length < 3) {\n      throw new Error('Template helper \\'compare\\' needs 2 parameters');\n    }\n    const operator = options.hash.operator || '==';\n    const operators = {\n        '=='(l,r) { return l === r; },\n        '==='(l,r) { return l === r; },\n        '!='(l,r) { return l !== r; },\n        '<'(l,r) { return l < r; },\n        '>'(l,r) { return l > r; },\n        '<='(l,r) { return l <= r; },\n        '>='(l,r) { return l >= r; },\n        'typeof'(l,r) { return typeof l === r; }\n      };\n    if (!operators[operator]) {\n      throw new Error(`Helper 'compare' doesn't know the operator ${operator}`);\n    }\n    const result = operators[operator]( lvalue, rvalue );\n    if (result) { return options.fn(this); } else { return options.inverse(this); }\n  },\n\n\n\n  /**\n  Emit padded text.\n  */\n  pad(stringOrArray, padAmount/*, unused*/ ) {\n    stringOrArray = stringOrArray || '';\n    padAmount = padAmount || 0;\n    let ret = '';\n    const PAD = require('string-padding');\n    if (!String.is(stringOrArray)) {\n      ret = stringOrArray\n        .map(line => PAD(line, line.length + Math.abs(padAmount), null, padAmount < 0 ? PAD.LEFT : PAD.RIGHT))\n        .join('\\n');\n    } else {\n      ret = PAD(stringOrArray, stringOrArray.length + Math.abs(padAmount), null, padAmount < 0 ? PAD.LEFT : PAD.RIGHT);\n    }\n    return ret;\n  },\n\n\n\n  /**\n  Given the name of a skill (\"JavaScript\" or \"HVAC repair\"), return the number\n  of years assigned to that skill in the resume.skills.list collection.\n  */\n  skillYears( skill, rez ) {\n    const sk = _.find(rez.skills.list, sk => sk.name.toUpperCase() === skill.toUpperCase());\n    if (sk) { return sk.years; } else { return '?'; }\n  },\n\n\n\n  /**\n  Given an object that may be a string or an object, return it as-is if it's a\n  string, otherwise return the value at obj[objPath].\n  */\n  stringOrObject( obj, objPath/*, rez */) {\n    if (_.isString(obj)) { return obj; } else { return LO.get(obj, objPath); }\n  }\n});\n\n\n\n/**\nReport an error to the outside world without throwing an exception. Currently\nrelies on kludging the running verb into. opts.\n*/\nvar _reportError = ( code, params ) => GenericHelpers.opts.errHandler.err( code, params );\n\n\n\n/**\nFormat a from/to date range for display.\n*/\nvar _fromTo = function( dateA, dateB, fmt, sep, fallback ) {\n  // Prevent accidental use of safe.start, safe.end, safe.date\n  // The dateRange helper is for raw dates only\n  if (moment.isMoment( dateA ) || moment.isMoment( dateB )) {\n    _reportError( HMSTATUS.invalidHelperUse, { helper: 'dateRange' } );\n    return '';\n  }\n\n  let dateFrom = null;\n  let dateTo = null;\n  let dateTemp = null;\n\n  // Check for 'current', 'present', 'now', '', null, and undefined\n  dateA = dateA || '';\n  dateB = dateB || '';\n  const dateATrim = dateA.trim().toLowerCase();\n  const dateBTrim = dateB.trim().toLowerCase();\n  const reserved = ['current','present','now', ''];\n\n  fmt = (fmt && String.is(fmt) && fmt) || 'YYYY-MM';\n  sep = (sep && String.is(sep) && sep) || ' — ';\n\n  if (_.contains( reserved, dateATrim )) {\n    dateFrom = fallback || '???';\n  } else {\n    dateTemp = FluentDate.fmt( dateA );\n    dateFrom = dateTemp.format( fmt );\n  }\n\n  if (_.contains( reserved, dateBTrim )) {\n    dateTo = fallback || 'Present';\n  } else {\n    dateTemp = FluentDate.fmt( dateB );\n    dateTo = dateTemp.format( fmt );\n  }\n\n\n  if (dateFrom === dateTo) {\n    return dateFrom;\n  } else if (dateFrom && dateTo) {\n    return dateFrom + sep + dateTo;\n  } else if (dateFrom || dateTo) {\n    return dateFrom || dateTo;\n  }\n  return '';\n};\n\n\n\nvar _skillLevelToIndex = function( lvl ) {\n  let idx = 0;\n  if (String.is( lvl )) {\n    lvl = lvl.trim().toLowerCase();\n    const intVal = parseInt( lvl );\n    if (isNaN(intVal)) {\n      switch (lvl) {\n        case 'beginner': idx = 1; break;\n        case 'intermediate': idx = 2; break;\n        case 'advanced': idx = 3; break;\n        case 'master': idx = 4; break;\n      }\n    } else {\n      idx = Math.min( intVal / 2, 4 );\n      idx = Math.max( 0, idx );\n    }\n  } else {\n    idx = Math.min( lvl / 2, 4 );\n    idx = Math.max( 0, idx );\n  }\n  return idx;\n};\n\n\n\n// Note [1] --------------------------------------------------------------------\n// Make sure it's precisely a string or array since some template engines jam\n// their options/context object into the last parameter and we are allowing the\n// defFont parameter to be omitted in certain cases. This is a little kludgy,\n// but works fine for this case. If we start doing this regularly, we should\n// rebind these parameters.\n\n// Note [2]: -------------------------------------------------------------------\n// If execution reaches here, some sort of cosmic ray or sunspot has landed on\n// HackMyResume, or a theme author is deliberately messing with us by doing\n// something like:\n//\n// \"fonts\": {\n//   \"default\": \"\",\n//   \"heading1\": null\n// }\n//\n// Rather than sort it out, we'll just fall back to defFont.\n"
  },
  {
    "path": "src/helpers/handlebars-helpers.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n\n/**\nTemplate helper definitions for Handlebars.\n@license MIT. See LICENSE.md for details.\n@module handlebars-helpers.js\n*/\n\nconst HANDLEBARS = require('handlebars');\nconst _ = require('underscore');\nconst helpers = require('./generic-helpers');\nconst path = require('path');\nconst blockHelpers = require('./block-helpers');\nconst HMS = require('../core/status-codes');\n\n/**\nRegister useful Handlebars helpers.\n@method registerHelpers\n*/\n\nmodule.exports = function( theme, rez, opts ) {\n\n  helpers.theme = theme;\n  helpers.opts = opts;\n  helpers.type = 'handlebars';\n\n  // Prepare generic helpers for use with Handlebars. We do this by wrapping them\n  // in a Handlebars-aware wrapper which calls the helper internally.\n  const wrappedHelpers = _.mapObject(helpers, function( hVal/*, hKey*/ ) {\n    if (_.isFunction(hVal)) {\n      return _.wrap(hVal, function(func) {\n        const args = Array.prototype.slice.call(arguments);\n        args.shift();                  // lose the 1st element (func) [^1]\n        //args.pop()                   # lose the last element (HB options hash)\n        args[ args.length - 1 ] = rez; // replace w/ resume object\n        return func.apply(this, args);\n      });            // call the generic helper\n    }\n    return hVal;\n  }\n  , this);\n  HANDLEBARS.registerHelper(wrappedHelpers);\n\n  // Prepare Handlebars-specific helpers - \"blockHelpers\" is really a misnomer\n  // since any kind of Handlebars-specific helper can live here\n  HANDLEBARS.registerHelper(blockHelpers);\n\n  // Register any theme-provided custom helpers...\n\n  // Normalize \"theme.helpers\" (string or array) to an array\n  if (_.isString(theme.helpers)) { theme.helpers = [ theme.helpers ]; }\n\n  if (_.isArray(theme.helpers)) {\n    const glob = require('glob');\n    const slash = require('slash');\n    let curGlob = null;\n    try {\n      _.each(theme.helpers, function(fGlob) {            // foreach theme.helpers entry\n        curGlob = fGlob;                           // ..cache in case of exception\n        fGlob = path.join(theme.folder, fGlob);     // ..make relative to theme\n        const files = glob.sync(slash(fGlob));             // ..expand the glob\n        if (files.length > 0) {                       // ..guard against empty glob\n          _.each(files, function(f) {                    // ..loop over concrete paths\n            HANDLEBARS.registerHelper(require(f));   // ..register the path\n          });\n        } else {\n          throw {fluenterror: HMS.themeHelperLoad, inner: null, glob: fGlob};\n        }\n      });\n      return;\n    } catch (ex) {\n      throw{\n        fluenterror: HMS.themeHelperLoad,\n        inner: ex,\n        glob: curGlob, exit: true\n      };\n    }\n  }\n};\n\n// [^1]: This little bit of acrobatics ensures that our generic helpers are\n// called as generic helpers, not as Handlebars-specific helpers. This allows\n// them to be used in other templating engines, like Underscore. If you need a\n// Handlebars-specific helper with normal Handlebars context and options, put it\n// in block-helpers.coffee.\n"
  },
  {
    "path": "src/helpers/underscore-helpers.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nTemplate helper definitions for Underscore.\n@license MIT. See LICENSE.md for details.\n@module handlebars-helpers.js\n*/\n\n\n\nconst _ = require('underscore');\nconst helpers = require('./generic-helpers');\n\n\n\n/**\nRegister useful Underscore helpers.\n@method registerHelpers\n*/\nmodule.exports = function( theme, opts, cssInfo, ctx, eng ) {\n  helpers.theme = theme;\n  helpers.opts = opts;\n  helpers.cssInfo = cssInfo;\n  helpers.engine = eng;\n  ctx.h = helpers;\n  _.each(helpers, function( hVal ) {\n    if (_.isFunction(hVal)) {\n      return _.bind(hVal, ctx);\n    }\n  }\n  , this);\n};\n"
  },
  {
    "path": "src/index.js",
    "content": "/**\nExternal API surface for HackMyResume.\n@license MIT. See LICENSE.md for details.\n@module hackmycore/index\n*/\n\n\n\n/** API facade for HackMyResume. */\n\nmodule.exports = {\n\n  verbs: {\n    build:              require('./verbs/build'),\n    analyze:            require('./verbs/analyze'),\n    validate:           require('./verbs/validate'),\n    convert:            require('./verbs/convert'),\n    new:                require('./verbs/create'),\n    peek:               require('./verbs/peek')\n  },\n\n  alias: {\n    generate:           require('./verbs/build'),\n    create:             require('./verbs/create')\n  },\n\n  options:              require('./core/default-options'),\n  formats:              require('./core/default-formats'),\n  Sheet:                require('./core/fresh-resume'),\n  FRESHResume:          require('./core/fresh-resume'),\n  JRSResume:            require('./core/jrs-resume'),\n  FRESHTheme:           require('./core/fresh-theme'),\n  JRSTheme:             require('./core/jrs-theme'),\n  ResumeFactory:        require('./core/resume-factory'),\n  FluentDate:           require('./core/fluent-date'),\n  HtmlGenerator:        require('./generators/html-generator'),\n  TextGenerator:        require('./generators/text-generator'),\n  HtmlPdfCliGenerator:  require('./generators/html-pdf-cli-generator'),\n  WordGenerator:        require('./generators/word-generator'),\n  MarkdownGenerator:    require('./generators/markdown-generator'),\n  JsonGenerator:        require('./generators/json-generator'),\n  YamlGenerator:        require('./generators/yaml-generator'),\n  JsonYamlGenerator:    require('./generators/json-yaml-generator'),\n  LaTeXGenerator:       require('./generators/latex-generator'),\n  HtmlPngGenerator:     require('./generators/html-png-generator')\n};\n"
  },
  {
    "path": "src/inspectors/duration-inspector.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\nconst FluentDate = require('../core/fluent-date');\nconst _ = require('underscore');\nconst lo = require('lodash');\n\nmodule.exports = {\n\n  /**\n  Compute the total duration of the work history.\n  @returns The total duration of the sheet's work history, that is, the number\n  of years between the start date of the earliest job on the resume and the\n  *latest end date of all jobs in the work history*. This last condition is for\n  sheets that have overlapping jobs.\n  */\n  run(rez, collKey, startKey, endKey, unit) {\n    unit = unit || 'years';\n    const hist = lo.get(rez, collKey);\n    if (!hist || !hist.length) { return 0; }\n\n    // BEGIN CODE DUPLICATION --> src/inspectors/gap-inspector.coffee (TODO)\n\n    // Convert the candidate's employment history to an array of dates,\n    // where each element in the array is a start date or an end date of a\n    // job -- it doesn't matter which.\n    let new_e = hist.map(function( job ) {\n      let obj = _.pick( job, [startKey, endKey] );\n      // Synthesize an end date if this is a \"current\" gig\n      if (!_.has(obj, endKey)) { obj[endKey] = 'current'; }\n      if (obj && (obj[startKey] || obj[endKey])) {\n        obj = _.pairs(obj);\n        obj[0][1] = FluentDate.fmt( obj[0][1] );\n        if (obj.length > 1) {\n          obj[1][1] = FluentDate.fmt( obj[1][1] );\n        }\n      }\n      return obj;\n    });\n\n    // Flatten the array, remove empties, and sort\n    new_e = _.filter(_.flatten( new_e, true ), v => v && v.length && v[0] && v[0].length);\n    if (!new_e || !new_e.length) { return 0; }\n    new_e = _.sortBy(new_e,  elem  => elem[1].unix());\n\n    // END CODE DUPLICATION\n\n    const firstDate = _.first( new_e )[1];\n    const lastDate = _.last( new_e )[1];\n    return lastDate.diff(firstDate, unit);\n  }\n};\n"
  },
  {
    "path": "src/inspectors/gap-inspector.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nEmployment gap analysis for HackMyResume.\n@license MIT. See LICENSE.md for details.\n@module inspectors/gap-inspector\n*/\n\n\n\nconst _ = require('underscore');\nconst FluentDate = require('../core/fluent-date');\nconst moment = require('moment');\nconst LO = require('lodash');\n\n\n\n/**\nIdentify gaps in the candidate's employment history.\n*/\nmodule.exports = {\n\n  moniker: 'gap-inspector',\n\n  /**\n  Run the Gap Analyzer on a resume.\n  @method run\n  @return {Array} An array of object representing gaps in the candidate's\n  employment history. Each object provides the start, end, and duration of the\n  gap:\n      { <-- gap\n        start: // A Moment.js date\n        end: // A Moment.js date\n        duration: // Gap length\n      }\n  */\n\n  run(rez) {\n\n    // This is what we'll return\n    const coverage = {\n      gaps: [],\n      overlaps: [],\n      pct: '0%',\n      duration: {\n        total: 0,\n        work: 0,\n        gaps: 0\n      }\n    };\n\n    // Missing employment section? Bye bye.\n    const hist = LO.get(rez, 'employment.history');\n\n    if (!hist || !hist.length) { return coverage; }\n\n    // Convert the candidate's employment history to an array of dates,\n    // where each element in the array is a start date or an end date of a\n    // job -- it doesn't matter which.\n    let new_e = hist.map( function( job ) {\n      let obj = _.pick( job, ['start', 'end'] );\n      if (obj && (obj.start || obj.end)) {\n        obj = _.pairs( obj );\n        obj[0][1] = FluentDate.fmt( obj[0][1] );\n        if (obj.length > 1) {\n          obj[1][1] = FluentDate.fmt( obj[1][1] );\n        }\n      }\n      return obj;\n    });\n\n    // Flatten the array, remove empties, and sort\n    new_e = _.filter(_.flatten( new_e, true ), v => v && v.length && v[0] && v[0].length);\n\n    if (!new_e || !new_e.length) { return coverage; }\n    new_e = _.sortBy(new_e,  elem  => elem[1].unix());\n\n    // Iterate over elements in the array. Each time a start date is found,\n    // increment a reference count. Each time an end date is found, decrement\n    // the reference count. When the reference count reaches 0, we have a gap.\n    // When the reference count is > 0, the candidate is employed. When the\n    // reference count reaches 2, the candidate is overlapped.\n\n    let ref_count = 0;\n    let total_gap_days = 0;\n\n    new_e.forEach(function(point) {\n\n      const inc = point[0] === 'start' ? 1 : -1;\n      ref_count += inc;\n\n      // If the ref count just reached 0, start a new GAP\n      if (ref_count === 0) {\n        return coverage.gaps.push( { start: point[1], end: null });\n\n      // If the ref count reached 1 by rising, end the last GAP\n      } else if ((ref_count === 1) && (inc === 1)) {\n        const lastGap = _.last( coverage.gaps );\n        if (lastGap) {\n          lastGap.end = point[1];\n          lastGap.duration = lastGap.end.diff( lastGap.start, 'days' );\n          return total_gap_days += lastGap.duration;\n        }\n\n      // If the ref count reaches 2 by rising, start a new OVERLAP\n      } else if ((ref_count === 2) && (inc === 1)) {\n        return coverage.overlaps.push( { start: point[1], end: null });\n\n      // If the ref count reaches 1 by falling, end the last OVERLAP\n      } else if ((ref_count === 1) && (inc === -1)) {\n        const lastOver = _.last( coverage.overlaps );\n        if (lastOver) {\n          lastOver.end = point[1];\n          lastOver.duration = lastOver.end.diff( lastOver.start, 'days' );\n          if (lastOver.duration === 0) {\n            return coverage.overlaps.pop();\n          }\n        }\n      }\n    });\n\n\n    // It's possible that the last gap/overlap didn't have an explicit .end\n    // date.If so, set the end date to the present date and compute the\n    // duration normally.\n    if (coverage.overlaps.length) {\n      const o = _.last( coverage.overlaps );\n      if (o && !o.end) {\n        o.end = moment();\n        o.duration = o.end.diff( o.start, 'days' );\n      }\n    }\n\n    if (coverage.gaps.length) {\n      const g = _.last( coverage.gaps );\n      if (g && !g.end) {\n        g.end = moment();\n        g.duration = g.end.diff( g.start, 'days' );\n      }\n    }\n\n    // Package data for return to the client\n    const tdur = rez.duration('days');\n    const dur = {\n      total: tdur,\n      work: tdur - total_gap_days,\n      gaps: total_gap_days\n    };\n\n    coverage.pct = (dur.total > 0) && (dur.work > 0) ? ((((dur.total - dur.gaps) / dur.total) * 100)).toFixed(1) + '%' : '???';\n    coverage.duration = dur;\n    return coverage;\n  }\n};\n"
  },
  {
    "path": "src/inspectors/keyword-inspector.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nKeyword analysis for HackMyResume.\n@license MIT. See LICENSE.md for details.\n@module inspectors/keyword-inspector\n*/\n\n/**\nAnalyze the resume's use of keywords.\nTODO: BUG: Keyword search regex is inaccurate, especially for one or two\nletter keywords like \"C\" or \"CLI\".\n@class keywordInspector\n*/\nmodule.exports = {\n\n  /** A unique name for this inspector. */\n  moniker: 'keyword-inspector',\n\n  /**\n  Run the Keyword Inspector on a resume.\n  @method run\n  @return An collection of statistical keyword data.\n  */\n  run( rez ) {\n\n    // \"Quote\" or safely escape a keyword so it can be used as a regex. For\n    // example, if the keyword is \"C++\", yield \"C\\+\\+\".\n    // http://stackoverflow.com/a/2593661/4942583\n    const regex_quote = str => (str + '').replace(/[.?*+^$[\\]\\\\(){}|-]/ig, '\\\\$&');\n\n    // Create a searchable plain-text digest of the resume\n    // TODO: BUG: Don't search within keywords for other keywords. Job A\n    // declares the \"foo\" keyword. Job B declares the \"foo & bar\" keyword. Job\n    // B's mention of \"foobar\" should not count as a mention of \"foo\".\n    // To achieve this, remove keywords from the search digest and treat them\n    // separately.\n    let searchable = '';\n    rez.transformStrings(['imp', 'computed', 'safe'], ( key, val ) => searchable += ` ${val}`);\n\n    // Assemble a regex skeleton we can use to test for keywords with a bit\n    // more\n    const prefix = `(?:${['^', '\\\\s+', '[\\\\.,]+'].join('|')})`;\n    const suffix = `(?:${['$', '\\\\s+', '[\\\\.,]+'].join('|')})`;\n\n    return rez.keywords().map(function(kw) {\n\n      // 1. Using word boundary or other regex class is inaccurate\n      //\n      //    var regex = new RegExp( '\\\\b' + regex_quote( kw )/* + '\\\\b'*/, 'ig');\n      //\n      // 2. Searching for the raw keyword is inaccurate (\"C\" will match any\n      // word containing a 'c'!).\n      //\n      //    var regex = new RegExp( regex_quote( kw ), 'ig');\n      //\n      // 3. Instead, use a custom regex with special delimeters.\n\n      const regex_str = prefix + regex_quote( kw ) + suffix;\n      const regex = new RegExp( regex_str, 'ig');\n      let count = 0;\n      while (regex.exec( searchable ) !== null) {\n        count++;\n      }\n      return {\n        name: kw,\n        count\n      };\n    });\n  }\n};\n"
  },
  {
    "path": "src/inspectors/totals-inspector.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nSection analysis for HackMyResume.\n@license MIT. See LICENSE.md for details.\n@module inspectors/totals-inspector\n*/\n\nconst _ = require('underscore');\n\n/**\nRetrieve sectional overview and summary information.\n@class totalsInspector\n*/\nmodule.exports = {\n\n  moniker: 'totals-inspector',\n\n  /**\n  Run the Totals Inspector on a resume.\n  @method run\n  @return An object containing summary information for each section on the\n  resume.\n  */\n  run( rez ) {\n\n    const sectionTotals = { };\n    _.each(rez, function(val, key) {\n      if (_.isArray( val ) && !_.isString(val)) {\n        return sectionTotals[ key ] = val.length;\n      } else if (val.history && _.isArray( val.history )) {\n        return sectionTotals[ key ] = val.history.length;\n      } else if (val.sets && _.isArray( val.sets )) {\n        return sectionTotals[ key ] = val.sets.length;\n      }\n    });\n\n    return {\n      totals: sectionTotals,\n      numSections: Object.keys( sectionTotals ).length\n    };\n  }\n};\n"
  },
  {
    "path": "src/renderers/handlebars-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the HandlebarsGenerator class.\n@license MIT. See LICENSE.md for details.\n@module renderers/handlebars-generator\n*/\n\n\nconst _ = require('underscore');\nconst HANDLEBARS = require('handlebars');\nconst FS = require('fs');\nconst registerHelpers = require('../helpers/handlebars-helpers');\nconst PATH = require('path');\nconst parsePath = require('parse-filepath');\nconst READFILES = require('recursive-readdir-sync');\nconst HMSTATUS = require('../core/status-codes');\nconst SLASH = require('slash');\n\n\n\n/**\nPerform template-based resume generation using Handlebars.js.\n@class HandlebarsGenerator\n*/\nmodule.exports = {\n\n\n\n  generateSimple( data, tpl ) {\n\n    let template;\n    try {\n      // Compile and run the Handlebars template.\n      template = HANDLEBARS.compile(tpl, {\n        strict: false,\n        assumeObjects: false,\n        noEscape: data.opts.noescape\n      }\n      );\n      return template(data);\n    } catch (err) {\n      throw{\n        fluenterror:\n          HMSTATUS[ template ? 'invokeTemplate' : 'compileTemplate' ],\n        inner: err\n      };\n    }\n  },\n\n\n\n  generate( json, jst, format, curFmt, opts, theme ) {\n\n    // Preprocess text\n    let encData = json;\n    if ((format === 'html') || (format === 'pdf')) {\n      encData = json.markdownify();\n    }\n    if( format === 'doc' ) {\n      encData = json.xmlify();\n    }\n\n    // Set up partials and helpers\n    registerPartials(format, theme);\n    registerHelpers(theme, encData, opts);\n\n    // Set up the context\n    const ctx = {\n      r: encData,\n      RAW: json,\n      filt: opts.filters,\n      format,\n      opts,\n      engine: this,\n      results: curFmt.files,\n      headFragment: opts.headFragment || ''\n    };\n\n    // Render the template\n    return this.generateSimple(ctx, jst);\n  }\n};\n\n\n\nvar registerPartials = function(format, theme) {\n\n  if (_.contains( ['html','doc','md','txt','pdf'], format )) {\n\n    // Locate the global partials folder\n    const partialsFolder = PATH.join(\n      parsePath( require.resolve('fresh-themes') ).dirname,\n      '/partials/',\n      format === 'pdf' ? 'html' : format\n    );\n\n    // Register global partials in the /partials/[format] folder\n    // TODO: Only do this once per HMR invocation.\n    _.each(READFILES( partialsFolder ), function( el ) {\n      const name = SLASH(PATH.relative( partialsFolder, el ).replace(/\\.(?:html|xml|hbs|md|txt)$/i, ''));\n      const tplData = FS.readFileSync(el, 'utf8');\n      const compiledTemplate = HANDLEBARS.compile(tplData);\n      HANDLEBARS.registerPartial(name, compiledTemplate);\n      return theme.partialsInitialized = true;\n    });\n  }\n\n  // Register theme-specific partials\n  return _.each(theme.partials, function( el ) {\n    const tplData = FS.readFileSync(el.path, 'utf8');\n    const compiledTemplate = HANDLEBARS.compile(tplData);\n    return HANDLEBARS.registerPartial(el.name, compiledTemplate);\n  });\n};\n"
  },
  {
    "path": "src/renderers/jrs-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the JRSGenerator class.\n@license MIT. See LICENSE.md for details.\n@module renderers/jrs-generator\n*/\n\nconst MD = require('marked');\n\n/**\nPerform template-based resume generation for JSON Resume themes.\n@class JRSGenerator\n*/\n\nmodule.exports = {\n\n  generate( json, jst, format, cssInfo, opts, theme ) {\n\n    // Disable JRS theme chatter (console.log, console.error, etc.)\n    const turnoff = ['log', 'error', 'dir'];\n    const org = turnoff.map(function(c) {\n      const ret = console[c]; // eslint-disable-line no-console\n      console[c] = function() {}; // eslint-disable-line no-console\n      return ret;\n    });\n\n    // Freeze and render\n    let rezHtml = theme.render(json.harden());\n\n    // Turn logging back on\n    turnoff.forEach((c, idx) => console[c] = org[idx]); // eslint-disable-line no-console\n\n    // Unfreeze and apply Markdown\n    return rezHtml = rezHtml.replace(/@@@@~[\\s\\S]*?~@@@@/g, val => MDIN( val.replace( /~@@@@/g,'' ).replace( /@@@@~/g,'' ) ));\n  }\n};\n\n\nvar MDIN = txt => // TODO: Move this\n  MD(txt || '' ).replace(/^\\s*<p>|<\\/p>\\s*$/gi, '')\n;\n"
  },
  {
    "path": "src/renderers/underscore-generator.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the UnderscoreGenerator class.\n@license MIT. See LICENSE.md for details.\n@module underscore-generator.js\n*/\n\n\n\nconst _ = require('underscore');\nconst registerHelpers = require('../helpers/underscore-helpers');\nrequire('../utils/string');\nconst escapeLaTeX = require('escape-latex');\n\n/**\nPerform template-based resume generation using Underscore.js.\n@class UnderscoreGenerator\n*/\nmodule.exports = {\n\n\n\n  generateSimple( data, tpl ) {\n    let t;\n    try {\n      // Compile and run the Handlebars template.\n      t = _.template(tpl);\n      return t(data);\n    } catch (err) {\n      //console.dir _error\n      const HMS = require('../core/status-codes');\n      throw{\n        fluenterror: HMS[t ? 'invokeTemplate' : 'compileTemplate'],\n        inner: err\n      };\n    }\n  },\n\n\n\n  generate( json, jst, format, cssInfo, opts, theme ) {\n\n    // Tweak underscore's default template delimeters\n    let delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;\n    if (opts.themeObj && opts.themeObj.delimeters) {\n      delims = _.mapObject(delims, (val) => new RegExp(val, 'ig'));\n    }\n    _.templateSettings = delims;\n\n    // Massage resume strings / text\n    let r = null;\n    switch (format) {\n      case 'html': r = json.markdownify(); break;\n      case 'pdf': r = json.markdownify(); break;\n      case 'png': r = json.markdownify(); break;\n      case 'latex':\n        var traverse = require('traverse');\n        r = traverse(json).map(function() {\n          if (this.isLeaf && String.is(this.node)) {\n            return escapeLaTeX(this.node);\n          }\n          return this.node;\n        });\n        break;\n      default: r = json;\n    }\n\n    // Set up the context\n    const ctx = {\n      r,\n      filt: opts.filters,\n      XML: require('xml-escape'),\n      RAW: json,\n      cssInfo,\n      //engine: @\n      headFragment: opts.headFragment || '',\n      opts\n    };\n\n    // Link to our helpers\n    registerHelpers(theme, opts, cssInfo, ctx, this);\n\n    // Generate!\n    return this.generateSimple(ctx, jst);\n  }\n};\n"
  },
  {
    "path": "src/utils/file-contains.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the SyntaxErrorEx class.\n@module file-contains.js\n*/\n\nmodule.exports = ( file, needle ) => require('fs').readFileSync(file,'utf-8').indexOf( needle ) > -1;\n"
  },
  {
    "path": "src/utils/fresh-version-regex.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefines a regex suitable for matching FRESH versions.\n@module file-contains.js\n*/\n\n// Set up a regex that matches all of the following:\n//\n//   - FRESH\n//   - JRS\n//   - FRESCA\n//   - FRESH@1.0.0\n//   - FRESH@1.0\n//   - FRESH@1\n//   - JRS@0.16.0\n//   - JRS@0.16\n//   - JRS@0\n//\n// Don't use a SEMVER regex (eg, NPM's semver-regex) because a) we want to\n// support partial semvers like \"0\" or \"1.2\" and b) we'll expand this later to\n// support fully scoped FRESH versions.\n\nmodule.exports = () => RegExp('^(FRESH|FRESCA|JRS)(?:@(\\\\d+(?:\\\\.\\\\d+)?(?:\\\\.\\\\d+)?))?$');\n"
  },
  {
    "path": "src/utils/html-to-wpml.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the Markdown to WordProcessingML conversion routine.\n@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.\n@module utils/html-to-wpml\n*/\n\n\nconst XML = require('xml-escape');\nconst _ = require('underscore');\nconst HTML5Tokenizer = require('simple-html-tokenizer');\n\nmodule.exports = function( html ) {\n\n  // Tokenize the HTML stream.\n  let is_bold, is_italic, is_link, link_url;\n  const tokens = HTML5Tokenizer.tokenize( html );\n  let final = (is_bold = (is_italic = (is_link = (link_url = ''))));\n\n  // Process <em>, <strong>, and <a> elements in the HTML stream, producing\n  // equivalent WordProcessingML that can be dumped into a <w:p> or other\n  // text container element.\n  _.each(tokens, function( tok ) {\n\n    switch (tok.type) {\n\n      case 'StartTag':\n        switch (tok.tagName) {\n          case 'p': return final += '<w:p>';\n          case 'strong': return is_bold = true;\n          case 'em': return is_italic = true;\n          case 'a':\n            is_link = true;\n            return link_url = tok.attributes.filter(attr => attr[0] === 'href')[0][1];\n        }\n        break;\n\n      case 'EndTag':\n        switch (tok.tagName) {\n          case 'p': return final += '</w:p>';\n          case 'strong': return is_bold = false;\n          case 'em': return is_italic = false;\n          case 'a': return is_link = false;\n        }\n        break;\n\n      case 'Chars':\n        if( tok.chars.trim().length ) {\n          let style = is_bold ? '<w:b/>' : '';\n          style += is_italic ? '<w:i/>' : '';\n          style += is_link ? '<w:rStyle w:val=\"Hyperlink\"/>' : '';\n          return final +=\n            (is_link ? (`<w:hlink w:dest=\"${link_url}\">`) : '') +\n            '<w:r><w:rPr>' + style + '</w:rPr><w:t>' + XML(tok.chars) +\n            '</w:t></w:r>' + (is_link ? '</w:hlink>' : '');\n        }\n        break;\n    }\n  });\n  return final;\n};\n"
  },
  {
    "path": "src/utils/md2chalk.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nInline Markdown-to-Chalk conversion routines.\n@license MIT. See LICENSE.md for details.\n@module utils/md2chalk\n*/\n\n\nconst CHALK = require('chalk');\nconst LO = require('lodash');\n\nmodule.exports = function( v, style, boldStyle ) {\n  boldStyle = boldStyle || 'bold';\n  const temp = v.replace(/\\*\\*(.*?)\\*\\*/g, LO.get( CHALK, boldStyle )('$1'));\n  if (style) { return LO.get( CHALK, style )(temp); } else { return temp; }\n};\n"
  },
  {
    "path": "src/utils/rasterize.js",
    "content": "/* eslint-disable */\n(function() {\n  // Exemplar script for generating documents with Phantom.js.\n  // https://raw.githubusercontent.com/ariya/phantomjs/master/examples/rasterize.js\n  // Converted to CoffeeScript by hacksalot\n  \"use strict\";\n  var address, output, page, pageHeight, pageWidth, size, system;\n\n  page = require('webpage').create();\n\n  system = require('system');\n\n  address = output = size = null;\n\n  if (system.args.length < 3 || system.args.length > 5) {\n    console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');\n    console.log('  paper (pdf output) examples: \"5in*7.5in\", \"10cm*20cm\", \"A4\", \"Letter\"');\n    console.log('  image (png/jpg output) examples: \"1920px\" entire page, window width 1920px');\n    console.log('                                   \"800px*600px\" window, clipped to 800x600');\n    phantom.exit(1);\n  } else {\n    address = system.args[1];\n    output = system.args[2];\n    page.viewportSize = {\n      width: 600,\n      height: 600\n    };\n    if (system.args.length > 3 && system.args[2].substr(-4) === \".pdf\") {\n      size = system.args[3].split('*');\n      page.paperSize = size.length === 2 ? {\n        width: size[0],\n        height: size[1],\n        margin: '0px'\n      } : {\n        format: system.args[3],\n        orientation: 'portrait',\n        margin: '1cm'\n      };\n    } else if (system.args.length > 3 && system.args[3].substr(-2) === \"px\") {\n      size = system.args[3].split('*');\n      if (size.length === 2) {\n        pageWidth = parseInt(size[0], 10);\n        pageHeight = parseInt(size[1], 10);\n        page.viewportSize = {\n          width: pageWidth,\n          height: pageHeight\n        };\n        page.clipRect = {\n          top: 0,\n          left: 0,\n          width: pageWidth,\n          height: pageHeight\n        };\n      } else {\n        console.log(\"size:\", system.args[3]);\n        pageWidth = parseInt(system.args[3], 10);\n        pageHeight = parseInt(pageWidth * 3 / 4, 10); // it's as good an assumption as any\n        console.log(\"pageHeight:\", pageHeight);\n        page.viewportSize = {\n          width: pageWidth,\n          height: pageHeight\n        };\n      }\n    }\n    if (system.args.length > 4) {\n      page.zoomFactor = system.args[4];\n    }\n    page.open(address, function(status) {\n      if (status !== 'success') {\n        console.log('Unable to load the address!');\n        phantom.exit(1);\n      } else {\n        return window.setTimeout(function() {\n          page.render(output);\n          phantom.exit();\n        }, 200);\n      }\n    });\n  }\n\n}).call(this);\n\n/* eslint-enable */\n//# sourceMappingURL=rasterize.js.map\n"
  },
  {
    "path": "src/utils/resume-detector.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the ResumeDetector class.\n@module utils/resume-detector\n@license MIT. See LICENSE.md for details.\n*/\n\nmodule.exports = function( rez ) {\n  if (rez.meta && rez.meta.format) { //&& rez.meta.format.substr(0, 5).toUpperCase() == 'FRESH'\n    return 'fresh';\n  } else if (rez.basics) {\n    return 'jrs';\n  } else {\n    return 'unk';\n  }\n};\n"
  },
  {
    "path": "src/utils/resume-scrubber.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n\nconst _ = require('underscore');\n\nmodule.exports = {\n\n  /**\n  Removes ignored or private fields from a resume object\n  @returns an object with the following structure:\n  {\n    scrubbed: the processed resume object\n    ignoreList: an array of ignored nodes that were removed\n    privateList: an array of private nodes that were removed\n  }\n  */\n  scrubResume(rep, opts) {\n    const traverse = require('traverse');\n    const ignoreList = [];\n    const privateList = [];\n    const includePrivates = opts && opts.private;\n\n    const scrubbed = traverse( rep ).map(function() { // [^1]\n      if (!this.isLeaf) {\n        if ((this.node.ignore === true) || (this.node.ignore === 'true')) {\n          ignoreList.push(this.node);\n          this.delete();\n        } else if (((this.node.private === true) || (this.node.private === 'true')) && !includePrivates) {\n          privateList.push(this.node);\n          this.delete();\n        }\n      }\n      if (_.isArray(this.node)) { // [^2]\n        this.after(function() {\n          this.update(_.compact(this.node));\n        });\n      }\n    });\n\n    return {\n      scrubbed,\n      ingoreList: ignoreList,\n      privateList\n    };\n  }\n};\n\n\n\n// [^1]: As of v0.6.6, the NPM traverse library has a quirk when attempting\n// to remove array elements directly using traverse's `this.remove`. See:\n//\n// https://github.com/substack/js-traverse/issues/48\n//\n// [^2]: The workaround is to use traverse's 'this.delete' to nullify the value\n// first, followed by removal with something like _.compact.\n//\n// https://github.com/substack/js-traverse/issues/48#issuecomment-142607200\n//\n"
  },
  {
    "path": "src/utils/safe-json-loader.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the SafeJsonLoader class.\n@module utils/safe-json-loader\n@license MIT. See LICENSE.md for details.\n*/\n\nconst FS = require('fs');\nconst SyntaxErrorEx = require('./syntax-error-ex');\n\nmodule.exports = function( file ) {\n  const ret = { };\n  try {\n    ret.raw = FS.readFileSync( file, 'utf8' );\n    ret.json = JSON.parse( ret.raw );\n  } catch (err) {\n    // If we get here, either FS.readFileSync or JSON.parse failed.\n    // We'll return HMSTATUS.readError or HMSTATUS.parseError.\n    const retRaw = ret.raw && ret.raw.trim();\n    ret.ex = {\n      op: retRaw ? 'parse' : 'read',\n      inner:\n        SyntaxErrorEx.is( err )\n        ? (new SyntaxErrorEx( err, retRaw ))\n        : err,\n      file\n    };\n  }\n  return ret;\n};\n"
  },
  {
    "path": "src/utils/safe-spawn.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nSafe spawn utility for HackMyResume / FluentCV.\n@module utils/safe-spawn\n@license MIT. See LICENSE.md for details.\n*/\n\n/** Safely spawn a process synchronously or asynchronously without throwing an\nexception */\nmodule.exports = function( cmd, args, isSync, callback, param ) {\n\n  try {\n    // .spawnSync not available on earlier Node.js, so default to .spawn\n    const spawn = require('child_process')[ isSync ? 'spawnSync' : 'spawn'];\n    const info = spawn(cmd, args);\n\n    // Check for error depending on whether we're sync or async TODO: Promises\n    if (!isSync) {\n      info.on('error', function(err) {\n        if (typeof callback === 'function') {\n          callback(err, param);\n        }\n      });\n      return;\n    } else {\n      if (info.error) {\n        if (typeof callback === 'function') {\n          callback(info.error, param);\n        }\n        return {cmd, inner: info.error};\n      }\n    }\n\n  } catch (ex) {\n    if (typeof callback === 'function') {\n      callback(ex, param);\n    }\n    return ex;\n  }\n};\n"
  },
  {
    "path": "src/utils/string-transformer.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nObject string transformation.\n@module utils/string-transformer\n@license MIT. See LICENSE.md for details.\n*/\n\nconst _ = require('underscore');\nconst moment = require('moment');\n\n/**\nCreate a copy of this object in which all string fields have been run through\na transformation function (such as a Markdown filter or XML encoder).\n*/\n\nmodule.exports = function( ret, filt, transformer ) {\n\n  // TODO: refactor recursion\n  var transformStringsInObject = function( obj, filters ) {\n    if (!obj) { return; }\n    if (moment.isMoment(obj)) { return; }\n\n    if (_.isArray( obj )) {\n      return obj.forEach(function(elem, idx, ar) {\n        if ((typeof elem === 'string') || elem instanceof String) {\n          return ar[idx] = transformer( null, elem );\n        } else if (_.isObject(elem)) {\n          return transformStringsInObject( elem, filters );\n        }\n      });\n    } else if (_.isObject( obj )) {\n      return Object.keys( obj ).forEach(function(k) {\n        if (filters.length && _.contains(filters, k)) {\n          return;\n        }\n        const sub = obj[k];\n        if ((typeof sub === 'string') || sub instanceof String) {\n          return obj[k] = transformer( k, sub );\n        } else if (_.isObject( sub )) {\n          return transformStringsInObject( sub, filters );\n        }\n      });\n    }\n  };\n\n  Object.keys( ret ).forEach(function(member) {\n    if (!filt || !filt.length || !_.contains(filt, member)) {\n      return transformStringsInObject( ret[ member ], filt || [] );\n    }\n  });\n  return ret;\n};\n"
  },
  {
    "path": "src/utils/string.js",
    "content": "/**\nDefinitions of string utility functions.\n@module utils/string\n*/\n\n/**\nDetermine if the string is null, empty, or whitespace.\nSee: http://stackoverflow.com/a/32800728/4942583\n@method isNullOrWhitespace\n*/\n\n\nString.isNullOrWhitespace =  input  => !input || !input.trim();\nString.prototype.endsWith = function(suffix) { return this.indexOf(suffix, this.length - suffix.length) !== -1; };\nString.is =  val  => (typeof val === 'string') || val instanceof String;\n"
  },
  {
    "path": "src/utils/syntax-error-ex.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS101: Remove unnecessary use of Array.from\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the SyntaxErrorEx class.\n@module utils/syntax-error-ex\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\n/**\nRepresents a SyntaxError exception with line and column info.\nCollect syntax error information from the provided exception object. The\nJavaScript `SyntaxError` exception isn't interpreted uniformly across environ-\nments, so we reparse on error to grab the line and column.\nSee: http://stackoverflow.com/q/13323356\n@class SyntaxErrorEx\n*/\n\nclass SyntaxErrorEx {\n  constructor( ex, rawData ) {\n    let JSONLint = require('json-lint');\n    const lint = JSONLint(rawData, { comments: false });\n    if (lint.error) { [this.line, this.col] = Array.from([lint.line, lint.character]); }\n    if (!lint.error) {\n      JSONLint = require('jsonlint');\n      try {\n        JSONLint.parse(rawData);\n      } catch (err) {\n        this.line = (/on line (\\d+)/.exec(err))[1];\n      }\n    }\n  }\n}\n\n\n// Return true if the supplied parameter is a JavaScript SyntaxError\nSyntaxErrorEx.is =  ex  => ex instanceof SyntaxError;\n\nmodule.exports = SyntaxErrorEx;\n"
  },
  {
    "path": "src/verbs/analyze.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nImplementation of the 'analyze' verb for HackMyResume.\n@module verbs/analyze\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst HMEVENT       = require('../core/event-codes');\nconst HMSTATUS      = require('../core/status-codes');\nconst _             = require('underscore');\nconst ResumeFactory = require('../core/resume-factory');\nconst Verb          = require('../verbs/verb');\n\n\n\n/** An invokable resume analysis command. */\nclass AnalyzeVerb extends Verb {\n  constructor() { super('analyze', _analyze); }\n}\n\nmodule.exports = AnalyzeVerb;\n\n\n\n/** Private workhorse for the 'analyze' command. */\nvar _analyze = function( sources, dst, opts ) {\n\n  if (!sources || !sources.length) {\n    this.err(HMSTATUS.resumeNotFound, { quit: true });\n    return null;\n  }\n\n  const nlzrs = _loadInspectors();\n  const results = _.map(sources, function(src) {\n    const r = ResumeFactory.loadOne(src, { format: 'FRESH', objectify: true, inner: {\n      private: opts.private === true\n    }\n  }, this);\n    if (opts.assert && this.hasError()) { return { }; }\n\n    if (r.fluenterror) {\n      r.quit = opts.assert;\n      this.err(r.fluenterror, r);\n      return r;\n    } else {\n      return _analyzeOne.call(this, r, nlzrs, opts);\n    }\n  }\n  , this);\n\n\n  if (this.hasError() && !opts.assert) {\n    this.reject(this.errorCode);\n  } else if (!this.hasError()) {\n    this.resolve(results);\n  }\n  return results;\n};\n\n\n\n/** Analyze a single resume. */\nvar _analyzeOne = function( resumeObject, nlzrs ) {\n  const { rez } = resumeObject;\n  const safeFormat =\n    rez.meta && rez.meta.format && rez.meta.format.startsWith('FRESH')\n    ? 'FRESH' : 'JRS';\n\n  this.stat( HMEVENT.beforeAnalyze, { fmt: safeFormat, file: resumeObject.file });\n  const info = _.mapObject(nlzrs, (val) => val.run(rez));\n  this.stat(HMEVENT.afterAnalyze, { info });\n  return info;\n};\n\n\n\nvar _loadInspectors = () =>\n  ({\n    totals: require('../inspectors/totals-inspector'),\n    coverage: require('../inspectors/gap-inspector'),\n    keywords: require('../inspectors/keyword-inspector')\n  })\n;\n"
  },
  {
    "path": "src/verbs/build.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * DS207: Consider shorter variations of null checks\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nImplementation of the 'build' verb for HackMyResume.\n@module verbs/build\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst _              = require('underscore');\nconst PATH           = require('path');\nconst MKDIRP         = require('mkdirp');\nconst extend         = require('extend');\nconst parsePath      = require('parse-filepath');\nconst RConverter     = require('fresh-jrs-converter');\nconst HMSTATUS       = require('../core/status-codes');\nconst HMEVENT        = require('../core/event-codes');\nconst RTYPES         = {\n  FRESH: require('../core/fresh-resume'),\n  JRS: require('../core/jrs-resume')\n};\nconst _opts          = require('../core/default-options');\nconst FRESHTheme     = require('../core/fresh-theme');\nconst JRSTheme       = require('../core/jrs-theme');\nconst ResumeFactory  = require('../core/resume-factory');\nconst _fmts          = require('../core/default-formats');\nconst Verb           = require('../verbs/verb');\n\n//const _err = null;\n//const _log = null;\nlet _rezObj = null;\n//const build = null;\n//const prep = null;\n//const single = null;\n//const verifyOutputs = null;\n//const addFreebieFormats = null;\n//const expand = null;\n//const verifyTheme = null;\n//const loadTheme = null;\n\n/** An invokable resume generation command. */\nclass BuildVerb extends Verb {\n\n  /** Create a new build verb. */\n  constructor() { super('build', _build); }\n}\n\n\nmodule.exports = BuildVerb;\n\n\n\n/**\nGiven a source resume in FRESH or JRS format, a destination resume path, and a\ntheme file, generate 0..N resumes in the desired formats.\n@param src Path to the source JSON resume file: \"rez/resume.json\".\n@param dst An array of paths to the target resume file(s).\n@param opts Generation options.\n*/\nvar _build = function( src, dst, opts ) {\n\n  let err;\n  if (!src || !src.length) {\n    this.err(HMSTATUS.resumeNotFound, {quit: true});\n    return null;\n  }\n\n  _prep.call(this, src, dst, opts);\n\n  // Load input resumes as JSON...\n  const sheetObjects = ResumeFactory.load(src, {\n    format: null, objectify: false, quit: true, inner: {\n      sort: _opts.sort,\n      private: _opts.private\n    }\n  }\n  , this);\n\n  // Explicit check for any resume loading errors...\n  const problemSheets = _.filter(sheetObjects, so => so.fluenterror);\n  if (problemSheets && problemSheets.length) {\n    problemSheets[0].quit = true; // can't go on\n    this.err(problemSheets[0].fluenterror, problemSheets[0]);\n    return null;\n  }\n\n  // Get the collection of raw JSON sheets\n  const sheets = sheetObjects.map(r => r.json);\n\n  // Load the theme...\n  let theme = null;\n  this.stat(HMEVENT.beforeTheme, { theme: _opts.theme });\n  try {\n    const tFolder = _verifyTheme.call(this, _opts.theme);\n    if (tFolder.fluenterror) {\n      tFolder.quit = true;\n      this.err(tFolder.fluenterror, tFolder);\n      return;\n    }\n    theme = (_opts.themeObj = _loadTheme(tFolder));\n    _addFreebieFormats(theme);\n  } catch (error) {\n    err = error;\n    const newEx = {\n      fluenterror: HMSTATUS.themeLoad,\n      inner: err,\n      attempted: _opts.theme,\n      quit: true\n    };\n    this.err(HMSTATUS.themeLoad, newEx);\n    return null;\n  }\n\n  this.stat(HMEVENT.afterTheme, {theme});\n\n  // Check for invalid outputs...\n  const inv = _verifyOutputs.call(this, dst, theme);\n  if (inv && inv.length) {\n    this.err(HMSTATUS.invalidFormat, {data: inv, theme, quit: true});\n    return null;\n  }\n\n  //# Merge input resumes, yielding a single source resume...\n  let rez = null;\n  if (sheets.length > 1) {\n    const isFRESH = !sheets[0].basics;\n    const mixed = _.any(sheets, function(s) { if (isFRESH) { return s.basics; } else { return !s.basics; } });\n    this.stat(HMEVENT.beforeMerge, { f: _.clone(sheetObjects), mixed });\n    if (mixed) {\n      this.err(HMSTATUS.mixedMerge);\n    }\n    rez = _.reduceRight(sheets, ( a, b ) => extend( true, b, a ));\n    this.stat(HMEVENT.afterMerge, { r: rez });\n  } else {\n    rez = sheets[0];\n  }\n\n  // Convert the merged source resume to the theme's format, if necessary..\n  const orgFormat = rez.basics ? 'JRS' : 'FRESH';\n  const toFormat = theme.render ? 'JRS' : 'FRESH';\n  if (toFormat !== orgFormat) {\n    this.stat(HMEVENT.beforeInlineConvert);\n    rez = RConverter[ `to${toFormat}` ]( rez );\n    this.stat(HMEVENT.afterInlineConvert, { file: sheetObjects[0].file, fmt: toFormat });\n  }\n\n  // Announce the theme\n  this.stat(HMEVENT.applyTheme, {r: rez, theme});\n\n  // Load the resume into a FRESHResume or JRSResume object\n  _rezObj = new (RTYPES[ toFormat ])().parseJSON( rez, {private: _opts.private} );\n\n  // Expand output resumes...\n  const targets = _expand(dst, theme);\n\n  // Run the transformation!\n  _.each(targets, function(t) {\n    if (this.hasError() && opts.assert) { return { }; }\n    t.final = _single.call(this, t, theme, targets);\n    if (t.final != null ? t.final.fluenterror : undefined) {\n      t.final.quit = opts.assert;\n      this.err(t.final.fluenterror, t.final);\n    }\n  }\n  , this);\n\n  const results = {\n    sheet: _rezObj,\n    targets,\n    processed: targets\n  };\n\n  if (this.hasError() && !opts.assert) {\n    this.reject(results);\n  } else if (!this.hasError()) {\n    this.resolve(results);\n  }\n\n  return results;\n};\n\n\n\n/**\nPrepare for a BUILD run.\n*/\nvar _prep = function( src, dst, opts ) {\n  // Cherry-pick options //_opts = extend( true, _opts, opts );\n  _opts.theme = (opts.theme && opts.theme.toLowerCase().trim()) || 'modern';\n  _opts.prettify = opts.prettify === true;\n  _opts.private = opts.private === true;\n  _opts.noescape = opts.noescape === true;\n  _opts.css = opts.css;\n  _opts.pdf = opts.pdf;\n  _opts.wrap = opts.wrap || 60;\n  _opts.stitles = opts.sectionTitles;\n  _opts.tips = opts.tips;\n  _opts.errHandler = opts.errHandler;\n  _opts.noTips = opts.noTips;\n  _opts.debug = opts.debug;\n  _opts.sort = opts.sort;\n  _opts.wkhtmltopdf = opts.wkhtmltopdf;\n  const that = this;\n\n  // Set up callbacks for internal generators\n  _opts.onTransform = function(info) {\n    that.stat(HMEVENT.afterTransform, info);\n  };\n  _opts.beforeWrite = function(info) {\n    that.stat(HMEVENT.beforeWrite, info);\n  };\n  _opts.afterWrite = function(info) {\n    that.stat(HMEVENT.afterWrite, info);\n  };\n\n\n  // If two or more files are passed to the GENERATE command and the TO\n  // keyword is omitted, the last file specifies the output file.\n  ( (src.length > 1) && ( !dst || !dst.length ) ) && dst.push( src.pop() );\n};\n\n\n\n/**\nGenerate a single target resume such as \"out/rez.html\" or \"out/rez.doc\".\nTODO: Refactor.\n@param targInfo Information for the target resume.\n@param theme A FRESHTheme or JRSTheme object.\n*/\nvar _single = function( targInfo, theme, finished ) {\n\n  let ret = null;\n  let ex = null;\n  const f = targInfo.file;\n\n  try {\n\n    if (!targInfo.fmt) {\n      return { };\n    }\n    let theFormat = null;\n\n    this.stat(HMEVENT.beforeGenerate, {\n      fmt: targInfo.fmt.outFormat,\n      file: PATH.relative(process.cwd(), f)\n    }\n    );\n\n    _opts.targets = finished;\n\n    // If targInfo.fmt.files exists, this format is backed by a document.\n    // Fluent/FRESH themes are handled here.\n    if (targInfo.fmt.files && targInfo.fmt.files.length) {\n      theFormat = _fmts.filter( fmt => fmt.name === targInfo.fmt.outFormat)[0];\n      MKDIRP.sync(PATH.dirname( f ));\n      ret = theFormat.gen.generate(_rezObj, f, _opts);\n\n    // Otherwise this is an ad-hoc format (JSON, YML, or PNG) that every theme\n    // gets \"for free\".\n    } else {\n      theFormat = _fmts.filter( fmt => fmt.name === targInfo.fmt.outFormat)[0];\n      const outFolder = PATH.dirname(f);\n      MKDIRP.sync(outFolder); // Ensure dest folder exists;\n      ret = theFormat.gen.generate(_rezObj, f, _opts);\n    }\n\n  } catch (e) {\n    ex = e;\n  }\n\n  this.stat(HMEVENT.afterGenerate, {\n    fmt: targInfo.fmt.outFormat,\n    file: PATH.relative(process.cwd(), f),\n    error: ex\n  }\n  );\n\n  if (ex) {\n    if (ex.fluenterror) {\n      ret = ex;\n    } else {\n      ret = {fluenterror: HMSTATUS.generateError, inner: ex};\n    }\n  }\n  return ret;\n};\n\n\n\n/** Ensure that user-specified outputs/targets are valid. */\nvar _verifyOutputs = function( targets, theme ) {\n  this.stat(HMEVENT.verifyOutputs, {targets, theme});\n  return _.reject(targets.map( function( t ) {\n    const pathInfo = parsePath(t);\n    return {format: pathInfo.extname.substr(1)}; }),\n    t => (t.format === 'all') || theme.hasFormat( t.format ));\n};\n\n\n\n/**\nReinforce the chosen theme with \"freebie\" formats provided by HackMyResume.\nA \"freebie\" format is an output format such as JSON, YML, or PNG that can be\ngenerated directly from the resume model or from one of the theme's declared\noutput formats. For example, the PNG format can be generated for any theme\nthat declares an HTML format; the theme doesn't have to provide an explicit\nPNG template.\n@param theTheme A FRESHTheme or JRSTheme object.\n*/\nvar _addFreebieFormats = function( theTheme ) {\n  // Add freebie formats (JSON, YAML, PNG) every theme gets...\n  // Add HTML-driven PNG only if the theme has an HTML format.\n  theTheme.formats.json = theTheme.formats.json || {\n    freebie: true, title: 'json', outFormat: 'json', pre: 'json',\n    ext: 'json', path: null, data: null\n  };\n  theTheme.formats.yml = theTheme.formats.yml || {\n    freebie: true, title: 'yaml', outFormat: 'yml', pre: 'yml',\n    ext: 'yml', path: null, data: null\n  };\n  if (theTheme.formats.html && !theTheme.formats.png) {\n    theTheme.formats.png = {\n      freebie: true, title: 'png', outFormat: 'png',\n      ext: 'yml', path: null, data: null\n    };\n  }\n};\n\n\n\n/**\nExpand output files. For example, \"foo.all\" should be expanded to\n[\"foo.html\", \"foo.doc\", \"foo.pdf\", \"etc\"].\n@param dst An array of output files as specified by the user.\n@param theTheme A FRESHTheme or JRSTheme object.\n*/\nvar _expand = function( dst, theTheme ) {\n\n  // Set up the destination collection. It's either the array of files passed\n  // by the user or 'out/resume.all' if no targets were specified.\n  const destColl = (dst && dst.length && dst) || [PATH.normalize('out/resume.all')];\n\n  // Assemble an array of expanded target files... (can't use map() here)\n  const targets = [];\n  destColl.forEach(function(t) {\n    const to = PATH.resolve(t);\n    const pa = parsePath(to);\n    const fmat = pa.extname || '.all';\n    return targets.push.apply( targets,\n      fmat === '.all'\n      ? Object.keys( theTheme.formats ).map( function( k ) {\n        const z = theTheme.formats[k];\n        return { file: to.replace( /all$/g, z.outFormat ), fmt: z };\n      })\n      : [{ file: to, fmt: theTheme.getFormat( fmat.slice(1) ) }]\n    );\n  });\n  return targets;\n};\n\n\n\n/**\nVerify the specified theme name/path.\n*/\nvar _verifyTheme = function( themeNameOrPath ) {\n\n  // First, see if this is one of the predefined FRESH themes. There are only a\n  // handful of these, but they may change over time, so we need to query\n  // the official source of truth: the fresh-themes repository, which mounts the\n  // themes conveniently by name to the module object, and which is embedded\n  // locally inside the HackMyResume installation.\n  let tFolder;\n  const themesObj = require('fresh-themes');\n  if (_.has(themesObj.themes, themeNameOrPath)) {\n    tFolder = PATH.join(\n      parsePath( require.resolve('fresh-themes') ).dirname,\n      '/themes/',\n      themeNameOrPath\n    );\n  } else {\n  // Otherwsie it's a path to an arbitrary FRESH or JRS theme sitting somewhere\n  // on the user's system (or, in the future, at a URI).\n    tFolder = PATH.resolve(themeNameOrPath);\n  }\n\n  // In either case, make sure the theme folder exists\n  const exists = require('path-exists').sync;\n  if (exists(tFolder)) {\n    return tFolder;\n  } else {\n    return {fluenterror: HMSTATUS.themeNotFound, data: _opts.theme};\n  }\n};\n\n\n\n/**\nLoad the specified theme, which could be either a FRESH theme or a JSON Resume\ntheme (or both).\n*/\nvar _loadTheme = function( tFolder ) {\n\n  const themeJsonPath = PATH.join(tFolder, 'theme.json'); // [^1]\n  const exists = require('path-exists').sync;\n\n  // Create a FRESH or JRS theme object\n  const theTheme =\n    exists(themeJsonPath)\n    ? new FRESHTheme().open(tFolder)\n    : new JRSTheme().open(tFolder);\n\n  // Cache the theme object\n  _opts.themeObj = theTheme;\n  return theTheme;\n};\n\n\n// FOOTNOTES\n// ------------------------------------------------------------------------------\n// [^1] We don't know ahead of time whether this is a FRESH or JRS theme.\n//      However, all FRESH themes have a theme.json file, so we'll use that as a\n//      canary for now, as an interim solution.\n//\n//      Unfortunately, with the exception of FRESH's theme.json, both FRESH and\n//      JRS themes are free-form and don't have a ton of reliable distinguishing\n//      marks, which makes a simple task like ad hoc theme detection harder than\n//      it should be to do cleanly.\n//\n//      Another complicating factor is that it's possible for a theme to be BOTH.\n//      That is, a single set of theme files can serve as a FRESH theme -and- a\n//      JRS theme.\n//\n//      TODO: The most robust way to deal with all these issues is with a strong\n//      theme validator. If a theme structure validates as a particular theme\n//      type, then for all intents and purposes, it IS a theme of that type.\n"
  },
  {
    "path": "src/verbs/convert.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nImplementation of the 'convert' verb for HackMyResume.\n@module verbs/convert\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst ResumeFactory = require('../core/resume-factory');\nconst Verb = require('../verbs/verb');\nconst HMSTATUS = require('../core/status-codes');\nconst _ = require('underscore');\nconst HMEVENT = require('../core/event-codes');\n\n\n\nclass ConvertVerb extends Verb {\n  constructor() { super('convert', _convert); }\n}\n\nmodule.exports = ConvertVerb;\n\n\n\n/** Private workhorse method. Convert 0..N resumes between FRESH and JRS\nformats. */\n\nvar _convert = function( srcs, dst, opts ) {\n\n  // If no source resumes are specified, error out\n  let fmtUp;\n  if (!srcs || !srcs.length) {\n    this.err(HMSTATUS.resumeNotFound, { quit: true });\n    return null;\n  }\n\n  // If no destination resumes are specified, error out except for the special\n  // case of two resumes:\n  //   hackmyresume CONVERT r1.json r2.json\n  if (!dst || !dst.length) {\n    if (srcs.length === 1) {\n      this.err(HMSTATUS.inputOutputParity, { quit: true });\n    } else if (srcs.length === 2) {\n      dst = dst || []; dst.push( srcs.pop() );\n    } else {\n      this.err(HMSTATUS.inputOutputParity, { quit: true });\n    }\n  }\n\n  // Different number of source and dest resumes? Error out.\n  if (srcs && dst && srcs.length && dst.length && (srcs.length !== dst.length)) {\n    this.err(HMSTATUS.inputOutputParity, { quit: true });\n  }\n\n  // Validate the destination format (if specified)\n  //const targetVer = null;\n  if (opts.format) {\n    fmtUp = opts.format.trim().toUpperCase();\n    if (!_.contains(['FRESH','FRESCA','JRS','JRS@1','JRS@edge'], fmtUp)) {\n      this.err(HMSTATUS.invalidSchemaVersion, {data: opts.format.trim(), quit: true});\n    }\n  }\n    // freshVerRegex = require '../utils/fresh-version-regex'\n    // matches = fmtUp.match freshVerRegex()\n    // # null\n    // # [ 'JRS@1.0', 'JRS', '1.0', index: 0, input: 'FRESH' ]\n    // # [ 'FRESH', 'FRESH', undefined, index: 0, input: 'FRESH' ]\n    // if not matches\n    //   @err HMSTATUS.invalidSchemaVersion, data: opts.format.trim(), quit: true\n    // targetSchema = matches[1]\n    // targetVer = matches[2] || '1'\n\n  // If any errors have occurred this early, we're done.\n  if (this.hasError()) {\n    this.reject(this.errorCode);\n    return null;\n  }\n\n  // Map each source resume to the converted destination resume\n  const results = _.map(srcs, function( src, idx ) {\n\n    // Convert each resume in turn\n    const r = _convertOne.call(this, src, dst, idx, fmtUp);\n\n    // Handle conversion errors\n    if (r.fluenterror) {\n      r.quit = opts.assert;\n      this.err(r.fluenterror, r);\n    }\n    return r;\n  }\n  , this);\n\n\n  if (this.hasError() && !opts.assert) {\n    this.reject(results);\n  } else if (!this.hasError()) {\n    this.resolve(results);\n  }\n  return results;\n};\n\n\n\n/** Private workhorse method. Convert a single resume. */\nvar _convertOne = function(src, dst, idx, targetSchema) {\n\n  // Load the resume\n  const rinfo = ResumeFactory.loadOne(src, {\n    format: null,\n    objectify: true,\n    inner: {\n      privatize: false\n    }\n  }\n  );\n\n  // If a load error occurs, report it and move on to the next file (if any)\n  if (rinfo.fluenterror) {\n    this.stat(HMEVENT.beforeConvert, {\n      srcFile: src, //rinfo.file\n      srcFmt: '???',\n      dstFile: dst[idx],\n      dstFmt: '???',\n      error: true\n    }\n    );\n    //@err rinfo.fluenterror, rinfo\n    return rinfo;\n  }\n\n  // Determine the resume's SOURCE format\n  // TODO: replace with detector component\n  const { rez } = rinfo;\n  let srcFmt = '';\n  if (rez.meta && rez.meta.format) { //&& rez.meta.format.substr(0, 5).toUpperCase() == 'FRESH'\n    srcFmt = 'FRESH';\n  } else if (rez.basics) {\n    srcFmt = 'JRS';\n  } else {\n    rinfo.fluenterror = HMSTATUS.unknownSchema;\n    return rinfo;\n  }\n\n  // Determine the TARGET format for the conversion\n  const targetFormat = targetSchema || (srcFmt === 'JRS' ? 'FRESH' : 'JRS');\n\n  // Fire the beforeConvert event\n  this.stat(HMEVENT.beforeConvert, {\n    srcFile: rinfo.file,\n    srcFmt,\n    dstFile: dst[idx],\n    dstFmt: targetFormat\n  }\n  );\n\n  // Save it to the destination format\n  try {\n    rez.saveAs(dst[idx], targetFormat);\n  } catch (err) {\n    if (err.badVer) {\n      return {fluenterror: HMSTATUS.invalidSchemaVersion, quit: true, data: err.badVer};\n    }\n  }\n  return rez;\n};\n"
  },
  {
    "path": "src/verbs/create.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nImplementation of the 'create' verb for HackMyResume.\n@module verbs/create\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst MKDIRP = require('mkdirp');\nconst PATH = require('path');\nconst Verb = require('../verbs/verb');\nconst _ = require('underscore');\nconst HMSTATUS = require('../core/status-codes');\nconst HMEVENT = require('../core/event-codes');\n\n\n\nclass CreateVerb extends Verb {\n\n  constructor() { super('new', _create); }\n}\n\n\nmodule.exports = CreateVerb;\n\n\n\n/** Create a new empty resume in either FRESH or JRS format. */\nvar _create = function( src, dst, opts ) {\n\n  if (!src || !src.length) {\n    this.err(HMSTATUS.createNameMissing, { quit: true });\n    return null;\n  }\n\n  const results = _.map(src, function( t ) {\n    if (opts.assert && this.hasError()) { return { }; }\n    const r = _createOne.call(this, t, opts);\n    if (r.fluenterror) {\n      r.quit = opts.assert;\n      this.err(r.fluenterror, r);\n    }\n    return r;\n  }\n  , this);\n\n  if (this.hasError() && !opts.assert) {\n    this.reject(this.errorCode);\n  } else if (!this.hasError()) {\n    this.resolve(results);\n  }\n  return results;\n};\n\n\n\n/** Create a single new resume */\nvar _createOne = function( t, opts ) {\n  let ret, safeFmt;\n  try {\n    ret = null;\n    safeFmt = opts.format.toUpperCase();\n    this.stat(HMEVENT.beforeCreate, { fmt: safeFmt, file: t });\n    MKDIRP.sync(PATH.dirname( t )); // Ensure dest folder exists;\n    const RezClass = require(`../core/${safeFmt.toLowerCase()}-resume`);\n    const newRez = RezClass.default();\n    newRez.save(t);\n    ret = newRez;\n  } catch (err) {\n    ret = {\n      fluenterror: HMSTATUS.createError,\n      inner: err\n    };\n  }\n  finally {\n    this.stat(HMEVENT.afterCreate, { fmt: safeFmt, file: t, isError: ret.fluenterror });\n  }\n  return ret;\n};\n"
  },
  {
    "path": "src/verbs/peek.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nImplementation of the 'peek' verb for HackMyResume.\n@module verbs/peek\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst Verb = require('../verbs/verb');\nconst _ = require('underscore');\nconst __ = require('lodash');\nconst safeLoadJSON = require('../utils/safe-json-loader');\nconst HMSTATUS = require('../core/status-codes');\nconst HMEVENT = require('../core/event-codes');\n\n\n\nclass PeekVerb extends Verb {\n\n  constructor() { super('peek', _peek); }\n\n}\n\n\nmodule.exports = PeekVerb;\n\n/** Peek at a resume, resume section, or resume field. */\nvar _peek = function( src, dst, opts ) {\n\n  if (!src || !src.length) {\n    this.err(HMSTATUS.resumeNotFound, { quit: true });\n    return null;\n  }\n\n  const objPath = (dst && dst[0]) || '';\n\n  const results = _.map(src, function( t ) {\n\n    if (opts.assert && this.hasError()) { return { }; }\n\n    const tgt = _peekOne.call(this, t, objPath);\n    if (tgt.error) {\n      this.setError(tgt.error.fluenterror, tgt.error);\n    }\n      //tgt.error.quit = opts.assert\n      //@err tgt.error.fluenterror, tgt.error\n    return tgt;\n  }\n  , this);\n\n  if (this.hasError() && !opts.assert) {\n    this.reject(this.errorCode);\n  } else if (!this.hasError()) {\n    this.resolve(results);\n  }\n  return results;\n};\n\n\n\n/** Peek at a single resume, resume section, or resume field. */\nvar _peekOne = function( t, objPath ) {\n\n  this.stat(HMEVENT.beforePeek, { file: t, target: objPath });\n\n  // Load the input file JSON 1st\n  const obj = safeLoadJSON(t);\n\n  // Fetch the requested object path (or the entire file)\n  let tgt = null;\n  if (!obj.ex) {\n    tgt = objPath ? __.get(obj.json, objPath) : obj.json;\n  }\n\n  //# safeLoadJSON can only return a READ error or a PARSE error\n  let pkgError = null;\n  if (obj.ex) {\n    const errCode = obj.ex.op === 'parse' ? HMSTATUS.parseError : HMSTATUS.readError;\n    if (errCode === HMSTATUS.readError) {\n      obj.ex.quiet = true;\n    }\n    pkgError = {fluenterror: errCode, inner: obj.ex};\n  }\n\n  // Fire the 'afterPeek' event with collected info\n  this.stat(HMEVENT.afterPeek, {\n    file: t,\n    requested: objPath,\n    target: obj.ex ? undefined : tgt,\n    error: pkgError\n  }\n  );\n\n  return {\n    val: obj.ex ? undefined : tgt,\n    error: pkgError\n  };\n};\n"
  },
  {
    "path": "src/verbs/validate.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nImplementation of the 'validate' verb for HackMyResume.\n@module verbs/validate\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst Verb = require('../verbs/verb');\nconst HMSTATUS = require('../core/status-codes');\nconst HMEVENT = require('../core/event-codes');\nconst _ = require('underscore');\nconst safeLoadJSON = require('../utils/safe-json-loader');\n\n\n\n/** An invokable resume validation command. */\nclass ValidateVerb extends Verb {\n  constructor() { super('validate', _validate); }\n}\n\n\n\n// Validate 1 to N resumes in FRESH or JSON Resume format.\nvar _validate = function(sources, unused, opts)  {\n\n  if (!sources || !sources.length) {\n    this.err(HMSTATUS.resumeNotFoundAlt, {quit: true});\n    return null;\n  }\n\n  const validator = require('is-my-json-valid');\n  const schemas = {\n    fresh: require('fresh-resume-schema'),\n    jars: require('../core/resume.json')\n  };\n\n  const results = _.map(sources, function(t)  {\n    const r = _validateOne.call(this, t, validator, schemas, opts);\n    if (r.error) { this.err(r.error.fluenterror, r.error); }\n    return r;\n  }\n  , this);\n\n  if (this.hasError() && !opts.assert) {\n    this.reject(this.errorCode);\n  } else if (!this.hasError()) {\n    this.resolve(results);\n  }\n  return results;\n};\n\nmodule.exports = ValidateVerb;\n\n/**\nValidate a single resume.\n@returns {\n  file: <fileName>,\n  isValid: <validFlag>,\n  status: <validationStatus>,\n  violations: <validationErrors>,\n  schema: <schemaType>,\n  error: <errorObject>\n}\n*/\nvar _validateOne = function(t, validator, schemas) {\n\n  const ret = {file: t, isValid: false, status: 'unknown', schema: '-----'};\n\n  try {\n\n    // Read and parse the resume JSON. Won't throw.\n    const obj = safeLoadJSON(t);\n\n    // If success, validate the resume against the schema\n    if (!obj.ex) {\n      if (obj.json.basics) { ret.schema = 'jars'; } else { ret.schema = 'fresh'; }\n      const validate = validator(schemas[ ret.schema ], // Note [1]\n        {formats: { date: /^\\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/ }});\n      ret.isValid = validate(obj.json);\n      ret.status = ret.isValid ? 'valid' : 'invalid';\n      if (!ret.isValid) { ret.violations = validate.errors; }\n\n    // If failure, package JSON read/parse errors\n    } else {\n      let errCode;\n      if (obj.ex.op === 'parse') {\n        errCode = HMSTATUS.parseError;\n        ret.status = 'broken';\n      } else {\n        errCode = HMSTATUS.readError;\n        ret.status = 'missing';\n      }\n      ret.error = {\n        fluenterror: errCode,\n        inner: obj.ex.inner,\n        quiet: errCode === HMSTATUS.readError\n      };\n    }\n\n  } catch (err) {\n    // Package any unexpected exceptions\n    ret.error = {fluenterror: HMSTATUS.validateError, inner: err};\n  }\n\n  this.stat(HMEVENT.afterValidate, ret);\n  return ret;\n};\n"
  },
  {
    "path": "src/verbs/verb.js",
    "content": "/*\n * decaffeinate suggestions:\n * DS102: Remove unnecessary code created because of implicit returns\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md\n */\n/**\nDefinition of the Verb class.\n@module verbs/verb\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nconst EVENTS = require('events');\nconst HMEVENT = require('../core/event-codes');\nconst Promise = require('pinkie-promise');\n\n\n\n/**\nAn abstract invokable verb.\nProvides base class functionality for verbs. Provide common services such as\nerror handling, event management, and promise support.\n@class Verb\n*/\n\nclass Verb {\n\n\n\n  /** Constructor. Automatically called at creation. */\n  constructor( moniker, workhorse ) {\n    this.moniker = moniker;\n    this.workhorse = workhorse;\n    this.emitter = new EVENTS.EventEmitter();\n  }\n\n\n\n  /** Invoke the command. */\n  invoke() {\n\n    // Sent the 'begin' notification for this verb\n    this.stat(HMEVENT.begin, {cmd: this.moniker});\n\n    // Prepare command arguments\n    const argsArray = Array.prototype.slice.call(arguments);\n\n    // Create a promise for this verb instance\n    const that = this;\n    return this.promise = new Promise(function(res, rej) {\n      that.resolve = res;\n      that.reject = rej;\n      that.workhorse.apply(that, argsArray);\n    });\n  }\n\n\n\n  /** Forward subscriptions to the event emitter. */\n  on() { return this.emitter.on.apply(this.emitter, arguments); }\n\n\n\n  /** Fire an arbitrary event, scoped to \"hmr:\". */\n  fire(evtName, payload) {\n    payload = payload || { };\n    payload.cmd = this.moniker;\n    this.emitter.emit(`hmr:${evtName}`, payload);\n    return true;\n  }\n\n\n\n  /** Handle an error condition. */\n  err( errorCode, payload, hot ) {\n    payload = payload || { };\n    payload.sub = (payload.fluenterror = errorCode);\n    payload.throw = hot;\n    this.setError(errorCode, payload);\n    if (payload.quit) {\n      this.reject(errorCode);\n    }\n    this.fire('error', payload);\n    if (hot) {\n      throw payload;\n    }\n    return true;\n  }\n\n\n\n  /** Fire the 'hmr:status' error event. */\n  stat( subEvent, payload ) {\n    payload = payload || { };\n    payload.sub = subEvent;\n    this.fire('status', payload);\n    return true;\n  }\n\n\n\n  /** Has an error occurred during this verb invocation? */\n  hasError() { return this.errorCode || this.errorObj; }\n\n\n\n  /** Associate error info with the invocation. */\n  setError( code, obj ) {\n    this.errorCode = code;\n    this.errorObj = obj;\n  }\n}\n\nmodule.exports = Verb;\n"
  },
  {
    "path": "test/.gitignore",
    "content": "sandbox/\n"
  },
  {
    "path": "test/all.js",
    "content": "\nvar MKDIRP = require('mkdirp');\nvar PATH = require('path');\nMKDIRP( PATH.join( __dirname, '/sandbox' ) );\n\nrequire('./scripts/test-cli');\nrequire('./scripts/test-fresh-sheet');\nrequire('./scripts/test-jrs-sheet');\nrequire('./scripts/test-themes');\nrequire('./scripts/test-verbs');\nrequire('./scripts/test-output');\nrequire('./scripts/test-dates');\n"
  },
  {
    "path": "test/expected/modern/modern-html.css",
    "content": "\n* {\n  box-sizing: border-box;\n}\n\nmain {\n  display: block;\n}\n\nbody {\n  font-family: 'Helvetica Neue', 'Helvetica', 'Segoe UI', 'Calibri', 'sans-serif';\n  font-size: 15px;\n  color: #333;\n  line-height: 1.42857143;\n  background-color: #F0F0F0;\n  margin: 0;\n  padding: 0;\n}\n\n/* Typical page borders are awkward when rendered to PDF. */\nbody.pdf {\n  background-color: #FFFFFF;\n}\n\n/* Adobe or wkhtmltopdf has issues with the <main> tag, so we use <div> for\nthe PDF case, <main> for the HTML case, and style both via an ID. */\n#main {\n  background-color: #FFF;\n  margin: 10px;\n  padding: 10px;\n  border: 1px solid #E6E6E6;\n}\n\nbody.pdf > #main {\n  border: none;\n}\n\n#container > header {\n  padding-top: 6em;\n  padding-bottom: 1em;\n}\n\nbody.pdf #container > header {\n  padding: 0;\n}\n\n#main > #container > section {\n  margin-left: 5em;\n  position: relative;\n  display: block;\n}\n\nspan.fa\n{\n  position: absolute;\n  top: 4px;\n  left: -50px;\n  font-size: 30px;\n  color: #BFC1C3;\n}\n\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #EEE;\n}\n\n.tenure, .keywords {\n  font-size: 75%;\n}\n\nh1 {\n  margin: 0;\n  font-size: 46px;\n}\n\nh2 {\n  font-size: 24px;\n  color: #BFC1C3;\n  text-transform: uppercase;\n  font-weight: normal;\n}\n\nh3 {\n  margin-bottom: 0;\n  font-size: 18px;\n}\n\na, a:visited {\n  color: #428BCA;\n  text-decoration: none;\n  font-weight: bold;\n}\n\na:hover {\n  text-decoration: underline;\n}\n\n.defunct {\n  color: #989898;\n  font-weight: bold;\n}\n\n#summary > p > strong {\n  font-size: 1.25em;\n}\n\n\n.label-keyword {\n  display: inline-block;\n  background: #7eb0db;\n  color: white;\n  font-size: 0.9em;\n  padding: 5px;\n  border: 1px solid #357ebd;\n  border-radius: 5px;\n  margin-top: 2px;\n}\n\n.card-skills {\n    position: relative;\n}\n.card-nested {\n    min-height: 0;\n    margin-bottom: 10px;\n    border-width: 1px 0 0 0;\n}\n.card {\n    background: #FFF;\n    border-radius: 3px;\n    padding: 10px;\n}\n\n.skill-level {\n  border-radius: 3px;\n  position: absolute;\n  top: 10px;\n  bottom: 10px;\n  left: 0;\n  width: 10px;\n  box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);\n}\n.skill-level .skill-progress {\n  position: absolute;\n  border-radius: 3px;\n  bottom: 0;\n  width: 100%;\n  -webkit-transition: height 1s ease;\n}\n.skill-level .skill-progress.beginner {\n  height: 50%;\n  background: #e74c3c;\n}\n.skill-level .skill-progress.intermediate {\n  height: 70%;\n  background: #f1c40f;\n}\n.skill-level .skill-progress.advanced {\n  height: 80%;\n  background: #428bca;\n}\n.skill-level .skill-progress.master {\n  height: 95%;\n  background: #5cb85c;\n}\n.skill-info {\n  margin-left: 10px;\n}\n@media (max-width: 480px) {\n  .skill-info {\n    margin-left: 20px;\n  }\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.card-skills {\n  position: relative;\n}\n\n.space-top {\n    margin-top: 10px;\n}\n\n#container {\n  max-width: 800px;\n  margin: 0 auto;\n}\n\n#elevator-pitch {\n  text-align: center;\n  font-size: 24px;\n  color: #BFC1C3;\n  text-transform: uppercase;\n  font-weight: normal;\n}\n\n.res-label {\n  font-style: italic;\n}\n"
  },
  {
    "path": "test/expected/modern/modern-pdf.css",
    "content": "* {\n  box-sizing: border-box;\n}\n\nmain {\n  display: block;\n}\n\nbody {\n  font-family: 'Helvetica Neue', 'Helvetica', 'Segoe UI', 'Calibri', 'sans-serif';\n  font-size: 15px;\n  color: #333;\n  line-height: 1.42857143;\n  background-color: #F0F0F0;\n  margin: 0;\n  padding: 0;\n}\n\n/* Typical page borders are awkward when rendered to PDF. */\nbody {\n  background-color: #FFFFFF;\n}\n\n/* Adobe or wkhtmltopdf has issues with the <main> tag, so we use <div> for\nthe PDF case, <main> for the HTML case, and style both via an ID. */\n#main {\n  background-color: #FFF;\n  margin: 10px;\n  padding: 10px;\n  border: 1px solid #E6E6E6;\n}\n\nbody > #main {\n  border: none;\n}\n\n#container > header {\n  padding-top: 6em;\n  padding-bottom: 1em;\n}\n\nbody.pdf #container > header {\n  padding: 0;\n}\n\n#main > #container > section {\n  margin-left: 5em;\n  position: relative;\n  display: block;\n}\n\nspan.fa\n{\n  position: absolute;\n  top: 4px;\n  left: -50px;\n  font-size: 30px;\n  color: #BFC1C3;\n}\n\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #EEE;\n}\n\n.tenure, .keywords {\n  font-size: 75%;\n}\n\nh1 {\n  margin: 0;\n  font-size: 46px;\n}\n\nh2 {\n  font-size: 24px;\n  color: #BFC1C3;\n  text-transform: uppercase;\n  font-weight: normal;\n}\n\nh3 {\n  margin-bottom: 0;\n  font-size: 18px;\n}\n\na, a:visited {\n  color: #428BCA;\n  text-decoration: none;\n  font-weight: bold;\n}\n\na:hover {\n  text-decoration: underline;\n}\n\n.defunct {\n  color: #989898;\n  font-weight: bold;\n}\n\n#summary > p > strong {\n  font-size: 1.25em;\n}\n\n\n.label-keyword {\n  display: inline-block;\n  background: #7eb0db;\n  color: white;\n  font-size: 0.9em;\n  padding: 5px;\n  border: 1px solid #357ebd;\n  border-radius: 5px;\n  margin-top: 2px;\n}\n\n.card-skills {\n    position: relative;\n}\n.card-nested {\n    min-height: 0;\n    margin-bottom: 10px;\n    border-width: 1px 0 0 0;\n}\n.card {\n    background: #FFF;\n    border-radius: 3px;\n    padding: 10px;\n}\n\n.skill-level {\n  border-radius: 3px;\n  position: absolute;\n  top: 10px;\n  bottom: 10px;\n  left: 0;\n  width: 10px;\n  box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);\n}\n.skill-level .skill-progress {\n  position: absolute;\n  border-radius: 3px;\n  bottom: 0;\n  width: 100%;\n  -webkit-transition: height 1s ease;\n}\n.skill-level .skill-progress.beginner {\n  height: 50%;\n  background: #e74c3c;\n}\n.skill-level .skill-progress.intermediate {\n  height: 70%;\n  background: #f1c40f;\n}\n.skill-level .skill-progress.advanced {\n  height: 80%;\n  background: #428bca;\n}\n.skill-level .skill-progress.master {\n  height: 95%;\n  background: #5cb85c;\n}\n.skill-info {\n  margin-left: 10px;\n}\n@media (max-width: 480px) {\n  .skill-info {\n    margin-left: 20px;\n  }\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.card-skills {\n  position: relative;\n}\n\n.space-top {\n    margin-top: 10px;\n}\n\n#container {\n  max-width: 800px;\n  margin: 0 auto;\n}\n\n#elevator-pitch {\n  text-align: center;\n  font-size: 24px;\n  color: #BFC1C3;\n  text-transform: uppercase;\n  font-weight: normal;\n}\n\n.res-label {\n  font-style: italic;\n}\n"
  },
  {
    "path": "test/expected/modern/resume.doc",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?mso-application progid=\"Word.Document\"?>\n<w:wordDocument xmlns:aml=\"http://schemas.microsoft.com/aml/2001/core\" xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:dt=\"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.microsoft.com/office/word/2003/wordml\" xmlns:wx=\"http://schemas.microsoft.com/office/word/2003/auxHint\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wsp=\"http://schemas.microsoft.com/office/word/2003/wordml/sp2\" xmlns:sl=\"http://schemas.microsoft.com/schemaLibrary/2003/core\" w:macrosPresent=\"no\" w:embeddedObjPresent=\"no\" w:ocxPresent=\"no\" xml:space=\"preserve\">\n  <w:ignoreSubtree w:val=\"http://schemas.microsoft.com/office/word/2003/wordml/sp2\"/>\n\n\n  <o:DocumentProperties>\n    <o:Title>Resume for Jane Q. Fullstacker</o:Title>\n    <o:Author>Jane Q. Fullstacker</o:Author>\n    <o:Keywords>resume;CV</o:Keywords>\n    <o:LastAuthor>Jane Q. Fullstacker</o:LastAuthor>\n    <o:Revision>1</o:Revision>\n    <o:TotalTime>60</o:TotalTime>\n    <o:Created>2015-12-16T17:38:00Z</o:Created>\n    <o:LastSaved>2015-12-16T18:32:00Z</o:LastSaved>\n    <o:Pages>1</o:Pages>\n    <o:Words>241</o:Words>\n    <o:Characters>1379</o:Characters>\n    <o:Lines>11</o:Lines>\n    <o:Paragraphs>3</o:Paragraphs>\n    <o:CharactersWithSpaces>1617</o:CharactersWithSpaces>\n    <o:Version>15</o:Version>\n  </o:DocumentProperties>\n  \n  <w:fonts>\n    <w:defaultFonts w:ascii=\"Calibri\" w:fareast=\"Calibri\" w:h-ansi=\"Calibri\" w:cs=\"Calibri\"/>\n  \n  \n    <w:font w:name=\"Calibri\">\n      <w:panose-1 w:val=\"02020603050405020304\"/>\n      <w:charset w:val=\"00\"/>\n      <w:family w:val=\"Roman\"/>\n      <w:pitch w:val=\"variable\"/>\n      <w:sig w:usb-0=\"E0002AFF\" w:usb-1=\"C0007841\" w:usb-2=\"00000009\" w:usb-3=\"00000000\" w:csb-0=\"000001FF\" w:csb-1=\"00000000\"/>\n    </w:font>\n  \n  \n    <w:font w:name=\"Calibri\">\n      <w:panose-1 w:val=\"020F0502020204030204\"/>\n      <w:charset w:val=\"00\"/>\n      <w:family w:val=\"Swiss\"/>\n      <w:pitch w:val=\"variable\"/>\n      <w:sig w:usb-0=\"A00002EF\" w:usb-1=\"4000207B\" w:usb-2=\"00000000\" w:usb-3=\"00000000\" w:csb-0=\"0000009F\" w:csb-1=\"00000000\"/>\n    </w:font>\n  \n  </w:fonts>\n  <w:lists>\n    <w:listDef w:listDefId=\"1\">\n      <w:lsid w:val=\"602C53DD\"/>\n      <w:plt w:val=\"HybridMultilevel\"/>\n      <w:tmpl w:val=\"61849B8C\"/>\n      <w:lvl w:ilvl=\"0\" w:tplc=\"DD7ED086\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"•\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"720\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"1\" w:tplc=\"04090003\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"o\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"1440\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Courier New\" w:h-ansi=\"Courier New\" w:cs=\"Courier New\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"2\" w:tplc=\"04090005\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"2160\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Marlett\" w:h-ansi=\"Marlett\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"3\" w:tplc=\"04090001\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"2880\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Symbol\" w:h-ansi=\"Symbol\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"4\" w:tplc=\"04090003\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"o\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"3600\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Courier New\" w:h-ansi=\"Courier New\" w:cs=\"Courier New\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"5\" w:tplc=\"04090005\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"4320\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Marlett\" w:h-ansi=\"Marlett\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"6\" w:tplc=\"04090001\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"5040\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Symbol\" w:h-ansi=\"Symbol\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"7\" w:tplc=\"04090003\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"o\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"5760\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Courier New\" w:h-ansi=\"Courier New\" w:cs=\"Courier New\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n      <w:lvl w:ilvl=\"8\" w:tplc=\"04090005\" w:tentative=\"on\">\n        <w:start w:val=\"1\"/>\n        <w:nfc w:val=\"23\"/>\n        <w:lvlText w:val=\"\"/>\n        <w:lvlJc w:val=\"left\"/>\n        <w:pPr>\n          <w:ind w:left=\"6480\" w:hanging=\"360\"/>\n        </w:pPr>\n        <w:rPr>\n          <w:rFonts w:ascii=\"Marlett\" w:h-ansi=\"Marlett\" w:hint=\"default\"/>\n        </w:rPr>\n      </w:lvl>\n    </w:listDef>\n    <w:list w:ilfo=\"1\">\n      <w:ilst w:val=\"1\"/>\n    </w:list>\n  </w:lists>\n\n\n  <w:styles>\n    <w:style w:type=\"paragraph\" w:default=\"on\" w:styleId=\"Normal\">\n      <w:name w:val=\"Normal\"/>\n      <w:rsid w:val=\"002743C8\"/>\n      <w:rPr>\n        <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\"/>\n        <wx:font wx:val=\"Calibri\"/>\n        <w:sz-cs w:val=\"24\"/>\n        <w:lang w:val=\"EN-US\" w:fareast=\"EN-US\" w:bidi=\"AR-SA\"/>\n      </w:rPr>\n      <w:pPr>\n        <w:jc w:val=\"both\"/>\n      </w:pPr>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"Heading1\">\n      <w:name w:val=\"heading 1\"/>\n      <wx:uiName wx:val=\"Heading 1\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:link w:val=\"Heading1Char\"/>\n      <w:rsid w:val=\"00505903\"/>\n      <w:pPr>\n        <w:spacing w:before=\"100\" w:before-autospacing=\"on\"/>\n        <w:outlineLvl w:val=\"0\"/>\n        <w:pBdr>\n          <w:top w:val=\"single\" w:sz=\"6\" w:space=\"1\" w:color=\"#EEEEEE\" />\n        </w:pBdr>\n      </w:pPr>\n      <w:rPr>\n        <wx:font wx:val=\"Trebuchet MS\"/>\n        <w:rFonts w:ascii=\"Trebuchet MS\" w:h-ansi=\"Trebuchet MS\"/>\n        <w:color w:val=\"AEAAAA\"/>\n        <w:kern w:val=\"36\"/>\n        <w:sz w:val=\"40\"/>\n        <w:sz-cs w:val=\"40\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"Heading2\">\n      <w:name w:val=\"heading 2\"/>\n      <wx:uiName wx:val=\"Heading 2\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:link w:val=\"Heading2Char\"/>\n      <w:rsid w:val=\"00505903\"/>\n      <w:pPr>\n        <w:spacing w:before=\"600\"/>\n        <w:outlineLvl w:val=\"1\"/>\n      </w:pPr>\n      <w:rPr>\n        <w:color w:val=\"595959\"/>\n        <wx:font wx:val=\"Calibri\"/>\n        <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\"/>\n        <w:b/>\n        <w:b-cs/>\n        <!-- <w:caps/> -->\n        <w:sz-cs w:val=\"28\"/>\n        <w:sz w:val=\"28\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"Heading3\">\n      <w:name w:val=\"heading 3\"/>\n      <wx:uiName wx:val=\"Heading 3\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:link w:val=\"Heading3Char\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:pPr>\n        <w:spacing w:before=\"240\" w:after=\"100\" w:after-autospacing=\"on\"/>\n        <w:outlineLvl w:val=\"2\"/>\n      </w:pPr>\n      <w:rPr>\n        <wx:font wx:val=\"Calibri\"/>\n        <w:b/>\n        <w:b-cs/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"FromTo\">\n      <w:name w:val=\"FromTo\"/>\n      <w:rsid w:val=\"004E2103\"/>\n      <w:rPr>\n        <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\"/>\n        <w:b w:val=\"off\"/>\n        <w:b-cs/>\n        <w:color w:val=\"AEAAAA\"/>\n        <w:sz w:val=\"28\"/>\n        <w:sz-cs w:val=\"28\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:default=\"on\" w:styleId=\"DefaultParagraphFont\">\n      <w:name w:val=\"Default Paragraph Font\"/>\n    </w:style>\n    <w:style w:type=\"table\" w:default=\"on\" w:styleId=\"TableNormal\">\n      <w:name w:val=\"Normal Table\"/>\n      <wx:uiName wx:val=\"Table Normal\"/>\n      <w:rPr>\n        <wx:font wx:val=\"Times New Roman\"/>\n        <w:lang w:val=\"EN-US\" w:fareast=\"EN-US\" w:bidi=\"AR-SA\"/>\n      </w:rPr>\n      <w:tblPr>\n        <w:tblInd w:w=\"0\" w:type=\"dxa\"/>\n        <w:tblCellMar>\n          <w:top w:w=\"0\" w:type=\"dxa\"/>\n          <w:left w:w=\"108\" w:type=\"dxa\"/>\n          <w:bottom w:w=\"0\" w:type=\"dxa\"/>\n          <w:right w:w=\"108\" w:type=\"dxa\"/>\n        </w:tblCellMar>\n      </w:tblPr>\n    </w:style>\n    <w:style w:type=\"list\" w:default=\"on\" w:styleId=\"NoList\">\n      <w:name w:val=\"No List\"/>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"Hyperlink\">\n      <w:name w:val=\"Hyperlink\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:rPr>\n        <w:strike w:val=\"off\"/>\n        <w:dstrike w:val=\"off\"/>\n        <w:color w:val=\"2F5496\"/>\n        <w:u w:val=\"none\"/>\n        <w:effect w:val=\"none\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"FollowedHyperlink\">\n      <w:name w:val=\"FollowedHyperlink\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:rPr>\n        <w:strike w:val=\"off\"/>\n        <w:dstrike w:val=\"off\"/>\n        <w:color w:val=\"7B0796\"/>\n        <w:u w:val=\"none\"/>\n        <w:effect w:val=\"none\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"Heading2Char\">\n      <w:name w:val=\"Heading 2 Char\"/>\n      <w:link w:val=\"Heading2\"/>\n      <w:rsid w:val=\"00505903\"/>\n      <w:rPr>\n        <wx:font wx:val=\"Calibri\"/>\n        <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\"/>\n        <w:b/>\n        <w:b-cs/>\n        <!-- <w:caps/> -->\n        <w:sz-cs w:val=\"28\"/>\n        <w:sz w:val=\"28\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"Heading3Char\">\n      <w:name w:val=\"Heading 3 Char\"/>\n      <w:link w:val=\"Heading3\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:rPr>\n        <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\"/>\n        <w:color w:val=\"1F4D78\"/>\n        <w:sz w:val=\"28\"/>\n        <w:sz-cs w:val=\"28\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"NormalWeb\">\n      <w:name w:val=\"Normal (Web)\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:pPr>\n        <w:spacing w:before=\"100\" w:before-autospacing=\"on\" w:after=\"100\" w:after-autospacing=\"on\"/>\n        <w:jc w:val=\"both\"/>\n      </w:pPr>\n      <w:rPr>\n        <wx:font wx:val=\"Calibri\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"Heading1Char\">\n      <w:name w:val=\"Heading 1 Char\"/>\n      <w:link w:val=\"Heading1\"/>\n      <w:rsid w:val=\"00505903\"/>\n      <w:rPr>\n        <wx:font wx:val=\"Trebuchet MS\"/>\n        <w:rFonts w:ascii=\"Trebuchet MS\" w:h-ansi=\"Trebuchet MS\"/>\n        <w:color w:val=\"AEAAAA\"/>\n        <w:kern w:val=\"36\"/>\n        <w:sz w:val=\"40\"/>\n        <w:sz-cs w:val=\"40\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"Strong\">\n      <w:name w:val=\"Strong\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:rPr>\n        <w:b/>\n        <w:b-cs/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"Emphasis\">\n      <w:name w:val=\"Emphasis\"/>\n      <w:rsid w:val=\"001B7422\"/>\n      <w:rPr>\n        <w:i/>\n        <w:i-cs/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"tenure\">\n      <w:name w:val=\"tenure\"/>\n      <w:basedOn w:val=\"DefaultParagraphFont\"/>\n      <w:rsid w:val=\"001B7422\"/>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"Title\">\n      <w:name w:val=\"Title\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:next w:val=\"Normal\"/>\n      <w:link w:val=\"TitleChar\"/>\n      <w:rsid w:val=\"002D3B7B\"/>\n      <w:pPr>\n        <w:contextualSpacing/>\n      </w:pPr>\n      <w:rPr>\n        <w:rFonts w:ascii=\"Segoe UI\" w:h-ansi=\"Segoe UI\"/>\n        <wx:font wx:val=\"Segoe UI\"/>\n        <w:b/>\n        <w:spacing w:val=\"-10\"/>\n        <w:kern w:val=\"28\"/>\n        <w:sz w:val=\"48\"/>\n        <w:sz-cs w:val=\"56\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"TitleChar\">\n      <w:name w:val=\"Title Char\"/>\n      <w:link w:val=\"Title\"/>\n      <w:rsid w:val=\"002D3B7B\"/>\n      <w:rPr>\n        <w:rFonts w:ascii=\"Segoe UI\" w:h-ansi=\"Segoe UI\"/>\n        <w:spacing w:val=\"-10\"/>\n        <w:kern w:val=\"28\"/>\n        <w:sz w:val=\"48\"/>\n        <w:sz-cs w:val=\"56\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"ListParagraph\">\n      <w:name w:val=\"List Paragraph\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:rsid w:val=\"00C146CA\"/>\n      <w:pPr>\n        <w:ind w:left=\"720\"/>\n        <w:contextualSpacing/>\n      </w:pPr>\n      <w:rPr>\n        <wx:font wx:val=\"Calibri\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"paragraph\" w:styleId=\"Summary\">\n      <w:name w:val=\"Summary\"/>\n      <w:basedOn w:val=\"Normal\"/>\n      <w:link w:val=\"SummaryChar\"/>\n      <w:rsid w:val=\"00A210E1\"/>\n      <w:pPr>\n        <w:spacing w:before=\"120\"/>\n      </w:pPr>\n      <w:rPr>\n        <wx:font wx:val=\"Calibri\"/>\n        <w:color w:val=\"767171\"/>\n      </w:rPr>\n    </w:style>\n    <w:style w:type=\"character\" w:styleId=\"SummaryChar\">\n      <w:name w:val=\"Summary Char\"/>\n      <w:link w:val=\"Summary\"/>\n      <w:rsid w:val=\"00A210E1\"/>\n      <w:rPr>\n        <w:rFonts w:ascii=\"Calibri\" w:h-ansi=\"Calibri\"/>\n        <w:sz-cs w:val=\"24\"/>\n      </w:rPr>\n    </w:style>\n  </w:styles>\n\n  <w:docPr>\n    <w:view w:val=\"print\"/>\n    <w:zoom w:percent=\"98\"/>\n    <w:doNotEmbedSystemFonts/>\n    <w:defaultTabStop w:val=\"720\"/>\n    <w:characterSpacingControl w:val=\"DontCompress\"/>\n    <w:webPageEncoding w:val=\"unicode\"/>\n    <w:optimizeForBrowser/>\n    <w:allowPNG/>\n    <w:validateAgainstSchema/>\n    <w:saveInvalidXML w:val=\"off\"/>\n    <w:ignoreMixedContent w:val=\"off\"/>\n    <w:alwaysShowPlaceholderText w:val=\"off\"/>\n    <w:compat>\n      <w:breakWrappedTables/>\n    </w:compat>\n    <wsp:rsids>\n      <wsp:rsidRoot wsp:val=\"00C146CA\"/>\n      <wsp:rsid wsp:val=\"000A3AF0\"/>\n      <wsp:rsid wsp:val=\"001B7422\"/>\n      <wsp:rsid wsp:val=\"002743C8\"/>\n      <wsp:rsid wsp:val=\"002865F0\"/>\n      <wsp:rsid wsp:val=\"002D3B7B\"/>\n      <wsp:rsid wsp:val=\"00397D4D\"/>\n      <wsp:rsid wsp:val=\"00437135\"/>\n      <wsp:rsid wsp:val=\"00505903\"/>\n      <wsp:rsid wsp:val=\"00606071\"/>\n      <wsp:rsid wsp:val=\"006C2CFB\"/>\n      <wsp:rsid wsp:val=\"00771B3E\"/>\n      <wsp:rsid wsp:val=\"007D096C\"/>\n      <wsp:rsid wsp:val=\"009452CA\"/>\n      <wsp:rsid wsp:val=\"00A210E1\"/>\n      <wsp:rsid wsp:val=\"00B43FDC\"/>\n      <wsp:rsid wsp:val=\"00C146CA\"/>\n      <wsp:rsid wsp:val=\"00C77315\"/>\n      <wsp:rsid wsp:val=\"00CD3781\"/>\n      <wsp:rsid wsp:val=\"00E578D4\"/>\n      <wsp:rsid wsp:val=\"00EA0B64\"/>\n      <wsp:rsid wsp:val=\"00FE101B\"/>\n    </wsp:rsids>\n  </w:docPr>\n\n\n  <w:body>\n    <wx:sect>\n\n\n      <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"007D096C\" wsp:rsidP=\"00C146CA\">\n        <w:pPr>\n          <w:pStyle w:val=\"Title\"/>\n        </w:pPr>\n        <w:r>\n\n\n          <w:t>Jane Q. Fullstacker</w:t>\n        </w:r>\n      </w:p>\n\n\n      <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"00505903\" wsp:rsidP=\"00C146CA\">\n        <w:pPr>\n          <w:rPr>\n            <w:sz-cs w:val=\"20\"/>\n          </w:rPr>\n        </w:pPr>\n        <w:hlink w:dest=\"mailto:jdoe@onecoolstartup.io\">\n          <w:r wsp:rsidRPr=\"003876BF\">\n            <w:rPr>\n              <w:rStyle w:val=\"Hyperlink\"/>\n              <w:sz w:val=\"16\"/>\n            </w:rPr>\n            <w:t>jdoe@onecoolstartup.io<w:br/></w:t>\n          </w:r>\n        </w:hlink>\n        <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\">\n          <w:rPr>\n            <w:sz w:val=\"16\"/>\n          </w:rPr>\n          <w:t>1-650-999-7777<w:br/></w:t>\n        </w:r>\n        <w:hlink w:dest=\"http://janef.me/blog\">\n          <w:r wsp:rsidRPr=\"003876BF\">\n            <w:rPr>\n              <w:rStyle w:val=\"Hyperlink\"/>\n              <w:sz w:val=\"16\"/>\n            </w:rPr>\n            <w:t>http://janef.me/blog</w:t>\n          </w:r>\n        </w:hlink>\n      </w:p>\n\n\n      \n\n\n      <wx:sub-section>\n  <wx:pBdrGroup>\n    <wx:borders>\n      <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n    </wx:borders>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00D1523B\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading1\"/>\n        <w:ind w:left=\"-720\"/>\n      </w:pPr>\n      <w:r>\n        <w:pict>\n          <v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\" o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">\n            <v:stroke joinstyle=\"miter\"/>\n            <v:formulas>\n              <v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>\n              <v:f eqn=\"sum @0 1 0\"/>\n              <v:f eqn=\"sum 0 0 @1\"/>\n              <v:f eqn=\"prod @2 1 2\"/>\n              <v:f eqn=\"prod @3 21600 pixelWidth\"/>\n              <v:f eqn=\"prod @3 21600 pixelHeight\"/>\n              <v:f eqn=\"sum @0 0 1\"/>\n              <v:f eqn=\"prod @6 1 2\"/>\n              <v:f eqn=\"prod @7 21600 pixelWidth\"/>\n              <v:f eqn=\"sum @8 21600 0\"/>\n              <v:f eqn=\"prod @7 21600 pixelHeight\"/>\n              <v:f eqn=\"sum @10 21600 0\"/>\n            </v:formulas>\n            <v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>\n            <o:lock v:ext=\"edit\" aspectratio=\"t\"/>\n          </v:shapetype>\n          <w:binData w:name=\"wordml://03000002.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPlQTFRFv8HDv8HEv8LQv8LSv8zdv8HGv8LKv8HKv8jXv8bVv8LOwczdzcHDycLEwcHDxcHGycLD18bD1cTDzcLDx8HD28jD08LDw8HD1cbDxcHD2czS1czSy8bEw9Dmzdzxz97xydj1xdLqx9Tqy9jszdz7wc7iy9bu0+P/2ef72e//2/X/+djK4czD6dDE89bK4crD99rM997Q/dzO5c7E89TI997T//vd/efX/+HQ++XT//Hd/+3V/+nT///5+/n/+//////75f//6f///f/////s///q8//////1///37/////vo///k4fH/5//////w4+/7//Hk5fH/////unTQ4QAAAQ1JREFUSMft1GtTQUEYB/A/JSlCoXJJUYqKqNwvFaFDquf7f5h0jrMXe3BmvGrGvnp29jc7O/99dkG2BzZ0Q/8/bbVt01vsd+zRlzskbO5a9jqul9OK78woqgfOV6r5kwtpJYCtN726x3a3F4QruYBO5c6NXr0f4pyofiRbWEhqhNxZUiwsJOWx2yfFwkIOwrgwKslClWJUooUqjahUq9NhAUh1Gf2Lik0eAM+HsKsWhCNtLo8iuGSyeIy9sXRW7YTb5qk7ZyFZAoI1o5qTPFdmeVSyFG7LtDwqWYo9MLMls2fmpNRZU+v8pEdc6bNJWJZyv2rRLyGq79jP8lcgRrXiwTzxqFbR53hm/S/jF09ZANBqGaBnAAAAAElFTkSuQmCC</w:binData>\n          <v:shape id=\"_x0000_i1028\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n            <v:imagedata src=\"wordml://03000002.png\" o:title=\"fa-code\"/>\n          </v:shape>\n        </w:pict>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>SKILLS</w:t>\n      </w:r>\n    </w:p>\n  </wx:pBdrGroup>\n\n  <w:tbl>\n    <w:tblPr>\n      <w:tblW w:w=\"0\" w:type=\"auto\"/>\n      <w:tblLook w:val=\"04A0\"/>\n    </w:tblPr>\n    <w:tblGrid>\n      <w:gridCol w:w=\"828\"/>\n      <w:gridCol w:w=\"8748\"/>\n    </w:tblGrid>\n\n\n    <w:tr wsp:rsidR=\"00427ECC\" wsp:rsidTr=\"00FD3B33\">\n      <w:trPr>\n        <w:trHeight w:val=\"882\"/>\n      </w:trPr>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"828\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1028\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:38.25pt;z-index:1\" fillcolor=\"#428BCA\"  strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1026\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:8pt;z-index:2\" fillcolor=\"#FFFFFF\" strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n        </w:p>\n      </w:tc>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"8748\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p>\n          <w:pPr>\n            <w:spacing w:before=\"120\"/>\n          </w:pPr>\n          <w:r>\n            <w:rPr>\n              <w:sz w:val=\"24\"/>\n              <w:b/>\n              <w:caps/>\n            </w:rPr>\n            <w:t>Web</w:t>\n          </w:r>\n        </w:p>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:caps/>\n              <w:spacing w:val=\"22\"/>\n            </w:rPr>\n            <w:t>JavaScript  HTML 5  CSS  LAMP  MVC  REST</w:t>\n          </w:r>\n        </w:p>\n      </w:tc>\n    </w:tr>\n\n\n    <w:tr wsp:rsidR=\"00427ECC\" wsp:rsidTr=\"00FD3B33\">\n      <w:trPr>\n        <w:trHeight w:val=\"882\"/>\n      </w:trPr>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"828\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1028\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:38.25pt;z-index:1\" fillcolor=\"#C00000\"  strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1026\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:0pt;z-index:2\" fillcolor=\"#FFFFFF\" strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n        </w:p>\n      </w:tc>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"8748\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p>\n          <w:pPr>\n            <w:spacing w:before=\"120\"/>\n          </w:pPr>\n          <w:r>\n            <w:rPr>\n              <w:sz w:val=\"24\"/>\n              <w:b/>\n              <w:caps/>\n            </w:rPr>\n            <w:t>JavaScript</w:t>\n          </w:r>\n        </w:p>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:caps/>\n              <w:spacing w:val=\"22\"/>\n            </w:rPr>\n            <w:t>Node.js  Angular.js  jQuery  Bootstrap  React.js  Backbone.js</w:t>\n          </w:r>\n        </w:p>\n      </w:tc>\n    </w:tr>\n\n\n    <w:tr wsp:rsidR=\"00427ECC\" wsp:rsidTr=\"00FD3B33\">\n      <w:trPr>\n        <w:trHeight w:val=\"882\"/>\n      </w:trPr>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"828\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1028\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:38.25pt;z-index:1\" fillcolor=\"#F1C40F\"  strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1026\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:16pt;z-index:2\" fillcolor=\"#FFFFFF\" strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n        </w:p>\n      </w:tc>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"8748\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p>\n          <w:pPr>\n            <w:spacing w:before=\"120\"/>\n          </w:pPr>\n          <w:r>\n            <w:rPr>\n              <w:sz w:val=\"24\"/>\n              <w:b/>\n              <w:caps/>\n            </w:rPr>\n            <w:t>Database</w:t>\n          </w:r>\n        </w:p>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:caps/>\n              <w:spacing w:val=\"22\"/>\n            </w:rPr>\n            <w:t>MySQL  PostgreSQL  NoSQL  ORM  Hibernate</w:t>\n          </w:r>\n        </w:p>\n      </w:tc>\n    </w:tr>\n\n\n    <w:tr wsp:rsidR=\"00427ECC\" wsp:rsidTr=\"00FD3B33\">\n      <w:trPr>\n        <w:trHeight w:val=\"882\"/>\n      </w:trPr>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"828\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1028\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:38.25pt;z-index:1\" fillcolor=\"#F1C40F\"  strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1026\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:16pt;z-index:2\" fillcolor=\"#FFFFFF\" strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n        </w:p>\n      </w:tc>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"8748\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p>\n          <w:pPr>\n            <w:spacing w:before=\"120\"/>\n          </w:pPr>\n          <w:r>\n            <w:rPr>\n              <w:sz w:val=\"24\"/>\n              <w:b/>\n              <w:caps/>\n            </w:rPr>\n            <w:t>Cloud</w:t>\n          </w:r>\n        </w:p>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:caps/>\n              <w:spacing w:val=\"22\"/>\n            </w:rPr>\n            <w:t>AWS  EC2  RDS  S3  Azure  Dropbox</w:t>\n          </w:r>\n        </w:p>\n      </w:tc>\n    </w:tr>\n\n\n    <w:tr wsp:rsidR=\"00427ECC\" wsp:rsidTr=\"00FD3B33\">\n      <w:trPr>\n        <w:trHeight w:val=\"882\"/>\n      </w:trPr>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"828\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1028\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:38.25pt;z-index:1\" fillcolor=\"#5CB85C\"  strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n          <w:r>\n            <w:rPr>\n              <w:noProof/>\n            </w:rPr>\n            <w:pict>\n              <v:rect id=\"_x0000_s1026\" style=\"position:absolute;left:0;text-align:left;margin-left:20.6pt;margin-top:1.4pt;width:7.15pt;height:30pt;z-index:2\" fillcolor=\"#FFFFFF\" strokeweight=\"0\"/>\n            </w:pict>\n          </w:r>\n        </w:p>\n      </w:tc>\n      <w:tc>\n        <w:tcPr>\n          <w:tcW w:w=\"8748\" w:type=\"dxa\"/>\n          <w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"auto\"/>\n        </w:tcPr>\n        <w:p>\n          <w:pPr>\n            <w:spacing w:before=\"120\"/>\n          </w:pPr>\n          <w:r>\n            <w:rPr>\n              <w:sz w:val=\"24\"/>\n              <w:b/>\n              <w:caps/>\n            </w:rPr>\n            <w:t>Project</w:t>\n          </w:r>\n        </w:p>\n        <w:p wsp:rsidR=\"00427ECC\" wsp:rsidRDefault=\"00427ECC\" wsp:rsidP=\"00427ECC\">\n          <w:r>\n            <w:rPr>\n              <w:caps/>\n              <w:spacing w:val=\"22\"/>\n            </w:rPr>\n            <w:t>Agile  TFS  JIRA  GitHub  Unified Process  MS Project</w:t>\n          </w:r>\n        </w:p>\n      </w:tc>\n    </w:tr>\n\n\n  </w:tbl>\n</wx:sub-section>\n\n\n\n\n\n\n\n      \n      \n      \n      \n      \n      \n      \n      \n      \n      \n      \n\n\n      <wx:sub-section>\n\n\n\n        <wx:pBdrGroup>\n          <wx:borders>\n            <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n          </wx:borders>\n          <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n            <w:pPr>\n              <w:pStyle w:val=\"Heading1\"/>\n              <w:ind w:left=\"-720\"/>      \n            </w:pPr>\n            <w:r>\n              <w:pict>\n                <w:binData w:name=\"wordml://03000003.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASZQTFRFv8HDv8HOv8HGv8LIv8TTv8zdv8LOv8bVv8LEv8HEv8HKv8rbv8LQv8HIv8jXv8HMv8LKv8TQz8bEw8LEw8LGydDfyczOz8jGw8jOz8zKw8HDwcbMz8zOycTDy8zOzcHD1cTDxcHDz8LD3crEwcHDwcLEw8LDycHDx8HD0cLDy8HD1drb3dTMy9Tb3drTycLDwcrV3drb1cjE29rb287Izdz/z9zsxdDky9r7ydbs2/X/2/H/1eXw79LG79zQ69bK7dLG487E897Q89bK/+3d///d/+nT8+vd//XZ/+fT//HZ/ePS8+XV8+/f//vb9///4f//7//////q4evw8+/s6+/w7f/////o/f//4+/w8+/w7+/w4fv/4//////59+/w8/P5////sDySyAAAAP9JREFUSMdjSCQaMIwqHZJKXYSEsQARUX9MpbYMWAFjAD2VMomJMzBISEoxSMvIMjDLieNRyhLoKs8YEKTAYArksia6KeJWyhZsJ8Vk5q7EYB6izMAeaq9CHW+pqjEwcAAxpzDQQFUVvG71UOeyArrVAuxWTzxuZQnzUueyDgcpdWDgjvCWoncU8ET6aPDa+GoyWEY5MvBFO0nh85afFn8MUVEADixVYEBBAkuNOm4V0NZR4dTV02cwMDRiEDQ2oU5yIcFUUpMLHOANAVC4wlXidysothg4wLlahUBsgQCXFQoXn1KoHJWVkuAAuLdwK3XGEQWxmErj4qOwgQS4AgDkC738cGCe/AAAAABJRU5ErkJggk==</w:binData>\n                <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n                  <v:imagedata src=\"wordml://03000003.png\" o:title=\"fa-building\"/>\n                </v:shape>\n              </w:pict>\n            </w:r>\n            <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n              <w:t>EMPLOYMENT</w:t>\n            </w:r>\n          </w:p>\n        </wx:pBdrGroup>\n\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Head Code Ninja, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"https://area52.io/does-not-exist\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Area 52</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Sep 2013 — Present</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Development team manager for </w:t></w:r><w:hlink w:dest=\"https://en.wikipedia.org/wiki/Vaporware\"><w:r><w:rPr><w:b/><w:rStyle w:val=\"Hyperlink\"/></w:rPr><w:t>Quantum Diorama</w:t></w:r></w:hlink><w:r><w:rPr></w:rPr><w:t>, a distributed molecular modeling and analysis suite for Linux and OS X.</w:t></w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Managed a 5-person development team</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 2</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Etc.</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Principal Developer, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"https://en.wikipedia.org/wiki/Better_Off_Ted#Plot\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Veridian Dynamics</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Jul 2011 — Aug 2013</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Developer on numerous projects culminating in technical lead role for the </w:t></w:r><w:hlink w:dest=\"http://betteroffted.wikia.com/wiki/Jabberwocky\"><w:r><w:rPr><w:rStyle w:val=\"Hyperlink\"/></w:rPr><w:t>Jabberwocky project</w:t></w:r></w:hlink><w:r><w:rPr></w:rPr><w:t> and promotion to principal developer.</w:t></w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Managed a 5-person development team</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 2</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Etc.</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>IT Administrator, </w:t>\n      </w:r>\n      \n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:t>Stark Industries</w:t>\n        </w:r>\n      \n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Oct 2008 — Jun 2011</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Junior programmer with heavy code responsibilities. Promoted to intermediate role after 6 months.</w:t></w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Promoted to intermediate developer after 6 months</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 2</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Etc.</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Intern, </w:t>\n      </w:r>\n      \n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:t>Dunder Mifflin</w:t>\n        </w:r>\n      \n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Jun 2008 — Sep 2008</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Performed IT administration and deployments for Dunder Mifflin.</w:t></w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Supervised roll-out of Dunder Mifflin Infinity website.</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Performed mission-critical system backups and</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Etc.</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000001.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAR1QTFRFv8HEv8HDv8jZv8HGv8rbv8HIv8HOv8zdv8bVv8TOv8TMv8LK08TD1cTD2dDOz8rIw8LDwcLGycrOz9DX0crIw8LEwcHDw8LGycrTx8HD2cjDzcHDw8bQ29zZz8TDxcHDy8TDx8LD3drizdzxz97xzdz/xdTs09zqz+H70+P70+X/0eH/0+Px1eX51+v/3ef11+Hw1en/99jK+drM49rb7dTI7dbK8djM9drO99zO89bK5c7E/9zO79rQ8dTI7drO69zi/efZ/+/X/+HQ///d/+vV8+HT///7+fX5///m9//////q+f///fXx8+vk6+/w9/n/5fH/4//////w7////f/////54f//+/////v1//Hm4+Hq//vw8fv/////A0CiDgAAARBJREFUSMdjiCMRMIxqGNUwqoHaGtw9SNRgxKBBkgZPHkYmL1I0GDMyMmuSoAFoASNOKxiwW4DbCgYcFuC0ggGHBUArtIjU4M0L0cDI4kNQg6+fCR+/ACMMCAoJK/kH4NLgKCIqxogNMIhLBGLTYMyIEzBoY9PgbopTvTJ2P7ibiRGhHtnT2HUwq+AOJXdzTB2sOviC1d1CjJB69IizRNXBqksopp0kUTSwBRHS4Ixmgx4hDVZoflAlpMEaTYMaAQ3BUmga2AlocJGGqJORlYMwOELwa3CVB6ni1A+NC3NTAAdTOH4NNkA1XAahYHaYrSIwYRji12DHyK0eAedF2stjBhOqhqjoCBR+jEMs/UtvAMiRyWLg7gtIAAAAAElFTkSuQmCC</w:binData>\n        <v:shape id=\"_x0000_i1031\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000001.png\" o:title=\"star-icon\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>PROJECTS</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>contributor, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"https://fluentdesk.com/hackmyresume\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>HackMyResume</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2015-09 — Present</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Exemplar user for HackMyResume and FluentCV!</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>co-creator, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"http://project.website.com\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Augmented Android</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2012-02 — 2014-01</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Performed flagship product conceptualization and development.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>creator, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"http://myblog.jane.com/blog\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Blog</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>??? — Present</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Conceptualization, design, development, and deployment.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000011.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA8dJREFUeNrsl+1v2lYUhy8GLo6xsQHjuEA9MI4hTatG2qR+2D8/aR8mVVOytlrLO65DKLOT4DcoOMYMGqlbi7GdJlOjyVf+4mv76Dlvv3scW61W4CGtWAQUAUVAEVAEFAFFQBFQBHQ3IEcft6ShMQdomi2JZQZ+XyC1+VtrfP35NsmIPz5hE/81kNo/HRquZ3jm2mIJkqR4wEG1/VZduPEUhXoDoYV6g8MCgcJ4Y2rm1Nj9GKfrRRoCOo+rI2O50KYLz9cgnAJwP0AERaSR3RGyLlqj7DpCl9Z6xydCZPp/W0PAsfQ52MNx6N1lf75t6ksQ2+Pqz3jPLnNmM8uFFB6GFAl+xWifnLz5/eRV17OOEiSLo58spXLePT8bvjp9+fqPl29UcB9AzqinzomySNij3pl7+xS4w540RTmeAhOpa9wdSGlKJizWKsVaATWHTeW2PJPuuY5kOb7cqIRzyR/I6A40kK0IGQAyopgFyqA9vw2O3ZPGNlE5LKxTW/whD0O45AfkyoORnS7XCje3VG0/Y6tN2QnN86E9nqJMtXhTzDmBJ4NdQvxa+syEdOUfdcV4kYbaWVMLhzNvDS8AJdYzn+ufOQh2CdltTlIAyR9kvxDlgyINtHYrRHE6Z03FzrDrYv7XCuES4muuxnwlHYmSyKbnymAUlDft3VCDebH29Vlx41K3M7sd0C5zmyOpVmGhKb1T/aWrPQF0ScA9dKsk0ClL6SlOeKBZv6+51CMvc5uVFR4RjjaUZ77Sld4XyzsOtXqFAXq/MwkJ5CidvwxYaHA7hR7hqkU4lTvn3qJy1ZZNyFb53aNaofGYsC9kz7xvAc0kWQdMVUT9UpIRqhSij6WZV3jeT2yCFXK+vb1xyZRbk+DxQxtcWkksp3f7un/VonhSGw8u+aP8l/vy2ETwwkLqdAMEEEvZ2loXsrQ/EAYT4NqUP5hhlAaHe1t7SSS21NSxEeb7FIEGpgxWWToeTvjiJFfdbsPHlVwy5OSToTk8uIYSpSdHZSqQKU4IR4eMV91TR4cNMpAphhWEYy9Z8TCJUJXjF8zVoNNVzNly6+l6SGW4RnUf7uzCDPv8Ba302+/Vi4/XW50Yx4g8X+VpKvFNE6NtWVcTxdzM7ShRyOVIdLube6e/nE9BnDr++Sm19f1cM43LieVuKoahCCyDIXca8iGOs+vrm0dkiFL59cWE/gABD2w9OKAwfx3S61/PfXVl5XyygcRiPv6hzNOf6uS9/Ci6zmoVZkx0Vyufkdm27fuK0LpTPjp3zkUC8+rQrfW3AAMAaZzVLhuUv2EAAAAASUVORK5CYII=</w:binData>\n        <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000011.png\" o:title=\"fa-justice-scales\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>GOVERNANCE</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Member, </w:t>\n      </w:r>\n\n      <w:hlink w:dest=\"http://themommiesnetwork.org\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>The Mommies Network</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2008-02 — 2010-01</w:t>\n      </w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Since 2008 I&apos;ve been a full-time member of the board of directors for TMN.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Academic Contributor, </w:t>\n      </w:r>\n\n      <w:hlink w:dest=\"https://www.khronos.org\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Khronos Group</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2015-01 — Present</w:t>\n      </w:r>\n    </w:p>\n\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Participated in GORFF standardization process (Draft 2).</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000004.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAaFQTFRFv8HDv8LIv8HGv8HEv8HKv8HMv8jXv8HOv8jZv8TT3dLS2c7Kw8HDwcbM08rIwcHDwcTKz9Lbz8jGy9DXy8bEyczTycTDxcrSx8LDw8jV2dDMxcHD3dLOw8jO1cTDx8rSwc7fzdLbz8LD1czK3dLTx8HD28jDy8HDy8zOz8rI0cLD3crD18jE0cjGyc7Z29LQz8rKxcLEw8LEw8TKy8zQ1djdzcHD1drk09bi09jm0dbizdz/xdLqy9jsxdTswc7i3ePs2eHo2+Ps2e3/z+H/3ev/2/X/3fn/2e//z+H71en/69zT6djS49LO/d7Q6drT4czD59TQ/97O/drM79LG5c7E8ePZ+eHS7eHX8+Pb/+/X/ePS8ePb//Xb9eXZ7+Pd///d/+nT/+HQ///7+evk8fX7///59+fi6/P5//v16ev1/f////nz5efz+////fXs+fv/+/Po9/n/6////evi9///8/n////q//nu4+fz///i+fHw9fX7///18//q4f/q8//i//nm6+/7///o+f//7///4///9+/w8+/w8/P5////rwMOhgAAAWBJREFUSMdj6CIaMIwqHVVKL6XJKVzmqUQoTUvn5mEAAl6LDLxKM8P4+BngQEAwKxu70hxvISR1EMAonJuHrjTfR4QBO2ASdShAKC30FWPAC8Qdi8BKwyUYiACSxUClJVLShFXyWpaCHZCcIoPXBbLmZUjeKpfDoYxZ3qkANQT8+FmcK/zRQ4tJtDIPPVyTAxgUQMGdGYGIA0ZF1BiAKq1SYnbpCgQHSVqkMjBmBawywJ5QcUVXGqXK4tYVAPQoOJ0kV9eAU4MUMBit0ZVG87C616pBYh5sXmaMMjjVYCiNVWdgYKuDBwKjhibcxehKg4Bi7PVYw8sGm6kNWsQo7QpmYPGo1cYWA57oSkMYmLy6GnUwVdpmoysNBbs/OU4XNbL0mjCiABROdpCsEK9vYGgEBMYmpmiRBVHaDPS8PXGZO8GMgYGjhSilicDEzdlKlNIkYOSwtxGlNK29o6OToFsBkPOxfsuGle0AAAAASUVORK5CYIJ=</w:binData>\n        <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000004.png\" o:title=\"fa-mortar-board\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>EDUCATION</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:hlink w:dest=\"https://www.cornell.edu/\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Cornell University</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2005 — 2008</w:t>\n      </w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:hlink w:dest=\"https://en.wikipedia.org/wiki/Medfield_College\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Medfield College</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2003 — 2005</w:t>\n      </w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000005.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMxQTFRFv8HDv8HEv8jXv8HOv8LSv8TTv8zdv8LKv8bT3czIwcHDwcTM18bDxcHDw8zdx8HD08bDw8HDw8rZ3drbz8TDycHDzcHDw8LDwc7ixdLqzdzxxdLoxdTs1ePx0eH72+n//dzO79LG89bK+9rM997Q5drb/9zO7dbK5c7G/+nV++XT/+3X//Hf//HZ///d/+fT//nq///q8////fXx8+/z+///4f//9///6f///f//7/////Xk8fv///Hk/fXo5ef1///7///x6fX/////TAOGGAAAALpJREFUSMft1NcOgjAUBuCDe4Hixr33Xohb+/7vZCnEKC3ShEv4b5om30Xzn5wC4g741Keu6CqegGSdh65TgCM0OGgLSAKbv3S72yPUNmjwYN6ZdCyCpKKOQUNHNBGhrLFpFwtJnaYJVXQJ4RObnjPE9mR8ZC+6FCp2b70a9tbP3TVKWhog9pNfaS3r21ok1essbyfpEcwLJq06TmtRNKniZSqUuGlk4Hm6xCtQc6SPoRxtPkcQe7n4s96JF4yPwZXEugAAAABJRU5ErkJggk==</w:binData>\n        <v:shape id=\"_x0000_i1029\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000005.png\" o:title=\"fa-child\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>SERVICE</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Technical Consultant, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"http://technology-for-tots.org\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Technology for Tots</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Nov 2003 — Jun 2005</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Summary of this volunteer stint.</w:t></w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 1</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 2</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>etc</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>NCO, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"http://www.usar.army.mil/\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>US Army Reserves</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Nov 1999 — Jun 2003</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Summary of this military stint.</w:t></w:r>\n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 1</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Accomplishment 2</w:t></w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>etc</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000010.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAihJREFUeNrsl+1P2lAUxukLFyxaEULFrjNoAFGMiW7OZPv3TZYlbkEbNkSsCghYIWCVIqWUFXUfxKa9k0vF5J6vTc759Z7nnPtcYjAYeKYpSM+UBQbCQBgIA2EgDISBMBAGwkDvDIieSFatKV9c1pSeQXpnw5FlfhFA1yFQvzp05fjw6KqjPyvi4xPbySj9Bi27PxUzIzRmDLqV/M+c7L6GVOl3pW1Yf+vVLgqay0BG9Uax6X+nWVTdBVLUe3t5aXcuAhmtUkU1pmLsTZT8SbnW6TsNNBPkUAHpjaIoFW+7T+ND+UJcbCMRISFRHgKEeB7NHlLOM2K59aIoTVF6v28pgpedIwP8l0+rfhQtUwp/LGiGpzZKQ/jnFlPpeNBzLYlSud37h+Vlw8JG+oMfTgBOJ1QR9ws3ulOSJxTwfKaUtk4HGIZGKepWU7WlIYCJshYLWVSlATsP0E+ZYT/JZHApHmJctB+s3/4n+3L++69s6U5DBuSkIbVwcFCDWLCUqdxk4uMsmLz9aGV/ZBo9uGxDLAHU89X2q+0HjB/S6tnDXKM7UiPKh/V6td6FtFPeaGovxaEBerwfquclWdFMjZOA5WIrS4+DpctS7gwOayb6dTcOUAE5XC1QWD7h826cGW/KYJcHt7q5921rgZoi+zHMRZIT30P/FcF522sCzn4g9dSCwPnGtR9oXx0LyXWeJazKBPiddORN3mXm2pqo/RhjFbzOfvwVYACXgQOVsrGQ2gAAAABJRU5ErkJggg==</w:binData>\n        <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000010.png\" o:title=\"fa-share-alt\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>AFFILIATION</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Member, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"https://www.ieee.org/index.html\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>IEEE</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Jun 2013 — Present</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Member in good standing since 2013-06.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Member, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"https://developer.apple.com/\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Apple Developer Network</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>??? — Present</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Member of the </w:t></w:r><w:hlink w:dest=\"https://developer.apple.com/\"><w:r><w:rPr><w:rStyle w:val=\"Hyperlink\"/></w:rPr><w:t>Apple Developer program</w:t></w:r></w:hlink><w:r><w:rPr></w:rPr><w:t> since 2008.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Subscriber, </w:t>\n      </w:r>\n      <w:hlink w:dest=\"https://msdn.microsoft.com\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>MSDN</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Jan 2010 — Present</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Super-Ultra-gold level Ultimate Access MSDN subscriber package with subscription toaster and XBox ping pong racket.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>Coordinator, </w:t>\n      </w:r>\n      \n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:t>Campus Coder&apos;s Meetup</w:t>\n        </w:r>\n      \n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>Feb 2003 — Apr 2004</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Host of a monthly </w:t></w:r><w:r><w:rPr><w:b/></w:rPr><w:t>campus-wide meetup for CS students</w:t></w:r><w:r><w:rPr></w:rPr><w:t>. Code, coffee, and crullers!</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000006.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAI1QTFRFv8HDv8HEv8bVv8jXv8LKv8HGv8HIv8zdv8rZv8TT18bDxcHD2dLd1cbDwczd2cjDxcLKwc7fxcTDx8HDz8TDy9jszdzxy9jmy9jo2ef72+n/1eX56dLI79LG/efT/+3X//Hf///59+/w9fX7//vo/f//9///7///8////fv7//nm8+/w8/H1/fXx////vxL+UwAAAMZJREFUSMft1NkSgjAMBdCL4i7uG+4KiIr2/z/PwghtsYk8+WSez2TuJJlAVC786Z/+mp7OQUUaduHMoypUSpgWnDQtRfc9lK2dhv1LYRcsDT0MCluLGSollK1faSqlsxzm1vXpAKlcbfO+Sn7SQmZ25NNz1WRqb/S2DAl3Td9ASfr0ubDSoLzU6Rep0XRHY0YqKmVjAkYqukNzc/cYqdOWEG9rlTptJ48os3apU6ATi8OUkmV6nJHSpHROG6Wlos8kq4D+Ni/aqw5+HvnsQQAAAABJRU5ErkJggk==</w:binData>\n        <v:shape id=\"_x0000_i1030\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000006.png\" o:title=\"fa-pencil\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>WRITING</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:hlink w:dest=\"http://codeproject.com/build-ui-electron-atom.aspx\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Building User Interfaces with Electron and Atom</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2011</w:t>\n      </w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:hlink w:dest=\"http://janef.me\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Jane Fullstacker&apos;s Blog</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2011</w:t>\n      </w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:hlink w:dest=\"http://url.to.publication.com/blah\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Teach Yourself GORFF in 21 Days</w:t>\n        </w:r>\n      </w:hlink>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2008</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>A primer on the programming language of GORFF, whose for loops are coterminous with all of time and space.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000013.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArtJREFUeNrsmP1v0kAYx1soxZW2YOl4s8xkvkyJMZop/380JkuMLpmOxSkvQQasdNCWUks5Wq8WZP4waG9HMpPeL/SSK/e553m+z/NcSdd1ibs0YsQdGxFQBBQBRUARUAQUAUVAEVAE9J8BUUhv2er3by2TpJ2Z7QTahS3u7ZfSQU5PItw67Prx0cXECfkWk39ZPeC34bJRQw5NA4dpKFuJIavekmdI0RpLbCOGBo3+dfOQFLl+vQsWEUHymeI2gJx/w+J19YBZt7p+/O5i4q8VynCvka5wvEjhA5IH6vzvJM7szAxVu3k16CqTxeMOV4BbqZe12g/x1dvHPB4gIPfG9mo6V1pflIAS40s0QRi9sUVM9QFB8DiC2mqenmtzpLyVzOShZ82+PoXBRCfxxJDVVcZgNU0UKofP1kUDaH88avzyebhSBvJ0VY+HFSQ8sp+C6wGdTEtrY5MAnaG1eKSZLAsDvDc24H6sUMKjMvPSO98KT/n8/sOa0ziuu+SP89ldCNjXTThh+SIe2RvNkXnjluuLE5vzbNKTDZiRUuJDCkem1s9rV0jp2fNRJgd/2kMd8iRThU0WCAY0mJiI3QTJZ8te/hoZ0JxMRqKx1DLVtFDbG0ZY+csXPwagXkefI/Kk0hL0kXzl/YEv/tsD2fX+EJWHYQtwA2MwsZfivzWQ2fjaRel+/GQllKGPtK4BBRHP5Hdx9EPK2ED+jp3kCswygZGsmMPS5M8cB1lf4h70kf1TgwqleCEYz6bEqFqL6h4jyTDNJcUIUuUR4yVo44997j/Ac+ugYh4GW6y+eUKjmAm0vY5okaxxuIzNc/egTOSzjmKG952tnA10T2xcIXDN3HgNAsPTTyeodcNvVHJPDyuBiYLcy4DZPDvpaBaK3BLi/vMXEh9CC8EvisDQLBCqriYYngl7z/otwABxHQzMzw8ozAAAAABJRU5ErkJggg==</w:binData>\n        <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000013.png\" o:title=\"fa-book\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>READING</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <!-- <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs> -->\n      </w:pPr>\n      <w:hlink w:dest=\"https://www.reddit.com/r/programming/\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>r/programming</w:t>\n        </w:r>\n      </w:hlink>\n      <!-- <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r> -->\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Daily reader and longtime lurker.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <!-- <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs> -->\n      </w:pPr>\n      <w:hlink w:dest=\"https://news.ycombinator.com/\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Hacker News / YCombinator</w:t>\n        </w:r>\n      </w:hlink>\n      <!-- <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r> -->\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Daily reader and longtime lurker.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <!-- <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs> -->\n      </w:pPr>\n      <w:hlink w:dest=\"http://www.codinghorror.com\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Coding Horror</w:t>\n        </w:r>\n      </w:hlink>\n      <!-- <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r> -->\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>, Jeff Atwood</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Reader since 2007; member of the StackOverflow Beta.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <!-- <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs> -->\n      </w:pPr>\n      <w:hlink w:dest=\"http://www.cc2e.com/Default.aspx\">\n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:rPr>\n            <w:rStyle w:val=\"Hyperlink\"/>\n          </w:rPr>\n          <w:t>Code Complete</w:t>\n        </w:r>\n      </w:hlink>\n      <!-- <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r> -->\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>, Steve McConnell</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>My &apos;desert-island&apos; software construction manual.</w:t></w:r>\n    </w:p>\n\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000007.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAUFQTFRFv8HDv8HEv8bVv8HOv8HMv8HKv8zdv8LSv8TTv8TSv8jZv8HGv8LIv8LQv8LKv8HI08zOz8zOz87TzcHDy8HDwcHDw8LEwcLE1cTDzcLDw87f18jExcHDx8LDwcTK3dTM0djb08LD0cbDw8rVwczdzdzxzdz/xdLmw9Dk0djkzdrw0droz97xwdDky9jo3eXw2+/w2e3/0+P/z+H/0+P71ePx7dLI79LG/dzO4crD4czE99zO89bK49LM8drO5dTM7dbK99rM5dDI7+HX///d8+/Z/eHQ//Xb//Xd8e3Z7+Pd//Hf///5/f/////77///4f//+/Pw8+/w9fX76f/////q6fv////o+f//+//////x6///9fv///nm4/Po//nu+fv/4+Ps///k/fXx8+/s9/n/6/n/5f//+fHw8/P5////sapGIwAAASVJREFUSMdjyCIaMIwqHVVKB6U+zgKCMCCk74tHqZ8ZAxJgVMWj1EUYWSkDkz/RSpkDsCoNDAICVxEUpSwGIMFgNKVuogy4AKshqlJzBkYxIEBTJQ4UEmVQQ1fKhulW9pCsrFAJopRy+GNTasHAGZaVFS6BopQrIivLXYTRCFWphySDemSWnyWKUo2srCgrBs5otMCyFmWQismyQYkt46xYaQZuE/RwBcUpj6YncsDyxtnKMDBq+WLElp+dDJZA5TPFGrHx9rJoCuW0E3AmwkAveVi08SskBuNP2n4OELXcOkTkAkeQWoS/8SlNUoSGPmGl4HjQJSobhkoQaWpyihM4pvSCUvEr9VZCClXlNDxKQ1FTlkoE0dmQN50qSv0ygpBBJqpbAYc7NrM+qyXXAAAAAElFTkSuQmCC</w:binData>\n        <v:shape id=\"_x0000_i1031\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000007.png\" o:title=\"fa-trophy\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>RECOGNITION</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      \n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:t>Honorable Mention</w:t>\n        </w:r>\n      \n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2012-01</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      \n    </w:p>\n\n\n  </wx:sub-section>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      \n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:t>Summa cum laude</w:t>\n        </w:r>\n      \n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2012-01</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      \n    </w:p>\n\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000014.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA5hJREFUeNrsmPtT2kAQx0M4DhJeAZFGqohBGdHal9PWdvrX94dOO1Pta2gtICLFgBQhhhDgOJLGii8khZBMpz9kh58y2c3n9na/e4dDVVXifzKS+M/MBrKBbCAbyAaygWwgG+gfG5jqLfSr/IOvyjImPb4AyyUXaDBlfCQcZEuNjoRJmvYvLnMRZoKnY+KJUaln977XpJtvOf2prUexwCQYfJLdzfO9m54uNrW9zgIzW/Yrm7tNo9mglc8V0CScWqZwm0azfjWX4bGZGipX6/1xaWufFoW/e1Z4cTDmsdoqH8gmaqiHddaD8WWKFFls1GtiT1sdFb43z/jgRTIUnVrAqE0Q9KxALlLLoTLOEWjfRZX9z8Vq5zoTpeND4Aom0ulFRj8H0Gtiy2KRsHPcc7c/Rhb23h/cpBkmoH+W/7K7X11k/Y5xnlRkiTYBBO5vJBk42ppeLj1XzvCiboOeF6+ylIi4Rj0D99c4eva2x0hWIA0V4Wc2x9e7WjmR0Def2lylj3bfVjoT1hJMvt6E5e/FsjD0ZFfSXBQqCBEQksaBcOPr7pdmH7iDieVkjKUvQ2AFE+WP7wqdSYrhCj9+lgoAQF5HPC4elsrtAemNPd/mPMaKWi4Wmucdj3tn+exePusAf0pCUUF0g1PQFCrd74mgVHhTkYe1pGL1SjVOCjVuI2qohurt23KhhTv/KYan09AR39qJgdSUjRU16iBFT4G6IR+cgsTlDsh6MnahRkaAZKQXShWbTZahJs9tOkQft/RUGaGWZccPJPD1lTjr+vvU9ibWPIV6x2hwXSAajq93SAVjrB+I/vXNWMChu1vs2tYigXyRaNTrHhsIAMoYEEzeyYHTv/pw5/kyQ8hn/GGuhOJPXyRZalTItdGx+nA75ans/+DrEvIspF7tJFm3YyR/8ZWFGYQRdasnfKt3gR64F0EHmWzralY46FD8QXrJg0aGKyHkMt8q7StlAO7IxpN5dDTsK0iFouyczgZMcUC7MiHz/tPp3bOIk6Z8DEP9ia90xbNGu3e3HTQl3NnmpmnNqYHk/IcPVWn2s7IzsvryQcy6Q7501DRBc66EjZOfFt465KrYM3mdUCShZh3QqYQIs6Z2RdkqIKHdteDfbIxEq4AQVszzEINu275K/yugMO2x4Ftu35xVQCCeCLnMLt07l2As2zIQ3kqvh9xgVhroZR8/snZ0DDtXlqW+0Y4DdNADp335twADAHYlmV3HkUP7AAAAAElFTkSuQmCC</w:binData>\n        <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000014.png\" o:title=\"fa-group\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>SPEAKING</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n\n  <wx:sub-section>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      \n        <w:r wsp:rsidR=\"009452CA\" wsp:rsidRPr=\"00606071\">\n          <w:t>Data Warehousing Evolved: DARMA 2.0</w:t>\n        </w:r>\n      \n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:rPr>\n          <w:rStyle w:val=\"FromTo\"/>\n        </w:rPr>\n        <w:t>2012-01</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidRDefault=\"00C146CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      \n    </w:p>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRDefault=\"009452CA\" wsp:rsidP=\"00C146CA\">\n      <w:pPr>\n        <w:pStyle w:val=\"ListParagraph\"/>\n        <w:listPr>\n          <w:ilvl w:val=\"0\"/>\n          <w:ilfo w:val=\"1\"/>\n          <wx:t wx:val=\"•\"/>\n          <wx:font wx:val=\"Calibri\"/>\n        </w:listPr>\n        <w:rPr>\n          <w:sz-cs w:val=\"20\"/>\n        </w:rPr>\n      </w:pPr>\n      <w:r><w:rPr></w:rPr><w:t>Won &apos;Best Presentation on an Emerging Technical Field&apos; prize.</w:t></w:r>\n    </w:p>\n\n  </wx:sub-section>\n\n\n</wx:sub-section>\n\n      <wx:sub-section>\n\n<wx:pBdrGroup>\n  <wx:borders>\n    <wx:top wx:val=\"solid\" wx:bdrwidth=\"15\" wx:space=\"1\" wx:color=\"EEEEEE\"/>\n  </wx:borders>\n  <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00693C5A\" wsp:rsidP=\"00C146CA\">\n    <w:pPr>\n      <w:pStyle w:val=\"Heading1\"/>\n      <w:ind w:left=\"-720\"/>      \n    </w:pPr>\n    <w:r>\n      <w:pict>\n        <w:binData w:name=\"wordml://03000015.png\" xml:space=\"preserve\">iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABEpJREFUeNrsV2tz2kYUXQmBBQghZDAYZFsmxo/4VbfOtNPp3+9MmzpxqF8EAyYEbCxjLITEQwipuwIMxIChqSeZqTT6sivp7rnnnj13hRmGAb6nCwff2WUBsgBZgCxAFiALkAXIAmQBsgBZgCxA/zNAxFdHkEppQdL7Y4c7EA578W8GKJ0+LSjDU3cS/uZ1iHhZQHpNqqlf/nTjDrcr4POXGqLapUg3DB20hXQi5N9h/xUkbLp/+9vz3y+F9pezDt/Gr7uB4QKmjuJF2YCPYr/sBvEXE7WHoewEhvXuR94aslgZuvVA1D8Hn6gPmURRezmGBi/t+vjPZHWKr2zM3s8zF25mUhvpk1R1uhzaYuLiVv+vGNLKheyna0FudqSMYzaSmo8GtVSq3IBDz8pvB0v4CLjHbwuKDjDK7agpTR3Y2KBXFytSs91BhtudLBuOvlp0ETMAUktn8fP75tjk7MzemxG10IunfyRFFXQU7cz/dZKpj+ESc3Jb+2t+YpptLxXjF4lKy8zGHYqEwzSJUpcgYWXZjE+Q1Ij8tNvEFUID4W5uBXEpU2r00Ng966t8J4z4OZ97qKtGPX/+Tl3/6aldEU84TycRGsw1H/1xe/HxMXGfqfXia9XC6SV7GKMH08jFUwL6zhndhuQ9JC+upUd2WjURuMMMDOalmCAnFU7PrkqtlnB5xvj3w8QkUd+kilABgPDyhwNoQDnxASkDSofb9NoAMGThU2k4jawC18focGyZBvpVrthEzCys73LIBJBVlh9NgI7sbIdp6B1GNffxYeIuy5dE5H7OcCyCD9Ti/GOpYdZiZ5cPxQIUWkIq5vvSeW/CdfjWfngFadPy5aqJPrgZ8q5thSjsyY6jo+us3SxhQZxQMrnaQGnMeTjXgOucmLWA6xGtXPw4B3QVJWeIheMPt+YWaCh96aCJBxnBBxTNoyG9thOqvL2pm1Y5/ygaat7tuBfVdksCgBnHkKaZtBKEo1+M7HXPddS6IirwrneMQGt2hkoNkoq5Tel0XlRURLON9HRjkLEY70QsCYV8fzGWdDzbXAkCDtsQF9q63WB8NKjkZH2oz9YQJmLOTXW/xsng6nJf4m4HlFm73agCsNCt0PIGX0uXXUtcP0y5oT4LiPKQxF1Ta1bzNRDtVo1gN/bZwZdqqaOjugowJnKww400GR9FAkEBspTVAY/3hLx5EBmSx71ZaJudniRqzs/A5ED9+rIwxhU14fJORoHoEDf2SMOxHhhXr96O7a9SJllGwiSZCDOxly2uhdxwSqtkj85utBEOfpyoIMlQCyv+CQ1ydTmEdjt0mpOc+CQM8iHTpTDP8obv2dYxzqlv8oWSaG43wsMdHvDkMyfbzPt4xxsx0hOILgVNc+85Nei41AinnrWXYS4fv7cbIac6bWf/PsmX27P1smm7PcBsLmqeX+EXWMcspwlVTCczQkVuGV/T7b/l9Y8AAwCSXjehR+kgEQAAAABJRU5ErkJggg==</w:binData>\n        <v:shape id=\"_x0000_i1026\" type=\"#_x0000_t75\" style=\"width:31.5pt;height:31.5pt\">\n          <v:imagedata src=\"wordml://03000015.png\" o:title=\"fa-bicycle\"/>\n        </v:shape>\n      </w:pict>\n    </w:r>\n    <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n      <w:t>INTERESTS</w:t>\n    </w:r>\n  </w:p>\n</wx:pBdrGroup>\n\n  <wx:sub-section>\n\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>reading</w:t>\n      </w:r>\n      <w:r wsp:rsidR=\"00EA0B64\">\n        <w:tab/>\n      </w:r>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>mystery, Agatha Christie, John Grisham</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>hiking</w:t>\n      </w:r>\n    </w:p>\n    <w:p wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\" wsp:rsidRDefault=\"00606071\" wsp:rsidP=\"00E578D4\">\n      <w:pPr>\n        <w:pStyle w:val=\"Heading2\"/>\n        <w:tabs>\n          <w:tab w:val=\"right\" w:pos=\"9360\"/>\n        </w:tabs>\n      </w:pPr>\n      <w:r wsp:rsidR=\"00C146CA\" wsp:rsidRPr=\"00C146CA\">\n        <w:t>yoga</w:t>\n      </w:r>\n    </w:p>\n\n  </wx:sub-section>\n</wx:sub-section>\n\n      \n\n\n      <w:sectPr wsp:rsidR=\"00B43FDC\" wsp:rsidRPr=\"000A3AF0\" wsp:rsidSect=\"001B7422\">\n        <w:pgSz w:w=\"12240\" w:h=\"15840\"/>\n        <w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\" w:header=\"720\" w:footer=\"720\" w:gutter=\"0\"/>\n        <w:cols w:space=\"720\"/>\n        <w:docGrid w:line-pitch=\"360\"/>\n      </w:sectPr>\n    </wx:sect>\n  </w:body>\n</w:wordDocument>\n"
  },
  {
    "path": "test/expected/modern/resume.html",
    "content": "<!DOCTYPE html>\n<html>\n    \n    <head>\n        <meta charset=\"utf-8\">\n        <title>Jane Q. Fullstacker</title>\n        <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic'\n        rel='stylesheet' type='text/css'>\n        <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css\">\n        <style>\n            * {\n              box-sizing: border-box;\n            }\n            \n            main {\n              display: block;\n            }\n            \n            body {\n              font-family: 'Helvetica Neue', 'Helvetica', 'Segoe UI', 'Calibri', 'sans-serif';\n              font-size: 15px;\n              color: #333;\n              line-height: 1.42857143;\n              background-color: #F0F0F0;\n              margin: 0;\n              padding: 0;\n            }\n            \n            /* Typical page borders are awkward when rendered to PDF. */\n            body.pdf {\n              background-color: #FFFFFF;\n            }\n            \n            /* Adobe or wkhtmltopdf has issues with the <main> tag, so we use <div> for\n            the PDF case, <main> for the HTML case, and style both via an ID. */\n            #main {\n              background-color: #FFF;\n              margin: 10px;\n              padding: 10px;\n              border: 1px solid #E6E6E6;\n            }\n            \n            body.pdf > #main {\n              border: none;\n            }\n            \n            #container > header {\n              padding-top: 6em;\n              padding-bottom: 1em;\n            }\n            \n            body.pdf #container > header {\n              padding: 0;\n            }\n            \n            #main > #container > section {\n              margin-left: 5em;\n              position: relative;\n              display: block;\n            }\n            \n            span.fa\n            {\n              position: absolute;\n              top: 4px;\n              left: -50px;\n              font-size: 30px;\n              color: #BFC1C3;\n            }\n            \n            hr {\n              margin-top: 20px;\n              margin-bottom: 20px;\n              border: 0;\n              border-top: 1px solid #EEE;\n            }\n            \n            .tenure, .keywords {\n              font-size: 75%;\n            }\n            \n            h1 {\n              margin: 0;\n              font-size: 46px;\n            }\n            \n            h2 {\n              font-size: 24px;\n              color: #BFC1C3;\n              text-transform: uppercase;\n              font-weight: normal;\n            }\n            \n            h3 {\n              margin-bottom: 0;\n              font-size: 18px;\n            }\n            \n            a, a:visited {\n              color: #428BCA;\n              text-decoration: none;\n              font-weight: bold;\n            }\n            \n            a:hover {\n              text-decoration: underline;\n            }\n            \n            .defunct {\n              color: #989898;\n              font-weight: bold;\n            }\n            \n            #summary > p > strong {\n              font-size: 1.25em;\n            }\n            \n            \n            .label-keyword {\n              display: inline-block;\n              background: #7eb0db;\n              color: white;\n              font-size: 0.9em;\n              padding: 5px;\n              border: 1px solid #357ebd;\n              border-radius: 5px;\n              margin-top: 2px;\n            }\n            \n            .card-skills {\n                position: relative;\n            }\n            .card-nested {\n                min-height: 0;\n                margin-bottom: 10px;\n                border-width: 1px 0 0 0;\n            }\n            .card {\n                background: #FFF;\n                border-radius: 3px;\n                padding: 10px;\n            }\n            \n            .skill-level {\n              border-radius: 3px;\n              position: absolute;\n              top: 10px;\n              bottom: 10px;\n              left: 0;\n              width: 10px;\n              box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);\n            }\n            .skill-level .skill-progress {\n              position: absolute;\n              border-radius: 3px;\n              bottom: 0;\n              width: 100%;\n              -webkit-transition: height 1s ease;\n            }\n            .skill-level .skill-progress.beginner {\n              height: 50%;\n              background: #e74c3c;\n            }\n            .skill-level .skill-progress.intermediate {\n              height: 70%;\n              background: #f1c40f;\n            }\n            .skill-level .skill-progress.advanced {\n              height: 80%;\n              background: #428bca;\n            }\n            .skill-level .skill-progress.master {\n              height: 95%;\n              background: #5cb85c;\n            }\n            .skill-info {\n              margin-left: 10px;\n            }\n            @media (max-width: 480px) {\n              .skill-info {\n                margin-left: 20px;\n              }\n            }\n            \n            .list-unstyled {\n              padding-left: 0;\n              list-style: none;\n            }\n            \n            .card-skills {\n              position: relative;\n            }\n            \n            .space-top {\n                margin-top: 10px;\n            }\n            \n            #container {\n              max-width: 800px;\n              margin: 0 auto;\n            }\n            \n            #elevator-pitch {\n              text-align: center;\n              font-size: 24px;\n              color: #BFC1C3;\n              text-transform: uppercase;\n              font-weight: normal;\n            }\n            \n            .res-label {\n              font-style: italic;\n            }\n        </style>\n    </head>\n    \n    <body>\n        <main id=\"main\">\n            <div id=\"container\">\n                <header>\n                     <h1>Jane Q. Fullstacker</h1>\r\n                    <div id=\"contact\"></div>\n                </header>\n                <hr>\n                <section id=\"summary\">\n                    <header> <span class=\"fa fa-lg fa-info\"></span> \n                         <h2>info</h2>\n\n                    </header> <strong>Imaginary full-stack software developer with 6+ years industry experience</strong> specializing\n                    in cloud-driven web applications and middleware. A native of southern CA,\n                    Jane enjoys hiking, mystery novels, and the company of Rufus, her two year\n                    old beagle.</section>\n                <hr>\n                <section id=\"skills\">\n                    <header>\n                         <h2>Skills</h2>\r\n                    </header> <span class=\"fa fa-lg fa-code\"></span>\r\n                    <ul class=\"list-unstyled\">\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"advanced\" data-placement=\"left\">\n                                <div class=\"skill-progress advanced\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Web</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">JavaScript</span>\r <span class=\"label label-keyword\">HTML 5</span>\r\n                                    <span\n                                    class=\"label label-keyword\">CSS</span> <span class=\"label label-keyword\">LAMP</span>\r <span class=\"label label-keyword\">MVC</span>\r\n                                        <span\n                                        class=\"label label-keyword\">REST</span>\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"master\" data-placement=\"left\">\n                                <div class=\"skill-progress master\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>JavaScript</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">Node.js</span>\r <span class=\"label label-keyword\">Angular.js</span>\r\n                                    <span\n                                    class=\"label label-keyword\">jQuery</span> <span class=\"label label-keyword\">Bootstrap</span>\r <span class=\"label label-keyword\">React.js</span>\r\n                                        <span\n                                        class=\"label label-keyword\">Backbone.js</span>\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"intermediate\" data-placement=\"left\">\n                                <div class=\"skill-progress intermediate\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Database</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">MySQL</span>\r <span class=\"label label-keyword\">PostgreSQL</span>\r\n                                    <span\n                                    class=\"label label-keyword\">NoSQL</span> <span class=\"label label-keyword\">ORM</span>\r <span class=\"label label-keyword\">Hibernate</span>\r\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"intermediate\" data-placement=\"left\">\n                                <div class=\"skill-progress intermediate\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Cloud</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">AWS</span>\r <span class=\"label label-keyword\">EC2</span>\r\n                                    <span\n                                    class=\"label label-keyword\">RDS</span> <span class=\"label label-keyword\">S3</span>\r <span class=\"label label-keyword\">Azure</span>\r\n                                        <span\n                                        class=\"label label-keyword\">Dropbox</span>\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"beginner\" data-placement=\"left\">\n                                <div class=\"skill-progress beginner\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Project</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">Agile</span>\r <span class=\"label label-keyword\">TFS</span>\r\n                                    <span\n                                    class=\"label label-keyword\">JIRA</span> <span class=\"label label-keyword\">GitHub</span>\r <span class=\"label label-keyword\">Unified Process</span>\r\n                                        <span\n                                        class=\"label label-keyword\">MS Project</span>\n                                </div>\n                            </div>\n                        </li>\n                    </ul>\n                </section>\n                <hr>\n                <section id=\"employment\">\n                    <header> <span class=\"fa fa-lg fa-building\"></span> \n                         <h2>employment</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Head Code Ninja</em>,\n\n    <a href=\"https://area52.io/does-not-exist\">Area 52</a>\n\n    </h3>\r <span class=\"tenure\">2013-09 — Present</span>\r| <span class=\"keywords\">Agile PM C C++ R OpenGL Boost MySQL PostgreSQL JIRA </span>\r\n                        <p>\n                            <p>Development team manager for <a href=\"https://en.wikipedia.org/wiki/Vaporware\"><strong>Quantum Diorama</strong></a>,\n                                a distributed molecular modeling and analysis suite for Linux and OS X.</p>\n                        </p>\n                        <ul>\n                            <li>Managed a 5-person development team</li>\n                            <li>Accomplishment 2</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>Principal Developer</em>,\n\n    <a href=\"https://en.wikipedia.org/wiki/Better_Off_Ted#Plot\">Veridian Dynamics</a>\n\n    </h3>\r <span class=\"tenure\">2011-07 — 2013-08</span>\r| <span class=\"keywords\">C++ C Linux R Clojure </span>\r\n                        <p>\n                            <p>Developer on numerous projects culminating in technical lead role for\n                                the <a href=\"http://betteroffted.wikia.com/wiki/Jabberwocky\">Jabberwocky project</a> and\n                                promotion to principal developer.</p>\n                        </p>\n                        <ul>\n                            <li>Managed a 5-person development team</li>\n                            <li>Accomplishment 2</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>IT Administrator</em>,\n\n    Stark Industries\n\n    </h3>\r <span class=\"tenure\">2008-10 — 2011-06</span>\r| <span class=\"keywords\">Novell Active Directory Linux Windows </span>\r\n                        <p>\n                            <p>Junior programmer with heavy code responsibilities. Promoted to intermediate\n                                role after 6 months.</p>\n                        </p>\n                        <ul>\n                            <li>Promoted to intermediate developer after 6 months</li>\n                            <li>Accomplishment 2</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>Intern</em>,\n\n    Dunder Mifflin\n\n    </h3>\r <span class=\"tenure\">2008-06 — 2008-09</span>\r| <span class=\"keywords\">Novell Active Directory Linux Windows </span>\r\n                        <p>\n                            <p>Performed IT administration and deployments for Dunder Mifflin.</p>\n                        </p>\n                        <ul>\n                            <li>Supervised roll-out of Dunder Mifflin Infinity website.</li>\n                            <li>Performed mission-critical system backups and</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"projects\">\n                    <header> <span class=\"fa fa-lg fa-star\"></span> \n                         <h2>projects</h2>\n\n                    </header>\n                    <div>\n                        \n<h3><em>Contributor</em>,\n\n<a href=\"https://fluentdesk.com/hackmyresume\">HackMyResume</a>\n\n</h3>\r\n<span class=\"tenure\">2015-09 — Present</span>\r| <span class=\"keywords\">JavaScript Node.js cross-platform JSON </span>\r\n                        <p>Exemplar user for HackMyResume and FluentCV!</p>\n                    </div>\n                    <div>\n                        \n<h3><em>Co-creator</em>,\n\n<a href=\"http://project.website.com\">Augmented Android</a>\n\n</h3>\r\n<span class=\"tenure\">2012-02 — 2014-01</span>\r| <span class=\"keywords\">Android Java Xamarin </span>\r\n                        <p>Performed flagship product conceptualization and development.</p>\n                    </div>\n                    <div>\n                        \n<h3><em>Creator</em>,\n\n<a href=\"http://myblog.jane.com/blog\">Blog</a>\n\n</h3>\r\n<span class=\"keywords\">Jekyll Ruby HTML 5 JavaScript HTTP LAMP </span>\r\n                        <p>Conceptualization, design, development, and deployment.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"education\">\n                    <header> <span class=\"fa fa-lg fa-mortar-board\"></span> \n                         <h2>education</h2>\n\n                    </header>\n                    <div>\n                        \n<h3><em>BSCS</em>,\n\n<a href=\"https://www.cornell.edu/\">Cornell University</a>\n\n</h3>\r\n<span class=\"tenure\">2005-09 — 2008-05</span>\r| <span class=\"keywords\">Course 1 Course 2 Course 2 </span>\r\n                        <p>A multiline summary of the education.</p>\n                    </div>\n                    <div>\n                        \n<h3>\n\n<a href=\"https://en.wikipedia.org/wiki/Medfield_College\">Medfield College</a>\n\n</h3>\r\n<span class=\"tenure\">2003-09 — 2005-06</span>\r| <span class=\"keywords\">Course 1 Course 2 Course 2 </span>\r\n                        <p>A multiline summary of the education.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"governance\">\n                    <header> <span class=\"fa fa-lg fa-balance-scale\"></span> \n                         <h2>governance</h2>\n\n                    </header>\n                    <div>\n                        \n<h3><em>Member</em>,\n\n<a href=\"http://themommiesnetwork.org\">The Mommies Network</a>\n\n</h3>\r\n<span class=\"tenure\">2008-02 — 2010-01</span>\r\n                        <p>Since 2008 I&#39;ve been a full-time member of the board of directors\n                            for TMN.</p>\n                    </div>\n                    <div>\n                        \n<h3><em>Academic Contributor</em>,\n\n<a href=\"https://www.khronos.org\">Khronos Group</a>\n\n</h3>\r\n<span class=\"tenure\">2015-01 — Present</span>\r\n                        <ul>\n                            <li>Participated in GORFF standardization process (Draft 2).</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"service\">\n                    <header> <span class=\"fa fa-lg fa-child\"></span> \n                         <h2>service</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Technical Consultant</em>,\n      <a href=\"http://technology-for-tots.org\">Technology for Tots</a>\n    </h3>\n <span class=\"tenure\">2003-11 — 2005-06</span>\n\n                        <p>\n                            <p>Summary of this volunteer stint.</p>\n                        </p>\n                        <ul>\n                            <li>Accomplishment 1</li>\n                            <li>Accomplishment 2</li>\n                            <li>etc</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>NCO</em>,\n      <a href=\"http://www.usar.army.mil/\">US Army Reserves</a>\n    </h3>\n <span class=\"tenure\">1999-11 — 2003-06</span>\n\n                        <p>\n                            <p>Summary of this military stint.</p>\n                        </p>\n                        <ul>\n                            <li>Accomplishment 1</li>\n                            <li>Accomplishment 2</li>\n                            <li>etc</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"affiliation\">\n                    <header> <span class=\"fa fa-lg fa-share-alt\"></span> \n                         <h2>affiliation</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Member</em>,\n        <a href=\"https://www.ieee.org/index.html\">IEEE</a>\n        </h3>\n <span class=\"tenure\">2013-06 — Present</span>\n\n                        <p>Member in good standing since 2013-06.</p>\n                    </div>\n                    <div>\n                         <h3><em>Member</em>,\n        <a href=\"https://developer.apple.com/\">Apple Developer Network</a>\n        </h3>\n <span class=\"tenure\">??? — Present</span>\n\n                        <p>Member of the <a href=\"https://developer.apple.com/\">Apple Developer program</a> since\n                            2008.</p>\n                    </div>\n                    <div>\n                         <h3><em>Subscriber</em>,\n        <a href=\"https://msdn.microsoft.com\">MSDN</a>\n        </h3>\n <span class=\"tenure\">2010-01 — Present</span>\n\n                        <p>Super-Ultra-gold level Ultimate Access MSDN subscriber package with subscription\n                            toaster and XBox ping pong racket.</p>\n                    </div>\n                    <div>\n                         <h3><em>Coordinator</em>,\n        Campus Coder&#39;s Meetup\n        </h3>\n <span class=\"tenure\">2003-02 — 2004-04</span>\n\n                        <p>Host of a monthly <strong>campus-wide meetup for CS students</strong>.\n                            Code, coffee, and crullers!</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"samples\">\n                    <header> <span class=\"fa fa-lg fa-share\"></span> \n                         <h2>samples</h2>\n\n                    </header>\n                    <div>\n                         <h3>\n    <a href=\"http://janef.me/asteroids\">Asteroids</a>\n    </h3>\n <span class=\"tenure\">2014-09</span>\n\n                        <p>A browser-based space shooter built on Three.js.</p>\n                    </div>\n                    <div>\n                         <h3>\n    <a href=\"https://rememberpedia.com\">Rememberpedia</a>\n    </h3>\n <span class=\"tenure\">2015-07</span>\n\n                        <p>A website to help you remember things.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"writing\">\n                    <header> <span class=\"fa fa-lg fa-pencil\"></span> \n                         <h2>writing</h2>\n\n                    </header>\n                    <div>\n                         <h3><em><a href=\"http://codeproject.com/build-ui-electron-atom.aspx\">Building User Interfaces with Electron and Atom</a></em>,\n      Code Project</h3>\n <span class=\"tenure\">2011</span>\n\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://janef.me\">Jane Fullstacker&#39;s Blog</a></em>,\n      self</h3>\n <span class=\"tenure\">2011</span>\n\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://url.to.publication.com/blah\">Teach Yourself GORFF in 21 Days</a></em>,\n      Amazon</h3>\n <span class=\"tenure\">2008</span>\n\n                        <p>A primer on the programming language of GORFF, whose for loops are coterminous\n                            with all of time and space.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"reading\">\n                    <header> <span class=\"fa fa-lg fa-book\"></span> \n                         <h2>reading</h2>\n\n                    </header>\n                    <div>\n                         <h3><em><a href=\"https://www.reddit.com/r/programming/\">r/programming</a></em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Daily reader and longtime lurker.</p>\n                    </div>\n                    <div>\n                         <h3><em><a href=\"https://news.ycombinator.com/\">Hacker News / YCombinator</a></em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Daily reader and longtime lurker.</p>\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://www.codinghorror.com\">Coding Horror</a></em>, Jeff Atwood</h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Reader since 2007; member of the StackOverflow Beta.</p>\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://www.cc2e.com/Default.aspx\">Code Complete</a></em>, Steve McConnell</h3>\n <span class=\"tenure\">2014</span>\n\n                        <p>My &#39;desert-island&#39; software construction manual.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"recognition\">\n                    <header> <span class=\"fa fa-lg fa-trophy\"></span> \n                         <h2>recognition</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Honorable Mention</em>, Google</h3>\n <span class=\"tenure\">2012</span>\n\n                    </div>\n                    <div>\n                         <h3><em>Summa cum laude</em>, Cornell University</h3>\n <span class=\"tenure\">2012</span>\n\n                    </div>\n                </section>\n                <hr>\n                <section id=\"speaking\">\n                    <header> <span class=\"fa fa-lg fa-users\"></span> \n                         <h2>speaking</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Data Warehousing Evolved: DARMA 2.0</em>, OPENSTART 2013 Developer&#39;s Conference</h3>\n <span class=\"tenure\">2012</span>\n\n                        <ul>\n                            <li>Won &#39;Best Presentation on an Emerging Technical Field&#39; prize.</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"testimonials\">\n                    <header> <span class=\"fa fa-lg fa-quote-left\"></span> \n                         <h2>testimonials</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>John Davidson</em></h3>\n\n                        <p>Jane is awesome! I&#39;d hire her again in a heartbeat.</p>\n                    </div>\n                    <div>\n                         <h3><em>Dana Nevins</em></h3>\n\n                        <p>I&#39;ve known Jane personally and professionally for almost ten years.\n                            She is one in a million.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"interests\">\n                    <header> <span class=\"fa fa-lg fa-bicycle\"></span> \n                         <h2>interests</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>reading</em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Jane is a fan of mystery novels and courtroom dramas including Agatha\n                            Christie and John Grisham.</p>\n                    </div>\n                    <div>\n                         <h3><em>hiking</em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Jane enjoys hiking, light mountain climbing, and has four summits under\n                            her belt!</p>\n                    </div>\n                    <div>\n                         <h3><em>yoga</em></h3>\n <span class=\"tenure\">Current</span>\n\n                    </div>\n                </section>\n            </div>\n        </main>\n    </body>\n\n</html>"
  },
  {
    "path": "test/expected/modern/resume.json",
    "content": "{\n  \"basics\": {\n    \"name\": \"Jane Q. Fullstacker\",\n    \"label\": \"Senior Developer\",\n    \"summary\": \"**Imaginary full-stack software developer with 6+ years industry experience** specializing in cloud-driven web applications and middleware. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two year old beagle.\",\n    \"website\": \"http://janef.me/blog\",\n    \"phone\": \"1-650-999-7777\",\n    \"email\": \"jdoe@onecoolstartup.io\",\n    \"picture\": \"jane_doe.png\",\n    \"location\": {\n      \"address\": \"Jane Fullstacker\\n123 Somewhere Rd.\\nMountain View, CA 94035\",\n      \"postalCode\": \"94035\",\n      \"city\": \"Mountain View\",\n      \"countryCode\": \"US\",\n      \"region\": \"CA\"\n    },\n    \"profiles\": [\n      {\n        \"network\": \"GitHub\",\n        \"username\": \"janef-was-here\",\n        \"url\": \"https://github.com/janef-was-here\"\n      },\n      {\n        \"network\": \"Twitter\",\n        \"username\": \"janef-was-here\",\n        \"url\": \"https://twitter.com/janef-was-here\"\n      }\n    ]\n  },\n  \"work\": [\n    {\n      \"company\": \"Area 52\",\n      \"website\": \"https://area52.io/does-not-exist\",\n      \"position\": \"Head Code Ninja\",\n      \"startDate\": \"2013-09\",\n      \"summary\": \"Development team manager for [**Quantum Diorama**](https://en.wikipedia.org/wiki/Vaporware), a distributed molecular modeling and analysis suite for Linux and OS X.\",\n      \"highlights\": [\n        \"Managed a 5-person development team\",\n        \"Accomplishment 2\",\n        \"Etc.\"\n      ]\n    },\n    {\n      \"company\": \"Veridian Dynamics\",\n      \"website\": \"https://en.wikipedia.org/wiki/Better_Off_Ted#Plot\",\n      \"position\": \"Principal Developer\",\n      \"startDate\": \"2011-07\",\n      \"endDate\": \"2013-08\",\n      \"summary\": \"Developer on numerous projects culminating in technical lead role for the [Jabberwocky project](http://betteroffted.wikia.com/wiki/Jabberwocky) and promotion to principal developer.\",\n      \"highlights\": [\n        \"Managed a 5-person development team\",\n        \"Accomplishment 2\",\n        \"Etc.\"\n      ]\n    },\n    {\n      \"company\": \"Stark Industries\",\n      \"position\": \"IT Administrator\",\n      \"startDate\": \"2008-10\",\n      \"endDate\": \"2011-06\",\n      \"summary\": \"Junior programmer with heavy code responsibilities. Promoted to intermediate role after 6 months.\",\n      \"highlights\": [\n        \"Promoted to intermediate developer after 6 months\",\n        \"Accomplishment 2\",\n        \"Etc.\"\n      ]\n    },\n    {\n      \"company\": \"Dunder Mifflin\",\n      \"position\": \"Intern\",\n      \"startDate\": \"2008-06\",\n      \"endDate\": \"2008-09\",\n      \"summary\": \"Performed IT administration and deployments for Dunder Mifflin.\",\n      \"highlights\": [\n        \"Supervised roll-out of Dunder Mifflin Infinity website.\",\n        \"Performed mission-critical system backups and \",\n        \"Etc.\"\n      ]\n    }\n  ],\n  \"education\": [\n    {\n      \"institution\": \"Cornell University\",\n      \"gpa\": \"3.5\",\n      \"courses\": [\n        \"Course 1\",\n        \"Course 2\",\n        \"Course 2\"\n      ],\n      \"startDate\": \"2005-09\",\n      \"endDate\": \"2008-05\"\n    },\n    {\n      \"institution\": \"Medfield College\",\n      \"gpa\": \"3.2\",\n      \"courses\": [\n        \"Course 1\",\n        \"Course 2\",\n        \"Course 2\"\n      ],\n      \"startDate\": \"2003-09\",\n      \"endDate\": \"2005-06\"\n    }\n  ],\n  \"skills\": [\n    {\n      \"name\": \"Web\",\n      \"level\": \"advanced\",\n      \"keywords\": [\n        \"JavaScript\",\n        \"HTML 5\",\n        \"CSS\",\n        \"LAMP\",\n        \"MVC\",\n        \"REST\"\n      ]\n    },\n    {\n      \"name\": \"JavaScript\",\n      \"level\": \"master\",\n      \"keywords\": [\n        \"Node.js\",\n        \"Angular.js\",\n        \"jQuery\",\n        \"Bootstrap\",\n        \"React.js\",\n        \"Backbone.js\"\n      ]\n    },\n    {\n      \"name\": \"Database\",\n      \"level\": \"intermediate\",\n      \"keywords\": [\n        \"MySQL\",\n        \"PostgreSQL\",\n        \"NoSQL\",\n        \"ORM\",\n        \"Hibernate\"\n      ]\n    },\n    {\n      \"name\": \"Cloud\",\n      \"level\": \"intermediate\",\n      \"keywords\": [\n        \"AWS\",\n        \"EC2\",\n        \"RDS\",\n        \"S3\",\n        \"Azure\",\n        \"Dropbox\"\n      ]\n    },\n    {\n      \"name\": \"Project\",\n      \"level\": \"beginner\",\n      \"keywords\": [\n        \"Agile\",\n        \"TFS\",\n        \"JIRA\",\n        \"GitHub\",\n        \"Unified Process\",\n        \"MS Project\"\n      ]\n    }\n  ],\n  \"volunteer\": [\n    {\n      \"flavor\": \"volunteer\",\n      \"organization\": \"Technology for Tots\",\n      \"position\": \"Technical Consultant\",\n      \"startDate\": \"2003-11\",\n      \"endDate\": \"2005-06\",\n      \"website\": \"http://technology-for-tots.org\",\n      \"summary\": \"Summary of this volunteer stint.\",\n      \"highlights\": [\n        \"Accomplishment 1\",\n        \"Accomplishment 2\",\n        \"etc\"\n      ]\n    },\n    {\n      \"flavor\": \"military\",\n      \"organization\": \"US Army Reserves\",\n      \"position\": \"NCO\",\n      \"startDate\": \"1999-11\",\n      \"endDate\": \"2003-06\",\n      \"website\": \"http://www.usar.army.mil/\",\n      \"summary\": \"Summary of this military stint.\",\n      \"highlights\": [\n        \"Accomplishment 1\",\n        \"Accomplishment 2\",\n        \"etc\"\n      ]\n    }\n  ],\n  \"awards\": [\n    {\n      \"flavor\": \"award\",\n      \"title\": \"Honorable Mention\",\n      \"date\": \"2012\",\n      \"awarder\": \"Google\"\n    },\n    {\n      \"flavor\": \"honor\",\n      \"title\": \"Summa cum laude\",\n      \"date\": \"2012\",\n      \"awarder\": \"Cornell University\"\n    }\n  ],\n  \"publications\": [\n    {\n      \"name\": \"Building User Interfaces with Electron and Atom\",\n      \"publisher\": \"Code Project\",\n      \"releaseDate\": \"2011\",\n      \"website\": \"http://codeproject.com/build-ui-electron-atom.aspx\"\n    },\n    {\n      \"name\": \"Jane Fullstacker's Blog\",\n      \"publisher\": \"self\",\n      \"releaseDate\": \"2011\",\n      \"website\": \"http://janef.me\"\n    },\n    {\n      \"name\": \"Teach Yourself GORFF in 21 Days\",\n      \"publisher\": \"Amazon\",\n      \"releaseDate\": \"2008\",\n      \"website\": \"http://url.to.publication.com/blah\",\n      \"summary\": \"A primer on the programming language of GORFF, whose for loops are coterminous with all of time and space.\"\n    }\n  ],\n  \"interests\": [\n    {\n      \"name\": \"reading\",\n      \"summary\": \"Jane is a fan of mystery novels and courtroom dramas including Agatha Christie and John Grisham.\",\n      \"keywords\": [\n        \"mystery\",\n        \"Agatha Christie\",\n        \"John Grisham\"\n      ]\n    },\n    {\n      \"name\": \"hiking\",\n      \"summary\": \"Jane enjoys hiking, light mountain climbing, and has four summits under her belt!\"\n    },\n    {\n      \"name\": \"yoga\"\n    }\n  ],\n  \"references\": [\n    {\n      \"name\": \"John Davidson\",\n      \"reference\": \"Jane is awesome! I'd hire her again in a heartbeat.\"\n    },\n    {\n      \"name\": \"Dana Nevins\",\n      \"reference\": \"I've known Jane personally and professionally for almost ten years. She is one in a million.\"\n    }\n  ],\n  \"languages\": [\n    {\n      \"language\": \"English\",\n      \"level\": \"Native\"\n    },\n    {\n      \"language\": \"Spanish\",\n      \"level\": \"Moderate\",\n      \"years\": 10\n    }\n  ],\n  \"projects\": [\n    {\n      \"name\": \"HackMyResume\",\n      \"description\": \"A resume authoring and analysis tool for OS X, Linux, and Windows.\",\n      \"keywords\": [\n        \"JavaScript\",\n        \"Node.js\",\n        \"cross-platform\",\n        \"JSON\"\n      ],\n      \"startDate\": \"2015-09\",\n      \"url\": \"https://fluentdesk.com/hackmyresume\",\n      \"roles\": [\n        \"contributor\"\n      ]\n    },\n    {\n      \"name\": \"Augmented Android\",\n      \"description\": \"An augmented reality app for Android.\",\n      \"keywords\": [\n        \"Android\",\n        \"Java\",\n        \"Xamarin\"\n      ],\n      \"startDate\": \"2012-02\",\n      \"endDate\": \"2014-01\",\n      \"url\": \"http://project.website.com\",\n      \"roles\": [\n        \"co-creator\"\n      ]\n    },\n    {\n      \"name\": \"Blog\",\n      \"description\": \"My programming blog. Powered by Jekyll.\",\n      \"keywords\": [\n        \"Jekyll\",\n        \"Ruby\",\n        \"HTML 5\",\n        \"JavaScript\",\n        \"HTTP\",\n        \"LAMP\"\n      ],\n      \"url\": \"http://myblog.jane.com/blog\",\n      \"roles\": [\n        \"creator\"\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "test/expected/modern/resume.md",
    "content": "Jane Q. Fullstacker\n============\nEmail: jdoe@onecoolstartup.io\nTel: 1-650-999-7777\nWeb: http://janef.me/blog\n\n**Imaginary full-stack software developer with 6+ years industry experience** specializing in cloud-driven web applications and middleware. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two year old beagle.\n\n## SKILLS\n\n  - Web: JavaScript HTML 5 CSS LAMP MVC REST \n  - JavaScript: Node.js Angular.js jQuery Bootstrap React.js Backbone.js \n  - Database: MySQL PostgreSQL NoSQL ORM Hibernate \n  - Cloud: AWS EC2 RDS S3 Azure Dropbox \n  - Project: Agile TFS JIRA GitHub Unified Process MS Project \n\n## EMPLOYMENT\n\n### *Head Code Ninja*, [Area 52](https://area52.io/does-not-exist) (2013-09 — Present)\n\nDevelopment team manager for [**Quantum Diorama**](https://en.wikipedia.org/wiki/Vaporware), a distributed molecular modeling and analysis suite for Linux and OS X.\n  - Managed a 5-person development team\n  - Accomplishment 2\n  - Etc.\n\n### *Principal Developer*, [Veridian Dynamics](https://en.wikipedia.org/wiki/Better_Off_Ted#Plot) (2011-07 — 2013-08)\n\nDeveloper on numerous projects culminating in technical lead role for the [Jabberwocky project](http://betteroffted.wikia.com/wiki/Jabberwocky) and promotion to principal developer.\n  - Managed a 5-person development team\n  - Accomplishment 2\n  - Etc.\n\n### *IT Administrator*, Stark Industries (2008-10 — 2011-06)\n\nJunior programmer with heavy code responsibilities. Promoted to intermediate role after 6 months.\n  - Promoted to intermediate developer after 6 months\n  - Accomplishment 2\n  - Etc.\n\n### *Intern*, Dunder Mifflin (2008-06 — 2008-09)\n\nPerformed IT administration and deployments for Dunder Mifflin.\n  - Supervised roll-out of Dunder Mifflin Infinity website.\n  - Performed mission-critical system backups and \n  - Etc.\n\n\n## PROJECTS\n\n### *Contributor*, [HackMyResume](https://fluentdesk.com/hackmyresume) (2015-09 — Present)\n\nA resume authoring and analysis tool for OS X, Linux, and Windows.\nExemplar user for HackMyResume and FluentCV!\n\n### *Co-creator*, [Augmented Android](http://project.website.com) (2012-02 — 2014-01)\n\nAn augmented reality app for Android.\nPerformed flagship product conceptualization and development.\n\n### *Creator*, [Blog](http://myblog.jane.com/blog) (??? — Present)\n\nMy programming blog. Powered by Jekyll.\nConceptualization, design, development, and deployment.\n\n\n## GOVERNANCE\n\n### *Member*, [The Mommies Network](http://themommiesnetwork.org) \n\nSince 2008 I've been a full-time member of the board of directors for TMN.\n\n### *Academic Contributor*, [Khronos Group](https://www.khronos.org) \n\n- Participated in GORFF standardization process (Draft 2).\n\n\n\n## EDUCATION\n\n### [Cornell University](https://www.cornell.edu/) (2005-09 — 2008-05)\n\nA multiline summary of the education.\n\n\n### [Medfield College](https://en.wikipedia.org/wiki/Medfield_College) (2003-09 — 2005-06)\n\nA multiline summary of the education.\n\n\n\n## AFFILIATION\n\n### *Member*, [IEEE](https://www.ieee.org/index.html) (2013-06 — Present)\n\nMember in good standing since 2013-06.\n\n### *Member*, [Apple Developer Network](https://developer.apple.com/) (??? — Present)\n\nMember of the [Apple Developer program](https://developer.apple.com/) since 2008.\n\n### *Subscriber*, [MSDN](https://msdn.microsoft.com) (2010-01 — Present)\n\nSuper-Ultra-gold level Ultimate Access MSDN subscriber package with subscription toaster and XBox ping pong racket.\n\n### *Coordinator*, Campus Coder's Meetup (2003-02 — 2004-04)\n\nHost of a monthly **campus-wide meetup for CS students**. Code, coffee, and crullers!\n\n\n## SAMPLES\n\n### [Asteroids](http://janef.me/asteroids) (2014-09)\n\nA browser-based space shooter built on Three.js.\n\n### [Rememberpedia](https://rememberpedia.com) (2015-07)\n\nA website to help you remember things.\n\n\n## WRITING\n\n### [Building User Interfaces with Electron and Atom](http://codeproject.com/build-ui-electron-atom.aspx) (2011-01)\n\n\n\n### [Jane Fullstacker's Blog](http://janef.me) (2011-01)\n\n\n\n### [Teach Yourself GORFF in 21 Days](http://url.to.publication.com/blah) (2008-01)\n\nA primer on the programming language of GORFF, whose for loops are coterminous with all of time and space.\n\n\n## READING\n\n### [*r/programming*](https://www.reddit.com/r/programming/)\nDaily reader and longtime lurker.\n\n### [*Hacker News / YCombinator*](https://news.ycombinator.com/)\nDaily reader and longtime lurker.\n\n### [*Coding Horror*](http://www.codinghorror.com), Jeff Atwood\nReader since 2007; member of the StackOverflow Beta.\n\n### [*Code Complete*](http://www.cc2e.com/Default.aspx), Steve McConnell\nMy 'desert-island' software construction manual.\n\n\n## SERVICE\n\n### *Technical Consultant*, [Technology for Tots](http://technology-for-tots.org) (2003-11 — 2005-06)\n\nSummary of this volunteer stint.\n  - Accomplishment 1\n  - Accomplishment 2\n  - etc\n\n### *NCO*, [US Army Reserves](http://www.usar.army.mil/) (1999-11 — 2003-06)\n\nSummary of this military stint.\n  - Accomplishment 1\n  - Accomplishment 2\n  - etc\n\n\n## RECOGNITION\n\n### Honorable Mention, Google (Jan 2012)\n\n### Summa cum laude, Cornell University (Jan 2012)\n\n\n## SPEAKING\n\n### *Data Warehousing Evolved: DARMA 2.0*, OPENSTART 2013 Developer's Conference (2012)\n\n\n  - Won 'Best Presentation on an Emerging Technical Field' prize.\n\n\n\n## INTERESTS\n\n- READING: mystery Agatha Christie John Grisham \nJane is a fan of mystery novels and courtroom dramas including Agatha Christie and John Grisham.\n\n- HIKING\nJane enjoys hiking, light mountain climbing, and has four summits under her belt!\n\n- YOGA\n\n\n"
  },
  {
    "path": "test/expected/modern/resume.pdf.html",
    "content": "\n<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n\n    <title>Jane Q. Fullstacker</title>\n\n    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css\">\n\n\n    <style>* {\n  box-sizing: border-box;\n}\n\nmain {\n  display: block;\n}\n\nbody {\n  font-family: 'Helvetica Neue', 'Helvetica', 'Segoe UI', 'Calibri', 'sans-serif';\n  font-size: 15px;\n  color: #333;\n  line-height: 1.42857143;\n  background-color: #F0F0F0;\n  margin: 0;\n  padding: 0;\n}\n\n/* Typical page borders are awkward when rendered to PDF. */\nbody {\n  background-color: #FFFFFF;\n}\n\n/* Adobe or wkhtmltopdf has issues with the <main> tag, so we use <div> for\nthe PDF case, <main> for the HTML case, and style both via an ID. */\n#main {\n  background-color: #FFF;\n  margin: 10px;\n  padding: 10px;\n  border: 1px solid #E6E6E6;\n}\n\nbody > #main {\n  border: none;\n}\n\n#container > header {\n  padding-top: 6em;\n  padding-bottom: 1em;\n}\n\nbody.pdf #container > header {\n  padding: 0;\n}\n\n#main > #container > section {\n  margin-left: 5em;\n  position: relative;\n  display: block;\n}\n\nspan.fa\n{\n  position: absolute;\n  top: 4px;\n  left: -50px;\n  font-size: 30px;\n  color: #BFC1C3;\n}\n\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #EEE;\n}\n\n.tenure, .keywords {\n  font-size: 75%;\n}\n\nh1 {\n  margin: 0;\n  font-size: 46px;\n}\n\nh2 {\n  font-size: 24px;\n  color: #BFC1C3;\n  text-transform: uppercase;\n  font-weight: normal;\n}\n\nh3 {\n  margin-bottom: 0;\n  font-size: 18px;\n}\n\na, a:visited {\n  color: #428BCA;\n  text-decoration: none;\n  font-weight: bold;\n}\n\na:hover {\n  text-decoration: underline;\n}\n\n.defunct {\n  color: #989898;\n  font-weight: bold;\n}\n\n#summary > p > strong {\n  font-size: 1.25em;\n}\n\n\n.label-keyword {\n  display: inline-block;\n  background: #7eb0db;\n  color: white;\n  font-size: 0.9em;\n  padding: 5px;\n  border: 1px solid #357ebd;\n  border-radius: 5px;\n  margin-top: 2px;\n}\n\n.card-skills {\n    position: relative;\n}\n.card-nested {\n    min-height: 0;\n    margin-bottom: 10px;\n    border-width: 1px 0 0 0;\n}\n.card {\n    background: #FFF;\n    border-radius: 3px;\n    padding: 10px;\n}\n\n.skill-level {\n  border-radius: 3px;\n  position: absolute;\n  top: 10px;\n  bottom: 10px;\n  left: 0;\n  width: 10px;\n  box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);\n}\n.skill-level .skill-progress {\n  position: absolute;\n  border-radius: 3px;\n  bottom: 0;\n  width: 100%;\n  -webkit-transition: height 1s ease;\n}\n.skill-level .skill-progress.beginner {\n  height: 50%;\n  background: #e74c3c;\n}\n.skill-level .skill-progress.intermediate {\n  height: 70%;\n  background: #f1c40f;\n}\n.skill-level .skill-progress.advanced {\n  height: 80%;\n  background: #428bca;\n}\n.skill-level .skill-progress.master {\n  height: 95%;\n  background: #5cb85c;\n}\n.skill-info {\n  margin-left: 10px;\n}\n@media (max-width: 480px) {\n  .skill-info {\n    margin-left: 20px;\n  }\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.card-skills {\n  position: relative;\n}\n\n.space-top {\n    margin-top: 10px;\n}\n\n#container {\n  max-width: 800px;\n  margin: 0 auto;\n}\n\n#elevator-pitch {\n  text-align: center;\n  font-size: 24px;\n  color: #BFC1C3;\n  text-transform: uppercase;\n  font-weight: normal;\n}\n\n.res-label {\n  font-style: italic;\n}\n</style>\n\n\n  </head>\n\n\n  <body>\n    <main id=\"main\"> \n      <div id=\"container\">\n      <header>\n\n\n        <h1>Jane Q. Fullstacker</h1>\n\n        <div id=\"contact\">\n          \n          \n          \n        </div>\n      </header>\n\n\n\n\n<hr>\n<section id=\"summary\">\n    <header>\n      <span class=\"fa fa-lg fa-info\"></span>  <h2>info</h2>\n    </header>\n    <strong>Imaginary full-stack software developer with 6+ years industry experience</strong> specializing in cloud-driven web applications and middleware. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two year old beagle.\n</section>\n\n\n\n\n<hr>\n<section id=\"skills\">\n  <header>\n  <h2>Skills</h2>\n  </header>\n  <span class=\"fa fa-lg fa-code\"></span>\n  <ul class=\"list-unstyled\">\n      <li class=\"card card-nested card-skills\">\n        <div class=\"skill-level\" rel=\"tooltip\" title=\"advanced\" data-placement=\"left\">\n          <div class=\"skill-progress advanced\"></div>\n        </div>\n        <div class=\"skill-info\">\n          <strong>Web</strong>\n          <div class=\"space-top labels\">\n                <span class=\"label label-keyword\">JavaScript</span>\n                <span class=\"label label-keyword\">HTML 5</span>\n                <span class=\"label label-keyword\">CSS</span>\n                <span class=\"label label-keyword\">LAMP</span>\n                <span class=\"label label-keyword\">MVC</span>\n                <span class=\"label label-keyword\">REST</span>\n          </div>\n        </div>\n      </li>\n      <li class=\"card card-nested card-skills\">\n        <div class=\"skill-level\" rel=\"tooltip\" title=\"master\" data-placement=\"left\">\n          <div class=\"skill-progress master\"></div>\n        </div>\n        <div class=\"skill-info\">\n          <strong>JavaScript</strong>\n          <div class=\"space-top labels\">\n                <span class=\"label label-keyword\">Node.js</span>\n                <span class=\"label label-keyword\">Angular.js</span>\n                <span class=\"label label-keyword\">jQuery</span>\n                <span class=\"label label-keyword\">Bootstrap</span>\n                <span class=\"label label-keyword\">React.js</span>\n                <span class=\"label label-keyword\">Backbone.js</span>\n          </div>\n        </div>\n      </li>\n      <li class=\"card card-nested card-skills\">\n        <div class=\"skill-level\" rel=\"tooltip\" title=\"intermediate\" data-placement=\"left\">\n          <div class=\"skill-progress intermediate\"></div>\n        </div>\n        <div class=\"skill-info\">\n          <strong>Database</strong>\n          <div class=\"space-top labels\">\n                <span class=\"label label-keyword\">MySQL</span>\n                <span class=\"label label-keyword\">PostgreSQL</span>\n                <span class=\"label label-keyword\">NoSQL</span>\n                <span class=\"label label-keyword\">ORM</span>\n                <span class=\"label label-keyword\">Hibernate</span>\n          </div>\n        </div>\n      </li>\n      <li class=\"card card-nested card-skills\">\n        <div class=\"skill-level\" rel=\"tooltip\" title=\"intermediate\" data-placement=\"left\">\n          <div class=\"skill-progress intermediate\"></div>\n        </div>\n        <div class=\"skill-info\">\n          <strong>Cloud</strong>\n          <div class=\"space-top labels\">\n                <span class=\"label label-keyword\">AWS</span>\n                <span class=\"label label-keyword\">EC2</span>\n                <span class=\"label label-keyword\">RDS</span>\n                <span class=\"label label-keyword\">S3</span>\n                <span class=\"label label-keyword\">Azure</span>\n                <span class=\"label label-keyword\">Dropbox</span>\n          </div>\n        </div>\n      </li>\n      <li class=\"card card-nested card-skills\">\n        <div class=\"skill-level\" rel=\"tooltip\" title=\"beginner\" data-placement=\"left\">\n          <div class=\"skill-progress beginner\"></div>\n        </div>\n        <div class=\"skill-info\">\n          <strong>Project</strong>\n          <div class=\"space-top labels\">\n                <span class=\"label label-keyword\">Agile</span>\n                <span class=\"label label-keyword\">TFS</span>\n                <span class=\"label label-keyword\">JIRA</span>\n                <span class=\"label label-keyword\">GitHub</span>\n                <span class=\"label label-keyword\">Unified Process</span>\n                <span class=\"label label-keyword\">MS Project</span>\n          </div>\n        </div>\n      </li>\n  </ul>\n</section>\n\n\n\n\n\n\n\n\n\n\n<hr>\n<section id=\"employment\">\n    <header>\n      <span class=\"fa fa-lg fa-building\"></span>  <h2>employment</h2>\n    </header>\n\n<div>\n  <h3><em>Head Code Ninja</em>,\n    <a href=\"https://area52.io/does-not-exist\">Area 52</a>\n    </h3>\n    <span class=\"tenure\">2013-09 — Present</span>\n    | <span class=\"keywords\">Agile PM C C++ R OpenGL Boost MySQL PostgreSQL JIRA </span>\n  <p><p>Development team manager for <a href=\"https://en.wikipedia.org/wiki/Vaporware\"><strong>Quantum Diorama</strong></a>, a distributed molecular modeling and analysis suite for Linux and OS X.</p>\n</p>\n  <ul>\n    <li>Managed a 5-person development team</li>\n    <li>Accomplishment 2</li>\n    <li>Etc.</li>\n  </ul>\n</div>\n<div>\n  <h3><em>Principal Developer</em>,\n    <a href=\"https://en.wikipedia.org/wiki/Better_Off_Ted#Plot\">Veridian Dynamics</a>\n    </h3>\n    <span class=\"tenure\">2011-07 — 2013-08</span>\n    | <span class=\"keywords\">C++ C Linux R Clojure </span>\n  <p><p>Developer on numerous projects culminating in technical lead role for the <a href=\"http://betteroffted.wikia.com/wiki/Jabberwocky\">Jabberwocky project</a> and promotion to principal developer.</p>\n</p>\n  <ul>\n    <li>Managed a 5-person development team</li>\n    <li>Accomplishment 2</li>\n    <li>Etc.</li>\n  </ul>\n</div>\n<div>\n  <h3><em>IT Administrator</em>,\n    Stark Industries\n    </h3>\n    <span class=\"tenure\">2008-10 — 2011-06</span>\n    | <span class=\"keywords\">Novell Active Directory Linux Windows </span>\n  <p><p>Junior programmer with heavy code responsibilities. Promoted to intermediate role after 6 months.</p>\n</p>\n  <ul>\n    <li>Promoted to intermediate developer after 6 months</li>\n    <li>Accomplishment 2</li>\n    <li>Etc.</li>\n  </ul>\n</div>\n<div>\n  <h3><em>Intern</em>,\n    Dunder Mifflin\n    </h3>\n    <span class=\"tenure\">2008-06 — 2008-09</span>\n    | <span class=\"keywords\">Novell Active Directory Linux Windows </span>\n  <p><p>Performed IT administration and deployments for Dunder Mifflin.</p>\n</p>\n  <ul>\n    <li>Supervised roll-out of Dunder Mifflin Infinity website.</li>\n    <li>Performed mission-critical system backups and </li>\n    <li>Etc.</li>\n  </ul>\n</div>\n</section>\n\n\n\n\n\n\n\n<hr>\n<section id=\"projects\">\n    <header>\n      <span class=\"fa fa-lg fa-star\"></span>  <h2>projects</h2>\n    </header>\n<div>\n<h3><em>Contributor</em>,\n<a href=\"https://fluentdesk.com/hackmyresume\">HackMyResume</a>\n</h3>\n<span class=\"tenure\">2015-09 — Present</span>\n| <span class=\"keywords\">JavaScript Node.js cross-platform JSON </span>\n<p>Exemplar user for HackMyResume and FluentCV!</p>\n\n</div>\n<div>\n<h3><em>Co-creator</em>,\n<a href=\"http://project.website.com\">Augmented Android</a>\n</h3>\n<span class=\"tenure\">2012-02 — 2014-01</span>\n| <span class=\"keywords\">Android Java Xamarin </span>\n<p>Performed flagship product conceptualization and development.</p>\n\n</div>\n<div>\n<h3><em>Creator</em>,\n<a href=\"http://myblog.jane.com/blog\">Blog</a>\n</h3>\n\n<span class=\"keywords\">Jekyll Ruby HTML 5 JavaScript HTTP LAMP </span>\n<p>Conceptualization, design, development, and deployment.</p>\n\n</div>\n</section>\n\n\n\n\n\n\n<hr>\n<section id=\"education\">\n    <header>\n      <span class=\"fa fa-lg fa-mortar-board\"></span>  <h2>education</h2>\n    </header>\n<div>\n<h3><em>BSCS</em>,\n<a href=\"https://www.cornell.edu/\">Cornell University</a>\n</h3>\n<span class=\"tenure\">2005-09 — 2008-05</span>\n| <span class=\"keywords\">Course 1 Course 2 Course 2 </span>\n<p>A multiline summary of the education.</p>\n\n</div>\n<div>\n<h3>\n<a href=\"https://en.wikipedia.org/wiki/Medfield_College\">Medfield College</a>\n</h3>\n<span class=\"tenure\">2003-09 — 2005-06</span>\n| <span class=\"keywords\">Course 1 Course 2 Course 2 </span>\n<p>A multiline summary of the education.</p>\n\n</div>\n</section>\n\n\n\n\n\n\n<hr>\n<section id=\"governance\">\n    <header>\n      <span class=\"fa fa-lg fa-balance-scale\"></span>  <h2>governance</h2>\n    </header>\n\n<div>\n<h3><em>Member</em>,\n<a href=\"http://themommiesnetwork.org\">The Mommies Network</a>\n</h3>\n<span class=\"tenure\">2008-02 — 2010-01</span>\n<p>Since 2008 I&#39;ve been a full-time member of the board of directors for TMN.</p>\n\n</div>\n<div>\n<h3><em>Academic Contributor</em>,\n<a href=\"https://www.khronos.org\">Khronos Group</a>\n</h3>\n<span class=\"tenure\">2015-01 — Present</span>\n\n<ul>\n  <li>Participated in GORFF standardization process (Draft 2).</li>\n</ul>\n</div>\n</section>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<hr>\n<section id=\"service\">\n    <header>\n      <span class=\"fa fa-lg fa-child\"></span>  <h2>service</h2>\n    </header>\n    <div>\n    <h3><em>Technical Consultant</em>,\n      <a href=\"http://technology-for-tots.org\">Technology for Tots</a>\n    </h3>\n    <span class=\"tenure\">2003-11 — 2005-06</span>\n    <p><p>Summary of this volunteer stint.</p>\n</p>\n    <ul>\n      <li>Accomplishment 1</li>\n      <li>Accomplishment 2</li>\n      <li>etc</li>\n    </ul>\n    </div>\n    <div>\n    <h3><em>NCO</em>,\n      <a href=\"http://www.usar.army.mil/\">US Army Reserves</a>\n    </h3>\n    <span class=\"tenure\">1999-11 — 2003-06</span>\n    <p><p>Summary of this military stint.</p>\n</p>\n    <ul>\n      <li>Accomplishment 1</li>\n      <li>Accomplishment 2</li>\n      <li>etc</li>\n    </ul>\n    </div>\n</section>\n<hr>\n<section id=\"affiliation\">\n    <header>\n      <span class=\"fa fa-lg fa-share-alt\"></span>  <h2>affiliation</h2>\n    </header>\n\n    <div>\n      <h3><em>Member</em>,\n        <a href=\"https://www.ieee.org/index.html\">IEEE</a>\n        </h3>\n        <span class=\"tenure\">2013-06 — Present</span>\n      <p>Member in good standing since 2013-06.</p>\n\n      \n    </div>\n    <div>\n      <h3><em>Member</em>,\n        <a href=\"https://developer.apple.com/\">Apple Developer Network</a>\n        </h3>\n        <span class=\"tenure\">??? — Present</span>\n      <p>Member of the <a href=\"https://developer.apple.com/\">Apple Developer program</a> since 2008.</p>\n\n      \n    </div>\n    <div>\n      <h3><em>Subscriber</em>,\n        <a href=\"https://msdn.microsoft.com\">MSDN</a>\n        </h3>\n        <span class=\"tenure\">2010-01 — Present</span>\n      <p>Super-Ultra-gold level Ultimate Access MSDN subscriber package with subscription toaster and XBox ping pong racket.</p>\n\n      \n    </div>\n    <div>\n      <h3><em>Coordinator</em>,\n        Campus Coder&#39;s Meetup\n        </h3>\n        <span class=\"tenure\">2003-02 — 2004-04</span>\n      <p>Host of a monthly <strong>campus-wide meetup for CS students</strong>. Code, coffee, and crullers!</p>\n\n      \n    </div>\n</section>\n<hr>\n<section id=\"samples\">\n    <header>\n      <span class=\"fa fa-lg fa-share\"></span>  <h2>samples</h2>\n    </header>\n    <div>\n    <h3>\n    <a href=\"http://janef.me/asteroids\">Asteroids</a>\n    </h3>\n    <span class=\"tenure\">2014-09</span>\n    <p>A browser-based space shooter built on Three.js.</p>\n\n    </div>\n    <div>\n    <h3>\n    <a href=\"https://rememberpedia.com\">Rememberpedia</a>\n    </h3>\n    <span class=\"tenure\">2015-07</span>\n    <p>A website to help you remember things.</p>\n\n    </div>\n</section>\n<hr>\n<section id=\"writing\">\n    <header>\n      <span class=\"fa fa-lg fa-pencil\"></span>  <h2>writing</h2>\n    </header>\n    <div>\n    <h3><em><a href=\"http://codeproject.com/build-ui-electron-atom.aspx\">Building User Interfaces with Electron and Atom</a></em>,\n      Code Project</h3>\n      <span class=\"tenure\">2011</span>\n      \n    </div>\n    <div>\n    <h3><em><a href=\"http://janef.me\">Jane Fullstacker&#39;s Blog</a></em>,\n      self</h3>\n      <span class=\"tenure\">2011</span>\n      \n    </div>\n    <div>\n    <h3><em><a href=\"http://url.to.publication.com/blah\">Teach Yourself GORFF in 21 Days</a></em>,\n      Amazon</h3>\n      <span class=\"tenure\">2008</span>\n      <p>A primer on the programming language of GORFF, whose for loops are coterminous with all of time and space.</p>\n\n    </div>\n</section>\n<hr>\n<section id=\"reading\">\n    <header>\n      <span class=\"fa fa-lg fa-book\"></span>  <h2>reading</h2>\n    </header>\n    <div>\n    <h3><em><a href=\"https://www.reddit.com/r/programming/\">r/programming</a></em></h3>\n      <span class=\"tenure\">Current</span>\n      <p>Daily reader and longtime lurker.</p>\n\n    </div>\n    <div>\n    <h3><em><a href=\"https://news.ycombinator.com/\">Hacker News / YCombinator</a></em></h3>\n      <span class=\"tenure\">Current</span>\n      <p>Daily reader and longtime lurker.</p>\n\n    </div>\n    <div>\n    <h3><em><a href=\"http://www.codinghorror.com\">Coding Horror</a></em>, Jeff Atwood</h3>\n      <span class=\"tenure\">Current</span>\n      <p>Reader since 2007; member of the StackOverflow Beta.</p>\n\n    </div>\n    <div>\n    <h3><em><a href=\"http://www.cc2e.com/Default.aspx\">Code Complete</a></em>, Steve McConnell</h3>\n      <span class=\"tenure\">2014</span>\n      <p>My &#39;desert-island&#39; software construction manual.</p>\n\n    </div>\n</section>\n<hr>\n<section id=\"recognition\">\n    <header>\n      <span class=\"fa fa-lg fa-trophy\"></span>  <h2>recognition</h2>\n    </header>\n    <div>\n    <h3><em>Honorable Mention</em>, Google</h3>\n    <span class=\"tenure\">2012</span>\n    \n    </div>\n    <div>\n    <h3><em>Summa cum laude</em>, Cornell University</h3>\n    <span class=\"tenure\">2012</span>\n    \n    </div>\n</section>\n<hr>\n<section id=\"speaking\">\n    <header>\n      <span class=\"fa fa-lg fa-users\"></span>  <h2>speaking</h2>\n    </header>\n    <div>\n    <h3><em>Data Warehousing Evolved: DARMA 2.0</em>, OPENSTART 2013 Developer&#39;s Conference</h3>\n    <span class=\"tenure\">2012</span>\n    \n    <ul>\n      <li>Won &#39;Best Presentation on an Emerging Technical Field&#39; prize.</li>\n    </ul>\n    </div>\n</section>\n<hr>\n<section id=\"testimonials\">\n    <header>\n      <span class=\"fa fa-lg fa-quote-left\"></span>  <h2>testimonials</h2>\n    </header>\n    <div>\n    <h3><em>John Davidson</em></h3>\n    <p>Jane is awesome! I&#39;d hire her again in a heartbeat.</p>\n    </div>\n    <div>\n    <h3><em>Dana Nevins</em></h3>\n    <p>I&#39;ve known Jane personally and professionally for almost ten years. She is one in a million.</p>\n    </div>\n</section>\n<hr>\n<section id=\"interests\">\n    <header>\n      <span class=\"fa fa-lg fa-bicycle\"></span>  <h2>interests</h2>\n    </header>\n    <div>\n    <h3><em>reading</em></h3>\n    <span class=\"tenure\">Current</span>\n    <p>Jane is a fan of mystery novels and courtroom dramas including Agatha Christie and John Grisham.</p>\n\n    </div>\n    <div>\n    <h3><em>hiking</em></h3>\n    <span class=\"tenure\">Current</span>\n    <p>Jane enjoys hiking, light mountain climbing, and has four summits under her belt!</p>\n\n    </div>\n    <div>\n    <h3><em>yoga</em></h3>\n    <span class=\"tenure\">Current</span>\n    \n    </div>\n</section>\n\n      </div>\n    </main>\n  </body>\n</html>\n"
  },
  {
    "path": "test/expected/modern/resume.png.html",
    "content": "<!DOCTYPE html>\n<html>\n    \n    <head>\n        <meta charset=\"utf-8\">\n        <title>Jane Q. Fullstacker</title>\n        <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic'\n        rel='stylesheet' type='text/css'>\n        <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css\">\n        <style>\n            * {\n              box-sizing: border-box;\n            }\n            \n            main {\n              display: block;\n            }\n            \n            body {\n              font-family: 'Helvetica Neue', 'Helvetica', 'Segoe UI', 'Calibri', 'sans-serif';\n              font-size: 15px;\n              color: #333;\n              line-height: 1.42857143;\n              background-color: #F0F0F0;\n              margin: 0;\n              padding: 0;\n            }\n            \n            /* Typical page borders are awkward when rendered to PDF. */\n            body.pdf {\n              background-color: #FFFFFF;\n            }\n            \n            /* Adobe or wkhtmltopdf has issues with the <main> tag, so we use <div> for\n            the PDF case, <main> for the HTML case, and style both via an ID. */\n            #main {\n              background-color: #FFF;\n              margin: 10px;\n              padding: 10px;\n              border: 1px solid #E6E6E6;\n            }\n            \n            body.pdf > #main {\n              border: none;\n            }\n            \n            #container > header {\n              padding-top: 6em;\n              padding-bottom: 1em;\n            }\n            \n            body.pdf #container > header {\n              padding: 0;\n            }\n            \n            #main > #container > section {\n              margin-left: 5em;\n              position: relative;\n              display: block;\n            }\n            \n            span.fa\n            {\n              position: absolute;\n              top: 4px;\n              left: -50px;\n              font-size: 30px;\n              color: #BFC1C3;\n            }\n            \n            hr {\n              margin-top: 20px;\n              margin-bottom: 20px;\n              border: 0;\n              border-top: 1px solid #EEE;\n            }\n            \n            .tenure, .keywords {\n              font-size: 75%;\n            }\n            \n            h1 {\n              margin: 0;\n              font-size: 46px;\n            }\n            \n            h2 {\n              font-size: 24px;\n              color: #BFC1C3;\n              text-transform: uppercase;\n              font-weight: normal;\n            }\n            \n            h3 {\n              margin-bottom: 0;\n              font-size: 18px;\n            }\n            \n            a, a:visited {\n              color: #428BCA;\n              text-decoration: none;\n              font-weight: bold;\n            }\n            \n            a:hover {\n              text-decoration: underline;\n            }\n            \n            .defunct {\n              color: #989898;\n              font-weight: bold;\n            }\n            \n            #summary > p > strong {\n              font-size: 1.25em;\n            }\n            \n            \n            .label-keyword {\n              display: inline-block;\n              background: #7eb0db;\n              color: white;\n              font-size: 0.9em;\n              padding: 5px;\n              border: 1px solid #357ebd;\n              border-radius: 5px;\n              margin-top: 2px;\n            }\n            \n            .card-skills {\n                position: relative;\n            }\n            .card-nested {\n                min-height: 0;\n                margin-bottom: 10px;\n                border-width: 1px 0 0 0;\n            }\n            .card {\n                background: #FFF;\n                border-radius: 3px;\n                padding: 10px;\n            }\n            \n            .skill-level {\n              border-radius: 3px;\n              position: absolute;\n              top: 10px;\n              bottom: 10px;\n              left: 0;\n              width: 10px;\n              box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);\n            }\n            .skill-level .skill-progress {\n              position: absolute;\n              border-radius: 3px;\n              bottom: 0;\n              width: 100%;\n              -webkit-transition: height 1s ease;\n            }\n            .skill-level .skill-progress.beginner {\n              height: 50%;\n              background: #e74c3c;\n            }\n            .skill-level .skill-progress.intermediate {\n              height: 70%;\n              background: #f1c40f;\n            }\n            .skill-level .skill-progress.advanced {\n              height: 80%;\n              background: #428bca;\n            }\n            .skill-level .skill-progress.master {\n              height: 95%;\n              background: #5cb85c;\n            }\n            .skill-info {\n              margin-left: 10px;\n            }\n            @media (max-width: 480px) {\n              .skill-info {\n                margin-left: 20px;\n              }\n            }\n            \n            .list-unstyled {\n              padding-left: 0;\n              list-style: none;\n            }\n            \n            .card-skills {\n              position: relative;\n            }\n            \n            .space-top {\n                margin-top: 10px;\n            }\n            \n            #container {\n              max-width: 800px;\n              margin: 0 auto;\n            }\n            \n            #elevator-pitch {\n              text-align: center;\n              font-size: 24px;\n              color: #BFC1C3;\n              text-transform: uppercase;\n              font-weight: normal;\n            }\n            \n            .res-label {\n              font-style: italic;\n            }\n        </style>\n    </head>\n    \n    <body>\n        <main id=\"main\">\n            <div id=\"container\">\n                <header>\n                     <h1>Jane Q. Fullstacker</h1>\r\n                    <div id=\"contact\"></div>\n                </header>\n                <hr>\n                <section id=\"summary\">\n                    <header> <span class=\"fa fa-lg fa-info\"></span> \n                         <h2>info</h2>\n\n                    </header> <strong>Imaginary full-stack software developer with 6+ years industry experience</strong> specializing\n                    in cloud-driven web applications and middleware. A native of southern CA,\n                    Jane enjoys hiking, mystery novels, and the company of Rufus, her two year\n                    old beagle.</section>\n                <hr>\n                <section id=\"skills\">\n                    <header>\n                         <h2>Skills</h2>\r\n                    </header> <span class=\"fa fa-lg fa-code\"></span>\r\n                    <ul class=\"list-unstyled\">\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"advanced\" data-placement=\"left\">\n                                <div class=\"skill-progress advanced\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Web</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">JavaScript</span>\r <span class=\"label label-keyword\">HTML 5</span>\r\n                                    <span\n                                    class=\"label label-keyword\">CSS</span> <span class=\"label label-keyword\">LAMP</span>\r <span class=\"label label-keyword\">MVC</span>\r\n                                        <span\n                                        class=\"label label-keyword\">REST</span>\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"master\" data-placement=\"left\">\n                                <div class=\"skill-progress master\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>JavaScript</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">Node.js</span>\r <span class=\"label label-keyword\">Angular.js</span>\r\n                                    <span\n                                    class=\"label label-keyword\">jQuery</span> <span class=\"label label-keyword\">Bootstrap</span>\r <span class=\"label label-keyword\">React.js</span>\r\n                                        <span\n                                        class=\"label label-keyword\">Backbone.js</span>\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"intermediate\" data-placement=\"left\">\n                                <div class=\"skill-progress intermediate\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Database</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">MySQL</span>\r <span class=\"label label-keyword\">PostgreSQL</span>\r\n                                    <span\n                                    class=\"label label-keyword\">NoSQL</span> <span class=\"label label-keyword\">ORM</span>\r <span class=\"label label-keyword\">Hibernate</span>\r\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"intermediate\" data-placement=\"left\">\n                                <div class=\"skill-progress intermediate\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Cloud</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">AWS</span>\r <span class=\"label label-keyword\">EC2</span>\r\n                                    <span\n                                    class=\"label label-keyword\">RDS</span> <span class=\"label label-keyword\">S3</span>\r <span class=\"label label-keyword\">Azure</span>\r\n                                        <span\n                                        class=\"label label-keyword\">Dropbox</span>\n                                </div>\n                            </div>\n                        </li>\n                        <li class=\"card card-nested card-skills\">\n                            <div class=\"skill-level\" rel=\"tooltip\" title=\"beginner\" data-placement=\"left\">\n                                <div class=\"skill-progress beginner\"></div>\n                            </div>\n                            <div class=\"skill-info\"> <strong>Project</strong>\r\n                                <div class=\"space-top labels\"> <span class=\"label label-keyword\">Agile</span>\r <span class=\"label label-keyword\">TFS</span>\r\n                                    <span\n                                    class=\"label label-keyword\">JIRA</span> <span class=\"label label-keyword\">GitHub</span>\r <span class=\"label label-keyword\">Unified Process</span>\r\n                                        <span\n                                        class=\"label label-keyword\">MS Project</span>\n                                </div>\n                            </div>\n                        </li>\n                    </ul>\n                </section>\n                <hr>\n                <section id=\"employment\">\n                    <header> <span class=\"fa fa-lg fa-building\"></span> \n                         <h2>employment</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Head Code Ninja</em>,\n\n    <a href=\"https://area52.io/does-not-exist\">Area 52</a>\n\n    </h3>\r <span class=\"tenure\">2013-09 — Present</span>\r| <span class=\"keywords\">Agile PM C C++ R OpenGL Boost MySQL PostgreSQL JIRA </span>\r\n                        <p>\n                            <p>Development team manager for <a href=\"https://en.wikipedia.org/wiki/Vaporware\"><strong>Quantum Diorama</strong></a>,\n                                a distributed molecular modeling and analysis suite for Linux and OS X.</p>\n                        </p>\n                        <ul>\n                            <li>Managed a 5-person development team</li>\n                            <li>Accomplishment 2</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>Principal Developer</em>,\n\n    <a href=\"https://en.wikipedia.org/wiki/Better_Off_Ted#Plot\">Veridian Dynamics</a>\n\n    </h3>\r <span class=\"tenure\">2011-07 — 2013-08</span>\r| <span class=\"keywords\">C++ C Linux R Clojure </span>\r\n                        <p>\n                            <p>Developer on numerous projects culminating in technical lead role for\n                                the <a href=\"http://betteroffted.wikia.com/wiki/Jabberwocky\">Jabberwocky project</a> and\n                                promotion to principal developer.</p>\n                        </p>\n                        <ul>\n                            <li>Managed a 5-person development team</li>\n                            <li>Accomplishment 2</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>IT Administrator</em>,\n\n    Stark Industries\n\n    </h3>\r <span class=\"tenure\">2008-10 — 2011-06</span>\r| <span class=\"keywords\">Novell Active Directory Linux Windows </span>\r\n                        <p>\n                            <p>Junior programmer with heavy code responsibilities. Promoted to intermediate\n                                role after 6 months.</p>\n                        </p>\n                        <ul>\n                            <li>Promoted to intermediate developer after 6 months</li>\n                            <li>Accomplishment 2</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>Intern</em>,\n\n    Dunder Mifflin\n\n    </h3>\r <span class=\"tenure\">2008-06 — 2008-09</span>\r| <span class=\"keywords\">Novell Active Directory Linux Windows </span>\r\n                        <p>\n                            <p>Performed IT administration and deployments for Dunder Mifflin.</p>\n                        </p>\n                        <ul>\n                            <li>Supervised roll-out of Dunder Mifflin Infinity website.</li>\n                            <li>Performed mission-critical system backups and</li>\n                            <li>Etc.</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"projects\">\n                    <header> <span class=\"fa fa-lg fa-star\"></span> \n                         <h2>projects</h2>\n\n                    </header>\n                    <div>\n                        \n<h3><em>Contributor</em>,\n\n<a href=\"https://fluentdesk.com/hackmyresume\">HackMyResume</a>\n\n</h3>\r\n<span class=\"tenure\">2015-09 — Present</span>\r| <span class=\"keywords\">JavaScript Node.js cross-platform JSON </span>\r\n                        <p>Exemplar user for HackMyResume and FluentCV!</p>\n                    </div>\n                    <div>\n                        \n<h3><em>Co-creator</em>,\n\n<a href=\"http://project.website.com\">Augmented Android</a>\n\n</h3>\r\n<span class=\"tenure\">2012-02 — 2014-01</span>\r| <span class=\"keywords\">Android Java Xamarin </span>\r\n                        <p>Performed flagship product conceptualization and development.</p>\n                    </div>\n                    <div>\n                        \n<h3><em>Creator</em>,\n\n<a href=\"http://myblog.jane.com/blog\">Blog</a>\n\n</h3>\r\n<span class=\"keywords\">Jekyll Ruby HTML 5 JavaScript HTTP LAMP </span>\r\n                        <p>Conceptualization, design, development, and deployment.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"education\">\n                    <header> <span class=\"fa fa-lg fa-mortar-board\"></span> \n                         <h2>education</h2>\n\n                    </header>\n                    <div>\n                        \n<h3><em>BSCS</em>,\n\n<a href=\"https://www.cornell.edu/\">Cornell University</a>\n\n</h3>\r\n<span class=\"tenure\">2005-09 — 2008-05</span>\r| <span class=\"keywords\">Course 1 Course 2 Course 2 </span>\r\n                        <p>A multiline summary of the education.</p>\n                    </div>\n                    <div>\n                        \n<h3>\n\n<a href=\"https://en.wikipedia.org/wiki/Medfield_College\">Medfield College</a>\n\n</h3>\r\n<span class=\"tenure\">2003-09 — 2005-06</span>\r| <span class=\"keywords\">Course 1 Course 2 Course 2 </span>\r\n                        <p>A multiline summary of the education.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"governance\">\n                    <header> <span class=\"fa fa-lg fa-balance-scale\"></span> \n                         <h2>governance</h2>\n\n                    </header>\n                    <div>\n                        \n<h3><em>Member</em>,\n\n<a href=\"http://themommiesnetwork.org\">The Mommies Network</a>\n\n</h3>\r\n<span class=\"tenure\">2008-02 — 2010-01</span>\r\n                        <p>Since 2008 I&#39;ve been a full-time member of the board of directors\n                            for TMN.</p>\n                    </div>\n                    <div>\n                        \n<h3><em>Academic Contributor</em>,\n\n<a href=\"https://www.khronos.org\">Khronos Group</a>\n\n</h3>\r\n<span class=\"tenure\">2015-01 — Present</span>\r\n                        <ul>\n                            <li>Participated in GORFF standardization process (Draft 2).</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"service\">\n                    <header> <span class=\"fa fa-lg fa-child\"></span> \n                         <h2>service</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Technical Consultant</em>,\n      <a href=\"http://technology-for-tots.org\">Technology for Tots</a>\n    </h3>\n <span class=\"tenure\">2003-11 — 2005-06</span>\n\n                        <p>\n                            <p>Summary of this volunteer stint.</p>\n                        </p>\n                        <ul>\n                            <li>Accomplishment 1</li>\n                            <li>Accomplishment 2</li>\n                            <li>etc</li>\n                        </ul>\n                    </div>\n                    <div>\n                         <h3><em>NCO</em>,\n      <a href=\"http://www.usar.army.mil/\">US Army Reserves</a>\n    </h3>\n <span class=\"tenure\">1999-11 — 2003-06</span>\n\n                        <p>\n                            <p>Summary of this military stint.</p>\n                        </p>\n                        <ul>\n                            <li>Accomplishment 1</li>\n                            <li>Accomplishment 2</li>\n                            <li>etc</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"affiliation\">\n                    <header> <span class=\"fa fa-lg fa-share-alt\"></span> \n                         <h2>affiliation</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Member</em>,\n        <a href=\"https://www.ieee.org/index.html\">IEEE</a>\n        </h3>\n <span class=\"tenure\">2013-06 — Present</span>\n\n                        <p>Member in good standing since 2013-06.</p>\n                    </div>\n                    <div>\n                         <h3><em>Member</em>,\n        <a href=\"https://developer.apple.com/\">Apple Developer Network</a>\n        </h3>\n <span class=\"tenure\">??? — Present</span>\n\n                        <p>Member of the <a href=\"https://developer.apple.com/\">Apple Developer program</a> since\n                            2008.</p>\n                    </div>\n                    <div>\n                         <h3><em>Subscriber</em>,\n        <a href=\"https://msdn.microsoft.com\">MSDN</a>\n        </h3>\n <span class=\"tenure\">2010-01 — Present</span>\n\n                        <p>Super-Ultra-gold level Ultimate Access MSDN subscriber package with subscription\n                            toaster and XBox ping pong racket.</p>\n                    </div>\n                    <div>\n                         <h3><em>Coordinator</em>,\n        Campus Coder&#39;s Meetup\n        </h3>\n <span class=\"tenure\">2003-02 — 2004-04</span>\n\n                        <p>Host of a monthly <strong>campus-wide meetup for CS students</strong>.\n                            Code, coffee, and crullers!</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"samples\">\n                    <header> <span class=\"fa fa-lg fa-share\"></span> \n                         <h2>samples</h2>\n\n                    </header>\n                    <div>\n                         <h3>\n    <a href=\"http://janef.me/asteroids\">Asteroids</a>\n    </h3>\n <span class=\"tenure\">2014-09</span>\n\n                        <p>A browser-based space shooter built on Three.js.</p>\n                    </div>\n                    <div>\n                         <h3>\n    <a href=\"https://rememberpedia.com\">Rememberpedia</a>\n    </h3>\n <span class=\"tenure\">2015-07</span>\n\n                        <p>A website to help you remember things.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"writing\">\n                    <header> <span class=\"fa fa-lg fa-pencil\"></span> \n                         <h2>writing</h2>\n\n                    </header>\n                    <div>\n                         <h3><em><a href=\"http://codeproject.com/build-ui-electron-atom.aspx\">Building User Interfaces with Electron and Atom</a></em>,\n      Code Project</h3>\n <span class=\"tenure\">2011</span>\n\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://janef.me\">Jane Fullstacker&#39;s Blog</a></em>,\n      self</h3>\n <span class=\"tenure\">2011</span>\n\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://url.to.publication.com/blah\">Teach Yourself GORFF in 21 Days</a></em>,\n      Amazon</h3>\n <span class=\"tenure\">2008</span>\n\n                        <p>A primer on the programming language of GORFF, whose for loops are coterminous\n                            with all of time and space.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"reading\">\n                    <header> <span class=\"fa fa-lg fa-book\"></span> \n                         <h2>reading</h2>\n\n                    </header>\n                    <div>\n                         <h3><em><a href=\"https://www.reddit.com/r/programming/\">r/programming</a></em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Daily reader and longtime lurker.</p>\n                    </div>\n                    <div>\n                         <h3><em><a href=\"https://news.ycombinator.com/\">Hacker News / YCombinator</a></em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Daily reader and longtime lurker.</p>\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://www.codinghorror.com\">Coding Horror</a></em>, Jeff Atwood</h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Reader since 2007; member of the StackOverflow Beta.</p>\n                    </div>\n                    <div>\n                         <h3><em><a href=\"http://www.cc2e.com/Default.aspx\">Code Complete</a></em>, Steve McConnell</h3>\n <span class=\"tenure\">2014</span>\n\n                        <p>My &#39;desert-island&#39; software construction manual.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"recognition\">\n                    <header> <span class=\"fa fa-lg fa-trophy\"></span> \n                         <h2>recognition</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Honorable Mention</em>, Google</h3>\n <span class=\"tenure\">2012</span>\n\n                    </div>\n                    <div>\n                         <h3><em>Summa cum laude</em>, Cornell University</h3>\n <span class=\"tenure\">2012</span>\n\n                    </div>\n                </section>\n                <hr>\n                <section id=\"speaking\">\n                    <header> <span class=\"fa fa-lg fa-users\"></span> \n                         <h2>speaking</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>Data Warehousing Evolved: DARMA 2.0</em>, OPENSTART 2013 Developer&#39;s Conference</h3>\n <span class=\"tenure\">2012</span>\n\n                        <ul>\n                            <li>Won &#39;Best Presentation on an Emerging Technical Field&#39; prize.</li>\n                        </ul>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"testimonials\">\n                    <header> <span class=\"fa fa-lg fa-quote-left\"></span> \n                         <h2>testimonials</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>John Davidson</em></h3>\n\n                        <p>Jane is awesome! I&#39;d hire her again in a heartbeat.</p>\n                    </div>\n                    <div>\n                         <h3><em>Dana Nevins</em></h3>\n\n                        <p>I&#39;ve known Jane personally and professionally for almost ten years.\n                            She is one in a million.</p>\n                    </div>\n                </section>\n                <hr>\n                <section id=\"interests\">\n                    <header> <span class=\"fa fa-lg fa-bicycle\"></span> \n                         <h2>interests</h2>\n\n                    </header>\n                    <div>\n                         <h3><em>reading</em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Jane is a fan of mystery novels and courtroom dramas including Agatha\n                            Christie and John Grisham.</p>\n                    </div>\n                    <div>\n                         <h3><em>hiking</em></h3>\n <span class=\"tenure\">Current</span>\n\n                        <p>Jane enjoys hiking, light mountain climbing, and has four summits under\n                            her belt!</p>\n                    </div>\n                    <div>\n                         <h3><em>yoga</em></h3>\n <span class=\"tenure\">Current</span>\n\n                    </div>\n                </section>\n            </div>\n        </main>\n    </body>\n\n</html>"
  },
  {
    "path": "test/expected/modern/resume.txt",
    "content": "Jane Q. Fullstacker\nEmail: jdoe@onecoolstartup.io\nTel: 1-650-999-7777\nWeb: http://janef.me/blog\n================================================================================\n\n**Imaginary full-stack software developer with 6+ years industry experience** specializing in cloud-driven web applications and middleware. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two year old beagle.\n\nSKILLS -------------------------------------------------------------------------\n\n- Web: JavaScript HTML 5 CSS LAMP MVC REST \n- JavaScript: Node.js Angular.js jQuery Bootstrap React.js Backbone.js \n- Database: MySQL PostgreSQL NoSQL ORM Hibernate \n- Cloud: AWS EC2 RDS S3 Azure Dropbox \n- Project: Agile TFS JIRA GitHub Unified Process MS Project \n\nEMPLOYMENT ---------------------------------------------------------------------\n\nHead Code Ninja, Area 52 (2013-09 — Present)\nDevelopment team manager for [**Quantum Diorama**](https://en.wikipedia.org/wiki/Vaporware), a distributed molecular modeling and analysis suite for Linux and OS X.\n- Managed a 5-person development team\n- Accomplishment 2\n- Etc.\n\nPrincipal Developer, Veridian Dynamics (2011-07 — 2013-08)\nDeveloper on numerous projects culminating in technical lead role for the [Jabberwocky project](http://betteroffted.wikia.com/wiki/Jabberwocky) and promotion to principal developer.\n- Managed a 5-person development team\n- Accomplishment 2\n- Etc.\n\nIT Administrator, Stark Industries (2008-10 — 2011-06)\nJunior programmer with heavy code responsibilities. Promoted to intermediate role after 6 months.\n- Promoted to intermediate developer after 6 months\n- Accomplishment 2\n- Etc.\n\nIntern, Dunder Mifflin (2008-06 — 2008-09)\nPerformed IT administration and deployments for Dunder Mifflin.\n- Supervised roll-out of Dunder Mifflin Infinity website.\n- Performed mission-critical system backups and \n- Etc.\n\n\nPROJECTS -----------------------------------------------------------------------\n\nHackMyResume, contributor (2015-09 — Present)\nA resume authoring and analysis tool for OS X, Linux, and Windows.\nExemplar user for HackMyResume and FluentCV!\n\nAugmented Android, co-creator (2012-02 — 2014-01)\nAn augmented reality app for Android.\nPerformed flagship product conceptualization and development.\n\nBlog, creator (??? — Present)\nMy programming blog. Powered by Jekyll.\nConceptualization, design, development, and deployment.\n\n\nGOVERNANCE ---------------------------------------------------------------------\n\nMember, The Mommies Network\nSince 2008 I've been a full-time member of the board of directors for TMN.\n\nAcademic Contributor, Khronos Group\n- Participated in GORFF standardization process (Draft 2).\n\n\n\nEDUCATION ----------------------------------------------------------------------\n\nCornell University (2005-09 — 2008-05)\nA multiline summary of the education.\n\nMedfield College (2003-09 — 2005-06)\nA multiline summary of the education.\n\n\nAFFILIATION --------------------------------------------------------------------\n\nMember, IEEE (2013-06 — Present)\nMember in good standing since 2013-06.\n\nMember, Apple Developer Network (??? — Present)\nMember of the [Apple Developer program](https://developer.apple.com/) since 2008.\n\nSubscriber, MSDN (2010-01 — Present)\nSuper-Ultra-gold level Ultimate Access MSDN subscriber package with subscription toaster and XBox ping pong racket.\n\nCoordinator, Campus Coder's Meetup (2003-02 — 2004-04)\nHost of a monthly **campus-wide meetup for CS students**. Code, coffee, and crullers!\n\n\nSAMPLES ------------------------------------------------------------------------\n\nAsteroids (2014-09)\n\nA browser-based space shooter built on Three.js.\n\nRememberpedia (2015-07)\n\nA website to help you remember things.\n\n\nWRITING ------------------------------------------------------------------------\n\nBuilding User Interfaces with Electron and Atom (2011-01)\n\nJane Fullstacker's Blog (2011-01)\n\nTeach Yourself GORFF in 21 Days (2008-01)\nA primer on the programming language of GORFF, whose for loops are coterminous with all of time and space.\n\n\nREADING ------------------------------------------------------------------------\n\n\"r/programming\"\nhttps://www.reddit.com/r/programming/\nDaily reader and longtime lurker.\n\n\"Hacker News / YCombinator\"\nhttps://news.ycombinator.com/\nDaily reader and longtime lurker.\n\n\"Coding Horror\", Jeff Atwood\nhttp://www.codinghorror.com\nReader since 2007; member of the StackOverflow Beta.\n\n\"Code Complete\", Steve McConnell\nhttp://www.cc2e.com/Default.aspx\nMy 'desert-island' software construction manual.\n2014-09\n\n\nSERVICE ------------------------------------------------------------------------\n\nTechnology for Tots (2003-11 — 2005-06)\nSummary of this volunteer stint.\n- Accomplishment 1\n- Accomplishment 2\n- etc\n\nUS Army Reserves (1999-11 — 2003-06)\nSummary of this military stint.\n- Accomplishment 1\n- Accomplishment 2\n- etc\n\n\nRECOGNITION --------------------------------------------------------------------\n\nHonorable Mention, Google (Jan 2012)\n\nSumma cum laude, Cornell University (Jan 2012)\n\n\n\nINTERESTS ----------------------------------------------------------------------\n\nREADING: mystery Agatha Christie John Grisham \nJane is a fan of mystery novels and courtroom dramas including Agatha Christie and John Grisham.\n\nHIKING\nJane enjoys hiking, light mountain climbing, and has four summits under her belt!\n\nYOGA\n\n\n"
  },
  {
    "path": "test/expected/modern/resume.yml",
    "content": "name: 'Jane Q. Fullstacker'\nmeta:\n  format: FRESH@0.6.0\n  version: 0.4.0\ninfo:\n  label: 'Senior Developer'\n  characterClass: Programmer\n  brief: '**Imaginary full-stack software developer with 6+ years industry experience** specializing in cloud-driven web applications and middleware. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two year old beagle.'\n  image: jane_doe.png\n  quote: 'Be the change you want to see in the world.'\ncontact:\n  website: 'http://janef.me/blog'\n  phone: 1-650-999-7777\n  email: jdoe@onecoolstartup.io\n  other:\n    -\n      label: 'Home Phone'\n      flavor: phone\n      value: 1-650-999-4321\n    -\n      label: 'Work Phone'\n      flavor: phone\n      value: 1-650-777-1234\n    -\n      label: 'Personal Email'\n      flavor: email\n      value: jane@janef.me\nlocation:\n  address: \"Jane Fullstacker\\n123 Somewhere Rd.\\nMountain View, CA 94035\"\n  city: 'Mountain View'\n  region: CA\n  code: '94035'\n  country: US\nprojects:\n  -\n    title: HackMyResume\n    category: FOSS\n    role: contributor\n    url: 'https://fluentdesk.com/hackmyresume'\n    start: 2015-09\n    repo: 'https://github.com/hacksalot/hackmyresume'\n    description: 'A resume authoring and analysis tool for OS X, Linux, and Windows.'\n    summary: 'Exemplar user for HackMyResume and FluentCV!'\n    keywords:\n      - JavaScript\n      - Node.js\n      - cross-platform\n      - JSON\n    media:\n      -\n        category: download\n        url: 'https://www.npmjs.com/package/hackmyresume'\n  -\n    title: 'Augmented Android'\n    category: commercial\n    role: co-creator\n    url: 'http://project.website.com'\n    repo: 'http://repo.website.com'\n    description: 'An augmented reality app for Android.'\n    start: 2012-02\n    end: 2014-01\n    summary: 'Performed flagship product conceptualization and development.'\n    keywords:\n      - Android\n      - Java\n      - Xamarin\n  -\n    title: Blog\n    category: personal\n    role: creator\n    url: 'http://myblog.jane.com/blog'\n    description: 'My programming blog. Powered by Jekyll.'\n    summary: 'Conceptualization, design, development, and deployment.'\n    keywords:\n      - Jekyll\n      - Ruby\n      - 'HTML 5'\n      - JavaScript\n      - HTTP\n      - LAMP\nsocial:\n  -\n    label: GitHub\n    network: GitHub\n    user: janef-was-here\n    url: 'https://github.com/janef-was-here'\n  -\n    label: Twitter\n    network: Twitter\n    user: janef-was-here\n    url: 'https://twitter.com/janef-was-here'\nemployment:\n  summary: '7+ years industry IT and software development experience.'\n  history:\n    -\n      employer: 'Area 52'\n      url: 'https://area52.io/does-not-exist'\n      position: 'Head Code Ninja'\n      summary: 'Development team manager for [**Quantum Diorama**](https://en.wikipedia.org/wiki/Vaporware), a distributed molecular modeling and analysis suite for Linux and OS X.'\n      start: 2013-09\n      keywords:\n        - Agile\n        - PM\n        - C\n        - C++\n        - R\n        - OpenGL\n        - Boost\n        - MySQL\n        - PostgreSQL\n        - JIRA\n      highlights:\n        - 'Managed a 5-person development team'\n        - 'Accomplishment 2'\n        - Etc.\n    -\n      employer: 'Veridian Dynamics'\n      url: 'https://en.wikipedia.org/wiki/Better_Off_Ted#Plot'\n      position: 'Principal Developer'\n      summary: 'Developer on numerous projects culminating in technical lead role for the [Jabberwocky project](http://betteroffted.wikia.com/wiki/Jabberwocky) and promotion to principal developer.'\n      start: 2011-07\n      end: 2013-08\n      keywords:\n        - C++\n        - C\n        - Linux\n        - R\n        - Clojure\n      highlights:\n        - 'Managed a 5-person development team'\n        - 'Accomplishment 2'\n        - Etc.\n    -\n      employer: 'Stark Industries'\n      position: 'IT Administrator'\n      summary: 'Junior programmer with heavy code responsibilities. Promoted to intermediate role after 6 months.'\n      start: 2008-10\n      end: 2011-06\n      keywords:\n        - Novell\n        - 'Active Directory'\n        - Linux\n        - Windows\n      highlights:\n        - 'Promoted to intermediate developer after 6 months'\n        - 'Accomplishment 2'\n        - Etc.\n    -\n      employer: 'Dunder Mifflin'\n      position: Intern\n      summary: 'Performed IT administration and deployments for Dunder Mifflin.'\n      start: 2008-06\n      end: 2008-09\n      keywords:\n        - Novell\n        - 'Active Directory'\n        - Linux\n        - Windows\n      highlights:\n        - 'Supervised roll-out of Dunder Mifflin Infinity website.'\n        - 'Performed mission-critical system backups and '\n        - Etc.\neducation:\n  summary: \"\"\n  level: degree\n  degree: BSCS\n  history:\n    -\n      institution: 'Cornell University'\n      title: BSCS\n      url: 'https://www.cornell.edu/'\n      start: 2005-09\n      end: 2008-05\n      grade: '3.5'\n      summary: 'A multiline summary of the education.'\n      curriculum:\n        - 'Course 1'\n        - 'Course 2'\n        - 'Course 2'\n    -\n      institution: 'Medfield College'\n      title: \"\"\n      url: 'https://en.wikipedia.org/wiki/Medfield_College'\n      start: 2003-09\n      end: 2005-06\n      grade: '3.2'\n      summary: 'A multiline summary of the education.'\n      curriculum:\n        - 'Course 1'\n        - 'Course 2'\n        - 'Course 2'\naffiliation:\n  summary: 'Member of numerous collegiate and professional groups and organizations.'\n  history:\n    -\n      role: Member\n      organization: IEEE\n      url: 'https://www.ieee.org/index.html'\n      start: 2013-06\n      summary: 'Member in good standing since 2013-06.'\n    -\n      role: Member\n      organization: 'Apple Developer Network'\n      url: 'https://developer.apple.com/'\n      summary: 'Member of the [Apple Developer program](https://developer.apple.com/) since 2008.'\n    -\n      role: Subscriber\n      organization: MSDN\n      url: 'https://msdn.microsoft.com'\n      start: '2010'\n      summary: 'Super-Ultra-gold level Ultimate Access MSDN subscriber package with subscription toaster and XBox ping pong racket.'\n    -\n      role: Coordinator\n      organization: 'Campus Coder''s Meetup'\n      start: 2003-02\n      end: 2004-04\n      summary: 'Host of a monthly **campus-wide meetup for CS students**. Code, coffee, and crullers!'\nservice:\n  summary: 'Active US Army Reserve member and Technology for Tots technical consultant and volunteer coordinator.'\n  history:\n    -\n      flavor: volunteer\n      position: 'Technical Consultant'\n      organization: 'Technology for Tots'\n      url: 'http://technology-for-tots.org'\n      start: 2003-11\n      end: 2005-06\n      summary: 'Summary of this volunteer stint.'\n      highlights:\n        - 'Accomplishment 1'\n        - 'Accomplishment 2'\n        - etc\n    -\n      flavor: military\n      position: NCO\n      organization: 'US Army Reserves'\n      url: 'http://www.usar.army.mil/'\n      start: 1999-11\n      end: 2003-06\n      summary: 'Summary of this military stint.'\n      highlights:\n        - 'Accomplishment 1'\n        - 'Accomplishment 2'\n        - etc\nskills:\n  sets:\n    -\n      name: Web\n      level: advanced\n      skills:\n        - JavaScript\n        - 'HTML 5'\n        - CSS\n        - LAMP\n        - MVC\n        - REST\n    -\n      name: JavaScript\n      level: master\n      skills:\n        - Node.js\n        - Angular.js\n        - jQuery\n        - Bootstrap\n        - React.js\n        - Backbone.js\n    -\n      name: Database\n      level: intermediate\n      skills:\n        - MySQL\n        - PostgreSQL\n        - NoSQL\n        - ORM\n        - Hibernate\n    -\n      name: Cloud\n      level: intermediate\n      skills:\n        - AWS\n        - EC2\n        - RDS\n        - S3\n        - Azure\n        - Dropbox\n    -\n      name: Project\n      level: beginner\n      skills:\n        - Agile\n        - TFS\n        - JIRA\n        - GitHub\n        - 'Unified Process'\n        - 'MS Project'\n  list:\n    -\n      name: C++\n      id: '1'\n      summary: 'Optional summary of your experience with the skill.'\n      level: '9'\n      years: 7\n      proof: 'http://myblog.com/interesting-cplusplus-post'\n    -\n      name: Ruby\n      id: '2'\n      summary: 'Optional summary of your experience with the skill.'\n      level: '9'\n      years: 7\n      proof: 'http://myblog.com/interesting-cplusplus-post'\n    -\n      name: Xcode\n      summary: 'Xcode 6 development.'\n      level: '5'\n      years: '3'\n    -\n      name: Linux\n      summary: 'Optional summary of your experience with the skill.'\n      level: advanced\n      years: 4+\n    -\n      name: Agile\n      summary: 'Optional summary of your experience with the skill.'\n      level: B+\n      years: 2\nsamples:\n  -\n    title: Asteroids\n    summary: 'A browser-based space shooter built on Three.js.'\n    url: 'http://janef.me/asteroids'\n    date: 2014-09\n  -\n    title: Rememberpedia\n    summary: 'A website to help you remember things.'\n    url: 'https://rememberpedia.com'\n    date: 2015-07\nwriting:\n  -\n    title: 'Building User Interfaces with Electron and Atom'\n    flavor: article\n    date: '2011'\n    publisher:\n      name: 'Code Project'\n      url: 'http://codeproject.com'\n    url: 'http://codeproject.com/build-ui-electron-atom.aspx'\n  -\n    title: 'Jane Fullstacker''s Blog'\n    flavor: blog\n    date: '2011'\n    publisher:\n      name: self\n      url: 'http://janef.me'\n    url: 'http://janef.me'\n  -\n    title: 'Teach Yourself GORFF in 21 Days'\n    flavor: book\n    date: '2008'\n    publisher:\n      name: Amazon\n      url: 'https://www.amazon.com'\n    url: 'http://url.to.publication.com/blah'\n    author:\n      - 'Jane Fullstacker'\n      - 'John Smith'\n    summary: 'A primer on the programming language of GORFF, whose for loops are coterminous with all of time and space.'\nreading:\n  -\n    title: r/programming\n    flavor: website\n    url: 'https://www.reddit.com/r/programming/'\n    summary: 'Daily reader and longtime lurker.'\n  -\n    title: 'Hacker News / YCombinator'\n    flavor: website\n    url: 'https://news.ycombinator.com/'\n    summary: 'Daily reader and longtime lurker.'\n  -\n    title: 'Coding Horror'\n    flavor: blog\n    url: 'http://www.codinghorror.com'\n    author: 'Jeff Atwood'\n    summary: 'Reader since 2007; member of the StackOverflow Beta.'\n  -\n    title: 'Code Complete'\n    flavor: book\n    url: 'http://www.cc2e.com/Default.aspx'\n    author: 'Steve McConnell'\n    date: 2014-09\n    summary: 'My ''desert-island'' software construction manual.'\nspeaking:\n  -\n    title: 'Data Warehousing Evolved: DARMA 2.0'\n    role: Speaker\n    event: 'OPENSTART 2013 Developer''s Conference'\n    location: 'Portland, OR'\n    date: '2012'\n    highlights:\n      - 'Won ''Best Presentation on an Emerging Technical Field'' prize.'\nrecognition:\n  -\n    flavor: award\n    from: Google\n    title: 'Honorable Mention'\n    event: 'Summer of Code'\n    date: '2012'\n  -\n    flavor: honor\n    from: 'Cornell University'\n    title: 'Summa cum laude'\n    event: graduation\n    date: '2012'\nreferences: []\ntestimonials:\n  -\n    name: 'John Davidson'\n    flavor: professional\n    quote: 'Jane is awesome! I''d hire her again in a heartbeat.'\n    private: true\n  -\n    name: 'Dana Nevins'\n    flavor: personal\n    quote: 'I''ve known Jane personally and professionally for almost ten years. She is one in a million.'\nlanguages:\n  -\n    language: English\n    level: Native\n  -\n    language: Spanish\n    level: Moderate\n    years: 10\nextracurricular:\n  -\n    title: 'Bay Area Crew Club'\n    activity: \"\"\n    location: 'San Francisco, CA'\n    start: 2014-05\n  -\n    title: 'Organizer / Manager'\n    activity: 'JavaScript Game Development Meetup'\n    location: 'Austin, TX'\n    start: 2011-03\n    end: 2014-01\n    highlights:\n      - 'Monthly speaker on creative JavaScript development.'\n      - 'Founded group and oversaw growth to 500+ members.'\ngovernance:\n  -\n    flavor: board\n    role: Member\n    organization: 'The Mommies Network'\n    url: 'http://themommiesnetwork.org'\n    start: 2008-02\n    end: 2010-01\n    summary: 'Since 2008 I''ve been a full-time member of the board of directors for TMN.'\n  -\n    flavor: committee\n    role: 'Academic Contributor'\n    organization: 'Khronos Group'\n    url: 'https://www.khronos.org'\n    start: 2015-01\n    highlights:\n      - 'Participated in GORFF standardization process (Draft 2).'\ninterests:\n  -\n    name: reading\n    summary: 'Jane is a fan of mystery novels and courtroom dramas including Agatha Christie and John Grisham.'\n    keywords:\n      - mystery\n      - 'Agatha Christie'\n      - 'John Grisham'\n  -\n    name: hiking\n    summary: 'Jane enjoys hiking, light mountain climbing, and has four summits under her belt!'\n  -\n    name: yoga\n"
  },
  {
    "path": "test/scripts/hmr-options-broken.json",
    "content": "{\n  // Set the default theme to \"compact\"\n  //\"theme\": \"node_modules/jsonresume-theme-elegant\",\n  //\"theme\": \"jsonresume-theme-elegant\",\n  \"theme\": \"elegant\",\n  // Change the \"employment\" section title text to \"Work\"\n  \"sectionTitles\": {\n    \"employment\": \"Work\"\n  }\n}\n"
  },
  {
    "path": "test/scripts/hmr-options.json",
    "content": "{\n  \"theme\": \"positive\",\n  \"debug\": true\n}\n"
  },
  {
    "path": "test/scripts/test-cli.js",
    "content": "/**\nCLI test routines for HackMyResume. Test the HackMyResume command-line interface\nby spawning HMR directly and observing the return code and std output.\n@module test-cli.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nvar chai = require('chai')\n  , should = chai.should()\n  , expect = chai.expect\n  , FS = require('fs')\n  , PATH = require('path')\n  , EXEC = require('child_process').exec\n\n\n\ndescribe('Testing CLI interface', function () {\n\n  this.timeout(50000);\n\n  function run( args, expErr ) {\n    var title = args;\n    it( 'Testing: \"' + title + '\"\\n\\n', function( done ) {\n      try {\n        EXEC('hackmyresume ' + args, null, function(err,stdo,stde) {\n          var errCode = (err && err.code) || 0;\n          errCode.should.equal( parseInt(expErr, 10) );\n          done();\n        });\n      }\n      catch(ex) {\n        ex.status.should.equal( parseInt(expErr, 10) );\n        done();\n      }\n    });\n  }\n\n  var testFile = PATH.join( __dirname, './test-hmr.txt');\n  var lines = FS.readFileSync( testFile, 'utf8').split('\\n');\n  lines.forEach(function(l){\n    if( l && l.trim() ) {\n      if(l[0] !== '#') {\n        var lineInfo = l.split('|');\n        var errCode = lineInfo[0];\n        run( lineInfo.length > 1 ? lineInfo[1] : '', errCode );\n      }\n    }\n  });\n\n});\n"
  },
  {
    "path": "test/scripts/test-dates.js",
    "content": "/**\nTest routines for HackMyResume dates, times, and datetimes.\n@module test-dates.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nvar chai = require('chai')\n  , expect = chai.expect\n  , should = chai.should()\n  , path = require('path')\n  , _ = require('underscore')\n\t, FRESHResume = require('../../src/core/fresh-resume')\n  , FCMD = require( '../../src/index')\n  , validator = require('is-my-json-valid')\n  , EXTEND = require('extend');\n\n\n\nchai.config.includeStack = true;\n\n\n\nvar gig = {\n  employer: 'E1'\n};\n\nvar r = {\n  name: 'John Doe',\n  meta: {\n    format: 'FRESH@0.6.0'\n  },\n  employment: {\n    history: [ null ]\n  }\n};\n\n\n\nvar tests = [\n  // single job, concrete start, no end\n  [ { start: '2010-01-01' } , { val: 8, unit: 'year' } ],\n  [ { start: '2010-01' } , { val: 8, unit: 'year' } ],\n  [ { start: '2010' } , { val: 8, unit: 'year' } ],\n\n  // single job, concrete start, concrete end\n  [ { start: '2010-01-01', end: '2015-01-01' } , { val: 5, unit: 'year' } ],\n  [ { start: '2010-01', end: '2015-01' } , { val: 5, unit: 'year' } ],\n  [ { start: '2010', end: '2015' } , { val: 5, unit: 'year' } ],\n\n  // single job, falsy start, falsy end\n  [ { } , { val: 0, unit: 'year' } ],\n  [ { start: null } , { val: 0, unit: 'year' } ],\n  [ { end: null } , { val: 0, unit: 'year' } ],\n  [ { start: undefined } , { val: 0, unit: 'year' } ],\n  [ { end: undefined } , { val: 0, unit: 'year' } ],\n  [ { start: null, end: null } , { val: 0, unit: 'year' } ],\n  [ { start: '', end: '' } , { val: 0, unit: 'year' } ],\n  [ { start: ' ', end: ' ' } , { val: 0, unit: 'year' } ],\n  [ { start: undefined, end: undefined } , { val: 0, unit: 'year' } ],\n\n  // two jobs (concrete start + end) -> ( concrete start )\n  [ { start: '2000-01', end: '2013-01' }, { start: '2013-01' }, { val: 18, unit: 'year' } ],\n  [ { start: '2000-01', end: '2013-01' }, { start: '2013-01', end: '' }, { val: 18, unit: 'year' } ],\n  [ { start: '2000-01', end: '2013-01' }, { start: '2013-01', end: null }, { val: 18, unit: 'year' } ],\n  [ { start: '2000-01', end: '2013-01' }, { start: '2013-01', end: 'current' }, { val: 18, unit: 'year' } ]\n\n];\n\n\n\ntests.forEach(function(t){\n   _.initial( t ).forEach(function(t){ t.employer = 'E1' });\n})\n\n\n\ndescribe('Testing DATES', function () {\n\n  tests.forEach( function(t) {\n\n    it( JSON.stringify( _.initial(t) ), function () {\n      r.employment.history = _.initial( t );\n      var rObj = new FRESHResume();\n      rObj.parseJSON( r );\n      var dur = rObj.duration();\n      expect( dur ).to.equal( _.last(t).val );\n    });\n\n  });\n\n\n\n});\n"
  },
  {
    "path": "test/scripts/test-fresh-sheet.js",
    "content": "/**\nTest routines for the FRESHResume class.\n@module test-jrs-sheet.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nvar chai = require('chai')\n  , expect = chai.expect\n  , should = chai.should()\n  , path = require('path')\n  , _ = require('underscore')\n\t, FRESHResume = require('../../src/core/fresh-resume')\n  , ResumeFactory = require('../../src/core/resume-factory')\n  , validator = require('is-my-json-valid');\n\n\n\nchai.config.includeStack = false;\n\n\n\nfunction testResume(opts) {\n\n  describe( opts.title + ' (FRESH)', function () {\n\n      var _sheet;\n\n  \t  it('should open without throwing an exception', function () {\n        function tryOpen() {\n          var res = ResumeFactory.loadOne( opts.path, { objectify: true } );\n          _sheet = res.rez;\n          //_sheet = new FRESHResume().open( opts.path );\n        }\n        tryOpen.should.not.Throw();\n      });\n\n      it('should have one or more of each section', function() {\n        var newObj = _.pick( _sheet, opts.sections );\n        expect( Object.keys(newObj).length ).to.equal( opts.sections.length );\n      });\n\n      it('should have a work duration of ' + opts.duration + ' years', function() {\n        _sheet.computed.numYears.should.equal( opts.duration );\n      });\n\n      it('should save without throwing an exception', function(){\n        function trySave() {\n          _sheet.save( 'test/sandbox/' + opts.title + '.json' );\n        }\n        trySave.should.not.Throw();\n      });\n\n      it('should not be modified after saving', function() {\n        var savedSheet = ResumeFactory.loadOne( 'test/sandbox/' + opts.title + '.json', { objectify: true } );\n        //var savedSheet = new FRESHResume().open('test/sandbox/' + opts.title + '.json');\n        _sheet.stringify().should.equal( savedSheet.rez.stringify() );\n      });\n\n      it('should validate against the FRESH resume schema', function() {\n        var result = _sheet.isValid();\n        // var schemaJson = require('fresh-resume-schema');\n        // var validate = validator( schemaJson, { verbose: true } );\n        // var result = validate( JSON.parse( _sheet.imp.raw ) );\n        result || console.log(\"\\n\\nOops, resume didn't validate. \" +\n          \"Validation errors:\\n\\n\", _sheet.imp.validationErrors, \"\\n\\n\");\n        result.should.equal( true );\n      });\n\n\n  });\n}\n\nvar sects = [ 'info', 'employment', 'service', 'skills', 'education', 'writing', 'recognition', 'references' ];\ntestResume({ title: 'jane-q-fullstacker', path: 'node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json', duration: 9, sections: sects });\ntestResume({ title: 'johnny-trouble-resume', path: 'node_modules/fresh-test-resumes/src/fresh/johnny-trouble.json', duration: 6, sections: sects });\n\nsects = [ 'info', 'contact', 'location' ];\ntestResume({ title: 'jane-q-fullstacker A', path: 'node_modules/fresh-test-resumes/src/fresh/override/jane-partial-a.json', duration: 0, sections: sects });\n\nsects = [ 'projects', 'social', 'employment', 'education', 'affiliation' ];\ntestResume({ title: 'jane-q-fullstacker B', path: 'node_modules/fresh-test-resumes/src/fresh/override/jane-partial-b.json', duration: 9, sections: sects });\n\nsects = [ 'service', 'skills', 'samples', 'writing', 'reading', 'speaking', 'recognition', 'references', 'testimonials', 'languages', 'interests', 'extracurricular', 'governance' ];\ntestResume({ title: 'jane-q-fullstacker C', path: 'node_modules/fresh-test-resumes/src/fresh/override/jane-partial-c.json', duration: 0, sections: sects });\n"
  },
  {
    "path": "test/scripts/test-hmr.txt",
    "content": "4|\n0|--help\n0|-h\n4|--debug\n4|-d\n5|notacommand\n3|new\n0|new test/sandbox/cli-test/new-empty-resume.auto.json\n0|new test/sandbox/cli-test/new-empty-resume.jrs.json -f jrs\n0|new test/sandbox/cli-test/new-empty-resume.fresh.json -f fresh\n3|analyze\n14|analyze doesnt-exist.json\n0|analyze node_modules/fresh-test-resumes/src/fresh/johnny-trouble.json\n3|convert\n7|convert doesnt-exist.json\n14|convert from.json to.json\n7|convert z1.json z2.json z3.json\n7|convert z1.json z2.json z3.json z4.json\n14|convert z1.json z2.json to z3.json z4.json\n3|validate\n14|validate doesnt-exist.json\n0|validate node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json\n3|peek\n14|peek doesnt-exist.json\n14|peek doesnt-exist.json not.a.path\n15|peek node_modules/fresh-test-resumes/src/fresh/johnny-trouble.broken.json\n0|peek node_modules/fresh-test-resumes/src/jrs/richard-hendriks.json work[0]\n0|peek node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json employment.history[1]\n0|peek node_modules/fresh-test-resumes/src/fresh/johnny-trouble.json skills.sets\n3|build\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.all\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.html\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.pdf\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.md\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.txt\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.yml\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.json\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.all --theme modern\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.all --theme compact\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.all --theme positive\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.all --theme basis\n0|build node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json TO test/sandbox/cli-test/jane/resume.all --theme awesome\n14|build doesnt-exist.json\n14|build doesnt-exist.json -t not-a-theme\n14|build doesnt-exist.json -t node_modules/not-a-theme\n"
  },
  {
    "path": "test/scripts/test-jrs-sheet.js",
    "content": "/**\nTest routines for the JRSResume class.\n@module test-jrs-sheet.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nvar chai = require('chai')\n  , expect = chai.expect\n  , should = chai.should()\n  , path = require('path')\n  , _ = require('underscore')\n\t, JRSResume = require('../../src/core/jrs-resume')\n  , ResumeFactory = require('../../src/core/resume-factory')\n  , validator = require('is-my-json-valid');\n\n\n\nchai.config.includeStack = false;\n\n\n\nfunction testResume( opts ) {\n\n  describe( opts.title + ' (JRS)', function() {\n\n    opts.isValid = opts.isValid !== false;\n\n    var _sheet;\n\n    it('should open without throwing an exception', function () {\n      var that = this;\n      function tryOpen() {\n        var res = ResumeFactory.loadOne( path.normalize( path.join( __dirname, '/../../node_modules/fresh-test-resumes/src/jrs/' + opts.title + '.json' ) ), { objectify: true } );\n        _sheet = res.rez;\n      }\n      tryOpen.should.not.Throw();\n    });\n\n    it('should have one or more of each section', function() {\n      var newObj = _.pick( _sheet, opts.sections );\n      expect( Object.keys(newObj).length ).to.equal( opts.sections.length );\n    });\n\n    it('should have a work duration of ' + opts.duration + ' years', function() {\n      _sheet.basics.computed.numYears.should.equal( opts.duration );\n    });\n\n    it('should save without throwing an exception', function() {\n      var that = this;\n      function trySave() {\n        _sheet.save( 'test/sandbox/' + opts.title + '.json' );\n      }\n      trySave.should.not.Throw();\n    });\n\n    it('should not be modified after saving', function() {\n      var res = ResumeFactory.loadOne( 'test/sandbox/' + opts.title + '.json', { objectify: true } );\n      _sheet.stringify().should.equal( res.rez.stringify() );\n    });\n\n    it('should ' + (opts.isValid ? '' : 'NOT ') + 'validate against the JSON Resume schema', function() {\n      var result = _sheet.isValid();\n      // var schemaJson = require('../src/core/resume.json');\n      // var validate = validator( schemaJson, { verbose: true } );\n      // var result = validate( JSON.parse( _sheet.imp.raw ) );\n      result || console.log(\"\\n\\nOops, resume didn't validate. \" +\n       \"Validation errors:\\n\\n\", _sheet.imp.validationErrors, \"\\n\\n\");\n      result.should.equal( opts.isValid );\n    });\n\n  });\n}\n\nvar sects = [ 'basics', 'work', 'volunteer', 'skills', 'education', 'publications', 'awards', 'references' ];\n\ntestResume({ title: 'jane-fullstacker', duration: 9, sections: sects });\ntestResume({ title: 'jane-incomplete', duration: 0, sections: _.without(sects, 'awards', 'work') });\ntestResume({ title: 'richard-hendriks', duration: 1, sections: sects });\ntestResume({ title: 'empty', duration: 0, sections: [], isValid: false });\n"
  },
  {
    "path": "test/scripts/test-output.js",
    "content": "/**\nOutput test routines for HackMyResume. Make sure our outputs are consistent.\n@module test-output.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\n\nvar chai = require('chai')\n  , should = chai.should()\n  , expect = chai.expect\n  , HMRMAIN = require('../../src/cli/main')\n  , CHALK = require('chalk')\n  , FS = require('fs')\n  , PATH = require('path')\n  , PKG = require('../../package.json')\n  , STRIPCOLOR = require('stripcolorcodes')\n  , _ = require('underscore');\n\n\n\nvar gather = '';\nvar ConsoleLogOrg = console.log;\nvar ProcessExitOrg = process.exit;\nvar commandRetVal = 0;\n\n// TODO: use sinon\n// Replacement for process.exit()\nfunction MyProcessExit( retVal ) {\n  commandRetVal = retVal;\n}\n\n// TODO: use sinon\n// Replacement for console.log\nfunction MyConsoleLog() {\n  var tx = Array.prototype.slice.call(arguments).join(' ');\n  gather += STRIPCOLOR( tx );\n  ConsoleLogOrg.apply(this, arguments);\n}\n\n\ndescribe('Testing Ouput interface', function () {\n\n  this.timeout(50000);\n\n  // HackMyResume CLI stub. Handle a single HMR invocation.\n  function HackMyResumeOutputStub( args ) {\n\n    console.log = MyConsoleLog;\n    process.exit = MyProcessExit;\n    CHALK.enabled = false;\n\n    try {\n      args.unshift( process.argv[1] );\n      args.unshift( process.argv[0] );\n      HMRMAIN( args );\n    }\n    catch( ex ) {\n      console.error(ex);\n      require('../../src/cli/error').err( ex, false );\n    }\n    CHALK.enabled = true;\n    //process.exit = ProcessExitOrg;\n    console.log = ConsoleLogOrg;\n\n  }\n\n  // Run a test through the stub, gathering console.log output into \"gather\"\n  // and testing against it.\n  function run( title, args, tests ) {\n    it( title, function() {\n\n      gather = '';\n      HackMyResumeOutputStub( args );\n\n      expect(\n        _.all( tests, function(t) {\n          return gather.indexOf(t) > -1;\n        })\n      ).to.equal(true);\n\n    });\n  }\n\n  var title = '*** HackMyResume v' + PKG.version + ' ***';\n  var feedMe = 'Please feed me a resume in FRESH or JSON Resume format.';\n  var manPage = FS.readFileSync( PATH.resolve( __dirname, '../../src/cli/help/use.txt' ), 'utf8').replace(/\\*\\*/g, '');\n  var manPages = { };\n  ['build','new','convert','analyze','validate','peek'].forEach( function(verb) {\n    manPages[verb] = FS.readFileSync( PATH.resolve( __dirname, '../../src/cli/help/' + verb  + '.txt' ), 'utf8').replace(/\\*\\*/g, '');\n  });\n\n  // run('HMR should output a help string when no command is specified',\n  //     [], [ title, 'Please give me a command (BUILD, ANALYZE, VALIDATE, CONVERT, NEW, or PEEK).' ]);\n\n  run('BUILD should output a help message when no source is specified',\n      ['build'], [ title, manPages.build ]);\n\n  run('VALIDATE should output a help message when no source is specified',\n     ['validate'], [ title, manPages.validate ]);\n\n  run('ANALYZE should output a help message when no source is specified',\n      ['analyze'], [ title, manPages.analyze ]);\n\n  run('BUILD should display an error on a broken resume',\n     ['build',\n      'node_modules/fresh-test-resumes/src/fresh/johnny-trouble.broken.json',\n      '-t', 'modern'\n    ], [ title, 'Error: Invalid or corrupt JSON on line'  ]);\n\n  run('CONVERT should output a help message when no source is specified',\n      ['convert'], [ title, manPages.convert ]);\n\n  run('NEW should output a help message when no source is specified',\n      ['new'], [ title, manPages.new ]);\n\n  // This will cause the HELP doc to be emitted, followed by an \"unknown option --help\"\n  // error in the log, based on the way we're calling into HMR. As long as the test\n  // passes, any extraneous error messages can be ignored here.\n  run('HMR should output help doc with --help',\n      ['--help'], [ manPage ]);\n\n  run('HMR should accept raw JSON via --options',\n      [\n        'build',\n        'node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json',\n        'to',\n        'test/sandbox/temp/janeq-1.all',\n        '-o',\n        \"{ theme: 'compact', debug: true, pdf: 'wkhtmltopdf' }\"],\n      [ 'Applying COMPACT theme (', '(with wkhtmltopdf)'] );\n\n  run('HMR should accept a JSON settings file via --options',\n      [\n        'build',\n        'node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json',\n        'to',\n        'test/sandbox/temp/janeq-2.all',\n        '--options',\n        \"test/scripts/hmr-options.json\"],\n      [ 'Applying POSITIVE theme'] );\n\n  run('Explicit command line options should override --options',\n      [\n        'build',\n        'node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json',\n        'to',\n        'test/sandbox/temp/janeq-3.all',\n        '--options',\n        \"test/scripts/hmr-options.json\",\n        \"-t\",\n        \"modern\"\n      ],\n      [ 'Applying MODERN theme'] );\n\n  run('HMR should detect a missing or inaccessible options file',\n      [\n        'build',\n        'doesntmatter.json',\n        'to',\n        'dontcare.all',\n        '--options',\n        \"test/scripts/hmr-options-nonexistent.json\",\n        \"-t\",\n        \"modern\"\n      ],\n      [ 'The specified options file is missing or inaccessible'] );\n\n  run('HMR should detect an invalid or malformed options file',\n      [\n        'build',\n        'doesntmatter.json',\n        'to',\n        'dontcare.all',\n        '--options',\n        \"test/scripts/hmr-options-broken.json\",\n        \"-t\",\n        \"modern\"\n      ],\n      [ 'The specified options file is invalid'] );\n\n});\n"
  },
  {
    "path": "test/scripts/test-themes.js",
    "content": "/**\nTheme test routines for HackMyResume. Test all preinstalled HackMyResume themes\nalong with a handful of JSON Resume themes for good measure. Uses the HMR verb\ninterface.\n@module test-themes.js\n@license MIT. See LICENSE.md for details.\n*/\n\n\nvar chai         = require('chai')\n  , expect       = chai.expect\n  , should       = chai.should()\n  , path         = require('path')\n  , _            = require('underscore')\n  , HackMyResume = require( '../../src/index')\n  , readFolder   = require('recursive-readdir-sync')\n  , fileContains = require('../../src/utils/file-contains')\n  , dirCompare   = require('dir-compare');\n\n// Include stack traces for failed tests.\nchai.config.includeStack = true;\n\n/**\nTest the specified resume against multiple themes.\n*/\nfunction genThemes( title, src, fmt ) {\n\n  // Set up a new suite\n  describe('Testing themes against ' + title.toUpperCase()\n    + ' resume ' + '(' + fmt + ')' , function () {\n\n    // Increase the timeout since resume generation can be expensive..\n    this.timeout(50000);\n\n    // Define a local function to build a single resume to MULTIPLE themes\n    function genTheme( fmt, src, themeName, themeLoc, testTitle ) {\n      themeLoc = themeLoc || themeName;\n      testTitle = themeName.toUpperCase() + ' theme (' + fmt +\n        ') should generate without throwing an exception';\n\n      // Instantiate a test case\n      it( testTitle, function () {\n\n        // Set up options\n        var dst = ['test/sandbox/' + fmt + '/' + title + '/' +\n          themeName + '/resume.all'];\n        var opts = {\n          theme: themeLoc,\n          format: fmt,\n          prettify: true,\n          silent: false,\n          css: 'embed',\n          debug: true\n        };\n\n        // Run the command!\n        var v = new HackMyResume.verbs.build();\n        v.on('hmr:error', function(ex) {\n          console.error('Error thrown: %o', ex);\n          throw ex;\n          //assert(false);\n        });\n        var p = v.invoke( src, dst, opts );\n\n        // Let Mocha sort out the promise result\n        return p.then(\n          function(obj) { }\n          //,function(obj) { },\n        );\n\n      });\n    }\n\n    // Build the resume for each theme\n    //genTheme(fmt, src, 'hello-world');\n    genTheme(fmt, src, 'compact');\n    genTheme(fmt, src, 'modern');\n    genTheme(fmt, src, 'underscore', 'node_modules/fresh-theme-underscore' );\n    genTheme(fmt, src, 'awesome');\n    genTheme(fmt, src, 'positive');\n\n    genTheme(fmt, src, 'jsonresume-theme-boilerplate',\n       'node_modules/jsonresume-theme-boilerplate' );\n    genTheme(fmt, src, 'jsonresume-theme-sceptile',\n      'node_modules/jsonresume-theme-sceptile' );\n    genTheme(fmt, src, 'jsonresume-theme-modern',\n      'node_modules/jsonresume-theme-modern' );\n    genTheme(fmt, src, 'jsonresume-theme-classy',\n      'node_modules/jsonresume-theme-classy' );\n\n  });\n\n}\n\nfunction folderContains( needle, haystack ) {\n  var ignoreExts = ['.png','.jpg','.jpeg','.bmp','.pdf', '.gif'];\n  var safePath = path.normalize( path.join(__dirname, haystack));\n  return _.some( readFolder( safePath ), function( absPath ) {\n    if( require('fs').lstatSync( absPath ).isFile() ) {\n      var pathInfo = path.parse( absPath );\n      if( !_.contains(ignoreExts, pathInfo.ext) &&\n          fileContains(absPath, needle) ) {\n        console.error('Found invalid metadata in ' + absPath);\n        return true;\n      }\n      return false;\n    }\n  });\n}\n\nfunction foldersMatch( a, b ) {\n  var ret;\n  ret = dirCompare.compareSync(a, b, {compareSize: true, skipSubdirs: true});\n  if( !ret.same ) return false;\n  ret = dirCompare.compareSync(a, b, {compareContent: true, skipSubdirs: true});\n  return ret.differences === 1;\n}\n\ngenThemes(\n  'jane-q-fullstacker',\n  ['node_modules/fresh-test-resumes/src/fresh/jane-fullstacker.json'],\n  'FRESH'\n);\n\ngenThemes(\n  'johnny-trouble',\n  ['node_modules/fresh-test-resumes/src/fresh/johnny-trouble.json'],\n  'FRESH'\n);\n\ngenThemes(\n  'richard-hendriks',\n  ['node_modules/fresh-test-resumes/src/jrs/richard-hendriks.json'],\n  'JRS'\n);\n\ndescribe('Verifying generated theme files...', function() {\n\n  it('Generated files should not contain ICE.', function() {\n    var q = folderContains('@@@@', '../sandbox');\n    q.should.equal(false);\n  });\n\n  // it('Generated files should match exemplars...', function() {\n  //   var q = foldersMatch( 'test/sandbox/FRESH/jane-q-fullstacker/modern',\n  //       'test/expected/modern' );\n  //   q.should.equal(true);\n  // });\n\n});\n"
  },
  {
    "path": "test/scripts/test-verbs.js",
    "content": "/**\nHigh-level API test routines for HackMyResume. Test HackMyResume verbs such\nas build, new, peek, etc., by creating and invoking a Verb object.\n@module test-verbs.js\n@license MIT. See LICENSE.md for details.\n*/\n\nvar chai = require('chai')\n  , chaiAsPromised = require(\"chai-as-promised\")\n  , path = require('path')\n  , _ = require('underscore')\n\t, FRESHResume = require('../../src/core/fresh-resume')\n  , FCMD = require( '../../src/index')\n  , validator = require('is-my-json-valid')\n  , EXTEND = require('extend');\n\n// Initialize Chai As Promised\nchai.use(chaiAsPromised);\nexpect = chai.expect;\nassert = chai.assert;\nshould = chai.should();\nchai.config.includeStack = false;\n\nvar _sheet;\n\nvar opts = {\n  format: 'FRESH',\n  prettify: true,\n  silent: false,\n  assert: true  // Causes validation errors to throw exceptions\n};\n\nvar opts2 = {\n  format: 'JRS',\n  prettify: true,\n  silent: true\n};\n\nvar sb = 'test/sandbox/';\nvar ft = 'node_modules/fresh-test-resumes/src/fresh/';\n\n// Assemble an array of tests, taking the form of parameters we'll pass to\n// each of the defined HackMyResume verbs.\nvar tests = [\n\n  [ 'new',\n    [sb + 'new-fresh-resume.json'],\n    [],\n    opts,\n    ' (FRESH format)'\n  ],\n\n  [ 'new',\n    [sb + 'new-jrs-resume.json'],\n    [],\n    opts2,\n    ' (JRS format)'\n  ],\n\n  [\n    'new',\n    [sb + 'new-1.json', sb + 'new-2.json', sb + 'new-3.json'],\n    [],\n    opts,\n    ' (multiple FRESH resumes)'\n  ],\n\n  [ 'new',\n    [sb + 'new-jrs-1.json', sb + 'new-jrs-2.json', sb + 'new-jrs-3.json'],\n    [],\n    opts,\n    ' (multiple JRS resumes)'\n  ],\n\n  [ '!new',\n    [],\n    [],\n    opts,\n    \" (when a filename isn't specified)\"\n  ],\n\n  [ 'validate',\n    [ft + 'jane-fullstacker.json'],\n    [],\n    opts,\n    ' (jane-q-fullstacker|FRESH)'\n  ],\n\n  [ 'validate',\n    [ft + 'johnny-trouble.json'],\n    [],\n    opts,\n    ' (johnny-trouble|FRESH)'\n  ],\n\n  [ 'validate',\n    [sb + 'new-fresh-resume.json'],\n    [],\n    opts,\n    ' (new-fresh-resume|FRESH)'\n  ],\n\n  [ 'validate',\n    ['node_modules/fresh-test-resumes/src/jrs/richard-hendriks.json'],\n    [],\n    opts2,\n    ' (richard-hendriks.json|JRS)'\n  ],\n\n  [ 'validate',\n    ['node_modules/fresh-test-resumes/src/jrs/jane-incomplete.json'],\n    [],\n    opts2,\n    ' (jane-incomplete.json|JRS)'\n  ],\n\n  [ 'validate',\n    [sb + 'new-1.json', sb + 'new-jrs-resume.json', sb + 'new-1.json',\n      sb + 'new-2.json', sb + 'new-3.json'],\n    [],\n    opts,\n    ' (5|BOTH)'\n  ],\n\n  [ 'analyze',\n    [ft + 'jane-fullstacker.json'],\n    [],\n    opts,\n    ' (jane-q-fullstacker|FRESH)'\n  ],\n\n  [ 'analyze',\n    ['node_modules/fresh-test-resumes/src/jrs/richard-hendriks.json'],\n    [],\n    opts2,\n    ' (richard-hendriks|JRS)'\n  ],\n\n  [ 'build',\n    [ ft + 'jane-fullstacker.json', ft + 'override/jane-fullstacker-override.fresh.json' ],\n    [ sb + 'merged/jane-fullstacker-gamedev.fresh.all'],\n    opts,\n    ' (jane-q-fullstacker w/ override|FRESH)'\n  ],\n\n  [ 'build',\n    [ ft + 'override/jane-partial-a.json', ft + 'override/jane-partial-b.json',\n      ft + 'override/jane-partial-c.json' ],\n    [ sb + 'merged/jane-abc.fresh.all'],\n    opts,\n    ' (jane merge A + B + C|FRESH)',\n    function( r ) {\n      var expected = [\n        'name','meta','info', 'contact', 'location', 'projects', 'social',\n        'employment', 'education', 'affiliation', 'service', 'skills',\n        'samples', 'writing', 'reading', 'speaking', 'recognition',\n        'references', 'testimonials', 'languages', 'interests',\n        'extracurricular', 'governance'\n      ];\n\n      Object.keys( _.pick( r, expected ) ).length\n        .should.equal( expected.length );\n    }\n  ],\n\n  [ '!build',\n    [ ft + 'jane-fullstacker.json'],\n    [ sb + 'shouldnt-exist.pdf' ],\n    EXTEND(true, {}, opts, { theme: 'awesome' }),\n    ' (jane-q-fullstacker + Awesome + PDF|FRESH)'\n  ]\n\n];\n\n// Set up the main test suite for the API interface\ndescribe('Testing API interface', function () {\n\n  this.timeout(5000);\n\n  function run( verb, src, dst, opts, msg, fnTest ) {\n\n    msg = msg || '.';\n    var shouldSucceed = true;\n    if( verb[0] === '!' ) {\n      verb = verb.substr(1);\n      shouldSucceed = false;\n    }\n\n    it( 'The ' + verb.toUpperCase() + ' command should ' +\n        (shouldSucceed ? ' SUCCEED' : ' FAIL') + msg, function (done) {\n\n      var v = new FCMD.verbs[verb]();\n      v.on('hmr:error', function(ex) {\n        assert(false);\n      });\n      var prom = v.invoke( src, dst, opts );\n      var fulfillMethod = shouldSucceed ? 'fulfilled' : 'rejected';\n\n      if( fnTest ) {\n        prom.should.be[ fulfillMethod ].then( function( obj ) {\n          fnTest(obj.sheet);\n        }).should.notify(done);\n      }\n      else {\n        prom.should.be[fulfillMethod].notify(done);\n      }\n\n    });\n\n  }\n\n  tests.forEach( function(a) {\n    run.apply( /* The players of */ null, a );\n  });\n\n});\n"
  }
]