[
  {
    "path": ".circleci/config.yml",
    "content": "# Javascript Node CircleCI 2.0 configuration file\n#\n# Check https://circleci.com/docs/2.0/language-javascript/ for more details\n#\nversion: 2\njobs:\n  build:\n    docker:\n      # specify the version you desire here\n      # - image: circleci/node:10\n      - image: cypress/base:10\n\n      # Specify service dependencies here if necessary\n      # CircleCI maintains a library of pre-built images\n      # documented at https://circleci.com/docs/2.0/circleci-images/\n      # - image: circleci/mongo:3.4.4\n\n    working_directory: ~/repo\n\n    steps:\n      - checkout\n\n      # Download and cache dependencies\n      - restore_cache:\n          keys:\n            - v1-dependencies-{{ checksum \"package.json\" }}\n            # fallback to using the latest cache if no exact match is found\n            - v1-dependencies-\n\n      - run: yarn\n\n      - save_cache:\n          paths:\n            - node_modules\n          key: v1-dependencies-{{ checksum \"package.json\" }}\n\n      # run tests!\n      - run: yarn test\n"
  },
  {
    "path": ".gitignore",
    "content": "dist\npublic\ncoverage\nnode_modules\npackage-lock.json\npublic\n.cache\ncypress/videos\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"semi\": false,\n  \"singleQuote\": true,\n  \"trailingComma\": \"es5\",\n  \"jsxBracketSameLine\": true\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n- Add missing dependency\n\n## v4.1.0\n\n- Update colors on notes theme\n- Add support for static asset directory\n\n## v4.0.0\n\n- Refactored implementation for `mdx-deck` CLI\n- New `Header` and `Footer` components for adding persistent header and footer content\n- **Deprecated:** CLI `eject` command\n- **Deprecated:** Swipe gestures - to be replaced with new UI\n- **Deprecated:** Title is no longer inferred from first heading\n- **Deprecated:** `export const themes` has been removed - merge themes in a separate module if needed\n- **Deprecated:** Functional themes are no longer supported, merge themes in a separate module if needed\n- **Deprecated:** `theme.Provider` - use `Header` and `Footer` components instead\n- **Deprecated:** Fixed aspect ratio has been removed\n- Bug fixes\n- Update dependencies\n- **Deprecated:** `gatsby-theme-mdx-deck`: no longer resolves title from first heading\n\n## v3.1.0 2020-02-01\n\n- Update dependencies\n- Adjust schema customization in Gatsby theme\n\n## v3.0.13 2019-09-23\n\n- Adjust Gatsby content digest\n\n## v3.0.12 2019-09-23\n\n- Update dependencies\n\n## v3.0.11 2019-09-10\n\n- Add support for up and down keys #467\n- Fix for double slash in print route #473\n\n## v3.0.10 2019-09-05\n\n- Add remark-import-code #457\n- Fix pathname in windows #465\n\n## v3.0.9 2019-08-05\n\n- Fix for remounting component #428\n\n## v3.0.8 2019-07-28\n\n- Add support for Gatsby `pathPrefix` option\n\n## v3.0.0 2019-07-16\n\n- Refactored to leverage Gatsby\n- Rewritten CLI based on Gatsby\n- Updated Gatsby theme to allow for component shadowing\n- Gatsby theme has been renamed to `gatsby-theme-mdx-deck`\n- Now uses [Theme UI](https:/theme-ui.com) for theming\n- Improved touchscreen and mobile views\n- Deprecated:\n  - `@mdx-deck/components`\n  - `@mdx-deck/layouts`\n  - `@mdx-deck/loader`\n  - `@mdx-deck/mdx-plugin`\n  - `@mdx-deck/webpack-html-plugin`\n\nSee the [Migration](MIGRATION.md) docs for more\n\n## v2.5.1 2019-07-16\n\n- Fix loader #357\n\n## v2.5.0 2019-07-07\n\n- Update Gatsby theme to official API #389 #387 #385\n- Update docs #382\n\n## v2.4.0 2019-06-19\n\n- Add `useTheme` hook to API #359\n- Makes presenter mode themeable #366\n- Add support for `--webpack` flag #369\n\n## v2.3.2 2019-04-21\n\n- Fixed issue when Head only had one element #345\n\n## v2.3.1 2019-04-21\n\n- Add experimental support for fluid aspect ratios #342\n\n## v2.3.0 2019-04-20\n\n- Refactor localStorage to use hooks #334\n- Refactor keyboard shortcuts #335\n- Refactor query string to use hooks #336\n- Refactor to use hooks #337\n  - Adds `MDXDeckState` provider component\n  - Fixes an issue with rerenders in Gatsby theme\n  - Adjusts styles in grid mode\n  - Refactors `useSteps` to use effect hook\n\n## v2.2.3 2019-04-20\n\n- Refactor Head component #329\n\n## v2.2.2 2019-04-20\n\n- Fix typos #333\n- Refactor themes for better bundle sizes #328\n\n## v2.2.1 2019-04-15\n\n- Add support for page up/down keys #319\n- Fix: remove global styles from Embed component #331\n\n## v2.2.0 2019-04-13\n\n- Add Embed component #323\n- Adjust context passed to Slide component\n- Add default props to Slide to show all Appear steps\n- Adds header and footer components for shadowing in Gatsby theme\n- Refactor and clean up code\n\n## v2.1.4 2019-04-12\n\n- Add `mdx` option to Gatsby theme #325\n\n## v2.1.3 2019-04-12\n\n- Update docs for Gatsby theme #324\n\n## v2.1.2 2019-04-12\n\n- Bump dependencies to MDX 1.0.0 #322\n\n## v2.1.1 2019-04-11\n\n- Add support for single deck mode in Gatsby theme #320\n\n## v2.1.0 2019-04-11\n\n- Added Gatsby theme #318\n\n## v2.0.9 2019-04-05\n\n- Rename internal const #312\n\n## v2.0.8 2019-04-05\n\n- Update MDX #311\n\n## v2.0.7 2019-04-05\n\n- Add `--no-html` flag back #295\n\n## v2.0.6 2019-03-28\n\n- Pin alpha version of MDX #302\n\n## v2.0.5 2019-03-23\n\n- Update remark-unwrap-images #289\n- Update webpack config merging #290\n\n## v2.0.4 2019-03-23\n\n- Fix for css-loader #288\n\n## v2.0.3 2019-03-23\n\n- Fix for building decks with Google Fonts #287\n\n## v2.0.2 2019-03-23\n\n- Fix syntax error in theme #286\n\n## v2.0.1 2019-03-23\n\n- Add language support to syntax highlighter themes #278\n\n## v2.0.0 2019-03-16\n\n- Simplified custom mdx loader, removing unused front-matter support\n- Simplified theming and default styles\n- Removes default Provider component with dot indicator\n- Uses Reach Router - resolves issues with focus trapping\n- Removed PDF export and screenshots from core CLI - now available with the `@mdx-deck/export` package\n- Removed built-in syntax highlighting\n- Removed `notes` language attribute for fenced code blocks\n- Refactored dev server\n\n## v1.10.2 2019-03-10\n\n- Fix bad release\n\n## v1.10.1 2019-03-10\n\n- Prevent Appear children from disappearing during slide transition #253\n\n## v1.10.0 2019-02-18\n\n- Update to Babel 7\n\n## v1.9.0 2019-02-18\n\n- Fix for font size in nested lists #204\n- Add `--hot-port` option to CLI #206\n- Add support for `.jsx` file extensions #239\n- Fix typos in syntax highlighting component #250\n- Add context to grid view #187\n- Add `--no-sandbox` option to CLI #200\n- Surface compilation errors from webpack #252\n\n## v1.8.2 2018-12-04\n\n- Bugfix for window check\n\n## v1.8.1 2018-11-27\n\n- Show Appear children in PDF export\n\n## v1.8.0 2018-11-27\n\n- Adds button to open new window for presenting in presenter mode\n\n## v1.7.14 2018-11-18\n\n- Fix typo in SlideDeck\n\n## v1.7.13 2018-11-18\n\n- Add overflow auto to FullScreenCode\n\n## v1.7.12 2018-11-18\n\n- Keep styles intact for Appear children\n- Fix prop types for Appear component\n- Add missing CLI option to docs\n\n## v1.7.11 2018-11-18\n\n- Update remark-unwrap-images\n\n## v1.7.10 2018-11-12\n\n- Update dependencies\n\n## v1.7.9 2018-11-12\n\n- Update dependencies\n\n## v1.7.8 2018-11-12\n\n- Fix typo in Root prop types\n- Edit docs\n\n## v1.7.7 2018-09-22\n\n- Remove overflow hidden styles from body\n- Adds prettier\n\n## v1.7.6 2018-09-22\n\n- Changes styles to use `translate3d`\n- Add support for page up and page down keys\n\n## v1.7.5 2018-09-22\n\n- Add `Horizontal` layout component\n\n## v1.7.4 2018-09-15\n\n- Add `--host` option\n\n## v1.7.3 2018-09-05\n\n- Fix swipe direction on touchscreens\n\n## v1.7.1 2018-08-30\n\n- Fix for localStorage updater\n\n## v1.7.0 2018-08-29\n\n- Adds support for stepping through Appear component with left and right arrows #144\n- Refactor internal context\n\n## v1.6.9 2018-08-27\n\n- Adds support for custom webpack configs #136\n\n## v1.6.8 2018-08-27\n\n- Fixes `build` when using Notes or Appear components #138\n- Fixes slide number in presenter mode #142\n\n## v1.6.7 2018-08-25\n\n- Use `mkdirp` for build and export\n- Adds ability to change slide transition timing function and duration via themes\n\n## v1.6.6 2018-08-25\n\n- Left align text in code blocks #130\n- Extract static CSS on build #129\n- Adds `--no-html` option for client-side only builds\n\n## v1.6.5 2018-08-25\n\n- Adjust slide number in overview mode #122\n\n## v1.6.4 2018-08-18\n\n- Add respository field to package.json #117\n- Remove trailing comma in function arguments #115\n\n## v1.6.3 2018-08-16\n\n- Disable swiping with mouse #113\n\n## v1.6.2 2018-08-15\n\n- Adjust import/export parsing in loader #110\n\n## v1.6.1 2018-08-15\n\n- Add missing `babel-core` dependency\n\n## v1.6.0 2018-08-14\n\n- Adds `Head` component for setting document head\n- Adds screenshot command to create a screenshot of the first slide\n- Removes the `--title` option in favor of using the `Head` component\n\n## v1.5.15 2018-08-11\n\n- Adds swipe gesture support for touchscreen devices\n- Fixes URL bug when initializing mode\n- Fixes bug previous/next buttons are not rendered\n- Prevents last slide from cycling back to the beginning\n\n## v1.5.14 2018-08-10\n\n- Adds `size` prop to Image component\n\n## v1.5.13 2018-08-10\n\n- Fixes an issue where speaker notes would incorrectly show on the wrong slide\n\n## v1.5.12 2018-08-10\n\n- Add FullScreenCode layout component\n\n## v1.5.11 2018-08-10\n\n- Adjust querystring updater to fix mode showing as undefined\n\n## v1.5.10 2018-08-05\n\n- Update overview mode styles\n- Add grid view mode\n- Update docs\n\n## v1.5.9 2018-08-05\n\n- Update docs\n\n## v1.5.8 2018-08-05\n\n- Add support for `components` and `Provider` in themes\n\n## v1.5.7 2018-08-05\n\n- Add more built-in themes\n\n## v1.5.6 2018-08-05\n\n- Add invisible buttons to left and right for use on mobile devices\n\n## v1.5.5 2018-08-05\n\n- Update docs\n\n## v1.5.4 2018-08-04\n\n- Add docs for syntax highlighting\n\n## v1.5.3 2018-08-04\n\n- Add overview mode to see multiple slides at once\n- Add default layouts for inverting colors and creating a split layout slide\n\n## v1.5.2 2018-08-04\n\n- Add default styles for tables\n\n## v1.5.1 2018-08-04\n\n- Use remark-unwrap-images plugin\n\n## v1.5.0 2018-08-04\n\n- Add syntax highlighting option for fenced code blocks\n\n## v1.4.4 2018-08-04\n\n- Fix for how Appear children display on slide change\n\n## v1.4.3 2018-08-04\n\n- Update build setup for smaller package\n- Adjust keyboard shortcuts\n\n## v1.4.2 2018-08-03\n\n- Update ok-cli for better HTML output\n\n## v1.4.1 2018-08-03\n\n- Update docs\n- Add `yellow` theme\n\n## v1.4.0 2018-08-03\n\n- Adds Appear component\n- Adds propTypes to components\n- Update README\n\n## v1.3.2 2018-08-02\n\n- Remove default `target=\"_blank\"` from links\n- Move custom Provider component into app\n\n## v1.3.1 2018-08-02\n\n- Add speaker notes markdown syntax and component\n\n## v1.3.0 2018-08-02\n\n- Add presenter mode with preview of next slide and timer\n\n## v1.2.3 2018-08-01\n\n- Fix `history.pushState` hash\n\n## v1.2.2 2018-07-31\n\n- Update dev server for static file server\n\n## v1.2.1 2018-07-31\n\n- Merge custom components with defaults\n\n## v1.2.0 2018-07-31\n\n- Add PDF export to CLI\n\n## v1.1.3 2018-07-31\n\n- Add emoji support\n- Update `.npmignore`\n\n## v1.1.2 2018-07-31\n\n- Fix `--no-open` option\n- Add ability to ignore key events\n- Normalize newlines for cross-platform compatibility\n\n## v1.1.1 2018-07-31\n\n- Fix for supporting markdown tables\n\n## v1.1.0 2018-07-30\n\n- Updated styles and theming\n- Updated docs\n\n## v1.0.3 2018-07-29\n\n- Updated docs\n\n## v1.0.2 2018-07-29\n\n- Add hashchange listeners\n\n## v1.0.1 2018-07-29\n\n- Fix for `--out-dir` CLI flag\n\n## v1.0.0 2018-07-29\n\nInitial release\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nThanks for contributing!\n\nPlease take a look at the issues and PRs to see if there's already some discussion around any contribution you'd like to make.\nIf you'd like to make a significant change to the code base, please open an issue for discussion first,\notherwise we'd love to have your help!\n\n## Development\n\nThis project is set up as a monorepo using Yarn Workspaces.\n\n1. Clone the repo\n2. Install dependencies with `yarn`\n3. Run `yarn start` to see the demo `docs/demo.mdx`\n\n### Watch mode\n\nTo watch files for changes during development, run `npm run watch`\n\n## Testing\n\nTests are located in each package.\n\nRun `yarn test`\n\n- Watch Mode: `yarn test --watch`\n- Coverage: `yarn test --coverage`\n\n---\n\n# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or\n- advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic\n- address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at jxnblk@gmail.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n"
  },
  {
    "path": "LICENSE.md",
    "content": "\n# The MIT License (MIT)\nCopyright (c) 2018 Brent Jackson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "MIGRATION.md",
    "content": "# Migration\n\n## Upgrading to MDX Deck v4\n\nFor simple decks, upgrading to v4 should not require any major changes and should help resolve an issue when making changes to a file while the development server is running.\n\n- If you are using a custom `Provider` component, replace this component with the new `Header` and `Footer` components\n  - Note that some functionality previously available in the Provider component is no longer possible\n- Replace any instance of the `Appear` component with the new `Steps` component. This should be a 1:1 change.\n- The document title is no longer inferred from the first heading. Use the `Head` component with a `<title>` element instead.\n- Merging multiple themes using `export const themes` is no longer supported. Merge themes in a separate file, if necessary.\n- Functional themes are no longer supported.\n- Fixed aspect ratio is no longer supported.\n- Swipe gestures have been removed; these will be reintroduced in a later version.\n- If you are using `gatsby-theme-mdx-deck` directly, no major changes have been made to this package.\n\n## Upgrading to MDX Deck v3\n\n- The `export default` syntax for slide layouts is no longer supported. Replace this syntax with the layout component wrapped around the slide content instead.\n- The following packages have been deprecated. Import components directly from the `mdx-deck` package instead.\n  - `@mdx-deck/components`\n  - `@mdx-deck/layouts`\n  - `@mdx-deck/mdx-plugin`\n  - `@mdx-deck/loader`\n  - `@mdx-deck/webpack-html-plugin`\n- The Gatsby theme package as been renamed: `gatsby-theme-mdx-deck`\n- Theming now uses [Theme UI][], and the theme format has changed.\n  - See the [theming docs](/docs/theming.md) for information on creating custom themes.\n  - **Or** use the `convertLegacyTheme` utility to shim themes written in the v2 format\n- The standalone CLI has been rewritten with Gatsby, and the following CLI flags are no longer supported:\n  - `--webpack` - use the Gatsby theme directly to customize webpack features\n  - `--out-dir` - decks are now built in the `public/` directory\n  - `--no-html` - individual slides are rendered client side, but the first slide is always rendered as static HTML using Gatsby\n- Custom `Presenter` components can no longer be added to a theme. Use the component shadowing API with the Gatsby theme instead.\n- Multiple MDX files can no longer be combined into a single presentation\n\n[theme ui]: https://theme-ui.com\n\n## Upgrading to MDX Deck v2\n\nWith a few exceptions, decks created with v1 should be compatible with v2. The following is a list of steps to ensure your slide deck will work with v2.\n\n### Slide separator spacing\n\nWith v2, MDX Deck now splits slides based on the Remark AST's `thematicBreak` node. This means that the `---` (`<hr>`) used for splitting slides **must** have empty newlines surrounding it due to markdown syntax.\n\nFor example, the following **will not** be split into a new slide, but instead will be treated as a Setext-style heading:\n\n```md\nHello\n---\nNot another slide\n```\n\nTo fix this, be sure all slides are separated with empty newlines around the `---`:\n\n```md\nHello\n\n---\n\nAnother slide\n```\n\n### Syntax Highlighting\n\nIn v1, `react-syntax-highligher` was bundled with the `mdx-deck` package. This not only led to larger install sizes for people who were not using syntax highlighting, but also limited the API available and prevented the ability to update the syntax highlighting package separately from MDX Deck.\n\nTo enable syntax highlighting in v2, it's recommended to create a syntax highlighting theme that consists of one custom `code` component and use [composable themes][] to enable syntax highlighting with other themes.\n\n[composable themes]: docs/theming.md#composing-themes\n\n### Custom Layouts\n\nIf you've built custom layout components for your deck, the `children` prop should now be a flatter array of direct child elements from the slide.\n\nFor example, if you previously parsed children in your layout component, you should make the following change:\n\n```jsx\n// v1\nconst children = React.Children.toArray(props.children.props.children)\n```\n\n```jsx\n// updated for v2\nconst children = React.Children.toArray(props.children)\n```\n\n### Theming\n\nIf you've built a custom theme, some of the theming API has changed.\nPlease refer to the [theming docs](docs/theming.md) for more info, and note that MDX Deck now uses [Emotion][] for theming.\n\n### Third-Party Components\n\nSome third-party components that rely on MDX Deck internal APIs _may_ not work with v2 yet. Please be patient and give library authors time to release new versions that are compatible with v2.\n\nIf you absolutely must use one of these libraries, you can continue to use v1 for the time being.\n\n### Library Authors\n\nIf you've built a library or component that is meant for use with MDX Deck and relied on its internal state, you can try leveraging the new `useSteps` React hook available in the `@mdx-deck/components` package.\n\nFeel free to reach out by opening an issue for any assistance in upgrading your library to work with this library's internal APIs.\n\n[emotion]: https://emotion.sh\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n  presets: [\n    '@babel/preset-env',\n    '@babel/preset-react',\n  ],\n}\n"
  },
  {
    "path": "cypress/integration/hello.js",
    "content": "context('MDX Deck', () => {\n  beforeEach(() => {\n    cy.visit('http://localhost:8000')\n  })\n\n  it('opens', () => {\n    cy.visit('http://localhost:8000')\n  })\n\n  it('contains the title', () => {\n    cy.contains('MDX Deck')\n  })\n\n  /* doesn't work?? */\n  it('goes to the next slide', () => {\n    cy.get('body')\n      .trigger('keydown', {\n        keyCode: 39,\n      })\n      .contains('Presentation')\n  })\n})\n"
  },
  {
    "path": "cypress/plugins/index.js",
    "content": "// ***********************************************************\n// This example plugins/index.js can be used to load plugins\n//\n// You can change the location of this file or turn off loading\n// the plugins file with the 'pluginsFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/plugins-guide\n// ***********************************************************\n\n// This function is called when a project is opened or re-opened (e.g. due to\n// the project's config changing)\n\nmodule.exports = (on, config) => {\n  // `on` is used to hook into various events Cypress emits\n  // `config` is the resolved Cypress config\n}\n"
  },
  {
    "path": "cypress/support/commands.js",
    "content": "// ***********************************************\n// This example commands.js shows you how to\n// create various custom commands and overwrite\n// existing commands.\n//\n// For more comprehensive examples of custom\n// commands please read more here:\n// https://on.cypress.io/custom-commands\n// ***********************************************\n//\n//\n// -- This is a parent command --\n// Cypress.Commands.add(\"login\", (email, password) => { ... })\n//\n//\n// -- This is a child command --\n// Cypress.Commands.add(\"drag\", { prevSubject: 'element'}, (subject, options) => { ... })\n//\n//\n// -- This is a dual command --\n// Cypress.Commands.add(\"dismiss\", { prevSubject: 'optional'}, (subject, options) => { ... })\n//\n//\n// -- This is will overwrite an existing command --\n// Cypress.Commands.overwrite(\"visit\", (originalFn, url, options) => { ... })\n"
  },
  {
    "path": "cypress/support/index.js",
    "content": "// ***********************************************************\n// This example support/index.js is processed and\n// loaded automatically before your test files.\n//\n// This is a great place to put global configuration and\n// behavior that modifies Cypress.\n//\n// You can change the location of this file or turn off\n// automatically serving support files with the\n// 'supportFile' configuration option.\n//\n// You can read more here:\n// https://on.cypress.io/configuration\n// ***********************************************************\n\n// Import commands.js using ES2015 syntax:\nimport './commands'\n\n// Alternatively you can use CommonJS syntax:\n// require('./commands')\n"
  },
  {
    "path": "cypress.json",
    "content": "{\n  \"baseUrl\": \"http://localhost:8000/\"\n}\n"
  },
  {
    "path": "docs/Counter.js",
    "content": "import React from 'react'\nimport styled from '@emotion/styled'\nimport { space, color } from 'styled-system'\n\nconst Root = styled.div({\n  display: 'flex',\n  alignItems: 'center',\n})\n\nconst Button = styled.button(\n  {\n    appearance: 'none',\n    fontFamily: 'inherit',\n    fontSize: 'inherit',\n    fontWeight: 'bold',\n    borderRadius: '4px',\n    border: 'none',\n    width: '2em',\n    '&:focus': {\n      outline: 'none',\n      boxShadow: '0 0 0 2px magenta',\n    },\n  },\n  space,\n  color\n)\nButton.defaultProps = {\n  m: 0,\n  px: 3,\n  py: 2,\n  color: 'background',\n  bg: 'text',\n}\n\nconst Samp = styled.samp(space)\n\nexport default class Counter extends React.Component {\n  state = {\n    count: 0,\n  }\n\n  inc = () => {\n    this.setState(state => ({ count: state.count + 1 }))\n  }\n\n  dec = () => {\n    this.setState(state => ({ count: state.count - 1 }))\n  }\n\n  render() {\n    return (\n      <Root>\n        <Button ml=\"auto\" onClick={this.dec}>\n          -\n        </Button>\n        <Samp mx={3}>{this.state.count}</Samp>\n        <Button mr=\"auto\" onClick={this.inc}>\n          +\n        </Button>\n      </Root>\n    )\n  }\n}\n"
  },
  {
    "path": "docs/api.md",
    "content": "# API\n\n## Components\n\n- `Head`: Adds elements to the document `<head>`\n- `Notes`: Adds speaker notes to a slide\n- `Steps`: Steps through child elements one-by-one\n\n\n## `useSteps`\n\nThe `useSteps` hook can be used to register custom components that rely on multiple \"steps\" within a single slide,\nsimilar to the Appear component.\nThe hook takes one argument for the total `length` of steps and returns the current `step` state.\n\n```jsx\n// example\nimport React from 'react'\nimport { useSteps } from 'mdx-deck'\n\nexport default props => {\n  const length = 4\n  const step = useSteps(length)\n\n  return (\n    <h2>\n      The current step is {step}/{length}\n    </h2>\n  )\n}\n```\n\n## `useDeck`\n\nThe `useDeck` hook returns the MDX Deck state.\n\n"
  },
  {
    "path": "docs/components.md",
    "content": "# Components\n\nMDX Deck includes components to help with creating presentations.\nThese components are provided with MDX's *shortcodes* functionality, so they do not need to be imported.\n\n## Head\n\nUse the `Head` component to set content in the document head.\n\n```mdx\n// example for twitter cards\n\n<Head>\n  <title>My Presentation</title>\n  <meta name=\"twitter:card\" content=\"summary_large_image\" />\n  <meta name=\"twitter:site\" content=\"@jxnblk\" />\n  <meta name=\"twitter:title\" content=\"My Presentation\" />\n  <meta name=\"twitter:description\" content=\"A really great presentation\" />\n  <meta name=\"twitter:image\" content=\"https://example.com/card.png\" />\n</Head>\n```\n\n## Notes\n\nSpeaker notes that only show in presenter mode can be added to any slide with the `Notes` component.\n\n```mdx\n# Slide Content\n\n<Notes>\n\n- Only visible in presenter mode\n- Markdown syntax can be used with empty lines around the content\n\n</Notes>\n```\n\n## Header\n\nUse the `Header` component to render a persistent header (at the top of the screen) across the entire presentation.\n\n```mdx\n<Header>\n\nPut a logo, handle, or something else here...\n\n</Header>\n\n# My Presentation\n\n```\n\n## Footer\n\nThe `Footer` component renders a persistent footer (at the bottom of the screen) across the entire presentation.\n\n```mdx\n<Footer>\n\nPut a logo, handle, or something else here...\n\n</Footer>\n\n# My Presentation\n\n```\n\n## Steps\n\nUse the `Steps` (formerly `Appear`) component to make child elements appear one at a time within a single slide.\nUse the left and right arrow keys to step through each element.\n\n```mdx\n\n<Steps>\n\n- One\n- Two\n- Three\n- Four\n\n</Steps>\n```\n\nInternally, the `Steps` component uses the `useSteps` hook, which can be used to build custom components with similar behavior.\n\n\n<!--\n## Image\n\nUse the `Image` component to render a fullscreen image with the CSS `background-image` property.\n\n```mdx\nimport { Image } from 'mdx-deck'\n\n<Image src=\"kitten.png\" />\n```\n\n```mdx\nimport { Image } from 'mdx-deck'\n\n<Image src='kittens.png'>\n\n# Kittens\n\n</Image>\n```\n\n**Props**\n\n- `src` (string) image URL\n- `size` (string) CSS background-size\n\n## Embed\n\n**Experimental**\n\nThe `Embed` component is intended for use **outside** of an MDX Deck to render a preview of a particular slide.\nThis can be used to embed slide previews in other places, like a blog post write-up of a presentation.\n\n```jsx\nimport React from 'react'\nimport { Embed } from 'mdx-deck'\nimport deck from './my-deck.mdx'\n\nexport default props => (\n  <>\n    <h2>Second Slide</h2>\n    <Embed src={deck} slide={2} />\n  </>\n)\n```\n-->\n"
  },
  {
    "path": "docs/demo.mdx",
    "content": "import Counter from './Counter'\n\n<Head>\n  <title>MDX Deck</title>\n  <meta name='twitter:card' content='summary_large_image' />\n  <meta name='twitter:site' content='@jxnblk' />\n  <meta name='twitter:title' content='mdx-deck' />\n  <meta name='twitter:description' content='MDX-based presentation decks' />\n  <meta name='twitter:image' content='https://jxnblk.com/mdx-deck/card.png' />\n</Head>\n\n# MDX Deck\n\nMDX-based presentation decks\n\n---\n\n# Presentation decks\n\n---\n\n# Built with [MDX][]\n[MDX]: https://github.com/mdx-js/mdx\n\n---\n\n### Import and Use React Components\n\n<Counter />\n\n---\n\n- Make bulleted lists\n- To help make your point\n\n---\n\n## Getting Started\n\n1. `npm i -D mdx-deck`\n2. Write in markdown and JSX\n3. Present\n\n---\n\n## Features\n\n- Presenter Mode\n- Speaker Notes\n- Theming\n\n---\n\n```jsx\n<button>code example</button>\n```\n\n<Notes>\n\n- These are speaker notes\n- And they won't be rendered in your slide\n\n</Notes>\n\n---\n\n```jsx\nclass extends React.Component {\n  render () {\n    return (\n      <React.Fragment>\n        <h1>Indented code</h1>\n      </React.Fragment>\n    )\n  }\n}\n```\n\n---\n\n> “Blockquotes are essential to any good presentation”\n\n– Anonymous\n\n<Notes>\n  <ul>\n    <li>Speaker notes can also be</li>\n    <li>Written in JSX</li>\n  </ul>\n</Notes>\n\n---\n\n### Steps Component\n\n<Steps>\n\n- One\n- Two\n- Three\n- Four\n\n</Steps>\n\n---\n\n<img src='https://source.unsplash.com/random/768x2048?new_york' />\n\n<Notes>\nTesting object fit\n</Notes>\n\n---\n\n<img src='https://images.unsplash.com/photo-1462331940025-496dfbfc7564?new_york&w=2048&q=20' />\n\n---\n\n![](https://images.unsplash.com/photo-1462331940025-496dfbfc7564?new_york&w=2048&h=1024&q=20&fit=crop)\n\nInline image\n\n---\n\nProp | Type | Description\n---|---|---\n`width` | number, string, or array | sets element width\n`color` | string | sets foreground color\n`bg` | string | sets background color\n\n---\n\n<Invert>\n\n# Get started :sunglasses:\n\n[GitHub](https://github.com/jxnblk/mdx-deck)\n\n</Invert>\n\n"
  },
  {
    "path": "docs/exporting.md",
    "content": "# Exporting\n\n## Static Build\n\nTo export your deck as a static HTML page with JS bundle,\nadd a `build` script to your `package.json` file.\n\n```json\n\"scripts\": {\n  \"build\": \"mdx-deck build deck.mdx\"\n}\n```\n\n## PDF\n\nTo export a deck as PDF, use the [`website-pdf`](https://www.npmjs.com/package/website-pdf) CLI.\nStart the MDX Deck dev server,\nthen run the following command to create a PDF:\n\n```sh\nnpx website-pdf http://localhost:8000/print -o deck.pdf\n```\n\n## PNG\n\nTo export a PNG image, use the [`capture-website-cli`](https://github.com/sindresorhus/capture-website-cli) CLI.\nStart the dev server, then run the following:\n\n```sh\nnpx capture-website-cli http://localhost:8000 deck.png\n```\n\n## Open Graph Image\n\nTo add an open graph image, use the [Head](components.md#Head) component to add a meta tag.\nNote that the meta tag should point to a full URL, including schema and domain name.\n\n```mdx\nimport { Head } from 'mdx-deck'\n\n<Head>\n  <meta name=\"og:image\" content=\"https://example.com/card.png\" />\n</Head>\n```\n"
  },
  {
    "path": "docs/gatsby.md",
    "content": "\n# Usage with Gatsby\n\nMDX Deck includes a Gatsby theme, which can be used in any existing Gatsby site.\nThis means you can install MDX Deck as a theme within an existing Gatsby site to include presentations along with other content, such as a landing page or blog.\nThe theme also supports adding multiple presentations to a single site.\n\nInstall the theme in your Gatsby site.\n\n```sh\nnpm i gatsby-theme-mdx-deck\n```\n\nAdd the theme to the `plugins` array in your configuration.\n\n```js\n// gatsby-config.js\nmodule.exports = {\n  plugins: [\n    'gatsby-theme-mdx-deck',\n  ]\n}\n```\n\nCreate a directory to store your presentations.\n\n```sh\nmkdir decks\n```\n\nAdd MDX Deck presentations to this directory.\nEach deck will create a new page using the filename as its route.\n\n```mdx\n<!-- decks/hello.mdx -->\n\n# Hello\n\n---\n\nThis is my presentation\n```\n\nAfter running `gatsby develop`, this presentation should be viewable at `http://localhost:8000/hello` .\n\n## Component Shadowing\n\nBecause MDX Deck is built as a Gatsby theme, you can leverage the component shadowing API to override any part of the interface\nand create child themes based on MDX Deck that provide custom behavior.\n\nSee the [gatsby-theme-mdx-deck](../packages/gatsby-theme) docs for more documentation and options.\n"
  },
  {
    "path": "docs/layouts.md",
    "content": "# Layouts\n\nEach slide can include a custom layout around its content.\nThis is a way to provide *templates* for certain slides.\n\n```js\n// example Layout.js\nimport React from 'react'\n\nexport default ({ children }) => (\n  <div\n    style={{\n      width: '100vw',\n      height: '100vw',\n      backgroundColor: 'tomato',\n    }}\n  >\n    {children}\n  </div>\n)\n```\n\n```mdx\nimport Layout from './Layout'\n\n# No Layout\n\n---\n\n<Layout>\n\n# Custom Layout\n\n</Layout>\n```\n\nThe layout component will wrap the MDX elements within that slide,\nwhich means you can use a nested ThemeProvider or target elements with CSS-in-JS.\n\n**NOTE:** The newlines around child content in the layout component is **required** to use markdown syntax in a layout. Otherwise the content will be parsed as raw text.\n\n## Built-in Layouts\n\nMDX Deck includes a few built-in layouts for common slide variations.\n\n### Invert\n\nInverts the foreground and background colors from the theme.\n\n```mdx\nimport { Invert } from 'mdx-deck'\n\n# Normal\n\n---\n\n<Invert>\n\n# Inverted\n\n</Invert>\n```\n\n### Split\n\nCreates a horizontal layout with the first child on the left and all other children on the right.\n\n```mdx\nimport { Split } from 'mdx-deck'\n\n<Split>\n\n![](kitten.png)\n\n## Meow\n\n</Split>\n```\n\n### SplitRight\n\nSame as the Split component, but renders the first child on the right.\n\n```mdx\nimport { SplitRight } from 'mdx-deck'\n\n<SplitRight>\n\n![](kitten.png)\n\n## Meow\n\n</SplitRight>\n```\n\n### Horizontal\n\nSimilar to the Split components, but renders all children side-by-side\n\n### FullScreenCode\n\nRenders code blocks fullscreen.\n\n````mdx\nimport { FullScreenCode } from 'mdx-deck'\n\n<FullScreenCode>\n\n```jsx\n<Button>Beep</Button>\n```\n\n</FullScreenCode>\n````\n\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/docs\",\n  \"version\": \"4.1.1\",\n  \"main\": \"index.js\",\n  \"author\": \"Brent Jackson <jxnblk@gmail.com>\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"mdx-deck demo.mdx\",\n    \"build\": \"mdx-deck build demo.mdx\"\n  },\n  \"dependencies\": {\n    \"@emotion/core\": \"^10.0.7\",\n    \"@emotion/styled\": \"^10.0.7\",\n    \"mdx-deck\": \"^4.1.1\",\n    \"styled-system\": \"^5.0.15\"\n  }\n}\n"
  },
  {
    "path": "docs/presenting.md",
    "content": "\n# Presenting\n\n1. Enter presenter mode by pressing `Opt + P`\n2. Click the link at the bottom to open the presentation in another tab\n3. Move the new tab to its own window in the screen or projector that the audience sees\n4. Control the presentation from the original window\n5. Be sure to hide your mouse cursor so that it's not visible to the audience\n\n## Speaker Notes\n\nNotes that only show in presenter mode can be added to any slide\nby using the `<Notes />` component.\n\n```mdx\nimport { Notes } from 'mdx-deck'\n\n# Slide Content\n\n<Notes>\nOnly visible in presenter mode\n</Notes>\n```\n"
  },
  {
    "path": "docs/themes.md",
    "content": "# Themes\n\n![Default theme](images/default.png)\n\n---\n\n![Big theme](images/big.png)\n\n```js\nimport { big } from 'mdx-deck/themes'\n```\n\n---\n\n![Book theme](images/book.png)\n\n```js\nimport { book } from 'mdx-deck/themes'\n```\n\n---\n\n![Code theme](images/code.png)\n\n```js\nimport { code } from 'mdx-deck/themes'\n```\n\n---\n\n![Comic theme](images/comic.png)\n\n```js\nimport { comic } from 'mdx-deck/themes'\n```\n\n---\n\n![Condensed theme](images/condensed.png)\n\n```js\nimport { condensed } from 'mdx-deck/themes'\n```\n\n---\n\n![Dark theme](images/dark.png)\n\n```js\nimport { dark } from 'mdx-deck/themes'\n```\n\n---\n\n![Future theme](images/future.png)\n\n```js\nimport { future } from 'mdx-deck/themes'\n```\n\n---\n\n![Hack theme](images/hack.png)\n\n```js\nimport { hack } from 'mdx-deck/themes'\n```\n\n---\n\n![Notes theme](images/notes.png)\n\n```js\nimport { notes } from 'mdx-deck/themes'\n```\n\n---\n\n![Script theme](images/script.png)\n\n```js\nimport { script } from 'mdx-deck/themes'\n```\n\n---\n\n![Swiss theme](images/swiss.png)\n\n```js\nimport { swiss } from 'mdx-deck/themes'\n```\n\n---\n\n![Yellow theme](images/yellow.png)\n\n```js\nimport { yellow } from 'mdx-deck/themes'\n```\n\n---\n\nPoppins\n\n```js\nimport { poppins } from 'mdx-deck/themes'\n```\n\n"
  },
  {
    "path": "docs/theming.md",
    "content": "# Theming\n\nMDX Deck uses [Theme UI][] and [Emotion][] for styling, making practically any part of the presentation themeable.\n\n## Built-in Themes\n\nMDX Deck includes several built-in themes to change the look and feel of the presentation.\nExport `theme` from your MDX file to enable a theme.\n\n```mdx\nimport { themes } from 'mdx-deck'\n\nexport const theme = themes.dark\n\n# Dark Theme\n```\n\nView the [Themes](themes.md) docs to see all available themes.\n\n## Custom Themes\n\nA custom theme can be provided by exporting `theme` from the MDX file.\n\n```mdx\nimport myTheme from './theme'\n\nexport const theme = myTheme\n\n# Hello\n```\n\nThemes are based on [Theme UI][] and support customizing typography, color, layout, and other element styles.\n\n```js\n// Example theme.js\nexport default {\n  fonts: {\n    body: 'Roboto, sans-serif',\n    monospace: '\"Roboto Mono\", monospace',\n  },\n  colors: {\n    text: 'white',\n    background: 'black',\n    primary: 'blue',\n  },\n}\n```\n\n## Composing Themes\n\nTo compose multiple themes together, merge the objects together into a single theme and export that theme from your deck.\n\n## Google Fonts\n\nThemes can specify a `googleFont` field to automatically add a `<link>` tag to the document head.\nAlternatively, use the `<Head />` component to add a custom `<link>` tag.\n\n## Syntax Highlighting\n\nBy default fenced code blocks do not include any syntax highlighting.\nThemes can provide a set of custom MDX components, including a replacement for the default `code` component that can add syntax highlighting with libraries like [react-syntax-highlighter][].\n\nMDX Deck includes two themes for adding syntax highlighting with [react-syntax-highlighter][]: `highlight` and `prism`.\n\n```mdx\nimport { themes } from 'mdx-deck'\n\nexport const theme = {\n  ...themes.prism\n}\n```\n\nSince MDX supports using React components inline, you can also import a syntax highlighting component directly, if you prefer.\n\n```mdx\nimport Highlighter from 'react-syntax-highlighter'\n\n<Highlighter language='javascript'>\n{`export const hello = 'hi'`}\n</Highlighter>\n```\n\n## Styling Elements\n\nAdd a `theme.styles` object to style specific markdown elements.\n\n```js\n// example theme\nexport default {\n  styles: {\n    h1: {\n      textTransform: 'uppercase',\n      letterSpacing: '0.1em',\n    },\n    blockquote: {\n      fontStyle: 'italic',\n    },\n  }\n}\n```\n\n## Reference\n\n- `colors`: object of colors used for MDX components\n  - `text`: root foreground color\n  - `background`: root background color\n  - `primary`: primary color\n- `fonts.body`: base font family\n- `fonts.heading`: heading font family\n- `fonts.monospace`: font family for `<pre>` and `<code>`\n- `text.heading`: styles for all headings\n- `styles`: Theme UI styles for MDX elements\n- `styles.Slide`: styles for the wrapping Slide component\n- `styles.Header`: styles for the Header component\n- `styles.Footer`: styles for the Footer component\n- `components`: object of MDX components\n- `googleFont`: Stylesheet URL for adding a Google Font\n\n[emotion]: https://emotion.sh\n[theme ui]: https://theme-ui.com\n[mdx]: https://github.com/mdx-js/mdx\n[react-syntax-highlighter]: https://github.com/conorhastings/react-syntax-highlighter\n"
  },
  {
    "path": "examples/README.md",
    "content": "\n# Examples\n\n- [Basic Example](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/basic)\n- [Multiple Decks](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/multiple)\n- [Syntax Highlighting](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/syntax-highlighting)\n- [Prism Syntax Highlighting](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/prism)\n- [Aspect Ratio](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/aspect-ratio)\n- [Layouts](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/layouts)\n- [Images](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/images)\n- [Appear](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/appear)\n- [Head](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/head)\n- [Provider](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/provider)\n- [Themes](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/themes)\n\n<!--\n- [useSteps](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/use-steps)\n- [useDeck](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/use-deck)\n-->\n"
  },
  {
    "path": "examples/aspect-ratio/deck.mdx",
    "content": "import { future, aspect } from 'mdx-deck/themes'\n\nexport const themes = [\n  future,\n  aspect,\n]\n\n# Hello!\n\n---\n\nThis deck is fluid to a 16:9 aspect ratio\n\n---\n\nImages will still render full bleed at other aspect ratios\n\n"
  },
  {
    "path": "examples/aspect-ratio/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/aspect-ratio-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/basic/deck.mdx",
    "content": "\n# Hello!\n\n---\n\nThis is MDX Deck\n"
  },
  {
    "path": "examples/basic/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/basic-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/gatsby/decks/beep.mdx",
    "content": "\n# Beep\n\n---\n\n## Boop\n\n---\n\nBop\n"
  },
  {
    "path": "examples/gatsby/decks/hello.mdx",
    "content": "\n# Hello\n\n---\n\nThis is built with gatsby-theme-mdx-deck\n"
  },
  {
    "path": "examples/gatsby/gatsby-config.js",
    "content": "module.exports = {\n  pathPrefix: '/mdx-deck',\n  plugins: [\n    'gatsby-plugin-catch-links',\n    {\n      resolve: 'gatsby-theme-mdx-deck',\n      options: {\n        basePath: '/slides',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "examples/gatsby/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/gatsby-example\",\n  \"version\": \"4.1.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"gatsby develop\",\n    \"clean\": \"gatsby clean\",\n    \"build\": \"gatsby build --prefix-paths\",\n    \"serve\": \"gatsby serve --prefix-paths\",\n    \"gh-pages\": \"npx gh-pages -d public\"\n  },\n  \"dependencies\": {\n    \"gatsby\": \"*\",\n    \"gatsby-plugin-catch-links\": \"^2.1.2\",\n    \"gatsby-theme-mdx-deck\": \"^4.1.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/gatsby/src/pages/index.mdx",
    "content": "\n# MDX Deck Gatsby Example\n\n- [Deck](/slides)\n"
  },
  {
    "path": "examples/head/deck.mdx",
    "content": "\n<Head>\n  <title>Hello</title>\n</Head>\n\n# Hello!\n\n---\n\nThis deck has a custom title\n\n"
  },
  {
    "path": "examples/head/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/head-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/header-footer/deck.mdx",
    "content": "\n<Header>\n\n# Header\n\n</Header>\n\n<Footer>\n\n[@jxnblk](https://twitter.com/jxnblk)\n\n</Footer>\n\n# Hello!\n\n---\n\nThis deck has a header and footer\n\n"
  },
  {
    "path": "examples/header-footer/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/header-footer-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/images/deck.mdx",
    "content": "import {\n  Image,\n} from 'mdx-deck'\n\n# Hello!\n\n---\n\n<Image\n  src='https://source.unsplash.com/random/768x2048?brooklyn'\n  style={{\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n    color: 'white',\n    backgroundColor: 'black',\n  }}>\n\n## Background Image\n\n</Image>\n\n\n"
  },
  {
    "path": "examples/images/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/images-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/layouts/deck.mdx",
    "content": "\n# Hello!\n\n---\n\n<Invert>\n\n## Invert Layout\n\n</Invert>\n\n---\n\n<Split>\n\n![](https://source.unsplash.com/random/768x2048?brooklyn)\n\n## Split Layout\n\n</Split>\n\n---\n\n<SplitRight>\n\n![](https://source.unsplash.com/random/768x2048?brooklyn)\n\n## SplitRight Layout\n\n</SplitRight>\n\n---\n\n<Horizontal>\n\n## Horizontal Layout\n\n![](https://source.unsplash.com/random/768x2048?brooklyn)\n\n![](https://source.unsplash.com/random/768x2048?brooklyn)\n\n</Horizontal>\n\n---\n\n<FullScreenCode>\n\n```jsx\n<Button>FullScreenCode Layout</Button>\n```\n\n</FullScreenCode>\n"
  },
  {
    "path": "examples/layouts/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/layouts-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/multiple/deck.js",
    "content": "import { slides as one } from './one.mdx'\nimport { slides as two } from './two.mdx'\n\nexport const slides = [...one, ...two]\n"
  },
  {
    "path": "examples/multiple/one.mdx",
    "content": "\n# Hello!\n\n---\n\nThis is MDX Deck #1\n"
  },
  {
    "path": "examples/multiple/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/multiple-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.js\",\n    \"build\": \"mdx-deck build deck.js\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/multiple/two.mdx",
    "content": "\n# This is Deck # 2\n\n---\n\n:sunglasses:\n"
  },
  {
    "path": "examples/prism/deck.mdx",
    "content": "import { future, prism } from 'mdx-deck/themes'\n\nexport const themes = [\n  future,\n  prism\n]\n\n# Hello!\n\n---\n\n```jsx\nimport React from 'react'\n\nexport default props =>\n  <h1>Highlighting</h1>\n```\n"
  },
  {
    "path": "examples/prism/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/prism-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/provider/deck.mdx",
    "content": "import { comic } from 'mdx-deck/themes'\nimport theme from './theme'\n\nexport const themes = [\n  comic,\n  theme,\n]\n\n# Hello!\n\n---\n\nThis deck has a custom Provider component\n\n"
  },
  {
    "path": "examples/provider/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/provider-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/provider/theme.js",
    "content": "import React from 'react'\n\nconst Provider = props => (\n  <div>\n    {props.children}\n    <div\n      css={{\n        position: 'fixed',\n        right: 0,\n        bottom: 0,\n        margin: 16,\n      }}\n    >\n      Put your name here\n    </div>\n  </div>\n)\n\nexport default {\n  Provider,\n}\n"
  },
  {
    "path": "examples/steps/deck.mdx",
    "content": "\n# Hello!\n\n---\n\n<ul>\n  <li>One</li>\n  <Steps>\n    <li>Two</li>\n    <li>Three</li>\n    <li>Four</li>\n  </Steps>\n</ul>\n\n---\n\n## One\n\n<Steps>\n\n## Two\n## Three\n\n</Steps>\n\n"
  },
  {
    "path": "examples/steps/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/appear-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/syntax-highlighting/deck.mdx",
    "content": "import { future, highlight } from '@mdx-deck/themes'\n\nexport const theme = {\n  ...future,\n  ...highlight\n}\n\n# Hello!\n\n---\n\n```jsx\nimport React from 'react'\n\nexport default props =>\n  <h1>Highlighting</h1>\n```\n"
  },
  {
    "path": "examples/syntax-highlighting/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/syntax-highlighting-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/themes/deck.mdx",
    "content": "import { ThemeName } from './theme'\n\nexport { theme } from './theme'\n\n# Hello <ThemeName />!\n\n---\n\nThis deck has a custom Provider component\nthat lets you switch between all the different themes.\n\n---\n\n```jsx\nimport React from 'react'\n\nexport default ({ children }) => {\n  return (\n    <>\n      {children}\n    </>\n  )\n}\n```\n"
  },
  {
    "path": "examples/themes/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/themes-example\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/themes/theme.js",
    "content": "import React, { useState, useContext } from 'react'\nimport { ThemeProvider } from 'emotion-theming'\nimport { MDXProvider } from '@mdx-js/react'\nimport * as themes from 'mdx-deck/themes'\n\nconst names = Object.keys(themes)\n\nconst DefaultProvider = props => <>{props.children}</>\n\nconst Context = React.createContext()\n\nconst Provider = props => {\n  const [name, setTheme] = useState(names[0])\n  const cycle = e => {\n    const i = (names.indexOf(name) + 1) % names.length\n    setTheme(names[i])\n  }\n\n  const baseTheme = themes[name]\n  const theme = typeof baseTheme === 'function' ? baseTheme({}) : baseTheme\n  const Root = theme.Provider || DefaultProvider\n\n  return (\n    <div>\n      <Context.Provider value={name}>\n        <ThemeProvider theme={theme}>\n          <MDXProvider components={theme.components}>\n            <Root>{props.children}</Root>\n          </MDXProvider>\n        </ThemeProvider>\n      </Context.Provider>\n      <div\n        css={{\n          position: 'fixed',\n          right: 0,\n          bottom: 0,\n          margin: 16,\n        }}>\n        <label>\n          Theme\n          <select\n            value={name}\n            onChange={e => {\n              setTheme(e.target.value)\n            }}>\n            {names.map(name => (\n              <option key={name}>{name}</option>\n            ))}\n          </select>\n          <button onClick={cycle}>Next</button>\n        </label>\n      </div>\n    </div>\n  )\n}\n\nexport const ThemeName = props => {\n  const context = useContext(Context)\n\n  return <>{context}</>\n}\n\nexport const theme = {\n  Provider,\n}\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true,\n  \"version\": \"4.1.1\"\n}\n"
  },
  {
    "path": "netlify.toml",
    "content": "[build]\n  command = \"npm i yarn@latest && yarn && yarn build\"\n  publish = \"docs/public\"\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"workspaces\": [\n    \"packages/*\",\n    \"templates/*\",\n    \"examples/*\",\n    \"docs\"\n  ],\n  \"scripts\": {\n    \"start\": \"yarn workspace @mdx-deck/docs start\",\n    \"build\": \"yarn workspace @mdx-deck/docs build\",\n    \"export\": \"./packages/export/cli.js http://localhost:8000/print -o docs/public/deck.pdf\",\n    \"cypress:open\": \"cypress open\",\n    \"cypress:run\": \"cypress run\",\n    \"test:dev\": \"start-server-and-test start http://localhost:8000 cypress:open\",\n    \"jest\": \"jest\",\n    \"test\": \"jest && start-server-and-test start http://localhost:8000 cypress:run\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.8.4\",\n    \"@babel/preset-env\": \"^7.8.4\",\n    \"@babel/preset-react\": \"^7.8.3\",\n    \"@testing-library/react\": \"^10.0.2\",\n    \"cypress\": \"^4.3.0\",\n    \"husky\": \"^4.2.1\",\n    \"jest\": \"^25.1.0\",\n    \"jest-emotion\": \"^10.0.27\",\n    \"lerna\": \"^3.13.1\",\n    \"lint-staged\": \"^10.0.4\",\n    \"prettier\": \"^1.16.4\",\n    \"react-test-renderer\": \"^16.12.0\",\n    \"start-server-and-test\": \"^1.9.1\"\n  },\n  \"jest\": {\n    \"testMatch\": [\n      \"**/packages/**/test/*.js\"\n    ],\n    \"testPathIgnorePatterns\": [\n      \"/node_modules/\",\n      \"/.cache/\",\n      \"/public/\"\n    ],\n    \"coverageReporters\": [\n      \"lcov\",\n      \"text\",\n      \"html\"\n    ],\n    \"collectCoverageFrom\": [\n      \"packages/**/src/**/*.js\"\n    ],\n    \"coverageThreshold\": {\n      \"global\": {\n        \"branches\": 80,\n        \"functions\": 80,\n        \"lines\": 80,\n        \"statements\": 80\n      }\n    },\n    \"snapshotSerializers\": [\n      \"jest-emotion\"\n    ]\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  },\n  \"lint-staged\": {\n    \"*.{js,json}\": [\n      \"prettier --write\",\n      \"git add\"\n    ]\n  }\n}\n"
  },
  {
    "path": "packages/create-deck/README.md",
    "content": "# npm init deck\n\nCreate mdx-deck presentations\n\n```sh\nnpm init deck my-presentation\n```\n"
  },
  {
    "path": "packages/create-deck/cli.js",
    "content": "#!/usr/bin/env node\nconst fs = require('fs')\nconst path = require('path')\nconst meow = require('meow')\nconst chalk = require('chalk')\nconst initit = require('initit')\n\nconst logo = chalk.magenta('[mdx-deck]')\nconst log = (...args) => {\n  console.log(logo, ...args)\n}\nlog.error = (...args) => {\n  console.log(chalk.red('[ERROR]'), ...args)\n}\n\nconst template = 'jxnblk/mdx-deck/templates/basic'\n\nconst cli = meow(\n  `\n  Usage\n\n    $ npm init deck my-presentation\n\n    $ npx create-deck my-presentation\n\n`,\n  {\n    booleanDefault: undefined,\n    flags: {\n      help: {\n        type: 'boolean',\n        alias: 'h',\n      },\n      version: {\n        type: 'boolean',\n        alias: 'v',\n      },\n    },\n  }\n)\n\nconst [name] = cli.input\n\nif (!name) {\n  cli.showHelp(0)\n}\n\n// todo: ensure directory doesn't exist\ninitit({ name, template })\n  .then(res => {\n    log('created mdx-deck')\n    process.exit(0)\n  })\n  .catch(err => {\n    log.error('failed to create mdx-deck')\n    log.error(err)\n    process.exit(1)\n  })\n"
  },
  {
    "path": "packages/create-deck/package.json",
    "content": "{\n  \"name\": \"create-deck\",\n  \"version\": \"4.0.0\",\n  \"description\": \"Create mdx-deck presentations\",\n  \"bin\": {\n    \"create-deck\": \"cli.js\"\n  },\n  \"author\": \"Brent Jackson\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"chalk\": \"^3.0.0\",\n    \"initit\": \"^1.0.0-2\",\n    \"meow\": \"^6.0.0\"\n  },\n  \"gitHead\": \"13d00b47780424cc3b52d38ad6f19e99d007c06a\"\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/.gitignore",
    "content": "coverage\n.cache\npublic\n"
  },
  {
    "path": "packages/gatsby-plugin/.npmignore",
    "content": ".cache\ncoverage\npublic\ntest\n"
  },
  {
    "path": "packages/gatsby-plugin/README.md",
    "content": "\n# @mdx-deck/gatsby-plugin\n\nPlugin used internally by mdx-deck core package -- **not intended for standalone usage**\n\nSee [`gatsby-theme-mdx-deck`](https://github.com/jxnblk/mdx-deck/tree/master/packages/gatsby-theme) for custom usage with Gatsby\n"
  },
  {
    "path": "packages/gatsby-plugin/gatsby-browser.js",
    "content": "export { wrapPageElement } from './src'\n"
  },
  {
    "path": "packages/gatsby-plugin/gatsby-config.js",
    "content": "module.exports = {\n  plugins: [\n    'gatsby-plugin-react-helmet',\n  ],\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/gatsby-node.js",
    "content": "const fs = require('fs')\nconst path = require('path')\nconst { createPath, validatePath } = require('gatsby-page-utils')\nconst remarkPlugins = [\n  require('remark-images'),\n  require('remark-unwrap-images'),\n  require('remark-emoji'),\n]\n\nexports.onPreBootstrap = ({}, opts = {}) => {\n  opts.dirname = opts.dirname || __dirname\n  const staticSourceDir = path.join(opts.dirname, 'static')\n  const hasStaticDir = fs.existsSync(staticSourceDir)\n\n  if (fs.existsSync('./static')) {\n    // remove temp directory\n    fs.unlinkSync('./static')\n  }\n\n  if (hasStaticDir) {\n    // link to source static directory\n    fs.symlinkSync(staticSourceDir, './static')\n  }\n}\n\nexports.onCreateWebpackConfig = ({\n  stage,\n  rules,\n  loaders,\n  plugins,\n  actions,\n}) => {\n  actions.setWebpackConfig({\n    module: {\n      rules: [\n        {\n          test: /\\.mdx$/,\n          use: [\n            loaders.js(),\n            {\n              loader: '@mdx-js/loader',\n              options: {\n                remarkPlugins,\n              }\n            },\n          ]\n        }\n      ]\n    }\n  })\n}\n\nexports.resolvableExtensions = () => ['.mdx']\n\nexports.createPages = ({\n  actions,\n}, {\n  path: source,\n} = {}) => {\n  if (!source) return\n\n  actions.createPage({\n    path: '/',\n    matchPath: '/*',\n    component: source,\n  })\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/gatsby-ssr.js",
    "content": "export { wrapPageElement } from './src'\n"
  },
  {
    "path": "packages/gatsby-plugin/index.js",
    "content": "// noop\nexport * from './src'\n"
  },
  {
    "path": "packages/gatsby-plugin/package.json",
    "content": "{\n  \"name\": \"@mdx-deck/gatsby-plugin\",\n  \"version\": \"4.1.1\",\n  \"main\": \"index.js\",\n  \"author\": \"Brent Jackson\",\n  \"license\": \"MIT\",\n  \"repository\": \"github:jxnblk/mdx-deck\",\n  \"scripts\": {\n    \"start\": \"gatsby develop --open\"\n  },\n  \"peerDependencies\": {\n    \"gatsby\": \"^2.14.0\",\n    \"react\": \"^16.10.0\",\n    \"react-dom\": \"^16.10.0\"\n  },\n  \"devDependencies\": {\n    \"gatsby\": \"^2.14.0\",\n    \"react\": \"^16.10.0\",\n    \"react-dom\": \"^16.10.0\"\n  },\n  \"dependencies\": {\n    \"@mdx-js/loader\": \"^1.5.3\",\n    \"@mdx-js/mdx\": \"^1.5.3\",\n    \"gatsby-page-utils\": \"^0.0.39\",\n    \"gatsby-plugin-react-helmet\": \"^3.1.18\",\n    \"hhmmss\": \"^1.0.0\",\n    \"react-helmet\": \"^5.2.1\",\n    \"remark-emoji\": \"^2.0.2\",\n    \"remark-images\": \"^2.0.0\",\n    \"remark-unwrap-images\": \"^2.0.0\",\n    \"theme-ui\": \"^0.3.0-alpha.6\"\n  },\n  \"gitHead\": \"13d00b47780424cc3b52d38ad6f19e99d007c06a\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  }\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/clock.js",
    "content": "import React from 'react'\n\nexport default props => {\n  const [time, setTime] = React.useState(new Date().toLocaleTimeString())\n\n  React.useEffect(() => {\n    const timer = setInterval(() => {\n      const now = new Date()\n      setTime(now.toLocaleTimeString())\n    }, 1000)\n    return () => {\n      clearInterval(timer)\n    }\n  }, [])\n\n  return time\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/components.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\nimport useSteps from './use-steps'\n\nconst createComponent = key => {\n  const Component = () => false\n  Component.__mdxDeck = true\n  Component[`__mdxDeck_${key}`] = true\n  return Component\n}\n\nexport const Notes = createComponent('notes')\nexport const Head = createComponent('head')\nexport const Header = createComponent('header')\nexport const Footer = createComponent('footer')\n\nexport const Color = ({\n  color,\n  bg,\n  ...props\n}) =>\n  <div\n    {...props}\n    sx={{\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      justifyContent: 'center',\n      width: '100%',\n      height: '100%',\n      color,\n      bg,\n      a: {\n        color: 'inherit',\n      }\n    }}\n  />\n\nexport const Invert = props =>\n  <Color\n    {...props}\n    color='background'\n    bg='text'\n  />\n\nexport const StepList = props => {\n  const list = React.Children.toArray(props.children)\n    .find(child => /^(ul|ol)$/.test(child.props.originalType))\n\n  // ensure this works\n  const items = React.Children.toArray(list && list.props.children)\n\n  const step = useSteps(items.length)\n\n  const children = items.map((item, i) => React.cloneElement(item, {\n    style: {\n      visibility: i < step ? 'visible' : 'hidden'\n    }\n  }))\n\n  return React.cloneElement(list, { children })\n}\n\nexport const Appear = props => {\n  const children = React.Children.toArray(props.children)\n  const step = useSteps(children.length)\n  const styled = children.map((child, i) =>\n    React.cloneElement(child, {\n      style: {\n        visibility: i < step ? 'visible' : 'hidden',\n      }\n    })\n  )\n  return <React.Fragment>{styled}</React.Fragment>\n}\n\nexport const Steps = props => {\n  const list = React.Children.toArray(props.children)\n    .find(child => /^(ul|ol)$/.test(child.props.originalType))\n\n  if (!list) return <Appear {...props} />\n  return <StepList {...props} />\n}\n\nexport const Image = ({\n  src,\n  width = '100%',\n  height = '100%',\n  size = 'cover',\n  ...props\n}) =>\n  <div\n    {...props}\n    sx={{\n      width,\n      height,\n      backgroundSize: size,\n      backgroundImage: `url(${src})`,\n      backgroundPosition: 'center',\n      backgroundRepeat: 'no-repeat',\n    }}\n  />\n\nexport const Horizontal = ({\n  ...props\n}) => {\n  const children = React.Children.toArray(props.children)\n  return (\n    <div\n      {...props}\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        height: '100%',\n        textAlign: 'center',\n      }}>\n      {children.map((child, i) => (\n        <div\n          key={child.key}\n          sx={{\n            width: 100 / children.length + '%',\n            img: {\n              height: 'auto',\n            }\n          }}>\n          {child}\n        </div>\n      ))}\n    </div>\n  )\n}\n\nconst Half = props => <div {...props} sx={{\n  width: '50%',\n  img: {\n    height: 'auto',\n  }\n}} />\n\nexport const Split = ({ reverse, ...props }) => {\n  const [first, ...rest] = React.Children.toArray(props.children)\n  const children = reverse\n    ? [ <Half key='rest'>{rest}</Half>, <Half key='first'>{first}</Half> ]\n    : [ <Half key='first'>{first}</Half>, <Half key='rest'>{rest}</Half> ]\n\n  return (\n    <div\n      {...props}\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        height: '100%',\n        textAlign: 'center',\n      }}>\n      {children}\n    </div>\n  )\n}\n\nexport const SplitRight = props =>\n  <Split\n    {...props}\n    reverse={true}\n  />\n\nexport const FullScreenCode = ({ ...props }) => (\n  <div\n    {...props}\n    sx={{\n      width: '100%',\n      height: '100%',\n      pre: {\n        // hack for prism styles\n        margin: '0 !important',\n        width: '100%',\n        height: '100%',\n        overflow: 'auto',\n      },\n    }}\n  />\n)\n"
  },
  {
    "path": "packages/gatsby-plugin/src/container.js",
    "content": "/** @jsx jsx */\nimport { jsx, Box, Flex } from 'theme-ui'\nimport React from 'react'\nimport { Context, useDeck } from './context'\nimport modes from './modes'\nimport Header from './header'\nimport Footer from './footer'\nimport Slide from './slide'\nimport Clock from './clock'\nimport Timer from './timer'\n\nconst Main = ({\n  width = '100vw',\n  height = '100vh',\n  preview = false,\n  ...props\n}) => {\n  const outer = useDeck()\n  const context = {\n    ...outer,\n    main: !preview,\n  }\n\n  return (\n    <Context.Provider value={context}>\n      <div\n        sx={{\n          width,\n          height,\n          position: 'relative',\n          overflow: 'hidden',\n        }}>\n        {props.header && (\n          <Header>\n            {props.header}\n          </Header>\n        )}\n        {props.children}\n        {props.footer && (\n          <Footer>\n            {props.footer}\n          </Footer>\n        )}\n      </div>\n    </Context.Provider>\n  )\n}\n\nconst Presenter = props => {\n  const next = props.slides[props.index + 1]\n\n  return (\n    <div\n      sx={{\n        display: 'flex',\n        height: '100vh',\n        color: 'white',\n        bg: 'backdrop',\n      }}>\n      <div\n        sx={{\n          width: '60%',\n          height: '100vh',\n          padding: 3,\n        }}>\n        <Main\n          {...props}\n          width='100%'\n          height='100%'>\n          <Slide>\n            {props.slide}\n          </Slide>\n        </Main>\n      </div>\n      <Flex\n        sx={{\n          flexDirection: 'column',\n          width: '40%',\n          height: '100vh',\n          py: 3,\n          pr: 3,\n          overflowY: 'auto',\n        }}>\n        <Slide\n          width='100%'\n          height='100vh'\n          zoom={1/2}\n          sx={{\n          }}>\n          {next}\n        </Slide>\n        <div\n          sx={{\n            py: 3,\n            flex: '1 1 auto',\n          }}>\n          {props.notes}\n        </div>\n        <Flex\n          sx={{\n            alignItems: 'baseline',\n            fontFamily: '\"Roboto Mono\", Menlo, monospace',\n          }}>\n          <Box>\n            {props.index} / {props.slides.length - 1}\n          </Box>\n          <a\n            href='/'\n            target='_blank'\n            title='Open in new window'\n            sx={{\n              ml: 3,\n              fontWeight: 'bold',\n              color: 'inherit',\n              textDecoration: 'none',\n            }}>\n            ⬈\n          </a>\n          <Box mx='auto' />\n          <Box>\n            <Timer />\n            {' '}\n            <Clock />\n          </Box>\n        </Flex>\n      </Flex>\n    </div>\n  )\n}\n\nconst Overview = props => {\n  const ref = React.useRef(null)\n\n  React.useEffect(() => {\n    if (!ref.current) return\n    if (typeof ref.current.scrollIntoViewIfNeeded !== 'function') return\n    ref.current.scrollIntoViewIfNeeded()\n  }, [ref.current])\n\n  return (\n    <div\n      sx={{\n        display: 'flex',\n        height: '100vh',\n        color: 'white',\n        bg: 'backdrop',\n      }}>\n      <div\n        sx={{\n          width: '25%',\n          height: '100vh',\n          overflowY: 'auto',\n          p: 2,\n        }}>\n        {props.slides.map((slide, i) => (\n          <div\n            key={i}\n            ref={i === props.index ? ref : null}\n            role='button'\n            title={`Go to slide ${i}`}\n            onClick={e => {\n              props.setIndex(i)\n              props.setStep(0)\n              props.setSteps(0)\n            }}\n            sx={{\n              p: 2,\n              height: '30%'\n            }}>\n            <Slide\n              sx={{\n                outline: props.index === i ? '2px solid cyan' : null,\n              }}\n              zoom={1/4}>\n              {slide}\n            </Slide>\n          </div>\n        ))}\n      </div>\n      <div\n        sx={{\n          width: '75%',\n          py: 3,\n          pr: 3,\n          pl: 2,\n        }}>\n        <Main\n          {...props}\n          width='100%'\n          height='100%'>\n          <Slide zoom={3/4}>\n            {props.slide}\n          </Slide>\n        </Main>\n      </div>\n    </div>\n  )\n}\n\nconst Grid = props => {\n  const ref = React.useRef(null)\n\n  React.useEffect(() => {\n    if (!ref.current) return\n    if (typeof ref.current.scrollIntoViewIfNeeded !== 'function') return\n    ref.current.scrollIntoViewIfNeeded()\n  }, [ref.current])\n\n  return (\n    <div\n      sx={{\n        minHeight: '100vh',\n        color: 'white',\n        bg: 'backdrop',\n      }}>\n      <div\n        sx={{\n          display: 'flex',\n          alignItems: 'flex-start',\n          flexWrap: 'wrap',\n        }}>\n        {props.slides.map((slide, i) => (\n          <div\n            key={i}\n            ref={i === props.index ? ref : null}\n            role='button'\n            title={`Go to slide ${i}`}\n            onClick={e => {\n              props.setIndex(i)\n              props.setStep(0)\n              props.setSteps(0)\n              props.setMode(modes.default)\n            }}\n            sx={{\n              p: 2,\n              width: '25%',\n              height: '23vh',\n            }}>\n            <Slide\n              sx={{\n                outline: props.index === i ? '2px solid cyan' : null,\n              }}\n              zoom={1/4}>\n              {slide}\n            </Slide>\n          </div>\n        ))}\n      </div>\n    </div>\n  )\n}\n\nconst Print = props => {\n  return (\n    <React.Fragment>\n      {props.slides.map((slide, i) => (\n        <Main key={i} preview>\n          <Slide>\n            {slide}\n          </Slide>\n        </Main>\n      ))}\n    </React.Fragment>\n  )\n}\n\nexport default props => {\n  const context = useDeck()\n\n  switch (context.mode) {\n    case modes.presenter:\n      return <Presenter {...props} {...context} />\n    case modes.overview:\n      return <Overview {...props} {...context} />\n    case modes.grid:\n      return <Grid {...props} {...context} />\n    case modes.print:\n      return <Print {...props} {...context} />\n    case modes.default:\n    default:\n      return <Main {...props} {...context} />\n  }\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/context.js",
    "content": "import React from 'react'\n\nexport const Context = React.createContext({})\n\nexport const useDeck = () => React.useContext(Context)\n"
  },
  {
    "path": "packages/gatsby-plugin/src/deck.js",
    "content": "import React from 'react'\nimport { Helmet } from 'react-helmet'\nimport { ThemeProvider, merge } from 'theme-ui'\nimport split from './split-slides'\nimport { Context } from './context'\nimport Keyboard from './keyboard'\nimport modes from './modes'\nimport Storage from './storage'\nimport Container from './container'\nimport Slide from './slide'\nimport baseTheme from './theme'\n\nconst getIndex = props => {\n  if (!props.location) return 0\n  const n = Number(props.location.hash.replace(/^#/, ''))\n  return n\n}\n\nexport default props => {\n  const slides = split(props)\n  const [index, setIndex] = React.useState(getIndex(props))\n  const { slug } = props.pageContext || {}\n  const slide = slides[index]\n\n  const [mode, setMode] = React.useState(modes.default)\n  const toggleMode = next => setMode(current =>\n    current === next ? modes.default : next\n  )\n\n  const [step, setStep] = React.useState(0)\n  const [steps, setSteps] = React.useState(0)\n\n  const lastIndex = React.useRef(0)\n  const direction = index - lastIndex.current\n\n  React.useEffect(() => {\n    lastIndex.current = index\n  }, [index])\n\n  React.useEffect(() => {\n    if (props.location.pathname === '/print') return\n    props.navigate('/#' + index, {\n      replace: true,\n    })\n  }, [index])\n\n  React.useEffect(() => {\n    if (props.location.pathname === '/print') {\n      setMode(modes.print)\n    }\n    if (!slide) {\n      props.navigate('/')\n      setIndex(0)\n    }\n  }, [])\n\n  if (!slide) return false\n\n  const context = {\n    slides,\n    slug,\n    index,\n    setIndex,\n    direction,\n    length: slides.length,\n    slide,\n    mode,\n    setMode,\n    toggleMode,\n    notes: slide.notes,\n    header: slides.header,\n    footer: slides.footer,\n    step,\n    setStep,\n    steps,\n    setSteps,\n  }\n\n  context.previous = () => {\n    if (steps && step > 0) {\n      setStep(n => n - 1)\n    } else {\n      setIndex(n => n > 0 ? n - 1 : n)\n      setStep(0)\n      setSteps(0)\n    }\n  }\n\n  context.next = () => {\n    if (step < steps) {\n      setStep(n => n + 1)\n    } else {\n      setIndex(n => n < slides.length - 1 ? n + 1 : n)\n      setStep(0)\n      setSteps(0)\n    }\n  }\n\n  const theme = merge(baseTheme, props.theme || {})\n\n  return (\n    <Context.Provider value={context}>\n      <Keyboard />\n      <Storage />\n      <Helmet>\n        {slides.head.children}\n        {theme.googleFont && <link rel='stylesheet' href={theme.googleFont} />}\n      </Helmet>\n      <ThemeProvider\n        theme={theme}\n        components={theme.components}>\n        <Container>\n          <Slide>\n            {slide}\n          </Slide>\n        </Container>\n      </ThemeProvider>\n    </Context.Provider>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/footer.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport default props =>\n  <footer\n    {...props}\n    sx={{\n      position: 'absolute',\n      zIndex: 1,\n      left: 0,\n      bottom: 0,\n      right: 0,\n      pointerEvents: 'none',\n      variant: 'styles.Footer',\n    }}\n  />\n"
  },
  {
    "path": "packages/gatsby-plugin/src/header.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport default props =>\n  <header\n    {...props}\n    sx={{\n      position: 'absolute',\n      zIndex: 1,\n      left: 0,\n      top: 0,\n      right: 0,\n      pointerEvents: 'none',\n      variant: 'styles.Header',\n    }}\n  />\n"
  },
  {
    "path": "packages/gatsby-plugin/src/index.js",
    "content": "import React from 'react'\nimport { MDXProvider } from '@mdx-js/react'\nimport wrapper from './deck'\nimport * as mdxComponents from './components'\n\nconst components = {\n  wrapper,\n  ...mdxComponents,\n}\n\nconst Page = props =>\n  <MDXProvider components={components}>\n    {props.children}\n  </MDXProvider>\n\nexport const wrapPageElement = ({ element, props }) =>\n  <Page {...props}>\n    {element}\n  </Page>\n\nexport { useDeck } from './context'\nexport { useSteps } from './use-steps'\nexport * from './components'\n"
  },
  {
    "path": "packages/gatsby-plugin/src/keyboard.js",
    "content": "import React from 'react'\nimport { useDeck } from './context'\nimport modes from './modes'\n\nconst keys = {\n  right: 39,\n  left: 37,\n  up: 38,\n  down: 40,\n  space: 32,\n  p: 80,\n  o: 79,\n  g: 71,\n  esc: 27,\n  pageUp: 33,\n  pageDown: 34,\n}\n\nexport const useKeyboard = () => {\n  const context = useDeck()\n\n  React.useEffect(() => {\n    const handleKeyDown = e => {\n      if (e.metaKey) return\n      if (e.ctrlKey) return\n\n      if (e.altKey) {\n        switch (e.keyCode) {\n          case keys.p:\n            if (e.shiftKey) {\n              context.toggleMode(modes.print)\n            } else {\n              context.toggleMode(modes.presenter)\n            }\n            break\n          case keys.o:\n            context.toggleMode(modes.overview)\n            break\n          case keys.g:\n            context.toggleMode(modes.grid)\n            break\n          default:\n            break\n        }\n      } else if (e.shiftKey) {\n        switch (e.keyCode) {\n          case keys.space:\n            e.preventDefault()\n            context.previous()\n            break\n          default:\n            break\n        }\n      } else {\n        switch (e.keyCode) {\n          case keys.right:\n          case keys.down:\n          case keys.pageDown:\n          case keys.space:\n            e.preventDefault()\n            context.next()\n            break\n          case keys.left:\n          case keys.up:\n          case keys.pageUp:\n            e.preventDefault()\n            context.previous()\n            break\n          case keys.esc:\n            context.setMode(modes.default)\n            break\n          default:\n            break\n        }\n      }\n    }\n\n    document.addEventListener('keydown', handleKeyDown)\n\n    return () => {\n      document.removeEventListener('keydown', handleKeyDown)\n    }\n  }, [context])\n}\n\nexport default () => {\n  useKeyboard()\n  return false\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/modes.js",
    "content": "export default {\n  default: 'default',\n  presenter: 'presenter',\n  overview: 'overview',\n  grid: 'grid',\n  print: 'print',\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/slide.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport default ({\n  zoom,\n  width = '100%',\n  height = '100%',\n  children,\n  ...props\n}) =>\n  <div\n    {...props}\n    sx={{\n      boxSizing: 'border-box',\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      justifyContent: 'center',\n      overflow: 'hidden',\n      position: 'relative',\n      color: 'text',\n      bg: 'background',\n      variant: 'styles.Slide',\n      width,\n      height,\n      zoom,\n    }}>\n    {children}\n  </div>\n"
  },
  {
    "path": "packages/gatsby-plugin/src/split-slides.js",
    "content": "import React from 'react'\n\nexport default props => {\n  const arr = React.Children.toArray(props.children)\n  const splits = []\n  const slides = []\n  slides.head = {\n    props: {},\n    children: [],\n  }\n  const notes = {}\n\n  arr.forEach((child, i) => {\n    const {\n      originalType,\n      mdxType,\n      parentName,\n      children,\n      ...childProps\n    } = child.props\n\n    // todo: figure out nested decks\n    // if (originalType.isMDXComponent) {}\n\n    // get notes\n    if (originalType.__mdxDeck_notes || mdxType === 'Notes') {\n      notes[splits.length] = children\n    } else if (originalType.__mdxDeck_header || mdxType === 'Header') {\n      slides.header = children\n    } else if (originalType.__mdxDeck_footer || mdxType === 'Footer') {\n      slides.footer = children\n    // get head content\n    } else if (originalType.__mdxDeck_head || mdxType === 'Head') {\n      slides.head.children.push(children)\n      Object.assign(slides.head.props, childProps)\n    }\n    if (mdxType === 'hr') {\n      splits.push(i)\n    }\n  })\n\n  let previousSplit = 0\n  splits.forEach((split, i) => {\n    const children = [...arr.slice(previousSplit, split)]\n    if (notes[i]) children.notes = notes[i]\n    slides.push(children)\n    previousSplit = split + 1\n  })\n  const last = [...arr.slice(previousSplit)]\n  if (notes[slides.length]) last.notes = notes[slides.length]\n  slides.push(last)\n\n  slides.head.children = React.Children.toArray(slides.head.children).map(\n    (child, i) => {\n      const { originalType, mdxType, parentName, ...childProps } = child.props\n      return React.createElement(originalType, {\n        key: i,\n        ...childProps,\n      })\n    }\n  )\n\n  return slides\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/storage.js",
    "content": "import React from 'react'\nimport { useDeck } from './context'\n\nconst keys = {\n  slide: 'mdx-deck-slide',\n  step: 'mdx-deck-step',\n}\n\nexport const useStorage = () => {\n  const context = useDeck()\n  const [focused, setFocused] = React.useState(false)\n\n  const handleFocus = () => setFocused(true)\n  const handleBlur = () => setFocused(false)\n\n  const handleStorageChange = e => {\n    const n = parseInt(e.newValue, 10)\n    if (isNaN(n)) return\n    switch (e.key) {\n      case keys.slide:\n        context.setIndex(n)\n        break\n      case keys.step:\n        context.setStep(n)\n        break\n    }\n  }\n\n  React.useEffect(() => {\n    setFocused(document.hasFocus())\n  }, [])\n\n  React.useEffect(() => {\n    if (!focused) window.addEventListener('storage', handleStorageChange)\n    window.addEventListener('focus', handleFocus)\n    window.addEventListener('blur', handleBlur)\n    return () => {\n      if (!focused) window.removeEventListener('storage', handleStorageChange)\n      window.removeEventListener('focus', handleFocus)\n      window.removeEventListener('blur', handleBlur)\n    }\n  }, [focused])\n\n  // store changes\n  React.useEffect(() => {\n    if (!focused) return\n    localStorage.setItem(keys.slide, context.index)\n  }, [focused, context.index])\n}\n\nexport default () => {\n  useStorage()\n  return false\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/theme.js",
    "content": "// base theme\nexport default {\n  colors: {\n    text: '#fff',\n    background: '#000',\n    backdrop: '#111',\n  },\n  fonts: {\n    body: 'system-ui, sans-serif',\n    heading: 'inherit',\n    monospace: 'Menlo, monospace',\n  },\n  fontWeights: {\n    body: 400,\n    heading: 700,\n  },\n  lineHeights: {\n    body: 1.5,\n    heading: 1.125,\n  },\n  text: {\n    heading: {\n      fontFamily: 'heading',\n      fontWeight: 'heading',\n      lineHeight: 'heading',\n    },\n  },\n  styles: {\n    root: {\n      fontFamily: 'system-ui, sans-serif',\n    },\n    img: {\n      width: '100vw',\n      maxWidth: '100%',\n      height: '100vh',\n      objectFit: 'contain',\n    },\n    h1: {\n      variant: 'text.heading',\n    },\n    h2: {\n      variant: 'text.heading',\n    },\n    h3: {\n      variant: 'text.heading',\n    },\n    h4: {\n      variant: 'text.heading',\n    },\n    h5: {\n      variant: 'text.heading',\n    },\n    h6: {\n      variant: 'text.heading',\n    },\n    code: {\n      fontFamily: 'monospace',\n    },\n    pre: {\n      fontFamily: 'monospace',\n    },\n    Slide: {\n      fontFamily: 'body',\n      fontSize: '2em',\n    },\n    Header: {\n      px: 3,\n    },\n    Footer: {\n      px: 3,\n    },\n  }\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/timer.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\nimport hhmmss from 'hhmmss'\n\nexport default props => {\n  const [seconds, setSeconds] = React.useState(0)\n  const [active, setActive] = React.useState(false)\n\n  React.useEffect(() => {\n    const timer = setInterval(() => {\n      if (!active) return\n      setSeconds(n => n + 1)\n    }, 1000)\n    return () => {\n      clearInterval(timer)\n    }\n  }, [active])\n\n  return (\n    <button\n      onClick={e => {\n        setActive(!active)\n        if (active) setSeconds(0)\n      }}\n      title={active ? 'Stop Timer' : 'Start Timer'}\n      sx={{\n        appearance: 'none',\n        fontFamily: '\"Roboto Mono\", Menlo, monospace',\n        fontSize: 'inherit',\n        color: 'white',\n        bg: 'black',\n        border: 0,\n        padding: 2,\n      }}>\n      {hhmmss(seconds)}\n    </button>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-plugin/src/use-steps.js",
    "content": "import React from 'react'\nimport { useDeck } from './context'\n\nexport const useSteps = length => {\n  const context = useDeck()\n\n  React.useEffect(() => {\n    if (!context.main) return\n    context.setSteps(length)\n    if (context.direction < 0) context.setStep(length)\n  }, [length, context])\n\n  if (!context.main) return length\n  return context.step\n}\n\nexport default useSteps\n"
  },
  {
    "path": "packages/gatsby-plugin/test/__snapshots__/components.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Color renders 1`] = `\n.emotion-0 {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-flex-direction: column;\n  -ms-flex-direction: column;\n  flex-direction: column;\n  -webkit-align-items: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  -webkit-justify-content: center;\n  -ms-flex-pack: center;\n  justify-content: center;\n  width: 100%;\n  height: 100%;\n  background-color: tomato;\n}\n\n.emotion-0 a {\n  color: inherit;\n}\n\n<div\n  className=\"emotion-0\"\n/>\n`;\n\nexports[`FullScreenCode renders 1`] = `\n.emotion-0 {\n  width: 100%;\n  height: 100%;\n}\n\n.emotion-0 pre {\n  margin: 0 !important;\n  width: 100%;\n  height: 100%;\n  overflow: auto;\n}\n\n<div\n  className=\"emotion-0\"\n>\n  Hi\n</div>\n`;\n\nexports[`Horizontal renders 1`] = `\n.emotion-2 {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-align-items: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  align-items: center;\n  height: 100%;\n  text-align: center;\n}\n\n.emotion-0 {\n  width: 50%;\n}\n\n.emotion-0 img {\n  height: auto;\n}\n\n<div\n  className=\"emotion-2\"\n>\n  <div\n    className=\"emotion-0\"\n  >\n    <div>\n      A\n    </div>\n  </div>\n  <div\n    className=\"emotion-0\"\n  >\n    <div>\n      B\n    </div>\n  </div>\n</div>\n`;\n\nexports[`Image renders 1`] = `\n.emotion-0 {\n  width: 100%;\n  height: 100%;\n  background-size: cover;\n  background-image: url(kittens.png);\n  background-position: center;\n  background-repeat: no-repeat;\n}\n\n<div\n  className=\"emotion-0\"\n/>\n`;\n\nexports[`Invert renders 1`] = `\n.emotion-0 {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-flex-direction: column;\n  -ms-flex-direction: column;\n  flex-direction: column;\n  -webkit-align-items: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  -webkit-justify-content: center;\n  -ms-flex-pack: center;\n  justify-content: center;\n  width: 100%;\n  height: 100%;\n  color: background;\n  background-color: text;\n}\n\n.emotion-0 a {\n  color: inherit;\n}\n\n<div\n  className=\"emotion-0\"\n/>\n`;\n\nexports[`Split renders 1`] = `\n.emotion-2 {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-align-items: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  align-items: center;\n  height: 100%;\n  text-align: center;\n}\n\n.emotion-0 {\n  width: 50%;\n}\n\n.emotion-0 img {\n  height: auto;\n}\n\n<div\n  className=\"emotion-2\"\n>\n  <div\n    className=\"emotion-0\"\n  >\n    <div>\n      A\n    </div>\n  </div>\n  <div\n    className=\"emotion-0\"\n  >\n    <div>\n      B\n    </div>\n  </div>\n</div>\n`;\n\nexports[`SplitRight renders 1`] = `\n.emotion-2 {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-align-items: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  align-items: center;\n  height: 100%;\n  text-align: center;\n}\n\n.emotion-0 {\n  width: 50%;\n}\n\n.emotion-0 img {\n  height: auto;\n}\n\n<div\n  className=\"emotion-2\"\n>\n  <div\n    className=\"emotion-0\"\n  >\n    <div>\n      B\n    </div>\n  </div>\n  <div\n    className=\"emotion-0\"\n  >\n    <div>\n      A\n    </div>\n  </div>\n</div>\n`;\n\nexports[`Steps renders 1`] = `\nArray [\n  <div\n    style={\n      Object {\n        \"visibility\": \"visible\",\n      }\n    }\n  >\n    One\n  </div>,\n  <div\n    style={\n      Object {\n        \"visibility\": \"visible\",\n      }\n    }\n  >\n    Two\n  </div>,\n]\n`;\n\nexports[`Steps renders with list 1`] = `\n<ul\n  originalType=\"ul\"\n>\n  <li\n    style={\n      Object {\n        \"visibility\": \"visible\",\n      }\n    }\n  >\n    One\n  </li>\n  <li\n    style={\n      Object {\n        \"visibility\": \"visible\",\n      }\n    }\n  >\n    Two\n  </li>\n</ul>\n`;\n"
  },
  {
    "path": "packages/gatsby-plugin/test/clock.js",
    "content": "import React from 'react'\nimport renderer from 'react-test-renderer'\nimport Clock from '../src/clock'\n\nconst render = el => renderer.create(el).toJSON()\n\ntest('renders time', () => {\n  const tree = render(<Clock />)\n  expect(tree).toMatch(/\\d\\d:\\d\\d/)\n})\n"
  },
  {
    "path": "packages/gatsby-plugin/test/components.js",
    "content": "import React from 'react'\nimport renderer from 'react-test-renderer'\nimport {\n  Notes,\n  Head,\n  Header,\n  Footer,\n  Color,\n  Invert,\n  Steps,\n  Image,\n  Horizontal,\n  Split,\n  SplitRight,\n  FullScreenCode,\n} from '../src/components'\n\nconst render = el => renderer.create(el).toJSON()\n\ntest('Color renders', () => {\n  const json = render(\n    <Color bg='tomato' />\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('Invert renders', () => {\n  const json = render(\n    <Invert />\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('Steps renders', () => {\n  const json = render(\n    <Steps>\n      <div>One</div>\n      <div>Two</div>\n    </Steps>\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('Steps renders with list', () => {\n  const json = render(\n    <Steps>\n      <ul originalType='ul'>\n        <li>One</li>\n        <li>Two</li>\n      </ul>\n    </Steps>\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('Image renders', () => {\n  const json = render(\n    <Image src='kittens.png' />\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('Horizontal renders', () => {\n  const json = render(\n    <Horizontal>\n      <div>A</div>\n      <div>B</div>\n    </Horizontal>\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('Split renders', () => {\n  const json = render(\n    <Split>\n      <div>A</div>\n      <div>B</div>\n    </Split>\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('SplitRight renders', () => {\n  const json = render(\n    <SplitRight>\n      <div>A</div>\n      <div>B</div>\n    </SplitRight>\n  )\n  expect(json).toMatchSnapshot()\n})\n\ntest('FullScreenCode renders', () => {\n  const json = render(\n    <FullScreenCode>\n      Hi\n    </FullScreenCode>\n  )\n  expect(json).toMatchSnapshot()\n})\n\n"
  },
  {
    "path": "packages/gatsby-plugin/test/deck.js",
    "content": "import React from 'react'\nimport {\n  render,\n  fireEvent,\n  cleanup\n} from '@testing-library/react'\nimport Deck from '../src/deck'\nimport {\n  Steps,\n  Header,\n  Footer,\n} from '../src'\n\nafterEach(cleanup)\n\nlet __key = 0\nconst Comp = ({\n  originalType,\n  mdxType,\n  ...props\n}) => React.createElement(originalType, props)\n\nconst x = (tag, props, children) =>\n  React.createElement(Comp, {\n    key: __key++,\n    tag,\n    originalType: tag,\n    mdxType: tag,\n    ...props\n  }, children)\n\nconst mdx = [\n  x('div', null, 'One'),\n  x('hr', null),\n  x('div', null, 'Two'),\n]\n\nconst deckProps = {\n  children: mdx,\n  location: {\n    hash: '',\n    pathname: '/',\n  },\n  navigate: jest.fn()\n}\n\ntest('renders', () => {\n  const tree = render(\n    <Deck {...deckProps} />\n  )\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('advances one slide with right arrow key', () => {\n  const tree =render (\n    <Deck {...deckProps} />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 39,\n  })\n  const text = tree.getByText('Two')\n  expect(text).toBeTruthy()\n})\n\ntest('advances one slide with down arrow key', () => {\n  const tree =render (\n    <Deck {...deckProps} />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 40,\n  })\n  const text = tree.getByText('Two')\n  expect(text).toBeTruthy()\n})\n\ntest('advances one slide with spacebar key', () => {\n  const tree =render (\n    <Deck {...deckProps} />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 32,\n  })\n  const text = tree.getByText('Two')\n  expect(text).toBeTruthy()\n})\n\ntest('advances one slide with page down key', () => {\n  const tree =render (\n    <Deck {...deckProps} />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 34,\n  })\n  const text = tree.getByText('Two')\n  expect(text).toBeTruthy()\n})\n\ntest('goes back one slide with left arrow key', () => {\n  const tree =render (\n    <Deck\n      {...deckProps}\n      location={{\n        hash: '#2',\n      }}\n    />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 37,\n  })\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('goes back one slide with up arrow key', () => {\n  const tree =render (\n    <Deck\n      {...deckProps}\n      location={{\n        hash: '#2',\n      }}\n    />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 38,\n  })\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('goes back one slide with page up key', () => {\n  const tree =render (\n    <Deck\n      {...deckProps}\n      location={{\n        hash: '#2',\n      }}\n    />\n  )\n  fireEvent.keyDown(document.body, {\n    keyCode: 33,\n  })\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('goes back one slide with shift + space bar', () => {\n  const tree =render (\n    <Deck\n      {...deckProps}\n      location={{\n        hash: '#2',\n      }}\n    />\n  )\n  fireEvent.keyDown(document.body, {\n    shiftKey: true,\n    keyCode: 32,\n  })\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('ignores meta keys', () => {\n  const tree =render (\n    <Deck {...deckProps} />\n  )\n  fireEvent.keyDown(document.body, {\n    metaKey: true,\n    keyCode: 39,\n  })\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('ignores ctrl keys', () => {\n  const tree =render (\n    <Deck {...deckProps} />\n  )\n  fireEvent.keyDown(document.body, {\n    ctrlKey: true,\n    keyCode: 39,\n  })\n  const text = tree.getByText('One')\n  expect(text).toBeTruthy()\n})\n\ntest('initializes print mode', () => {\n  const tree =render (\n    <Deck\n      {...deckProps}\n      location={{\n        hash: '',\n        pathname: '/print'\n      }}\n    />\n  )\n  const one = tree.getByText('One')\n  const two = tree.getByText('Two')\n  expect(one).toBeTruthy()\n  expect(two).toBeTruthy()\n})\n\ndescribe('steps', () => {\n  const children = [\n    x('div', null,\n      <Steps>\n        <div>A</div>\n        <div>B</div>\n        <div>C</div>\n      </Steps>\n    ),\n    x('hr', null),\n    x('div', null, 'Two'),\n  ]\n\n  test('increments step', () => {\n    const tree =render (\n      <Deck\n        {...deckProps}\n        children={children}\n      />\n    )\n    fireEvent.keyDown(document.body, {\n      keyCode: 39,\n    })\n    const a = tree.getByText('A')\n    const b = tree.getByText('B')\n    expect(a.style.visibility).toBe('visible')\n    expect(b.style.visibility).toBe('hidden')\n  })\n\n  test('decrements step', () => {\n    const tree =render (\n      <Deck\n        {...deckProps}\n        children={children}\n      />\n    )\n    fireEvent.keyDown(document.body, { keyCode: 39 })\n    fireEvent.keyDown(document.body, { keyCode: 39 })\n    fireEvent.keyDown(document.body, { keyCode: 37 })\n    const a = tree.getByText('A')\n    const b = tree.getByText('B')\n    expect(a.style.visibility).toBe('visible')\n    expect(b.style.visibility).toBe('hidden')\n  })\n})\n\ntest('renders with Header and Footer', () => {\n  const children = [\n    x(Header, null, 'Header'),\n    x(Footer, null, 'Footer'),\n    x('div', null, 'Beep'),\n    x('hr', null),\n    x('div', null, 'Two'),\n  ]\n  const tree =render (\n    <Deck\n      {...deckProps}\n      children={children}\n    />\n  )\n  const header = tree.getByText('Header')\n  const footer = tree.getByText('Footer')\n  expect(header).toBeTruthy()\n  expect(footer).toBeTruthy()\n})\n\ntest('option + p toggles presenter mode', () => {\n  let context\n})\n"
  },
  {
    "path": "packages/gatsby-theme/.gitignore",
    "content": ".cache\npublic\n"
  },
  {
    "path": "packages/gatsby-theme/README.md",
    "content": "\n# gatsby-theme-mdx-deck\n\nAdd MDX Deck presentations to any Gatsby site\n\n```sh\nnpm i gatsby-theme-mdx-deck\n```\n\n```js\n// gatsby-config.js\nmodule.exports = {\n  plugins: [\n    'gatsby-theme-mdx-deck',\n  ]\n}\n```\n\nAdd one or more MDX presentation files to the `decks/` directory.\nThe filenames will be used for creating routes to each deck.\n\nExample `decks/hello.mdx`\n\n```mdx\n# Hello!\n\n---\n\n## Beep boop\n```\n\n## Layouts\n\nIndividual slides can be wrapped with layout components,\nwhich work similarly to slide templates found in other presentation software.\n\nExample `decks/hello.mdx`\n\n```mdx\nimport Layout from './my-layout'\n\n<Layout>\n\n# Hello\n\n</Layout>\n\n---\n\n## Beep boop\n```\n\n## Configuration Options\n\nThe Gatsby theme accepts the following options.\n\n```js\n// gatsby-config.js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-theme-mdx-deck',\n      options: {\n        // enable or disable gatsby-plugin-mdx\n        mdx: false,\n        // source directory\n        contentPath: 'decks',\n        // base path for routes generate by this theme\n        basePath: ''\n      }\n    }\n  ]\n}\n```\n\nMIT License\n"
  },
  {
    "path": "packages/gatsby-theme/decks/beep.mdx",
    "content": "\n# Beep\n\n---\n\n## Boop bop\n\n"
  },
  {
    "path": "packages/gatsby-theme/decks/hello.mdx",
    "content": "import { Head, Appear, Notes } from '../src'\n\n<Head>\n  <link\n    rel='stylesheet'\n    href='https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap'\n  />\n</Head>\n\n# Hello\n\n---\n\n`@mdx-deck/gatsby-theme-next`\n\n<Notes>\n\nHi\nHello, my secret notes...\n\n</Notes>\n\n---\n\n## Beep\n\n---\n\n## Appear:\n\n<ul>\n  <Appear>\n    <li>One</li>\n    <li>Two</li>\n    <li>Three</li>\n  </Appear>\n</ul>\n\n---\n\n## Hi\n\n---\n\n```jsx\nimport React from 'react'\nimport { Embed } from 'gatsby-theme-mdx-deck'\nimport Hello from './hello.mdx'\n\nexport default props =>\n  <Embed\n    src={Hello}\n    slide={2}\n  />\n```\n\n---\n\nMore steps\n\n<Appear>\n  <div>beep</div>\n  <div>boop</div>\n</Appear>\n\n---\n\n## The End\n\n"
  },
  {
    "path": "packages/gatsby-theme/gatsby-browser.js",
    "content": "export { wrapPageElement } from './src'\n"
  },
  {
    "path": "packages/gatsby-theme/gatsby-config.js",
    "content": "const IS_LOCAL = process.cwd() === __dirname\n\nconst remarkPlugins = [require('remark-unwrap-images'), require('remark-emoji')]\nconst gatsbyRemarkPlugins = [`gatsby-remark-import-code`]\n\nconst config = (opts = {}) => {\n  const { mdx = true, contentPath: name = 'decks' } = opts\n\n  return {\n    plugins: [\n      {\n        resolve: 'gatsby-source-filesystem',\n        options: {\n          name,\n          path: name,\n        },\n      },\n      mdx && {\n        resolve: 'gatsby-plugin-mdx',\n        options: {\n          gatsbyRemarkPlugins,\n          remarkPlugins,\n        },\n      },\n      'gatsby-plugin-react-helmet',\n      'gatsby-plugin-emotion',\n      'gatsby-plugin-catch-links',\n      'gatsby-plugin-theme-ui',\n      {\n        resolve: 'gatsby-plugin-compile-es6-packages',\n        options: {\n          modules: ['@mdx-deck/themes'],\n        },\n      },\n    ].filter(Boolean),\n  }\n}\n\nmodule.exports = IS_LOCAL ? config() : config\n"
  },
  {
    "path": "packages/gatsby-theme/gatsby-node.js",
    "content": "// based on gatsby-theme-blog\nconst fs = require(`fs`)\nconst path = require(`path`)\nconst mkdirp = require(`mkdirp`)\nconst Debug = require(`debug`)\nconst pkg = require('./package.json')\n\nconst debug = Debug(pkg.name)\n\nlet basePath\nlet contentPath\n\nconst DeckTemplate = require.resolve(`./src/templates/deck`)\nconst DecksTemplate = require.resolve(`./src/templates/decks`)\n\nexports.onPreBootstrap = ({ store }, opts = {}) => {\n  const { program } = store.getState()\n\n  basePath = opts.basePath || `/`\n  contentPath = opts.contentPath || `decks`\n\n  if (opts.cli) return\n  const dirname = path.join(program.directory, contentPath)\n  mkdirp.sync(dirname)\n\n  debug(`Initializing ${dirname} directory`)\n}\n\nconst mdxResolverPassthrough = fieldName => async (\n  source,\n  args,\n  context,\n  info\n) => {\n  const type = info.schema.getType(`Mdx`)\n  const mdxNode = context.nodeModel.getNodeById({\n    id: source.parent,\n  })\n  const resolver = type.getFields()[fieldName].resolve\n  const result = await resolver(mdxNode, args, context, {\n    fieldName,\n  })\n  return result\n}\n\nconst resolveTitle = async (...args) => {\n  const headings = await mdxResolverPassthrough('headings')(...args)\n  const [first = {}] = headings\n  return first.value || ''\n}\n\nexports.createSchemaCustomization = ({ actions, schema }) => {\n  actions.createTypes(\n    schema.buildObjectType({\n      name: `Deck`,\n      fields: {\n        id: { type: `ID!` },\n        slug: {\n          type: `String!`,\n        },\n        title: {\n          type: 'String!',\n          resolve: resolveTitle,\n        },\n        body: {\n          type: `String!`,\n          resolve: mdxResolverPassthrough(`body`),\n        },\n      },\n      interfaces: [`Node`],\n    })\n  )\n}\n\nexports.createPages = async ({ graphql, actions, reporter, pathPrefix }) => {\n  const { createPage } = actions\n\n  const result = await graphql(`\n    {\n      allDeck {\n        edges {\n          node {\n            id\n            slug\n            title\n          }\n        }\n      }\n    }\n  `)\n\n  if (result.errors) {\n    reporter.panic(result.errors)\n  }\n\n  const { allDeck } = result.data\n  const decks = allDeck.edges\n\n  // single deck mode\n  if (decks.length === 1) {\n    const [deck] = decks\n    const base = basePath === '/' ? '' : basePath\n    const matchPath = [base, '*'].join('/')\n\n    const slug = [pathPrefix, base].filter(Boolean).join('')\n\n    createPage({\n      path: basePath,\n      matchPath,\n      component: DeckTemplate,\n      context: {\n        ...deck.node,\n        slug,\n      },\n    })\n    createPage({\n      path: base + '/print',\n      component: DeckTemplate,\n      context: {\n        ...deck.node,\n        slug,\n      },\n    })\n    return\n  }\n\n  decks.forEach(({ node }, index) => {\n    const matchPath = [node.slug, '*'].join('/')\n    const slug = [pathPrefix, node.slug].filter(Boolean).join('')\n\n    createPage({\n      path: node.slug,\n      matchPath,\n      component: DeckTemplate,\n      context: {\n        ...node,\n        slug,\n      },\n    })\n    createPage({\n      path: slug + '/print',\n      component: DeckTemplate,\n      context: {\n        ...node,\n        slug,\n      },\n    })\n  })\n\n  // index page\n  createPage({\n    path: basePath,\n    component: DecksTemplate,\n    context: {\n      decks,\n    },\n  })\n}\n\nexports.onCreateNode = ({\n  node,\n  actions,\n  getNode,\n  createNodeId,\n  createContentDigest,\n}) => {\n  const { createNode, createParentChildLink } = actions\n\n  const toPath = node => {\n    const { dir } = path.posix.parse(node.relativePath)\n    return path.posix.join(basePath, dir, node.name)\n  }\n\n  if (node.internal.type !== `Mdx`) return\n\n  const fileNode = getNode(node.parent)\n  const source = fileNode.sourceInstanceName\n\n  if (node.internal.type !== `Mdx` || source !== contentPath) return\n\n  const slug = toPath(fileNode)\n  const id = createNodeId(`${node.id} >>> Deck`)\n\n  createNode({\n    slug,\n    // Required fields.\n    id,\n    parent: node.id,\n    children: [],\n    internal: {\n      type: `Deck`,\n      contentDigest: createContentDigest(node.rawBody),\n      content: node.rawBody,\n      description: `Slide Decks`,\n    },\n  })\n  createParentChildLink({ parent: fileNode, child: getNode(id) })\n}\n\nexports.onCreateDevServer = ({ app }) => {\n  if (typeof process.send !== 'function') return\n  process.send({\n    mdxDeck: true,\n  })\n}\n"
  },
  {
    "path": "packages/gatsby-theme/gatsby-ssr.js",
    "content": "export { wrapPageElement } from './src'\n"
  },
  {
    "path": "packages/gatsby-theme/index.js",
    "content": "export * from './src'\n"
  },
  {
    "path": "packages/gatsby-theme/package.json",
    "content": "{\n  \"name\": \"gatsby-theme-mdx-deck\",\n  \"version\": \"4.1.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"gatsby develop\",\n    \"build\": \"gatsby build\",\n    \"clean\": \"gatsby clean\"\n  },\n  \"devDependencies\": {\n    \"gatsby\": \"^2.13.6\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  },\n  \"peerDependencies\": {\n    \"gatsby\": \"^2.13.6\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  },\n  \"dependencies\": {\n    \"@emotion/core\": \"^10.0.14\",\n    \"@mdx-deck/themes\": \"^4.1.0\",\n    \"@mdx-js/mdx\": \"^1.0.21\",\n    \"@mdx-js/react\": \"^1.0.21\",\n    \"@reach/router\": \"^1.2.1\",\n    \"debug\": \"^4.1.1\",\n    \"gatsby\": \"^2.13.24\",\n    \"gatsby-plugin-catch-links\": \"^2.1.0\",\n    \"gatsby-plugin-compile-es6-packages\": \"^2.0.0\",\n    \"gatsby-plugin-emotion\": \"^4.1.0\",\n    \"gatsby-plugin-mdx\": \"^1.0.13\",\n    \"gatsby-plugin-react-helmet\": \"^3.1.0\",\n    \"gatsby-plugin-theme-ui\": \"^0.3.0\",\n    \"gatsby-remark-import-code\": \"^0.1.1\",\n    \"gatsby-source-filesystem\": \"^2.1.3\",\n    \"hhmmss\": \"^1.0.0\",\n    \"lodash.get\": \"^4.4.2\",\n    \"lodash.merge\": \"^4.6.1\",\n    \"mkdirp\": \"^1.0.3\",\n    \"react-helmet\": \"^6.0.0-beta\",\n    \"react-swipeable\": \"^5.3.0\",\n    \"remark-emoji\": \"^2.0.2\",\n    \"remark-unwrap-images\": \"^2.0.0\",\n    \"theme-ui\": \"^0.3.1\"\n  },\n  \"gitHead\": \"13d00b47780424cc3b52d38ad6f19e99d007c06a\"\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/app.js",
    "content": "import React, { useReducer } from 'react'\nimport merge from 'lodash.merge'\nimport Context from '../context'\nimport { modes } from '../constants'\n\nconst reducer = (state, next) =>\n  typeof next === 'function'\n    ? merge({}, state, next(state))\n    : merge({}, state, next)\n\nexport default props => {\n  const [state, setState] = useReducer(reducer, {\n    mode: modes.normal,\n    step: 0,\n    metadata: {},\n  })\n\n  const register = (index, key, value) => {\n    if (state.metadata[index] && state.metadata[index][key]) return\n    setState({\n      metadata: {\n        [index]: {\n          [key]: value,\n        },\n      },\n    })\n  }\n\n  const context = {\n    ...state,\n    setState,\n    register,\n  }\n\n  return <Context.Provider value={context}>{props.children}</Context.Provider>\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/appear.js",
    "content": "import React from 'react'\nimport useSteps from '../hooks/use-steps'\n\nexport const Appear = props => {\n  const children = React.Children.toArray(props.children)\n  const step = useSteps(children.length)\n  const styled = children.map((child, i) =>\n    React.cloneElement(child, {\n      style: {\n        visibility: i < step ? 'visible' : 'hidden',\n      },\n    })\n  )\n\n  return <>{styled}</>\n}\n\nexport default Appear\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/clock.js",
    "content": "import { useEffect, useState } from 'react'\n\nexport const Clock = props => {\n  const [time, setTime] = useState(new Date().toLocaleTimeString())\n  useEffect(() => {\n    const tick = () => {\n      const now = new Date()\n      setTime(now.toLocaleTimeString())\n    }\n    const timer = setInterval(tick, 1000)\n    return () => {\n      clearInterval(timer)\n    }\n  }, [])\n\n  return time\n}\n\nexport default Clock\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/deck.js",
    "content": "import React from 'react'\nimport { Router, globalHistory } from '@reach/router'\nimport { Global } from '@emotion/core'\nimport { ThemeProvider } from 'theme-ui'\nimport { Helmet } from 'react-helmet'\nimport get from 'lodash.get'\nimport merge from 'lodash.merge'\nimport useKeyboard from '../hooks/use-keyboard'\nimport useStorage from '../hooks/use-storage'\nimport useDeck from '../hooks/use-deck'\nimport Context from '../context'\nimport Wrapper from './wrapper'\nimport Slide from './slide'\nimport { modes } from '../constants'\n\nimport Presenter from './presenter'\nimport Overview from './overview'\nimport Grid from './grid'\n\nconst Keyboard = () => {\n  useKeyboard()\n  return false\n}\n\nconst Storage = () => {\n  useStorage()\n  return false\n}\n\nconst Print = ({ slides }) => {\n  const outer = useDeck()\n  const context = {\n    ...outer,\n    mode: modes.print,\n  }\n\n  return (\n    <Context.Provider value={context}>\n      {slides.map((slide, i) => (\n        <Slide key={i} slide={slide} preview />\n      ))}\n    </Context.Provider>\n  )\n}\n\nconst getIndex = () => {\n  const { pathname } = globalHistory.location\n  const paths = pathname.split('/')\n  const n = Number(paths[paths.length - 1])\n  const index = isNaN(n) ? 0 : n\n  return index\n}\n\nconst GoogleFont = ({ theme }) => {\n  if (!theme.googleFont) return false\n  return (\n    <Helmet>\n      <link rel=\"stylesheet\" href={theme.googleFont} />\n    </Helmet>\n  )\n}\n\nconst mergeThemes = (...themes) =>\n  themes.reduce(\n    (acc, theme) =>\n      typeof theme === 'function' ? theme(acc) : merge(acc, theme),\n    {}\n  )\n\nconst DefaultMode = ({ children }) => <React.Fragment children={children} />\n\nexport default ({\n  slides = [],\n  pageContext: { title, slug },\n  theme = {},\n  themes = [],\n  ...props\n}) => {\n  const outer = useDeck()\n  const index = getIndex()\n\n  const head = slides.head.children\n\n  const { components, ...mergedTheme } = mergeThemes(theme, ...themes)\n\n  const context = {\n    ...outer,\n    slug,\n    length: slides.length,\n    index,\n    steps: get(outer, `metadata.${index}.steps`),\n    notes: get(outer, `metadata.${index}.notes`),\n    theme: mergedTheme,\n  }\n\n  let Mode = DefaultMode\n\n  switch (context.mode) {\n    case modes.presenter:\n      Mode = Presenter\n      break\n    case modes.overview:\n      Mode = Overview\n      break\n    case modes.grid:\n      Mode = Grid\n      break\n    default:\n      break\n  }\n\n  return (\n    <>\n      <Helmet>\n        {title && <title>{title}</title>}\n        {head}\n      </Helmet>\n      <GoogleFont theme={mergedTheme} />\n      <Context.Provider value={context}>\n        <ThemeProvider components={components} theme={mergedTheme}>\n          <Global\n            styles={{\n              body: {\n                overflow: context.mode === modes.normal ? 'hidden' : null,\n              },\n            }}\n          />\n          <Keyboard />\n          <Storage />\n          <Wrapper>\n            <Mode slides={slides}>\n              <Router\n                basepath={slug}\n                style={{\n                  height: '100%',\n                }}>\n                <Slide index={0} path=\"/\" slide={slides[0]} />\n                {slides.map((slide, i) => (\n                  <Slide key={i} index={i} path={i + '/*'} slide={slide} />\n                ))}\n                <Print path=\"/print\" slides={slides} />\n              </Router>\n            </Mode>\n          </Wrapper>\n        </ThemeProvider>\n      </Context.Provider>\n    </>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/decks.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport { Link } from 'gatsby'\n\nexport default ({ decks }) => {\n  return (\n    <div\n      sx={{\n        fontFamily: 'ui',\n        fontWeight: 'bold',\n        px: 4,\n        py: 3,\n      }}>\n      <h1>MDX Deck</h1>\n      <ul\n        sx={{\n          p: 0,\n        }}>\n        {decks.map(d => (\n          <li\n            key={d.id}\n            sx={{\n              my: 2,\n            }}>\n            <Link\n              to={d.slug}\n              sx={{\n                color: 'inherit',\n                textDecoration: 'none',\n                ':hover': {\n                  textDecoration: 'underline',\n                },\n              }}>\n              {d.slug}\n            </Link>\n          </li>\n        ))}\n      </ul>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/embed.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport splitSlides from '../split-slides'\nimport Slide from './slide'\nimport Zoom from './zoom'\n\nconst wrapper = ({ slide: i, ratio, zoom, ...props }) => {\n  const slides = splitSlides(props)\n  const slide = slides[i - 1]\n\n  if (!slide) {\n    return <pre>No slide found (slide {i})</pre>\n  }\n\n  return (\n    <Zoom zoom={zoom} ratio={ratio}>\n      <Slide slide={slide} preview />\n    </Zoom>\n  )\n}\n\nconst components = {\n  wrapper,\n}\n\nexport const Embed = ({\n  src: Deck,\n  slide = 1,\n  ratio = 16 / 9,\n  zoom = 1,\n  ...props\n}) => (\n  <Deck\n    {...props}\n    components={components}\n    slide={slide}\n    ratio={ratio}\n    zoom={zoom}\n  />\n)\n\nexport default Embed\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/full-screen-code.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport const FullScreenCode = ({ ...props }) => (\n  <div\n    {...props}\n    sx={{\n      width: '100%',\n      height: '100%',\n      pre: {\n        // hack for prism styles\n        margin: '0 !important',\n        width: '100%',\n        height: '100%',\n        overflow: 'auto',\n      },\n    }}\n  />\n)\n\nexport default FullScreenCode\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/grid.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport { navigate } from '@reach/router'\nimport useDeck from '../hooks/use-deck'\nimport { modes } from '../constants'\nimport SlideList from './slide-list'\n\nexport default ({ slides }) => {\n  const { slug, setState } = useDeck()\n  return (\n    <div\n      sx={{\n        minHeight: '100vh',\n        color: 'white',\n        bg: 'black',\n      }}>\n      <div\n        sx={{\n          display: 'flex',\n          flexWrap: 'wrap',\n        }}>\n        <SlideList\n          slides={slides}\n          onClick={i => {\n            navigate([slug, i].join('/'))\n            setState({ mode: modes.normal })\n          }}\n          sx={{\n            width: '25%',\n            m: 0,\n          }}\n        />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/head.js",
    "content": "export const Head = props => false\n\nHead.mdxDeckHead = true\n\nexport default Head\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/horizontal.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\n\nexport const Horizontal = ({ ...props }) => {\n  const children = React.Children.toArray(props.children)\n\n  return (\n    <div\n      {...props}\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        height: '100%',\n        textAlign: 'center',\n      }}>\n      {children.map((child, i) => (\n        <div key={child.key} sx={{ width: 100 / children.length + '%' }}>\n          {child}\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default Horizontal\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/image.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport const Image = ({\n  width = '100%',\n  height = '100%',\n  size = 'cover',\n  src,\n  css,\n  ...props\n}) => (\n  <div\n    {...props}\n    sx={{\n      width,\n      height,\n      backgroundImage: `url(${src})`,\n      backgroundSize: size,\n      backgroundPosition: 'center',\n      backgroundRepeat: 'no-repeat',\n    }}\n    css={css}\n  />\n)\n\nexport default Image\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/invert.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport const Invert = ({ ...props }) => (\n  <div\n    {...props}\n    sx={{\n      display: 'flex',\n      flexDirection: 'column',\n      alignItems: 'center',\n      justifyContent: 'center',\n      width: '100%',\n      height: '100%',\n      color: 'background',\n      bg: 'text',\n      a: {\n        color: 'inherit',\n      },\n    }}\n  />\n)\n\nexport default Invert\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/notes.js",
    "content": "import { useEffect } from 'react'\nimport useDeck from '../hooks/use-deck'\n\nexport const Notes = props => {\n  const context = useDeck()\n  useEffect(() => {\n    context.register(context.index, 'notes', props.children)\n  }, [props.children])\n\n  return false\n}\n\nexport default Notes\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/overview.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport { navigate } from '@reach/router'\nimport useDeck from '../hooks/use-deck'\nimport Zoom from './zoom'\nimport SlideList from './slide-list'\n\nexport default ({ slides, children }) => {\n  const { slug, index, length } = useDeck()\n\n  return (\n    <div\n      sx={{\n        display: 'flex',\n        height: '100vh',\n        fontFamily: 'ui',\n        color: 'white',\n        bg: 'black',\n      }}>\n      <div\n        sx={{\n          width: 100 / 6 + '%',\n          minWidth: 0,\n          flex: 'none',\n          height: '100vh',\n          overflowY: 'auto',\n          WebkitOverflowScrolling: 'touch',\n          p: 2,\n        }}>\n        <SlideList\n          slides={slides}\n          zoom={1 / 6}\n          onClick={i => {\n            navigate([slug, i].join('/'))\n          }}\n        />\n      </div>\n      <div\n        sx={{\n          width: 500 / 6 + '%',\n          py: 3,\n          pr: 3,\n          display: 'flex',\n          flexDirection: 'column',\n          height: '100vh',\n        }}>\n        <div\n          sx={{\n            flex: '1 1 auto',\n          }}>\n          <Zoom zoom={5 / 6}>{children}</Zoom>\n        </div>\n        <div\n          sx={{\n            py: 3,\n          }}>\n          {index} / {length - 1}\n        </div>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/presenter-footer.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\nimport { globalHistory } from '@reach/router'\nimport useDeck from '../hooks/use-deck'\nimport Clock from './clock'\nimport Timer from './timer'\n\nexport default props => {\n  const context = useDeck()\n  const { index, length } = context\n\n  return (\n    <React.Fragment>\n      <div>\n        {index} / {length - 1}\n      </div>\n      <div\n        sx={{\n          mx: 4,\n        }}>\n        <a\n          href={globalHistory.location.href}\n          rel=\"noopener noreferrer\"\n          target=\"_blank\"\n          sx={{\n            color: 'inherit',\n            textDecoration: 'none',\n          }}>\n          Open in New Window ↗︎\n        </a>\n      </div>\n      <div sx={{ mx: 'auto' }} />\n      <div\n        sx={{\n          display: 'flex',\n          alignItems: 'center',\n          mx: 4,\n        }}>\n        <Timer />\n      </div>\n      <div>\n        <Clock />\n      </div>\n    </React.Fragment>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/presenter.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\nimport Zoom from './zoom'\nimport Slide from './slide'\nimport useDeck from '../hooks/use-deck'\nimport Footer from './presenter-footer'\n\nexport const Presenter = ({ slides, children }) => {\n  const context = useDeck()\n  const next = slides[context.index + 1]\n  const notes = context.notes ? React.Children.toArray(context.notes) : false\n\n  return (\n    <div\n      sx={{\n        display: 'flex',\n        flexDirection: 'column',\n        justifyContent: 'space-between',\n        height: '100vh',\n        fontFamily: 'ui',\n        color: 'white',\n        bg: 'black',\n      }}>\n      <div\n        sx={{\n          display: 'flex',\n          flex: '1 1 auto',\n          height: '60vh',\n        }}>\n        <div\n          sx={{\n            width: '75%',\n            p: 3,\n          }}>\n          <Zoom zoom={3 / 4}>{children}</Zoom>\n        </div>\n        <div\n          sx={{\n            width: '25%',\n            p: 3,\n          }}>\n          <Zoom ratio={4 / 3} zoom={1 / 4}>\n            <Slide slide={next} preview />\n          </Zoom>\n          {notes && (\n            <div\n              sx={{\n                my: 3,\n              }}>\n              {notes}\n            </div>\n          )}\n        </div>\n      </div>\n      <div\n        sx={{\n          height: 96,\n          p: 3,\n          display: 'flex',\n          alignItems: 'center',\n          fontSize: 1,\n          fontWeight: 'bold',\n          fontVariantNumeric: 'tabular-nums',\n        }}>\n        <Footer />\n      </div>\n    </div>\n  )\n}\n\nexport default Presenter\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/slide-list.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React, { useEffect, useRef } from 'react'\nimport Zoom from './zoom'\nimport Slide from './slide'\nimport useDeck from '../hooks/use-deck'\n\nconst noop = () => {}\n\nexport const SlideList = ({\n  slides = [],\n  ratio = 16 / 9,\n  zoom = 1 / 4,\n  onClick = noop,\n  ...props\n}) => {\n  const { index } = useDeck()\n  const thumb = useRef(null)\n\n  useEffect(() => {\n    const el = thumb.current\n    if (!el) return\n    if (typeof el.scrollIntoViewIfNeeded === 'function') {\n      el.scrollIntoViewIfNeeded()\n    }\n  })\n\n  return (\n    <React.Fragment>\n      {slides.map((slide, i) => (\n        <div\n          {...props}\n          key={i}\n          role=\"link\"\n          ref={i === index ? thumb : null}\n          onClick={e => {\n            onClick(i)\n          }}\n          style={\n            index === i\n              ? {\n                  position: 'relative',\n                  zIndex: 1,\n                }\n              : null\n          }\n          sx={{\n            m: 2,\n            cursor: 'pointer',\n            outline: index === i ? `4px solid cyan` : null,\n          }}>\n          <Zoom zoom={zoom} ratio={ratio}>\n            <Slide slide={slide} preview />\n          </Zoom>\n        </div>\n      ))}\n    </React.Fragment>\n  )\n}\n\nexport default SlideList\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/slide.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React, { Fragment } from 'react'\nimport Context from '../context'\nimport useDeck from '../hooks/use-deck'\nimport useSwipe from '../hooks/use-swipe'\nimport { modes } from '../constants'\n\nexport const Slide = ({ slide, index, preview, ...props }) => {\n  const outer = useDeck()\n  const swipeProps = useSwipe()\n  const context = {\n    ...outer,\n    index,\n    preview,\n  }\n\n  return (\n    <Context.Provider value={context}>\n      <div\n        {...(!preview ? swipeProps : {})}\n        sx={{\n          boxSizing: 'border-box',\n          width: '100%',\n          height: context.mode === modes.print ? '100vh' : '100%',\n          display: 'flex',\n          flexDirection: 'column',\n          alignItems: 'center',\n          justifyContent: 'center',\n          overflow: 'hidden',\n          position: 'relative',\n          color: 'text',\n          bg: 'background',\n          variant: 'styles.Slide',\n        }}>\n        {slide}\n      </div>\n    </Context.Provider>\n  )\n}\n\nexport default Slide\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/split-right.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\n\nexport const SplitRight = ({ children, ...props }) => {\n  const [first, ...rest] = React.Children.toArray(children)\n  return (\n    <div\n      {...props}\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        height: '100%',\n        textAlign: 'center',\n      }}>\n      <div sx={{ width: '50%' }}>{rest}</div>\n      <div sx={{ width: '50%' }}>{first}</div>\n    </div>\n  )\n}\n\nexport default SplitRight\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/split.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React from 'react'\n\nexport const Split = ({ children, ...props }) => {\n  const [first, ...rest] = React.Children.toArray(children)\n  return (\n    <div\n      {...props}\n      sx={{\n        display: 'flex',\n        alignItems: 'center',\n        height: '100%',\n        textAlign: 'center',\n      }}>\n      <div sx={{ width: '50%' }}>{first}</div>\n      <div sx={{ width: '50%' }}>{rest}</div>\n    </div>\n  )\n}\n\nexport default Split\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/timer.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React, { useEffect } from 'react'\nimport hhmmss from 'hhmmss'\nimport useDeck from '../hooks/use-deck'\n\nlet ticker\n\nexport const Timer = props => {\n  const { setState, timer = false, seconds = 0 } = useDeck()\n\n  useEffect(() => {\n    const tick = () => {\n      if (!timer) return\n      setState({\n        seconds: seconds + 1,\n      })\n    }\n    ticker = setInterval(tick, 1000)\n    return () => {\n      clearInterval(ticker)\n    }\n  }, [timer, seconds])\n\n  const toggle = () => {\n    setState({\n      timer: !timer,\n    })\n  }\n\n  const reset = () => {\n    setState({ seconds: 0 })\n  }\n\n  return (\n    <React.Fragment>\n      <button\n        onClick={reset}\n        disabled={!seconds}\n        title=\"Reset timer\"\n        sx={{\n          mx: 1,\n        }}>\n        Reset\n      </button>{' '}\n      <button\n        title={timer ? 'Stop timer' : 'Start timer'}\n        onClick={toggle}\n        sx={{\n          mx: 1,\n        }}>\n        {timer ? 'Stop' : 'Start'}\n      </button>{' '}\n      {hhmmss(seconds)}\n    </React.Fragment>\n  )\n}\n\nexport default Timer\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/wrapper.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\nimport React, { Fragment, useState, useEffect } from 'react'\nimport useDeck from '../hooks/use-deck'\nimport { modes } from '../constants'\n\nconst DefaultProvider = props =>\n  React.createElement(Fragment, null, props.children)\n\nexport default props => {\n  const [height, setHeight] = useState('100vh')\n  const { mode, theme } = useDeck()\n\n  useEffect(() => {\n    // handle mobile safari height\n    setHeight(window.innerHeight)\n    const handleResize = e => {\n      setHeight(window.innerHeight)\n    }\n    const stopTouch = e => {\n      if (mode !== modes.normal) return\n      e.preventDefault()\n    }\n    window.addEventListener('resize', handleResize)\n    document.body.addEventListener('touchstart', stopTouch)\n    return () => {\n      window.removeEventListener('resize', handleResize)\n      document.body.removeEventListener('touchstart', stopTouch)\n    }\n  }, [mode])\n\n  const { Provider = DefaultProvider } = theme\n\n  return (\n    <Provider>\n      <div\n        {...props}\n        sx={{\n          width: '100vw',\n          height: mode !== modes.print ? height : '100vh',\n          variant: 'styles.root',\n          '*': {\n            boxSizing: 'border-box',\n          },\n        }}\n      />\n    </Provider>\n  )\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/components/zoom.js",
    "content": "/** @jsx jsx */\nimport { jsx } from 'theme-ui'\n\nexport const Zoom = ({ ratio, zoom = 1, ...props }) => (\n  <div\n    sx={{\n      boxSizing: 'border-box',\n      width: '100%',\n      position: 'relative',\n      height: ratio ? 0 : '100%',\n      pb: ratio ? `${(1 / ratio) * 100}%` : 0,\n    }}>\n    <div\n      {...props}\n      sx={{\n        boxSizing: 'border-box',\n        position: 'absolute',\n        top: 0,\n        right: 0,\n        bottom: 0,\n        left: 0,\n        bg: 'cyan',\n        width: `${(1 / zoom) * 100}%`,\n        height: `${(1 / zoom) * 100}%`,\n        transformOrigin: '0 0',\n        transform: `scale(${zoom})`,\n      }}\n    />\n  </div>\n)\n\nexport default Zoom\n"
  },
  {
    "path": "packages/gatsby-theme/src/constants.js",
    "content": "export const modes = {\n  normal: 'NORMAL',\n  presenter: 'PRESENTER',\n  overview: 'OVERVIEW',\n  grid: 'GRID',\n  print: 'PRINT',\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/context.js",
    "content": "import { createContext } from 'react'\n\nexport default createContext({})\n"
  },
  {
    "path": "packages/gatsby-theme/src/convert-legacy-theme.js",
    "content": "import merge from 'lodash.merge'\n\nexport const convertLegacyTheme = (legacyTheme = {}) => {\n  const {\n    components,\n    colors = {},\n    font,\n    monospace,\n    // UI\n    Provider,\n    Presenter,\n    googleFont,\n    // styles\n    css,\n    heading,\n    ...styles\n  } = legacyTheme\n\n  const theme = {\n    googleFont,\n    colors: {\n      ...colors,\n      primary: colors.link,\n      muted: colors.codeBackground,\n    },\n    fonts: {\n      body: font,\n      heading: font,\n      monospace,\n    },\n    text: {\n      heading,\n    },\n    styles: merge(\n      {\n        root: css,\n        h1: {\n          variant: 'text.heading',\n        },\n        h2: {\n          variant: 'text.heading',\n        },\n        h3: {\n          variant: 'text.heading',\n        },\n        h4: {\n          variant: 'text.heading',\n        },\n        h5: {\n          variant: 'text.heading',\n        },\n        h6: {\n          variant: 'text.heading',\n        },\n        code: {\n          fontFamily: 'monospace',\n          color: 'code',\n          bg: 'codeBackground',\n        },\n        pre: {\n          fontFamily: 'monospace',\n          color: 'code',\n          bg: 'codeBackground',\n        },\n      },\n      styles\n    ),\n  }\n\n  return {\n    components,\n    theme,\n  }\n}\n\nexport default convertLegacyTheme\n"
  },
  {
    "path": "packages/gatsby-theme/src/gatsby-plugin-theme-ui/components.js",
    "content": "import {\n  Appear,\n  Notes,\n  Head,\n  Image,\n  FullScreenCode,\n  Horizontal,\n  Invert,\n  Split,\n  SplitRight,\n} from '..'\n\nexport default {\n  Appear,\n  Notes,\n  Head,\n  Image,\n  FullScreenCode,\n  Horizontal,\n  Invert,\n  Split,\n  SplitRight,\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/gatsby-plugin-theme-ui/index.js",
    "content": "export default {\n  colors: {\n    text: '#000',\n    background: '#fff',\n    primary: '#07c',\n    secondary: '#80c',\n    muted: '#f6f6ff',\n  },\n  fonts: {\n    body: 'system-ui, sans-serif',\n    heading: 'inherit',\n    monospace: '\"Roboto Mono\", Menlo, monospace',\n    ui: 'system-ui, sans-serif',\n  },\n  lineHeights: {\n    body: 1.5,\n    heading: 1.125,\n  },\n  fontWeights: {\n    body: 500,\n    heading: 700,\n    bold: 700,\n  },\n  text: {\n    heading: {\n      fontFamily: 'heading',\n      lineHeight: 'heading',\n      fontWeight: 'heading',\n    },\n  },\n  styles: {\n    Slide: {\n      fontFamily: 'body',\n      fontSize: [3, 4, 5, 6],\n    },\n    h1: {\n      variant: 'text.heading',\n    },\n    h2: {\n      variant: 'text.heading',\n    },\n    h3: {\n      variant: 'text.heading',\n    },\n    h4: {\n      variant: 'text.heading',\n    },\n    h5: {\n      variant: 'text.heading',\n    },\n    h6: {\n      variant: 'text.heading',\n    },\n    a: {\n      color: 'primary',\n    },\n    ul: {\n      m: 0,\n    },\n    ol: {\n      m: 0,\n    },\n    inlineCode: {\n      fontFamily: 'monospace',\n    },\n    code: {\n      fontFamily: 'monospace',\n    },\n    pre: {\n      fontFamily: 'monospace',\n      p: 3,\n    },\n    img: {\n      maxWidth: '100%',\n      height: 'auto',\n      objectFit: 'cover',\n    },\n    table: {\n      width: '100%',\n      borderCollapse: 'separate',\n      borderSpacing: 0,\n    },\n    th: {\n      textAlign: 'left',\n      paddingRight: '.5em',\n      paddingTop: '.25em',\n      paddingBottom: '.25em',\n      borderBottom: '1px solid',\n      verticalAlign: 'top',\n    },\n    td: {\n      textAlign: 'left',\n      paddingRight: '.5em',\n      paddingTop: '.25em',\n      paddingBottom: '.25em',\n      borderBottom: '1px solid',\n      verticalAlign: 'top',\n    },\n    blockquote: {\n      fontWeight: 'bold',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/hooks/use-deck.js",
    "content": "import { useContext } from 'react'\nimport DeckContext from '../context'\n\nexport const useDeck = () => useContext(DeckContext)\nexport default useDeck\n"
  },
  {
    "path": "packages/gatsby-theme/src/hooks/use-keyboard.js",
    "content": "/* eslint-disable */\nimport { useEffect } from 'react'\nimport { navigate } from '@reach/router'\nimport useDeck from './use-deck'\nimport { modes } from '../constants'\nimport { previous, next } from '../navigate'\n\nconst keys = {\n  right: 39,\n  left: 37,\n  up: 38,\n  down: 40,\n  space: 32,\n  p: 80,\n  o: 79,\n  g: 71,\n  esc: 27,\n  pageUp: 33,\n  pageDown: 34,\n}\n\nconst toggleMode = next => state =>\n  state.mode === next\n    ? {\n        mode: modes.normal,\n      }\n    : {\n        mode: next,\n      }\n\nconst inputElements = ['input', 'select', 'textarea', 'a', 'button']\n\nexport const useKeyboard = () => {\n  const context = useDeck()\n\n  useEffect(() => {\n    const handleKeyDown = e => {\n      const { metaKey, ctrlKey, shiftKey, altKey } = e\n      if (metaKey || ctrlKey) return\n\n      // ignore custom keyboard shortcuts when elements are focused\n      const el = document.activeElement.tagName.toLowerCase()\n      if (inputElements.includes(el)) return\n\n      if (shiftKey) {\n        switch (e.keyCode) {\n          case keys.space:\n            previous(context)\n            break\n          case keys.p:\n            context.setState(toggleMode(modes.print))\n            navigate(`${context.slug}/print`)\n            break\n        }\n      } else if (altKey) {\n        switch (e.keyCode) {\n          case keys.p:\n            context.setState(toggleMode(modes.presenter))\n            break\n          case keys.o:\n            context.setState(toggleMode(modes.overview))\n            break\n          case keys.g:\n            context.setState(toggleMode(modes.grid))\n            break\n        }\n      } else {\n        switch (e.keyCode) {\n          case keys.right:\n          case keys.down:\n          case keys.pageDown:\n          case keys.space:\n            next(context)\n            break\n          case keys.left:\n          case keys.up:\n          case keys.pageUp:\n            previous(context)\n            break\n          case keys.esc:\n            context.setState({ mode: modes.normal })\n            break\n        }\n      }\n    }\n\n    window.addEventListener('keydown', handleKeyDown)\n\n    return () => {\n      window.removeEventListener('keydown', handleKeyDown)\n    }\n  }, [context])\n}\n\nexport default useKeyboard\n"
  },
  {
    "path": "packages/gatsby-theme/src/hooks/use-steps.js",
    "content": "import { useEffect } from 'react'\nimport useDeck from './use-deck'\n\nexport const useSteps = length => {\n  const context = useDeck()\n  useEffect(() => {\n    if (typeof context.register !== 'function') return\n    context.register(context.index, 'steps', length)\n  }, [])\n  if (context.preview) return length\n  return context.step\n}\n\nexport default useSteps\n"
  },
  {
    "path": "packages/gatsby-theme/src/hooks/use-storage.js",
    "content": "import { useEffect, useState } from 'react'\nimport { navigate } from '@reach/router'\nimport useDeck from './use-deck'\n\nconst keys = {\n  slide: 'mdx-deck-slide',\n  step: 'mdx-deck-step',\n}\n\nexport const useStorage = () => {\n  const context = useDeck()\n  const [focused, setFocused] = useState(false)\n\n  const handleFocus = () => setFocused(true)\n  const handleBlur = () => setFocused(false)\n\n  const handleStorageChange = e => {\n    const n = parseInt(e.newValue, 10)\n    // if (focused) return\n    if (isNaN(n)) return\n    switch (e.key) {\n      case keys.slide:\n        navigate([context.slug, n].join('/'))\n        break\n      case keys.step:\n        context.setState({ step: n })\n        break\n      default:\n        break\n    }\n  }\n\n  useEffect(() => {\n    setFocused(document.hasFocus())\n  }, [])\n\n  useEffect(() => {\n    if (!focused) window.addEventListener('storage', handleStorageChange)\n    window.addEventListener('focus', handleFocus)\n    window.addEventListener('blur', handleBlur)\n    return () => {\n      if (!focused) window.removeEventListener('storage', handleStorageChange)\n      window.removeEventListener('focus', handleFocus)\n      window.removeEventListener('blur', handleBlur)\n    }\n  }, [focused])\n\n  // store changes\n  useEffect(() => {\n    if (!focused) return\n    localStorage.setItem(keys.slide, context.index)\n    localStorage.setItem(keys.step, context.step)\n  }, [focused, context.index, context.step])\n}\n\nexport default useStorage\n"
  },
  {
    "path": "packages/gatsby-theme/src/hooks/use-swipe.js",
    "content": "import { useSwipeable } from 'react-swipeable'\nimport useDeck from './use-deck'\nimport { previous, next } from '../navigate'\nimport { modes } from '../constants'\n\nconst toggleMode = next => state =>\n  state.mode === next ? { mode: modes.normal } : { mode: next }\n\nexport const useSwipe = () => {\n  const context = useDeck()\n\n  const onSwipedLeft = e => {\n    next(context)\n  }\n\n  const onSwipedRight = e => {\n    previous(context)\n  }\n\n  const onSwipedUp = e => {\n    context.setState({ mode: modes.presenter })\n  }\n\n  const onSwipedDown = e => {\n    context.setState({ mode: modes.normal })\n  }\n\n  const props = useSwipeable({\n    onSwipedLeft,\n    onSwipedRight,\n    onSwipedUp,\n    onSwipedDown,\n  })\n\n  return props\n}\n\nexport default useSwipe\n"
  },
  {
    "path": "packages/gatsby-theme/src/index.js",
    "content": "import React from 'react'\nimport App from './components/app'\n\nexport const wrapPageElement = ({ element }) => <App>{element}</App>\n\nexport { Appear } from './components/appear'\nexport { Notes } from './components/notes'\nexport { Head } from './components/head'\nexport { Clock } from './components/clock'\nexport { Timer } from './components/timer'\nexport { Slide } from './components/slide'\nexport { Zoom } from './components/zoom'\nexport { Embed } from './components/embed'\nexport { Image } from './components/image'\nexport { FullScreenCode } from './components/full-screen-code'\nexport { Horizontal } from './components/horizontal'\nexport { Invert } from './components/invert'\nexport { Split } from './components/split'\nexport { SplitRight } from './components/split-right'\n\nexport { useDeck } from './hooks/use-deck'\nexport { useSteps } from './hooks/use-steps'\n\nexport { convertLegacyTheme } from './convert-legacy-theme'\n"
  },
  {
    "path": "packages/gatsby-theme/src/navigate.js",
    "content": "// utilities for navigation\nimport { navigate } from '@reach/router'\n\nconst nextSlide = ({ slug, length, index, setState }) => {\n  const n = index + 1\n  if (n >= length) return\n  navigate([slug, n].join('/'))\n  setState({ step: 0 })\n}\n\nexport const next = context => {\n  const { steps, step, setState } = context\n  if (!steps || step >= steps) return nextSlide(context)\n  setState({ step: step + 1 })\n}\n\nconst previousSlide = ({ slug, index, metadata, setState }) => {\n  const n = index - 1\n  if (n < 0) return\n  navigate([slug, n].join('/'))\n  const { steps = 0 } = metadata[n] || {}\n  setState({ step: steps })\n}\n\nexport const previous = context => {\n  const { steps, step, setState } = context\n  if (steps && step > 0) {\n    return setState({ step: step - 1 })\n  }\n  previousSlide(context)\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/split-slides.js",
    "content": "import React from 'react'\n\nexport default props => {\n  const arr = React.Children.toArray(props.children)\n  const splits = []\n  const slides = []\n  slides.head = {\n    props: {},\n    children: [],\n  }\n  arr.forEach((child, i) => {\n    const {\n      originalType,\n      mdxType,\n      parentName,\n      children,\n      ...childProps\n    } = child.props\n    if (originalType.mdxDeckHead) {\n      slides.head.children.push(children)\n      Object.assign(slides.head.props, childProps)\n      arr.splice(i, 1)\n    }\n    if (mdxType === 'hr') splits.push(i)\n  })\n  let previousSplit = 0\n  splits.forEach(i => {\n    const children = [...arr.slice(previousSplit, i)]\n    slides.push(children)\n    previousSplit = i + 1\n  })\n\n  slides.push([...arr.slice(previousSplit)])\n\n  slides.head.children = React.Children.toArray(slides.head.children).map(\n    (child, i) => {\n      const { originalType, mdxType, parentName, ...childProps } = child.props\n      return React.createElement(originalType, {\n        key: i,\n        ...childProps,\n      })\n    }\n  )\n\n  return slides\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/templates/deck.js",
    "content": "import React from 'react'\nimport { graphql } from 'gatsby'\nimport { MDXRenderer } from 'gatsby-plugin-mdx'\nimport Deck from '../components/deck'\nimport splitSlides from '../split-slides'\n\nexport const pageQuery = graphql`\n  query($id: String!) {\n    deck: deck(id: { eq: $id }) {\n      id\n      body\n      title\n    }\n  }\n`\n\nconst wrapper = props => {\n  const slides = splitSlides(props)\n  return <Deck {...props} slides={slides} />\n}\n\nconst components = {\n  wrapper,\n}\n\nexport default ({\n  data: {\n    deck: { id, body },\n  },\n  ...props\n}) => {\n  const Component = props => <MDXRenderer {...props} children={body} />\n\n  return <Component {...props} components={components} />\n}\n"
  },
  {
    "path": "packages/gatsby-theme/src/templates/decks.js",
    "content": "import React from 'react'\nimport Decks from '../components/decks'\n\nexport default ({ pageContext, ...props }) => {\n  const decks = pageContext.decks.map(d => d.node)\n\n  return <Decks {...props} decks={decks} />\n}\n"
  },
  {
    "path": "packages/mdx-deck/.gitignore",
    "content": ".cache\npublic\nstatic\n"
  },
  {
    "path": "packages/mdx-deck/.npmignore",
    "content": ".cache\npublic\nstatic\n"
  },
  {
    "path": "packages/mdx-deck/README.md",
    "content": "![](https://s3.amazonaws.com/jxnblk/mdx-deck-2.gif)\n\n# MDX Deck <img src='docs/ace.png' width='24' height='24' />\n\nAward-winning React [MDX][]-based presentation decks\n\n[![Build Status][badge]][circleci]\n[![Version][]][npm]\n[![Downloads][]][npm]\n\n[badge]: https://flat.badgen.net/github/status/jxnblk/mdx-deck/master/ci/circleci\n[circleci]: https://circleci.com/gh/jxnblk/mdx-deck\n[version]: https://flat.badgen.net/npm/v/mdx-deck\n[downloads]: https://flat.badgen.net/npm/dm/mdx-deck\n[npm]: https://npmjs.com/package/mdx-deck\n\n- :memo: Write presentations in markdown\n- :atom_symbol: Import and use [React components](#imports)\n- :nail_care: Customizable [themes](#theming) and components\n- :zero: Zero-config CLI\n- :tipping_hand_woman: [Presenter mode](#presenter-mode)\n- :notebook: [Speaker notes](#speaker-notes)\n\n[View demo](https://mdx-deck.jxnblk.com)\n\n- [Getting Started](#getting-started)\n- [Using MDX](#using-mdx)\n- [Theming](#theming)\n- [Components](#components)\n- [Layouts](#layouts)\n- [Presenter Mode](#presenter-mode)\n- [Keyboard Shortcuts](#keyboard-shortcuts)\n- [CLI Options](#cli-options)\n- [Videos & Articles](#videos-articles)\n- [Examples](#examples)\n\n## Getting Started\n\n```sh\nnpm i -D mdx-deck\n```\n\nCreate an [MDX][] file and separate each slide with `---`.\n\n````mdx\n\n# Hello\n\n---\n\n## This is my deck\n\n---\n\n## The End\n\n````\n\nAdd a run script to your `package.json` with the MDX Deck CLI\npointing to the `.mdx` file to start the development server:\n\n```json\n\"scripts\": {\n  \"start\": \"mdx-deck deck.mdx\"\n}\n```\n\nStart the development server:\n\n```sh\nnpm start\n```\n\nUse the left and right arrow keys to navigate through the presentation.\n\n## Using MDX\n\nMDX uses Markdown syntax and can render React components inline with JSX.\n\n### Imports\n\nTo import components, use ES import syntax separated with empty lines between any markdown or JSX syntax.\n\n```mdx\nimport { Box } from 'theme-ui'\n\n<Box color=\"tomato\">Hello</Box>\n```\n\nRead more about MDX syntax in the [MDX Docs][mdx].\n\n## Theming\n\n<div>\n  <img src='docs/images/future.png' width='256' />\n  <img src='docs/images/comic.png' width='256' />\n  <img src='docs/images/yellow.png' width='256' />\n</div>\n\nMDX Deck uses [Theme UI][] and [Emotion][] for styling, making practically any part of the presentation themeable.\nIt also includes several built-in themes to change the look and feel of the presentation.\n\n- See the list of available [Themes](docs/themes.md)\n- Read more about theming in the [Theming docs](docs/theming.md).\n\n## Components\n\nMDX Deck includes built-in components to help with creating presentations,\na `Notes` component for adding speaker notes,\na `Head` component for the document head,\n`Header` and `Footer` components for persistent header and footer content,\nand a `Steps` component for adding multiple intermediate steps in a single slide.\n\nRead more in the [Components](docs/components.md) docs.\n\n### Third-Party Components\n\nThese optional libraries are intended for use with MDX Deck.\n\n- [CodeSurfer][]: React component for scrolling, zooming and highlighting code.\n- [mdx-code][]: Runnable code playgrounds for MDX Deck.\n- [mdx-deck-live-code][]: Live React and JS coding in slides.\n\n_Note: please check with version compatibility when using these libraries._\n\n[codesurfer]: https://github.com/pomber/code-surfer\n[mdx-code]: https://github.com/pranaygp/mdx-code\n[mdx-deck-live-code]: https://github.com/JReinhold/mdx-deck-live-code\n\n## Layouts\n\nEach slide can include a custom layout around its content,\nwhich can be used as a *template* for visually differentiating slides.\n\n```js\n// example Layout.js\nimport React from 'react'\n\nexport default ({ children }) => (\n  <div\n    style={{\n      width: '100vw',\n      height: '100vh',\n      backgroundColor: 'tomato',\n    }}>\n    {children}\n  </div>\n)\n```\n\n```mdx\nimport Layout from './Layout'\n\n# No Layout\n\n---\n\n<Layout>\n\n# Custom Layout\n\n</Layout>\n```\n\nThe layout component will wrap the MDX elements within that slide,\nwhich means you can add custom layout styles\nor style child elements with CSS-in-JS.\n\n## Presenter Mode\n\nPress `Option + P` to toggle *Presenter Mode*,\nwhich will show a preview of the next slide, a timer, and speaker notes.\n\n![presenter mode screenshot](docs/images/presenter-mode.png)\n\nThe presentation can be opened in two separate windows at the same time,\nand it will stay in sync with the other window.\n\n## Keyboard Shortcuts\n\n| Key         | Description                                  |\n| ----------- | -------------------------------------------- |\n| Left Arrow, Page Up, Shift + Space  | Go to previous slide (or step in [Steps][]) |\n| Right Arrow, Page Down, Space | Go to next slide (or step in [Steps][])     |\n| Option + P  | Toggle [Presenter Mode](#presenter-mode)     |\n| Option + O  | Toggle Overview Mode\n| Option + G  | Toggle Grid Mode\n\n[steps]: docs/components.md#steps\n\n## CLI Options\n\n```\n-p --port     Dev server port\n-h --host     Host the dev server listens to\n--no-open     Prevent from opening in default browser\n```\n\n## Videos & Articles\n\n- [Egghead Tutorial][egghead] by [Andrew Del Prete](https://github.com/andrewdelprete).\n- [mdx-deck: slide decks powered by markdown and react][kcd-blog] by [Kent C. Dodds][]\n- [Make Fast & Beautiful Presentations with MDX-Deck][hw-video] by [Harry Wolff][] ([Demo][hw-demo])\n- [What is MDX][kcd-video] by [Kent C. Dodds][]\n- [Build a Custom Provider Component for MDX-Deck][ks-egghead] by [Kyle Shevlin][]\n\n[egghead]: https://egghead.io/lessons/react-build-a-slide-deck-with-mdx-deck-using-markdown-react\n[kent c. dodds]: https://mobile.twitter.com/kentcdodds\n[kcd-video]: http://youtu.be/d2sQiI5NFAM?a\n[kcd-blog]: https://kentcdodds.com/blog/mdx-deck-slide-decks-powered-by-markdown-and-react\n[hw-video]: https://www.youtube.com/watch?v=LvP2EqCiQMg&feature=youtu.be\n[hw-demo]: https://github.com/hswolff/mdx-deck-demo\n[harry wolff]: https://mobile.twitter.com/hswolff\n[ks-egghead]: https://egghead.io/lessons/javascript-build-a-custom-provider-component-for-mdx-deck\n[kyle shevlin]: https://twitter.com/kyleshevlin\n\n\n## Examples\n\nSee how others have used MDX Deck for their presentations.\n\n- [Design Systems & React][design-systems-react] by [Diana Mounter](https://mobile.twitter.com/broccolini)\n- [Bringing Brazil to the Cloud, Now][brazil-now] by [Guillermo Rauch](https://mobile.twitter.com/rauchg/)\n- [Simplify React][simplify-react] by [Kent C. Dodds](https://mobile.twitter.com/kentcdodds)\n- [I Got 99 Problems but GraphQL Ain't One][99-problems] by [Sara Vieira](https://mobile.twitter.com/NikkitaFTW)\n- [Stop de #divFest][stop-div-fest] by [Sara Vieira](https://mobile.twitter.com/NikkitaFTW)\n- [MDX, authors and richer JAMstack content][mdx-talk] by [Josh Dzielak](https://mobile.twitter.com/dzello)\n- [Components as Data: A Cross Platform GraphQL Powered Component API][components-as-data] by [Luke Herrington](https://mobile.twitter.com/lukeherrington)\n- [A short history of webdevs future 🔮][webdev-intro] by [Hendrik Wallbaum](https://github.com/hoverbaum)\n\n### Usage Examples\n\nThe following examples will open in CodeSandbox.\n\n- [Basic Example](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/basic)\n- [Syntax Highlighting](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/syntax-highlighting)\n- [Steps](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/steps)\n- [Head](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/head)\n- [Header & Footer](https://codesandbox.io/s/github/jxnblk/mdx-deck/tree/master/examples/header-footer)\n\n---\n\n### Related\n\n- [MDX][]\n- [Gatsby][]\n- [Theme UI][]\n- [Emotion][]\n- [Spectacle][]\n\n[MIT License](LICENSE.md)\n\n[mdx]: https://mdxjs.com/\n[gatsby]: https://gatsbyjs.org\n[spectacle]: https://github.com/FormidableLabs/spectacle\n[emotion]: https://emotion.sh\n[theme ui]: https://theme-ui.com\n\n<!-- examples -->\n[design-systems-react]: https://github-ds.now.sh/#0\n[brazil-now]: https://braziljs.now.sh\n[simplify-react]: https://simply-react.netlify.com/#0\n[99-problems]: https://99-problems-graphql-aint-one.now.sh/#0\n[stop-div-fest]: https://stop-div-fest.now.sh/\n[mdx-talk]: https://mdx-talk.developermode.com/\n[components-as-data]: https://componentsasdata.lukeherrington.com\n[webdev-intro]: https://webdev-intro.talks.hoverbaum.net/\n"
  },
  {
    "path": "packages/mdx-deck/cli.js",
    "content": "#!/usr/bin/env node\nconst path = require('path')\nconst meow = require('meow')\nconst execa = require('execa')\nconst chalk = require('chalk')\nconst fs = require('fs-extra')\nconst pkg = require('./package.json')\n\nconst log = (...args) => {\n  console.log(chalk.green('[mdx-deck]'), ...args)\n}\nlog.error = (...args) => {\n  console.log(chalk.red('[err]'), ...args)\n}\n\nconst cli = meow(\n  `\n  ${chalk.gray('Usage')}\n\n    $ ${chalk.green('mdx-deck deck.mdx')}\n\n    $ ${chalk.green('mdx-deck build deck.mdx')}\n\n  ${chalk.gray('Options')}\n\n      -h --host     Dev server host\n      -p --port     Dev server port\n      --no-open     Prevent from opening in default browser\n\n`,\n  {\n    description: chalk.green('@mdx-deck/lite ') + chalk.gray(pkg.description),\n    flags: {\n      port: {\n        type: 'string',\n        alias: 'p',\n        default: '8000',\n      },\n      host: {\n        type: 'string',\n        alias: 'h',\n        default: 'localhost',\n      },\n      open: {\n        type: 'boolean',\n        alias: 'o',\n        default: true,\n      },\n    },\n  }\n)\n\nconst [cmd, file] = cli.input\nconst filename = file || cmd\n\nif (!filename) cli.showHelp(0)\n\nprocess.env.__SRC__ = path.resolve(filename)\n\nconst opts = Object.assign({}, cli.flags)\n\nlet dev\n\nconst gatsby = async (...args) => {\n  await execa('gatsby', ['clean'], {\n    cwd: __dirname,\n    stdio: 'inherit',\n    preferLocal: true,\n  })\n  return execa('gatsby', args.filter(Boolean), {\n    cwd: __dirname,\n    stdio: 'inherit',\n    preferLocal: true,\n  })\n}\n\nswitch (cmd) {\n  case 'build':\n    gatsby('build').then(() => {\n      const public = path.join(__dirname, 'public')\n      const dist = path.join(process.cwd(), 'public')\n      if (public === dist) return\n      fs.copySync(public, dist)\n    })\n    break\n  case 'dev':\n  default:\n    gatsby(\n      'develop',\n      '--host',\n      opts.host,\n      '--port',\n      opts.port,\n      opts.open && '--open'\n    )\n    break\n}\n"
  },
  {
    "path": "packages/mdx-deck/gatsby-config.js",
    "content": "const path = require('path')\n\nconst src = process.env.__SRC__\nconst dirname = path.dirname(src)\n\nmodule.exports = {\n  plugins: [\n    {\n      resolve: '@mdx-deck/gatsby-plugin',\n      options: {\n        path: src,\n        dirname,\n      },\n    },\n    {\n      resolve: 'gatsby-source-filesystem',\n      options: {\n        path: dirname,\n        ignore: [\n          'node_modules',\n          'public',\n          '.cache',\n        ]\n      },\n    },\n    {\n      resolve: 'gatsby-plugin-compile-es6-packages',\n      options: {\n        modules: ['mdx-deck', '@mdx-deck/themes'],\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "packages/mdx-deck/hello.mdx",
    "content": "\n<Head>\n  <title>MDX Deck v4</title>\n</Head>\n\n<Header>\n\nMDX Deck v4\n\n</Header>\n\n# Hello\n\n<Notes>\n\n## To do\n\n- [x] Print mode\n- [x] Grid mode\n- [x] page up/down\n- [x] Deprecate layouts/docs??\n- [x] Clean up docs/readme\n- [x] theme.components\n- [-] Changelog\n- [ ] Clean up demo\n\n</Notes>\n\n---\n\n## This is MDX Deck v4\n\nMDX-based presentation decks\n\n<Notes>\n\nThese are top-secret speaker notes. Shhhh!\n\n</Notes>\n\n---\n\n### What's New\n\n<StepList>\n\n- Persistent headers and footers\n- Simplified API\n- Refactored internals & bug fixes\n\n</StepList>\n\n---\n\n<img\n  src='https://images.unsplash.com/photo-1485881374599-20e5ddb80d84?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjF9'\n/>\n\n<Notes>\nStand clear of the closing doors\n</Notes>\n\n---\n\n```jsx\nimport React from 'react'\n\nexport default props =>\n  <div\n    {...props}\n    css={{\n      padding: 32,\n      backgroundColor: 'tomato',\n    }}\n  />\n```\n\n---\n\n## Get Started :sunglasses:\n\n[GitHub](https://github.com/jxnblk/mdx-deck)\n\n"
  },
  {
    "path": "packages/mdx-deck/index.js",
    "content": "import * as themes from '@mdx-deck/themes'\n\nexport { themes }\nexport * from '@mdx-deck/gatsby-plugin'\n"
  },
  {
    "path": "packages/mdx-deck/package.json",
    "content": "{\n  \"name\": \"mdx-deck\",\n  \"version\": \"4.1.1\",\n  \"description\": \"MDX-based presentation decks\",\n  \"bin\": {\n    \"mdx-deck\": \"./cli.js\"\n  },\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"./cli.js hello.mdx\",\n    \"build\": \"./cli.js build hello.mdx\",\n    \"help\": \"./cli.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"Brent Jackson\",\n  \"license\": \"MIT\",\n  \"repository\": \"github:jxnblk/mdx-deck\",\n  \"dependencies\": {\n    \"@mdx-deck/gatsby-plugin\": \"^4.1.1\",\n    \"@mdx-deck/themes\": \"^4.1.0\",\n    \"chalk\": \"^3.0.0\",\n    \"execa\": \"^4.0.0\",\n    \"fs-extra\": \"^8.1.0\",\n    \"gatsby\": \"^2.13.24\",\n    \"gatsby-plugin-compile-es6-packages\": \"^2.0.0\",\n    \"gatsby-source-filesystem\": \"^2.1.48\",\n    \"initit\": \"^1.0.0-2\",\n    \"meow\": \"^6.0.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  },\n  \"gitHead\": \"13d00b47780424cc3b52d38ad6f19e99d007c06a\"\n}\n"
  },
  {
    "path": "packages/starter/decks/.gitkeep",
    "content": ""
  },
  {
    "path": "packages/starter/gatsby-config.js",
    "content": "module.exports = {\n  plugins: ['gatsby-theme-mdx-deck'],\n}\n"
  },
  {
    "path": "packages/starter/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/gatsby-starter\",\n  \"version\": \"4.1.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"gatsby develop\",\n    \"clean\": \"gatsby clean\",\n    \"build\": \"gatsby build\"\n  },\n  \"dependencies\": {\n    \"gatsby\": \"^2.13.25\",\n    \"gatsby-theme-mdx-deck\": \"^4.1.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  },\n  \"gitHead\": \"36497d5571f1f354261b9f72f1f67e23c07bc22e\"\n}\n"
  },
  {
    "path": "packages/themes/README.md",
    "content": "# @mdx-deck/themes\n\nThemes used in MDX Deck\n\nhttps://github.com/jxnblk/mdx-deck\n"
  },
  {
    "path": "packages/themes/base.js",
    "content": "// kept for backwards compatibility\nexport default {}\n"
  },
  {
    "path": "packages/themes/big.js",
    "content": "const blue = '#0af'\n\nexport default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Bowlby+One+SC',\n  fonts: {\n    body: '\"Bowlby One SC\", sans-serif',\n  },\n  colors: {\n    text: '#dff',\n    background: '#011',\n    primary: blue,\n    blue,\n    black: '#000',\n  },\n  fontWeights: {\n    heading: 600,\n    bold: 600,\n  },\n  styles: {\n    pre: {\n      color: 'primary',\n      bg: 'black',\n    },\n    code: {\n      color: 'primary',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/book.js",
    "content": "const white = '#fffceb'\nconst black = '#11111f'\nconst blue = '#2d5dd7'\n\nexport default {\n  fonts: {\n    body: '\"Crimson Text\", serif',\n  },\n  googleFont: 'https://fonts.googleapis.com/css?family=Crimson+Text',\n  colors: {\n    text: black,\n    background: white,\n    link: blue,\n  },\n  styles: {\n    root: {\n      textAlign: 'left',\n    },\n    Slide: {\n      display: 'block',\n      padding: '2em',\n      textAlign: 'left',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/code.js",
    "content": "const blue = '#00cdf1'\nconst black = '#003d48'\nconst primary = '#0800e3'\n\nexport default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Source+Code+Pro',\n  fonts: {\n    body: '\"Source Code Pro\", monospace',\n    monospace: '\"Source Code Pro\", monospace',\n  },\n  colors: {\n    text: black,\n    background: blue,\n    primary,\n  },\n  styles: {\n    pre: {\n      color: 'background',\n      bg: 'text',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/comic.js",
    "content": "const white = '#fffceb'\nconst black = '#351e38'\nconst blue = '#2d5dd7'\n\nexport default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Gloria+Hallelujah',\n  fonts: {\n    body: '\"Gloria Hallelujah\", cursive',\n  },\n  colors: {\n    text: black,\n    background: white,\n    primary: blue,\n  },\n}\n"
  },
  {
    "path": "packages/themes/condensed.js",
    "content": "const blue = '#0af'\n\nexport default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Roboto+Condensed',\n  fonts: {\n    body: '\"Roboto Condensed\", system-ui, sans-serif',\n    monospace: '\"Roboto Mono\", monospace',\n  },\n  colors: {\n    text: '#fff',\n    background: '#000',\n    primary: blue,\n    pre: blue,\n    darkgray: '#111',\n  },\n  fontWeights: {\n    heading: 600,\n    bold: 600,\n  },\n  text: {\n    heading: {\n      textTransform: 'uppercase',\n    },\n  },\n  styles: {\n    pre: {\n      color: 'primary',\n      bg: 'darkgray',\n    },\n    code: {\n      color: 'primary',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/dark.js",
    "content": "export default {\n  colors: {\n    text: '#fff',\n    background: '#000',\n    primary: '#08f',\n    secondary: '#f0f',\n    darkgray: '#333',\n  },\n  styles: {\n    pre: {\n      color: 'secondary',\n      bg: 'darkgray',\n    },\n    code: {\n      color: 'secondary',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/future.js",
    "content": "const blue = '#0af'\n\nexport default {\n  fonts: {\n    body: '\"Avenir Next\", system-ui, sans-serif',\n  },\n  colors: {\n    text: '#fff',\n    background: '#111',\n    primary: blue,\n    black: '#000',\n  },\n  fontWeights: {\n    heading: 600,\n    bold: 600,\n  },\n  text: {\n    heading: {\n      textTransform: 'uppercase',\n      letterSpacing: '0.1em',\n    },\n  },\n  styles: {\n    pre: {\n      color: 'primary',\n      bg: 'black',\n    },\n    code: {\n      color: 'primary',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/index.js",
    "content": "export { default } from './base'\nexport { default as dark } from './dark'\nexport { default as future } from './future'\nexport { default as condensed } from './condensed'\nexport { default as yellow } from './yellow'\nexport { default as swiss } from './swiss'\nexport { default as poppins } from './poppins'\n\n// serif\nexport { default as book } from './book'\n\n// script\nexport { default as script } from './script'\nexport { default as comic } from './comic'\nexport { default as notes } from './notes'\nexport { default as code } from './code'\nexport { default as lobster } from './lobster'\n\n// syntax highlighting\nexport {\n  default as highlight,\n  default as syntaxHighlighter,\n} from './syntax-highlighter'\nexport {\n  default as prism,\n  default as syntaxHighlighterPrism,\n} from './syntax-highlighter-prism'\n"
  },
  {
    "path": "packages/themes/lobster.js",
    "content": "const text = '#220011'\n\nexport default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Lobster|Roboto+Mono',\n  fonts: {\n    body: 'Lobster, cursive',\n    monospace: '\"Roboto Mono\", monospace',\n  },\n  colors: {\n    text: text,\n    background: 'tomato',\n    primary: text,\n  },\n}\n"
  },
  {
    "path": "packages/themes/notes.js",
    "content": "const white = '#fff'\nconst black = '#000'\n\nexport default {\n  googleFont:\n    'https://fonts.googleapis.com/css?family=Annie+Use+Your+Telescope',\n  fonts: {\n    body: '\"Annie Use Your Telescope\", cursive',\n  },\n  colors: {\n    text: black,\n    background: white,\n  },\n  styles: {\n    root: {\n      textAlign: 'center',\n    },\n    pre: {\n      textAlign: 'left',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/package.json",
    "content": "{\n  \"name\": \"@mdx-deck/themes\",\n  \"version\": \"4.1.0\",\n  \"main\": \"index.js\",\n  \"author\": \"Brent Jackson <jxnblk@gmail.com>\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"lodash.merge\": \"^4.6.1\",\n    \"react-syntax-highlighter\": \"^12.2.1\"\n  },\n  \"gitHead\": \"13d00b47780424cc3b52d38ad6f19e99d007c06a\"\n}\n"
  },
  {
    "path": "packages/themes/poppins.js",
    "content": "export default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Poppins:400,900',\n  fonts: {\n    body: '\"Poppins\", sans-serif',\n  },\n  fontWeights: {\n    heading: 900,\n    bold: 900,\n  },\n  text: {\n    heading: {\n      fontWeight: 900,\n      letterSpacing: '-0.05em',\n    },\n  },\n  styles: {\n    blockquote: {\n      fontSize: '1.75em',\n      textAlign: 'left',\n      letterSpacing: '-0.05em',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/script.js",
    "content": "const cream = '#fe9'\nconst black = '#320'\n\nexport default {\n  googleFont: 'https://fonts.googleapis.com/css?family=Yellowtail|Roboto+Mono',\n  fonts: {\n    body: '\"Yellowtail\", cursive',\n    monospace: '\"Roboto Mono\", Menlo, monospace',\n  },\n  colors: {\n    text: black,\n    background: cream,\n    primary: black,\n  },\n  styles: {\n    root: {\n      textAlign: 'center',\n    },\n    pre: {\n      textAlign: 'left',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/swiss.js",
    "content": "const white = '#fff'\nconst black = '#000'\nconst red = '#f00'\n\nexport default {\n  fonts: {\n    body: '\"Helvetica Neue\", Helvetica, Arial, sans-serif',\n  },\n  colors: {\n    text: black,\n    background: white,\n    primary: red,\n  },\n  styles: {\n    root: {\n      textAlign: 'left',\n    },\n    Slide: {\n      display: 'block',\n      padding: '2em',\n      textAlign: 'left',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/themes/syntax-highlighter-prism.js",
    "content": "import React from 'react'\nimport { Prism } from 'react-syntax-highlighter'\n\nimport { getLanguage } from './syntax-highlighter'\n\nexport const pre = props => props.children\n\nexport const code = props => {\n  const language = getLanguage(props.className)\n  return <Prism language={language} {...props} />\n}\n\nexport default {\n  components: {\n    pre,\n    code,\n  },\n}\n"
  },
  {
    "path": "packages/themes/syntax-highlighter.js",
    "content": "import React from 'react'\nimport SyntaxHighlighter from 'react-syntax-highlighter'\n\nexport const getLanguage = className => {\n  const match = /language-(\\w*)/.exec(className || 'language-javascript')\n  let lang = 'javascript'\n  if (match && match.length > 1) {\n    lang = match[1]\n  }\n  return lang\n}\n\nexport const pre = props => props.children\n\nexport const code = props => {\n  const language = getLanguage(props.className)\n  return <SyntaxHighlighter language={language} {...props} />\n}\n\nexport default {\n  components: {\n    pre,\n    code,\n  },\n}\n"
  },
  {
    "path": "packages/themes/yellow.js",
    "content": "const yellow = '#fd0'\n\nexport default {\n  googleFont:\n    'https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700|Roboto+Mono',\n  fonts: {\n    body: '\"Roboto Condensed\", system-ui, sans-serif',\n    monospace: '\"Roboto Mono\", monospace',\n  },\n  colors: {\n    text: '#000',\n    background: yellow,\n    primary: '#333',\n  },\n  text: {\n    heading: {\n      textTransform: 'uppercase',\n    },\n  },\n  styles: {\n    pre: {\n      textAlign: 'left',\n      color: 'background',\n      bg: 'text',\n    },\n    code: {\n      color: 'background',\n      bg: 'text',\n    },\n  },\n}\n"
  },
  {
    "path": "packages/website-pdf/.gitignore",
    "content": "dist\n"
  },
  {
    "path": "packages/website-pdf/README.md",
    "content": "# website-pdf\n\nSave a URL as a PDF\n\n```sh\nnpm i -D website-pdf\n```\n\n```sh\nwebsite-pdf http://example.com -o example.pdf\n```\n\n## Options\n\n```\n-o --out-file   Output filename\n-w --width      Width in pixels\n-h --height     Height in pixels\n--no-sandbox    Disable puppeteer sandbox\n```\n"
  },
  {
    "path": "packages/website-pdf/cli.js",
    "content": "#!/usr/bin/env node\nconst path = require('path')\nconst meow = require('meow')\n\nconst cli = meow(\n  `\n  Usage:\n\n    $ website-pdf http://example.com\n\n  Options:\n\n    -o --out-file   Output filename\n    -w --width      Width in pixels\n    -h --height     Height in pixels\n    --no-sandbox    Disable puppeteer sandbox\n\n`,\n  {\n    flags: {\n      outFile: {\n        type: 'string',\n        alias: 'o',\n        default: 'website.pdf',\n      },\n      width: {\n        type: 'string',\n        alias: 'w',\n        default: '1280',\n      },\n      height: {\n        type: 'string',\n        alias: 'h',\n        default: '960',\n      },\n      sandbox: {\n        type: 'boolean',\n        default: true,\n      },\n    },\n  }\n)\n\nconst [url] = cli.input\n\nif (!url) {\n  cli.showHelp(0)\n}\n\nconst opts = Object.assign({}, cli.flags, {\n  url,\n})\n\nrequire('./index')(opts)\n  .then(filename => {\n    console.log(`saved PDF to`, filename)\n    process.exit(0)\n  })\n  .catch(err => {\n    console.log(err)\n    process.exit(1)\n  })\n"
  },
  {
    "path": "packages/website-pdf/index.js",
    "content": "const path = require('path')\nconst puppeteer = require('puppeteer')\nconst mkdirp = require('mkdirp')\n\nmodule.exports = async ({ url, outFile, width, height, sandbox }) => {\n  if (!url) {\n    throw new Error('URL is required for website-pdf')\n  }\n\n  const args = []\n  if (!sandbox) {\n    args.push('--no-sandbox', '--disable-setuid-sandbox')\n  }\n\n  const browser = await puppeteer.launch({ args })\n  const page = await browser.newPage()\n  const filename = path.resolve(outFile)\n  const outDir = path.dirname(filename)\n  mkdirp.sync(outDir)\n\n  await page.goto(url, {\n    waitUntil: 'networkidle2',\n  })\n\n  await page.pdf({\n    width,\n    height,\n    path: filename,\n    scale: 1,\n    printBackground: true,\n  })\n\n  await browser.close()\n\n  return filename\n}\n"
  },
  {
    "path": "packages/website-pdf/package.json",
    "content": "{\n  \"name\": \"website-pdf\",\n  \"version\": \"4.1.0\",\n  \"author\": \"Brent Jackson <jxnblk@gmail.com>\",\n  \"license\": \"MIT\",\n  \"bin\": {\n    \"website-pdf\": \"./cli.js\"\n  },\n  \"scripts\": {\n    \"test\": \"./cli.js http://localhost:8000/print -o ../../docs/dist\"\n  },\n  \"dependencies\": {\n    \"meow\": \"^6.0.0\",\n    \"mkdirp\": \"^1.0.3\",\n    \"puppeteer\": \"^2.0.0\"\n  },\n  \"gitHead\": \"13d00b47780424cc3b52d38ad6f19e99d007c06a\"\n}\n"
  },
  {
    "path": "templates/basic/.gitignore",
    "content": "dist\nnode_modules\n"
  },
  {
    "path": "templates/basic/README.md",
    "content": "# mdx-deck basic template\n\nThis was generated with [mdx-deck][]'s `npm init deck` command.\n\n## Development\n\nTo run the presentation deck in development mode:\n\n```sh\nnpm start\n```\n\nEdit the [`deck.mdx`](deck.mdx) file to get started.\n\n## Exporting\n\nTo build the presentation deck as static HTML:\n\n```sh\nnpm run build\n```\n\nFor more documentation see the [mdx-deck][] repo.\n\n[mdx-deck]: https://github.com/jxnblk/mdx-deck\n"
  },
  {
    "path": "templates/basic/deck.mdx",
    "content": "import { Head, Notes } from 'mdx-deck'\nimport { theme } from './theme'\n\nexport const themes = [ theme ]\n\n<Head>\n  <title>Presentation Title</title>\n</Head>\n\n# Hello\n\n---\n\n## Edit this file\n\nTo create your presentation\n\n<Notes>\nCreate speaker notes with the Notes component\n</Notes>\n\n---\n\n<https://github.com/jxnblk/mdx-deck>\n"
  },
  {
    "path": "templates/basic/package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"@mdx-deck/basic-template\",\n  \"version\": \"4.1.1\",\n  \"scripts\": {\n    \"start\": \"mdx-deck deck.mdx\",\n    \"build\": \"mdx-deck build deck.mdx\",\n    \"help\": \"mdx-deck\"\n  },\n  \"devDependencies\": {\n    \"mdx-deck\": \"^4.1.1\"\n  }\n}\n"
  },
  {
    "path": "templates/basic/theme.js",
    "content": "export const theme = {\n  // Customize your presentation theme here.\n  //\n  // Read the docs for more info:\n  // https://github.com/jxnblk/mdx-deck/blob/master/docs/theming.md\n  // https://github.com/jxnblk/mdx-deck/blob/master/docs/themes.md\n}\n"
  }
]