[
  {
    "path": ".gitignore",
    "content": ".rvmrc\n_site\n\n*.swp\n*.swo\n\n.DS_Store\n\n# IntelliJ IDEA / WebStorm\n/.idea/\n/*.iml"
  },
  {
    "path": ".ruby-gemset",
    "content": "coffeescript-cookbook\n"
  },
  {
    "path": ".ruby-version",
    "content": "1.9.3\n"
  },
  {
    "path": "Gemfile",
    "content": "source 'https://rubygems.org'\n\ngroup :development do\n  gem \"github-pages\"\n  gem \"tzinfo-data\"\n\n  gem \"foreman\"\n  gem \"serve\"\nend\n"
  },
  {
    "path": "LICENSE-CC-BY.textile",
    "content": "---\nlayout: default\ntitle: \"Creative Commons License: Attribution 3.0 Unported (CC BY 3.0)\"\n---\n\nLicense\n\nTHE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE (\"CCPL\" OR \"LICENSE\"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.\n\nBY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.\n\n1. Definitions\n\n\"Adaptation\" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image (\"synching\") will be considered an Adaptation for the purpose of this License.\n\"Collection\" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.\n\"Distribute\" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.\n\"Licensor\" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.\n\"Original Author\" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.\n\"Work\" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.\n\"You\" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.\n\"Publicly Perform\" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.\n\"Reproduce\" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.\n\n2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.\n\n3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:\n\nto Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;\nto create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked \"The original work was translated from English to Spanish,\" or a modification could indicate \"The original work has been modified.\";\nto Distribute and Publicly Perform the Work including as incorporated in Collections; and,\nto Distribute and Publicly Perform Adaptations.\nFor the avoidance of doubt:\n\nNon-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;\nWaivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,\nVoluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.\nThe above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.\n\n4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:\n\nYou may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.\nIf You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution (\"Attribution Parties\") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., \"French translation of the Work by Original Author,\" or \"Screenplay based on original Work by Original Author\"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.\nExcept as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.\n\n5. Representations, Warranties and Disclaimer\n\nUNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.\n\n6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n7. Termination\n\nThis License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.\nSubject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.\n\n8. Miscellaneous\n\nEach time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.\nEach time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.\nIf any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.\nNo term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.\nThis License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.\nThe rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.\n"
  },
  {
    "path": "Procfile",
    "content": "jekyll: bundle exec jekyll build --watch\nserve: bundle exec serve 4000 development _site\n"
  },
  {
    "path": "README.md",
    "content": "CoffeeScript Cookbook\n=============\n\nCoffeeScript Cookbook is a community run website for the CoffeeScript language.\nWe want you to write recipes and make the site better!\n\nContributing\n-----------\n\nYou can find details about contributing [on the site](http://coffeescript-cookbook.github.io/contributing). For now here is a simple formula:\n\n1. Fork the repository at [GitHub](http://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com)\n2. Do awesomeness!\n3. Send a pull request to [coffeescript-cookbook](http://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com)\n4. If we merge your pull request, you get commit access. BAM. Go back to step 2 and stay there as long as you want.\n\nHere are some relevant links from the site.\n\n* [Contributing](http://coffeescript-cookbook.github.io/contributing)\n* [Recipe Template](http://coffeescript-cookbook.github.io/recipe-template)\n* [Author's Guide](http://coffeescript-cookbook.github.io/authors-guide)\n* [Developer's Guide](http://coffeescript-cookbook.github.io/developers-guide)\n* [Designer's Guide](http://coffeescript-cookbook.github.io/designers-guide)\n\nJekyll\n------\n\nCoffeeScript Cookbook is currently implemented as a jekyll site. Jekyll is awesome.\n\n* [Site](http://jekyllrb.com/)\n* [Code](https://github.com/mojombo/jekyll)\n* [Wiki](https://github.com/mojombo/jekyll/wiki)\n\nLicense\n-------\n\nThis site and all contributions are [licensed](http://coffeescript-cookbook.github.io/LICENSE-CC-BY) under the Creative Commons Attribution 3.0 Unported (CC BY 3.0) license. By submitting information to this site you agree to grant this license to all users of the site, and that your editing of the authors page constitutes satisfactory attribution."
  },
  {
    "path": "_config.yml",
    "content": "baseurl: ''\nsafe: true\nhighlighter: pygments\nlsi: false\nmarkdown: redcarpet\nexclude:\n  - README.md\n  - CNAME\n  - TODO.md\n  - script\n  - Procfile\n  - Gemfile\n  - Gemfile.lock\n"
  },
  {
    "path": "_data/chapters.yml",
    "content": "---\n- Syntax\n- Classes and Objects\n- Strings\n- Arrays\n- Dates and Times\n- Math\n- Functions\n- Metaprogramming\n- jQuery\n- Ajax\n- Regular Expressions\n- Networking\n- Design Patterns\n- Databases\n- Testing\n"
  },
  {
    "path": "_layouts/chapter.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <title>CoffeeScript Cookbook &raquo; {{ page.title }}</title>\n    <link type=\"image/x-icon\" rel=\"shortcut icon\" href=\"{{ site.baseurl }}/images/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"{{ site.baseurl }}/css/style.css\" type=\"text/css\">\n  </head>\n  <body>\n\n    <section class=\"container\">\n\n      <header class=\"header\">\n        <h1><a class=\"\" href=\"{{ site.baseurl }}/\"><span class=\"entypo\">&oacute;</span><span class=\"title ir\">CoffeeScript Cookbook</span></a></h1>\n      </header>\n\n      <section class=\"content\">\n\n        <article class=\"content-block\">\n          <h2>{{ page.title }}</h2>\n          {{ content }}\n        </article>\n\n        <footer class=\"footer content-block\">\n          <p>Don't see the recipe you want? Add it yourself by reading the <a href=\"{{ site.baseurl }}/contributing\">Contributor's Guide</a>, or request it by adding it to <a href=\"{{ site.baseurl }}/wanted-recipes\">Wanted Recipes</a>.</p>\n          <a href=\"{{ site.baseurl }}/license\"><img src=\"{{ site.baseurl }}/images/cc_by_badge.png\" /></a>\n        </footer>\n\n      </section>\n\n    </section>\n\n    <aside id=\"sidebar\">\n\n      <section class=\"sidebar-block block-short\">\n        <nav class=\"navigation pages-nav home-nav\">\n          <h6><a class=\"nav-link\" href=\"{{ site.baseurl }}/\"><span class=\"entypo\">&oacute;</span>CoffeeScript Cookbook</a></h6>\n          <small class=\"thin dimmed\">(last updated {{ site.time | date: \"%d %B, %Y\" }})</small>\n        </nav>\n      </section>\n\n      <section class=\"sidebar-block\">\n        <nav class=\"navigation pages-nav\">\n          <ul class=\"plain-list inline-list\">\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/contributing\"><span class=\"entypo\">6</span>Contribute</a></li>\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/authors\"><span class=\"entypo\">,</span>Authors</a></li>\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/license\"><span class=\"entypo\">&copy;</span>License</a></li>\n          </ul>\n        </nav>\n      </section>\n\n      <section class=\"sidebar-block\">\n        <h5 class=\"sidebar-title\">Chapters Index</h5>\n        <ol class=\"navigation chapters-list\">\n          {% for chapter in site.data.chapters %}\n            {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n            {% capture indexurl %}{{ url }}/index.html{% endcapture %}\n            <li class=\"chapter\">\n              <div class=\"sidebar-subtitle{% if page.url == indexurl %} page-active{% endif %}\"><strong><a class=\"chapter-title\" href=\"{{ site.baseurl }}{{ url }}\">{{ chapter }}</a></strong></div>\n              <ul class=\"pseudo-list recipes-list\">\n                {% for site_page in site.pages %}\n                  {% if site_page.url contains url %}\n                    {% unless site_page.url == indexurl %}\n                      <li class=\"list-item recipe{% if page.url == site_page.url %} page-active{% endif %}\"><a class=\"recipe-title\" href=\"{{ site.baseurl }}{{ site_page.url | replace: '.html', '' }}\">{{ site_page.title }}</a></li>\n                    {% endunless %}\n                  {% endif %}\n                {% endfor %}\n              </ul>\n            </li>\n          {% endfor %}\n        </ol>\n      </section>\n\n    </aside>\n\n    <script type=\"text/javascript\" src=\"{{ site.baseurl }}/js/scripts.js\"></script>\n\n </body>\n</html>\n"
  },
  {
    "path": "_layouts/default.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <title>CoffeeScript Cookbook &raquo; {{ page.title }}</title>\n    <link type=\"image/x-icon\" rel=\"shortcut icon\" href=\"{{ site.baseurl }}/images/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"{{ site.baseurl }}/css/style.css\" type=\"text/css\">\n  </head>\n  <body>\n\n    <section class=\"container\">\n\n      <header class=\"header\">\n        <h1><a class=\"\" href=\"{{ site.baseurl }}/\"><span class=\"entypo\">&oacute;</span><span class=\"title ir\">CoffeeScript Cookbook</span></a></h1>\n      </header>\n\n      <section class=\"content\">\n\n        <article class=\"content-block\">{{ content }}</article>\n\n        <footer class=\"footer content-block\">\n          <p>Don't see a recipe you want? See an entire missing chapter? Add it yourself by reading the <a href=\"{{ site.baseurl }}/contributing\">Contributor's Guide</a>, or request it by adding it to <a href=\"{{ site.baseurl }}/wanted-recipes\">Wanted Recipes</a>.</p>\n          <a href=\"{{ site.baseurl }}/license\"><img src=\"{{ site.baseurl }}/images/cc_by_badge.png\" /></a>\n        </footer>\n\n      </section>\n\n    </section>\n\n    <aside id=\"sidebar\">\n\n      <section class=\"sidebar-block block-short\">\n        <nav class=\"navigation pages-nav home-nav\">\n          <h6><a class=\"nav-link\" href=\"{{ site.baseurl }}/\"><span class=\"entypo\">&oacute;</span>CoffeeScript Cookbook</a></h6>\n          <small class=\"thin dimmed\">(last updated {{ site.time | date: \"%d %B, %Y\" }})</small>\n        </nav>\n      </section>\n\n      <section class=\"sidebar-block\">\n        <nav class=\"navigation pages-nav\">\n          <ul class=\"plain-list inline-list\">\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/contributing\"><span class=\"entypo\">6</span>Contribute</a></li>\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/authors\"><span class=\"entypo\">,</span>Authors</a></li>\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/license\"><span class=\"entypo\">&copy;</span>License</a></li>\n          </ul>\n        </nav>\n      </section>\n\n      <section class=\"sidebar-block\">\n        <h5 class=\"sidebar-title\">Chapters Index</h5>\n        <ol class=\"navigation chapters-list\">\n          {% for chapter in site.data.chapters %}\n            {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n            {% capture indexurl %}{{ url }}/index.html{% endcapture %}\n            <li class=\"chapter\">\n              <div class=\"sidebar-subtitle{% if page.url == indexurl %} page-active{% endif %}\"><strong><a class=\"chapter-title\" href=\"{{ site.baseurl }}{{ url }}\">{{ chapter }}</a></strong></div>\n              <ul class=\"pseudo-list recipes-list\">\n                {% for site_page in site.pages %}\n                  {% if site_page.url contains url %}\n                    {% unless site_page.url == indexurl %}\n                      <li class=\"list-item recipe{% if page.url == site_page.url %} page-active{% endif %}\"><a class=\"recipe-title\" href=\"{{ site.baseurl }}{{ site_page.url | replace: '.html', '' }}\">{{ site_page.title }}</a></li>\n                    {% endunless %}\n                  {% endif %}\n                {% endfor %}\n              </ul>\n            </li>\n          {% endfor %}\n        </ol>\n      </section>\n\n    </aside>\n\n    <script type=\"text/javascript\" src=\"{{ site.baseurl }}/js/scripts.js\"></script>\n\n </body>\n</html>\n"
  },
  {
    "path": "_layouts/recipe.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <title>CoffeeScript Cookbook &raquo; {{ page.title }}</title>\n    <link type=\"image/x-icon\" rel=\"shortcut icon\" href=\"{{ site.baseurl }}/images/favicon.ico\">\n    <link rel=\"stylesheet\" href=\"{{ site.baseurl }}/css/style.css\" type=\"text/css\">\n  </head>\n  <body>\n\n    <section class=\"container\">\n\n      <header class=\"header\">\n        <h1><a class=\"\" href=\"{{ site.baseurl }}/\"><span class=\"entypo\">&oacute;</span><span class=\"title ir\">CoffeeScript Cookbook</span></a></h1>\n      </header>\n\n      <section class=\"content\">\n\n        <article class=\"content-block recipe-content\">\n          <h1>{{ page.title }}</h1>\n          {{ content }}\n        </article>\n\n        <footer class=\"footer\">\n          <p>Is this recipe wrong, incomplete, or non idiomatic? Help fix it by reading the <a href=\"{{ site.baseurl }}/contributing\">Contributor's Guide</a>!</p>\n          <a href=\"{{ site.baseurl }}/license\"><img src=\"{{ site.baseurl }}/images/cc_by_badge.png\" /></a>\n        </footer>\n      </section>\n\n    </section>\n\n    <aside id=\"sidebar\">\n\n      <section class=\"sidebar-block block-short\">\n        <nav class=\"navigation pages-nav home-nav\">\n          <h6><a class=\"nav-link\" href=\"{{ site.baseurl }}/\"><span class=\"entypo\">&oacute;</span>CoffeeScript Cookbook</a></h6>\n          <small class=\"thin dimmed\">(last updated {{ site.time | date: \"%d %B, %Y\" }})</small>\n        </nav>\n      </section>\n\n      <section class=\"sidebar-block\">\n        <nav class=\"navigation pages-nav\">\n          <ul class=\"plain-list inline-list\">\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/contributing\"><span class=\"entypo\">6</span>Contribute</a></li>\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/authors\"><span class=\"entypo\">,</span>Authors</a></li>\n            <li><a class=\"nav-link\" href=\"{{ site.baseurl }}/license\"><span class=\"entypo\">&copy;</span>License</a></li>\n          </ul>\n        </nav>\n      </section>\n\n      <section class=\"sidebar-block\">\n        <h5 class=\"sidebar-title\">Chapters Index</h5>\n        <ol class=\"navigation chapters-list\">\n          {% for chapter in site.data.chapters %}\n            {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n            {% capture indexurl %}{{ url }}/index.html{% endcapture %}\n            <li class=\"chapter\">\n              <div class=\"sidebar-subtitle{% if page.url == indexurl %} page-active{% endif %}\"><strong><a class=\"chapter-title\" href=\"{{ site.baseurl }}{{ url }}\">{{ chapter }}</a></strong></div>\n              <ul class=\"pseudo-list recipes-list\">\n                {% for site_page in site.pages %}\n                  {% if site_page.url contains url %}\n                    {% unless site_page.url == indexurl %}\n                      <li class=\"list-item recipe{% if page.url == site_page.url %} page-active{% endif %}\"><a class=\"recipe-title\" href=\"{{ site.baseurl }}{{ site_page.url | replace: '.html', '' }}\">{{ site_page.title }}</a></li>\n                    {% endunless %}\n                  {% endif %}\n                {% endfor %}\n              </ul>\n            </li>\n          {% endfor %}\n        </ol>\n      </section>\n\n    </aside>\n\n    <script type=\"text/javascript\" src=\"{{ site.baseurl }}/js/scripts.js\"></script>\n\n </body>\n</html>\n"
  },
  {
    "path": "authors-guide.md",
    "content": "---\nlayout: default\ntitle: Author's Guide\n---\n# Author's Guide\n\n## tl;dr: Look at Other Recipes, and Blend In\n\nLook at the source of other recipe pages and follow that page structure. Start with the [Developer's Guide]({{ site.baseurl }}/developers-guide) to get a test version of the cookbook up and running on your machine, and get to work!\n\n## General Guidelines\n\n* Feel free to add new pages, or even chapters. Just keep them organized. _(See \"How to Add a Chapter\" below)_\n* Try to write well-styled, idiomatic CoffeeScript.\n* Try to stay within the Problem/Solution/Discussion format. If you can't think of a good problem for your recipe... hang onto it for a while.\n* Sharing code that you think might only be used rarely is fine. Sharing esoteric code tricks is less so. There's a difference between sharing a translator for an obscure format and sharing a weird bit-shifting trick that does fast but inaccurate multiplication.\n* Don't forget to add your name to the authors page!\n\n## Use Cookbook Problem/Solution/Discussion Format\n\nA typical cookbook page will have three sections (four if you count the title):\n\n* **Problem** A one- or two-sentence description of the problem, such as \"You want to access parts of a string\" or \"You want to format a floating point number as currency, with a leading dollar sign, two digits of precision and comma-separated triples.\" Where possible, phrase the problem as though speaking directly to the reader: \"You want to...\", \"You have an X but you want a Y\", etc.\n* **Solution** State the solution as briefly as possible, ideally as a single sentence that identifies the strategy you would use, and give example code. It's tempting to explain the solution, but don't do it yet. Remember that the reader will look this solution up many times after the first time, and that they will be looking for a quick reference each time. You're going to explain the solution in the **Discussion**, and the first time reader will read your solution, think about it, and then proceed to the discussion if necessary. For example, for \"accessing parts of a string\", a good Solution sentence might be \"Use CoffeeScript's array range subscripts, or JavaScript's slice function.\"\n* **Discussion** Here you should explain why your solution works, or give further examples such as edge cases. If your solution can break on some edge cases, be sure to note them here. For example, if a percentage function crashes when given a zero, you could note this in the discussion and give a workaround. NOTE: If your solution has really dangerous edge cases, so dangerous that you would include them in the solution, please consider whether your recipe should be included at all. Remember, this Cookbook is for good code!\n\n## Copyright Issues\n\nDo not post code that is copyrighted by another user, unless you have permission to use that code AND to relicense that code under the [CC BY 3.0]({{ site.baseurl }}/license) license. If you DO have permission and the author would like credit, please add them to the [authors]({{ site.baseurl }}/authors) page.\n\nAlso, just a stylistic note, please do not yank code directly from [http://coffeescript.org/](http://coffeescript.org/) and post it with little or no discussion. The CoffeeScript Cookbook is not affiliated with them. We think they're awesome and want them to like us, too! Make sure that anything taken from [http://coffeescript.org/](http://coffeescript.org/) is permissible use and that it stands alone as a valid recipe. If the recipe is too terse, consider adding more examples and discussion.\n\n## Tag the page with Jekyll frontmatter\n\n...that's a lot of fancy words that mean \"don't forget to put the layout, chapter and page title at the top of the file in a YAML block\". For example, the string interpolation page begins with\n\n{% highlight text %}\n---\nlayout: recipe\ntitle: String Interpolation\nchapter: Strings\n---\n{% endhighlight %}\n\n## Use Liquid highlighting templates\n\nTurn on syntax highlighting for CoffeeScript with `highlight coffeescript`.\n\ntest2\n\n&lbrace;% highlight coffeescript %&rbrace;\n&#35; Calculate the square of a number\nsquare = (x) -> x * x\n\nsquare(16)\n&#35; => 256\n&lbrace;% endhighlight %&rbrace;\n\nThis produces the following:\n\n{% highlight coffeescript %}\n# Calculate the square of a number\nsquare = (x) -> x * x\n\nsquare(16)\n# => 256\n{% endhighlight %}\n\n## Include Output\n\nAfter writing an important expression, show the reader what the output would be by adding it with a `# =>` on the following line. Once we get automated script testing working up in this joint, we'll actually load up your recipe snippets and evaluate its expressions against the output comment you wrote. (In other words, `# =>` tells the reader what the output will be, but it tells automated checker what the assertEquals should be)\n\n{% highlight coffeescript %}\n# right\n[1,2,3].map (x) -> x * 2\n# => [ 2, 4, 6 ]\n\n# very wrong!\n[1,2,3].map (x) -> x * 2\n\n# right; only add for important/results statements\nevens = x for x in [0..10] by 2\nevens.some (x) -> x == 6\n# => true\n\n# less wrong; may require tweaking the automatic checker\n[1,2,3].map (x) -> x * 2 # => [ 2, 4, 6 ]\n\n# less wrong (possibly not wrong at all--the output merely does not match what the coffee interpreter renders)\n[1,2,3].map (x) -> x * 2\n# => [2,4,6]\n{% endhighlight %}\n\nNot all snippets evaluate to something useful. For example, array.forEach has side effects but does not return anything. Also, the console.log() and alert() commands are also side-effect-only commands that return nothing. When possible, try to have your snippets evaluate to something inspectable, and leave displaying to the console or browser out of it. (Unless your snippet is _about_ displaying to the console or browser.)\n\nWhen in doubt about what output to show, try evaluating your snippet in the coffee interpreter and see what IT thinks. Ideally your output should match, or at least be machine-comparable.\n\n# Grindy HOWTOs\n\n## How to Add a Recipe\n\nCreate a new markdown page (or copy the [Recipe Template]({{ site.baseurl }}/recipe-template). The filename should be about the problem, e.g. `finding-last-day-of-the-month.md` or `reversing-arrays.md`. In your file, start with the following template:\n\n{% highlight text %}\n---\nlayout: recipe\ntitle: Title of The Recipe\nchapter: Chapter Name\n---\n\n## Problem\n\nYou have a problem.\n\n## Solution\n\nDo this about it.\n\n## Discussion\n\nHere's why.\n{% endhighlight %}\n\nOne fussy little bit, the chapter name should match the directory the chapter is in, otherwise the page won't render correctly. For example, if you're writing a recipe for arrays, make sure the chapter is \"Arrays\", not \"arrays\" or \"aray\" ...or especially not \"Chapter Name\".\n\n## How to Add a Chapter\n\n* Open chapters/index.html and your chapter's name to the yaml list of chapters.\n* cd into chapters/ and create the directory for the chapter name. Downcase the name and replace spaces with underscores.\n* add an index.html file that uses `layout: chapter`. For convenience, just copy the index.html from another chapter and update the yaml frontmatter to reflect the name of your new chapter.\n\nFor example, to add a chapter called \"Dates and Times\", you would add it to the chapters array:\n\n{% highlight yaml %}\nchapters:\n- Syntax\n- Objects\n- Arrays\n- Dates and Times\n{% endhighlight %}\n\n...and then create that chapter in the file system:\n\n{% highlight bash %}\ncd chapters\nmkdir dates_and_times\n{% endhighlight %}\n\nNow create a new page in that chapter (remember to add its YAML front matter) and once jekyll regenerates the chapter index, your new page should appear.\n\n# FAQ\n\n## I Have a Weird Recipe. Should I Share It?\n\nMaybe! The real question is, is it really useful, or is it just clever? If you have a formatter for a weird Albanian GIS format, that's a real problem that almost nobody would ever have -- but when somebody DOES have that problem, they REALLY need a solution. If you have a bit shifting trick that can swap two numbers using three xor-equals operations, that's a really clever solution but it's not very good CoffeeScript. (For one thing, `x ^= y ^= x ^= y` is not idiomatic, while `[x,y]=[y,x]` is. For another, there's a bug in that code. And once you fix it, there's another bug caused by extrapolating this register trick to a reference-based language where -- look, it's just a bad idea, okay?)\n\nIf you have a cool but weird recipe, ask yourself if a reader would genuinely find it useful. Here are two very good questions to consider:\n\n* Does it really solve a problem that an actual person might have?\n* If somebody really does have that problem, would your recipe really be the best solution?\n\nIf the answer to either question is no, you might have some code that is a \"clever solution in search of a problem\". If in doubt, ask.\n\n## What If My Recipe is Inefficient/Too Big/Too Slow?\n\nIf it solves a problem to which the alternative is to _not_ solve the problem, share it. Let the reader decide if they want to use it. Sometimes we want tight efficient code, other times we want a robust feature set. If the code has abysmal performance characteristics, be sure to warn the reader in the Discussion.\n\n## Can I Edit An Existing Recipe?\n\nYes. Please improve anything and everything! Be sure to test your changes and make sure that your solution really is better.\n\n## I Have a Really Efficient Solution, But It's Not As Readable As the Existing Recipe. Should I Add It?\n\nSee the \"Weird Recipe\" note above. Do real people in the real world ever hit the performance constraint? If so, then by all means, add your strategy to the existing solution, and be sure to explain why your solution is not idiomatic. If a reader really has that problem, they'll be glad for the extra options.\n\n## I Have A Problem/Solution, But It's Basically Just JavaScript. Should I Add It?\n\nYes! CoffeeScript compiles to JavaScript, and that means that some of its functionality comes straight from JavaScript. (For example, see [Reversing Arrays]({{ site.baseurl }}/chapters/arrays/reversing-arrays).) But if you're programming in CoffeeScript and you need to reverse an array, this Cookbook should stand ready to tell you it's available to you in CoffeeScript -- even if it's just a straight call into a JavaScript library.\n\n## I Found a Typo. Is That Enough of a Fix? Does That Count?\n\nAbsolutely!\n"
  },
  {
    "path": "authors.md",
    "content": "---\nlayout: default\ntitle: Authors\n---\n\n# Authors\n\nThe following people are totally rad and awesome because they have contributed recipes!\n\n* David Brady *ratgeyser@gmail.com*\n* John Ford *jwford@gmail.com*\n* Steven Reid *steven @ reidnorthwest . com*\n* David Moulton *dave@themoultons.net*\n* Sebastian Slomski *sebastian@simple-systems.org*\n* Aaron Weinberger *aw9994@cs.ship.edu*\n* James C. Holder *coffeescriptcookbook.com@thirdtruck.org*\n* Jason Giedymin *jasong@apache.org*\n* Phil Cohen *github@phlippers.net*\n* João Moreno *coffeecb @joaomoreno .com*\n* Jeff Pickhardt *pickhardt (at) gmail (dot) com*\n* Frederic Hemberger\n* Mike Hatfield *oakraven13@gmail.com*\n* [Anton Rissanen](http://github.com/antris) *hello@anton.fi*\n* Calum Robertson *http://github.com/randusr836*\n* Jake Burkhead *https://github.com/jlburkhead*\n* [Alex Johnson](https://github.com/nonsensery)\n* ...You! What are you waiting for? Check out the [contributing]({{ site.baseurl }}/contributing) section and get cracking!\n\n# Developers\n\n*The following people are amazingly rad and awesome because they have helped fix the code for the site!*\n\n* David Brady *ratgeyser@gmail.com*\n* Mike Moore *mike@blowmage.com*\n* Peter Hellberg *peter@c7.se*\n* Jamie Gaskins *jgaskins@gmail.com*\n* Sami Pussinen *me@samipussinen.com*\n* [Devin Weaver (@sukima)](https://github.com/sukima)\n* ...You! What are you waiting for? Check out the [contributing]({{ site.baseurl }}/contributing) section and get cracking!\n\n# Designers\n\nThe following people are astonishingly rad and awesome because they did great design for the site!\n\n* [Amsul](http://github.com/amsul) reach@amsul.ca\n* ...You! Check out the [contributing]({{ site.baseurl }}/contributing) section and get cracking!\n"
  },
  {
    "path": "chapters/ajax/ajax_request_without_jquery.md",
    "content": "---\nlayout: recipe\ntitle: Ajax Request Without jQuery\nchapter: Ajax\n---\n## Problem\n\nYou want to load data from your server via AJAX without using the jQuery library.\n\n## Solution\n\nYou will use the native <a href=\"http://en.wikipedia.org/wiki/XMLHttpRequest\" target=\"_blank\">XMLHttpRequest</a> object.\n\nLet's set up a simple test HTML page with a button.\n\n{% highlight html %}\n<!DOCTYPE HTML>\n<html lang=\"en-US\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>XMLHttpRequest Tester</title>\n</head>\n<body>\n\t<h1>XMLHttpRequest Tester</h1>\n\t<button id=\"loadDataButton\">Load Data</button>\n\n\t<script type=\"text/javascript\" src=\"XMLHttpRequest.js\"></script>\n</body>\n</html>\n{% endhighlight %}\n\nWhen the button is clicked, we want to send an Ajax request to the server to retrieve some data.  For this sample, we have a small JSON file.\n\n{% highlight javascript %}\n// data.json\n{\n  message: \"Hello World\"\n}\n{% endhighlight %}\n\nNext, create the CoffeeScript file to hold the page logic.  The code in this file creates a function to be called when the Load Data button is clicked.\n\n{% highlight coffeescript linenos %}\n# XMLHttpRequest.coffee\nloadDataFromServer = ->\n  req = new XMLHttpRequest()\n\n  req.addEventListener 'readystatechange', ->\n    if req.readyState is 4                        # ReadyState Complete\n      successResultCodes = [200, 304]\n      if req.status in successResultCodes\n        data = eval '(' + req.responseText + ')'\n        console.log 'data message: ', data.message\n      else\n        console.log 'Error loading data...'\n\n  req.open 'GET', 'data.json', false\n  req.send()\n\nloadDataButton = document.getElementById 'loadDataButton'\nloadDataButton.addEventListener 'click', loadDataFromServer, false\n{% endhighlight %}\n\n## Discussion\n\nIn the above code we grab a handle to the button in our HTML (line 16) and add a *click* event listener (line 17).  In our event listener, we define our callback function as loadDataFromServer.\n\nWe define our loadDataFromServer callback beginning on line 2.\n\nWe create a XMLHttpRequest request object (line 3) and add a *readystatechange* event handler.  This fires whenever the request's readyState changes.\n\nIn the event handler we check to see if the readyState = 4, indicating the request has completed.  Then, we check the request status value.  Both 200 or 304 represent a successful request.  Anything else represents an error condition.\n\nIf the request was indeed successful, we eval the JSON returned from the server and assign it to a data variable.  At this point, we can use the returned data in any way we need to.\n\nThe last thing we need to do is actually make our request.\n\nLine 13 opens a 'GET' request to retrieve the data.json file.\n\nLine 14 sends our request to the server.\n\n## Older Browser Support\n\nIf your application needs to target older versions of Internet Explorer, you will need to ensure the XMLHttpRequest object exists.  You can do this by including this code before creating the XMLHttpRequest instance.\n\n{% highlight coffeescript %}\nif (typeof @XMLHttpRequest == \"undefined\")\n  console.log 'XMLHttpRequest is undefined'\n  @XMLHttpRequest = ->\n    try\n      return new ActiveXObject(\"Msxml2.XMLHTTP.6.0\")\n    catch error\n    try\n      return new ActiveXObject(\"Msxml2.XMLHTTP.3.0\")\n    catch error\n    try\n      return new ActiveXObject(\"Microsoft.XMLHTTP\")\n    catch error\n    throw new Error(\"This browser does not support XMLHttpRequest.\")\n{% endhighlight %}\n\nThis code ensures the XMLHttpRequest object is available in the global namespace.\n"
  },
  {
    "path": "chapters/ajax/index.html",
    "content": "---\nlayout: chapter\ntitle: Ajax\nchapter: Ajax\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/arrays/check-type-is-array.md",
    "content": "---\nlayout: recipe\ntitle: Check if type of value is an Array\nchapter: Arrays\n---\n## Problem\n\nYou want to check if a value is an `Array`.\n\n{% highlight coffeescript %}\nmyArray = []\nconsole.log typeof myArray // outputs 'object'\n{% endhighlight %}\n\nThe `typeof` operator gives a faulty output for arrays.\n\n## Solution\n\nUse the following code:\n\n{% highlight coffeescript %}\ntypeIsArray = Array.isArray || ( value ) -> return {}.toString.call( value ) is '[object Array]'\n{% endhighlight %}\n\nTo use this, just call `typeIsArray` as such:\n\n{% highlight coffeescript %}\nmyArray = []\ntypeIsArray myArray // outputs true\n{% endhighlight %}\n\n## Discussion\n\nThe method above has been adopted from \"the Miller Device\". An alternative is to use Douglas Crockford's snippet:\n\n{% highlight coffeescript %}\ntypeIsArray = ( value ) ->\n    value and\n        typeof value is 'object' and\n        value instanceof Array and\n        typeof value.length is 'number' and\n        typeof value.splice is 'function' and\n        not ( value.propertyIsEnumerable 'length' )\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/arrays/concatenating-arrays.md",
    "content": "---\nlayout: recipe\ntitle: Concatenating Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to join two arrays together.\n\n## Solution\n\nThere are two standard options for concatenating arrays in JavaScript.\n\nThe first is to use JavaScript's Array `concat()` method:\n\n{% highlight coffeescript %}\narray1 = [1, 2, 3]\narray2 = [4, 5, 6]\narray3 = array1.concat array2\n# => [1, 2, 3, 4, 5, 6]\n{% endhighlight %}\n\nNote that `array1` is _not_ modified by the operation. The concatenated array is returned as a new object.\n\nIf you want to merge two arrays without creating a new object, you can use the following technique:\n\n{% highlight coffeescript %}\narray1 = [1, 2, 3]\narray2 = [4, 5, 6]\nArray::push.apply array1, array2\narray1\n# => [1, 2, 3, 4, 5, 6]\n{% endhighlight %}\n\nIn the example above, the `Array.prototype.push.apply(a, b)` approach modifies `array1` in place without creating a new array object.\n\nWe can simplify the pattern above using CoffeeScript by creating a new `merge()` method for Arrays.\n\n{% highlight coffeescript %}\nArray::merge = (other) -> Array::push.apply @, other\n\narray1 = [1, 2, 3]\narray2 = [4, 5, 6]\narray1.merge array2\narray1\n# => [1, 2, 3, 4, 5, 6]\n{% endhighlight %}\n\nAlternatively, we can pass a CoffeeScript splat (`array2...`) directly into `push()`, avoiding the Array prototype.\n\n{% highlight coffeescript %}\narray1 = [1, 2, 3]\narray2 = [4, 5, 6]\narray1.push array2...\narray1\n# => [1, 2, 3, 4, 5, 6]\n{% endhighlight %}\n\nA more idiomatic approach is to use the splat operator (`...`) directly in an array literal. This can be used to concatenate any number of arrays.\n\n{% highlight coffeescript %}\narray1 = [1, 2, 3]\narray2 = [4, 5, 6]\narray3 = [array1..., array2...]\narray3\n# => [1, 2, 3, 4, 5, 6]\n{% endhighlight %}\n\n## Discussion\n\nCoffeeScript lacks a special syntax for joining arrays, but `concat()` and `push()` are standard JavaScript methods.\n"
  },
  {
    "path": "chapters/arrays/creating-a-dictionary-object-from-an-array.md",
    "content": "---\nlayout: recipe\ntitle: Creating a dictionary Object from an Array\nchapter: Arrays\n---\n## Problem\n\nYou have an Array of Objects, such as:\n\n{% highlight coffeescript %}\ncats = [\n  {\n    name: \"Bubbles\"\n    age: 1\n  },\n  {\n    name: \"Sparkle\"\n    favoriteFood: \"tuna\"\n  }\n]\n{% endhighlight %}\n\nBut you want to access it as a dictionary by key, like `cats[\"Bubbles\"]`.\n\n## Solution\n\nYou need to convert your array into an Object. Use reduce for this.\n\n{% highlight coffeescript %}\n# key = The key by which to index the dictionary\nArray::toDict = (key) ->\n  @reduce ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {}\n{% endhighlight %}\n\nTo use this:\n\n{% highlight coffeescript %}\n  catsDict = cats.toDict('name')\n  catsDict[\"Bubbles\"]\n  # => { age: 1, name: \"Bubbles\" }\n{% endhighlight %}\n\n## Discussion\n\nAlternatively, you can use an Array comprehension:\n\n{% highlight coffeescript %}\nArray::toDict = (key) ->\n  dict = {}\n  dict[obj[key]] = obj for obj in this when obj[key]?\n  dict\n{% endhighlight %}\n\nIf you use Underscore.js, you can create a mixin:\n\n{% highlight coffeescript %}\n_.mixin toDict: (arr, key) ->\n    throw new Error('_.toDict takes an Array') unless _.isArray arr\n    _.reduce arr, ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {}\ncatsDict = _.toDict(cats, 'name')\ncatsDict[\"Sparkle\"]\n# => { favoriteFood: \"tuna\", name: \"Sparkle\" }\n{% endhighlight %}"
  },
  {
    "path": "chapters/arrays/creating-a-string-from-an-array.md",
    "content": "---\nlayout: recipe\ntitle: Creating a String from an Array\nchapter: Arrays\n---\n## Problem\n\nYou want to create a string from an array.\n\n## Solution\n\nUse JavaScript's Array toString() method:\n\n{% highlight coffeescript %}\n[\"one\", \"two\", \"three\"].toString()\n# => 'one,two,three'\n{% endhighlight %}\n\n## Discussion\n\n`toString()` is a standard JavaScript method. Don't forget the parentheses.\n"
  },
  {
    "path": "chapters/arrays/define-ranges.md",
    "content": "---\nlayout: recipe\ntitle: Define Ranges Array\nchapter: Arrays\n---\n## Problem\n\nYou want to define a range in an array.\n\n## Solution\n\nThere are two ways to define a range of array elements in CoffeeScript.\n\n{% highlight coffeescript %}\n\n# inclusive\nmyArray = [1..10]\n# => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]\n\n{% endhighlight %}\n\n{% highlight coffeescript %}\n\n# exclusive\nmyArray = [1...10]\n# => [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n\n{% endhighlight %}\n\nWe can also reverse the range of element by writing it this way.\n\n{% highlight coffeescript %}\n\nmyLargeArray = [10..1]\n# => [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]\n\n{% endhighlight %}\n\n{% highlight coffeescript %}\nmyLargeArray = [10...1]\n# => [ 10, 9, 8, 7, 6, 5, 4, 3, 2 ]\n\n{% endhighlight %}\n\n## Discussion\n\nInclusive ranges are defined by the '..' operator and include the last value.\n\nExclusive ranges are defined by '...', and always omit the last value.\n\n"
  },
  {
    "path": "chapters/arrays/filtering-arrays.md",
    "content": "---\nlayout: recipe\ntitle: Filtering Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to be able to filter arrays based on a boolean condition.\n\n## Solution\n\nUse Array.filter (ECMAScript 5):\n\n{% highlight coffeescript %}\narray = [1..10]\n\narray.filter (x) -> x > 5\n# => [6,7,8,9,10]\n{% endhighlight %}\n\nIn pre-EC5 implementations, extend the Array prototype to add a filter function which will take a callback and perform a comprehension over itself, collecting all elements for which the callback is true. Be sure to check if the function is already implemented before overwriting it:\n\n{% highlight coffeescript %}\n# Extending Array's prototype\nunless Array::filter\n  Array::filter = (callback) ->\n    element for element in this when callback(element)\n\narray = [1..10]\n\n# Filter odd elements\nfiltered_array = array.filter (x) -> x % 2 == 0\n# => [2,4,6,8,10]\n\n# Filter elements less than or equal to 5:\ngt_five = (x) -> x > 5\nfiltered_array = array.filter gt_five\n# => [6,7,8,9,10]\n{% endhighlight %}\n\n## Discussion\n\nThis is similar to using ruby's Array#select method.\n"
  },
  {
    "path": "chapters/arrays/index.html",
    "content": "---\nlayout: chapter\ntitle: Arrays\nchapter: Arrays\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/arrays/list-comprehensions.md",
    "content": "---\nlayout: recipe\ntitle: List Comprehensions\nchapter: Arrays\n---\n## Problem\n\nYou have an array of objects and want to map them to another array, similar to Python's list comprehensions.\n\n## Solution\n\nUse a list comprehension, but don't forget about [mapping arrays]({{ site.baseurl }}/chapters/arrays/mapping-arrays).\n\n{% highlight coffeescript %}\nelectric_mayhem = [ { name: \"Doctor Teeth\", instrument: \"piano\" },\n                    { name: \"Janice\", instrument: \"lead guitar\" },\n                    { name: \"Sgt. Floyd Pepper\", instrument: \"bass\" },\n                    { name: \"Zoot\", instrument: \"sax\" },\n                    { name: \"Lips\", instrument: \"trumpet\" },\n                    { name: \"Animal\", instrument: \"drums\" } ]\n\nnames = (muppet.name for muppet in electric_mayhem)\n# => [ 'Doctor Teeth', 'Janice', 'Sgt. Floyd Pepper', 'Zoot', 'Lips', 'Animal' ]\n{% endhighlight %}\n\n## Discussion\n\nBecause CoffeeScript directly support list comprehensions, they work pretty much as advertised wherever you would use one in Python. For simple mappings, list comprehensions are much more readable. For complicated transformations or for chained mappings, [mapping arrays]({{ site.baseurl }}/chapters/arrays/mapping-arrays) might be more elegant.\n"
  },
  {
    "path": "chapters/arrays/mapping-arrays.md",
    "content": "---\nlayout: recipe\ntitle: Mapping Arrays\nchapter: Arrays\n---\n## Problem\n\nYou have an array of objects and want to map them to another array, similar to Ruby's map.\n\n## Solution\n\nUse map() with an anonymous function, but don't forget about <a href=\"{{ site.baseurl }}/chapters/arrays/list-comprehensions\">list comprehensions</a>.\n\n{% highlight coffeescript %}\nelectric_mayhem = [ { name: \"Doctor Teeth\", instrument: \"piano\" },\n                    { name: \"Janice\", instrument: \"lead guitar\" },\n                    { name: \"Sgt. Floyd Pepper\", instrument: \"bass\" },\n                    { name: \"Zoot\", instrument: \"sax\" },\n                    { name: \"Lips\", instrument: \"trumpet\" },\n                    { name: \"Animal\", instrument: \"drums\" } ]\n\nnames = electric_mayhem.map (muppet) -> muppet.name\n# => [ 'Doctor Teeth', 'Janice', 'Sgt. Floyd Pepper', 'Zoot', 'Lips', 'Animal' ]\n{% endhighlight %}\n\n## Discussion\n\nBecause CoffeeScript has clean support for anonymous functions, mapping an array in CoffeeScript is nearly as easy as it is in Ruby.\n\nMaps are are good way to handle complicated transforms and chained mappings in CoffeeScript. If your transformation is as simple as the one above, however, it may read more cleanly as a <a href=\"{{ site.baseurl }}/chapters/arrays/list-comprehensions\">list comprehension</a>.\n"
  },
  {
    "path": "chapters/arrays/max-array-value.md",
    "content": "---\nlayout: recipe\ntitle: Max Array Value\nchapter: Arrays\n---\n## Problem\n\nYou need to find the largest value contained in an array.\n\n## Solution\n\nYou can use Math.max() JavaScript method along with splats.\n\n{% highlight coffeescript %}\nMath.max [12, 32, 11, 67, 1, 3]...\n# => 67\n{% endhighlight %}\n\nAlternatively, it's possible to use ES5 `reduce` method. For backward compatibility with older JavaScript implementations, use the above.\n\n{% highlight coffeescript %}\n# ECMAScript 5\n[12,32,11,67,1,3].reduce (a,b) -> Math.max a, b\n# => 67\n{% endhighlight %}\n\n## Discussion\n\n`Math.max` compares every argument and returns the largest number from arguments. The ellipsis (`...`) converts every array value into argument which is given to the function. You can also use it with other functions which take variable amount of arguments, such as `console.log`.\n"
  },
  {
    "path": "chapters/arrays/reducing-arrays.md",
    "content": "---\nlayout: recipe\ntitle: Reducing Arrays\nchapter: Arrays\n---\n## Problem\n\nYou have an array of objects and want to reduce them to a value, similar to Ruby's `reduce()` and `reduceRight()`.\n\n## Solution\n\nYou can simply use Array's `reduce()` and `reduceRight()` methods along with an anonymous function, keeping the code clean and readable. The reduction may be something simple such as using the `+` operator with numbers or strings.\n\n{% highlight coffeescript %}\n[1,2,3,4].reduce (x,y) -> x + y\n# => 10\n{% endhighlight %}\n\n{% highlight coffeescript %}\n[\"words\", \"of\", \"bunch\", \"A\"].reduceRight (x, y) -> x + \" \" + y\n# => 'A bunch of words'\n{% endhighlight %}\n\nOr it may be something more complex such as aggregating elements from a list into a combined object.\n\n{% highlight coffeescript %}\npeople = [\n    { name: 'alec', age: 10 }\n    { name: 'bert', age: 16 }\n    { name: 'chad', age: 17 }\n]\n\npeople.reduce (x, y) ->\n    x[y.name]= y.age\n    x\n, {}\n# => { alec: 10, bert: 16, chad: 17 }\n{% endhighlight %}\n\n## Discussion\n\nJavascript introduced `reduce` and `reduceRight` in version 1.8. Coffeescript provides a natural and simple way to express anonymous functions. Both go together cleanly in the problem of merging a collection's items into a combined result.\n"
  },
  {
    "path": "chapters/arrays/removing-duplicate-elements-from-arrays.md",
    "content": "---\nlayout: recipe\ntitle: Removing Duplicate Elements from Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to remove duplicate elements from an array.\n\n## Solution\n\n{% highlight coffeescript %}\nArray::unique = ->\n  output = {}\n  output[@[key]] = @[key] for key in [0...@length]\n  value for key, value of output\n\n[1,1,2,2,2,3,4,5,6,6,6,\"a\",\"a\",\"b\",\"d\",\"b\",\"c\"].unique()\n# => [ 1, 2, 3, 4, 5, 6, 'a', 'b', 'd', 'c' ]\n{% endhighlight %}\n\n## Discussion\n\nThere are many implementations of the `unique` method in JavaScript. This one is based on \"The fastest method to find unique items in array\" found [here](http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/).\n\n**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/)).\n\n\n"
  },
  {
    "path": "chapters/arrays/reversing-arrays.md",
    "content": "---\nlayout: recipe\ntitle: Reversing Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to reverse an array.\n\n## Solution\n\nUse JavaScript's Array reverse() method:\n\n{% highlight coffeescript %}\n[\"one\", \"two\", \"three\"].reverse()\n# => [\"three\", \"two\", \"one\"]\n{% endhighlight %}\n\n## Discussion\n\n`reverse()` is a standard JavaScript method. Don't forget the parentheses.\n"
  },
  {
    "path": "chapters/arrays/shuffling-array-elements.md",
    "content": "---\nlayout: recipe\ntitle: Shuffling Array Elements\nchapter: Arrays\n---\n## Problem\n\nYou want to shuffle the elements in an array.\n\n## Solution\n\nThe [Fisher-Yates shuffle] is a highly efficient and completely unbiased way to randomize\nthe elements in an array. It's a fairly simple method: Start at the end of the list, and\nswap the last element with a random element from earlier in the list. Go down one and \nrepeat, until you're at the beginning of the list, with all of the shuffled elements \nat the end of the list. This [Fisher-Yates shuffle Visualization] may help you understand\nthe algorithm.\n\n{% highlight coffeescript %}\nshuffle = (source) ->\n  # Arrays with < 2 elements do not shuffle well. Instead make it a noop.\n  return source unless source.length >= 2\n  # From the end of the list to the beginning, pick element `index`.\n  for index in [source.length-1..1]\n    # Choose random element `randomIndex` to the front of `index` to swap with.\n    randomIndex = Math.floor Math.random() * (index + 1)\n    # Swap `randomIndex` with `index`, using destructured assignment\n    [source[index], source[randomIndex]] = [source[randomIndex], source[index]]\n  source\n\nshuffle([1..9])\n# => [ 3, 1, 5, 6, 4, 8, 2, 9, 7 ]\n{% endhighlight %}\n\n[Fisher-Yates shuffle]: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\n[Fisher-Yates Shuffle Visualization]: http://bost.ocks.org/mike/shuffle/\n\n## Discussion\n\n### The Wrong Way to do it\n\nThere is a common--but terribly wrong way--to shuffle an array, by sorting by a random\nnumber.\n\n{% highlight coffeescript %}\nshuffle = (a) -> a.sort -> 0.5 - Math.random()\n{% endhighlight %}\n\nIf you do a sort randomly, it should give you a random order, right? Even [Microsoft used \nthis random-sort algorithm][msftshuffle]. Turns out, [this random-sort algorithm produces\nbiased results][naive], because it only has the illusion of shuffling. Randomly sorting\nwill not result in a neat, tidy shuffle; it will result in a wild mass of inconsistent\nsorting.\n\n[msftshuffle]: http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html\n[naive]: http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html\n\n### Optimizing for speed and space\n\nThe solution above isn't as fast, or as lean, as it can be. The list comprehension, when\ntransformed into Javascript, is far more complex than it needs to be, and the\ndestructured assignment is far slower than dealing with bare variables. The following\ncode is less idiomatic, and takes up more source-code space... but will compile down\nsmaller and run a bit faster:\n\n{% highlight coffeescript %}\nshuffle = (a) ->\n  i = a.length\n  while --i > 0\n    j = ~~(Math.random() * (i + 1)) # ~~ is a common optimization for Math.floor\n    t = a[j]\n    a[j] = a[i]\n    a[i] = t\n  a\n{% endhighlight %}\n\n### Extending Javascript to include this shuffle.\n\nThe following code adds the shuffle function to the Array prototype, which means that\nyou are able to run it on any array you wish, in a much more direct manner.\n\n{% highlight coffeescript %}\nArray::shuffle ?= ->\n  if @length > 1 then for i in [@length-1..1]\n    j = Math.floor Math.random() * (i + 1)\n    [@[i], @[j]] = [@[j], @[i]]\n  this\n\n[1..9].shuffle()\n# => [ 3, 1, 5, 6, 4, 8, 2, 9, 7 ]\n{% endhighlight %}\n\n**Note:** Although it's quite common in languages like Ruby, extending native objects is \noften considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify \nobjects you don’t own][dontown]; [Extending built-in native objects. Evil or not?]\n[extendevil]). That being said, the code above is really quite safe to add. It only adds\n`Array::shuffle` if it doesn't exist already, thanks to the existential assignment \noperator (`?=`). That way, we don't overwrite someone else's, or a native browser method.\n\nAlso, if you think you'll be using a lot of these utility functions, consider using a\nutility library, like [Lo-dash](http://lodash.com/)^†. They include a lot of nifty\nfeatures, like maps and forEach, in a cross-browser, lean, high-performance way. \n\n^† [Underscore](http://underscorejs.org/) is also a good alternative to Lo-dash.\n\n[dontown]: http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/\n[extendevil]: http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/\n"
  },
  {
    "path": "chapters/arrays/testing-every-element.md",
    "content": "---\nlayout: recipe\ntitle: Testing Every Element\nchapter: Arrays\n---\n## Problem\n\nYou want to be able to check that every element in an array meets a particular condition.\n\n## Solution\n\nUse Array.every (ECMAScript 5):\n\n{% highlight coffeescript %}\nevens = (x for x in [0..10] by 2)\n\nevens.every (x)-> x % 2 == 0\n# => true\n{% endhighlight %}\n\nArray.every was added to Mozilla's Javascript 1.6 and made standard with ECMAScript 5. If you to support browsers that do not implement EC5 then check out [`_.all` from underscore.js][underscore].\n\nFor a real world example, pretend you have a multiple select list that looks like:\n\n{% highlight html %}\n<select multiple id=\"my-select-list\">\n  <option>1</option>\n  <option>2</option>\n  <option>Red Car</option>\n  <option>Blue Car</option>\n</select>\n{% endhighlight %}\n\nNow you want to verify that the user selected only numbers. Let's use Array.every:\n\n{% highlight coffeescript %}\nvalidateNumeric = (item)->\n  parseFloat(item) == parseInt(item) && !isNaN(item)\n\nvalues = $(\"#my-select-list\").val()\n\nvalues.every validateNumeric\n{% endhighlight %}\n\n## Discussion\n\nThis is similar to using ruby's Array#all? method.\n\n[underscore]: http://documentcloud.github.com/underscore/\n"
  },
  {
    "path": "chapters/arrays/using-arrays-to-swap-variables.md",
    "content": "---\nlayout: recipe\ntitle: Using Arrays to Swap Variables\nchapter: Arrays\n---\n## Problem\n\nYou want to use an array to swap variables.\n\n## Solution\n\nUse CoffeeScript's [destructuring assignment](http://jashkenas.github.com/coffee-script/#destructuring) syntax:\n\n{% highlight coffeescript %}\na = 1\nb = 3\n\n[a, b] = [b, a]\n\na\n# => 3\n\nb\n# => 1\n{% endhighlight %}\n\n## Discussion\n\nDestructuring assignment allows swapping two values without the use of a temporary variable.\n\nThis can be useful when traversing arrays and ensuring iteration only happens over the shortest one:\n\n{% highlight coffeescript %}\n\nray1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\nray2 = [ 5, 9, 14, 20 ]\n\nintersection = (a, b) ->\n  [a, b] = [b, a] if a.length > b.length\n  value for value in a when value in b\n\nintersection ray1, ray2\n# => [ 5, 9 ]\n\nintersection ray2, ray1\n# => [ 5, 9 ]\n\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/arrays/where-for-arrays-of-objects.md",
    "content": "---\nlayout: recipe\ntitle: where for arrays of objects\nchapter: Arrays\n---\n## Problem\n\nYou want to get an array of objects that match your request for some properties\n\nYou have an Array of Objects, such as:\n\n{% highlight coffeescript %}\ncats = [\n  {\n    name: \"Bubbles\"\n    favoriteFood: \"mice\"\n    age: 1\n  },\n  {\n    name: \"Sparkle\"\n    favoriteFood: \"tuna\"\n  },\n  {\n    name: \"flyingCat\"\n    favoriteFood: \"mice\"\n    age: 1\n  }\n]\n{% endhighlight %}\n\nYou want to filter with some properties, like cats.where({ age: 1}) or cats.where({ age: 1, favoriteFood: \"mice\"})\n\n## Solution\n\nYou can extend Array like this : \n\n{% highlight coffeescript %}\nArray::where = (query) ->\n    return [] if typeof query isnt \"object\"\n    hit = Object.keys(query).length\n    @filter (item) ->\n        match = 0\n        for key, val of query\n            match += 1 if item[key] is val\n        if match is hit then true else false\n\ncats.where age:1\n# => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 },{ name: 'flyingCat', favoriteFood: 'mice', age: 1 } ]\n\ncats.where age:1, name: \"Bubbles\"\n# => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 } ]\n\ncats.where age:1, favoriteFood:\"tuna\"\n# => []\n{% endhighlight %}\n\n## Discussion\n\nThis is an exact match. we could make it more flexible with a matcher function :\n\n{% highlight coffeescript %}\nArray::where = (query, matcher = (a,b) -> a is b) ->\n    return [] if typeof query isnt \"object\"\n    hit = Object.keys(query).length\n    @filter (item) ->\n        match = 0\n        for key, val of query\n            match += 1 if matcher(item[key], val)\n        if match is hit then true else false\n\ncats.where name:\"bubbles\"\n# => []\n# it's case sensitive\n\ncats.where name:\"bubbles\", (a, b) -> \"#{ a }\".toLowerCase() is \"#{ b }\".toLowerCase()\n# => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 } ]\n# now it's case insensitive\n{% endhighlight %}\n\nit's more a method to deal with collection and it could be rename as \"find\" but popular libraries like underscore or lodash name it \"where\". \n"
  },
  {
    "path": "chapters/arrays/zip-function.md",
    "content": "---\nlayout: recipe\ntitle: Python-like Zip Function\nchapter: Arrays\n---\n## Problem\n\nYou want to zip together multiple arrays into an array of arrays, similar to Python's zip function.  Python's zip function returns an array of tuples, where each tuple contains the i-th element from each of the argument arrays.\n\n## Solution\n\nUse the following CoffeeScript code:\n\n{% highlight coffeescript %}\n# Usage: zip(arr1, arr2, arr3, ...)\nzip = () ->\n  lengthArray = (arr.length for arr in arguments)\n  length = Math.min(lengthArray...)\n  for i in [0...length]\n    arr[i] for arr in arguments\n\nzip([0, 1, 2, 3], [0, -1, -2, -3])\n# => [[0, 0], [1, -1], [2, -2], [3, -3]]\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/classes_and_objects/chaining.md",
    "content": "---\nlayout: recipe\ntitle: Chaining Calls to an Object\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to call multiple methods on a single object without having to reference that object each time.\n\n## Solution\n\nReturn the `this` (i.e. `@`) object after every chained method.\n\n{% highlight coffeescript %}\nclass CoffeeCup\n\tconstructor:  ->\n\t\t@properties=\n\t\t\tstrength: 'medium'\n\t\t\tcream: false\n\t\t\tsugar: false\n\tstrength: (newStrength) ->\n\t\t@properties.strength = newStrength\n\t\tthis\n\tcream: (newCream) ->\n\t\t@properties.cream = newCream\n\t\tthis\n\tsugar: (newSugar) ->\n\t\t@properties.sugar = newSugar\n\t\tthis\n\nmorningCup = new CoffeeCup()\n\nmorningCup.properties # => { strength: 'medium', cream: false, sugar: false }\n\neveningCup = new CoffeeCup().strength('dark').cream(true).sugar(true)\n\neveningCup.properties # => { strength: 'dark', cream: true, sugar: true }\n\n{% endhighlight %}\n\n## Discussion\n\nThe jQuery library uses a similar approach by returning a selector object from every relevant method, modifying it as subsequent methods tweak the selection:\n\n{% highlight coffeescript %}\n$('p').filter('.topic').first()\n{% endhighlight %}\n\nFor your own objects, a touch of metaprogramming can automate the setup process and explicitly state the purpose of returning *this*.\n\n{% highlight coffeescript %}\naddChainedAttributeAccessor = (obj, propertyAttr, attr) ->\n\tobj[attr] = (newValues...) ->\n\t\tif newValues.length == 0\n\t\t\tobj[propertyAttr][attr]\n\t\telse\n\t\t\tobj[propertyAttr][attr] = newValues[0]\n\t\t\tobj\n\nclass TeaCup\n\tconstructor:  ->\n\t\t@properties=\n\t\t\tsize: 'medium'\n\t\t\ttype: 'black'\n\t\t\tsugar: false\n\t\t\tcream: false\n\t\taddChainedAttributeAccessor(this, 'properties', attr) for attr of @properties\n\nearlgrey = new TeaCup().size('small').type('Earl Grey').sugar(false)\n\nearlgrey.properties # => { size: 'small', type: 'Earl Grey', sugar: false, cream: false }\n\nearlgrey.sugar true\n\nearlgrey.sugar() # => true\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/classes_and_objects/class-methods-and-instance-methods.md",
    "content": "---\nlayout: recipe\ntitle: Class Methods and Instance Methods\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to create class and instance methods.\n\n## Solution\n\n### Class Method\n\n{% highlight coffeescript %}\n\nclass Songs\n  @_titles: 0    # Although it's directly accessible, the leading _ defines it by convention as private property.\n\n  @get_count: ->\n    @_titles\n\n  constructor: (@artist, @title) ->\n    @constructor._titles++     # Refers to <Classname>._titles, in this case Songs.titles\n\nSongs.get_count()\n# => 0\n\nsong = new Songs(\"Rick Astley\", \"Never Gonna Give You Up\")\nSongs.get_count()\n# => 1\n\nsong.get_count()\n# => TypeError: Object <Songs> has no method 'get_count'\n\n{% endhighlight %}\n\n### Instance Method\n{% highlight coffeescript %}\n\nclass Songs\n  _titles: 0    # Although it's directly accessible, the leading _ defines it by convention as private property.\n\n  get_count: ->\n    @_titles\n\n  constructor: (@artist, @title) ->\n    @_titles++\n\nsong = new Songs(\"Rick Astley\", \"Never Gonna Give You Up\")\nsong.get_count()\n# => 1\n\nSongs.get_count()\n# => TypeError: Object function Songs(artist, title) ... has no method 'get_count'\n\n{% endhighlight %}\n\n\n## Discussion\n\nCoffeescript will store class methods (also called static methods) on the object itself rather than on the object prototype (and thus on individual object instances), which conserves memory and gives a central location to store class-level values.\n"
  },
  {
    "path": "chapters/classes_and_objects/class-variables-and-instance-variables.md",
    "content": "---\nlayout: recipe\ntitle: Class Variables and Instance Variables\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to create class variables and instance variables (properties).\n\n## Solution\n\n### Class Variables\n\n{% highlight coffeescript %}\nclass Zoo\n  @MAX_ANIMALS: 50\n  MAX_ZOOKEEPERS: 3\n  \n  helpfulInfo: =>\n    \"Zoos may contain a maximum of #{@constructor.MAX_ANIMALS} animals and #{@MAX_ZOOKEEPERS} zoo keepers.\"\n\nZoo.MAX_ANIMALS\n# => 50\n\nZoo.MAX_ZOOKEEPERS\n# => undefined (it is a prototype member)\n\nZoo::MAX_ZOOKEEPERS\n# => 3\n\nzoo = new Zoo\nzoo.MAX_ZOOKEEPERS\n# => 3\nzoo.helpfulInfo()\n# => \"Zoos may contain a maximum of 50 animals and 3 zoo keepers.\"\n\nzoo.MAX_ZOOKEEPERS = \"smelly\"\nzoo.MAX_ANIMALS = \"seventeen\"\nzoo.helpfulInfo()\n# => \"Zoos may contain a maximum of 50 animals and smelly zoo keepers.\"\n{% endhighlight %}\n\n\n### Instance Variables\n\nYou have to define instance variables (i.e. properties) inside a class' method, initialize your defaults in the constructor.\n\n{% highlight coffeescript %}\nclass Zoo\n  constructor: ->\n    @animals = [] # Here the instance variable is defined\n    \n  addAnimal: (name) ->\n    @animals.push name\n\n\nzoo = new Zoo()\nzoo.addAnimal 'elephant'\n\notherZoo = new Zoo()\notherZoo.addAnimal 'lion'\n\nzoo.animals\n# => ['elephant']\n\notherZoo.animals\n# => ['lion']\n{% endhighlight %}\n\n#### WARNING!\n*Do not add the variable accidently to the prototype, by defining it outside the constructor* (Even if mentioned [elsewhere](http://arcturo.github.io/library/coffeescript/03_classes.html#content), this does not work as intended, due to the underlying JavaScript prototype concept).\n\n{% highlight coffeescript %}\nclass BadZoo\n  animals: []           # Translates to BadZoo.prototype.animals = []; and is thus shared between instances\n    \n  addAnimal: (name) ->\n    @animals.push name  # Works due to the prototype concept of Javascript\n\n\nzoo = new BadZoo()\nzoo.addAnimal 'elephant'\n\notherZoo = new BadZoo()\notherZoo.addAnimal 'lion'\n\nzoo.animals\n# => ['elephant','lion'] # Oops...\n\notherZoo.animals\n# => ['elephant','lion'] # Oops...\n\nBadZoo::animals\n# => ['elephant','lion'] # The value is stored in the prototype\n{% endhighlight %}\n\n## Discussion\n\nCoffeescript will store the values of class variables on the class itself rather than on the prototype it defines. These are useful for defining variables on classes which can't be overwritten by instance attribute variables.\n"
  },
  {
    "path": "chapters/classes_and_objects/cloning.md",
    "content": "---\nlayout: recipe\ntitle: Cloning an Object (Deep Copy)\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to clone an object with all its sub-objects.\n\n## Solution\n\n{% highlight coffeescript %}\nclone = (obj) ->\n  if not obj? or typeof obj isnt 'object'\n    return obj\n\n  if obj instanceof Date\n    return new Date(obj.getTime()) \n\n  if obj instanceof RegExp\n    flags = ''\n    flags += 'g' if obj.global?\n    flags += 'i' if obj.ignoreCase?\n    flags += 'm' if obj.multiline?\n    flags += 'y' if obj.sticky?\n    return new RegExp(obj.source, flags) \n\n  newInstance = new obj.constructor()\n\n  for key of obj\n    newInstance[key] = clone obj[key]\n\n  return newInstance\n\nx =\n  foo: 'bar'\n  bar: 'foo'\n\ny = clone(x)\n\ny.foo = 'test'\n\nconsole.log x.foo isnt y.foo, x.foo, y.foo\n# => true, bar, test\n{% endhighlight %}\n\n## Discussion\n\nThe difference between copying an object through assignment and through this clone-function is how they handle references. The assignment only copies the object's reference, whereas the clone-function creates a complete new object by\n\n* creating a new object like the source object,\n* copying all attributes form the source object to the new object and\n* repeating these steps for all sub-objects by calling the clone-function recursively.\n\nExample of an assignment copy:\n\n{% highlight coffeescript %}\nx =\n  foo: 'bar'\n  bar: 'foo'\n\ny = x\n\ny.foo = 'test'\n\nconsole.log x.foo isnt y.foo, x.foo, y.foo\n# => false, test, test\n{% endhighlight %}\n\nAs you can see, when you change `y` after the copy, you also change `x`.\n"
  },
  {
    "path": "chapters/classes_and_objects/index.html",
    "content": "---\nlayout: chapter\ntitle: Classes and Objects\nchapter: Classes and Objects\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/classes_and_objects/mixins.md",
    "content": "---\nlayout: recipe\ntitle: Mixins for classes\nchapter: Classes and Objects\n---\n## Problem\n\nYou have a few utility methods that you want to include in a number of different classes.\n\n## Solution\n\nUse a mixOf factory function that generates a mixed superclass for you.\n\n{% highlight coffeescript %}\nmixOf = (base, mixins...) ->\n  class Mixed extends base\n  for mixin in mixins by -1 #earlier mixins override later ones\n    for name, method of mixin::\n      Mixed::[name] = method\n  Mixed\n\n...\n\nclass DeepThought\n  answer: ->\n    42\n    \nclass PhilosopherMixin\n  pontificate: ->\n    console.log \"hmm...\"\n    @wise = yes\n\nclass DeeperThought extends mixOf DeepThought, PhilosopherMixin\n  answer: ->\n    @pontificate()\n    super()\n    \nearth = new DeeperThought\nearth.answer()\n# hmm...\n# => 42\n{% endhighlight %}\n\n## Discussion\n\nThis is intended for lightweight mixins. Thus you inherit methods of the\nbase and its ancestors, and those of the mixins, but not those of the ancestors of \nthe mixins. Also, after declaring a mixed class, further changes in the mixins are not \nreflected.\n"
  },
  {
    "path": "chapters/classes_and_objects/object-literal.md",
    "content": "---\nlayout: recipe\ntitle: Create an Object Literal if It Does Not Already Exist\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to initialize an object literal, but you do not want to overwrite the object if it already exists.\n\n## Solution\n\nUse the Existential operator\n\n{% highlight coffeescript %}\nwindow.MY_NAMESPACE ?= {}\n{% endhighlight %}\n\n## Discussion\n\nThis is equivalent to the following JavaScript:\n\n{% highlight javascript %}\nif(window.MY_NAMESPACE === null || window.MY_NAMESPACE === undefined) {\n  window.MY_NAMESPACE = {};\n}\n{% endhighlight %}\n\n## Problem\n\nYou want to make a conditonal assignment if it does not exists or if it is falsy (empty, 0, null, false)\n\n## Solution\n\nUse the Conditional assignment operator\n\n{% highlight coffeescript %}\nwindow.my_variable ||= {}\n{% endhighlight %}\n\n## Discussion\n\nThis is equivalent to the following JavaScript:\n\n{% highlight javascript %}\nwindow.my_variable = window.my_variable || {};\n{% endhighlight %}\n\nCommon JavaScript technique, using conditional assignment to ensure that we have an object that is not falsy\n"
  },
  {
    "path": "chapters/classes_and_objects/type-function.md",
    "content": "---\nlayout: recipe\ntitle: A CoffeeScript Type Function\nchapter: Classes and Objects\n---\n## Problem\n\nYou'd like to know the type of a object without using typeof. (See http://javascript.crockford.com/remedial.html for more information on why typeof is pretty inferior.)\n\n## Solution\n\nUse the following function:\n\n{% highlight coffeescript %}\n  type = (obj) ->\n    if obj == undefined or obj == null\n      return String obj\n    classToType = {\n      '[object Boolean]': 'boolean',\n      '[object Number]': 'number',\n      '[object String]': 'string',\n      '[object Function]': 'function',\n      '[object Array]': 'array',\n      '[object Date]': 'date',\n      '[object RegExp]': 'regexp',\n      '[object Object]': 'object'\n    }\n    return classToType[Object.prototype.toString.call(obj)]\n{% endhighlight %}\n\n## Discussion\n\nThis function was modeled on jQuery's [$.type function](http://api.jquery.com/jQuery.type/). \n\nNote that, as an alternative to type checking, you can often use duck typing and the existential operator together to eliminating the need to examine an object's type, in certain cases.  For example, here is exception-free code that pushes an element to an array, if myArray is in fact an array (or array-like, with a push function), and does nothing otherwise.\n\n{% highlight coffeescript %}\nmyArray?.push? myValue\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/databases/index.html",
    "content": "---\nlayout: chapter\ntitle: Databases\nchapter: Databases\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/databases/mongodb.md",
    "content": "---\nlayout: recipe\ntitle: MongoDB\nchapter: Databases\n---\n## Problem\n\nYou need to interface with a MongoDB database.\n\n## Solution\n\n### For Node.js\n\n### Setup\n* [Install MongoDB](http://www.mongodb.org/display/DOCS/Quickstart) on your computer if you have not already.\n\n* [Install the native MongoDB module](https://github.com/christkv/node-mongodb-native).\n\n#### Saving Records\n\n{% highlight coffeescript %}\nmongo = require 'mongodb'\n\nserver = new mongo.Server \"127.0.0.1\", 27017, {}\n\nclient = new mongo.Db 'test', server, {w:1}\n\n# save() updates existing records or inserts new ones as needed\nexampleSave = (dbErr, collection) ->\n\tconsole.log \"Unable to access database: #{dbErr}\" if dbErr\n\tcollection.save { _id: \"my_favorite_latte\", flavor: \"honeysuckle\" }, (err, docs) ->\n\t\tconsole.log \"Unable to save record: #{err}\" if err\n\t\tclient.close()\n\nclient.open (err, database) ->\n\tclient.collection 'coffeescript_example', exampleSave\n{% endhighlight %}\n\n#### Finding Records\n\n{% highlight coffeescript %}\nmongo = require 'mongodb'\n\nserver = new mongo.Server \"127.0.0.1\", 27017, {}\n\nclient = new mongo.Db 'test', server, {w:1}\n\nexampleFind = (dbErr, collection) ->\n\tconsole.log \"Unable to access database: #{dbErr}\" if dbErr\n\tcollection.find({ _id: \"my_favorite_latte\" }).nextObject (err, result) ->\n\t\tif err\n\t\t\tconsole.log \"Unable to find record: #{err}\"\n\t\telse\n\t\t\tconsole.log result # => {  id: \"my_favorite_latte\", flavor: \"honeysuckle\" }\n\t\tclient.close()\n\nclient.open (err, database) ->\n\tclient.collection 'coffeescript_example', exampleFind\n{% endhighlight %}\n\n### For Browsers\n\nA [REST-based interface](https://github.com/tdegrunt/mongodb-rest) is in the works.  This will provide AJAX-based access.\n\n## Discussion\n\nThis recipe breaks the *save* and *find* into separate examples in order to separate the MongoDB-specific concerns from the task of connection and callback management.  The [async module](https://github.com/caolan/async) can help with that.\n"
  },
  {
    "path": "chapters/databases/sqlite.md",
    "content": "---\nlayout: recipe\ntitle: SQLite\nchapter: Databases\n---\n## Problem\n\nYou need to interface with a [SQLite](http://www.sqlite.org/) database from inside of Node.js.\n\n## Solution\n\nUse the [SQLite module](http://code.google.com/p/node-sqlite/).\n\n{% highlight coffeescript %}\nsqlite = require 'sqlite'\n\ndb = new sqlite.Database\n\n# The module uses asynchronous methods,\n# so we chain the calls the db.execute\nexampleCreate = ->\n\tdb.execute \"CREATE TABLE snacks (name TEXT(25), flavor TEXT(25))\",\n\t\t(exeErr, rows) ->\n\t\t\tthrow exeErr if exeErr\n\t\t\texampleInsert()\n\nexampleInsert = ->\n\tdb.execute \"INSERT INTO snacks (name, flavor) VALUES ($name, $flavor)\",\n\t\t{ $name: \"Potato Chips\", $flavor: \"BBQ\" },\n\t\t(exeErr, rows) ->\n\t\t\tthrow exeErr if exeErr\n\t\t\texampleSelect()\n\nexampleSelect = ->\n\tdb.execute \"SELECT name, flavor FROM snacks\",\n\t\t(exeErr, rows) ->\n\t\t\tthrow exeErr if exeErr\n\t\t\tconsole.log rows[0] # => { name: 'Potato Chips', flavor: 'BBQ' }\n\n# :memory: creates a DB in RAM\n# You can supply a filepath (like './example.sqlite') to create/open one on disk\ndb.open \":memory:\", (openErr) ->\n\tthrow openErr if openErr\n\texampleCreate()\n{% endhighlight %}\n\n## Discussion\n\nYou can also prepare your SQL queries beforehand:\n\n{% highlight coffeescript %}\nsqlite = require 'sqlite'\nasync = require 'async' # Not required but added to make the example more concise\n\ndb = new sqlite.Database\n\ncreateSQL = \"CREATE TABLE drinks (name TEXT(25), price NUM)\"\n\ninsertSQL = \"INSERT INTO drinks (name, price) VALUES (?, ?)\"\n\nselectSQL = \"SELECT name, price FROM drinks WHERE price < ?\"\n\ncreate = (onFinish) ->\n\tdb.execute createSQL, (exeErr) ->\n\t\tthrow exeErr if exeErr\n\t\tonFinish()\n\t\nprepareInsert = (name, price, onFinish) ->\n\tdb.prepare insertSQL, (prepErr, statement) ->\n\t\tstatement.bindArray [name, price], (bindErr) ->\n\t\t\tstatement.fetchAll (fetchErr, rows) -> # Called so that it executes the insert\n\t\t\t\tonFinish()\n\nprepareSelect = (onFinish) ->\n\tdb.prepare selectSQL, (prepErr, statement) ->\n\t\tstatement.bindArray [1.00], (bindErr) ->\n\t\t\tstatement.fetchAll (fetchErr, rows) ->\n\t\t\t\tconsole.log rows[0] # => { name: \"Mia's Root Beer\", price: 0.75 }\n\t\t\t\tonFinish()\n\ndb.open \":memory:\", (openErr) ->\n\tasync.series([\n\t\t(onFinish) -> create onFinish,\n\t\t(onFinish) -> prepareInsert \"LunaSqueeze\", 7.95, onFinish,\n\t\t(onFinish) -> prepareInsert \"Viking Sparkling Grog\", 4.00, onFinish,\n\t\t(onFinish) -> prepareInsert \"Mia's Root Beer\", 0.75, onFinish,\n\t\t(onFinish) -> prepareSelect onFinish\n\t])\n{% endhighlight %}\n\nThe [SQLite version of SQL](http://www.sqlite.org/lang.html) and the [node-sqlite module documentation](https://github.com/orlandov/node-sqlite#readme) provide more complete information.\n\n"
  },
  {
    "path": "chapters/dates_and_times/date-of-easter.md",
    "content": "---\nlayout: recipe\ntitle: Calculate the Date of Easter Sunday\nchapter: Dates and Times\n---\n## Problem\n\nYou need to find the month and day of the Easter Sunday for given year.\n\n## Solution\n\nThe following function returns array with two elements: month (1-12) and day of the Easter Sunday. If no arguments are given\nresult is for the current year.\nThis is an implementation of [Anonymous Gregorian algorithm](http://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm) in CoffeeScript.\n\n{% highlight coffeescript %}\n\ngregorianEaster = (year = (new Date).getFullYear()) ->\n  a = year % 19\n  b = ~~(year / 100)\n  c = year % 100\n  d = ~~(b / 4)\n  e = b % 4\n  f = ~~((b + 8) / 25)\n  g = ~~((b - f + 1) / 3)\n  h = (19 * a + b - d - g + 15) % 30\n  i = ~~(c / 4)\n  k = c % 4\n  l = (32 + 2 * e + 2 * i - h - k) % 7\n  m = ~~((a + 11 * h + 22 * l) / 451)\n  n = h + l - 7 * m + 114\n  month = ~~(n / 31)\n  day = (n % 31) + 1\n  [month, day]\n\n{% endhighlight %}\n\n## Discussion\n\nNB! Javascript numbers months from 0 to 11 so .getMonth() for date in March will return 2, this function will return 3.\nYou can modify the function if you want this to be consistent.\n\nThe function uses ~~ trick instead of Math.floor().\n\n{% highlight coffeescript %}\n\ngregorianEaster()    # => [4, 24] (April 24th in 2011)\ngregorianEaster 1972 # => [4, 2]\n\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/dates_and_times/date-of-thanksgiving.md",
    "content": "---\nlayout: recipe\ntitle: Calculate the Date of Thanksgiving (USA and Canada)\nchapter: Dates and Times\n---\n## Problem\n\nYou need to calculate when Thanksgiving is in a given year.\n\n## Solution\n\nThe following functions return the day of Thanksgiving for a given year. If no year is given then current year is used.\n\nIn the USA Thanksgiving is celebrated on the fourth Thursday in November:\n\n{% highlight coffeescript %}\n\nthanksgivingDayUSA = (year = (new Date).getFullYear()) ->\n  first = new Date year, 10, 1\n  day_of_week = first.getDay()\n  22 + (11 - day_of_week) % 7\n\n{% endhighlight %}\n\nIn Canada it is the second Monday in October:\n\n{% highlight coffeescript %}\n\nthanksgivingDayCA = (year = (new Date).getFullYear()) ->\n    first = new Date year, 9, 1\n    day_of_week = first.getDay()\n    8 + (8 - day_of_week) % 7\n\n{% endhighlight %}\n\n## Discussion\n\n{% highlight coffeescript %}\n\nthanksgivingDayUSA() #=> 24 (November 24th, 2011)\n\nthanksgivingDayCA() # => 10 (October 10th, 2011)\n\nthanksgivingDayUSA(2012) # => 22 (November 22nd)\n\nthanksgivingDayCA(2012) # => 8 (October 8th)\n\n{% endhighlight %}\n\nThe idea is very simple:\n1. Find out what day of the week is the first day of respective month (November for USA, October for Canada).\n2. Calculate offset from that day to the next occurrence of weekday required (Thursday for USA, Monday for Canada).\n3. Add that offset to the first possible date of the holiday (22nd for USA Thanksgiving, 8th for Canada).\n"
  },
  {
    "path": "chapters/dates_and_times/days-between-two-dates.md",
    "content": "---\nlayout: recipe\ntitle: Get Days Between Two Dates\nchapter: Dates and Times\n---\n## Problem\n\nYou need to find how many seconds, minutes, hours, days, months or years have passed between two dates.\n\n## Solution\n\nUse JavaScript's Date function  getTime(). Which provides how much time in milliseconds have passed since 01/01/1970:\n\n{% highlight coffeescript %}\nDAY = 1000 * 60 * 60  * 24\n\nd1 = new Date('02/01/2011')\nd2 = new Date('02/06/2011')\n\ndays_passed = Math.round((d2.getTime() - d1.getTime()) / DAY)\n{% endhighlight %}\n\n## Discussion\n\nUsing milliseconds makes the life easier to avoid overflow mistakes with Dates. So we first calculate how many milliseconds are in a day.\nThen, given two distinct dates, get the difference in milliseconds between two dates and then divide by how many milliseconds are in a day. It will return the days between two distinct dates.\n\nIf you'd like to calculate the hours between two date objects, you can do that by dividing the difference in milliseconds by the conversion of milliseconds to hours. The same goes for minutes and seconds.\n\n{% highlight coffeescript %}\nHOUR = 1000 * 60 * 60\n\nd1 = new Date('02/01/2011 02:20')\nd2 = new Date('02/06/2011 05:20')\n\nhour_passed = Math.round((d2.getTime() - d1.getTime()) / HOUR)\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/dates_and_times/finding-last-day-of-the-month.md",
    "content": "---\nlayout: recipe\ntitle: Finding the Last Day of the Month\nchapter: Dates and Times\n---\n## Problem\n\nYou need to find the last day of the month, but don't want to keep a lookup table of the number of days in each month of the year.\n\n## Solution\n\nUse JavaScript's Date underflow to find the -1th day of the following month:\n\n{% highlight coffeescript %}\nnow = new Date\nlastDayOfTheMonth = new Date(1900+now.getYear(), now.getMonth()+1, 0)\n{% endhighlight %}\n\n## Discussion\n\nJavaScript's Date constructor cheerfully handles overflow and underflow conditions, which makes date math very easy. Given this ease of manipulation, it doesn't make sense to worry about how many days are in a given month; just nudge the math around. In December, the solution above will actually ask for the 0th day of the 13th month of the current year, which works out to the day before the 1st day of January of NEXT year, which works out to the 31st day of December of the current year.\n"
  },
  {
    "path": "chapters/dates_and_times/finding-last-or-next-month.md",
    "content": "---\nlayout: recipe\ntitle: Finding Last (or Next) Month\nchapter: Dates and Times\n---\n## Problem\n\nYou need to calculate a relative date range like \"last month\" or \"next month\".\n\n## Solution\n\nAdd or subtract from the current month, secure in the knowledge that JavaScript's Date constructor will fix up the math.\n\n{% highlight coffeescript %}\n# these examples were written in GMT-6\n# Note that these examples WILL work in January!\nnow = new Date\n# => \"Sun, 08 May 2011 05:50:52 GMT\"\n\nlastMonthStart = new Date 1900+now.getYear(), now.getMonth()-1, 1\n# => \"Fri, 01 Apr 2011 06:00:00 GMT\"\n\nlastMonthEnd = new Date 1900+now.getYear(), now.getMonth(), 0\n# => \"Sat, 30 Apr 2011 06:00:00 GMT\"\n{% endhighlight %}\n\n## Discussion\n\nJavaScript Date objects will cheerfully handle underflows and overflows in the month and day fields, and will adjust the date object accordingly. You can ask for the 42nd of March, for example, and will get the 11th of April.\n\nJavaScript Date objects store the year as the number of years since 1900, the month as an integer from 0 to 11, and the date (day of month) as an integer from 1 to 31. In the solution above, last_month_start is obtained by asking for the first day of a month in the current year, but the month is -1 to 10. If month is -1 the Date object will actually return December of the previous year:\n\n{% highlight coffeescript %}\nlastNewYearsEve = new Date 1900+now.getYear(), -1, 31\n# => \"Fri, 31 Dec 2010 07:00:00 GMT\"\n{% endhighlight %}\n\nThe same is true for overflows:\n\n{% highlight coffeescript %}\nthirtyNinthOfFourteember = new Date 1900+now.getYear(), 13, 39\n# => \"Sat, 10 Mar 2012 07:00:00 GMT\"\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/dates_and_times/index.html",
    "content": "---\nlayout: chapter\ntitle: Dates and Times\nchapter: Dates and Times\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/dates_and_times/moon-phase-for-date.md",
    "content": "---\nlayout: recipe\ntitle: Calculate Phase of the Moon for a Date\nchapter: Dates and Times\n---\n## Problem\n\nYou want to find the current phase of the moon.\n\n## Solution\n\nThe following code provides a method to calculate the phase of the moon for a given date.\n\n{% highlight coffeescript %}\n# moonPhase.coffee\n\n# Moon-phase calculator\n# Roger W. Sinnott, Sky & Telescope, June 16, 2006\n# http://www.skyandtelescope.com/observing/objects/javascript/moon_phases\n#\n# Translated to CoffeeScript by Mike Hatfield @WebCoding4Fun\n\nproper_ang = (big) ->\n\ttmp = 0\n\tif big > 0\n\t\ttmp = big / 360.0\n\t\ttmp = (tmp - (~~tmp)) * 360.0\n\telse\n\t\ttmp = Math.ceil(Math.abs(big / 360.0))\n\t\ttmp = big + tmp * 360.0\n\n\ttmp\n\njdn = (date) ->\t\n\tmonth = date.getMonth()\n\tday = date.getDate()\n\tyear = date.getFullYear()\n\tzone = date.getTimezoneOffset() / 1440\n\n\tmm = month\n\tdd = day\n\tyy = year\n\n\tyyy = yy\n\tmmm = mm\n\tif mm < 3\n\t\tyyy = yyy - 1\n\t\tmmm = mm + 12\n     \n\tday = dd + zone + 0.5\n\ta = ~~( yyy / 100 )\n\tb = 2 - a + ~~( a / 4 )\n\tjd = ~~( 365.25 * yyy ) + ~~( 30.6001 * ( mmm+ 1 ) ) + day + 1720994.5\n\tjd + b if jd > 2299160.4999999\n    \nmoonElong = (jd) ->\n\tdr    = Math.PI / 180\n\trd    = 1 / dr\n\tmeeDT = Math.pow((jd - 2382148), 2) / (41048480 * 86400)\n\tmeeT  = (jd + meeDT - 2451545.0) / 36525\n\tmeeT2 = Math.pow(meeT, 2)\n\tmeeT3 = Math.pow(meeT, 3)\n\tmeeD  = 297.85 + (445267.1115 * meeT) - (0.0016300 * meeT2) + (meeT3 / 545868)\n\tmeeD  = (proper_ang meeD) * dr\n\tmeeM1 = 134.96 + (477198.8676 * meeT) + (0.0089970 * meeT2) + (meeT3 / 69699)\n\tmeeM1 = (proper_ang meeM1) * dr\n\tmeeM  = 357.53 + (35999.0503 * meeT)\n\tmeeM  = (proper_ang meeM) * dr\n\n\telong = meeD * rd + 6.29 * Math.sin( meeM1 )\n\telong = elong     - 2.10 * Math.sin( meeM )\n\telong = elong     + 1.27 * Math.sin( 2*meeD - meeM1 )\n\telong = elong     + 0.66 * Math.sin( 2*meeD )\n\telong = proper_ang elong\n\telong = Math.round elong\n\n\tmoonNum = ( ( elong + 6.43 ) / 360 ) * 28\n\tmoonNum = ~~( moonNum )\n\n\tif moonNum is 28 then 0 else moonNum\n\ngetMoonPhase = (age) ->\n\tmoonPhase = \"new Moon\"\n\tmoonPhase = \"first quarter\" if age > 3 and age < 11 \n\tmoonPhase = \"full Moon\"     if age > 10 and age < 18\n\tmoonPhase = \"last quarter\"  if age > 17 and age < 25\n\n\tif ((age is 1) or (age is 8) or (age is 15) or (age is 22))\n\t\tmoonPhase = \"1 day past \" + moonPhase\n\n\tif ((age is 2) or (age is 9) or (age is 16) or (age is 23))\n\t\tmoonPhase = \"2 days past \" + moonPhase\n\n\tif ((age is 3) or (age is 1) or (age is 17) or (age is 24))\n\t\tmoonPhase = \"3 days past \" + moonPhase\n\t\n\tif ((age is 4) or (age is 11) or (age is 18) or (age is 25))\n\t\tmoonPhase = \"3 days before \" + moonPhase\n\t\n\tif ((age is 5) or (age is 12) or (age is 19) or (age is 26))\n\t\tmoonPhase = \"2 days before \" + moonPhase\n\t\n\tif ((age is 6) or (age is 13) or (age is 20) or (age is 27))\n\t\tmoonPhase = \"1 day before \" + moonPhase\n\t\n\tmoonPhase\n\nMoonPhase = exports? and exports or @MoonPhase = {}\n\nclass MoonPhase.Calculator\n\tgetMoonDays: (date) ->\n\t\tjd = jdn date \n\t\tmoonElong jd\n\n\tgetMoonPhase: (date) ->\t\t\n\t\tjd = jdn date \n\t\tgetMoonPhase( moonElong jd )\n{% endhighlight %}\n\n## Discussion\n\nThis code exposes a MoonPhase Calculator object with two methods.  Calculator -> getMoonPhase will return a text representation of the lunar phase for the date provided.\n\nThis can be used in both the browser and Node.js.\n\n{% highlight console %}\n$ node\n> var MoonPhase = require('./moonPhase.js');\n undefined\n> var calc = new MoonPhase.Calculator();\n undefined\n> calc.getMoonPhase(new Date());\n 'full moon'\n> calc.getMoonPhase(new Date(1972, 6, 30));\n '3 days before last quarter'\n{% endhighlight %}"
  },
  {
    "path": "chapters/design_patterns/adapter.md",
    "content": "---\nlayout: recipe\ntitle: Adapter pattern\nchapter: Design patterns\n---\n## Problem\n\nImagine you are traveling to a foreign country and once at your hotel room you realize your power cord socket is not compatible with the wall socket.\nLuckily, you remembered you've brought your power adapter with you.\nIt will connect your power cord socket on one side and wall socket on the other side, allowing for communication between them.\n\nThe same situation may arise in code, when 2 (or more) instances (of classes, modules, etc.) want to talk to each other, but whose communication protocol (e.i. the language they use to communicate) is different from each other.\nIn such a situation, the [Adapter Pattern]({{ site.baseurl }}//en.wikipedia.org/wiki/Adapter_pattern) comes in handy. It will do the translation, from one side to the other.\n\n## Solution\n\n{% highlight coffeescript %}\n# a fragment of 3-rd party grid component\nclass AwesomeGrid\n\tconstructor: (@datasource)->\n\t\t@sort_order = 'ASC' \n\t\t@sorter = new NullSorter # in this place we use NullObject pattern (another useful pattern)\n\tsetCustomSorter: (@customSorter) ->\n\t\t@sorter = customSorter\n\tsort: () ->\n\t\t@datasource = @sorter.sort @datasource, @sort_order\n\t\t# don't forget to change sort order\n\n\nclass NullSorter\n\tsort: (data, order) -> # do nothing; it is just a stub\n\t\nclass RandomSorter\n\tsort: (data)->\n\t\tfor i in [data.length-1..1] #let's shuffle the data a bit\n    \t\t\tj = Math.floor Math.random() * (i + 1)\n    \t\t\t[data[i], data[j]] = [data[j], data[i]]\n\t\treturn data\n\nclass RandomSorterAdapter\n\tconstructor: (@sorter) ->\n\tsort: (data, order) ->\n\t\t@sorter.sort data\n\nagrid = new AwesomeGrid ['a','b','c','d','e','f']\nagrid.setCustomSorter new RandomSorterAdapter(new RandomSorter)\nagrid.sort() # sort data with custom sorter through adapter\n\n{% endhighlight %}\n\n## Discussion\n\nAdapter is useful when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3rd party libraries  or you work with legacy code. \nIn any case be careful with adapter: it can be helpful but it can instigate design errors. \n"
  },
  {
    "path": "chapters/design_patterns/bridge.md",
    "content": "---\nlayout: recipe\ntitle: Bridge Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou need to maintain a reliable interface for code that can change frequently or change between multiple implementations.\n\n## Solution\n\nUse the Bridge pattern as an intermediate between the different implementations and the rest of the code.\n\nAssume that you developed an in-browser text editor that saves to the cloud.  Now, however, you need to port it to a stand-alone client that saves locally.\n\n{% highlight coffeescript %}\nclass TextSaver\n\tconstructor: (@filename, @options) ->\n\tsave: (data) ->\n\nclass CloudSaver extends TextSaver\n\tconstructor: (@filename, @options) ->\n\t\tsuper @filename, @options\n\tsave: (data) ->\n\t\t# Assuming jQuery\n\t\t# Note the fat arrows\n\t\t$( =>\n\t\t\t$.post \"#{@options.url}/#{@filename}\", data, =>\n\t\t\t\talert \"Saved '#{data}' to #{@filename} at #{@options.url}.\"\n\t\t)\n\nclass FileSaver extends TextSaver\n\tconstructor: (@filename, @options) ->\n\t\tsuper @filename, @options\n\t\t@fs = require 'fs'\n\tsave: (data) ->\n\t\t@fs.writeFile @filename, data, (err) => # Note the fat arrow\n\t\t\tif err? then console.log err\n\t\t\telse console.log \"Saved '#{data}' to #{@filename} in #{@options.directory}.\"\n\nfilename = \"temp.txt\"\ndata = \"Example data\"\n\nsaver = if window?\n\tnew CloudSaver filename, url: 'http://localhost' # => Saved \"Example data\" to temp.txt at http://localhost\nelse if root?\n\tnew FileSaver filename, directory: './' # => Saved \"Example data\" to temp.txt in ./\n\nsaver.save data\n{% endhighlight %}\n\n## Discussion\n\nThe Bridge pattern helps you to move the implementation-specific code out of sight so that you can focus on your program's specific code.  In the above example, the rest of your application can call `saver.save data` without regard for where the file ultimately ends up.\n"
  },
  {
    "path": "chapters/design_patterns/builder.md",
    "content": "---\nlayout: recipe\ntitle: Builder Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou need to prepare a complicated, multi-part object, but you expect to do it more than once or with varying configurations.\n\n## Solution\n\nCreate a Builder to encapsulate the object production process.\n\nThe [Todo.txt](http://todotxt.com) format provides an advanced but still plain-text method for maintaining lists of to-do items.  Typing out each item by hand would provide exhausting and error-prone, however, so a TodoTxtBuilder class could save us the trouble:\n\n{% highlight coffeescript %}\nclass TodoTxtBuilder\n    constructor: (defaultParameters={ }) ->\n        @date = new Date(defaultParameters.date) or new Date\n        @contexts = defaultParameters.contexts or [ ]\n        @projects = defaultParameters.projects or [ ]\n        @priority =  defaultParameters.priority or undefined\n    newTodo: (description, parameters={ }) ->\n        date = (parameters.date and new Date(parameters.date)) or @date\n        contexts = @contexts.concat(parameters.contexts or [ ])\n        projects = @projects.concat(parameters.projects or [ ])\n        priorityLevel = parameters.priority or @priority\n        createdAt = [date.getFullYear(), date.getMonth()+1, date.getDate()].join(\"-\")\n        contextNames = (\"@#{context}\" for context in contexts when context).join(\" \")\n        projectNames = (\"+#{project}\" for project in projects when project).join(\" \")\n        priority = if priorityLevel then \"(#{priorityLevel})\" else \"\"\n        todoParts = [priority, createdAt, description, contextNames, projectNames]\n        (part for part in todoParts when part.length > 0).join \" \"\n\nbuilder = new TodoTxtBuilder(date: \"10/13/2011\")\n\nbuilder.newTodo \"Wash laundry\"\n\n# => '2011-10-13 Wash laundry'\n\nworkBuilder = new TodoTxtBuilder(date: \"10/13/2011\", contexts: [\"work\"])\n\nworkBuilder.newTodo \"Show the new design pattern to Lucy\", contexts: [\"desk\", \"xpSession\"]\n\n# => '2011-10-13 Show the new design pattern to Lucy @work @desk @xpSession'\n\nworkBuilder.newTodo \"Remind Sean about the failing unit tests\", contexts: [\"meeting\"], projects: [\"compilerRefactor\"], priority: 'A'\n\n# => '(A) 2011-10-13 Remind Sean about the failing unit tests @work @meeting +compilerRefactor'\n\n{% endhighlight %}\n\n## Discussion\n\nThe TodoTxtBuilder class takes care of all the heavy lifting of text generation and lets the programmer focus on the unique elements of each to-do item.  Additionally, a command line tool or GUI could plug into this code and still retain support for later, more advanced versions of the format with ease.\n\n### Pre-Construction\n\nInstead of creating a new instance of the needed object from scratch every time, we shift the burden to a separate object that we can then tweak during the object creation process.\n\n{% highlight coffeescript %}\nbuilder = new TodoTxtBuilder(date: \"10/13/2011\")\n\nbuilder.newTodo \"Order new netbook\"\n\n# => '2011-10-13 Order new netbook'\n\nbuilder.projects.push \"summerVacation\"\n\nbuilder.newTodo \"Buy suntan lotion\"\n\n# => '2011-10-13 Buy suntan lotion +summerVacation'\n\nbuilder.contexts.push \"phone\"\n\nbuilder.newTodo \"Order tickets\"\n\n# => '2011-10-13 Order tickets @phone +summerVacation'\n\ndelete builder.contexts[0]\n\nbuilder.newTodo \"Fill gas tank\"\n\n# => '2011-10-13 Fill gas tank +summerVacation'\n{% endhighlight %}\n\n### Exercises\n\n* Expand the project- and context-tag generation code to filter out duplicate entries.\n* Some Todo.txt users like to insert project and context tags inside the description of their to-do items.  Add code to identify these tags and filter them out of the end tags.\n"
  },
  {
    "path": "chapters/design_patterns/command.md",
    "content": "---\nlayout: recipe\ntitle: Command Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou need to let another object handle when your private code is executed.\n\n## Solution\n\nUse the [Command pattern](http://en.wikipedia.org/wiki/Command_pattern) to pass along references to your functions.\n\n{% highlight coffeescript %}\n# Using a private variable to simulate external scripts or modules\nincrementers = (() ->\n\tprivateVar = 0\n\n\tsingleIncrementer = () ->\n\t\tprivateVar += 1\n\n\tdoubleIncrementer = () ->\n\t\tprivateVar += 2\n\t\n\tcommands = \n\t\tsingle: singleIncrementer\n\t\tdouble: doubleIncrementer\n\t\tvalue: -> privateVar\n)()\n\nclass RunsAll\n\tconstructor: (@commands...) ->\n\trun: -> command() for command in @commands\n\nrunner = new RunsAll(incrementers.single, incrementers.double, incrementers.single, incrementers.double)\nrunner.run()\nincrementers.value() # => 6\n{% endhighlight %}\n\n## Discussion\n\nWith functions as first-class objects and with the function-bound variable scope inherited from Javascript, the CoffeeScript language makes the pattern nearly invisible.  In fact, any function passed along as callbacks can act as a *Command*.\n\nThe `jqXHR` object returned by jQuery AJAX methods uses this pattern.\n\n{% highlight coffeescript %}\njqxhr = $.ajax\n\turl: \"/\"\n\nlogMessages = \"\"\n\njqxhr.success -> logMessages += \"Success!\\n\"\njqxhr.error -> logMessages += \"Error!\\n\"\njqxhr.complete -> logMessages += \"Completed!\\n\"\n\n# On a valid AJAX request:\n# logMessages == \"Success!\\nCompleted!\\n\"\n{% endhighlight %}\n\n"
  },
  {
    "path": "chapters/design_patterns/decorator.md",
    "content": "---\nlayout: recipe\ntitle: Decorator Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou have a set of data that you need to process in multiple, possibly varying ways.\n\n## Solution\n\nUse the Decorator pattern in order to structure how you apply the changes.\n\n{% highlight coffeescript %}\nminiMarkdown = (line) ->\n    if match = line.match /^(#+)\\s*(.*)$/\n        headerLevel = match[1].length\n        headerText = match[2]\n        \"<h#{headerLevel}>#{headerText}</h#{headerLevel}>\"\n    else\n        if line.length > 0\n            \"<p>#{line}</p>\"\n        else\n            ''\n\nstripComments = (line) ->\n    line.replace /\\s*\\/\\/.*$/, '' # Removes one-line, double-slash C-style comments\n\nclass TextProcessor\n    constructor: (@processors) ->\n\n    reducer: (existing, processor) ->\n        if processor\n            processor(existing or '')\n        else\n            existing\n    processLine: (text) ->\n        @processors.reduce @reducer, text\n    processString: (text) ->\n        (@processLine(line) for line in text.split(\"\\n\")).join(\"\\n\")\n\nexampleText = '''\n              # A level 1 header\n              A regular line\n              // a comment\n              ## A level 2 header\n              A line // with a comment\n              '''\n\nprocessor = new TextProcessor [stripComments, miniMarkdown]\n\nprocessor.processString exampleText\n\n# => \"<h1>A level 1 header</h1>\\n<p>A regular line</p>\\n\\n<h2>A level 2 header</h2>\\n<p>A line</p>\"\n{% endhighlight %}\n\n### Results\n\n{% highlight html %}\n<h1>A level 1 header</h1>\n<p>A regular line</p>\n\n<h2>A level 1 header</h2>\n<p>A line</p>\n{% endhighlight %}\n\n## Discussion\n\nThe TextProcessor serves the role of Decorator by binding the individual, specialized text processors together.  This frees up the miniMarkdown and stripComments components to focus on handling nothing but a single line of text.  Future developers only have to write functions that return a string and add it to the array of processors.\n\nWe can even modify the existing Decorator object on the fly:\n\n{% highlight coffeescript %}\nsmilies =\n    ':)' : \"smile\"\n    ':D' : \"huge_grin\"\n    ':(' : \"frown\"\n    ';)' : \"wink\"\n\nsmilieExpander = (line) ->\n    if line\n        (line = line.replace symbol, \"<img src='#{text}.png' alt='#{text}' />\") for symbol, text of smilies\n    line\n\nprocessor.processors.unshift smilieExpander\n\nprocessor.processString \"# A header that makes you :) // you may even laugh\"\n\n# => \"<h1>A header that makes you <img src='smile.png' alt='smile' /></h1>\"\n\nprocessor.processors.shift()\n\n# => \"<h1>A header that makes you :)</h1>\"\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/design_patterns/factory_method.md",
    "content": "---\nlayout: recipe\ntitle: Factory Method Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou don't know what kind of object you will need until runtime.\n\n## Solution\n\nUse the [Factory Method](http://en.wikipedia.org/wiki/Factory_method_pattern) pattern and choose the object to be generated dynamically.\n\nSay that you need to load a file into an editor but you don't know its format until the user chooses the file.  A class using the [Factory Method](http://en.wikipedia.org/wiki/Factory_method_pattern) pattern can serve up different parsers depending on the file's extension.\n\n{% highlight coffeescript %}\nclass HTMLParser\n\tconstructor: ->\n\t\t@type = \"HTML parser\"\nclass MarkdownParser\n\tconstructor: ->\n\t\t@type = \"Markdown parser\"\nclass JSONParser\n\tconstructor: ->\n\t\t@type = \"JSON parser\"\n\nclass ParserFactory\n\tmakeParser: (filename) ->\n\t\tmatches = filename.match /\\.(\\w*)$/\n\t\textension = matches[1]\n\t\tswitch extension\n\t\t\twhen \"html\" then new HTMLParser\n\t\t\twhen \"htm\" then new HTMLParser\n\t\t\twhen \"markdown\" then new MarkdownParser\n\t\t\twhen \"md\" then new MarkdownParser\n\t\t\twhen \"json\" then new JSONParser\n\nfactory = new ParserFactory\n\nfactory.makeParser(\"example.html\").type # => \"HTML parser\"\n\nfactory.makeParser(\"example.md\").type # => \"Markdown parser\"\n\nfactory.makeParser(\"example.json\").type # => \"JSON parser\"\n{% endhighlight %}\n\n## Discussion\n\nIn the example, you can ignore the specifics of the file's format and focus on the parsed content.  A more advanced Factory Method might, for instance, also search for versioning data within the file itself before returning a more precise parser (e.g. an HTML5 parser instead of an HTML v4 parser).\n"
  },
  {
    "path": "chapters/design_patterns/index.html",
    "content": "---\nlayout: chapter\ntitle: Design Patterns\nchapter: Design Patterns\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/design_patterns/interpreter.md",
    "content": "---\nlayout: recipe\ntitle: Interpreter Pattern\nchapter: Design Patterns\n---\n## Problem\n\nSomeone else needs to run parts of your code in a controlled fashion.  Alternately, your language of choice cannot express the problem domain in a concise fashion.\n\n## Solution\n\nUse the Interpreter pattern to create a domain-specific language that you translate into specific code.\n\nAssume, for example, that the user wants to perform math inside of your application.  You could let them forward code to _eval_ but that would let them run arbitrary code.  Instead, you can provide a miniature \"stack calculator\" language that you parse separately in order to only run mathematical operations while reporting more useful error messages.\n\n{% highlight coffeescript %}\nclass StackCalculator\n\tparseString: (string) ->\n\t\t@stack = [ ]\n\t\tfor token in string.split /\\s+/\n\t\t\t@parseToken token\n\n\t\tif @stack.length > 1\n\t\t\tthrow \"Not enough operators: numbers left over\"\n\t\telse\n\t\t\t@stack[0]\n\n\tparseToken: (token, lastNumber) ->\n\t\tif isNaN parseFloat(token) # Assume that anything other than a number is an operator\n\t\t\t@parseOperator token\n\t\telse\n\t\t\t@stack.push parseFloat(token)\n\n\tparseOperator: (operator) ->\n\t\tif @stack.length < 2\n\t\t\tthrow \"Can't operate on a stack without at least 2 items\"\n\n\t\tright = @stack.pop()\n\t\tleft = @stack.pop()\n\n\t\tresult = switch operator\n\t\t\twhen \"+\" then left + right\n\t\t\twhen \"-\" then left - right\n\t\t\twhen \"*\" then left * right\n\t\t\twhen \"/\"\n\t\t\t\tif right is 0\n\t\t\t\t\tthrow \"Can't divide by 0\"\n\t\t\t\telse\n\t\t\t\t\tleft / right\n\t\t\telse\n\t\t\t\tthrow \"Unrecognized operator: #{operator}\"\n\n\t\t@stack.push result\n\ncalc = new StackCalculator\n\ncalc.parseString \"5 5 +\" # => { result: 10 }\n\ncalc.parseString \"4.0 5.5 +\" # => { result: 9.5 }\n\ncalc.parseString \"5 5 + 5 5 + *\" # => { result: 100 }\n\ntry\n\tcalc.parseString \"5 0 /\"\ncatch error\n\terror # => \"Can't divide by 0\"\n\ntry\n\tcalc.parseString \"5 -\"\ncatch error\n\terror # => \"Can't operate on a stack without at least 2 items\"\n\ntry\n\tcalc.parseString \"5 5 5 -\"\ncatch error\n\terror # => \"Not enough operators: numbers left over\"\n\ntry\n\tcalc.parseString \"5 5 5 foo\"\ncatch error\n\terror # => \"Unrecognized operator: foo\"\n{% endhighlight %}\n\n## Discussion\n\nAs an alternative to writing our own interpreter, you can co-op the existing CoffeeScript interpreter in a such a way that its normal syntax makes for more natural (and therefore more comprehensible) expressions of your algorithm.\n\n{% highlight coffeescript %}\nclass Sandwich\n\tconstructor: (@customer, @bread='white', @toppings=[], @toasted=false)->\n\nwhite = (sw) ->\n\tsw.bread = 'white'\n\tsw\n\nwheat = (sw) ->\n\tsw.bread = 'wheat'\n\tsw\n\nturkey = (sw) ->\n\tsw.toppings.push 'turkey'\n\tsw\n\nham = (sw) ->\n\tsw.toppings.push 'ham'\n\tsw\n\nswiss = (sw) ->\n\tsw.toppings.push 'swiss'\n\tsw\n\nmayo = (sw) ->\n\tsw.toppings.push 'mayo'\n\tsw\n\ntoasted = (sw) ->\n\tsw.toasted = true\n\tsw\n\nsandwich = (customer) ->\n\tnew Sandwich customer\n\nto = (customer) ->\n\tcustomer\n\nsend = (sw) ->\n\ttoastedState = sw.toasted and 'a toasted' or 'an untoasted'\n\n\ttoppingState = ''\n\tif sw.toppings.length > 0\n\t\tif sw.toppings.length > 1\n\t\t\ttoppingState = \" with #{sw.toppings[0..sw.toppings.length-2].join ', '} and #{sw.toppings[sw.toppings.length-1]}\"\n\t\telse\n\t\t\ttoppingState = \" with #{sw.toppings[0]}\"\n\t\"#{sw.customer} requested #{toastedState}, #{sw.bread} bread sandwich#{toppingState}\"\n\nsend sandwich to 'Charlie' # => \"Charlie requested an untoasted, white bread sandwich\"\nsend turkey sandwich to 'Judy' # => \"Judy requested an untoasted, white bread sandwich with turkey\"\nsend toasted ham turkey sandwich to 'Rachel' # => \"Rachel requested a toasted, white bread sandwich with turkey and ham\"\nsend toasted turkey ham swiss sandwich to 'Matt' # => \"Matt requested a toasted, white bread sandwich with swiss, ham and turkey\"\n{% endhighlight %}\n\nThis example allows for layers of functions by how it returns the modified object so that outer functions can modify it in turn.  By borrowing a verb and the preposition _to_, the example lends natural grammar to the construction and ends up reading like an actual sentence when used correctly.  This way, both your CoffeeScript skills and your existing language skills can help catch code problems.\n"
  },
  {
    "path": "chapters/design_patterns/memento.md",
    "content": "---\nlayout: recipe\ntitle: Memento Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou want to anticipate the reversion of changes to an object.\n\n## Solution\n\nUse the [Memento pattern](http://en.wikipedia.org/wiki/Memento_pattern) to track changes to an object.  The class using the pattern will export a `memento` object stored elsewhere.\n\nIf you have application where the user can edit a text file, for example, they may want to undo their last action.  You can save the current state of the file before the user changes it and then roll back to that at a later point.\n\n{% highlight coffeescript %}\nclass PreserveableText\n\tclass Memento\n\t\tconstructor: (@text) ->\n\n\tconstructor: (@text) ->\n\tsave: (newText) ->\n\t\tmemento = new Memento @text\n\t\t@text = newText\n\t\tmemento\n\trestore: (memento) ->\n\t\t@text = memento.text\n\npt = new PreserveableText \"The original string\"\npt.text # => \"The original string\"\n\nmemento = pt.save \"A new string\"\npt.text # => \"A new string\"\n\npt.save \"Yet another string\"\npt.text # => \"Yet another string\"\n\npt.restore memento\npt.text # => \"The original string\"\n{% endhighlight %}\n\n## Discussion\n\nThe Memento object returned by `PreserveableText#save` stores the important state information separately for safe-keeping.  You could even serialize this Memento in order to maintain an \"undo\" buffer on the hard disk or remotely for such data-intensive objects as edited images.\n"
  },
  {
    "path": "chapters/design_patterns/observer.md",
    "content": "---\nlayout: recipe\ntitle: Observer Pattern\nchapter: Design patterns\n---\n## Problem\n\nYou have to notify some objects about an event happen\n\n## Solution\n\nUse an [Observer Pattern](http://en.wikipedia.org/wiki/Observer_pattern)\n\n{% highlight coffeescript %}\n\nclass PostOffice\n\tconstructor: () ->\n\t\t@subscribers = []\n\tnotifyNewItemReleased: (item) ->\n\t\tsubscriber.callback(item) for subscriber in @subscribers when subscriber.item is item\n\tsubscribe: (to, onNewItemReleased) ->\n\t\t@subscribers.push {'item':to, 'callback':onNewItemReleased}\n\nclass MagazineSubscriber\n\tonNewMagazine: (item) ->\n\t\talert \"I've got new \"+item\n\nclass NewspaperSubscriber\n\tonNewNewspaper: (item) ->\n\t\talert \"I've got new \"+item\n\npostOffice = new PostOffice()\nsub1 = new MagazineSubscriber()\nsub2 = new NewspaperSubscriber()\npostOffice.subscribe \"Mens Health\", sub1.onNewMagazine\npostOffice.subscribe \"Times\", sub2.onNewNewspaper\npostOffice.notifyNewItemReleased \"Times\"\npostOffice.notifyNewItemReleased \"Mens Health\"\n\n{% endhighlight %}\n\n## Discussion\n\nHere you have an observer object (PostOffice) and observable objects (MagazineSubscriber, NewspaperSubscriber).\nTo be notified about an event of publishing new periodical observable object should make subscription on PostOffice.\nEvery of subscribed objects is stored internally in the PostOffice array of subscriptions.\nEvery subscriber is notified on new concrete periodical is published.\n"
  },
  {
    "path": "chapters/design_patterns/singleton.md",
    "content": "---\nlayout: recipe\ntitle: Singleton Pattern\nchapter: Design Patterns\n---\n## Problem\n\nMany times you only want one, and only one, instance of a class. For example, you may only need one class that creates server resources and you want to ensure that the one object can control those resources. Beware, however, because the singleton pattern can be easily abused to mimic unwanted global variables.\n\n\n## Solution\n\nThe publicly available class only contains the method to get the one true instance. The instance is kept within the closure of that public object and is always returned.\n\nThis works because CoffeeScript allows you to define executable statements inside a class definition. However, because most CoffeeScript compiles into a [IIFE][] wrapper you do not have to place the private class inside the class definition if this style suits you. The later might be useful when developing modular code such as found in [CommonJS][] (Node.js) or [Require.js][] (See the discussion for an example).\n\n[IIFE]: http://benalman.com/news/2010/11/immediately-invoked-function-expression/\n[CommonJS]: http://www.commonjs.org/\n[Require.js]: http://requirejs.org/\n\n{% highlight coffeescript %}\nclass Singleton\n  # You can add statements inside the class definition\n  # which helps establish private scope (due to closures)\n  # instance is defined as null to force correct scope\n  instance = null\n  # Create a private class that we can initialize however\n  # defined inside this scope to force the use of the\n  # singleton class.\n  class PrivateClass\n    constructor: (@message) ->\n    echo: -> @message\n  # This is a static method used to either retrieve the\n  # instance or create a new one.\n  @get: (message) ->\n    instance ?= new PrivateClass(message)\n\na = Singleton.get \"Hello A\"\na.echo() # => \"Hello A\"\n\nb = Singleton.get \"Hello B\"\nb.echo() # => \"Hello A\"\n\nSingleton.instance # => undefined\na.instance # => undefined\nSingleton.PrivateClass # => undefined\n{% endhighlight %}\n\n\n## Discussion\n\nSee in the above example how all instances are outputting from the same instance of the Singleton class. You can also see that the PrivateClass and instance variable are not accessible outside the Singleton class. In essence the Singleton class provides a static method get which returns only one instance of PrivateClass and only one. It also hides the PrivateClass from the world so that you can not create your own.\n\nThe idea of hiding or making private the inner workings is preference. Especially since by default CoffeeScript wraps the compiled code inside it's own IIFE (closure) allowing you to define classes without worry that it might be accessible from outside the file. In this example, note that I am using the idiomatic module export feature to emphasize the publicly accessible portion of the module. (See this discussion for further explanation on [exporting to the global namespace][1]).\n\n[1]: http://stackoverflow.com/questions/4214731/coffeescript-global-variables\n\n{% highlight coffeescript %}\nroot = exports ? this\n\n# Create a private class that we can initialize however\n# defined inside the wrapper scope.\nclass ProtectedClass\n  constructor: (@message) ->\n  echo: -> @message\n\nclass Singleton\n  # You can add statements inside the class definition\n  # which helps establish private scope (due to closures)\n  # instance is defined as null to force correct scope\n  instance = null\n  # This is a static method used to either retrieve the\n  # instance or create a new one.\n  @get: (message) ->\n    instance ?= new ProtectedClass(message)\n\n# Export Singleton as a module\nroot.Singleton = Singleton\n{% endhighlight %}\n\nNote how incredibly simple coffeescript makes this design pattern. For reference and discussion on nice javascript implementations, check out [Essential JavaScript Design Patterns For Beginners](http://addyosmani.com/resources/essentialjsdesignpatterns/book/).\n"
  },
  {
    "path": "chapters/design_patterns/strategy.md",
    "content": "---\nlayout: recipe\ntitle: Strategy Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou have more than one way to solve a problem but you need to choose (or even switch) between these methods at run time.\n\n## Solution\n\nEncapsulate your algorithms inside of Strategy objects.\n\nGiven an unsorted list, for example, we can change the sorting algorithm under different circumstances.\n\n###The base class:\n\n{% highlight coffeescript %}\nStringSorter = (algorithm) ->\n    sort: (list) -> algorithm list\n{% endhighlight %}\n\n###The strategies:\n\n{% highlight coffeescript %}\nbubbleSort = (list) ->\n    anySwaps = false\n    swapPass = ->\n        for r in [0..list.length-2]\n            if list[r] > list[r+1]\n                anySwaps = true\n                [list[r], list[r+1]] = [list[r+1], list[r]]\n\n    swapPass()\n    while anySwaps\n        anySwaps = false\n        swapPass()\n    list\n\nreverseBubbleSort = (list) ->\n    anySwaps = false\n    swapPass = ->\n        for r in [list.length-1..1]\n            if list[r] < list[r-1]\n                anySwaps = true\n                [list[r], list[r-1]] = [list[r-1], list[r]]\n\n    swapPass()\n    while anySwaps\n        anySwaps = false\n        swapPass()\n    list\n{% endhighlight %}\n\n###Using the strategies:\n\n{% highlight coffeescript %}\nsorter = new StringSorter bubbleSort\n\nunsortedList = ['e', 'b', 'd', 'c', 'x', 'a']\n\nsorter.sort unsortedList\n\n# => ['a', 'b', 'c', 'd', 'e', 'x']\n\nunsortedList.push 'w'\n\n# => ['a', 'b', 'c', 'd', 'e', 'x', 'w']\n\nsorter.algorithm = reverseBubbleSort\n\nsorter.sort unsortedList\n\n# => ['a', 'b', 'c', 'd', 'e', 'w', 'x']\n{% endhighlight %}\n\n## Discussion\n\n\"No plan survives first contact with the enemy\", nor users, but we can use the knowledge gained from changing circumstances to adapt.  Near the end of the example, for instance, the newest item in the array now lies out of order.  Knowing that detail, we can then speed the sort up by switching to an algorithm optimized for that exact scenario with nothing but a simple reassignment.\n\n### Exercises\n\n* Expand `StringSorter` into an `AlwaysSortedArray` class that implements all of the functionality of a regular array but which automatically sorts new items based on the method of insertion (e.g. `push` vs. `shift`).\n"
  },
  {
    "path": "chapters/design_patterns/template_method.md",
    "content": "---\nlayout: recipe\ntitle: Template Method Pattern\nchapter: Design Patterns\n---\n## Problem\n\nDefine the structure of an algorithm as a series of high-level steps, making it possible to specify the behaviour of each step, giving rise to a family of algorithms that have the same structure but different behaviours.\n\n## Solution\n\nUse the Template Method to describe the algorithm structure in a superclass, delegating the implementation of some steps to one or more concrete subclasses.\n\nFor example, imagine you wish to model the production of various types of document and each one may contain a header and a body.\n\n{% highlight coffeescript %}\nclass Document\n\tproduceDocument: ->\n\t\t@produceHeader()\n\t\t@produceBody()\n\n\tproduceHeader: ->\n\tproduceBody: ->\n\nclass DocWithHeader extends Document\n\tproduceHeader: ->\n\t\tconsole.log \"Producing header for DocWithHeader\"\n\n\tproduceBody: ->\n\t\tconsole.log \"Producing body for DocWithHeader\"\n\nclass DocWithoutHeader extends Document\n\tproduceBody: ->\n\t\tconsole.log \"Producing body for DocWithoutHeader\"\n\ndocs = [new DocWithHeader, new DocWithoutHeader]\ndoc.produceDocument() for doc in docs\n{% endhighlight %}\n\n## Discussion\n\nIn this example, the algorithm consists of two steps describing document production: one for producing a document header and the second for producing the document body. An empty method implementation for each step is present in the superclass and polymorphism is exploited such that each concrete subclass can provide a different implementation for a step by overriding a step method. In this example,the DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only implements the body step.\n\nThe production of different types of document is then straightforward when document objects are stored in an array, and it is then a simple of matter of iterating over each document object and calling its produceDocument method."
  },
  {
    "path": "chapters/functions/debounce.md",
    "content": "---\nlayout: recipe\ntitle: Debounce Functions\nchapter: Functions\n---\n## Problem\n\nYou want to execute a function only once, coalescing multiple sequential calls into a single execution at the beginning or end.\n\n## Solution\n\nWith a named function:\n\n{% highlight coffeescript %}\ndebounce: (func, threshold, execAsap) ->\n  timeout = null\n  (args...) ->\n    obj = this\n    delayed = ->\n      func.apply(obj, args) unless execAsap\n      timeout = null\n    if timeout\n      clearTimeout(timeout)\n    else if (execAsap)\n      func.apply(obj, args)\n    timeout = setTimeout delayed, threshold || 100\n{% endhighlight %}\n\n{% highlight coffeescript %}\nmouseMoveHandler: (e) ->\n  @debounce((e) ->\n    # Do something here, but only once 300 milliseconds after the mouse cursor stops.\n  300)\n\nsomeOtherHandler: (e) ->\n  @debounce((e) ->\n    # Do something here, but only once 250 milliseconds after initial execution.\n  250, true)\n{% endhighlight %}\n\n## Discussion\n\nLearn about [debouncing JavaScript methods](http://unscriptable.com/2009/03/20/debouncing-javascript-methods/) at John Hann's excellent blog article.\n\n"
  },
  {
    "path": "chapters/functions/index.html",
    "content": "---\nlayout: chapter\ntitle: Functions\nchapter: Functions\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/functions/parentheses.md",
    "content": "---\nlayout: recipe\ntitle: When Function Parentheses Are Not Optional\nchapter: Functions\n---\n## Problem\n\nYou want to call a function that takes no arguments, but don't want to use parentheses.\n\n## Solution\n\nUse parentheses anyway.\n\nAnother alternative is to utilize the do-notation like so:\n\n{% highlight coffeescript %}\nnotify = -> alert \"Hello, user!\"\ndo notify if condition\n{% endhighlight %}\n\nThis compiles to the following JavaScript:\n\n{% highlight javascript %}\nvar notify;\nnotify = function() {\n\treturn alert(\"Hello, user!\");\n};\nif (condition) {\n\tnotify();\n}\n{% endhighlight %}\n\n## Discussion\n\nLike Ruby, CoffeeScript allows you to drop parentheses to method calls. Unlike Ruby, however, CoffeeScript treats a bare function name as the pointer to the function. The practical upshot of this is that if you give no arguments to a method, CoffeeScript cannot tell if you want to call the function or use it as a reference.\n\nIs this good or bad? It's just different. It creates an unexpected syntax case -- parentheses aren't _always_ optional -- but in exchange it gives you the ability to pass and receive functions fluently by name, something that's a bit clunky in Ruby.\n\nThis usage of the do-notation is a neat approach for CoffeeScript with parenphobia.\nSome people simply prefer to write out the parentheses in the function call, though.\n"
  },
  {
    "path": "chapters/functions/recursion.md",
    "content": "---\nlayout: recipe\ntitle: Recursive Functions\nchapter: Functions\n---\n## Problem\n\nYou want to call a function from within that same function.\n\n## Solution\n\nWith a named function:\n\n{% highlight coffeescript %}\nping = ->\n\tconsole.log \"Pinged\"\n\tsetTimeout ping, 1000\n{% endhighlight %}\n\nWith an unnamed function, using @arguments.callee@:\n\n{% highlight coffeescript %}\ndelay = 1000\n\nsetTimeout((->\n\tconsole.log \"Pinged\"\n\tsetTimeout arguments.callee, delay\n\t), delay)\n{% endhighlight %}\n\n## Discussion\n\nWhile `arguments.callee` allows for the recursion of anonymous functions and might have the advantage in a very memory-intensive application, named functions keep their purpose more explicit and make for more maintainable code.\n"
  },
  {
    "path": "chapters/functions/splat_arguments.md",
    "content": "---\nlayout: recipe\ntitle: Splat Arguments\nchapter: Functions\n---\n## Problem\n\nYour function will be called with a varying number of arguments.\n\n## Solution\n\nUse _splats_.\n\n{% highlight coffeescript %}\nloadTruck = (firstDibs, secondDibs, tooSlow...) ->\n\ttruck:\n\t\tdriversSeat: firstDibs\n\t\tpassengerSeat: secondDibs\n\t\ttrunkBed: tooSlow\n\nloadTruck(\"Amanda\", \"Joel\")\n# => { truck: { driversSeat: \"Amanda\", passengerSeat: \"Joel\", trunkBed: [] } }\n\nloadTruck(\"Amanda\", \"Joel\", \"Bob\", \"Mary\", \"Phillip\")\n# => { truck: { driversSeat: \"Amanda\", passengerSeat: \"Joel\", trunkBed: [\"Bob\", \"Mary\", \"Phillip\"] } }\n{% endhighlight %}\n\nWith a trailing argument:\n\n{% highlight coffeescript %}\nloadTruck = (firstDibs, secondDibs, tooSlow..., leftAtHome) ->\n\ttruck:\n\t\tdriversSeat: firstDibs\n\t\tpassengerSeat: secondDibs\n\t\ttrunkBed: tooSlow\n\ttaxi:\n\t\tpassengerSeat: leftAtHome\n\nloadTruck(\"Amanda\", \"Joel\", \"Bob\", \"Mary\", \"Phillip\", \"Austin\")\n# => { truck: { driversSeat: 'Amanda', passengerSeat: 'Joel', trunkBed: [ 'Bob', 'Mary', 'Phillip' ] }, taxi: { passengerSeat: 'Austin' } }\n\nloadTruck(\"Amanda\")\n# => { truck: { driversSeat: \"Amanda\", passengerSeat: undefined, trunkBed: [] }, taxi: undefined }\n{% endhighlight %}\n\n## Discussion\n\nBy adding an ellipsis (`...`) next to no more than one of a function's arguments, CoffeeScript will combine all of the argument values not captured by other named arguments into a list.  It will serve up an empty list even if some of the named arguments were not supplied.\n"
  },
  {
    "path": "chapters/index.html",
    "content": "---\nlayout: default\ntitle: Cookbook\n---\n\n<article class=\"content-block\">\n\n  <h5 class=\"sidebar-title\">Chapters</h5>\n\n  <ol class=\"navigation chapters-list\">\n    {% for chapter in site.data.chapters %}\n      {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n      {% capture indexurl %}{{ url }}/index.html{% endcapture %}\n      <li class=\"chapter\">\n        <h4><a class=\"chapter-title\" href=\"{{ site.baseurl }}{{ url }}\">{{ chapter }}</a></h4>\n        <ul class=\"pseudo-list recipes-list\">\n          {% for page in site.pages %}\n            {% if page.url contains url %}\n              {% unless page.url == indexurl %}\n                <li class=\"list-item recipe\"><a class=\"recipe-title\" href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n              {% endunless %}\n            {% endif %}\n          {% endfor %}\n        </ul>\n      </li>\n    {% endfor %}\n  </ol>\n\n</article>\n"
  },
  {
    "path": "chapters/jquery/ajax.md",
    "content": "---\nlayout: recipe\ntitle: AJAX\nchapter: jQuery\n---\n## Problem\n\nYou want to make AJAX calls using jQuery.\n\n## Solution\n\n{% highlight coffeescript %}\n$ ?= require 'jquery' # For Node.js compatibility\n\n$(document).ready ->\n\t# Basic Examples\n\t$.get '/', (data) ->\n\t\t$('body').append \"Successfully got the page.\"\n\n\t$.post '/',\n\t\tuserName: 'John Doe'\n\t\tfavoriteFlavor: 'Mint'\n\t\t(data) -> $('body').append \"Successfully posted to the page.\"\n\n\t# Advanced Settings\n\t$.ajax '/',\n\t\ttype: 'GET'\n\t\tdataType: 'html'\n\t\terror: (jqXHR, textStatus, errorThrown) ->\n\t\t\t$('body').append \"AJAX Error: #{textStatus}\"\n\t\tsuccess: (data, textStatus, jqXHR) ->\n\t\t\t$('body').append \"Successful AJAX call: #{data}\"\n\n{% endhighlight %}\n\njQuery 1.5 and later have added a new, supplemental API for handling different callbacks.\n\n{% highlight coffeescript %}\n\trequest = $.get '/'\n\trequest.success (data) -> $('body').append \"Successfully got the page again.\"\n\trequest.error (jqXHR, textStatus, errorThrown) -> $('body').append \"AJAX Error: ${textStatus}.\"\n{% endhighlight %}\n\n## Discussion\n\nThe jQuery and $ variables can be used interchangeably. See also [Callback bindings]({{ site.baseurl }}/chapters/jquery/callback-bindings-jquery).\n"
  },
  {
    "path": "chapters/jquery/callback-bindings-jquery.md",
    "content": "---\nlayout: recipe\ntitle: Callback Bindings # using => instead of ->\nchapter: jQuery\n---\n## Problem\n\nYou want to bind a callback function to an object.\n\n## Solution\n\n{% highlight coffeescript %}\n$ ->\n  class Basket\n    constructor: () ->\n      @products = []\n\n      $('.product').click (event) =>\n        @add $(event.currentTarget).attr 'id'\n\n    add: (product) ->\n      @products.push product\n      console.log @products\n\n  new Basket()\n{% endhighlight %}\n\n## Discussion\n\nBy using the fat arrow (`=>`) instead of the normal arrow (`->`) the function gets\nautomatically bound to the object and can access the `@-variable`.\n"
  },
  {
    "path": "chapters/jquery/index.html",
    "content": "---\nlayout: chapter\ntitle: jQuery\nchapter: jQuery\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/jquery/plugin.md",
    "content": "---\nlayout: recipe\ntitle: Create a jQuery Plugin\nchapter: jQuery\n---\n## Problem\n\nYou'd like to create jQuery plugin using CoffeeScript\n\n## Solution\n\n{% highlight coffeescript %}\n# Reference jQuery\n$ = jQuery\n\n# Adds plugin object to jQuery\n$.fn.extend\n  # Change pluginName to your plugin's name.\n  pluginName: (options) ->\n    # Default settings\n    settings =\n      option1: true\n      option2: false\n      debug: false\n\n    # Merge default settings with options.\n    settings = $.extend settings, options\n\n    # Simple logger.\n    log = (msg) ->\n      console?.log msg if settings.debug\n\n    # _Insert magic here._\n    return @each ()->\n      log \"Preparing magic show.\"\n      # You can use your settings in here now.\n      log \"Option 1 value: #{settings.option1}\"\n{% endhighlight %}\n\n## Discussion\n\nHere are a couple of examples of how to use your new plugin.\n\n### JavaScript\n\n{% highlight javascript %}\n$(\"body\").pluginName({\n  debug: true\n});\n\n{% endhighlight %}\n\n### CoffeeScript:\n\n{% highlight coffeescript %}\n$(\"body\").pluginName\n  debug: true\n\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/math/constants.md",
    "content": "---\nlayout: recipe\ntitle: Math Constants\nchapter: Math\n---\n## Problem\n\nYou need to use common mathematical constants like pi or e.\n\n## Solution\n\nUse Javascript's Math object to provide commonly needed mathematical constants.\n\n{% highlight coffeescript %}\nMath.PI\n# => 3.141592653589793\n\n# Note: Capitalization matters! This produces no output, it's undefined.\nMath.Pi\n# =>\n\nMath.E\n# => 2.718281828459045\n\nMath.SQRT2\n# => 1.4142135623730951\n\nMath.SQRT1_2\n# => 0.7071067811865476\n\n# Natural log of 2. ln(2)\nMath.LN2\n# => 0.6931471805599453\n\nMath.LN10\n# => 2.302585092994046\n\nMath.LOG2E\n# => 1.4426950408889634\n\nMath.LOG10E\n# => 0.4342944819032518\n\n{% endhighlight %}\n\n## Discussion\n\nFor another example of how a math constant is used in a real world problem, refer to the [Converting Radians and Degrees]({{ site.baseurl }}/chapters/math/radians-degrees) section of this Math chapter.\n"
  },
  {
    "path": "chapters/math/fast-fibonacci.md",
    "content": "---\nlayout: recipe\ntitle: Faster Fibonacci Algorithm\nchapter: Math\n---\n## Problem\n\nYou would like to calculate a number N in the Fibonacci sequence but want\nto do it quickly.\n\n## Solution\n\nThe following solution (which can still be improved on) was originally\ntalked about on Robin Houston's blog.\n\nHere are a few links talking about the algorithm and ways to improve it:\n* [http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/](http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/)\n* [http://www.math.rutgers.edu/~erowland/fibonacci](http://www.math.rutgers.edu/~erowland/fibonacci.html)\n* [http://jsfromhell.com/classes/bignumber](http://jsfromhell.com/classes/bignumber)\n* [http://www.math.rutgers.edu/~erowland/fibonacci](http://www.math.rutgers.edu/~erowland/fibonacci.html)\n* [http://bigintegers.blogspot.com/2010/11/square-division-power-square-root](http://bigintegers.blogspot.com/2010/11/square-division-power-square-root.html)\n* [http://bugs.python.org/issue3451](http://bugs.python.org/issue3451)\n\nThis code is in gist form here:\n[https://gist.github.com/1032685](https://gist.github.com/1032685)\n\n{% highlight coffeescript %}\n###\nAuthor: Jason Giedymin <jasong _a_t_ apache -dot- org>\n        http://www.jasongiedymin.com\n        https://github.com/JasonGiedymin\n\nThis CoffeeScript Javascript Fast Fibonacci code is\nbased on the python code from Robin Houston's blog.\nSee below links.\n\nA few things I want to introduce in time are implementations of\nNewtonian, Burnikel / Ziegler, and Binet's algorithms on top\nof a Big Number framework.\n\nTodo:\n- https://github.com/substack/node-bigint\n- BZ and Newton mods.\n- Timing\n\n###\n\nMAXIMUM_JS_FIB_N = 1476\n\nfib_bits = (n) ->\n\t#Represent an integer as an array of binary digits.\n\n\tbits = []\n\twhile n > 0\n    \t[n, bit] = divmodBasic n, 2\n    \tbits.push bit\n\n  \tbits.reverse()\n  \treturn bits\n\nfibFast = (n) ->\n\t#Fast Fibonacci\n\n\tif n < 0\n\t\tconsole.log \"Choose an number >= 0\"\n\t\treturn\n\n\t[a, b, c] = [1, 0, 1]\n\n\tfor bit in fib_bits n\n\t    if bit\n\t    \t[a, b] = [(a+c)*b, b*b + c*c]\n\t    else\n\t    \t[a, b] = [a*a + b*b, (a+c)*b]\n\n\t    c = a + b\n\t  \treturn b\n\ndivmodNewton = (x, y) ->\n\tthrow new Error \"Method not yet implemented yet.\"\n\ndivmodBZ = () ->\n\tthrow new Error \"Method not yet implemented yet.\"\n\ndivmodBasic = (x, y) ->\n\t###\n\tAbsolutely nothing special here. Maybe later versions will be Newtonian or\n\tBurnikel / Ziegler _if_ possible...\n\t###\n\n\treturn [(q = Math.floor x/y), (r = if x < y then x else x % y)]\n\nstart = (new Date).getTime();\ncalc_value = fibFast(MAXIMUM_JS_FIB_N)\ndiff = (new Date).getTime() - start;\nconsole.log \"[#{calc_value}] took #{diff} ms.\"\n{% endhighlight %}\n\n## Discussion\n\nQuestions?\n"
  },
  {
    "path": "chapters/math/fast-inv-square.md",
    "content": "---\nlayout: recipe\ntitle: Fast Inverse Square Root\nchapter: Math\n---\n## Problem\n\nYou would like to calculate a the inverse square root of a number [quickly][5].\n\n## Solution\nAppearing in the Quake III Arena [source code][1], this strange algorithm uses\ninteger operations along with a 'magic number' to calculate floating point\napproximation values of inverse square roots.\n\nIn this CoffeeScript variant I supply the original classic, and newer optimal\n32 bit magic numbers found by [Chris Lomont][2]. Also supplied is the 64-bit\nsized magic number.\n\nAnother feature included is the ability to alter the level of precision.\nThis is done by controlling the number of iterations for performing [Newton's\nmethod][3].\n\nDepending on the machine and level of precision this algorithm may still\nprovide performance increases over the classic.\n\nTo run this, compile the script with coffee:\n    coffee -c script.coffee\n\nThen copy & paste the compiled js code in to the JavaScript console of your\nbrowser.\n\nNote: You will need a browser which supports [typed-arrays][4].\n\nReferences:\n1. [ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip](ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip)\n2. [http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf](http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf)\n3. [http://en.wikipedia.org/wiki/Newton%27s_method](http://en.wikipedia.org/wiki/Newton%27s_method)\n4. [https://developer.mozilla.org/en/JavaScript_typed_arrays](https://developer.mozilla.org/en/JavaScript_typed_arrays)\n5. [http://en.wikipedia.org/wiki/Fast_inverse_square_root](http://en.wikipedia.org/wiki/Fast_inverse_square_root)\n\n[1]: ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip \"ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip\"\n[2]: http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf \"http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf\"\n[3]: http://en.wikipedia.org/wiki/Newton%27s_method \"http://en.wikipedia.org/wiki/Newton%27s_method\"\n[4]: https://developer.mozilla.org/en/JavaScript_typed_arrays \"https://developer.mozilla.org/en/JavaScript_typed_arrays\"\n[5]: http://en.wikipedia.org/wiki/Fast_inverse_square_root \"http://en.wikipedia.org/wiki/Fast_inverse_square_root\"\n\nThis code is in gist form here:\n[https://gist.github.com/1036533](https://gist.github.com/1036533)\n\n{% highlight coffeescript %}\n###\n\nAuthor: Jason Giedymin <jasong _a_t_ apache -dot- org>\n        http://www.jasongiedymin.com\n        https://github.com/JasonGiedymin\n\nAppearing in the Quake III Arena source code[1], this strange algorithm uses\ninteger operations along with a 'magic number' to calculate floating point\napproximation values of inverse square roots[5].\n\nIn this CoffeeScript variant I supply the original classic, and newer optimal\n32 bit magic numbers found by Chris Lomont[2]. Also supplied is the 64-bit\nsized magic number.\n\nAnother feature included is the ability to alter the level of precision.\nThis is done by controlling the number of iterations for performing Newton's\nmethod[3].\n\nDepending on the machine and level of precision this algorithm may still\nprovide performance increases over the classic.\n\nTo run this, compile the script with coffee:\n    coffee -c <this script>.coffee\n\nThen copy & paste the compiled js code in to the JavaScript console of your\nbrowser.\n\nNote: You will need a browser which supports typed-arrays[4].\n\nReferences: \n[1] ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip\n[2] http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf\n[3] http://en.wikipedia.org/wiki/Newton%27s_method\n[4] https://developer.mozilla.org/en/JavaScript_typed_arrays\n[5] http://en.wikipedia.org/wiki/Fast_inverse_square_root\n\n###\n\napprox_const_quake_32 = 0x5f3759df # See [1]\napprox_const_32 = 0x5f375a86 # See [2]\napprox_const_64 = 0x5fe6eb50c7aa19f9 # See [2]\n\nfastInvSqrt_typed = (n, precision=1) ->\n\t# Using typed arrays. Right now only works in browsers.\n\t# Node.JS version coming soon.\n\n    y = new Float32Array(1)\n    i = new Int32Array(y.buffer)\n\n    y[0] = n\n    i[0] = 0x5f375a86 - (i[0] >> 1)\n    \n    for iter in [1...precision]\n        y[0] = y[0] * (1.5 - ((n * 0.5) * y[0] * y[0]))\n    \n    return y[0]\n\n### Sample single runs ###\ntestSingle = () ->\n    example_n = 10\n\n    console.log(\"Fast InvSqrt of 10, precision 1: #{fastInvSqrt_typed(example_n)}\")\n    console.log(\"Fast InvSqrt of 10, precision 5: #{fastInvSqrt_typed(example_n, 5)}\")\n    console.log(\"Fast InvSqrt of 10, precision 10: #{fastInvSqrt_typed(example_n, 10)}\")\n    console.log(\"Fast InvSqrt of 10, precision 20: #{fastInvSqrt_typed(example_n, 20)}\")\n    console.log(\"Classic of 10: #{1.0 / Math.sqrt(example_n)}\")\n\ntestSingle()\n\n{% endhighlight %}\n\n## Discussion\n\nQuestions?\n"
  },
  {
    "path": "chapters/math/generating-predictable-random-numbers.md",
    "content": "---\nlayout: recipe\ntitle: Generating Predictable Random Numbers\nchapter: Math\n---\n## Problem\n\nYou need to generate a random number in a certain range, but you also need to be able to \"seed\" the generator to deliver predictable values.\n\n## Solution\n\nWrite your own random number generator. There are a LOT of ways to do this. Here's a simple one. _This generator is +ABSOLUTELY NOT+ acceptable for cryptographic purposes!_\n\n{% highlight coffeescript %}\nclass Rand\n  # if created without a seed, uses current time as seed\n  constructor: (@seed) ->\n    # Knuth and Lewis' improvements to Park and Miller's LCPRNG\n    @multiplier = 1664525\n    @modulo = 4294967296 # 2**32-1;\n    @offset = 1013904223\n    unless @seed? && 0 <= seed < @modulo\n      @seed = (new Date().valueOf() * new Date().getMilliseconds()) % @modulo\n\n  # sets new seed value\n  seed: (seed) ->\n    @seed = seed\n\n  # return a random integer 0 <= n < @modulo\n  randn: ->\n    # new_seed = (a * seed + c) % m\n    @seed = (@multiplier*@seed + @offset) % @modulo\n\n # return a random float 0 <= f < 1.0\n  randf: ->\n    this.randn() / @modulo\n\n  # return a random int 0 <= f < n\n  rand: (n) ->\n    Math.floor(this.randf() * n)\n\n  # return a random int min <= f < max\n  rand2: (min, max) ->\n    min + this.rand(max-min)\n{% endhighlight %}\n\n## Discussion\n\nJavaScript and CoffeeScript do not provide a seedable random number generator. Writing your own will be an exercise in trading off the amount of randomness with the simplicity of the generator. A full discussion of randomness is beyond the scope of this cookbook; for further reading consult Donald Knuth's _The Art of Computer Programming_, Volume II, Chapter 3, \"Random Numbers\", and _Numerical Recipes in C_, 2nd Edition, Chapter 7, \"Random Numbers\".\n\nA brief explanation of this random number generator is in order, however. It is a Linear Congruential Pseudorandom Number Generator. LCPRNG's operate on the mathematical formula `I<sub>j+1</sub> = (aI<sub>j</sub>+c) % m`, where a is the multiplier, c is the addition offset, and m is the modulus.\n Each time a random number is requested, a very large multiplication and addition are performed -- \"very large\" relative to the key space -- and the resulting number is modulused back down into the keyspace.\n\nThis generator has a period of 2<sup>32</sup>. It is absolutely unacceptable for cryptographic purposes, but for most simple randomness requirements it is quite adequate. `randn()` will traverse the entire keyspace before repeating itself, and the next number is determined by the previous one.\n\nIf you want to tinker with this generator, you are _strongly_ encouraged to read Chapter 3 of Knuth's _The Art of Computer Programming_. Random number generation is VERY easy to screw up, and Knuth explains how to tell a good RNG from a bad one.\n\nAvoid the temptation to modulus the output of this generator. If you need an integer range, use division. Linear Congruential generators are very nonrandom in their lower bits. This one in particular always generates an odd number from an even seed, and vice versa. So if you need a random 0 or 1, do NOT use\n\n{% highlight coffeescript %}\n# NOT random! Do not do this!\nr.randn() % 2\n{% endhighlight %}\n\nbecause you will most definitely not get random digits. Use `r.rand(2)` instead.\n"
  },
  {
    "path": "chapters/math/generating-random-numbers.md",
    "content": "---\nlayout: recipe\ntitle: Generating Random Numbers\nchapter: Math\n---\n## Problem\n\nYou need to generate a random number in a certain range.\n\n## Solution\n\nUse JavaScript's Math.random() to get floating-point numbers from 0 <= x < 1.0. Use multiplication and Math.floor to get a number in a certain range.\n\n{% highlight coffeescript %}\nprobability = Math.random()\n0.0 <= probability < 1.0\n# => true\n\n# Note that percentile does NOT ever reach 100. A full range of 0 to 100 is actually a span of 101.\npercentile = Math.floor(Math.random() * 100)\n0 <= percentile < 100\n# => true\n\ndice = Math.floor(Math.random() * 6) + 1\n1 <= dice <= 6\n# => true\n\nmax = 42\nmin = -13\nrange = Math.random() * (max - min) + min\n-13 <= range < 42\n# => true\n{% endhighlight %}\n\n## Discussion\n\nThis is a straight lift from JavaScript.\n\nNote that JavaScript's Math.random() does not allow you to seed the random number generator to force certain values. See [Generating Predictable Random Numbers]({{ site.baseurl }}/chapters/math/generating-predictable-random-numbers) for that.\n\nTo generate a number from 0 up to (but not including) n, multiply by n. To generate a number from 1 to n (inclusive), multiply by n and add 1.\n"
  },
  {
    "path": "chapters/math/index.html",
    "content": "---\nlayout: chapter\ntitle: Math\nchapter: Math\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/math/radians-degrees.md",
    "content": "---\nlayout: recipe\ntitle: Converting Radians and Degrees\nchapter: Math\n---\n## Problem\n\nYou need to convert between radians and degrees.\n\n## Solution\n\nUse Javascript's Math.PI and a simple formula to convert between the two.\n\n{% highlight coffeescript %}\n# To convert from radians to degrees\nradiansToDegrees = (radians) ->\n    degrees = radians * 180 / Math.PI\n\nradiansToDegrees(1)\n# => 57.29577951308232\n\n# To convert from degrees to radians\ndegreesToRadians = (degrees) ->\n    radians = degrees * Math.PI / 180\n\ndegreesToRadians(1)\n# => 0.017453292519943295\n{% endhighlight %}\n\n## Discussion\n\nQuestions?\n"
  },
  {
    "path": "chapters/math/random-integer.md",
    "content": "---\nlayout: recipe\ntitle: A Random Integer Function\nchapter: Math\n---\n## Problem\n\nYou'd like to get a random integer between two integers, inclusive.\n\n## Solution\n\nUse the following function.\n\n{% highlight coffeescript %}\nrandomInt = (lower, upper) ->\n  [lower, upper] = [0, lower]     unless upper?           # Called with one argument\n  [lower, upper] = [upper, lower] if lower > upper        # Lower must be less then upper\n  Math.floor(Math.random() * (upper - lower + 1) + lower) # Last statement is a return value\n\n(randomInt(1) for i in [0...10])\n# => [0,1,1,0,0,0,1,1,1,0]\n\n(randomInt(1, 10) for i in [0...10])\n# => [7,3,9,1,8,5,4,10,10,8]\n{% endhighlight %}\n\n## Discussion\n\nQuestions?\n"
  },
  {
    "path": "chapters/math/working-with-exponents-and-logarithms.md",
    "content": "---\nlayout: recipe\ntitle: Working with Exponents and Logarithms\nchapter: Math\n---\n## Problem\n\nYou need to do some calculations that involve exponents and logarithms.\n\n## Solution\n\nUse Javascript's Math object to provide common mathematical functions.\n\n{% highlight coffeescript %}\n# Math.pow(x, y) returns x^y\nMath.pow(2, 4)\n# => 16\n\n# Math.exp(x) returns E^x and is shorthand for Math.pow(Math.E, x)\nMath.exp(2)\n# => 7.38905609893065\n\n# Math.log returns the natural (base E) log\nMath.log(5)\n# => 1.6094379124341003\nMath.log(Math.exp(42))\n# => 42\n\n# To get a log with some other base n, divide by Math.log(n)\nMath.log(100) / Math.log(10)\n# => 2\n\n{% endhighlight %}\n\n## Discussion\n\nFor more information on the Math object see the documentation on the [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math). Also refer to [Math Constants]({{ site.baseurl }}/chapters/math/constants) for discussion of the various constants in the Math object.\n"
  },
  {
    "path": "chapters/metaprogramming/detecting-and-replacing-functions.md",
    "content": "---\nlayout: recipe\ntitle: Detecting and Creating Missing Functions\nchapter: Metaprogramming\n---\n## Problem\n\nYou want to detect if a function exists and create it if it does not (such as an ECMAScript 5 function in Internet Explorer 8).\n\n## Solution\n\nUse the existential assignment operator (`?=`) to assign a function to the classes' prototype (using the `::` shorthand), and wrap it all in a IIFE (`do ->`) to contain the variables.\n\n{% highlight coffeescript %}\ndo -> Array::filter ?= (callback) ->\n  element for element in this when callback element\n\narray = [1..10]\n\narray.filter (x) -> x > 5\n# => [6,7,8,9,10]\n{% endhighlight %}\n\n## Discussion\n\nObjects in JavaScript (and thus, in CoffeeScript) have a prototype member that defines what member functions should be available on all objects based on that prototype.  \nIn Coffeescript, you access this prototype using the `::` shortcut. So, if you want to add a filter function to the array class, you do `Array::filter = ...`. This will add the filter function to all arrays.\n\nHowever, we don't ever want to overwrite a prototype that we haven't created in the first place. For example, if `Array::filter` already exists in a fast native form in the browser, or a library maker has their own specific version of `Array::filter`, then you'll either replace the quick native version with a slow Javascript version, or you will break the library that depends on their own Array::shuffle.  \nWhat you need to do is only add the function if it doesn't already exist. That's where the existential assignment operator (`?=`) comes in. If we do `Array::filter ?= ...` instead, it will see if `Array::filter` already exists. If it does, then it will use the current version. If it doesn't, it will add yours.\n\nFinally, because the existential assignment operator--when compiled--creates a few variables, we clean up the code by wrapping it in an [Immediately-Invoked Function Expression (IIFE)](http://benalman.com/news/2010/11/immediately-invoked-function-expression/). This hides those internal-use-only variables from leaking outside. So, if the function we're writing already exists, it runs, does basically nothing, and exits, affecting absolutely none of your code. But, if the function we're writing *doesn't* exist, we send out only the function we're writing as a closure, so only the function you've made affects the code. The internal workings of `?=` are hidden either way.\n\n### Example\n\nBelow, we've compiled and annotated the coffeescript written in the solution above\n\n{% highlight javascript %}\n// (function(){ ... })() is an IIFE, compiled in thanks to `do ->`\n(function() {\n\n  // This is from the `?=` operator, used to check if Array.prototype.filter (`Array::filter`) exists.\n  // If it does, we set it to itself, and return. If it doesn't, then we set it to the function, and return the function.\n  // The IIFE is only used to hide _base and _ref from the outside world.\n  var _base, _ref;\n  return (_ref = (_base = Array.prototype).filter) != null ? _ref : _base.filter = function(callback) {\n\n    // `element for element in this when callback element`\n    var element, _i, _len, _results;\n    _results = [];\n    for (_i = 0, _len = this.length; _i < _len; _i++) {\n      element = this[_i];\n      if (callback(element)) {\n        _results.push(element);\n      }\n    }\n    return _results;\n    \n  };\n// The end of the IIFE from `do ->`\n})();\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/metaprogramming/extending-built-in-objects.md",
    "content": "---\nlayout: recipe\ntitle: Extending Built-in Objects\nchapter: Metaprogramming\n---\n## Problem\n\nYou want to extend a class to add new functionality or replace old.\n\n## Solution\n\nUse `::` to assign your new function to the prototype of the object or class.\n\n{% highlight coffeescript %}\nString::capitalize = () ->\n  (this.split(/\\s+/).map (word) -> word[0].toUpperCase() + word[1..-1].toLowerCase()).join ' '\n\n\"foo bar     baz\".capitalize()\n# => 'Foo Bar Baz'\n{% endhighlight %}\n\n## Discussion\n\nObjects in JavaScript (and thus, in CoffeeScript) have a prototype member that defines what member functions should be available on all objects based on that prototype. In CoffeeScript, you can access the prototype directly via the `::` operator.\n\n**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-native-builtins/)).\n"
  },
  {
    "path": "chapters/metaprogramming/index.html",
    "content": "---\nlayout: chapter\ntitle: Metaprogramming\nchapter: Metaprogramming\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/networking/basic-client.md",
    "content": "---\nlayout: recipe\ntitle: Basic Client\nchapter: Networking\n---\n## Problem\n\nYou want to access a service provided over the network.\n\n## Solution\n\nCreate a basic TCP client.\n\n### In Node.js\n\n{% highlight coffeescript %}\nnet = require 'net'\n\ndomain = 'localhost'\nport = 9001\n\nconnection = net.createConnection port, domain\n\nconnection.on 'connect', () ->\n\tconsole.log \"Opened connection to #{domain}:#{port}.\"\n\nconnection.on 'data', (data) ->\n\tconsole.log \"Received: #{data}\"\n\tconnection.end()\n{% endhighlight %}\n\n### Example Usage\n\nAccessing the [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server):\n\n{% highlight console %}\n$ coffee basic-client.coffee\nOpened connection to localhost:9001\nReceived: Hello, World!\n{% endhighlight %}\n\n## Discussion\n\nThe most important work takes place in the _connection.on 'data'_ handler, where the client receives its response from the server and would most likely arrange for responses to it.\n\nSee also the [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server), [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client), and [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server) recipes.\n\n### Exercises\n\n* Add support for choosing the target domain and port based on command-line arguments or from a configuration file.\n"
  },
  {
    "path": "chapters/networking/basic-http-client.md",
    "content": "---\nlayout: recipe\ntitle: Basic HTTP Client\nchapter: Networking\n---\n\n## Problem\n\nYou want to create a HTTP client.\n\n## Solution\n\nIn this recipe, we'll use [node.js](http://nodejs.org/)'s HTTP library. We'll go from a simple GET request example to a client which returns the external IP of a computer.\n\n### GET something\n\n{% highlight coffeescript %}\nhttp = require 'http'\n\nhttp.get { host: 'www.google.com' }, (res) ->\n    console.log res.statusCode\n{% endhighlight %}\n\nThe `get` function, from node.js's `http` module, issues a GET request to a HTTP server. The response comes in the form of a callback, which we can handle in a function. This example merely prints the response status code. Check it out:\n\n{% highlight console %}\n$ coffee http-client.coffee \n200\n\n{% endhighlight %}\n\n### What's my IP?\n\nIf you are inside a network which relies on [NAT](http://en.wikipedia.org/wiki/Network_address_translation) such as a LAN, you probably have faced the issue of finding out what's your external IP address. Let's write a small coffeescript for this.\n\n{% highlight coffeescript %}\nhttp = require 'http'\n\nhttp.get { host: 'checkip.dyndns.org' }, (res) ->\n    data = ''\n    res.on 'data', (chunk) ->\n        data += chunk.toString()\n    res.on 'end', () ->\n        console.log data.match(/([0-9]+\\.){3}[0-9]+/)[0]\n{% endhighlight %}\n\nWe can get the data from the result object by listening on its `'data'` event; and know that it has come to an end once the `'end'` event has been fired. When that happens, we can do a simple regular expression match to extract our IP address. Try it:\n\n{% highlight console %}\n$ coffee http-client.coffee \n123.123.123.123\n{% endhighlight %}\n\n## Discussion\n\nNote that `http.get` is a shortcut of `http.request`. The latter allows you to issue HTTP requests with different methods, such as POST or PUT.\n\nFor API and overall information on this subject, check node.js's [http](http://nodejs.org/docs/latest/api/http.html) and [https](http://nodejs.org/docs/latest/api/https.html) documentation pages. Also, the [HTTP spec](http://www.ietf.org/rfc/rfc2616.txt) might come in handy.\n\n### Exercises\n\n* Create a client for the key-value store HTTP server, from the [Basic HTTP Server](basic-http-server) recipe.\n\n"
  },
  {
    "path": "chapters/networking/basic-http-server.md",
    "content": "---\nlayout: recipe\ntitle: Basic HTTP Server\nchapter: Networking\n---\n\n## Problem\n\nYou want to create a HTTP server over a network. Over the course of this recipe, we'll go step by step from the smallest server possible to a functional key-value store.\n\n## Solution\n\nWe'll use [node.js](http://nodejs.org/)'s HTTP library to our own selfish purposes and create the simplest web server possible in Coffeescript.\n\n### Say 'hi\\n'\n\nWe can start by importing node.js's HTTP module. This contains `createServer` which, given a simple request handler, returns a HTTP server. We can use that server to listen on a TCP port.\n\n{% highlight coffeescript %}\nhttp = require 'http'\nserver = http.createServer (req, res) -> res.end 'hi\\n'\nserver.listen 8000\n{% endhighlight %}\n\nTo run this example, simply put in a file and run it. You can kill it with `Ctrl-C`. We can test it using the `curl` command, available on most \\*nix platforms:\n\n{% highlight console %}\n$ curl -D - http://localhost:8000/\nHTTP/1.1 200 OK\nConnection: keep-alive\nTransfer-Encoding: chunked\n\nhi\n{% endhighlight %}\n\n### What's going on? \n\nLet's get a little bit more feedback on what's happening on our server. While we're at it, we could also be friendlier to our clients and provide them some HTTP headers.\n\n{% highlight coffeescript %}\nhttp = require 'http'\n\nserver = http.createServer (req, res) ->\n    console.log req.method, req.url\n    data = 'hi\\n'\n    res.writeHead 200,\n        'Content-Type':     'text/plain'\n        'Content-Length':   data.length\n    res.end data\n\nserver.listen 8000\n{% endhighlight %}\n\nTry to access it once again, but this time use different URL paths, such as `http://localhost:8000/coffee`. You'll see something like this on the server console:\n\n{% highlight console %}\n$ coffee http-server.coffee \nGET /\nGET /coffee\nGET /user/1337\n{% endhighlight %}\n\n### GETting stuff\n\nWhat if our webserver was able to hold some data? We'll try to come up with a simple key-value store in which elements are retrievable via GET requests. Provide a key on the request path and the server will return the corresponding value &mdash; or 404 if it doesn't exist.\n\n{% highlight coffeescript %}\nhttp = require 'http'\n\nstore = # we'll use a simple object as our store\n    foo:    'bar'\n    coffee: 'script'\n\nserver = http.createServer (req, res) ->\n    console.log req.method, req.url\n    \n    value = store[req.url[1..]]\n\n    if not value\n        res.writeHead 404\n    else\n        res.writeHead 200,\n            'Content-Type': 'text/plain'\n            'Content-Length': value.length + 1\n        res.write value + '\\n'\n    \n    res.end()\n\nserver.listen 8000\n{% endhighlight %}\n\nWe can try several URLs to see how it responds:\n\n{% highlight console %}\n$ curl -D - http://localhost:8000/coffee\nHTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 7\nConnection: keep-alive\n\nscript\n\n$ curl -D - http://localhost:8000/oops\nHTTP/1.1 404 Not Found\nConnection: keep-alive\nTransfer-Encoding: chunked\n\n{% endhighlight %}\n\n### Use your head(ers)\n\nLet's face it, `text/plain` is kind of lame. How about if we use something hip like `application/json` or `text/xml`? Also, our store retrieval process could use a bit of refactoring &mdash; how about some exception throwing &amp; handling? Let's see what we can come up with:\n\n{% highlight coffeescript %}\nhttp = require 'http'\n\n# known mime types\n[any, json, xml] = ['*/*', 'application/json', 'text/xml']\n\n# gets a value from the db in format [value, contentType]\nget = (store, key, format) ->\n    value = store[key]\n    throw 'Unknown key' if not value\n    switch format\n        when any, json then [JSON.stringify({ key: key, value: value }), json]\n        when xml then [\"<key>#{ key }</key>\\n<value>#{ value }</value>\", xml]\n        else throw 'Unknown format'\n\nstore =\n    foo:    'bar'\n    coffee: 'script'\n\nserver = http.createServer (req, res) ->\n    console.log req.method, req.url\n    \n    try\n        key = req.url[1..]\n        [value, contentType] = get store, key, req.headers.accept\n        code = 200\n    catch error\n        contentType = 'text/plain'\n        value = error\n        code = 404\n \n    res.writeHead code,\n        'Content-Type': contentType\n        'Content-Length': value.length + 1\n    res.write value + '\\n'\n    res.end()\n\nserver.listen 8000\n{% endhighlight %}\n\nThis server will still return the value which matches a given key, or 404 if non-existent. But it will structure the response either in JSON or XML, according to the `Accept` header. See for yourself:\n\n{% highlight console %}\n$ curl http://localhost:8000/\nUnknown key\n\n$ curl http://localhost:8000/coffee\n{\"key\":\"coffee\",\"value\":\"script\"}\n\n$ curl -H \"Accept: text/xml\" http://localhost:8000/coffee\n<key>coffee</key>\n<value>script</value>\n\n$ curl -H \"Accept: image/png\" http://localhost:8000/coffee\nUnknown format\n{% endhighlight %}\n\n### You gotta give to get back\n\nThe obvious last step in our adventure is to provide the client the ability to store data. We'll keep our RESTiness by listening to POST requests for this purpose.\n\n{% highlight coffeescript %}\nhttp = require 'http'\n\n# known mime types\n[any, json, xml] = ['*/*', 'application/json', 'text/xml']\n\n# gets a value from the db in format [value, contentType]\nget = (store, key, format) ->\n    value = store[key]\n    throw 'Unknown key' if not value\n    switch format\n        when any, json then [JSON.stringify({ key: key, value: value }), json]\n        when xml then [\"<key>#{ key }</key>\\n<value>#{ value }</value>\", xml]\n        else throw 'Unknown format'\n\n# puts a value in the db\nput = (store, key, value) ->\n    throw 'Invalid key' if not key or key is ''\n    store[key] = value\n\nstore =\n    foo:    'bar'\n    coffee: 'script'\n\n# helper function that responds to the client\nrespond = (res, code, contentType, data) ->\n    res.writeHead code,\n        'Content-Type': contentType\n        'Content-Length': data.length\n    res.write data\n    res.end()\n\nserver = http.createServer (req, res) ->\n    console.log req.method, req.url\n    key = req.url[1..]\n    contentType = 'text/plain'\n    code = 404\n    \n    switch req.method\n        when 'GET'\n            try\n                [value, contentType] = get store, key, req.headers.accept\n                code = 200\n            catch error\n                value = error\n            respond res, code, contentType, value + '\\n'\n\n        when 'POST'\n            value = ''\n            req.on 'data', (chunk) -> value += chunk\n            req.on 'end', () ->\n                try\n                    put store, key, value\n                    value = ''\n                    code = 200\n                catch error\n                    value = error + '\\n'\n                respond res, code, contentType, value\n\nserver.listen 8000\n{% endhighlight %}\n\nNotice how the data is received in a POST request. By attaching some handlers on the `'data'` and `'end'` events of the request object, we're able to buffer and finally save the data from the client in the `store`.\n\n{% highlight console %}\n$ curl -D - http://localhost:8000/cookie\nHTTP/1.1 404 Not Found # ...\nUnknown key\n\n$ curl -D - -d \"monster\" http://localhost:8000/cookie\nHTTP/1.1 200 OK # ...\n\n$ curl -D - http://localhost:8000/cookie\nHTTP/1.1 200 OK # ...\n{\"key\":\"cookie\",\"value\":\"monster\"}\n{% endhighlight %}\n\n## Discussion\n\nGive `http.createServer` a function in the shape of `(request, response) -> ...` and it will return a server object, which we can use to listen on a port. Interact with the `request` and `response` objects to give the server its behaviour. Listen on port 8000 using `server.listen 8000`.\n\nFor API and overall information on this subject, check node.js's [http](http://nodejs.org/docs/latest/api/http.html) and [https](http://nodejs.org/docs/latest/api/https.html) documentation pages. Also, the [HTTP spec](http://www.ietf.org/rfc/rfc2616.txt) might come in handy.\n\n### Exercises\n\n* Create a layer in between the server and the developer which would allow the developer to do something like:\n\n{% highlight coffeescript %}\nserver = layer.createServer\n    'GET /': (req, res) ->\n        ...\n    'GET /page': (req, res) ->\n        ...\n    'PUT /image': (req, res) ->\n        ...\n{% endhighlight %}\n\n"
  },
  {
    "path": "chapters/networking/basic-server.md",
    "content": "---\nlayout: recipe\ntitle: Basic Server\nchapter: Networking\n---\n## Problem\n\nYou want to provide a service over a network.\n\n## Solution\n\nCreate a basic TCP server.\n\n### In Node.js\n\n{% highlight coffeescript %}\nnet = require 'net'\n\ndomain = 'localhost'\nport = 9001\n\nserver = net.createServer (socket) ->\n\tconsole.log \"Received connection from #{socket.remoteAddress}\"\n\tsocket.write \"Hello, World!\\n\"\n\tsocket.end()\n\nconsole.log \"Listening to #{domain}:#{port}\"\nserver.listen port, domain\n{% endhighlight %}\n\n### Example Usage\n\nAccessed by the [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client):\n\n{% highlight console %}\n$ coffee basic-server.coffee\nListening to localhost:9001\nReceived connection from 127.0.0.1\nReceived connection from 127.0.0.1\n[...]\n{% endhighlight %}\n\n## Discussion\n\nThe function passed to @net.createServer@ receives the new socket provided for each new connection to a client.  This basic server simply socializes with its visitors but a hard-working server would pass this socket along to a dedicated handler and then return to the task of waiting for the next client.\n\nSee also the [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client), [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server), and [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client) recipes.\n\n### Exercises\n\n* Add support for choosing the target domain and port based on command-line arguments or from a configuration file.\n"
  },
  {
    "path": "chapters/networking/bi-directional-client.md",
    "content": "---\nlayout: recipe\ntitle: Bi-Directional Client\nchapter: Networking\n---\n## Problem\n\nYou want to a persistent service over a network, one which maintains an on-going connection with its clients.\n\n## Solution\n\nCreate a bi-directional TCP client.\n\n### In Node.js\n\n{% highlight coffeescript %}\nnet = require 'net'\n\ndomain = 'localhost'\nport = 9001\n\nping = (socket, delay) ->\n\tconsole.log \"Pinging server\"\n\tsocket.write \"Ping\"\n\tnextPing = -> ping(socket, delay)\n\tsetTimeout nextPing, delay\n\nconnection = net.createConnection port, domain\n\nconnection.on 'connect', () ->\n\tconsole.log \"Opened connection to #{domain}:#{port}\"\n\tping connection, 2000\n\nconnection.on 'data', (data) ->\n\tconsole.log \"Received: #{data}\"\n\nconnection.on 'end', (data) ->\n\tconsole.log \"Connection closed\"\n\tprocess.exit()\n{% endhighlight %}\n\n### Example Usage\n\nAccessing the [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server):\n\n{% highlight console %}\n$ coffee bi-directional-client.coffee\nOpened connection to localhost:9001\nPinging server\nReceived: You have 0 peers on this server\nPinging server\nReceived: You have 0 peers on this server\nPinging server\nReceived: You have 1 peer on this server\n[...]\nConnection closed\n{% endhighlight %}\n\n## Discussion\n\nThis particular example initiates contact with the server and starts the conversation in the @connection.on 'connect'@ handler.  The bulk of the work in a real client, however, will lie in the @connection.on 'data'@ handler, which processes output from the server.  The @ping@  function only recurses in order to illustrate continuous communication with the server and can be removed from a real client.\n\nSee also the [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server), [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client), and [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server) recipes.\n\n### Exercises\n\n* Add support for choosing the target domain and port based on command-line arguments or from a configuration file.\n"
  },
  {
    "path": "chapters/networking/bi-directional-server.md",
    "content": "---\nlayout: recipe\ntitle: Bi-Directional Server\nchapter: Networking\n---\n## Problem\n\nYou want to provide a persistent service over a network, one which maintains an on-going connection with a client.\n\n## Solution\n\nCreate a bi-directional TCP server.\n\n### In Node.js\n\n{% highlight coffeescript %}\nnet = require 'net'\n\ndomain = 'localhost'\nport = 9001\n\nserver = net.createServer (socket) ->\n\tconsole.log \"New connection from #{socket.remoteAddress}\"\n\n\tsocket.on 'data', (data) ->\n\t\tconsole.log \"#{socket.remoteAddress} sent: #{data}\"\n\t\tothers = server.connections - 1\n\t\tsocket.write \"You have #{others} #{others == 1 and \"peer\" or \"peers\"} on this server\"\n\nconsole.log \"Listening to #{domain}:#{port}\"\nserver.listen port, domain\n{% endhighlight %}\n\n### Example Usage\n\nAccessed by the [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client):\n\n{% highlight console %}\n$ coffee bi-directional-server.coffee\nListening to localhost:9001\nNew connection from 127.0.0.1\n127.0.0.1 sent: Ping\n127.0.0.1 sent: Ping\n127.0.0.1 sent: Ping\n[...]\n{% endhighlight %}\n\n## Discussion\n\nThe bulk of the work lies in the @socket.on 'data'@ handler, which processes all of the input from the client.  A real server would likely pass the data onto another function to process it and generate any responses so that the original handler.\n\nSee also the [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client), [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client), and [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server) recipes.\n\n### Exercises\n\n* Add support for choosing the target domain and port based on command-line arguments or on a configuration file.\n"
  },
  {
    "path": "chapters/networking/index.html",
    "content": "---\nlayout: chapter\ntitle: Networking\nchapter: Networking\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/regular_expressions/heregexes.md",
    "content": "---\nlayout: recipe\ntitle: Using Heregexes\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to write a complex regular expression.\n\n## Solution\n\nUse Coffeescript's \"heregexes\" -- extended regular expressions that ignore internal whitespace and can contain comments.\n\n{% highlight coffeescript %}\npattern = ///\n  ^\\(?(\\d{3})\\)? # Capture area code, ignore optional parens\n  [-\\s]?(\\d{3})  # Capture prefix, ignore optional dash or space\n  -?(\\d{4})      # Capture line-number, ignore optional dash\n///\n[area_code, prefix, line] = \"(555)123-4567\".match(pattern)[1..3]\n# => ['555', '123', '4567']\n{% endhighlight %}\n\n## Discussion\n\nBreaking up your complex regular expressions and commenting key sections makes them a lot more decipherable and maintainable. For example, changing this regex to allow an optional space between the prefix and line number would now be fairly obvious.\n\n### Whitespace characters in heregexes\n\nWhitespace is ignored in heregexes -- so what do you do if you need to match a literal ASCII space?\n\nOne solution is to use the @\\s@ character class, which will match spaces, tabs\nand line breaks. If you only want to match a space, though, you'll need to use\n`\\x20` to denote a literal ASCII space.\n"
  },
  {
    "path": "chapters/regular_expressions/index.html",
    "content": "---\nlayout: chapter\ntitle: Regular Expressions\nchapter: Regular Expressions\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/regular_expressions/replacing-html-tags-with-html-named-entities.md",
    "content": "---\nlayout: recipe\ntitle: Replacing HTML Tags with HTML Named Entities\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to replace HTML tags with named entities:\n\n`<br/> => &lt;br/&gt;`\n\n## Solution\n\n{% highlight coffeescript %}\nhtmlEncode = (str) ->\n  str.replace /[&<>\"']/g, ($0) ->\n    \"&\" + {\"&\":\"amp\", \"<\":\"lt\", \">\":\"gt\", '\"':\"quot\", \"'\":\"#39\"}[$0] + \";\"\n\nhtmlEncode('<a href=\"http://bn.com\">Barnes & Noble</a>')\n# => '&lt;a href=&quot;http://bn.com&quot;&gt;Barnes &amp; Noble&lt;/a&gt;'\n{% endhighlight %}\n\n## Discussion\n\nThere are probably better ways to implement the above method.\n"
  },
  {
    "path": "chapters/regular_expressions/replacing-substrings.md",
    "content": "---\nlayout: recipe\ntitle: Replacing Substrings\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to replace a portion of a string with another value.\n\n## Solution\n\nUse the JavaScript `replace` method. `replace` matches with the given string, and returns the edited string.\n\nThe first version takes 2 arguments: _pattern_ and _string replacement_\n\n{% highlight coffeescript %}\n\"JavaScript is my favorite!\".replace /Java/, \"Coffee\"\n# => 'CoffeeScript is my favorite!'\n\n\"foo bar baz\".replace /ba./, \"foo\"\n# => 'foo foo baz'\n\n\"foo bar baz\".replace /ba./g, \"foo\"\n# => 'foo foo foo'\n{% endhighlight %}\n\nThe second version takes 2 arguments: _pattern_ and _callback function_\n\n{% highlight coffeescript %}\n\"CoffeeScript is my favorite!\".replace /(\\w+)/g, (match) ->\n  match.toUpperCase()\n# => 'COFFEESCRIPT IS MY FAVORITE!'\n{% endhighlight %}\n\nThe callback function is invoked for each match, and the match value is passed as the argument to the callback.\n\n## Discussion\n\nRegular Expressions are a powerful way to match and replace strings.\n"
  },
  {
    "path": "chapters/regular_expressions/searching-for-substrings.md",
    "content": "---\nlayout: recipe\ntitle: Searching for Substrings\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to search for a substring, and return either the starting position of the match or the matching value itself.\n\n## Solution\n\nThere are several ways to accomplish this using regular expressions. Some methods are called on a `RegExp` pattern or object and some are called on `String` objects.\n\n### `RegExp` objects\n\nThe first way is to call the `test` method on a `RegExp` pattern or object. The `test` method returns a boolean value:\n\n{% highlight coffeescript %}\nmatch = /sample/.test(\"Sample text\")\n# => false\n\nmatch = /sample/i.test(\"Sample text\")\n# => true\n{% endhighlight %}\n\nThe next way to is to call the `exec` method on a `RegExp` pattern or object. The `exec` method returns an array with the match information or `null`:\n\n{% highlight coffeescript %}\nmatch = /s(amp)le/i.exec \"Sample text\"\n# => [ 'Sample', 'amp', index: 0, input: 'Sample text' ]\n\nmatch = /s(amp)le/.exec \"Sample text\"\n# => null\n{% endhighlight %}\n\n### `String` objects\n\nThe `match` method matches a given string with the `RegExp`. With 'g' flag returns an array containing the matches, without 'g' flag returns just the first match or if no match is found returns `null`.\n\n{% highlight coffeescript %}\n\"Watch out for the rock!\".match(/r?or?/g)\n# => [ 'o', 'or', 'ro' ]\n\n\"Watch out for the rock!\".match(/r?or?/)\n# => [ 'o', index: 6, input: 'Watch out for the rock!' ]\n\n\"Watch out for the rock!\".match(/ror/)\n# => null\n{% endhighlight %}\n\nThe `search` method matches `RegExp` with string and returns the index of the beginning of the match if found, -1 if not.\n\n{% highlight coffeescript %}\n\"Watch out for the rock!\".search /for/\n# => 10\n\n\"Watch out for the rock!\".search /rof/\n# => -1\n{% endhighlight %}\n\n## Discussion\n\nRegular Expressions are a powerful way to test and match substrings.\n"
  },
  {
    "path": "chapters/strings/capitalizing-words.md",
    "content": "---\nlayout: recipe\ntitle: Capitalizing Words\nchapter: Strings\n---\n## Problem\n\nYou want to capitalize the first letter of every word in a string.\n\n## Solution\n\nUse the split, map, join pattern: Split the string into words, then use a map to capitalize the first letter and lowercase all other letters of each word before gluing the string back together with join.\n\n{% highlight coffeescript %}\n(\"foo bar baz\".split(' ').map (word) -> word[0].toUpperCase() + word[1..-1].toLowerCase()).join ' '\n# => 'Foo Bar Baz'\n{% endhighlight %}\n\nOr do the same thing using a list comprehension:\n\n{% highlight coffeescript %}\n(word[0].toUpperCase() + word[1..-1].toLowerCase() for word in \"foo   bar   baz\".split /\\s+/).join ' '\n# => 'Foo Bar Baz'\n{% endhighlight %}\n\n## Discussion\n\nSplit, map, join is a common scripting pattern dating back to Perl. This function may benefit from being placed directly onto the String class by [Extending Classes]({{ site.baseurl }}/chapters/objects/extending-classes).\n\nBe aware that two wrinkles can appear in the split, map, join pattern. The first is that the split text works best when it is constant. If the source string has multiple spaces in it, the split will need to take this into account to prevent getting extra, empty words. One way to do this is with a regular expression to split on runs of whitespace instead of a single space:\n\n{% highlight coffeescript %}\n(\"foo    bar    baz\".split(/\\s+/).map (word) -> word[0].toUpperCase() + word[1..-1].toLowerCase()).join ' '\n# => 'Foo Bar Baz'\n{% endhighlight %}\n\n...but this leads us to the second wrinkle: notice that the runs of whitespace are now compressed down to a single character by the join.\n\nQuite often one or both of these wrinkles is acceptable, however, so the split, map, join pattern can be a powerful tool.\n"
  },
  {
    "path": "chapters/strings/finding-substrings.md",
    "content": "---\nlayout: recipe\ntitle: Finding Substrings\nchapter: Strings\n---\n## Problem\n\nYou need to find the first or last occurrence of a search string within a message.\n\n## Solution\n\nUse Javascript's indexOf() and lastIndexOf() to find the first and last occurrences of a string, respectively.\nSyntax: string.indexOf searchstring, start\n\n{% highlight coffeescript %}\nmessage = \"This is a test string. This has a repeat or two. This might even have a third.\"\nmessage.indexOf \"This\", 0\n# => 0\n\n# Modifying the start parameter\nmessage.indexOf \"This\", 5\n# => 23\n\nmessage.lastIndexOf \"This\"\n# => 49\n\n# Count occurrences of a given string\nmessage.split(\" a \").length - 1\n# => 3\n\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/strings/generating-a-unique-id.md",
    "content": "---\nlayout: recipe\ntitle: Generating a Unique ID\nchapter: Strings\n---\n## Problem\n\nYou want to generate a random unique identifier.\n\n## Solution\n\nYou can create a Base 36 encoded string from a random number.\n\n{% highlight coffeescript %}\nuniqueId = (length=8) ->\n  id = \"\"\n  id += Math.random().toString(36).substr(2) while id.length < length\n  id.substr 0, length\n\nuniqueId()    # => n5yjla3b\nuniqueId(2)   # => 0d\nuniqueId(20)  # => ox9eo7rt3ej0pb9kqlke\nuniqueId(40)  # => xu2vo4xjn4g0t3xr74zmndshrqlivn291d584alj\n{% endhighlight %}\n\n## Discussion\n\nThere are other possible techniques, but this is relatively performant and flexible.\n"
  },
  {
    "path": "chapters/strings/index.html",
    "content": "---\nlayout: chapter\ntitle: Strings\nchapter: Strings\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/strings/interpolation.md",
    "content": "---\nlayout:   recipe\ntitle:    String Interpolation\nchapter:  Strings\n---\n## Problem\n\nYou want to create a string that contains a text representation of a\nCoffeeScript Variable.\n\n## Solution\n\nUse CoffeeScript's ruby-like string interpolation instead of\nJavaScript's string addition. You must use Double-quoted strings to \nallow for interpolation. Single-quoted strings are treated as literals.\n\nInterpolation:\n\n{% highlight coffeescript %}\nmuppet = \"Beeker\"\nfavorite = \"My favorite muppet is #{muppet}!\"\n\n# => \"My favorite muppet is Beeker!\"\n{% endhighlight %}\n\n{% highlight coffeescript %}\nsquare = (x) -> x * x\nmessage = \"The square of 7 is #{square 7}.\"\n\n# => \"The square of 7 is 49.\"\n{% endhighlight %}\n\n## Discussion\n\nCoffeeScript interpolates strings in similar fashion to ruby. Most\nexpressions are valid inside the `#{...}` interpolation syntax.\n\nCoffeeScript permits multiple expressions inside the interpolation\nwhich can have side effects, but this is discouraged. Only the last\nvalue will be returned.\n\n{% highlight coffeescript %}\n# You can do this, but don't. YOU WILL GO MAD.\nsquare = (x) -> x * x\nmuppet = \"Beeker\"\nmessage = \"The square of 10 is #{muppet='Animal'; square 10}. Oh, and your favorite muppet is now #{muppet}.\"\n\n# => \"The square of 10 is 100. Oh, and your favorite muppet is now Animal.\"\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/strings/lowercasing-a-string.md",
    "content": "---\nlayout: recipe\ntitle: Lowercasing a String\nchapter: Strings\n---\n## Problem\n\nYou want to lowercase a string.\n\n## Solution\n\nUse JavaScript's String toLowerCase() method:\n\n{% highlight coffeescript %}\n\"ONE TWO THREE\".toLowerCase()\n# => 'one two three'\n{% endhighlight %}\n\n## Discussion\n\n`toLowerCase()` is a standard JavaScript method. Don't forget the parentheses.\n\n### Syntax Sugar\n\nYou can add some Ruby-like syntax sugar with the following shortcut:\n\n{% highlight coffeescript %}\nString::downcase = -> @toLowerCase()\n\"ONE TWO THREE\".downcase()\n# => 'one two three'\n{% endhighlight %}\n\nThe snippet above demonstrates a few features of CoffeeScript:\n\n* The double-colon `::` is shorthand for saying `.prototype.`\n* The \"at\" sign `@` is shorthand for saying `this.`\n\nThe code above compiles in to the following JavaScript:\n\n{% highlight javascript %}\nString.prototype.downcase = function() {\n  return this.toLowerCase();\n};\n\"ONE TWO THREE\".downcase();\n{% endhighlight %}\n\n**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/))."
  },
  {
    "path": "chapters/strings/matching-strings.md",
    "content": "---\r\nlayout:   recipe\r\ntitle:    Matching Strings\r\nchapter:  Strings\r\n---\r\n## Problem\r\n\r\nYou want to match two or more strings.\r\n\r\n## Solution\r\n\r\nCalculate the edit distance, or number of operations required to transform one string into the other.\r\n\r\n{% highlight coffeescript %}\r\n\r\n  levenshtein = (str1, str2) ->\r\n    \r\n    l1 = str1.length\r\n    l2 = str2.length\r\n    prevDist = [0..l2]\r\n    nextDist = [0..l2]\r\n\r\n    for i in [1..l1] by 1\r\n      nextDist[0] = i\r\n      for j in [1..l2] by 1\r\n        if (str1.charAt i-1) == (str2.charAt j-1)\r\n          nextDist[j] = prevDist[j-1]\r\n        else\r\n          nextDist[j] = 1 + Math.min prevDist[j], nextDist[j-1], prevDist[j-1]\r\n        [prevDist,nextDist]=[nextDist, prevDist]\r\n    \r\n    prevDist[l2]\r\n\r\n{% endhighlight %}\r\n\r\n## Discussion\r\n\r\nYou can use either Hirschberg or Wagner–Fischer's algorithm to calculate a Levenshtein distance. This example uses Wagner–Fischer's algorithm.\r\n\r\nThis version of Levenshtein algorithm is linear in memory, quadratic in time.\r\n\r\nstr.charAt i is preferred here to str[i] because the latter syntax is not supported by some browsers (e.g. IE7).\r\n\r\nAt first glance the use of \"by 1\" in the two loops might look useless. It is actually here to avoid a common danger \r\nof the coffeescript [i..j] syntax. If str1 or str2 is an empty string, then [1..l1] or [1..l2] will return [1,0].\r\nThe loops with the \"by 1\" statement also compiles to cleaner / slightly more performant javascript.\r\n\r\nFinally the optimization of recycling of arrays at the end of the loops is mainly here to\r\ndemonstrate the syntax of coffeescript for swapping two variables.\n"
  },
  {
    "path": "chapters/strings/repeating.md",
    "content": "---\nlayout: recipe\ntitle: Repeating a String\nchapter: Strings\n---\n## Problem\n\nYou want to repeat a string.\n\n## Solution\n\nCreate an array of n+1 nulls, and then join it with the repetition string as the glue:\n\n{% highlight coffeescript %}\n# create a string of 10 foos\nArray(11).join 'foo'\n\n# => \"foofoofoofoofoofoofoofoofoofoo\"\n{% endhighlight %}\n\n## Repeat method for Strings\n\nYou could also create a method for this in String prototype. It is as simple as that:\n\n{% highlight coffeescript %}\n# add repeat method for all strings, that returns string repeated n times\nString::repeat = (n) -> Array(n+1).join(this)\n{% endhighlight %}\n\n## Discussion\n\nJavaScript lacks a string repeat function, as does CoffeeScript. List comprehensions and maps can be pressed into service here, but in the case of a simple string repeat it's easier to simply build an array of n+1 nulls and then glue them together.\n"
  },
  {
    "path": "chapters/strings/replacing-sub-strings.md",
    "content": "---\nlayout: recipe\ntitle: Replacing Sub-Strings Within a String\nchapter: Strings\n---\n## Problem\n\nYou want to replace a sub-string with a new sub-string.\n\n## Solution\n\nSplit the string using the sub-string you want to remove as a delimiter. Then re-join using the new sub-string as the delimiter.\n\n{% highlight coffeescript %}\n\"Orange is the new Black\".split(\"Orange\").join(\"Pink\")\n# => \"Pink is the new Black\"\n\n\"I am so sad. I cannot believe how sad I am today!\".split(\"sad\").join(\"happy\")\n# => \"I am so happy. I cannot believe how happy I am today!\"\n\n\"I am not a crook.\".split(\"not \").join(\"\")\n# => \"I am a crook.\"\n{% endhighlight %}\n\n## Discussion\n\nYou can also use regexes. If you're matching an exact string, this way is simpler and 10x faster.\n \nIf you use regexes, remember that you must escape certain characters. \n"
  },
  {
    "path": "chapters/strings/splitting-a-string.md",
    "content": "---\nlayout: recipe\ntitle: Splitting a String\nchapter: Strings\n---\n## Problem\n\nYou want to split a string.\n\n## Solution\n\nUse JavaScript's String split() method:\n\n{% highlight coffeescript %}\n\"foo bar baz\".split \" \"\n# => [ 'foo', 'bar', 'baz' ]\n{% endhighlight %}\n\n## Discussion\n\nString's split() is a standard JavaScript method. It can be used to split a string on any delimiter, including regular expressions. It also accepts a second parameter that specifies the number of splits to return.\n\n{% highlight coffeescript %}\n\"foo-bar-baz\".split \"-\"\n# => [ 'foo', 'bar', 'baz' ]\n{% endhighlight %}\n\n{% highlight coffeescript %}\n\"foo   bar  \\t baz\".split /\\s+/\n# => [ 'foo', 'bar', 'baz' ]\n{% endhighlight %}\n\n{% highlight coffeescript %}\n\"the sun goes down and I sit on the old broken-down river pier\".split \" \", 2\n# => [ 'the', 'sun' ]\n{% endhighlight %}\n"
  },
  {
    "path": "chapters/strings/trimming-whitespace-from-a-string.md",
    "content": "---\nlayout: recipe\ntitle: Trimming Whitespace from a String\nchapter: Strings\n---\n## Problem\n\nYou want to trim whitespace from a string.\n\n## Solution\n\nUse JavaScript's Regular Expression support to replace whitespace.\n\nTo trim leading and trailing whitespace, use the following:\n\n{% highlight coffeescript %}\n\"  padded string  \".replace /^\\s+|\\s+$/g, \"\"\n# => 'padded string'\n{% endhighlight %}\n\nTo trim only leading whitespace, use the following:\n\n{% highlight coffeescript %}\n\"  padded string  \".replace /^\\s+/g, \"\"\n# => 'padded string  '\n{% endhighlight %}\n\nTo trim only trailing whitespace, use the following:\n\n{% highlight coffeescript %}\n\"  padded string  \".replace /\\s+$/g, \"\"\n# => '  padded string'\n{% endhighlight %}\n\n## Discussion\n\nOpera, Firefox and Chrome all have a native string prototype `trim` method, and the other browsers could add one as well. For this particular method, I would use the built-in method where possible, otherwise create a polyfill:\n\n{% highlight coffeescript %}\nunless String::trim then String::trim = -> @replace /^\\s+|\\s+$/g, \"\"\n\n\"  padded string  \".trim()\n# => 'padded string'\n{% endhighlight %}\n\n\n### Syntax Sugar\n\nYou can add some Ruby-like syntax sugar with the following shortcuts:\n\n{% highlight coffeescript %}\nString::strip = -> if String::trim? then @trim() else @replace /^\\s+|\\s+$/g, \"\"\nString::lstrip = -> @replace /^\\s+/g, \"\"\nString::rstrip = -> @replace /\\s+$/g, \"\"\n\n\"  padded string  \".strip()\n# => 'padded string'\n\"  padded string  \".lstrip()\n# => 'padded string  '\n\"  padded string  \".rstrip()\n# => '  padded string'\n{% endhighlight %}\n\nFor an interesting discussion and benchmarks of JavaScript `trim` performance, see [this blog post](http://blog.stevenlevithan.com/archives/faster-trim-javascript) by Steve Levithan.\n"
  },
  {
    "path": "chapters/strings/uppercasing-a-string.md",
    "content": "---\nlayout: recipe\ntitle: Uppercasing a String\nchapter: Strings\n---\n## Problem\n\nYou want to uppercase a string.\n\n## Solution\n\nUse JavaScript's String toUpperCase() method:\n\n{% highlight coffeescript %}\n\"one two three\".toUpperCase()\n# => 'ONE TWO THREE'\n{% endhighlight %}\n\n## Discussion\n\n`toUpperCase()` is a standard JavaScript method. Don't forget the parentheses.\n\n### Syntax Sugar\n\nYou can add some Ruby-like syntax sugar with the following shortcut:\n\n{% highlight coffeescript %}\nString::upcase = -> @toUpperCase()\n\"one two three\".upcase()\n# => 'ONE TWO THREE'\n{% endhighlight %}\n\nThe snippet above demonstrates a few features of CoffeeScript:\n\n* The double-colon `::` is shorthand for saying `.prototype.`\n* The \"at\" sign `@` is shorthand for saying `this.`\n\nThe code above compiles in to the following JavaScript:\n\n{% highlight javascript %}\nString.prototype.upcase = function() {\n  return this.toUpperCase();\n};\n\"one two three\".upcase();\n{% endhighlight %}\n\n**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/)).\n"
  },
  {
    "path": "chapters/syntax/code_reuse_on_client_and_server.md",
    "content": "---\nlayout: recipe\ntitle: Code Reuse on Client and Server\nchapter: Syntax\n---\n## Problem\n\nYou have created some functionality in CoffeeScript that you wish to use on the client with a web browser and on the server with Node.js.\n\n## Solution\n\nExport the functionality in the following manner:\n\n{% highlight coffeescript %}\n\n# simpleMath.coffee\n\n# these methods are private\nadd = (a, b) ->\n\ta + b\n\nsubtract = (a, b) ->\n\ta - b\n\nsquare = (x) ->\n\tx * x\n\n# create a namespace to export our public methods\nSimpleMath = exports? and exports or @SimpleMath = {}\n\n# items attached to our namespace are available in Node.js as well as client browsers\nclass SimpleMath.Calculator\n\tadd: add\n\tsubtract: subtract\n\tsquare: square\n\n{% endhighlight %}\n\n## Discussion\n\nIn the above example, we create a new namespace called SimpleMath.  If `export` is available, our class is exported as a Node.js module.  If `export` is *not* available, then SimpleMath is added to the global namespace and available to our web page.\n\nIn Node.js, we can include our module using the `require` command.\n\n{% highlight console %}\n\n$ node\n\n> var SimpleMath = require('./simpleMath');\nundefined\n> var Calc = new SimpleMath.Calculator();\nundefined\n> console.log(\"5 + 6 = \", Calc.add(5, 6));\n5 + 6 =  11\nundefined\n> \n\n{% endhighlight %}\n\nIn our web page, we can include our module by including it as a script.\n\n{% highlight html %}\n\n<!DOCTYPE HTML>\n<html lang=\"en-US\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>SimpleMath Module Example</title>\n\t<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\"></script>\n\t<script src=\"simpleMath.js\"></script>\n\t<script>\n\t\tjQuery(document).ready(function\t(){\n\t\t\tvar Calculator = new SimpleMath.Calculator();\n\t\t\tvar result = $('<li>').html(\"5 + 6 = \" + Calculator.add(5, 6));\n\t\t\t$('#SampleResults').append(result);\t\n\t\t});\n\t</script>\n</head>\n<body>\n\t<h1>A SimpleMath Example</h1>\n\t<ul id=\"SampleResults\"></ul>\n</body>\n</html>\n\n{% endhighlight %}\n\nResult:\n\n#A SimpleMath Example\n* 5 + 6 = 11"
  },
  {
    "path": "chapters/syntax/comparing_ranges.md",
    "content": "---\nlayout: recipe\ntitle: Comparing Ranges\nchapter: Syntax\n---\n## Problem\n\nYou want to know if a variable is inside a given range.\n\n## Solution\n\nUse CoffeeScript's chained comparison syntax.\n\n{% highlight coffeescript %}\nmaxDwarfism = 147\nminAcromegaly = 213\n\nheight = 180\n\nnormalHeight = maxDwarfism < height < minAcromegaly\n# => true\n{% endhighlight %}\n\n## Discussion\n\nThis is a nice feature lifted from Python. Instead of writing out the full comparison like\n\n{% highlight coffeescript %}\nnormalHeight = height > maxDwarfism && height < minAcromegaly\n{% endhighlight %}\n\nCoffeeScript allows us to chain the two comparisons together in a form that more closely matches the way a mathematician would write it.\n"
  },
  {
    "path": "chapters/syntax/embedding_javascript.md",
    "content": "---\nlayout: recipe\ntitle: Embedding JavaScript\nchapter: Syntax\n---\n## Problem\n\nYou want to include some found/pre-written JavaScript code inline with your CoffeeScript.\n\n## Solution\n\nWrap the JavaScript with backticks:\n\n{% highlight coffeescript %}\n`function greet(name) {\nreturn \"Hello \"+name;\n}`\n\n# Back to CoffeeScript\ngreet \"Coffee\"\n# => \"Hello Coffee\"\n{% endhighlight %}\n\n## Discussion\n\nThis is a simple way to integrate small snippets of JavaScript code into your CoffeeScript without converting it over to use CoffeeScript syntax. As shown in the [CoffeeScript Language Reference](http://jashkenas.github.com/coffee-script/#embedded) you can mix the two languages to a certain extent:\n\n{% highlight coffeescript %}\nhello = `function (name) {\nreturn \"Hello \"+name\n}`\nhello \"Coffee\"\n# => \"Hello Coffee\"\n\n{% endhighlight %}\n\nHere the `hello` variable is still in CoffeeScript, but is assigned a function written in JavaScript.\n"
  },
  {
    "path": "chapters/syntax/for_loops.md",
    "content": "---\nlayout: recipe\ntitle: For Loops\nchapter: Syntax\n---\n## Problem\n\nYou need to iterate over an array, object or range with a for loop.\n\n## Solution\n\n{% highlight coffeescript %}\n# for(i = 1; i<= 10; i++)\nx for x in [1..10]\n# => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]\n\n# To count by 2\n# for(i=1; i<= 10; i=i+2)\nx for x in [1..10] by 2\n# => [ 1, 3, 5, 7, 9 ]\n\n# Perform a simple operation like squaring each item.\nx * x for x in [1..10]\n# = > [1,4,9,16,25,36,49,64,81,100]\n{% endhighlight %}\n\n## Discussion\n\nComprehensions replace for loops in CoffeeScript, but they simply compile into the traditional javascript equivalent for-loop."
  },
  {
    "path": "chapters/syntax/index.html",
    "content": "---\nlayout: chapter\ntitle: Syntax\nchapter: Syntax\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/testing/index.html",
    "content": "---\nlayout: chapter\ntitle: Testing\nchapter: Testing\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}\n{% capture indexurl %}{{ url }}/index.html{% endcapture %}\n\n<ul>\n{% for page in site.pages %}\n  {% if page.url contains url %}\n    {% unless page.url == indexurl %}\n  <li><a href=\"{{ site.baseurl }}{{ page.url | replace: '.html', '' }}\">{{ page.title }}</a></li>\n    {% endunless %}\n  {% endif %}\n{% endfor %}\n</ul>\n"
  },
  {
    "path": "chapters/testing/testing_with_jasmine.md",
    "content": "---\nlayout: recipe\ntitle: Testing with Jasmine\nchapter: Testing\n---\n## Problem\n\nYou are writing a simple calculator using CoffeeScript and you want to verify it functions as expected.  You decide to use the <a href=\"http://jasmine.github.io/\" target=\"_blank\">Jasmine</a> test framework.\n\n## Discussion\n\nWhen using the Jasmine test framework, you write tests in a specification (spec) file that describes the expected functionality of the code to be tested.\n\nFor example, we expect our calculator will be able to add and subtract and will function correctly with both positive and negative numbers.  Our spec is listed below.\n\n{% highlight coffeescript %}\n\n# calculatorSpec.coffee\n\ndescribe 'Calculator', ->\n\n\tit 'can add two positive numbers', ->\n\t\tcalculator = new Calculator()\n\t\tresult = calculator.add 2, 3\n\t\texpect(result).toBe 5\n\n\tit 'can handle negative number addition', ->\n\t\tcalculator = new Calculator()\n\t\tresult = calculator.add -10, 5\n\t\texpect(result).toBe -5\n\n\tit 'can subtract two positive numbers', ->\n\t\tcalculator = new Calculator()\n\t\tresult = calculator.subtract 10, 6\n\t\texpect(result).toBe 4\n\n\tit 'can handle negative number subtraction', ->\n\t\tcalculator = new Calculator()\n\t\tresult = calculator.subtract 4, -6\n\t\texpect(result).toBe 10\n\n{% endhighlight %}\n\n\n### Configuring Jasmine\n\nBefore you can run your tests, you must download and configure Jasmine.  This involves:\n1. downloading the latest <a href=\"https://github.com/pivotal/jasmine/tree/master/dist\" target=\"_blank\">Jasmine</a> zip file;\n2. creating a spec and a spec/jasmine folder in your project;\n3. extracting the downloaded Jasmine files into the spec/jasmine folder; and\n4. creating a test runner.\n\n### Create a Test Runner\n\nJasmine can run your tests within a web browser by using a spec runner HTML file.  The spec runner is a simple HTML page that links the necessary JavaScript and CSS files for both Jasmine and your code.  A sample is below.\n\n{% highlight html linenos %}\n\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n  \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n  <title>Jasmine Spec Runner</title>\n  <link rel=\"shortcut icon\" type=\"image/png\" href=\"spec/jasmine/jasmine_favicon.png\">\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"spec/jasmine/jasmine.css\">\n  <script src=\"http://code.jquery.com/jquery.min.js\"></script>\n  <script src=\"spec/jasmine/jasmine.js\"></script>\n  <script src=\"spec/jasmine/jasmine-html.js\"></script>\n  <script src=\"spec/jasmine/jasmine-jquery-1.3.1.js\"></script>\n\n  <!-- include source files here... -->\n  <script src=\"js/calculator.js\"></script>\n\n  <!-- include spec files here... -->\n  <script src=\"spec/calculatorSpec.js\"></script>\n\n</head>\n\n<body>\n  <script type=\"text/javascript\">\n    (function() {\n      var jasmineEnv = jasmine.getEnv();\n      jasmineEnv.updateInterval = 1000;\n\n      var trivialReporter = new jasmine.TrivialReporter();\n\n      jasmineEnv.addReporter(trivialReporter);\n\n      jasmineEnv.specFilter = function(spec) {\n        return trivialReporter.specFilter(spec);\n      };\n\n      var currentWindowOnload = window.onload;\n\n      window.onload = function() {\n        if (currentWindowOnload) {\n          currentWindowOnload();\n        }\n        execJasmine();\n      };\n\n      function execJasmine() {\n        jasmineEnv.execute();\n      }\n\n    })();\n  </script>\n</body>\n</html>\n\n{% endhighlight %}\n\nThis spec runner can be downloaded from this GitHub <a href=\"https://gist.github.com/2623232\" target=\"_blank\">gist</a>.\n\nTo use the SpecRunner.html, simply reference your compiled JavaScript files and compiled tests after jasmine.js and its dependencies.\n\nIn the above example, we include our yet-to-be-developed calculator.js file on line 14 and our compiled calculatorSpec.js file on line 17.\n\n## <span style=\"color: red;\">Running the Tests</span>\n\nTo run our tests, simply open SpecRunner.html in a web browser.  In our example we see 4 failing specs with a total of 8 failures (below).\n\n<img src=\"images/jasmine_failing_all.jpg\" alt=\"All failing tests\" />\n\nIt appears our tests are failing because Jasmine cannot find the variable Calculator.  That's because it has not been created yet.  Let's do that now by creating a new file named js/calculator.coffee.\n\n\n{% highlight coffeescript %}\n\n# calculator.coffee\n\nwindow.Calculator = class Calculator\n\n{% endhighlight %}\n\nCompile calculator.coffee and refresh the browser to re-run the test suite.\n\n<img src=\"images/jasmine_failing_better.jpg\" alt=\"Still failing, but better\" />\n\nWe now have 4 failures instead of our previous 8.  That's a 50% improvement with only one line of code.\n\n## <span style=\"color: green;\">Getting the Tests to Pass</span>\n\nLet's implement our methods and see if we can get these tests to pass.\n\n{% highlight coffeescript %}\n\n# calculator.coffee\n\nwindow.Calculator = class Calculator\n\tadd: (a, b) ->\n\t\ta + b\n\n\tsubtract: (a, b) ->\n\t\ta - b \n\n{% endhighlight %}\n\nWhen we refresh we see they all pass.\n\n<img src=\"images/jasmine_passing.jpg\" alt=\"All passing\" />\n\n\n## <span style=\"color: green;\">Refactoring the Tests</span>\n\nNow that our tests pass, we should look to see if our code or our test(s) can be refactored.\n\nIn our spec file, each test creates its own calculator instance.  This can make our tests quite repetitive especially for larger test suites.  Ideally, we should consider moving that initialization code into a routine that runs before each test.  \n\nLuckily Jasmine has a beforeEach function just for this purpose.\n\n{% highlight coffeescript %}\n\ndescribe 'Calculator', ->\n\tcalculator = null\n\n\tbeforeEach ->\n\t\tcalculator = new Calculator()\n\n\tit 'can add two positive numbers', ->\n\t\tresult = calculator.add 2, 3\n\t\texpect(result).toBe 5\n\n\tit 'can handle negative number addition', ->\n\t\tresult = calculator.add -10, 5\n\t\texpect(result).toBe -5\n\n\tit 'can subtract two positive numbers', ->\n\t\tresult = calculator.subtract 10, 6\n\t\texpect(result).toBe 4\n\n\tit 'can handle negative number subtraction', ->\n\t\tresult = calculator.subtract 4, -6\n\t\texpect(result).toBe 10\n\n{% endhighlight %}\n\nWhen we recompile our spec and refresh the browser we see the tests still all pass.\n\n<img src=\"images/jasmine_passing.jpg\" alt=\"All passing\" />\n"
  },
  {
    "path": "chapters/testing/testing_with_nodeunit.md",
    "content": "---\nlayout: recipe\ntitle: Testing with Nodeunit\nchapter: Testing\n---\n## Problem\n\nYou are writing a simple calculator using CoffeeScript and you want to verify it functions as expected.  You decide to use the <a href=\"https://github.com/caolan/nodeunit\" target=\"_blank\">Nodeunit</a> test framework.\n\n## Discussion\n\nNodeunit is a JavaScript implementation of the xUnit family of Unit Testing libraries, similar libraries are available for Java, Python, Ruby, Smalltalk etc.\n\nWhen using xUnit family test frameworks, you write tests in a file that describes the expected functionality of the code to be tested.\n\nFor example, we expect our calculator will be able to add and subtract and will function correctly with both positive and negative numbers.  Our test is listed below.\n\n{% highlight coffeescript %}\n\n# test/calculator.test.coffee\n\nCalculator = require '../calculator'\n\nexports.CalculatorTest =\n\n    'test can add two positive numbers': (test) ->\n        calculator = new Calculator\n        result = calculator.add 2, 3\n        test.equal(result, 5)\n        test.done()\n\n    'test can handle negative number addition': (test) ->\n        calculator = new Calculator\n        result = calculator.add -10, 5\n        test.equal(result,  -5)\n        test.done()\n\n    'test can subtract two positive numbers': (test) ->\n        calculator = new Calculator\n        result = calculator.subtract 10, 6\n        test.equal(result, 4)\n        test.done()\n\n    'test can handle negative number subtraction': (test) ->\n        calculator = new Calculator\n        result = calculator.subtract 4, -6\n        test.equal(result, 10)\n        test.done()\n\n{% endhighlight %}\n\n### Installing Nodeunit\n\nBefore you can run your tests, you must install Nodeunit:\n\nFirst of all create a `package.json` file\n\n{% highlight javascript %}\n{\n  \"name\": \"calculator\",\n  \"version\": \"0.0.1\",\n  \"scripts\": {\n    \"test\": \"./node_modules/.bin/nodeunit test\"\n  },\n  \"dependencies\": {\n    \"coffee-script\": \"~1.4.0\",\n    \"nodeunit\": \"~0.7.4\"\n  }\n}\n{% endhighlight %}\n\nNext from a terminal run.\n\n{% highlight bash %}\n$ npm install\n{% endhighlight %}\n\n## <span style=\"color: red;\">Running the Tests</span>\n\nIt's easy to run the tests from the command-line:\n\n{% highlight bash %}\n$ npm test\n{% endhighlight %}\n\nThe test runner should fail, because we have no calculator.coffee\n\n    suki@Yuzuki:nodeunit_testing (master)$ npm test\n    npm WARN package.json calculator@0.0.1 No README.md file found!\n\n    > calculator@0.0.1 test /Users/suki/tmp/nodeunit_testing\n    > ./node_modules/.bin/nodeunit test\n\n\n    /Users/suki/tmp/nodeunit_testing/node_modules/nodeunit/lib/nodeunit.js:72\n            if (err) throw err;\n                           ^\n    Error: ENOENT, stat '/Users/suki/tmp/nodeunit_testing/test'\n    npm ERR! Test failed.  See above for more details.\n    npm ERR! not ok code 0\n\nLet's create a simple file \n\n{% highlight coffeescript %}\n\n# calculator.coffee\n\nclass Calculator\n\nmodule.exports = Calculator\n{% endhighlight %}\n\nAnd re-run the test suite.\n\n    suki@Yuzuki:nodeunit_testing (master)$ npm test\n    npm WARN package.json calculator@0.0.1 No README.md file found!\n\n    > calculator@0.0.1 test /Users/suki/tmp/nodeunit_testing\n    > ./node_modules/.bin/nodeunit test\n\n\n    calculator.test\n    ✖ CalculatorTest - test can add two positive numbers\n\n    TypeError: Object #<Calculator> has no method 'add'\n      ...\n\n    ✖ CalculatorTest - test can handle negative number addition\n\n    TypeError: Object #<Calculator> has no method 'add'\n      ...\n\n    ✖ CalculatorTest - test can subtract two positive numbers\n\n    TypeError: Object #<Calculator> has no method 'subtract'\n      ...\n\n    ✖ CalculatorTest - test can handle negative number subtraction\n\n    TypeError: Object #<Calculator> has no method 'subtract'\n      ...\n\n\n    FAILURES: 4/4 assertions failed (31ms)\n    npm ERR! Test failed.  See above for more details.\n    npm ERR! not ok code 0\n\n\n## <span style=\"color: green;\">Getting the Tests to Pass</span>\n\nLet's implement our methods and see if we can get these tests to pass.\n\n{% highlight coffeescript %}\n\n# calculator.coffee\n\nclass Calculator\n\n  add: (a, b) ->\n    a + b\n\n  subtract: (a, b) ->\n    a - b\n\nmodule.exports = Calculator\n{% endhighlight %}\n\nWhen we rerun the tests we see they're all passing:\n\n    suki@Yuzuki:nodeunit_testing (master)$ npm test\n    npm WARN package.json calculator@0.0.1 No README.md file found!\n\n    > calculator@0.0.1 test /Users/suki/tmp/nodeunit_testing\n    > ./node_modules/.bin/nodeunit test\n\n\n    calculator.test\n    ✔ CalculatorTest - test can add two positive numbers\n    ✔ CalculatorTest - test can handle negative number addition\n    ✔ CalculatorTest - test can subtract two positive numbers\n    ✔ CalculatorTest - test can handle negative number subtraction\n\n    OK: 4 assertions (27ms)\n\n\n## <span style=\"color: green;\">Refactoring the Tests</span>\n\nNow that our tests pass, we should look to see if our code or our test(s) can be refactored.\n\nIn our test file, each test creates its own calculator instance.  This can make our tests quite repetitive especially for larger test suites.  Ideally, we should consider moving that initialization code into a routine that runs before each test.  \n\nIn common with other xUnit libraries, Nodeunit provides a setUp (and tearDown) function which will be called before each test.\n\n{% highlight coffeescript %}\n\nCalculator = require '../calculator'\n\nexports.CalculatorTest =\n\n    setUp: (callback) ->\n        @calculator = new Calculator\n        callback()\n\n    'test can add two positive numbers': (test) ->\n        result = @calculator.add 2, 3\n        test.equal(result, 5)\n        test.done()\n\n    'test can handle negative number addition': (test) ->\n        result = @calculator.add -10, 5\n        test.equal(result,  -5)\n        test.done()\n\n    'test can subtract two positive numbers': (test) ->\n        result = @calculator.subtract 10, 6\n        test.equal(result, 4)\n        test.done()\n\n    'test can handle negative number subtraction': (test) ->\n        result = @calculator.subtract 4, -6\n        test.equal(result, 10)\n        test.done()\n\n{% endhighlight %}\n\nWe can rerun the tests and everything should continue to pass.\n"
  },
  {
    "path": "contributing.md",
    "content": "---\nlayout: default\ntitle: Contributing\n---\n# Contributing\n\nThe Cookbook needs your help!\n\nHere's the Contribution Recipe:\n\n1. Fork the repository at [https://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com](https://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com)\n2. Do awesomeness!\n3. Send a pull request to coffeescript-cookbook\n4. If we merge your pull request, you get commit access. BAM. Go back to step 2 and stay there as long as you want.\n\n## Wanted Recipes\n\nWant to help, but don't know where to start? Want a recipe, but don't know how to write it? Check out the [Wanted Recipes]({{ site.baseurl }}/wanted-recipes) page!\n\n## Authors\n\nWrite recipes! Fork the repository, author some pages, and send us a pull request. For more information read the [Author's Guide]({{ site.baseurl }}/authors-guide).\n\n## Developers\n\nImprove the code! Fork the repository, extend or improve the site coded, and send a pull request. For more information read the [Developer's Guide]({{ site.baseurl }}/developers-guide).\n\n## Designers\n\nMake this site look pretty! Fork the repository, extend, improve or update the design, and send a pull request. For more information read the [Designer's Guide]({{ site.baseurl }}/designers-guide).\n"
  },
  {
    "path": "css/autumn.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #aaaaaa; font-style: italic } /* Comment */\n.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */\n.highlight .k { color: #0000aa } /* Keyword */\n.highlight .cm { color: #aaaaaa; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #4c8317 } /* Comment.Preproc */\n.highlight .c1 { color: #aaaaaa; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #0000aa; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #aa0000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #aa0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00aa00 } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #555555 } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #aa0000 } /* Generic.Traceback */\n.highlight .kc { color: #0000aa } /* Keyword.Constant */\n.highlight .kd { color: #0000aa } /* Keyword.Declaration */\n.highlight .kn { color: #0000aa } /* Keyword.Namespace */\n.highlight .kp { color: #0000aa } /* Keyword.Pseudo */\n.highlight .kr { color: #0000aa } /* Keyword.Reserved */\n.highlight .kt { color: #00aaaa } /* Keyword.Type */\n.highlight .m { color: #009999 } /* Literal.Number */\n.highlight .s { color: #aa5500 } /* Literal.String */\n.highlight .na { color: #1e90ff } /* Name.Attribute */\n.highlight .nb { color: #00aaaa } /* Name.Builtin */\n.highlight .nc { color: #00aa00; text-decoration: underline } /* Name.Class */\n.highlight .no { color: #aa0000 } /* Name.Constant */\n.highlight .nd { color: #888888 } /* Name.Decorator */\n.highlight .ni { color: #800000; font-weight: bold } /* Name.Entity */\n.highlight .nf { color: #00aa00 } /* Name.Function */\n.highlight .nn { color: #00aaaa; text-decoration: underline } /* Name.Namespace */\n.highlight .nt { color: #1e90ff; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #aa0000 } /* Name.Variable */\n.highlight .ow { color: #0000aa } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #009999 } /* Literal.Number.Float */\n.highlight .mh { color: #009999 } /* Literal.Number.Hex */\n.highlight .mi { color: #009999 } /* Literal.Number.Integer */\n.highlight .mo { color: #009999 } /* Literal.Number.Oct */\n.highlight .sb { color: #aa5500 } /* Literal.String.Backtick */\n.highlight .sc { color: #aa5500 } /* Literal.String.Char */\n.highlight .sd { color: #aa5500 } /* Literal.String.Doc */\n.highlight .s2 { color: #aa5500 } /* Literal.String.Double */\n.highlight .se { color: #aa5500 } /* Literal.String.Escape */\n.highlight .sh { color: #aa5500 } /* Literal.String.Heredoc */\n.highlight .si { color: #aa5500 } /* Literal.String.Interpol */\n.highlight .sx { color: #aa5500 } /* Literal.String.Other */\n.highlight .sr { color: #009999 } /* Literal.String.Regex */\n.highlight .s1 { color: #aa5500 } /* Literal.String.Single */\n.highlight .ss { color: #0000aa } /* Literal.String.Symbol */\n.highlight .bp { color: #00aaaa } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #aa0000 } /* Name.Variable.Class */\n.highlight .vg { color: #aa0000 } /* Name.Variable.Global */\n.highlight .vi { color: #aa0000 } /* Name.Variable.Instance */\n.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/borland.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #008800; font-style: italic } /* Comment */\n.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */\n.highlight .k { color: #000080; font-weight: bold } /* Keyword */\n.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #008080 } /* Comment.Preproc */\n.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */\n.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #aa0000 } /* Generic.Error */\n.highlight .gh { color: #999999 } /* Generic.Heading */\n.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #555555 } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #aaaaaa } /* Generic.Subheading */\n.highlight .gt { color: #aa0000 } /* Generic.Traceback */\n.highlight .kc { color: #000080; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #000080; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #0000FF } /* Literal.Number */\n.highlight .s { color: #0000FF } /* Literal.String */\n.highlight .na { color: #FF0000 } /* Name.Attribute */\n.highlight .nt { color: #000080; font-weight: bold } /* Name.Tag */\n.highlight .ow { font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #0000FF } /* Literal.Number.Float */\n.highlight .mh { color: #0000FF } /* Literal.Number.Hex */\n.highlight .mi { color: #0000FF } /* Literal.Number.Integer */\n.highlight .mo { color: #0000FF } /* Literal.Number.Oct */\n.highlight .sb { color: #0000FF } /* Literal.String.Backtick */\n.highlight .sc { color: #800080 } /* Literal.String.Char */\n.highlight .sd { color: #0000FF } /* Literal.String.Doc */\n.highlight .s2 { color: #0000FF } /* Literal.String.Double */\n.highlight .se { color: #0000FF } /* Literal.String.Escape */\n.highlight .sh { color: #0000FF } /* Literal.String.Heredoc */\n.highlight .si { color: #0000FF } /* Literal.String.Interpol */\n.highlight .sx { color: #0000FF } /* Literal.String.Other */\n.highlight .sr { color: #0000FF } /* Literal.String.Regex */\n.highlight .s1 { color: #0000FF } /* Literal.String.Single */\n.highlight .ss { color: #0000FF } /* Literal.String.Symbol */\n.highlight .il { color: #0000FF } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/bw.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { font-weight: bold } /* Keyword */\n.highlight .cm { font-style: italic } /* Comment.Multiline */\n.highlight .c1 { font-style: italic } /* Comment.Single */\n.highlight .cs { font-style: italic } /* Comment.Special */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gh { font-weight: bold } /* Generic.Heading */\n.highlight .gp { font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { font-weight: bold } /* Generic.Subheading */\n.highlight .kc { font-weight: bold } /* Keyword.Constant */\n.highlight .kd { font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { font-weight: bold } /* Keyword.Namespace */\n.highlight .kr { font-weight: bold } /* Keyword.Reserved */\n.highlight .s { font-style: italic } /* Literal.String */\n.highlight .nc { font-weight: bold } /* Name.Class */\n.highlight .ni { font-weight: bold } /* Name.Entity */\n.highlight .ne { font-weight: bold } /* Name.Exception */\n.highlight .nn { font-weight: bold } /* Name.Namespace */\n.highlight .nt { font-weight: bold } /* Name.Tag */\n.highlight .ow { font-weight: bold } /* Operator.Word */\n.highlight .sb { font-style: italic } /* Literal.String.Backtick */\n.highlight .sc { font-style: italic } /* Literal.String.Char */\n.highlight .sd { font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { font-style: italic } /* Literal.String.Double */\n.highlight .se { font-weight: bold; font-style: italic } /* Literal.String.Escape */\n.highlight .sh { font-style: italic } /* Literal.String.Heredoc */\n.highlight .si { font-weight: bold; font-style: italic } /* Literal.String.Interpol */\n.highlight .sx { font-style: italic } /* Literal.String.Other */\n.highlight .sr { font-style: italic } /* Literal.String.Regex */\n.highlight .s1 { font-style: italic } /* Literal.String.Single */\n.highlight .ss { font-style: italic } /* Literal.String.Symbol */\n"
  },
  {
    "path": "css/colorful.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #808080 } /* Comment */\n.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */\n.highlight .k { color: #008000; font-weight: bold } /* Keyword */\n.highlight .o { color: #303030 } /* Operator */\n.highlight .cm { color: #808080 } /* Comment.Multiline */\n.highlight .cp { color: #507090 } /* Comment.Preproc */\n.highlight .c1 { color: #808080 } /* Comment.Single */\n.highlight .cs { color: #cc0000; font-weight: bold } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #003080; font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #303090; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #6000E0; font-weight: bold } /* Literal.Number */\n.highlight .s { background-color: #fff0f0 } /* Literal.String */\n.highlight .na { color: #0000C0 } /* Name.Attribute */\n.highlight .nb { color: #007020 } /* Name.Builtin */\n.highlight .nc { color: #B00060; font-weight: bold } /* Name.Class */\n.highlight .no { color: #003060; font-weight: bold } /* Name.Constant */\n.highlight .nd { color: #505050; font-weight: bold } /* Name.Decorator */\n.highlight .ni { color: #800000; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #F00000; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0060B0; font-weight: bold } /* Name.Function */\n.highlight .nl { color: #907000; font-weight: bold } /* Name.Label */\n.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #007000 } /* Name.Tag */\n.highlight .nv { color: #906030 } /* Name.Variable */\n.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */\n.highlight .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */\n.highlight .mi { color: #0000D0; font-weight: bold } /* Literal.Number.Integer */\n.highlight .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */\n.highlight .sb { background-color: #fff0f0 } /* Literal.String.Backtick */\n.highlight .sc { color: #0040D0 } /* Literal.String.Char */\n.highlight .sd { color: #D04020 } /* Literal.String.Doc */\n.highlight .s2 { background-color: #fff0f0 } /* Literal.String.Double */\n.highlight .se { color: #606060; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */\n.highlight .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */\n.highlight .si { background-color: #e0e0e0 } /* Literal.String.Interpol */\n.highlight .sx { color: #D02000; background-color: #fff0f0 } /* Literal.String.Other */\n.highlight .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */\n.highlight .s1 { background-color: #fff0f0 } /* Literal.String.Single */\n.highlight .ss { color: #A06000 } /* Literal.String.Symbol */\n.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #306090 } /* Name.Variable.Class */\n.highlight .vg { color: #d07000; font-weight: bold } /* Name.Variable.Global */\n.highlight .vi { color: #3030B0 } /* Name.Variable.Instance */\n.highlight .il { color: #0000D0; font-weight: bold } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/default.css",
    "content": "/* Minimal reset */\n\n* {\n  vertical-align: baseline;\n  font-family: inherit;\n  font-style: inherit;\n  font-size: 100%;\n  border: none;\n  padding: 0;\n  margin: 0;\n}\n\nem {\n  font-style: italic;\n}\n\ncode {\n  font-family: courier;\n}\n\narticle, header, section, footer {\n  display: block;\n}\n\n/* Colors */\n\na, .header a:visited {\n  color: #26ADE4;\n  text-decoration: none;\n}\n\na:hover {\n  text-decoration: underline;\n  text-shadow: 0 0 0 #DCEEF5;\n}\n\nfooter {\n  border-top: 1px solid #eee;\n  padding-top: 22px;\n  margin: 21px 0 22px 0;\n  color: #888;\n  font-size: 14px;\n}\n\n/* Layout (margins, padding) */\n\npre {\n  padding: 22px;\n  line-height: 22px;\n  margin: 22px 0;\n}\n\np, header, section { margin-bottom: 22px; }\n\nul.unstyled {\n  list-style: none;\n}\n\nul, ol {\n  margin-left: 22px;\n  margin-bottom: 22px;\n}\n\nnav ul {\n  list-style:none;\n}\n\nnav ul li {\n  border-left:1px solid rgba(0, 0, 0, 0.2);\n  display:inline-block;\n  padding:0 10px;\n}\n\nnav ul li:first-child {\n  border:none;\n}\n\nnav ol {\n  list-style:none;\n}\n\nnav ol li {\n  display:inline-block;\n}\n\nnav ol.breadcrumbs li:before {\n  content: '\\000bb\\000a0'; /* Insert &raquo;&nbsp; between list items. */\n}\n\nnav ol.breadcrumbs li:first-child:before {\n  content: '';\n}\n\n/* Typography */\n\nbody {\n  text-rendering: optimizeLegibility;\n  color: #373837;\n  font-family: Palatino, \"Palatino Linotype\", serif;\n  text-shadow: 0 0 0 transparent;\n  font-size: 16px;\n  line-height: 22px;\n  margin: 22px;\n}\n\npre {\n  font-family: Monaco, Monospace;\n  font-size: 14px;\n}\n\nh1, h2, h3 {\n  margin: 0;\n  padding: 0;\n}\n\nh1 { font-size: 30px; line-height: 44px; }\nh2 { font-size: 22px; line-height: 44px; }\nh3 { font-size: 18px; line-height: 22px; }\n\n/* Syntax Highlighting */\n.highlight .hll { background-color: #ffffcc }\n.highlight  { background: #f8f8f8; }\n.highlight .c { color: #408080; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #008000; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #008000 } /* Keyword.Pseudo */\n.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #B00040 } /* Keyword.Type */\n.highlight .m { color: #666666 } /* Literal.Number */\n.highlight .s { color: #BA2121 } /* Literal.String */\n.highlight .na { color: #7D9029 } /* Name.Attribute */\n.highlight .nb { color: #008000 } /* Name.Builtin */\n.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.highlight .no { color: #880000 } /* Name.Constant */\n.highlight .nd { color: #AA22FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0000FF } /* Name.Function */\n.highlight .nl { color: #A0A000 } /* Name.Label */\n.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #19177C } /* Name.Variable */\n.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #666666 } /* Literal.Number.Float */\n.highlight .mh { color: #666666 } /* Literal.Number.Hex */\n.highlight .mi { color: #666666 } /* Literal.Number.Integer */\n.highlight .mo { color: #666666 } /* Literal.Number.Oct */\n.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n.highlight .sc { color: #BA2121 } /* Literal.String.Char */\n.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.highlight .sx { color: #008000 } /* Literal.String.Other */\n.highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n.highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n.highlight .ss { color: #19177C } /* Literal.String.Symbol */\n.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #19177C } /* Name.Variable.Class */\n.highlight .vg { color: #19177C } /* Name.Variable.Global */\n.highlight .vi { color: #19177C } /* Name.Variable.Instance */\n.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */"
  },
  {
    "path": "css/emacs.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #008800; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #AA22FF; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .cm { color: #008800; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #008800 } /* Comment.Preproc */\n.highlight .c1 { color: #008800; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #008800; font-weight: bold } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #AA22FF } /* Keyword.Pseudo */\n.highlight .kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #00BB00; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #666666 } /* Literal.Number */\n.highlight .s { color: #BB4444 } /* Literal.String */\n.highlight .na { color: #BB4444 } /* Name.Attribute */\n.highlight .nb { color: #AA22FF } /* Name.Builtin */\n.highlight .nc { color: #0000FF } /* Name.Class */\n.highlight .no { color: #880000 } /* Name.Constant */\n.highlight .nd { color: #AA22FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #00A000 } /* Name.Function */\n.highlight .nl { color: #A0A000 } /* Name.Label */\n.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #B8860B } /* Name.Variable */\n.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #666666 } /* Literal.Number.Float */\n.highlight .mh { color: #666666 } /* Literal.Number.Hex */\n.highlight .mi { color: #666666 } /* Literal.Number.Integer */\n.highlight .mo { color: #666666 } /* Literal.Number.Oct */\n.highlight .sb { color: #BB4444 } /* Literal.String.Backtick */\n.highlight .sc { color: #BB4444 } /* Literal.String.Char */\n.highlight .sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #BB4444 } /* Literal.String.Double */\n.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #BB4444 } /* Literal.String.Heredoc */\n.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.highlight .sx { color: #008000 } /* Literal.String.Other */\n.highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n.highlight .s1 { color: #BB4444 } /* Literal.String.Single */\n.highlight .ss { color: #B8860B } /* Literal.String.Symbol */\n.highlight .bp { color: #AA22FF } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #B8860B } /* Name.Variable.Class */\n.highlight .vg { color: #B8860B } /* Name.Variable.Global */\n.highlight .vi { color: #B8860B } /* Name.Variable.Instance */\n.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/friendly.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #60a0b0; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #007020; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #007020 } /* Comment.Preproc */\n.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #007020 } /* Keyword.Pseudo */\n.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #902000 } /* Keyword.Type */\n.highlight .m { color: #40a070 } /* Literal.Number */\n.highlight .s { color: #4070a0 } /* Literal.String */\n.highlight .na { color: #4070a0 } /* Name.Attribute */\n.highlight .nb { color: #007020 } /* Name.Builtin */\n.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */\n.highlight .no { color: #60add5 } /* Name.Constant */\n.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */\n.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #007020 } /* Name.Exception */\n.highlight .nf { color: #06287e } /* Name.Function */\n.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */\n.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #bb60d5 } /* Name.Variable */\n.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #40a070 } /* Literal.Number.Float */\n.highlight .mh { color: #40a070 } /* Literal.Number.Hex */\n.highlight .mi { color: #40a070 } /* Literal.Number.Integer */\n.highlight .mo { color: #40a070 } /* Literal.Number.Oct */\n.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */\n.highlight .sc { color: #4070a0 } /* Literal.String.Char */\n.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #4070a0 } /* Literal.String.Double */\n.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */\n.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */\n.highlight .sx { color: #c65d09 } /* Literal.String.Other */\n.highlight .sr { color: #235388 } /* Literal.String.Regex */\n.highlight .s1 { color: #4070a0 } /* Literal.String.Single */\n.highlight .ss { color: #517918 } /* Literal.String.Symbol */\n.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */\n.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */\n.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */\n.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/fruity.css",
    "content": ".highlight .hll { background-color: #333333 }\n.highlight .c { color: #008800; font-style: italic; background-color: #0f140f } /* Comment */\n.highlight .err { color: #ffffff } /* Error */\n.highlight .g { color: #ffffff } /* Generic */\n.highlight .k { color: #fb660a; font-weight: bold } /* Keyword */\n.highlight .l { color: #ffffff } /* Literal */\n.highlight .n { color: #ffffff } /* Name */\n.highlight .o { color: #ffffff } /* Operator */\n.highlight .x { color: #ffffff } /* Other */\n.highlight .p { color: #ffffff } /* Punctuation */\n.highlight .cm { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Multiline */\n.highlight .cp { color: #ff0007; font-weight: bold; font-style: italic; background-color: #0f140f } /* Comment.Preproc */\n.highlight .c1 { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Single */\n.highlight .cs { color: #008800; font-style: italic; background-color: #0f140f } /* Comment.Special */\n.highlight .gd { color: #ffffff } /* Generic.Deleted */\n.highlight .ge { color: #ffffff } /* Generic.Emph */\n.highlight .gr { color: #ffffff } /* Generic.Error */\n.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #ffffff } /* Generic.Inserted */\n.highlight .go { color: #444444; background-color: #222222 } /* Generic.Output */\n.highlight .gp { color: #ffffff } /* Generic.Prompt */\n.highlight .gs { color: #ffffff } /* Generic.Strong */\n.highlight .gu { color: #ffffff; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #ffffff } /* Generic.Traceback */\n.highlight .kc { color: #fb660a; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #fb660a; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #fb660a; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #fb660a } /* Keyword.Pseudo */\n.highlight .kr { color: #fb660a; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #cdcaa9; font-weight: bold } /* Keyword.Type */\n.highlight .ld { color: #ffffff } /* Literal.Date */\n.highlight .m { color: #0086f7; font-weight: bold } /* Literal.Number */\n.highlight .s { color: #0086d2 } /* Literal.String */\n.highlight .na { color: #ff0086; font-weight: bold } /* Name.Attribute */\n.highlight .nb { color: #ffffff } /* Name.Builtin */\n.highlight .nc { color: #ffffff } /* Name.Class */\n.highlight .no { color: #0086d2 } /* Name.Constant */\n.highlight .nd { color: #ffffff } /* Name.Decorator */\n.highlight .ni { color: #ffffff } /* Name.Entity */\n.highlight .ne { color: #ffffff } /* Name.Exception */\n.highlight .nf { color: #ff0086; font-weight: bold } /* Name.Function */\n.highlight .nl { color: #ffffff } /* Name.Label */\n.highlight .nn { color: #ffffff } /* Name.Namespace */\n.highlight .nx { color: #ffffff } /* Name.Other */\n.highlight .py { color: #ffffff } /* Name.Property */\n.highlight .nt { color: #fb660a; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #fb660a } /* Name.Variable */\n.highlight .ow { color: #ffffff } /* Operator.Word */\n.highlight .w { color: #888888 } /* Text.Whitespace */\n.highlight .mf { color: #0086f7; font-weight: bold } /* Literal.Number.Float */\n.highlight .mh { color: #0086f7; font-weight: bold } /* Literal.Number.Hex */\n.highlight .mi { color: #0086f7; font-weight: bold } /* Literal.Number.Integer */\n.highlight .mo { color: #0086f7; font-weight: bold } /* Literal.Number.Oct */\n.highlight .sb { color: #0086d2 } /* Literal.String.Backtick */\n.highlight .sc { color: #0086d2 } /* Literal.String.Char */\n.highlight .sd { color: #0086d2 } /* Literal.String.Doc */\n.highlight .s2 { color: #0086d2 } /* Literal.String.Double */\n.highlight .se { color: #0086d2 } /* Literal.String.Escape */\n.highlight .sh { color: #0086d2 } /* Literal.String.Heredoc */\n.highlight .si { color: #0086d2 } /* Literal.String.Interpol */\n.highlight .sx { color: #0086d2 } /* Literal.String.Other */\n.highlight .sr { color: #0086d2 } /* Literal.String.Regex */\n.highlight .s1 { color: #0086d2 } /* Literal.String.Single */\n.highlight .ss { color: #0086d2 } /* Literal.String.Symbol */\n.highlight .bp { color: #ffffff } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #fb660a } /* Name.Variable.Class */\n.highlight .vg { color: #fb660a } /* Name.Variable.Global */\n.highlight .vi { color: #fb660a } /* Name.Variable.Instance */\n.highlight .il { color: #0086f7; font-weight: bold } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/manni.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #0099FF; font-style: italic } /* Comment */\n.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */\n.highlight .k { color: #006699; font-weight: bold } /* Keyword */\n.highlight .o { color: #555555 } /* Operator */\n.highlight .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #009999 } /* Comment.Preproc */\n.highlight .c1 { color: #0099FF; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */\n.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */\n.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */\n.highlight .go { color: #AAAAAA } /* Generic.Output */\n.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #99CC66 } /* Generic.Traceback */\n.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #006699 } /* Keyword.Pseudo */\n.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #FF6600 } /* Literal.Number */\n.highlight .s { color: #CC3300 } /* Literal.String */\n.highlight .na { color: #330099 } /* Name.Attribute */\n.highlight .nb { color: #336666 } /* Name.Builtin */\n.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */\n.highlight .no { color: #336600 } /* Name.Constant */\n.highlight .nd { color: #9999FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #CC00FF } /* Name.Function */\n.highlight .nl { color: #9999FF } /* Name.Label */\n.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #003333 } /* Name.Variable */\n.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #FF6600 } /* Literal.Number.Float */\n.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */\n.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */\n.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */\n.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */\n.highlight .sc { color: #CC3300 } /* Literal.String.Char */\n.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #CC3300 } /* Literal.String.Double */\n.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */\n.highlight .si { color: #AA0000 } /* Literal.String.Interpol */\n.highlight .sx { color: #CC3300 } /* Literal.String.Other */\n.highlight .sr { color: #33AAAA } /* Literal.String.Regex */\n.highlight .s1 { color: #CC3300 } /* Literal.String.Single */\n.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */\n.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #003333 } /* Name.Variable.Class */\n.highlight .vg { color: #003333 } /* Name.Variable.Global */\n.highlight .vi { color: #003333 } /* Name.Variable.Instance */\n.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/murphy.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #606060; font-style: italic } /* Comment */\n.highlight .err { color: #F00000; background-color: #F0A0A0 } /* Error */\n.highlight .k { color: #208090; font-weight: bold } /* Keyword */\n.highlight .o { color: #303030 } /* Operator */\n.highlight .cm { color: #606060; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #507090 } /* Comment.Preproc */\n.highlight .c1 { color: #606060; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #c00000; font-weight: bold; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #208090; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #208090; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #208090; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #0080f0; font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { color: #208090; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #6060f0; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #6000E0; font-weight: bold } /* Literal.Number */\n.highlight .s { background-color: #e0e0ff } /* Literal.String */\n.highlight .na { color: #000070 } /* Name.Attribute */\n.highlight .nb { color: #007020 } /* Name.Builtin */\n.highlight .nc { color: #e090e0; font-weight: bold } /* Name.Class */\n.highlight .no { color: #50e0d0; font-weight: bold } /* Name.Constant */\n.highlight .nd { color: #505050; font-weight: bold } /* Name.Decorator */\n.highlight .ni { color: #800000 } /* Name.Entity */\n.highlight .ne { color: #F00000; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #50e0d0; font-weight: bold } /* Name.Function */\n.highlight .nl { color: #907000; font-weight: bold } /* Name.Label */\n.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #007000 } /* Name.Tag */\n.highlight .nv { color: #003060 } /* Name.Variable */\n.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */\n.highlight .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */\n.highlight .mi { color: #6060f0; font-weight: bold } /* Literal.Number.Integer */\n.highlight .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */\n.highlight .sb { background-color: #e0e0ff } /* Literal.String.Backtick */\n.highlight .sc { color: #8080F0 } /* Literal.String.Char */\n.highlight .sd { color: #D04020 } /* Literal.String.Doc */\n.highlight .s2 { background-color: #e0e0ff } /* Literal.String.Double */\n.highlight .se { color: #606060; font-weight: bold; background-color: #e0e0ff } /* Literal.String.Escape */\n.highlight .sh { background-color: #e0e0ff } /* Literal.String.Heredoc */\n.highlight .si { background-color: #e0e0e0 } /* Literal.String.Interpol */\n.highlight .sx { color: #f08080; background-color: #e0e0ff } /* Literal.String.Other */\n.highlight .sr { color: #000000; background-color: #e0e0ff } /* Literal.String.Regex */\n.highlight .s1 { background-color: #e0e0ff } /* Literal.String.Single */\n.highlight .ss { color: #f0c080 } /* Literal.String.Symbol */\n.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #c0c0f0 } /* Name.Variable.Class */\n.highlight .vg { color: #f08040 } /* Name.Variable.Global */\n.highlight .vi { color: #a0a0f0 } /* Name.Variable.Instance */\n.highlight .il { color: #6060f0; font-weight: bold } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/native.css",
    "content": ".highlight .hll { background-color: #404040 }\n.highlight .c { color: #999999; font-style: italic } /* Comment */\n.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */\n.highlight .g { color: #d0d0d0 } /* Generic */\n.highlight .k { color: #6ab825; font-weight: bold } /* Keyword */\n.highlight .l { color: #d0d0d0 } /* Literal */\n.highlight .n { color: #d0d0d0 } /* Name */\n.highlight .o { color: #d0d0d0 } /* Operator */\n.highlight .x { color: #d0d0d0 } /* Other */\n.highlight .p { color: #d0d0d0 } /* Punctuation */\n.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */\n.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */\n.highlight .gd { color: #d22323 } /* Generic.Deleted */\n.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #d22323 } /* Generic.Error */\n.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #589819 } /* Generic.Inserted */\n.highlight .go { color: #cccccc } /* Generic.Output */\n.highlight .gp { color: #aaaaaa } /* Generic.Prompt */\n.highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */\n.highlight .gt { color: #d22323 } /* Generic.Traceback */\n.highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */\n.highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */\n.highlight .ld { color: #d0d0d0 } /* Literal.Date */\n.highlight .m { color: #3677a9 } /* Literal.Number */\n.highlight .s { color: #ed9d13 } /* Literal.String */\n.highlight .na { color: #bbbbbb } /* Name.Attribute */\n.highlight .nb { color: #24909d } /* Name.Builtin */\n.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */\n.highlight .no { color: #40ffff } /* Name.Constant */\n.highlight .nd { color: #ffa500 } /* Name.Decorator */\n.highlight .ni { color: #d0d0d0 } /* Name.Entity */\n.highlight .ne { color: #bbbbbb } /* Name.Exception */\n.highlight .nf { color: #447fcf } /* Name.Function */\n.highlight .nl { color: #d0d0d0 } /* Name.Label */\n.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */\n.highlight .nx { color: #d0d0d0 } /* Name.Other */\n.highlight .py { color: #d0d0d0 } /* Name.Property */\n.highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #40ffff } /* Name.Variable */\n.highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #666666 } /* Text.Whitespace */\n.highlight .mf { color: #3677a9 } /* Literal.Number.Float */\n.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */\n.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */\n.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */\n.highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */\n.highlight .sc { color: #ed9d13 } /* Literal.String.Char */\n.highlight .sd { color: #ed9d13 } /* Literal.String.Doc */\n.highlight .s2 { color: #ed9d13 } /* Literal.String.Double */\n.highlight .se { color: #ed9d13 } /* Literal.String.Escape */\n.highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */\n.highlight .si { color: #ed9d13 } /* Literal.String.Interpol */\n.highlight .sx { color: #ffa500 } /* Literal.String.Other */\n.highlight .sr { color: #ed9d13 } /* Literal.String.Regex */\n.highlight .s1 { color: #ed9d13 } /* Literal.String.Single */\n.highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */\n.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #40ffff } /* Name.Variable.Class */\n.highlight .vg { color: #40ffff } /* Name.Variable.Global */\n.highlight .vi { color: #40ffff } /* Name.Variable.Instance */\n.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/pastie.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #888888 } /* Comment */\n.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */\n.highlight .k { color: #008800; font-weight: bold } /* Keyword */\n.highlight .cm { color: #888888 } /* Comment.Multiline */\n.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */\n.highlight .c1 { color: #888888 } /* Comment.Single */\n.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */\n.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #aa0000 } /* Generic.Error */\n.highlight .gh { color: #303030 } /* Generic.Heading */\n.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #555555 } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #606060 } /* Generic.Subheading */\n.highlight .gt { color: #aa0000 } /* Generic.Traceback */\n.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #008800 } /* Keyword.Pseudo */\n.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */\n.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */\n.highlight .na { color: #336699 } /* Name.Attribute */\n.highlight .nb { color: #003388 } /* Name.Builtin */\n.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */\n.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */\n.highlight .nd { color: #555555 } /* Name.Decorator */\n.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */\n.highlight .nl { color: #336699; font-style: italic } /* Name.Label */\n.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */\n.highlight .py { color: #336699; font-weight: bold } /* Name.Property */\n.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #336699 } /* Name.Variable */\n.highlight .ow { color: #008800 } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */\n.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */\n.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */\n.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */\n.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */\n.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */\n.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */\n.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */\n.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */\n.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */\n.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */\n.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */\n.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */\n.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */\n.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */\n.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #336699 } /* Name.Variable.Class */\n.highlight .vg { color: #dd7700 } /* Name.Variable.Global */\n.highlight .vi { color: #3333bb } /* Name.Variable.Instance */\n.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/perldoc.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #228B22 } /* Comment */\n.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */\n.highlight .k { color: #8B008B; font-weight: bold } /* Keyword */\n.highlight .cm { color: #228B22 } /* Comment.Multiline */\n.highlight .cp { color: #1e889b } /* Comment.Preproc */\n.highlight .c1 { color: #228B22 } /* Comment.Single */\n.highlight .cs { color: #8B008B; font-weight: bold } /* Comment.Special */\n.highlight .gd { color: #aa0000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #aa0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00aa00 } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #555555 } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #aa0000 } /* Generic.Traceback */\n.highlight .kc { color: #8B008B; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #8B008B; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #8B008B; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #8B008B; font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { color: #8B008B; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #a7a7a7; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #B452CD } /* Literal.Number */\n.highlight .s { color: #CD5555 } /* Literal.String */\n.highlight .na { color: #658b00 } /* Name.Attribute */\n.highlight .nb { color: #658b00 } /* Name.Builtin */\n.highlight .nc { color: #008b45; font-weight: bold } /* Name.Class */\n.highlight .no { color: #00688B } /* Name.Constant */\n.highlight .nd { color: #707a7c } /* Name.Decorator */\n.highlight .ne { color: #008b45; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #008b45 } /* Name.Function */\n.highlight .nn { color: #008b45; text-decoration: underline } /* Name.Namespace */\n.highlight .nt { color: #8B008B; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #00688B } /* Name.Variable */\n.highlight .ow { color: #8B008B } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #B452CD } /* Literal.Number.Float */\n.highlight .mh { color: #B452CD } /* Literal.Number.Hex */\n.highlight .mi { color: #B452CD } /* Literal.Number.Integer */\n.highlight .mo { color: #B452CD } /* Literal.Number.Oct */\n.highlight .sb { color: #CD5555 } /* Literal.String.Backtick */\n.highlight .sc { color: #CD5555 } /* Literal.String.Char */\n.highlight .sd { color: #CD5555 } /* Literal.String.Doc */\n.highlight .s2 { color: #CD5555 } /* Literal.String.Double */\n.highlight .se { color: #CD5555 } /* Literal.String.Escape */\n.highlight .sh { color: #1c7e71; font-style: italic } /* Literal.String.Heredoc */\n.highlight .si { color: #CD5555 } /* Literal.String.Interpol */\n.highlight .sx { color: #cb6c20 } /* Literal.String.Other */\n.highlight .sr { color: #1c7e71 } /* Literal.String.Regex */\n.highlight .s1 { color: #CD5555 } /* Literal.String.Single */\n.highlight .ss { color: #CD5555 } /* Literal.String.Symbol */\n.highlight .bp { color: #658b00 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #00688B } /* Name.Variable.Class */\n.highlight .vg { color: #00688B } /* Name.Variable.Global */\n.highlight .vi { color: #00688B } /* Name.Variable.Instance */\n.highlight .il { color: #B452CD } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/solarized-light.css",
    "content": "/*\nbase03:    #002b36;\nbase02:    #073642;\nbase01:    #586e75;\nbase00:    #657b83;\nbase0:     #839496;\nbase1:     #93a1a1;\nbase2:     #eee8d5;\nbase3:     #fdf6e3;\nyellow:    #b58900;\norange:    #cb4b16;\nred:       #dc322f;\nmagenta:   #d33682;\nviolet:    #6c71c4;\nblue:      #268bd2;\ncyan:      #2aa198;\ngreen:     #859900;\n*/\n\n.highlight         { background: #fdf6e3; color: #657b83; line-height: 1em; font-size: 13px; }\n.highlight .lineno { background-color: #eee8d5; color: #93a1a1; padding-left: .5em; padding-right: .5em; }\n.highlight .hll    { background-color: #eee8d5; } /* Don't know what this is... */\n.highlight .c      { color: #93a1a1; font-style: italic; } /* Comment */\n.highlight .err    { color: #dc322f; } /* Error */\n.highlight .g      { color: #839496; } /* Generic */\n.highlight .k      { color: #859900; } /* Keyword */\n.highlight .l      { color: #839496; } /* Literal */\n.highlight .n      { color: #839496; } /* Name */\n.highlight .o      { color: #859900; } /* Operator */\n.highlight .x      { color: #839496; } /* Other */\n.highlight .p      { color: #839496; } /* Punctuation */\n.highlight .cm     { color: #93a1a1; font-style: italic; } /* Comment.Multiline */\n.highlight .cp     { color: #93a1a1; font-style: italic; } /* Comment.Preproc */\n.highlight .c1     { color: #93a1a1; font-style: italic; } /* Comment.Single */\n.highlight .cs     { color: #93a1a1; font-style: italic; } /* Comment.Special */\n.highlight .gd     { color: #dc322f; } /* Generic.Deleted */\n.highlight .ge     { color: #839496; font-style: italic; } /* Generic.Emph */\n.highlight .gr     { color: #839496; } /* Generic.Error */\n.highlight .gh     { color: #839496; font-weight: bold; } /* Generic.Heading */\n.highlight .gi     { color: #859900; } /* Generic.Inserted */\n.highlight .go     { color: #839496; } /* Generic.Output */\n.highlight .gp     { color: #839496; font-weight: bold; } /* Generic.Prompt */\n.highlight .gs     { color: #839496; font-weight: bold; } /* Generic.Strong */\n.highlight .gu     { color: #839496; font-weight: bold; } /* Generic.Subheading */\n.highlight .gt     { color: #839496; } /* Generic.Traceback */\n.highlight .kc     { color: #839496; } /* Keyword.Constant */\n.highlight .kd     { color: #839496; } /* Keyword.Declaration */\n.highlight .kn     { color: #839496; } /* Keyword.Namespace */\n.highlight .kp     { color: #2aa198; } /* Keyword.Pseudo */\n.highlight .kr     { color: #839496; } /* Keyword.Reserved */\n.highlight .kt     { color: #839496; } /* Keyword.Type */\n.highlight .ld     { color: #839496; } /* Literal.Date */\n.highlight .m      { color: #839496; } /* Literal.Number */\n.highlight .s      { color: #2aa198; } /* Literal.String */\n.highlight .na     { color: #839496; } /* Name.Attribute */\n.highlight .nb     { color: #cb4b16; } /* Name.Builtin */\n.highlight .nc     { color: #839496; } /* Name.Class */\n.highlight .no     { color: #b58900; } /* Name.Constant */\n.highlight .nd     { color: #839496; } /* Name.Decorator */\n.highlight .ni     { color: #839496; } /* Name.Entity */\n.highlight .ne     { color: #839496; } /* Name.Exception */\n.highlight .nf     { color: #268bd2; } /* Name.Function */\n.highlight .nl     { color: #839496; } /* Name.Label */\n.highlight .nn     { color: #cb4b16; } /* Name.Namespace */\n.highlight .nx     { color: #839496; } /* Name.Other */\n.highlight .py     { color: #839496; } /* Name.Property */\n.highlight .nt     { color: #839496; } /* Name.Tag */\n.highlight .nv     { color: #839496; } /* Name.Variable */\n.highlight .ow     { color: #839496; } /* Operator.Word */\n.highlight .w      { color: #839496; } /* Text.Whitespace */\n.highlight .mf     { color: #2aa198; } /* Literal.Number.Float */\n.highlight .mh     { color: #2aa198; } /* Literal.Number.Hex */\n.highlight .mi     { color: #2aa198; } /* Literal.Number.Integer */\n.highlight .mo     { color: #2aa198; } /* Literal.Number.Oct */\n.highlight .sb     { color: #2aa198; } /* Literal.String.Backtick */\n.highlight .sc     { color: #2aa198; } /* Literal.String.Char */\n.highlight .sd     { color: #2aa198; } /* Literal.String.Doc */\n.highlight .s2     { color: #2aa198; } /* Literal.String.Double */\n.highlight .se     { color: #dc322f; } /* Literal.String.Escape */\n.highlight .sh     { color: #2aa198; } /* Literal.String.Heredoc */\n.highlight .si     { color: #2aa198; } /* Literal.String.Interpol */\n.highlight .sx     { color: #2aa198; } /* Literal.String.Other */\n.highlight .sr     { color: #2aa198; } /* Literal.String.Regex */\n.highlight .s1     { color: #2aa198; } /* Literal.String.Single */\n.highlight .ss     { color: #2aa198; } /* Literal.String.Symbol */\n.highlight .bp     { color: #839496; } /* Name.Builtin.Pseudo */\n.highlight .vc     { color: #839496; } /* Name.Variable.Class */\n.highlight .vg     { color: #839496; } /* Name.Variable.Global */\n.highlight .vi     { color: #839496; } /* Name.Variable.Instance */\n.highlight .il     { color: #839496; } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/style.css",
    "content": "/*\n  Author:         Amsul - http://github.com/amsul\n  Description:    CoffeeScript Cookbook stylings\n  Version:        1.0\n  Last Updated:   11 September, 2012\n*/\n\n\n\n/*\n    Font-face\n======================================================================== */\n\n@font-face {\n    font-family: 'Entypo';\n    src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'),\n        url(../fonts/entypo.ttf) format('truetype'),\n        url(../fonts/entypo.svg#EntypoRegular) format('svg');\n}\n\n\n\n\n\n\n/* ========================================================================\n\n    Cross-browser normalize (from HTML5 Boilerplate v4.0)\n\n======================================================================== */\n\n\n\n/*\n    HTML5 element display (old browsers)\n======================================================================== */\n\narticle, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary { display: block; }\naudio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }\naudio:not([controls]) { display: none; height: 0; }\n[hidden] { display: none; }\n\n\n\n/*\n    Base\n======================================================================== */\n\nhtml { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }\n\nhtml, button, input, select, textarea { font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", sans-serif; font-weight: 200; color: #424242; }\n\nbody { margin: 0; }\n\n\n::-moz-selection    { background: #b3d4fc; text-shadow: none; }\n::selection         { background: #b3d4fc; text-shadow: none; }\n\n\n\n\n/*\n    Links\n======================================================================== */\n\na:hover,\na:active {\n    outline: 0;\n}\n\na:focus { outline: thin dotted; }\n\n\n\n\n/*\n    Typography\n======================================================================== */\n\nh1 {\n    font-size: 2em;\n    margin: .67em 0;\n}\n\nh2 {\n    font-size: 1.5em;\n    margin: .83em 0;\n}\n\nh3 {\n    font-size: 1.17em;\n    margin: 1em 0;\n}\n\nh4 {\n    font-size: 1em;\n    margin: 1.33em 0;\n}\n\nh5 {\n    font-size: .83em;\n    margin: 1.67em 0;\n}\n\nh6 {\n    font-size: .75em;\n    margin: 2.33em 0;\n}\n\nabbr[title] { border-bottom: 1px dotted; }\n\nb, strong { font-weight: bold; }\n\nblockquote { margin: 1em 40px; }\n\ndfn { font-style: italic; }\n\nmark { background: #ff0; color: #000; }\n\np, pre { margin: 1em 0; }\n\npre, code, kbd, samp { font-family: 'Courier', 'Monaco', monospace, serif; font-size: 1em; }\n\npre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }\n\nq { quotes: none; }\nq:before, q:after { content: \"\"; content: none; }\n\nsmall { font-size: 80%; }\n\nsub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }\nsup { top: -.5em; }\nsub { bottom: -.25em; }\n\n\n\n\n/*\n    Lists\n======================================================================== */\n\ndl, menu, ol, ul { margin: 1em 0; }\n\ndd { margin: 0 0 0 40px; }\n\nmenu, ol, ul { padding: 0 0 0 40px; }\n\nnav ul,\nnav ol {\n    list-style: none;\n    list-style-image: none;\n}\n\n\n\n\n/*\n    Embedded content\n======================================================================== */\n\nobject, embed, img { max-width: 100%; }\n\nimg { border: 0; -ms-interpolation-mode: bicubic; }\n\nsvg:not(:root) { overflow: hidden; }\n\n\n\n/*\n    Figures\n======================================================================== */\n\nfigure { margin: 0; }\n\n\n\n\n\n/*\n    Forms\n======================================================================== */\n\nform { margin: 0; }\n\nfieldset {\n    border: 1px solid #c0c0c0;\n    margin: 0 2px;\n    padding: .35em .625em .75em;\n}\n\nlegend { border: 0; padding: 0; white-space: normal; }\n\nlabel:hover { cursor: default; }\n\n\nbutton, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; }\n\nbutton,\nhtml input[type=button],\ninput[type=reset],\ninput[type=submit] {\n    -webkit-appearance: button;\n    cursor: pointer;\n}\n\nbutton[disabled], input[disabled] { cursor: default; }\n\nbutton::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }\n\ninput[type=checkbox], input[type=radio] {\n    cursor: pointer;\n    padding: 0;\n}\n\ninput[type=search] {\n    -webkit-appearance: textfield;\n    -webkit-box-sizing: content-box;\n       -moz-box-sizing: content-box;\n            box-sizing: content-box;\n}\n\ntextarea { overflow: auto; vertical-align: top; resize: vertical; }\n\n\n\n\n/*\n    Tables\n======================================================================== */\n\ntable {\n    border-spacing: 0;\n    border-collapse: collapse;\n}\n\n\n\n\n\n\n\n\n\n\n/*\n    ========================================================================\n    ========================================================================\n    ========================================================================\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n/* ========================================================================\n\n    Primary styling\n\n======================================================================== */\n\n\n\n/*\n    Base\n======================================================================== */\n\nbody {\n    font-size: 16px;\n    line-height: 1.5;\n}\n\nhr {\n    display: block;\n    height: 1px;\n    border: 0;\n    border-top: 1px solid #ccc;\n    margin: 1em 0;\n    padding: 0;\n}\n\nimg {\n    vertical-align: middle;\n    height: auto;\n    max-width: 100%;\n}\n\na {\n    cursor: pointer;\n    text-decoration: underline;\n    color: #27ace3;\n}\n\n\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n    font-weight: bold;\n    line-height: 1.2;\n}\n\nh1:first-child,\nh2:first-child,\nh3:first-child,\nh4:first-child,\nh5:first-child,\nh6:first-child,\np:first-child {\n    margin-top: 0;\n}\n\nh1 {\n    font-size: 32px;\n    margin-bottom: .66em;\n}\n\nh2 {\n    font-size: 24px;\n    margin: 1.33em 0 .66em;\n}\n\nh3 {\n    font-size: 20px;\n    margin-bottom: .25em;\n}\n\nh4 {\n    font-size: 18px;\n    margin-bottom: .75em;\n}\n\nh5 {\n    font-size: 16px;\n    margin: 1.5em 0 .75em;\n}\n\nh6 {\n    font-size: 14px;\n    margin: 1.5em 0 .25em;\n}\n\n\n\n/*\n    Lists\n======================================================================== */\n\nul:not(.plain-list) li {\n    margin-bottom: 5px;\n}\n\nul.plain-list,\n.pseudo-list {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n}\n\n.pseudo-list li {\n    position: relative;\n    padding-left: 14px;\n}\n\n.pseudo-list li:before {\n    content: \"\\2013\";\n    position: absolute;\n    margin-left: -12px;\n}\n\n.inline-list li {\n    display: inline-block;\n    margin-right: 20px;\n}\n\n\n\n\n/*\n    Tables\n======================================================================== */\n\ntable {\n    background: #fff;\n    border: 1px solid #ccc;\n    line-height: 1.5;\n\n    -webkit-border-radius: 5px;\n       -moz-border-radius: 5px;\n            border-radius: 5px;\n}\n\nth,\ntd {\n    vertical-align: top;\n    padding: 6px 12px;\n    border-top: 1px solid #e2e2e2;\n    border-right: 1px solid #e2e2e2;\n}\nth:last-child,\ntd:last-child {\n    border-right: 0;\n}\n\nthead th {\n    background: #f5f5f5;\n    border-top: 0;\n}\nthead th:first-child {\n    -webkit-border-radius: 5px 0 0 0;\n       -moz-border-radius: 5px 0 0 0;\n            border-radius: 5px 0 0 0;\n}\nthead th:last-child {\n    -webkit-border-radius: 0 5px 0 0;\n       -moz-border-radius: 0 5px 0 0;\n            border-radius: 0 5px 0 0;\n}\n\ntbody th,\ntbody td {\n    font-size: 12px;\n}\n\ntbody tr:nth-child(even) th,\ntbody tr:nth-child(even) td {\n    background-color: #f9f9f9;\n}\n\ntbody tr:last-child th:first-child,\ntbody tr:last-child td:first-child {\n    -webkit-border-radius: 0 0 0 5px;\n       -moz-border-radius: 0 0 0 5px;\n            border-radius: 0 0 0 5px;\n}\n\ntbody tr:last-child th:last-child,\ntbody tr:last-child td:last-child {\n    -webkit-border-radius: 0 0 5px 0;\n       -moz-border-radius: 0 0 5px 0;\n            border-radius: 0 0 5px 0;\n}\n\n\n\n\n/*\n    Form elements\n======================================================================== */\n\nfieldset {\n    border: 0;\n    margin: 0 0 14px;\n    padding: 0;\n}\n\n\ninput[type=checkbox],\ninput[type=radio] {\n    margin-right: 5px;\n}\n\nlabel:hover {\n    color: #27ace3;\n}\n\n\n\n\n/*\n    Code blocks\n======================================================================== */\n\npre { display: table; width: 100%; margin: 0; padding: 24px; }\n\npre > code { display: block; }\n\n\n\n\n\n\n\n\n\n\n/*\n    Site structure\n======================================================================== */\n\n.container {\n    margin-left: 444px;\n    min-width: 666px;\n    max-width: 1000px;\n    padding: 40px;\n\n    -webkit-box-sizing: border-box;\n       -moz-box-sizing: border-box;\n            box-sizing: border-box;\n}\n\n.header a,\n.navigation a {\n    text-decoration: none;\n}\n\n.navigation:not(.pages-nav) a:hover {\n    text-decoration: underline;\n}\n\n\n/** Header **/\n\n.header {\n    margin-bottom: 32px;\n}\n\n.header .entypo {\n    font-size: 82px;\n    line-height: 0.2;\n    margin-right: 10px;\n    color: #27ace3;\n    position: relative;\n    top: -2px;\n}\n\n.header .title {\n    background: url(../images/title.png) no-repeat 0 0 transparent;\n    width: 421px;\n    height: 33px;\n    display: inline-block;\n    vertical-align: top;\n}\n\n\n/** Footer **/\n\n.footer {\n    border-top: 1px solid #eee;\n    padding-top: 42px;\n    font-size: 12px;\n    color: #888;\n}\n\n\n\n/** Content blocks and sections **/\n\n.content {\n    margin-right: 250px;\n}\n\n.content-block {\n    margin-bottom: 100px;\n}\n\n.content-full {\n    width: auto;\n}\n\n\n\n\n\n\n\n\n/*\n    Sidebar\n======================================================================== */\n\n#sidebar {\n    background: #f0f5f6;\n    border-right: 1px solid #e0e5e6;\n    position: fixed;\n    top: 0;\n    left: 0;\n    bottom: 0;\n    width: 444px;\n    padding: 40px 20px 40px 40px;\n    font-size: 12px;\n    overflow-y: scroll;\n\n    -webkit-box-sizing: border-box;\n       -moz-box-sizing: border-box;\n            box-sizing: border-box;\n}\n\n.sidebar-block {\n    margin-bottom: 54px;\n}\n\n.sidebar-block .navigation a {\n    color: #424242;\n}\n\n.block-short {\n    margin-bottom: 24px;\n}\n\n\n.sidebar-subtitle {\n    font-size: 14px;\n    margin-bottom: 6px;\n}\n\n\n/** Pages nav **/\n\n.pages-nav .nav-link {\n    text-transform: uppercase;\n}\n.pages-nav .nav-link:hover {\n    text-decoration: none;\n    color: #27ace3;\n}\n\n.pages-nav .entypo {\n    font-size: 36px;\n    vertical-align: baseline;\n    position: relative;\n    top: 4px;\n    margin-right: 8px;\n    line-height: .5;\n}\n\n.home-nav .nav-link {\n    text-transform: none;\n}\n.home-nav .entypo {\n    margin-right: 4px;\n}\n\n\n\n/** Chapters index **/\n\n.chapters-list {\n    margin: 0;\n}\n\n.chapter-title {\n    color: #424242\n}\n\n\n.recipes-list {\n    line-height: 1.25;\n    margin-bottom: 24px;\n}\n\n.recipes-list .list-item {\n    color: #888;\n}\n\n\n\n\n\n\n\n/*\n    Recipes page\n======================================================================== */\n\n.recipe-content h1 {\n    font-size: 28px;\n}\n\n.recipe-content h2 {\n    font-size: 20px;\n    margin-bottom: .5em;\n}\n\n.recipe-content p {\n    margin-top: 0;\n}\n\n\n\n\n\n/*\n    Active page\n======================================================================== */\n\n.page-active {\n    position: relative;\n    background: #fff;\n    padding-right: 24px;\n\n    -webkit-border-radius: 2px;\n       -moz-border-radius: 2px;\n            border-radius: 2px;\n}\n\n.page-active:after {\n    content: 'M';\n    position: absolute;\n    top: 4px;\n    right: 0;\n    font-family: 'Entypo';\n    font-size: 36px;\n    line-height: 6px;\n    color: #666;\n}\n\n.recipes-list .page-active:after {\n    top: 1px;\n}\n\n\n\n\n\n\n\n\n\n/*\n    ========================================================================\n    ========================================================================\n    ========================================================================\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n\n/*\n    Non-semantic helper classes\n======================================================================== */\n\n.dimmed, a.dimmed { color: #888; }\n\n.warning { color: red; }\n\n\n.hidden { display: none; visibility: hidden; }\n.invisible { visibility: hidden; }\n\n\n.thin { font-weight: 100; }\n\n.entypo {\n    font-family: 'Entypo';\n    line-height: 1;\n    text-transform: initial;\n}\n\n\n.alignleft { float: left; }\n.alignright { float: right; }\n\n\n.clear:before, .clear:after { content: \" \"; display: table; }\n.clear:after { clear: both; }\n.clear { *zoom: 1; }\n\n\n.ir {\n    background-color: transparent;\n    border: 0;\n    overflow: hidden;\n    *text-indent: -9999px;\n}\n.ir:before {\n    content: \"\";\n    display: block;\n    width: 0;\n    height: 100%;\n}\n\n\n\n\n\n\n\n\n\n/*\n    Code highlighting\n======================================================================== */\n\n/*\nbase03:    #002b36;\nbase02:    #073642;\nbase01:    #586e75;\nbase00:    #657b83;\nbase0:     #839496;\nbase1:     #93a1a1;\nbase2:     #eee8d5;\nbase3:     #fdf6e3;\nyellow:    #b58900;\norange:    #cb4b16;\nred:       #dc322f;\nmagenta:   #d33682;\nviolet:    #6c71c4;\nblue:      #268bd2;\ncyan:      #2aa198;\ngreen:     #859900;\n*/\n\n.highlight {\n    background: #f8f8f8;\n    font-size: 14px;\n    overflow-x: scroll;\n    margin-right: -250px;\n    margin-bottom: 36px;\n}\n.highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #408080; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #008000; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #008000 } /* Keyword.Pseudo */\n.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #B00040 } /* Keyword.Type */\n.highlight .m { color: #666666 } /* Literal.Number */\n.highlight .s { color: #BA2121 } /* Literal.String */\n.highlight .na { color: #7D9029 } /* Name.Attribute */\n.highlight .nb { color: #008000 } /* Name.Builtin */\n.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.highlight .no { color: #880000 } /* Name.Constant */\n.highlight .nd { color: #AA22FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0000FF } /* Name.Function */\n.highlight .nl { color: #A0A000 } /* Name.Label */\n.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #19177C } /* Name.Variable */\n.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #666666 } /* Literal.Number.Float */\n.highlight .mh { color: #666666 } /* Literal.Number.Hex */\n.highlight .mi { color: #666666 } /* Literal.Number.Integer */\n.highlight .mo { color: #666666 } /* Literal.Number.Oct */\n.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n.highlight .sc { color: #BA2121 } /* Literal.String.Char */\n.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.highlight .sx { color: #008000 } /* Literal.String.Other */\n.highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n.highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n.highlight .ss { color: #19177C } /* Literal.String.Symbol */\n.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #19177C } /* Name.Variable.Class */\n.highlight .vg { color: #19177C } /* Name.Variable.Global */\n.highlight .vi { color: #19177C } /* Name.Variable.Instance */\n.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */\n\n\n\n\n/* ==========================================================================\n\n    Media Queries\n\n========================================================================== */\n\n@media (max-width: 1110px) {\n\n    body:after {\n        content: 'narrow';\n        display: none;\n    }\n\n    #sidebar {\n        position: absolute;\n        bottom: auto;\n        border-bottom: 1px solid #e0e5e6;\n    }\n\n}\n\n\n\n\n\n\n\n/*\n    Print media queries\n======================================================================== */\n\n@media print {\n    * {\n        background: transparent !important;\n        color: #000 !important;\n        box-shadow:none !important;\n        text-shadow: none !important;\n    }\n    a, a:visited { text-decoration: underline; }\n    a[href]:after { content: \" (\" attr(href) \")\"; }\n    abbr[title]:after { content: \" (\" attr(title) \")\"; }\n    .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after { content: \"\"; }\n    pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }\n    thead { display: table-header-group; }\n    tr, img { page-break-inside: avoid; }\n    img { max-width: 100% !important; }\n    @page { margin: 0.5cm; }\n    p, h2, h3 { orphans: 3; widows: 3; }\n    h2, h3 { page-break-after: avoid; }\n}\n\n\n"
  },
  {
    "path": "css/tango.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #8f5902; font-style: italic } /* Comment */\n.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */\n.highlight .g { color: #000000 } /* Generic */\n.highlight .k { color: #204a87; font-weight: bold } /* Keyword */\n.highlight .l { color: #000000 } /* Literal */\n.highlight .n { color: #000000 } /* Name */\n.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */\n.highlight .x { color: #000000 } /* Other */\n.highlight .p { color: #000000; font-weight: bold } /* Punctuation */\n.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */\n.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #a40000 } /* Generic.Deleted */\n.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #ef2929 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #000000; font-style: italic } /* Generic.Output */\n.highlight .gp { color: #8f5902 } /* Generic.Prompt */\n.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */\n.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */\n.highlight .ld { color: #000000 } /* Literal.Date */\n.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */\n.highlight .s { color: #4e9a06 } /* Literal.String */\n.highlight .na { color: #c4a000 } /* Name.Attribute */\n.highlight .nb { color: #204a87 } /* Name.Builtin */\n.highlight .nc { color: #000000 } /* Name.Class */\n.highlight .no { color: #000000 } /* Name.Constant */\n.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */\n.highlight .ni { color: #ce5c00 } /* Name.Entity */\n.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #000000 } /* Name.Function */\n.highlight .nl { color: #f57900 } /* Name.Label */\n.highlight .nn { color: #000000 } /* Name.Namespace */\n.highlight .nx { color: #000000 } /* Name.Other */\n.highlight .py { color: #000000 } /* Name.Property */\n.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #000000 } /* Name.Variable */\n.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */\n.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */\n.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */\n.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */\n.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */\n.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */\n.highlight .sc { color: #4e9a06 } /* Literal.String.Char */\n.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */\n.highlight .se { color: #4e9a06 } /* Literal.String.Escape */\n.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */\n.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */\n.highlight .sx { color: #4e9a06 } /* Literal.String.Other */\n.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */\n.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */\n.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */\n.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #000000 } /* Name.Variable.Class */\n.highlight .vg { color: #000000 } /* Name.Variable.Global */\n.highlight .vi { color: #000000 } /* Name.Variable.Instance */\n.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/trac.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #999988; font-style: italic } /* Comment */\n.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */\n.highlight .k { font-weight: bold } /* Keyword */\n.highlight .o { font-weight: bold } /* Operator */\n.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */\n.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #aa0000 } /* Generic.Error */\n.highlight .gh { color: #999999 } /* Generic.Heading */\n.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #555555 } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #aaaaaa } /* Generic.Subheading */\n.highlight .gt { color: #aa0000 } /* Generic.Traceback */\n.highlight .kc { font-weight: bold } /* Keyword.Constant */\n.highlight .kd { font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { font-weight: bold } /* Keyword.Pseudo */\n.highlight .kr { font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */\n.highlight .m { color: #009999 } /* Literal.Number */\n.highlight .s { color: #bb8844 } /* Literal.String */\n.highlight .na { color: #008080 } /* Name.Attribute */\n.highlight .nb { color: #999999 } /* Name.Builtin */\n.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */\n.highlight .no { color: #008080 } /* Name.Constant */\n.highlight .ni { color: #800080 } /* Name.Entity */\n.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */\n.highlight .nn { color: #555555 } /* Name.Namespace */\n.highlight .nt { color: #000080 } /* Name.Tag */\n.highlight .nv { color: #008080 } /* Name.Variable */\n.highlight .ow { font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #009999 } /* Literal.Number.Float */\n.highlight .mh { color: #009999 } /* Literal.Number.Hex */\n.highlight .mi { color: #009999 } /* Literal.Number.Integer */\n.highlight .mo { color: #009999 } /* Literal.Number.Oct */\n.highlight .sb { color: #bb8844 } /* Literal.String.Backtick */\n.highlight .sc { color: #bb8844 } /* Literal.String.Char */\n.highlight .sd { color: #bb8844 } /* Literal.String.Doc */\n.highlight .s2 { color: #bb8844 } /* Literal.String.Double */\n.highlight .se { color: #bb8844 } /* Literal.String.Escape */\n.highlight .sh { color: #bb8844 } /* Literal.String.Heredoc */\n.highlight .si { color: #bb8844 } /* Literal.String.Interpol */\n.highlight .sx { color: #bb8844 } /* Literal.String.Other */\n.highlight .sr { color: #808000 } /* Literal.String.Regex */\n.highlight .s1 { color: #bb8844 } /* Literal.String.Single */\n.highlight .ss { color: #bb8844 } /* Literal.String.Symbol */\n.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #008080 } /* Name.Variable.Class */\n.highlight .vg { color: #008080 } /* Name.Variable.Global */\n.highlight .vi { color: #008080 } /* Name.Variable.Instance */\n.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/vim.css",
    "content": ".highlight .hll { background-color: #222222 }\n.highlight .c { color: #000080 } /* Comment */\n.highlight .err { color: #cccccc; border: 1px solid #FF0000 } /* Error */\n.highlight .g { color: #cccccc } /* Generic */\n.highlight .k { color: #cdcd00 } /* Keyword */\n.highlight .l { color: #cccccc } /* Literal */\n.highlight .n { color: #cccccc } /* Name */\n.highlight .o { color: #3399cc } /* Operator */\n.highlight .x { color: #cccccc } /* Other */\n.highlight .p { color: #cccccc } /* Punctuation */\n.highlight .cm { color: #000080 } /* Comment.Multiline */\n.highlight .cp { color: #000080 } /* Comment.Preproc */\n.highlight .c1 { color: #000080 } /* Comment.Single */\n.highlight .cs { color: #cd0000; font-weight: bold } /* Comment.Special */\n.highlight .gd { color: #cd0000 } /* Generic.Deleted */\n.highlight .ge { color: #cccccc; font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00cd00 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { color: #cccccc; font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #cdcd00 } /* Keyword.Constant */\n.highlight .kd { color: #00cd00 } /* Keyword.Declaration */\n.highlight .kn { color: #cd00cd } /* Keyword.Namespace */\n.highlight .kp { color: #cdcd00 } /* Keyword.Pseudo */\n.highlight .kr { color: #cdcd00 } /* Keyword.Reserved */\n.highlight .kt { color: #00cd00 } /* Keyword.Type */\n.highlight .ld { color: #cccccc } /* Literal.Date */\n.highlight .m { color: #cd00cd } /* Literal.Number */\n.highlight .s { color: #cd0000 } /* Literal.String */\n.highlight .na { color: #cccccc } /* Name.Attribute */\n.highlight .nb { color: #cd00cd } /* Name.Builtin */\n.highlight .nc { color: #00cdcd } /* Name.Class */\n.highlight .no { color: #cccccc } /* Name.Constant */\n.highlight .nd { color: #cccccc } /* Name.Decorator */\n.highlight .ni { color: #cccccc } /* Name.Entity */\n.highlight .ne { color: #666699; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #cccccc } /* Name.Function */\n.highlight .nl { color: #cccccc } /* Name.Label */\n.highlight .nn { color: #cccccc } /* Name.Namespace */\n.highlight .nx { color: #cccccc } /* Name.Other */\n.highlight .py { color: #cccccc } /* Name.Property */\n.highlight .nt { color: #cccccc } /* Name.Tag */\n.highlight .nv { color: #00cdcd } /* Name.Variable */\n.highlight .ow { color: #cdcd00 } /* Operator.Word */\n.highlight .w { color: #cccccc } /* Text.Whitespace */\n.highlight .mf { color: #cd00cd } /* Literal.Number.Float */\n.highlight .mh { color: #cd00cd } /* Literal.Number.Hex */\n.highlight .mi { color: #cd00cd } /* Literal.Number.Integer */\n.highlight .mo { color: #cd00cd } /* Literal.Number.Oct */\n.highlight .sb { color: #cd0000 } /* Literal.String.Backtick */\n.highlight .sc { color: #cd0000 } /* Literal.String.Char */\n.highlight .sd { color: #cd0000 } /* Literal.String.Doc */\n.highlight .s2 { color: #cd0000 } /* Literal.String.Double */\n.highlight .se { color: #cd0000 } /* Literal.String.Escape */\n.highlight .sh { color: #cd0000 } /* Literal.String.Heredoc */\n.highlight .si { color: #cd0000 } /* Literal.String.Interpol */\n.highlight .sx { color: #cd0000 } /* Literal.String.Other */\n.highlight .sr { color: #cd0000 } /* Literal.String.Regex */\n.highlight .s1 { color: #cd0000 } /* Literal.String.Single */\n.highlight .ss { color: #cd0000 } /* Literal.String.Symbol */\n.highlight .bp { color: #cd00cd } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #00cdcd } /* Name.Variable.Class */\n.highlight .vg { color: #00cdcd } /* Name.Variable.Global */\n.highlight .vi { color: #00cdcd } /* Name.Variable.Instance */\n.highlight .il { color: #cd00cd } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "css/vs.css",
    "content": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #008000 } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #0000ff } /* Keyword */\n.highlight .cm { color: #008000 } /* Comment.Multiline */\n.highlight .cp { color: #0000ff } /* Comment.Preproc */\n.highlight .c1 { color: #008000 } /* Comment.Single */\n.highlight .cs { color: #008000 } /* Comment.Special */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gh { font-weight: bold } /* Generic.Heading */\n.highlight .gp { font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { font-weight: bold } /* Generic.Subheading */\n.highlight .kc { color: #0000ff } /* Keyword.Constant */\n.highlight .kd { color: #0000ff } /* Keyword.Declaration */\n.highlight .kn { color: #0000ff } /* Keyword.Namespace */\n.highlight .kp { color: #0000ff } /* Keyword.Pseudo */\n.highlight .kr { color: #0000ff } /* Keyword.Reserved */\n.highlight .kt { color: #2b91af } /* Keyword.Type */\n.highlight .s { color: #a31515 } /* Literal.String */\n.highlight .nc { color: #2b91af } /* Name.Class */\n.highlight .ow { color: #0000ff } /* Operator.Word */\n.highlight .sb { color: #a31515 } /* Literal.String.Backtick */\n.highlight .sc { color: #a31515 } /* Literal.String.Char */\n.highlight .sd { color: #a31515 } /* Literal.String.Doc */\n.highlight .s2 { color: #a31515 } /* Literal.String.Double */\n.highlight .se { color: #a31515 } /* Literal.String.Escape */\n.highlight .sh { color: #a31515 } /* Literal.String.Heredoc */\n.highlight .si { color: #a31515 } /* Literal.String.Interpol */\n.highlight .sx { color: #a31515 } /* Literal.String.Other */\n.highlight .sr { color: #a31515 } /* Literal.String.Regex */\n.highlight .s1 { color: #a31515 } /* Literal.String.Single */\n.highlight .ss { color: #a31515 } /* Literal.String.Symbol */\n"
  },
  {
    "path": "designers-guide.md",
    "content": "---\nlayout: default\ntitle: Designer's Guide\n---\n\n# Designer's Guide\n\nStart with the [Developer's Guide]({{ site.baseurl }}/developers-guide) to get a test version of the cookbook up and running on your machine, and get started!\n\nIf you have been waiting for your chance to literally _write the designer's guide_ for a website that is also a cookbook about CoffeeScript...\n\n...welcome home.\n\nThe default color scheme is based on [Solarized](http://ethanschoonover.com/solarized) by Ethan Schoonover.\n"
  },
  {
    "path": "developers-guide.md",
    "content": "---\nlayout: default\ntitle: Developer's Guide\n---\n\n# Developer's Guide\n\n_Please help out by updating this page_\n\n### Operating System\n\nIt works on Mac OS X. Probably works without any changes or issues on Linux.\nA masochist could probably get it working on Windows.\n\n## Installation\n\n### Clone the repo\n\n{% highlight bash %}\ngit clone git://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com.git\n{% endhighlight %}\n\n### Ruby environment\n\nYou probably want to have [RVM](http://rvm.io/) installed.\n\nThe project includes a `.ruby-version` file locked to\n*1.9.3* since that is what Github Pages are currently using.\n\nThere is also a `.ruby-gemset` that is set to *coffeescript-cookbook*\n\n### Required dependencies\n\nWe are using [Bundler](http://bundler.io/) to install the required Ruby dependencies.\n\n{% highlight bash %}\nbundle install\n{% endhighlight %}\n\n#### Install pygments\n\nYou'll need python installed for this.\nMacs and most Linuces come with it preinstalled.\n\n{% highlight bash %}\neasy_install pygments # for syntax highlighting\n{% endhighlight %}\n\n## Building and Viewing the Website\n\nOpen a terminal window, cd into the project folder and run `foreman start` from the project root.\n\n{% highlight bash %}\nforeman start\n{% endhighlight %}\n\nLeave this window running while you work.\nAny time you change a file, jekyll will rerender it into the `_site` folder.\n\nOpen a browser and visit <http://localhost:4000/> and you should see the site.\n\n## Minutiae and Other Trivialities\n\nJekyll can take a second or two to catch up when you save a file. \nIf you edit a file and don't see the changes in your browser, give it a second or two and try again.\nAs long as it prints `Successfully generated site` you should be alright.\n"
  },
  {
    "path": "index.html",
    "content": "---\nlayout: default\ntitle: Home\n---\n\n\n<h2>Welcome to the CoffeeScript Cookbook!</h2>\n<p>CoffeeScript recipes for the community <em>by</em> the community. Head over to the <a href=\"{{ site.baseurl }}/contributing\">Contribute</a> page and see what you can do to help out!</p>\n\n\n\n"
  },
  {
    "path": "js/scripts.js",
    "content": "\n/*jshint browser: true, devel: true, debug: true */\n\n\n(function( window, document, undefined ) {\n\n    var activePage, position, sidebar,\n        narrowScreen = ( window.getComputedStyle( document.body, ':after' ).getPropertyValue( 'content' ) === 'narrow' ) ? true : false\n\n\n    // if it's not the index page and not a narrow screen\n    if ( window.location.pathname.length && !narrowScreen ) {\n\n        // get the sidebar\n        sidebar = document.getElementById( 'sidebar' )\n\n        // query the dom for the active page\n        activePage = document.getElementsByClassName( 'page-active' )\n\n        // if an active page was found\n        if ( activePage.length ) {\n\n            // get the offset position and give a padding of 80px\n            position = activePage[0].offsetTop - 80\n\n            // set the scroll position of the sidebar to the new position\n            sidebar.scrollTop = position\n        }\n    }\n\n\n})( window, document )\n\n"
  },
  {
    "path": "license.md",
    "content": "---\nlayout: default\ntitle: License\n---\n\ncoffeescript-cookbook.github.io is licensed under the [Creative Commons Attribution 3.0 Unported (CC BY 3.0)](http://creativecommons.org/licenses/by/3.0/) license. By submitting information to this site you agree to grant this license to all users of the site, and that your editing of the authors page constitutes satisfactory attribution.\n\n[LICENSE]({{ site.baseurl }}/LICENSE-CC-BY)\n"
  },
  {
    "path": "recipe-template.md",
    "content": "---\nlayout: default\ntitle: Recipe Template\n---\n\n## Sample recipe template\n\nCreate a new `my-recipe.md` file and use this text as a start.\n\n{% highlight text %}\n---\nlayout: recipe\ntitle: Title of The Recipe\nchapter: Chapter Name\n---\n## Problem\n\nYou have a problem.\n\n## Solution\n\nDo this about it.\n\n## Discussion\n\nHere's why.\n{% endhighlight %}\n"
  },
  {
    "path": "terms-of-use.md",
    "content": "---\nlayout: default\ntitle: Terms of Use\n---\n\n"
  },
  {
    "path": "wanted-recipes.md",
    "content": "---\nlayout: default\ntitle: Wanted Recipes\n---\n# Wanted Recipes\n\nHere's a list of recipes we think we need. Pick one, implement it, and remove it from the page. Alternately, add a quick note here for a recipe you'd like to see so someone else can add it.\n\nIn the notes below, \"JS\" means the recipe is just a simple pass-through to an existing JavaScript method.\n\n## Syntax\n\n* Ensuring variables are closed over # with \"do\"\n\n## Strings\n\n* HTML methods # JS .sup(), .sub(), .blink(), .link(url), etc. May not exist in your JS implementation!\n* substr\n{% highlight coffeescript %}\nstr.substr(x,y)  === str[x..x+y-1] === str[x...x+y]\n{% endhighlight %}\n* substring\n{% highlight coffeescript %}\nstr.substring(x,y) === str.slice(x,y)  === str[x..y-1] === str[x...y]\n{% endhighlight %}\n* Replacing substrings\n\n## Arrays\n\n* Testing every element in an array\n{% highlight coffeescript %}\nevens = (x for x in [0..10] by 2)\neven = (x) -> x % 2 == 0\nevens.every even\n# => true\n{% endhighlight %}\n* Detecting presence of matching items in an array\n{% highlight coffeescript %}\n[1..10].some (x) -> x % 2 == 0 # => true\n{% endhighlight %}\n\n## Math\n\n* square root # JS Math.sqrt\n* Constants # JS Math.PI, Math.E\n* floor, ceil, round # JS Math.floor, Math.ceil, Math.round\n* Raising a number to a power # JS Math.pow(x, y)\n* Logarithms # Math.log\n* Finding the base-n log # Math.log(num) / Math.log(base)\n* Exponents # Math.exp\n* Check if a credit card is valid (checksum, Luhn algorithm)\n\n## Functions\n\n* Nested functions\n\n{% highlight coffeescript %}\nhypotenuse = (a, b) ->\n  square = (x) -> x * x\n  Math.sqrt(square(a) + square(b))\n\nconsole.log hypotenuse 3, 4\n# => 5\n\nsquare 5\n# ReferenceError: square is not defined\n{% endhighlight %}\n\n* Optional Arguments # use arg? to detect presence: if arg=0, arg? == true\n\n{% highlight coffeescript %}\nfoo = (a, b=42, c) -> if c? then a*b*c else a*b\n[Function]\nfoo 6\n# => 252\nfoo 1, 2\n# => 2\nfoo 1, 2, 3\n# => 6\n{% endhighlight %}\n\n## Design patterns\n\n* Creational Patterns\n  * Abstract Factory\n  * Prototype\n\n* Structural Patterns\n  * Adapter\n  * Composite\n  * Facade\n  * Flyweight\n  * Proxy\n\n* Behavioral Patterns\n  * Chain of Responsibility\n  * Iterator\n  * Mediator\n  * Observer\n  * State\n  * Template Method\n  * Visitor\n\n## Databases\n\n* Couch access\n* MySQL/PostgreSQL access\n"
  }
]