[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nbin/.DS_Store\nlib/.DS_Store\nlib/libraries/.DS_Store\nlib/rad/.DS_Store\nlib/libraries/*/*.*"
  },
  {
    "path": "History.txt",
    "content": "== 0.3.0 2008-09-22\n* Pushing to rubyforge.. \n\t- added rad install arduino\n\t- added rad test arduino\n\n== 0.2.5 2008-07-21\n* 1ish large post Bastille Day update:\n\t- added i2c capability\n\t- added actual Wire library until workaround for os_x file caching is found\n\t- added DS1307 and OneWire libraries\n\t- added cool instance variable style global variables\n\t- added array and define methods\n\t- added def setup method, which added to setup \n\t- added numerous examples\n\n== 0.2.4 2008-07-12\n* 1ish large update:\n\t- added incredibly primitive tests \n\t- added 11 sketch examples which are compiled or compiled/uploaded\n\t\t- use rake test:compile or rake test:upload\n\t\t- can also use the following to run an example (make:compile also works)\n\t\t- make:upload sketch=examples/hello_servos\n\n== 0.2.3 2008-07-10\n* Manyish updates:\n\t- updated servo library to support position parameter\n\t- plus:\n\t- addition of plugins\n\t- latest and greatest lcd libraries for pa and sf\n\t- multiple methods \n\t- addition of rad_process and rad_rewrite methods methods\n\t- options for :device => servo, button, lcd, \n\t- and many more\n\n== 0.2.2 2008-04-27\n* 2ish updates:\n\t- updated makefile template and cli to expect arduino-0011\n\t- applied David Michael's patch for longs\n\t\n== 0.2.1 2008-04-02\n* 6ish updates:\n\t- applied Brian Riley's SWSerLCDpa patch\n\t- experimental libraries system in vendor/libraries\n\t- fixed require 'yaml' bug in makefile.rb\n\t- enhancements to the rad command: can set project config.\n\t- added first significant documentation \n\t- added examples directory to the website\n\n== 0.2.0 2008-03-15\n* 8ish updates, some major:\n\t* fixed regular serial support\n\t* class method for writing functions in assembler\n\t* applied Scott Windsor's patch for software serial support\n\t* added support for HIGH/LOW/ON/OFF constants\n\t* add an option for skipping the reset prompt on rake make:upload\n\t* changed default arduino location to be more realistic\n\t* put screencasts #1 and #2 on rad.rubyforge.org\n\t* put google analytics on rad.rubyforge.org\n\t\n== 0.1.1 2007-10-29\n* 2 major fixes:\n  * explicitly specify path to arduino avr tools (this was broken on systems that didn't have the avr toolchain installed, oops)\n  * add explicit path to avrdude.conf in the upload make target\n\n== 0.1.0 2007-10-28\n* 4ish major updates:\n  * Arduino interop has been updated, and consequently now requires Arduino 0010:\n    * new Makefile imported, with new configuration items (see below)\n    * main() function added to C++ output\n    * make:upload rake task has been updated\n  * C++ generation has been changed to produce a more readable output\n  * configuration file changes:\n    * hardware\n      * fixed typo in serial_port key\n      * added mcu key to specify atmega8/atmega168.  Defaults to atmega168\n      * changed serial_port to /dev/tty.usbserial*, which will pick the first device that matches that blob\n    * software\n      * updated arduino_root for 0010\n* 2 major enhancement:\n  * gem should now correctly install RubyToC\n  * can now enable internal pull-up resistors on input pins by passing the :pullup => true parameter to input_pin\n* 2 minor enhancements:\n  * cleanups in makefile.rb\n  * serial_print_str method added; can now send strings over the serial port\n\n== 0.0.4 2007-07-24\n\n* 1 major enhancement:\n  * serial_begin class method\n  \n== 0.0.3 2007-07-23\n\n* 1 major enhancement:\n  * bug fix in blink helper method\n  \n== 0.0.2 2007-07-23\n\n* 1 major enhancement:\n  * blink helper method\n  \n== 0.0.1 2007-07-22\n\n* 1 major enhancement:\n  * Initial release\n  * most features of the Arduino software library functional\n  * experimental implementation of the serial interface\n  * complete rake-based build, compile, and upload cycle\n\n\n"
  },
  {
    "path": "License.txt",
    "content": "\n                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n\n\n"
  },
  {
    "path": "Manifest.txt",
    "content": "History.txt\nLicense.txt\nManifest.txt\nREADME.rdoc\nRakefile\nbin/rad\nlib/examples/add_hysteresis.rb\nlib/examples/basic_blink.rb\nlib/examples/blink_m_address_assignment.rb\nlib/examples/blink_m_hello.rb\nlib/examples/blink_m_multi.rb\nlib/examples/blink_with_serial.rb\nlib/examples/configure_pa_lcd_boot.rb\nlib/examples/debounce_methods.rb\nlib/examples/external_variable_fu.rb\nlib/examples/external_variables.rb\nlib/examples/first_sound.rb\nlib/examples/frequency_generator.rb\nlib/examples/hello_array.rb\nlib/examples/hello_array2.rb\nlib/examples/hello_array_eeprom.rb\nlib/examples/hello_clock.rb\nlib/examples/hello_eeprom.rb\nlib/examples/hello_eeprom_lcdpa.rb\nlib/examples/hello_format_print.rb\nlib/examples/hello_lcd_charset.rb\nlib/examples/hello_pa_lcd.rb\nlib/examples/hello_servos.rb\nlib/examples/hello_spectra_sound.rb\nlib/examples/hello_world.rb\nlib/examples/hello_xbee.rb\nlib/examples/hysteresis_duel.rb\nlib/examples/i2c_with_clock_chip.rb\nlib/examples/midi_beat_box.rb\nlib/examples/midi_scales.rb\nlib/examples/motor_knob.rb\nlib/examples/servo_buttons.rb\nlib/examples/servo_calibrate_continuous.rb\nlib/examples/servo_throttle.rb\nlib/examples/software_serial.rb\nlib/examples/sparkfun_lcd.rb\nlib/examples/spectra_soft_pot.rb\nlib/examples/times_method.rb\nlib/examples/toggle.rb\nlib/examples/twitter.rb\nlib/examples/two_wire.rb\nlib/libraries/AFSoftSerial/AFSoftSerial.cpp\nlib/libraries/AFSoftSerial/AFSoftSerial.h\nlib/libraries/AFSoftSerial/keywords.txt\nlib/libraries/AF_XPort/AF_XPort.cpp\nlib/libraries/AF_XPort/AF_XPort.h\nlib/libraries/DS1307/DS1307.cpp\nlib/libraries/DS1307/DS1307.h\nlib/libraries/DS1307/keywords.txt\nlib/libraries/FrequencyTimer2/FrequencyTimer2.cpp\nlib/libraries/FrequencyTimer2/FrequencyTimer2.h\nlib/libraries/FrequencyTimer2/keywords.txt\nlib/libraries/I2CEEPROM/I2CEEPROM.cpp\nlib/libraries/I2CEEPROM/I2CEEPROM.h\nlib/libraries/I2CEEPROM/keywords.txt\nlib/libraries/LoopTimer/LoopTimer.cpp\nlib/libraries/LoopTimer/LoopTimer.h\nlib/libraries/LoopTimer/keywords.txt\nlib/libraries/OneWire/OneWire.cpp\nlib/libraries/OneWire/OneWire.h\nlib/libraries/OneWire/keywords.txt\nlib/libraries/OneWire/readme.txt\nlib/libraries/SWSerLCDpa/SWSerLCDpa.cpp\nlib/libraries/SWSerLCDpa/SWSerLCDpa.h\nlib/libraries/SWSerLCDsf/SWSerLCDsf.cpp\nlib/libraries/SWSerLCDsf/SWSerLCDsf.h\nlib/libraries/Servo/Servo.cpp\nlib/libraries/Servo/Servo.h\nlib/libraries/Stepper/Stepper.cpp\nlib/libraries/Stepper/Stepper.h\nlib/libraries/Stepper/keywords.txt\nlib/libraries/Wire/Wire.cpp\nlib/libraries/Wire/Wire.h\nlib/libraries/Wire/keywords.txt\nlib/libraries/Wire/twi.h\nlib/libraries/Wire/utility/twi.c\nlib/libraries/Wire/utility/twi.h\nlib/plugins/bitwise_ops.rb\nlib/plugins/blink.rb\nlib/plugins/blink_m.rb\nlib/plugins/debounce.rb\nlib/plugins/debug_output_to_lcd.rb\nlib/plugins/hysteresis.rb\nlib/plugins/input_output_state.rb\nlib/plugins/lcd_padding.rb\nlib/plugins/mem_test.rb\nlib/plugins/midi.rb\nlib/plugins/parallax_ping.rb\nlib/plugins/servo_pulse.rb\nlib/plugins/servo_setup.rb\nlib/plugins/smoother.rb\nlib/plugins/spark_fun_serial_lcd.rb\nlib/plugins/spectra_symbol.rb\nlib/plugins/twitter_connect.rb\nlib/rad.rb\nlib/rad/README.rdoc\nlib/rad/arduino_plugin.rb\nlib/rad/arduino_sketch.rb\nlib/rad/darwin_installer.rb\nlib/rad/generators/makefile/makefile.erb\nlib/rad/generators/makefile/makefile.rb\nlib/rad/hardware_library.rb\nlib/rad/init.rb\nlib/rad/linux_installer.rb\nlib/rad/progressbar.rb\nlib/rad/rad_processor.rb\nlib/rad/rad_rewriter.rb\nlib/rad/rad_type_checker.rb\nlib/rad/sim/arduino_sketch.rb\nlib/rad/sketch_compiler.rb\nlib/rad/tasks/build_and_make.rake\nlib/rad/tasks/rad.rb\nlib/rad/todo.txt\nlib/rad/variable_processing.rb\nlib/rad/version.rb\nscripts/txt2html\nsetup.rb\nspec/examples/hello_world.rb\nspec/examples/serial_motor.rb\nspec/models/arduino_sketch_spec.rb\nspec/models/sketch_compiler_spec.rb\nspec/models/spec_helper.rb\nspec/sim/hello_world_spec.rb\nspec/spec.opts\ntest/hello_world_test/Makefile\ntest/hello_world_test/hello_world.cpp\ntest/test_array_processing.rb\ntest/test_plugin_loading.rb\ntest/test_translation_post_processing.rb\ntest/test_variable_processing.rb\nwebsite/index.html\nwebsite/index.txt\nwebsite/javascripts/rounded_corners_lite.inc.js\nwebsite/stylesheets/screen.css\nwebsite/template.rhtml\nwebsite/examples/assembler_test.rb.html\nwebsite/examples/gps_reader.rb.html\nwebsite/examples/hello_world.rb.html\nwebsite/examples/serial_motor.rb.html"
  },
  {
    "path": "README.markdown",
    "content": "# Welcome to RAD (Ruby Arduino Development)\n\nRAD is a framework for programming the Arduino physcial computing platform using Ruby. RAD converts Ruby scripts written using a set of Rails-like conventions and helpers into C source code which can be compiled and run on the Arduino microcontroller. It also provides a set of Rake tasks for automating the compilation and upload process.\n\nFor a full introduction see http://rad.rubyforge.org\n\n## Documentation\n\nThe main documentation is here: ArduinoSketch.\n\nSee also the Arduino Software reference: http://www.arduino.cc/en/Reference/HomePage\n\n## Examples\n\nSee the examples directory for lots of examples of RAD in action: \nhttp://github.com/atduskgreg/rad/tree/master/lib/examples\n\nThe atduskgreg/rad wiki also contains a growing library of examples and hardware tutorials:\nhttp://github.com/atduskgreg/rad/wikis\n\n## Getting Started\n\nTo install the gem:\n\n    $ gem install rad\n\nRun the rad command to create a new project:\n\n    $ rad my_project\n\nWrite a sketch that will blink a single LED every 500ms:\n\n```ruby\nclass MyProject < ArduinoSketch\n  output_pin 13, :as => led\n  def loop\n    blink led, 500\n  end\nend\n```\n\nAttach your Arduino and use rake to complile and upload your sketch:\n\n    $ rake make:upload\n\n##Installing the Arduino Software\n\nInstalling RAD and the Arduino software on Linux can be a little more difficult than on OS X. Thankfully, the RAD command line tool can help. Run:\n\n    $ rad install arduino\n\nAnd RAD will do its best to get the Arduino software installed on your system.\n\n#Get Involved\n\n##Note on Patches/Pull Requests\n\n* Fork the project.\n* Make your feature addition or bug fix on a new topic branch\n* Add specs and cukes for it. This is important so I don't break it in a\n  future version unintentionally.\n* Commit, do not mess with rakefile, version, or history.\n  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)\n* Issue a pull request.\n\n##Cheers?  Jeers?  Questions?  Comments?  \n\nContact Greg Borenstein - greg [dot] borenstein [at] gmail [dot] com\n\nMatthew Williams - matthew [dot] williams [at] gmail [dot] com\n\nAlso, please don't hesitate to submit issues!"
  },
  {
    "path": "Rakefile",
    "content": "require 'rubygems'\nrequire 'rake'\nrequire 'rake/clean'\nrequire 'rake/testtask'\nrequire 'rake/packagetask'\nrequire 'rake/gempackagetask'\nrequire 'rake/rdoctask'\nrequire 'rake/contrib/rubyforgepublisher'\nrequire 'fileutils'\nrequire 'hoe'\n\nRAD_ROOT = File.expand_path(File.dirname(__FILE__))\n\nbegin\n  require 'spec/rake/spectask'\nrescue LoadError\n  puts 'To use rspec for testing you must install rspec gem:'\n  puts '$ sudo gem install rspec'\n  exit\nend\n\ninclude FileUtils\nrequire File.join(File.dirname(__FILE__), 'lib', 'rad', 'version')\n\nBIN = \"rad\"\nAUTHOR = 'Greg Borenstein'  # can also be an array of Authors\nEMAIL = \"greg@mfdz.com\"\nDESCRIPTION = \"A framework for programming the Arduino physcial computing platform using Ruby. RAD converts Ruby scripts written using a set of Rails-like conventions and helpers into C source code which can be compiled and run on the Arduino microcontroller.\"\nGEM_NAME = 'rad' # what ppl will type to install your gem\n\n@config_file = \"~/.rubyforge/user-config.yml\"\n@config = nil\ndef rubyforge_username\n  unless @config\n    begin\n      @config = YAML.load(File.read(File.expand_path(@config_file)))\n    rescue\n      puts <<-EOS\nERROR: No rubyforge config file found: #{@config_file}\"\nRun 'rubyforge setup' to prepare your env for access to Rubyforge\n - See http://newgem.rubyforge.org/rubyforge.html for more details\n      EOS\n      exit\n    end\n  end\n  @rubyforge_username ||= @config[\"username\"]\nend\n\nRUBYFORGE_PROJECT = 'rad' # The unix name for your project\nHOMEPATH = \"http://#{RUBYFORGE_PROJECT}.rubyforge.org\"\nDOWNLOAD_PATH = \"http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}\"\n\nNAME = \"rad\"\nREV = nil \n# UNCOMMENT IF REQUIRED: \n# REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil\nVERS = Rad::VERSION::STRING + (REV ? \".#{REV}\" : \"\")\nCLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']\nRDOC_OPTS = ['--quiet', '--title', 'rad documentation',\n    \"--opname\", \"index.html\",\n    \"--line-numbers\", \n    \"--main\", \"README\",\n    \"--inline-source\"]\n\nclass Hoe\n  def extra_deps \n    @extra_deps.reject { |x| Array(x).first == 'hoe' } \n  end \nend\n\n# Generate all the Rake tasks\n# Run 'rake -T' to see list of generated tasks (from gem root directory)\nhoe = Hoe.new(GEM_NAME, VERS) do |p|\n  p.author = AUTHOR \n  p.description = DESCRIPTION\n  p.email = EMAIL\n  p.summary = DESCRIPTION\n  p.url = HOMEPATH\n  p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT\n  p.test_globs = [\"test/**/test_*.rb\"]\n  p.clean_globs |= CLEAN  #An array of file patterns to delete on clean.\n  \n  # == Optional\n  p.changes = p.paragraphs_of(\"History.txt\", 0..1).join(\"\\n\\n\")\n  p.extra_deps =  [ ['RubyToC', '>= 1.0.0'] ]\n  #p.spec_extras = {}    # A hash of extra values to set in the gemspec.\nend\n\nCHANGES = hoe.paragraphs_of('History.txt', 0..1).join(\"\\n\\n\")\nPATH    = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : \"#{RUBYFORGE_PROJECT}/#{GEM_NAME}\"\nhoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\\/?/,''), 'rdoc')\n\ndesc 'Generate website files'\ntask :website_generate do\n  Dir['website/**/*.txt'].each do |txt|\n    sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }\n  end\nend\n\ndesc 'Upload website files to rubyforge'\ntask :website_upload do\n  host = \"#{rubyforge_username}@rubyforge.org\"\n  remote_dir = \"/var/www/gforge-projects/#{PATH}/\"\n  local_dir = 'website'\n  sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}\nend\n\ndesc 'Generate and upload website files'\ntask :website => [:website_generate, :website_upload, :publish_docs]\n\ndesc 'Release the website and new gem version'\ntask :deploy => [:check_version, :website, :release] do\n  puts \"Remember to create SVN tag:\"\n  puts \"svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk \" +\n    \"svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} \"\n  puts \"Suggested comment:\"\n  puts \"Tagging release #{CHANGES}\"\nend\n\ndesc 'Runs tasks website_generate and install_gem as a local deployment of the gem'\ntask :local_deploy => [:website_generate, :install_gem]\n\ntask :check_version do\n  unless ENV['VERSION']\n    puts 'Must pass a VERSION=x.y.z release version'\n    exit\n  end\n  unless ENV['VERSION'] == VERS\n    puts \"Please update your version.rb to match the release version, currently #{VERS}\"\n    exit\n  end\nend\n\ndesc \"Run the specs under spec/models\"\nSpec::Rake::SpecTask.new do |t|\n  t.spec_opts = ['--options', \"spec/spec.opts\"]\n  t.spec_files = FileList['spec/models/*_spec.rb']\nend\n\ndesc \"Default task is to run specs\"\ntask :default => :spec\n\n"
  },
  {
    "path": "bin/rad",
    "content": "#!/usr/bin/env ruby\n\nbegin\n  require 'rubygems'\nrescue LoadError\n  # no rubygems to load, so we fail silently\nend\n\nrequire 'optparse'\nrequire 'fileutils'\nrequire 'yaml'\nrequire 'open-uri'\nrequire 'readline'\n\nrequire File.expand_path(File.dirname(__FILE__)) + \"/../lib/rad/version.rb\"\nrequire File.expand_path(File.dirname(__FILE__)) + \"/../lib/rad/progressbar.rb\"\nrequire File.expand_path(File.dirname(__FILE__)) + \"/../lib/rad/linux_installer.rb\"\nrequire File.expand_path(File.dirname(__FILE__)) + \"/../lib/rad/darwin_installer.rb\"\n\nclass OptionParser #:nodoc:\n    \n  def self.parse(args)\n    # defaults\n    \n    options = {\"hardware\" => {\n                \"serial_port\"      => '/dev/tty.usbserial*', \n                \"mcu\"              => \"atmega168\", \n                \"physical_reset\"   => false\n                },\n                \"software\" => {\n                  \"arduino_root\"   => \"/Applications/arduino-0012\"\n                 }\n               }\n    \n    opts = OptionParser.new do |opts|\n      \n      opts.banner = <<-BANNER\nBuild a directory for your RAD Project and install RAD in its vendor sub-directory.\n\nUsage: #{File.basename($0)} <sketch_dir_name> <options for config>\n      BANNER\n      \n      opts.on(\"-p\", \"--port [SERIAL PORT]\", \n              \"Path to your serial port\", \n              \"   (default: #{options['hardware']['serial_port']})\") do |port|\n              \n        options[\"hardware\"][\"serial_port\"] = port if port\n      end\n      \n       opts.on(\"-m\", \"--mcu [PROCESSOR TYPE]\", \n              \"Type of processor on your board\", \n              \"   (default: #{options['hardware']['mcu']})\") do |port|\n              \n        options[\"hardware\"][\"serial_port\"] = port if port\n      end\n      \n      opts.on(\"-r\", \"--reset [RESET REQUIRED]\", \n              \"Require a hardware reset before uploading?\",\n              \"   (default: #{options['hardware']['physical_reset']})\") do |no_reset|\n        options[\"hardware\"][\"physical_reset\"] = true unless no_reset\n      end\n      \n      opts.on(\"-a\", \"--arduino [ARDUINO DIR]\", \n              \"Path to your Arduino install\",\n              \"   (default: #{options['software']['arduino_root']})\") do |arduino|\n        options[\"software\"][\"arduino_root\"] = arduino if arduino\n      end\n      \n      opts.on(\"-v\", \"--version [VERSION]\", \n              \"RAD version number\",\n              \"   (#{Rad::VERSION::STRING})\") do \n        puts Rad::VERSION::STRING\n        exit\n      end\n\n      opts.on_tail(\"-h\", \"--help\", \"Show this message\") do\n        puts opts\n        exit\n      end\n    end\n    \n    opts.parse!(args)\n    [options, opts]\n  end\n  \nend\n\n\n# home = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']\n# begin\n#   config = YAML::load open(home + \"/.rad\")\n# rescue\n#   config = false\n# end\n# \n\n\nif ARGV[0] == \"install\"\n  \n  case RUBY_PLATFORM\n  when /linux/\n    LinuxInstaller.install!\n  when /darwin/\n    DarwinInstaller.install!\n  else\n    raise \"Sorry. Can only install Arduino on Mac OS X. See here for Linux instructions: http://www.arduino.cc/playground/Learning/Linux\"\n  end\n\nelsif ARGV[0] == \"test\"\n  test_dir = File.expand_path(File.dirname(__FILE__)) + \"/../test/hello_world_test\"\n  puts \"Compiling hello_world.cpp to test your Arduino.\"\n  puts \"cd #{test_dir}; make depend; make;\"\n  `cd #{test_dir}; make depend; make;`\n  puts\n  puts \"Compilation successful.\"\n  puts\n  puts \"Make sure your Arduino is connected and then hit return.\"\n  Readline::readline('')\n  \n  `cd #{test_dir}; make upload`\n  \n  # find the USB port to make sure the Arduino's actually plugged in\n  options, parser = OptionParser.parse(ARGV)\n  usb_port = options[\"hardware\"][\"serial_port\"]\n  port_name = usb_port.split(\"/\").last\n  port_dir = usb_port.split(\"/\")[0..(usb_port.split(\"/\").length-2)].join(\"/\")\n  unless `ls #{port_dir}`.split(/\\n/).any?{|d| d.match(/#{port_name}/)}\n    puts\n    puts \"******************************************************\"\n    puts \"*** It looks like your Arduino is not plugged in.  ***\"\n    puts \"***        Plug it in and try again.               ***\"\n    puts \"***                                                ***\"\n    puts \"***   NOTE: If your usb port is not /dev/tty.usb*  ***\"\n    puts \"***  pass it in to this script with the -p option. ***\"\n    puts \"******************************************************\"\n  else \n    puts\n    puts \"******************************************************\"\n    puts \"***                 Success!                       ***\"\n    puts \"***  If your Arduino's light starts blinking soon, ***\"\n    puts \"***     then your Arduino environment is           ***\"\n    puts \"***          correctly configured.                 ***\"\n    puts \"***                                                ***\"\n    puts \"*** Otherwise something is not hooked up properly. ***\"\n    puts \"******************************************************\"\n  end\n  puts\n  puts \"cleaning up...\"\n  `rm #{test_dir}/hello_world.hex #{test_dir}/core.a #{test_dir}/hello_world.elf`\nelse\n  # Handle options:\n  options, parser = OptionParser.parse(ARGV)\n  sketch_name = ARGV[0]\n  parser.parse!([\"-h\"]) unless sketch_name \n    \n  \n  # Build vendor/rad:  \n    \n  FileUtils.mkdir_p \"#{sketch_name}/vendor/rad\"\n  puts \"Successfully created your sketch directory.\"\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/rad/.\", \"#{sketch_name}/vendor/rad\"\n  puts \"Installed RAD into #{sketch_name}/vendor/rad\"\n  puts\n  \n  # Build vendor/libraries:  \n  \n  FileUtils.mkdir_p \"#{sketch_name}/vendor/libraries\"\n  puts \"Successfully created your libraries directory.\"\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/AF_XPort/.\", \"#{sketch_name}/vendor/libraries/AF_XPort\"\n  puts \"Installed AF_XPort into #{sketch_name}/vendor/libraries\"\n  puts\n\n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/AFSoftSerial/.\", \"#{sketch_name}/vendor/libraries/AFSoftSerial\"\n  puts \"Installed AFSoftSerial into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/DS1307/.\", \"#{sketch_name}/vendor/libraries/DS1307\"\n  puts \"Installed DS1307 into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/FrequencyTimer2/.\", \"#{sketch_name}/vendor/libraries/FrequencyTimer2\"\n  puts \"Installed FrequencyTimer2 into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/I2CEEPROM/.\", \"#{sketch_name}/vendor/libraries/I2CEEPROM\" \n  puts \"Installed I2CEEPROM into #{sketch_name}/vendor/libraries\" \n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/LoopTimer/.\", \"#{sketch_name}/vendor/libraries/LoopTimer\" \n  puts \"Installed LoopTimer into #{sketch_name}/vendor/libraries\" \n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/OneWire/.\", \"#{sketch_name}/vendor/libraries/OneWire\"\n  puts \"Installed OneWire into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/Servo/.\", \"#{sketch_name}/vendor/libraries/Servo\"\n  puts \"Installed Servo into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/Stepper/.\", \"#{sketch_name}/vendor/libraries/Stepper\"\n  puts \"Installed Stepper into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/SWSerLCDpa/.\", \"#{sketch_name}/vendor/libraries/SWSerLCDpa\"\n  puts \"Installed SWSerLCDpa into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/SWSerLCDsf/.\", \"#{sketch_name}/vendor/libraries/SWSerLCDsf\"\n  puts \"Installed SWSerLCDsf into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/libraries/Wire/.\", \"#{sketch_name}/vendor/libraries/Wire\"\n  puts \"Installed Wire into #{sketch_name}/vendor/libraries\"\n  puts\n  \n  # Build examples -- used for basic testing\n  \n  FileUtils.mkdir_p \"#{sketch_name}/vendor/libraries\"\n  puts \"Successfully created your examples directory.\"\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/examples/.\", \"#{sketch_name}/examples\"\n  puts \"Installed examples into #{sketch_name}/examples\"\n  puts\n  \n  # Build test -- used testing\n  \n  # FIXME: this should put the tests into the vendor/tests directory instead.\n   \n  # FileUtils.mkdir_p \"#{sketch_name}/test\"\n  # puts \"Successfully created your test directory.\"\n  # \n  # FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/test/.\", \"#{sketch_name}/test\"\n  # puts \"Installed tests into #{sketch_name}/test\"\n  # puts\n  \n  # Build vendor/plugins:  \n  \n  FileUtils.mkdir_p \"#{sketch_name}/vendor/plugins\"\n  puts \"Successfully created your plugins directory.\"\n  \n  FileUtils.cp_r \"#{File.dirname(__FILE__)}/../lib/plugins/.\", \"#{sketch_name}/vendor/plugins\"\n  puts \"Installed Default plugins into #{sketch_name}/vendor/plugins\"\n  puts\n  \n  # Add an default sketch directory # needed to run test:compile\n  \n  FileUtils.mkdir_p \"#{sketch_name}/#{sketch_name}\"\n  puts \"Successfully created your default sketch directory.\"\n  \n  # Build sketch files, etc.:  \n  \n  FileUtils.touch \"#{sketch_name}/#{sketch_name}.rb\"\n  File.open(\"#{sketch_name}/#{sketch_name}.rb\", \"w\") do |file|\n    file << <<-EOS\n  class #{sketch_name.split(\"_\").collect{|c| c.capitalize}.join(\"\")} < ArduinoSketch\n    \n    # looking for hints?  check out the examples directory\n    # example sketches can be uploaded to your arduino with\n    # rake make:upload sketch=examples/hello_world\n    # just replace hello_world with other examples\n    \n      def loop\n       # your code here\n      end\n      \n  end\n    EOS\n  end\n  puts \"Added #{sketch_name}/#{sketch_name}.rb\"\n  \n  File.open(\"#{sketch_name}/Rakefile\", 'w') do |file|\n    file << <<-EOS \n  require 'vendor/rad/init.rb'\n    EOS\n  end\n  puts \"Added #{sketch_name}/Rakefile\"\n  \n  FileUtils.mkdir_p \"#{sketch_name}/config\"\n  puts \"Added #{sketch_name}/config\"\n  \n  File.open(\"#{sketch_name}/config/hardware.yml\", 'w') do |file|\n    file << options[\"hardware\"].to_yaml\n  end\n  puts \"Added #{sketch_name}/config/hardware.yml\"\n  \n  File.open(\"#{sketch_name}/config/software.yml\", 'w') do |file|\n    file << options[\"software\"].to_yaml\n  end\n  puts \"Added #{sketch_name}/config/software.yml\"\n  \n  puts\n  puts \"Run 'rake -T' inside your sketch dir to learn how to compile and upload it.\"\n  \n  puts \"***************************************************\"\n  puts \"***     Please note: This version supports      ***\"\n  puts \"***            Arduino 12 only!                 ***\"\n  puts \"***   run rad install arduino to upgrade        ***\"\n  puts \"***************************************************\"\nend"
  },
  {
    "path": "lib/examples/add_hysteresis.rb",
    "content": "class AddHysteresis < ArduinoSketch\n  \n  input_pin 3, :as => :sensor\n  output_pin 13, :as => :led\n\n\n  def loop\n    reading = add_hysteresis sensor, 8\n    blink led, 100 if reading > 100\n    blink led, 1000 if reading <= 100\n  end\n  \nend\n"
  },
  {
    "path": "lib/examples/basic_blink.rb",
    "content": "class BasicBlink < ArduinoSketch\n  # hello world (uncomment to run)\n  \n  output_pin 13, :as => :led\n  \n  def loop\n    blink led, 100 \n    x = 4\n  end\nend\n"
  },
  {
    "path": "lib/examples/blink_m_address_assignment.rb",
    "content": "class BlinkMAddressAssignment < ArduinoSketch\n\n  # want to use more than one blink m?\n  # since each blink m arrives with the same address, \n  # we can't address each one individually\n  # \n  # so the first thing we need to do is give each one a new address\n  # that's the purpose of this sketch\n  # \n  # install one blinkm at a time\n  # a pa_lcd screen makes this easier\n  # the screen will start at address ten and increment approximately every\n  # four seconds.  Pressing during the first four seconds sets the blnikm \n  # address to 10, during the next four seconds to 11 and so on\n  # difficult without a screen.\n  # if you need to, program an led to help with the timing\n   \n\n  @blink_m_start_address = 10\n  @flag = false\n  @addr1 = \"10, byte\"\n  @addr2 = \"11, byte\"\n  @addr3 = \"12, byte\"\n  \n  output_pin 19, :as => :wire, :device => :i2c, :enable => :true # reminder, true issues wire.begin\n  input_pin 7,  :as => :button_one, :device => :button\n  input_pin 8,  :as => :button_two, :device => :button\n  input_pin 9,  :as => :button_three, :device => :button\n  \n  output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n  \n  def setup\n    delay 1000\n    my_lcd.setxy 0,0, \"bienvenue\"\n        delay 5000\n  end\n  \n  def loop  \n \n    if @flag == false\n      staging\n    else\n      test_address \n    end\n    delay 100\n  end\n  \n  def staging\n    my_lcd.setxy 0,0, \"press button one to\"\n    my_lcd.setxy 0,1, \"set address to \"\n    my_lcd.print @blink_m_start_address\n    my_lcd.setxy 0,2, \"or two for status\"\n    delay 60\n    my_lcd.setxy 0,3, \"                \"\n    my_lcd.setxy 0,3\n    800.times do |i|\n      return 0 if @flag == true\n      my_lcd.print \".\" if i % 50 == 0 \n      delay 5\n      if button_one.read_input\n        assign_address \n      elsif button_two.read_input\n        test_address\n      end \n    end\n    @blink_m_start_address += 1 \n  end\n  \n  def assign_address\n    @flag = true\n    my_lcd.clearscr \"setting to \"\n    my_lcd.print @blink_m_start_address\n    delay 100\n    BlinkM_setAddress @blink_m_start_address\n    my_lcd.clearscr \"done\"\n    control_it\n  end\n  \n  def control_it\n    delay 500\n    my_lcd.clearscr \"stopping script\"\n    BlinkM_stopScript @blink_m_start_address\n    my_lcd.clearscr \"stopping script..\"\n    delay 500\n    my_lcd.clearscr \"fade to purple..\"\n    BlinkM_fadeToRGB(@blink_m_start_address, 0xff,0x00,0xff)\n    my_lcd.clearscr \"fade to purple\"\n    delay 500\n    BlinkM_fadeToRGB(@blink_m_start_address, 0xff,0x00,0xff)\n  end\n  \n  \n  def test_address\n    my_lcd.clearscr\n    my_lcd.setxy 0,0, \"testing address\"\n    my_lcd.setxy 0,1\n    my_lcd.print blink_m_check_address_message @blink_m_start_address\n    delay 5000\n  end\n\n  \n    \n\nend"
  },
  {
    "path": "lib/examples/blink_m_hello.rb",
    "content": "class BlinkMHello < ArduinoSketch\n\n  # just a scaffolding for blink_m_demo \n\n  output_pin 19, :as => :wire, :device => :i2c, :enable => :true\n  \n  def loop\n\n\t  x = 4    \n  \n  end\n    \n\nend"
  },
  {
    "path": "lib/examples/blink_m_multi.rb",
    "content": "class BlinkMMulti < ArduinoSketch\n\n  # demonstrate control of individual blinkms\n  # this assumes the leds have been assigned addresses 10, 11, 12\n  # which can be done with blink m address assignment\n\n  # two ways to address the blinkms, array and individual variables\n  @blink_addresses = [10,11,12]\n  @addr_all = \"0, byte\" \n  @addr1 = \"10, byte\"\n  @addr2 = \"11, byte\"\n  @addr3 = \"12, byte\"\n  \n  output_pin 19, :as => :wire, :device => :i2c, :enable => :true # reminder, true issues wire.begin\n  input_pin 7,  :as => :button_one, :device => :button\n  input_pin 8,  :as => :button_two, :device => :button\n  input_pin 9,  :as => :button_three, :device => :button\n  input_pin 10,  :as => :button_four, :device => :button\n  \n  # display the action on a 4x20 pa_lcd, yours may be 9200 instead of 19,200\n\n  output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n  \n  \n  def loop  \n    stop_and_fade(@addr1) if button_one.read_input\n    stop_and_fade(@addr2) if button_two.read_input \n    stop_and_fade(@addr3) if button_three.read_input \n    dance if button_four.read_input \n  end\n  \n  def stop_and_fade(addr)\n    f = 1 + addr # hack to coerce addr to int\n    my_lcd.clearscr\n    my_lcd.setxy 0,0, \"blinkm # \"\n    my_lcd.print addr\n    delay 700\n    BlinkM_stopScript addr\n    my_lcd.setxy 0,1, \"stopping script..\"\n    delay 700\n    my_lcd.setxy 0,2, \"fade to purple..\"\n    BlinkM_fadeToRGB(addr, 0xff,0x00,0xff)\n  end\n  \n  def dance\n    BlinkM_setFadeSpeed(@addr_all, 20) # 1-255, with 1 producing the slowest fade\n    my_lcd.clearscr\n    my_lcd.setxy 0,0, \"Do the shimmy..\"\n    my_lcd.setxy 0,1\n    @blink_addresses.each do |a|\n      BlinkM_fadeToRGB(a, 1,166,138)\n      delay 100\n    end\n    @blink_addresses.each do |a|\n      BlinkM_fadeToRGB(a, 35,0,112)\n      delay 100\n    end\n  end\n    \n\nend"
  },
  {
    "path": "lib/examples/blink_with_serial.rb",
    "content": "class BlinkWithSerial < ArduinoSketch\n  \n  # hello world (uncomment to run)\n  @i  = \"0, long\"\n  \n  output_pin 13, :as => :led\n  \n  serial_begin\n  \n    def loop\n      @i += 1\n      serial_println @i\n      blink led, 100 \n    end\n\nend\n"
  },
  {
    "path": "lib/examples/configure_pa_lcd_boot.rb",
    "content": "class ConfigurePaLcdBoot < ArduinoSketch\n  \n## important!  \n## most pa_lcd rates are set to 9200, but there are some newer at 19200\n## if you have a 19200, uncomment the end of line 38\n  \n## purpose:  \n## change cursor to none\n## and add custom boot screen\n## \n## jd's preferred setup for pa_lcd\n## \n## assumes 4 x 20 pa_lcd\n## \n## no blinking cursor press button 1\n## configure custom start up screen - press button 2\n## configure lcd to use custom startup screen - press button 3\n## \n## press buttons one, two and three \n## or season to taste\n##\n## refernce\n## K107 LCD Controller Board Manual\n## page 11 for cursors\n## page 13 for custom boot\n## http://wulfden.org/downloads/manuals/K107manual.pdf\n##\n##\n\n## set pins to your setup\n\n\n   input_pin 8,  :as => :button_one, :device => :button\n   input_pin 9,  :as => :button_two, :device => :button\n   input_pin 10, :as => :button_three, :device => :button\n   \n   ## note, most of these controllers are set to 9200\n   output_pin 14, :as => :my_lcd, :device => :pa_lcd #, :rate => 19200\n\n   \n   def loop\n     set_cursor     if button_one.read_input \n     set_custom_screen      if button_two.read_input \n     change_boot_to_custom  if button_three.read_input \n   end\n   \n   ## assumes 4 x 20 screen\n   ## maintain 20 characters after ?Cn\n   ## wny delays?  the controller needs them to give it \n   ## enough time to write 20 bytes to internl EEPROM\n   def set_custom_screen\n     my_lcd.clearscr\n     my_lcd.print \"?C0   RAD & Arduino    \"\n     delay 400\n     my_lcd.print \"?C1    Development     \"\n     delay 400\n     my_lcd.print \"?C2                    \"\n     delay 400\n     my_lcd.print \"?C3      v0.3.0        \"\n   end\n   \n   \n   ## ?c0 for no cursor\n   ## ?c2 for non blinking cursor\n   ## ?c3 for blinking cursor\n   def set_cursor\n     my_lcd.clearscr\n     my_lcd.print \"Changing to \"\n     my_lcd.setxy 0,1\n     my_lcd.print \"no cursor. \"\n     my_lcd.setxy 0,3\n     my_lcd.print \"Reboot to view... \"\n     \n     my_lcd.print(\"?c0\")\n   end\n   \n   ## \"?S0 for blank screen \n   ## ?S1 for configuration settings \n   ## ?S2 for custom text screen\n   def change_boot_to_custom\n     my_lcd.clearscr\n     my_lcd.print \"Changing to \"\n     my_lcd.setxy 0,1\n     my_lcd.print \"custom boot screen. \"\n     my_lcd.setxy 0,3\n     my_lcd.print \"Reboot to view... \"\n     my_lcd.print(\"?S2\")\n   end\n\n  \nend"
  },
  {
    "path": "lib/examples/debounce_methods.rb",
    "content": "class DebounceMethods < ArduinoSketch\n  \n  output_pin 13, :as => :led \n  input_pin 6, :as => :button_one, :device => :button # can also :adjust => 300\n  input_pin 7, :as => :button_two, :device => :button\n  input_pin 8, :as => :button_three, :device => :button\n  input_pin 9, :as => :button_four, :device => :button  \n  input_pin 10, :as => :button_five, :device => :button  \n  \n  # depressing and releasing button_one, button_two or button_four do the same thing\n  # with a slightly different syntax and number of blinks\n  # button_three simply toggles the led with the read_and_toggle method\n  # button_five does it with a twist\n\n     def loop\n       blink_twice if read_input button_one\n       blink_three_times if read_input button_two\n       button_three.read_and_toggle led #  \n       blink_three_times_basic if read_input button_four\n       blink_with_a_twist if read_input button_five\n     end\n     \n     def blink_twice\n        2.times do |i|\n          led.blink 200 + i\n        end\n      end\n     \n     def blink_three_times\n       3.times { led.blink 200 }\n     end\n\n     # no blink helper\n     def blink_three_times_basic\n       4.times do \n         led.digitalWrite HIGH\n         delay 200\n         led.digitalWrite LOW\n         delay 200\n       end\n     end\n     \n     def blink_with_a_twist\n       20.times do |i|\n         led.blink i * 10\n       end\n     end     \n     \nend"
  },
  {
    "path": "lib/examples/external_variable_fu.rb",
    "content": "class ExternalVariableFu < ArduinoSketch\n  \n  @one = int\n  @two = long\n  @three = unsigned\n  @four = short\n  @five = byte\n  @six = 1\n  @seven = 1.2\n  @eight = \"0x00\"\n  @nine = \"arduino\"\n  @ten = true\n  @eleven = false\n  @twelve = \"1, long\"\n  @thirteen = \"1, unsigned\"\n  @fourteen = \"1, byte\"\n  @fifteen = HIGH\n  @sixteen = LOW\n  @seventeen = ON \n  @eighteen = OFF\n\n  def loop\n   delay @six\n  end\n     \nend"
  },
  {
    "path": "lib/examples/external_variables.rb",
    "content": "class ExternalVariables < ArduinoSketch\n\n  define \"KOOL 10\"\n  define \"TRUE 1\"\n  define \"COMMENT true\"\n  define \"DS1307_CTRL 7\"\n  define \"DS1308_CTRL 7\"\n  array \"char buffer[32];\"\n  array \"char bufferz[32];\"\n\n\n  @foo = 1\n  @bidda = \"badda\"\n  @boom = \"1, int\"\n  @rad = \"1.00\"\n  \n  def loop\n\t  delay 1\n\t  @foo = 2\n    @foo = KOOL\n  end\n  \n  def setup # special one time only method\n    delay 100\n    delay 100\n    @foo = 10\n    5.times { delay 200 }\n\n  end\n    \n\nend"
  },
  {
    "path": "lib/examples/first_sound.rb",
    "content": "class FirstSound < ArduinoSketch\n\n\n\noutput_pin 11, :as => :myTone, :device => :freq_out, :frequency => 100 # frequency required\n\n    def loop\n        myTone.disable\n        1.upto(400) { |x| tone_out x }   # run up the scale to 4000 Hz in 10 Hz steps\n        399.downto(1) { |x| tone_out x } # come back down in 10 Hz steps\n        delay 2000\n    end\n\n    def tone_out(n)\n        myTone.set_frequency 10*n\n        myTone.enable\n        delay 80\n        myTone.disable\n        delay 10\n    end\n    \n\nend"
  },
  {
    "path": "lib/examples/frequency_generator.rb",
    "content": "class FrequencyGenerator < ArduinoSketch\n  \n  # need explaination\n  \n  output_pin 11, :as => :myTone, :device => :freq_out, :frequency => 100\n\n     def loop\n         uh_oh 4   \n     end\n\n     def uh_oh(n)\n       \n\n         n.times do\n             myTone.enable\n             myTone.set_frequency 1800\n             delay 500\n             myTone.disable\n             delay 100\n             myTone.enable\n             myTone.set_frequency 1800\n             delay 800\n             myTone.enable\n         end\n         # hack to help translator guess that n is an int\n         f = n + 0\n      end\n      \n\nend\n"
  },
  {
    "path": "lib/examples/hello_array.rb",
    "content": "class HelloArray < ArduinoSketch\n\n # still working this out...\n # for example, new instance style array declaration naming\n # is at odds with original style array naming  \n \n # for simple integer, string, float, and boolean arrays  \n @toppings = [1,2,3]\n @names = [\"ciero\", \"bianca\", \"antica\"]\n \n # when we just need to declare an array, or need more control, such as specific type requirements\n array \"int ingredients[10]\"\n array \"int pizzas[] = {1,2,3,4}\"\n \n output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n \n \n def loop\n   \n   my_lcd.clearscr \"toppings: \"\n   delay 500\n   \n   @toppings.each do |a|\n     my_lcd.print a\n     my_lcd.print \" \"\n     delay 500\n   end\n   \n   my_lcd.setxy 0,1, \"pizzas: \"\n   \n   pizzas.each do |p|\n     my_lcd.print p\n     my_lcd.print \" \"\n     delay 500\n   end\n   \n   my_lcd.setxy 0,2, \"names: \"\n   \n   @names.each do |p|\n     my_lcd.print p\n     my_lcd.print \" \"\n     delay 500\n   end\n   \n   \n end\n\nend"
  },
  {
    "path": "lib/examples/hello_array2.rb",
    "content": "class HelloArray2 < ArduinoSketch\n\n   # ----------------------------------------------------------------------\n   #    Checking out various array operations\n   #\n   #      JD Barnhart - Seattle, WA July 2008\n   #      Brian Riley - Underhill Center, VT, USA  July 2008\n   #                     <brianbr@wulfden.org>\n   #\n   # ----------------------------------------------------------------------\n\n # still working this out...\n # for example, new instance style array declaration naming\n # is at odds with original style array naming  \n\n define \"THROWAWAY 0\"\n \n # for simple integer, string, float, and boolean arrays  \n @toppings = [1,2,3]\n @names = [\"ciero\", \"bianca\", \"zeus\", \"athena\", \"apollo\"]\n \n # when we just need to declare an array, or need more control, such as specific type requirements\n array \"int ingredients[10]\"\n array \"int pizzas[] = {1,2,3,4}\"\n array \"byte buffer[20] = {'A', 'B', 'Z', 'C', 'Y', 'D', 'W', 'E', '%', 'H', '*', '!', ')', '=', 'P', '-', '+', 'R', 'I', 'K'}\"\n \n ## multidimensional arrays\n array 'int @my_numbers[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}'\n array 'char* @pizzas[2][4] = {{\"margherita\",\"funghi\",\"napoletana\",\"prosciutto cotto\"},{\"veggie\",\"pepperoni\",\"cheese\",\"kitchen sink\"}}'\n \n \n output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n \n \n def setup\n   \n   my_lcd.clearscr \"toppings: \"\n   delay 500\n   \n   @toppings.each do |a|\n     my_lcd.print a\n     my_lcd.print \" \"\n     delay 500\n   end\n   \n   my_lcd.setxy 0,1, \"pizzas: \"\n   \n   pizzas.each do |p|\n     my_lcd.print p\n     my_lcd.print \" \"\n     delay 500\n   end\n   \n   my_lcd.setxy 0,2, \"names: \"\n   \n   @names.each do |p|\n     my_lcd.print p\n     my_lcd.print \" \"\n     delay 500\n   end\n   \n   delay 3000\n   \n\n   \n   my_lcd.clearline 1, @names[2]\n   my_lcd.print \" [ \"\n   my_lcd.print pizzas[1]\n   my_lcd.print \" ]\"\n   \n   delay 2000\n   \n   my_lcd.clearscr \"Multidimensional ?n\"\n   \n   0.upto(2) do |f|\n     0.upto(3) do |s|\n       my_lcd.print @my_numbers[f][s]\n       my_lcd.print \", \"\n       delay 500\n     end\n   end\n   \n   delay 1000\n   \n   my_lcd.clearscr\n\n    0.upto(1) do |f|\n      0.upto(3) do |s|\n        my_lcd.print @pizzas[f][s]\n        my_lcd.print \", \"\n        delay 500\n      end\n    end\n\n\n\n    delay 2000\n   \n   my_lcd.clearscr \"Array Load?n\"\n   1.upto(20) do |x|\n#     buffer[x] = 64 + x  # we cannot set array elements yet except to initialize in declaration\n     my_lcd.print buffer[x-1]\n     my_lcd.print \" \"\n   end\n   \n end\n \n def loop\n    x = THROWAWAY\n end\n\nend"
  },
  {
    "path": "lib/examples/hello_array_eeprom.rb",
    "content": "class HelloArrayEeprom < ArduinoSketch\n\n   # ----------------------------------------------------------------------\n   #    Checking out various array operations  with I2C serial EEPROM\n   #      doing block writes and bloack readbacks with byte arrays\n   #\n   #      JD Barnhart - Seattle, WA July 2008\n   #      Brian Riley - Underhill Center, VT, USA  July 2008\n   #                     <brianbr@wulfden.org>\n   #\n   # ----------------------------------------------------------------------\n\n # still working this out...\n # for example, new instance style array declaration naming\n # is at odds with original style array naming  \n\n define \"THROWAWAY 0\"\n\n # when we just need to declare an array, or need more control, such as specific type requirements\n array \"byte page_data[20] = {'R', 'A', 'D', ' ', 'i', 's', ' ', 'B', 'A', 'D', '*', '!', ')', '=', 'P', '-', '+', 'R', 'I', 'K'}\"\n array \"byte in_buffer[20]\"\n \n output_pin 19, :as => :mem0, :device => :i2c_eeprom, :address => 1     # w/o :address defaults to  :address => 0  which is  0x50\n output_pin 14, :as => :my_lcd, :device => :pa_lcd, :rate => 19200\n \n \n def setup\n   \n   my_lcd.clearscr    \"  I2C EEPROM Demo\"\n   my_lcd.setxy 0, 1, \"block write and read\"\n   my_lcd.setxy 0, 2, \"  back and display\"\n   my_lcd.setxy 0, 3, \"    to the LCD\"\n   \n   delay 2000\n   \n   my_lcd.clearscr    \"  I2C EEPROM Demo?n    block write\"\n\n   mem0.write_page 0x0100, page_data, 20 \n\n   delay 1000\n   \n   my_lcd.clearline 1, \"  block readback\"\n   \n   mem0.read_buffer 0x0100, in_buffer, 20 \n   \n   my_lcd.setxy 0, 2\n   \n   1.upto(20) do |x|\n     my_lcd.print in_buffer[x-1]\n     my_lcd.print \" \"\n   end\n   \n end\n \n def loop\n    x = THROWAWAY\n end\n\nend"
  },
  {
    "path": "lib/examples/hello_clock.rb",
    "content": "class HelloClock < ArduinoSketch\n  \n# ----------------------------------------------------------------------------------\n#   <b>Time and Temp  (20 July 2008)</b>\n#   Example #1 - Brian Riley, Underhill Center, VT USA <brianbr@wulden.org>\n#   \n#   Connections\n#     I2C bus - DS1307 Real Time Clock chip\n#     Analog 0 (a.k.a Digital 14) - Wulfden K107 seria LCD Controller\n#                                   Peter Anderson chip\n#\n#   Comment\n#     - This is a straight forward program to read the Real Time Clock and Display\n#     delay() calls waiting for temperature conversion readings\n#\n#     - for the external data busses make sure you have 4.7K pullup resistors on the \n#      the SDA/SCL (I2C)\n#\n# ----------------------------------------------------------------------------------\n \n    @flag    = int\n\n    array \"byte clock[8]\"\n    \n    @days   = [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"]\n    @months = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]\n\n                              # implicit in :device => :ds1307 is that this i i2c\n                              # :enable => true issues the Wire.begin to ick over i2c\n    output_pin 19, :as => :rtc, :device => :i2c_ds1307, :enable => :true\n                              # software serial tx drives LCD display, screen cleared at startup\n                              # defines the softare protocol for controller as Peter Anderson\n    output_pin 14, :as => :myLCD, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n    loop_timer :as => :mainloop\n    \n\n    def setup\n      myLCD.clearscr \"   --<Date/Time>--\"\n      myLCD.setxy 1,3, \"looptime = \"\n      rtc.get clock, 1\n      print_main\n      @flag = 1\n    end\n    \n    def loop\n        mainloop.track\n        myLCD.setxy 12,3,  mainloop.get_total\n        rtc.get clock, 1\n        if clock[0] == 0\n          if @flag == 0\n            print_main\n            @flag = 1\n          end\n        else\n          @flag = 0\n        end\n       \tmyLCD.setxy 6,2\n       \tprintlz clock[2]\n       \tmyLCD.print \":\"\n  \t    printlz clock[1]\n       \tmyLCD.print \":\"\n  \t    printlz clock[0]\n\n       delay 50\n        \n    end\n\n    def\tprintlz(w)\n    \t\t\tmyLCD.print \"0\" if w < 10\n    \t\t\tmyLCD.print w\n    end\n\n    def\tprint_main\n \t    myLCD.setxy 1,1, @days[clock[3]-1]\n\t\t  myLCD.print \", \"\n      myLCD.print @months[clock[5]-1]\n   \t  myLCD.print \" \"\n      printlz clock[4]\n   \t  myLCD.print \", \"\n      printlz clock[6] + 2000\n      \n    end\n    \nend\n"
  },
  {
    "path": "lib/examples/hello_eeprom.rb",
    "content": "class HelloEeprom < ArduinoSketch\n  \n  output_pin 19, :as => :rtc, :device => :i2c_ds1307, :enable => :true\n  output_pin 19, :as => :mem0, :device => :i2c_eeprom\n\n  output_pin 14, :as => :myLCD, :device => :pa_lcd, :rate => 19200\n    \n  def loop\n\t    myLCD.setxy 0,0\t\t\t\t\t# set to 0,0\n\t    myLCD.print rtc.get(5, 1)\t# refresh registers (=1) get month\n     \tmyLCD.print \"/\"\n\t    myLCD.print rtc.get(4, 0)\t# no need to refresh (=0) get day \n     \tmyLCD.print \"/\"\n\t    myLCD.print rtc.get(6, 0)\t# get year\n     \tmyLCD.setxy(0,1)\t\t\t# set in 1 byte line 1 (second line)\n     \tprintlz 2\t\t\t\t\t# print hours with lead zero\n     \tmyLCD.print \":\"\n\t    printlz 1\t\t\t\t\t# print minutes with lead zero\n     \tmyLCD.print \":\"\n\t    printlz 0\t\t\t\t\t# print seconds with lead zero\n\t    \n\n\t\tmyLCD.setxy 10,0\n\t\tmyLCD.print \"write test\"\n\t\tmyLCD.setxy 0,2\n\t\t32.upto(109) do\t\t\t\t# write address of byte to that b yte\n\t\t\t|x| mem0.write_byte  x, x\n\t\t\tmyLCD.print(\".\") if x%2\n\t\t\tdelay 10\n\t\tend\n\n\t\tdelay 2000\n\t\t\n\t\tmyLCD.clearline 2 \t# clears bottom two lines           \n\t\tmyLCD.clearline 3\n\n\t\tmyLCD.setxy 10,0, \"read test \"\n\t\tmyLCD.setxy 0,2\n\t\t\t\t\t\t\t\t\t# read and print 39 addresses with printable numbers\n\t\t75.upto(113) { |x| myLCD.print(mem0.read_byte(x)) }\n\t\tdelay 10000\n\t\tmyLCD.clearscr\n  end\n  \n  def\tprintlz(w)\n  \t\t\ti = 0 + rtc.get(w,0)         # the '0 +' is YARH (Yet Another RubyToc Hack)\n  \t\t\tmyLCD.print \"0\" if i < 10\n  \t\t\tmyLCD.print i\n  end\n\nend\n"
  },
  {
    "path": "lib/examples/hello_eeprom_lcdpa.rb",
    "content": "class HelloEepromLcdpa < ArduinoSketch\n  # -----------------------------------------------------------------------\n  #    Simple Byte Write and Byte Read-back of I2C EEPROM\n  #\n  #      Brian Riley - Underhill Center, VT, USA  July 2008\n  #                     <brianbr@wulfden.org>\n  #\n  #    I2C Routines are in a plugin not a library\n  #    No block reads and write yet\n  #    Displays to PH Anderson based serial LCD Display\n  #\n  #    <b>I2C Serial EEPROM - Byte Read and Byte Write</b>\n  #      \n  #     i2c_eeprom_write_byte  dev_addr, chip_addr, value\n  #\n  #     dev_addr (byte) - range 0x50 to 0x57 determined by hardware wiring \n  #     chip_addr (unsigned) - 0 to as much as 64K, depends on chip\n  #     value (byte) - 0 to 255 (0x00 to 0xFF)\n  #\n  #     returns - nothing\n  #\n  #     i2c_eeprom_read_byte  dev_addr, chip_addr\n  #\n  #     dev_addr (byte) - range 0x50 to 0x57 determined by hardware wiring \n  #     chip_addr (unsigned) - 0 to as much as 64K, depends on chip\n  #\n  #     returns - byte value\n  #\n  #\n  #     http://www.arduino.cc/playground/Code/I2CEEPROM\n  # ----------------------------------------------------------------------\n  \n  output_pin 19, :as => :mem0, :device => :i2c_eeprom, :enable => :true\n  output_pin 14, :as => :myLCD, :device => :pa_lcd, :rate => 19200\n\n\n    \n  def setup\n      delay 1500        # give startup screen time to finish and clear\n\t    myLCD.clearscr    \"  I2C EEPROM Demo\"\n      myLCD.setxy 0, 1, \"byte write then read\"\n      myLCD.setxy 0, 2, \"  back and display\"\n      myLCD.setxy 0, 3, \"    to the LCD\"\n      \n      clear_off_test\n      myLCD.clearline 1, \"  byte write test\"\n      \n      myLCD.setxy 0, 2\n      32.upto(109) do\t\t\t\t# write address of byte to that b yte\n\t\t\t  |x| mem0.write_byte  x, x+7\n        myLCD.print(\".\") if x%2\n        delay 10      # EEPROM write _requires_ 3-10 ms pause\n      end\n\n      clear_off_test\n      myLCD.clearline 1, \"  byte read test \"\n\n      myLCD.setxy 0, 2\n\t\t\t\t\t\t\t\t\t# read and print 39 addresses with printable numbers\n      70.upto(105) { |x| myLCD.print(mem0.read_byte(x)) }\n\n      delay 2000\n      clear_off_test\n      myLCD.clearline 1, \"-< tests complete >- \"\n\n\n  end\n  \n  def loop\n    x = 4       # loop has to have _something_\n  end\n\n\n   def clear_off_test   # clears bottom two lines \n     delay 2000\n     myLCD.clearline 3\n     myLCD.clearline 2   # leaves you at start of a \n                              # cleared third line\n   end\n\nend\n"
  },
  {
    "path": "lib/examples/hello_format_print.rb",
    "content": "class HelloFormatPrint < ArduinoSketch\n\n  # ----------------------------------------------------------------------\n  #    Demonstrattion of Crude Adaptaion of C Function sprintf()\n  #    to do formatted printing. For now there are some absolutes:\n  #    The write_line method atkes as arguemnst the formatting string\n  #    and the appropriate arguments. It format them to an internal\n  #    buffer sepcified and created when you invoke formatted printing\n  #       formatted_print :as => :line_buf, :buffer_size => 80\n  #    now, to actual do it you use write_line\n  #       write_line \"Pies $%02d.%02d\", pie_cents/100, pie_cents%100\n  #    then print the string pointed at by string_line\n  #       my_lcd.setxy 3, 2, line_buf \n  #\n  #      Brian Riley - Underhill Center, VT, USA  Aug 2008\n  #                     <brianbr@wulfden.org>\n  #\n  # ----------------------------------------------------------------------\n\n# demonstrate 4 x 20 pa_lcd toggle between normal and Bignum mode\n# with @toggle external variable thrown in for fun\n\n# change your pins to suit your setup\n  \n  @toggle = \"0, int\"\n  @pie_cents = \"403, int\"\n  @pie_price = \"7.08\"\n\n  \n  input_pin 8,  :as => :button_one, :device => :button\n  input_pin 9,  :as => :button_two, :device => :button\n  input_pin 10, :as => :button_three, :device => :button\n  \n  formatted_print :as => :string_line, :buffer_size => 65   # generally this statement should precede any serial_begin or\n                                                            # LCD display directive\n\n  output_pin 14, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n\n  \n  def setup\n    my_lcd.clearscr \" --<Press Button>--?nOne, Two, or Three\"\n  end\n  \n  def loop \n    if millis % 500 == 0\n      write_line \"millis()= %ld\", millis\n      my_lcd.setxy 1, 2, string_line\n    end \n    say_hello     if button_one.read_input \n    say_more      if button_two.read_input \n    say_it_large  if button_three.read_input \n  end\n  \n  def say_hello\n    @toggle = true\n    my_lcd.clearscr \"This sketch has?nbeen running for?n \"\n    write_line \"%ld mins and %d secs?n\", millis/60000, (millis/1000)%60\n    my_lcd.print string_line\n    delay 3000\n    my_lcd.clearscr \" --<Press Button>--?nOne, Two, or Three\"\n  end\n  \n  def say_more # passing print strings to home and setxy (also works on clearscr)\n    @toggle = false\n    my_lcd.clearscr \"Food Store Prices\"\n    write_line \"Pies $%2d.%02d\", @pie_cents/100, @pie_cents%100\n#    write_line \"Pies $%6.2f\", @pie_price # float doessn't seem to work .....\n    my_lcd.setxy 2, 1, string_line\n#    write_line \"toggle state is [%s]\", @toggle ? \"ON\" : \"OFF\"  # RubyToC screws this construct up and RAD mistajekl put 1 ad 0\n                                                                # in place of \"ON\" and \"OFF\"\n    write_line \"toggle state is [%d]\", @toggle\n    my_lcd.setxy 2, 3, string_line\n    delay 3000\n    my_lcd.clearscr \" --<Press Button>--?nOne, Two, or Three\"\n  end\n  \n  \n  def say_it_large\n\n    my_lcd.intoBignum\n    my_lcd.clearscr            # line 0, col 0\n    1.upto(32) do |i|\n      my_lcd.setxy 0,1\n      my_lcd.print i * i\n      delay 200\n    end\n    my_lcd.outofBignum\n    delay 3000\n    my_lcd.clearscr \" --<Press Button>--?nOne, Two, or Three\"      \n  end\n  \n\n \nend"
  },
  {
    "path": "lib/examples/hello_lcd_charset.rb",
    "content": "class HelloLcdCharset < ArduinoSketch\n\n  # -------------------------------------------------------------------------\n  #    Program to Display the entire lower half (under 0x80) character set\n  #\n  #    The class variable @a defined as byte is needed to make RubyToC put\n  #    the value to be 'printed' as a byte and thus give us the character\n  #    that value represents.\n  #\n  #      Brian Riley - Underhill Center, VT, USA  July 2008\n  #                     <brianbr@wulfden.org>\n  #\n  # ----------------------------------------------------------------------\n  \n   \n      @a  = byte\n      \n      output_pin 14, :as => :myLCD, :device => :pa_lcd, :rate => 19200\n      output_pin 13, :as => :led\n\n  def loop\n    \n    myLCD.clearscr  \"Alphabet Chars?n\"\n    0x41.upto(0x5a) do |i|    # A to Z\n      @a = i                  # forces 'byte' typing to variable\n      myLCD.print @a          # so print rouien prints character represented \n      delay 50                # by the index value\n    end\n    0x61.upto(0x7a) do |i|    # a to z\n      @a = i\n      myLCD.print @a\n      delay 50\n    end\n    \n    delay 3000\n    myLCD.clearscr  \"Numeric Chars?n\"\n    0x30.upto(0x39) do |i|    # 0 to 9\n      @a = i\n      myLCD.print @a\n      delay 50\n    end\n    \n    delay 3000\n\n    myLCD.clearscr  \"Other Chars?n\"\n    0x21.upto(0x2f) do |i|    # punctuation et al\n      @a = i\n      myLCD.print @a\n      delay 50\n    end\n    0x3a.upto(0x40) do |i|\n      @a = i\n      myLCD.print @a\n      delay 50\n    end\n    0x5b.upto(0x60) do |i|\n      @a = i\n      myLCD.print @a\n      delay 50\n    end\n    0x7b.upto(0x7f) do |i|\n      @a = i\n      myLCD.print @a\n      delay 50\n    end\n    \n    delay 3000\n      \n\n\n  end\n  \n  \n  \nend"
  },
  {
    "path": "lib/examples/hello_pa_lcd.rb",
    "content": "class HelloPaLcd < ArduinoSketch\n\n\n# demonstrate 4 x 20 pa_lcd toggle between normal and Bignum mode\n# with @toggle external variable thrown in for fun\n\n# change your pins to suit your setup\n  \n  @toggle = false\n  \n  input_pin 6,  :as => :button_one, :device => :button\n  input_pin 7,  :as => :button_two, :device => :button\n  input_pin 8, :as => :button_three, :device => :button\n  \n  output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n\n  def setup\n    delay 3000\n    my_lcd.setxy 0,0\n    my_lcd.print \"Press button\"\n    my_lcd.setxy 0,1\n    my_lcd.print \"One, two or three....\"\n  end\n  \n  def loop  \n    say_hello     if button_one.read_input \n    say_more      if button_two.read_input \n    say_it_large  if button_three.read_input \n  end\n  \n  def say_hello\n    @toggle = true\n    my_lcd.clearscr \"Any sufficiently    advanced technology\"\n    my_lcd.setxy 0,2\n    my_lcd.setxy 0,3, \"toggle state: \"\n    my_lcd.print @toggle\n  end\n  \n  def say_more # passing print strings to home and setxy (also works on clearscr)\n    @toggle = false\n    my_lcd.clearscr \"is indistinguishablefrom magic\"\n    my_lcd.setxy 0,3, \"toggle state: \"\n    my_lcd.print @toggle\n  end\n  \n  \n  def say_it_large\n\n    my_lcd.intoBignum\n    my_lcd.clearscr            # line 0, col 0\n    1.upto(32) do |i|\n      my_lcd.setxy 0,1\n      my_lcd.print i * i\n      delay 200\n    end\n    my_lcd.outofBignum\n  end\n \nend"
  },
  {
    "path": "lib/examples/hello_servos.rb",
    "content": "class HelloServos < ArduinoSketch\n  \n  output_pin 2, :as => :servo_1, :max => 2400, :min => 800\n  output_pin 3, :as => :servo_2, :max => 2400, :min => 800\n  output_pin 4, :as => :servo_3, :max => 2400, :min => 800\n\n\n     # time to go old school\n     def loop\n       song_sheet_two\n     end\n     \n     def song_sheet_two\n       e\n       d\n       e\n       d \n       c\n       d\n       d\n       c\n       b\n       c\n       b\n       a\n       e\n       a\n       e\n       a\n       e\n       a\n       b\n       c\n       b\n       c\n       d\n       d\n       c\n       d\n       e\n       d\n       e\n     end\n     \n     def a\n       pulse_servo servo_1, 1450\n       delay 100\n       home servo_1\n       delay 20\n     end\n\n     def b\n       pulse_servo servo_1, 1350\n       delay 100\n       home servo_1\n       delay 20\n     end\n\n     def c\n       pulse_servo servo_2, 1450\n       delay 100\n       home servo_2\n       delay 20\n     end\n\n     def d\n       pulse_servo servo_2, 1350\n       delay 100\n       home servo_2\n       delay 20\n     end\n\n     def e\n       pulse_servo servo_3, 1500\n       delay 100\n       home servo_3\n       delay 20\n     end\n\n\n     # center servos\n\n     def home(s)\n       pulse_servo s, 1400\n       f = s + 0\n     end\n\nend"
  },
  {
    "path": "lib/examples/hello_spectra_sound.rb",
    "content": "class HelloSpectraSound < ArduinoSketch\n\n  # demonstrate capability to use soft pot as traditional pot\n  # the last pot reading remains \"locked\" to the last touch point\n  # similar same behavior as ipod\n  #\n  # this sketch assumes a pa_lcd operating at 19200 and one \n  # spectra symbol softpot connected to analog pin 3\n  # \n  @reading  = int\n  output_pin 14, :as => :my_lcd, :device => :pa_lcd, :rate => 9600, :clear_screen => :true\n  output_pin 11, :as => :sound, :device => :freq_out, :frequency => 100, :enable => :true\n  input_pin 3, :as => :sensor_one, :device => :spectra\n\n\n   def setup\n     delay 1000\n     my_lcd.setxy 0,0, \"spectra symbol\"\n     my_lcd.setxy 0,1, \"soft pot sound\"\n     delay 3000\n     my_lcd.clearscr\n   end\n\n   def loop\n     my_lcd.setxy 0,1\n     # since lcd's have issues clearing tens and hundreds digits when reading ones, \n     # we use pad_int_to_str, which is a hack to display these cleanly\n     # pad_int_to_str takes two arguments: an integer and the final string length\n     # \n#     my_lcd.print pad_int_to_str analogRead(sensor_one), 5\n     @reading = sensor_one.soft_lock\n     sound.set_frequency @reading * 10\n     my_lcd.print pad_int_to_str @reading, 3\n     delay 30\n   end\n    \n\nend"
  },
  {
    "path": "lib/examples/hello_world.rb",
    "content": "class HelloWorld < ArduinoSketch\n  \n  output_pin 13, :as => :led\n\n  def loop\n    blink led, 100\n  end\n\nend\n\n\n"
  },
  {
    "path": "lib/examples/hello_xbee.rb",
    "content": "class HelloXbee < ArduinoSketch\n  \n  output_pin 13, :as => :led\n  \n  serial_begin\n  def loop\n    led.blink 200\n    serial_print \"...testing...\"\n    delay 1000\n  end\n  \nend"
  },
  {
    "path": "lib/examples/hysteresis_duel.rb",
    "content": "class HysteresisDuel < ArduinoSketch\n  \n  # purpose \n  # side by side demo of affect of hysteresis on two different sensor readings\n  # \n  #\n\n  # requires one pa_lcd\n  # two sensors or potentiometers\n\n\n\n    output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n    input_pin 1, :as => :sensor_one, :device => :sensor\n    input_pin 2, :as => :sensor_two, :device => :sensor\n\n    def setup\n      delay 1000\n      my_lcd.setxy 0,0, \"hysteresis duel\"\n      delay 5000\n      my_lcd.clearscr\n    end\n\n    def loop\n      my_lcd.setxy 0,0, \"direct\"\n      my_lcd.setxy 0,1, \"one: \"\n      my_lcd.print analogRead sensor_one\n      my_lcd.print \" two: \"\n      my_lcd.print analogRead sensor_two\n      my_lcd.setxy 0,2, \"with hysteresis\"\n      my_lcd.setxy 0,3, \"one: \"\n      my_lcd.print sensor_one.with_hyst 4\n      my_lcd.print \" two: \"\n      my_lcd.print sensor_two.with_hyst 4\n      delay 230\n    end\n\n    \nend\n"
  },
  {
    "path": "lib/examples/i2c_with_clock_chip.rb",
    "content": "class I2cWithClockChip < ArduinoSketch\n  \n# ----------------------------------------------------------------------------------\n#   <b>Time and Temp  (20 July 2008)</b>\n#   Example #1 - Brian Riley, Underhill Center, VT USA <brianbr@wulden.org>\n#   \n#   Connections\n#     I2C bus - DS1307 Real Time Clock chip\n#     Analog 0 (a.k.a Digital 14) - Wulfden K107 seria LCD Controller\n#                                   Peter Anderson chip\n#     Digital 8 - Dallas SemiConductor DS18B20 One-Wire temperature Sensor (12 bit)\n#\n#   Comment\n#     - This is a straight forward, program with minimal error checking and brute force\n#     delay() calls waiting for temperature conversion readings\n#\n#     - for the external data busses make sure you have 4.7K pullup resistors on the \n#     data line (OnewWire) and the SDA/SCL (I2C)\n\n# ----------------------------------------------------------------------------------\n \n    @hi_byte    = int\n    @lo_byte    = int\n    @t_reading  = int\n    @device_crc = int\n    @sign_bit   = int\n    @tc_100     = int\n                              # implicit in :device => Z:ds1307 is that this i i2c\n                              # :enable => true issues the Wire.begin to ick over i2c\n    output_pin 19, :as => :rtc, :device => :i2c_ds1307, :enable => :true\n                              # software serial tx drives LCD display, screen cleared at startup\n                              # defines the softare protocol for controller as Peter Anderson\n    output_pin 14, :as => :myLCD, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n                              # defines  this pin as being connected to a DalSemi 1-Wire device\n                              # no specific device drivers yet, the specific device code is on you\n    output_pin 8, :as => :myTemp, :device => :onewire\n\n\n    def loop\n  \t\t  until myTemp.reset do   # reset bus, verify its clear and high\n  \t\t    clear_bottom_line\n  \t\t    myLCD.print \" <1Wire Buss Error>\"\n  \t\t    delay 2000\n  \t\t  end\n   \t\t\n    \t\tmyTemp.skip                 # \"listen up - everybody!\"\n    \t\tmyTemp.write 0x44, 1        # temperature sensors, strta conversion\n\n    \t\tmyLCD.setxy 6,0             # while they do that, lets print date/time\n  \t    myLCD.print rtc.get(5, 1)\n       \tmyLCD.print \"/\"\n  \t    myLCD.print rtc.get(4, 0)\n       \tmyLCD.print \"/\"\n  \t    myLCD.print rtc.get(6, 0)\n       \tmyLCD.setxy 6,1\n       \tprintlz rtc.get(2, 0)\n       \tmyLCD.print \":\"\n  \t    printlz rtc.get(1, 0)\n       \tmyLCD.print \":\"\n  \t    printlz rtc.get(0, 0)\n\n    \t\tdelay 800                   # conversion takes about 750 msecs\n\n    \t\tuntil myTemp.reset do       # reset bus, verify its clear and high\n    \t\t  clear_bottom_line\n    \t\t  myLCD.print \" <1Wire Buss Error>\"\n    \t\t  delay 2000\n    \t\tend\n     \t\tmyTemp.skip                 # listen up!\n    \t\tmyTemp.write 0xBE, 1        # send me your data conversions\n\n        @lo_byte = myTemp.read      # get irst byte\n        @hi_byte = myTemp.read      # get second byte\n        \n        # -------------------------------------------------------------\n        clear_bottom_line       # this code is debug - not necessary\n        myLCD.setxy 4,3         # raw hex display of temp value\n        myLCD.print \"raw = 0x\"\n        print_hexbyte @hi_byte  # prints 2 digit hex w/lead 0\n        print_hexbyte @lo_byte\n        # -------------------------------------------------------------\n\n        7.times { @device_crc = myTemp.read } # get next 6 bytes, drop them on floor\n                                              # next byte the ninth byte is the CRC\n        \n                                # DS18B20 brings data temperature back as 12 bits\n                                # in degrees centigrade with 4 bits fractional, that is \n                                # each bit s 1/16 of a degreeC\n                                \n        @t_reading  =   build_int @hi_byte, @lo_byte\n        @sign_bit   =   bit_and @t_reading, 0x8000\n        @t_reading  =   twos_comp @t_reading   if @sign_bit  # negative\n\n        @tc_100 = (6 * @t_reading) + (@t_reading / 4)   #multiply by (100 * 0.0625) or 6.25\n\n        myLCD.setxy 2,2\n        if @sign_bit\n            myLCD.print \"-\"\n        else\n            myLCD.print \" \"\n        end\n        myLCD.print(@tc_100 / 100)             # separate off the whole \n        myLCD.print \".\"\n        printlz(@tc_100 % 100)                  # and fractional portions\n        myLCD.print \" degrees C\"\n\n    end\n\n    def\tprintlz(w)\n    \t\t\tmyLCD.print \"0\" if w < 10\n    \t\t\tmyLCD.print w\n    end\n\n    def\tprint_hexbyte(w)\n    \t\t\tmyLCD.print \"0\" if w < 0x10\n    \t\t\tmyLCD.print w, 0x10\n    end\n\n    def clear_bottom_line\n\t\t      myLCD.setxy 0,3\n\t\t      myLCD.print \"?l\"\n    end\n    \nend\n"
  },
  {
    "path": "lib/examples/midi_beat_box.rb",
    "content": "class MidiBeatBox < ArduinoSketch\n  \n  # midi synthesiser output on channel 2\n  # with speed controlled by spectra soft pot\n\n    @channel = 2\n    input_pin 1, :as => :sensor_one, :device => :spectra\n    output_pin 13, :as => :led\n\n    serial_begin :rate => 31250\n\n    def setup\n      delay 3000\n    end\n\n    def loop\n      8.times {first}\n      2.times do \n        second\n        third\n      end\n      4.times {first}\n      2.times {second}\n    end\n    \n    def first\n      play 39, 52, 37\n      play  0,  0,  0\n      play 36, 52,  0\n      play 37, 52, 39\n\n      play 37,  0,  0\n      play 36,  0,  0\n      play 39, 50,  0\n      play  0,  0,  0\n\n      play 52, 36, 37\n      play 0,  0,   0\n      play 39,  0,  0\n      play 36, 37,  0\n\n      play 36, 37, 39\n      play 36, 38,  0\n      play 50,  0,  0\n      play 0,   0,  0\n    end\n    \n    def second\n      play 39, 52, 37\n      play 36,  0,  0\n      play  0,  0,  0\n      play 37, 52, 39\n\n      play 38,  0,  0\n      play 36,  0,  0\n      play 39, 50,  0\n      play  0,  0,  0\n    end\n    \n    def third\n      play  0, 36, 37\n      play  0,  0,   0\n      play 39, 36,  0\n      play 36, 37, 50\n\n      play 36, 37, 39\n      play 36, 37,  0\n      play 50,  0,  0\n      play 39,  0,  0\n    end\n    \n\n    def play(one, two, three)\n      n = 1 + one + two + three # ack to coerce parameters to int\n      note_on(@channel, one, 127) unless one == 0\n      note_on(@channel, two, 127) unless two == 0\n      note_on(@channel, three, 127) unless three == 0\n      delay 310 - sensor_one.soft_lock # start slowly \n      note_off(@channel, one, 0) unless one == 0\n      note_off(@channel, two, 0) unless two == 0\n      note_off(@channel, three, 0) unless three == 0\n    end\n    \n\n    \nend"
  },
  {
    "path": "lib/examples/midi_scales.rb",
    "content": "class MidiScales < ArduinoSketch\n  \n# purpose\n# trigger midi output with buttons and\n# spectra soft pots\n#\n#\n\n\n  @current_note = int\n  @last_note_one = 0\n  @last_note_two = 0\n  @last_note_three = 0\n  @note = int\n\n  input_pin 1, :as => :sensor_one, :device => :spectra\n  input_pin 2, :as => :sensor_two, :device => :spectra\n  input_pin 3, :as => :sensor_three, :device => :spectra\n  input_pin 7, :as => :button_one, :device => :button\n  input_pin 8, :as => :button_two, :device => :button\n  input_pin 9, :as => :button_three, :device => :button\n  output_pin 13, :as => :led\n\n  serial_begin :rate => 31250\n\n  def setup\n    delay 3000\n  end\n\n  def loop\n    change_tone if button_one.read_input\n    change_pressure if button_two.read_input\n    change_channels if button_three.read_input\n    read_sensor_one\n    read_sensor_two\n    read_sensor_three\n  end\n     \n  def change_tone \n    110.upto(127) do |note|\n      play 0, note, 127\n    end\n  end\n\n  def change_pressure\n    110.upto(127) do |pressure| \n       play 0, 45, pressure\n    end\n  end\n     \n  def change_channels \n    0.upto(6) do |channel| \n      play channel, 50, 100\n    end\n  end\n\n  def read_sensor_one\n    @current_note = sensor_one.soft_lock\n    pre_play(@current_note, @last_note_one, 13)\n    @last_note_one = @current_note\n  end\n\n  def read_sensor_two\n    @current_note = sensor_two.soft_lock\n    pre_play(@current_note, @last_note_two, 14)\n    @last_note_two = @current_note\n  end\n\n  def read_sensor_three\n    @current_note = sensor_three.soft_lock\n    pre_play(@current_note, @last_note_three, 15)\n    @last_note_three = @current_note\n  end\n\n  def pre_play(current_note, last_note, channel) # warning, don't use last as a parameter...\n    n = 1 + channel\n    unless current_note == last_note\n      @note = ((current_note /16) + 40)\n      play_with_no_delay( channel, @note, 100 )\n    end\n  end\n    \n  def play(chan, note, pressure)\n    note_on(chan, note, pressure)\n    delay 100 # adjust to need\n    note_off(chan, note, 0)\n  end\n  \n  def play_with_no_delay(chan, note, pressure) # note is not turned off\n    note_on(chan, note, pressure)\n  end\n\n\nend\n"
  },
  {
    "path": "lib/examples/motor_knob.rb",
    "content": "class MotorKnob < ArduinoSketch\n\n# ----------------------------------------------------------\n#    MotorKnob adapted from Tom Igoe's Arduino Sketch\n#\n#      Brian Riley - Underhill Center, VT, USA  July 2008\n#                     <brianbr@wulfden.org>\n#\n#    A stepper motor follows the turns of a potentiometer\n#    (or other sensor) on analog input 0.\n#\n#     http://www.arduino.cc/en/Reference/Stepper\n# ----------------------------------------------------------\n\n  fourwire_stepper  8, 9, 10, 11, :as => :mystepper, :speed => 31, :steps => 200\n  input_pin  0, :as => :sensor\n  \n  \n  @previous = \"0, int\"\n  @value    = \"0, int\"\n  \n  def loop\n    \n    @value = analogRead(sensor)\n    mystepper.set_steps @value - @previous\n    @previous = @value \n    \n  end\n\nend"
  },
  {
    "path": "lib/examples/servo_buttons.rb",
    "content": "class ServoButtons < ArduinoSketch\n  \n  # original syntax\n  input_pin 6, :as => :button_one, :latch => :off\n  # preferred syntax\n  input_pin 7, :as => :button_two, :device => :button\n  input_pin 8, :as => :button_three, :device => :button\n  output_pin 13, :as => :led \n  output_pin 2, :as => :my_servo, :device => :servo \n  \n\n  def loop\n   check_buttons\n   servo_refresh \n  end\n\n  def check_buttons\n  \tread_and_toggle button_one, led\n  \tmy_servo.position 180 if read_input button_two\n  \tmy_servo.position 60 if read_input button_three\n  end\n  \nend"
  },
  {
    "path": "lib/examples/servo_calibrate_continuous.rb",
    "content": "class ServoCalibrateContinuous < ArduinoSketch\n\n  # ----------------------------------------------------------------------\n  #    Program to calibrate a 'continuous' or 'modified' hobby servo\n  #\n  #    Basically uses teh servo 'spped' command to send a speed\n  #    of zero (0) to the servo continuously. You then use a small\n  #    screwdriver to adjust the potentiometer on the sero until there\n  #    is no motion whatsoever.\n  #\n  #    The program strats off by commanding max speed clockwise and then\n  #    counter clockwise. First the LED blinks rapidly for 2 seconds as\n  #    a warning that motion is coming. Then the LED is turned on solid\n  #    Then 2 seconds max rev clockwise, then two seconds max rev counter-\n  #    clockwise. Then the LED is turned off and this followed by twenty\n  #    second of the servo commanded to zero (0) speed. During this time\n  #    you may adjust the servo for no motion. If you stilll have more\n  #    adjustmenst to make you will be warned by the flashing LED to\n  #    back off while it moves back and forth. This full speed motion\n  #    is to let you knwo you have it right,\n  #\n  #    The 20 second timer uses the Arduino millis() counter which\n  #    rolls over after a couple million milliseconds. I made no attempt\n  #    to allow for ths. If your servo isn't calibrated after a couple\n  #    million milliseconds and the prgram jams up then (a) hit the reset\n  #    button, or (b) give up!\n  #\n  #      Brian Riley - Underhill Center, VT, USA  July 2008\n  #                     <brianbr@wulfden.org>\n  #\n  # ----------------------------------------------------------------------\n  \n   \n  @test_state = \"2, int\"\n  @cycle_time = \"0, long\"\n  \n  \n      # This sets up to do four units at once\n      # You can comment the extra lines out or leave them in, if there's nothing\n      # connected, no harm, no foul!\n      output_pin 12, :as => :servo4, :device => :servo, :minp => 400, :maxp => 2600\n      output_pin 11, :as => :servo3, :device => :servo, :minp => 400, :maxp => 2600\n      output_pin 10, :as => :servo2, :device => :servo, :minp => 400, :maxp => 2600\n      output_pin  9, :as => :servo1, :device => :servo, :minp => 400, :maxp => 2600\n \n      output_pin 13, :as => :led\n\n\n\n  def loop\n    if @test_state == 2\n\n      40.times { blink led, 50 }    # 40 x 50 ms is a 2 second blinking light\n                                    #  ** Warning! **  \"... danger Will Robinson!\"\n      toggle led                    # turn it on keep it on -- keep hands away\n      servo1.speed -90\n      servo2.speed -90\n      servo3.speed -90\n      servo4.speed -90\n      delay_servo 2000              # two full seconds max clockwise\n      servo1.speed 90\n      servo2.speed 90\n      servo3.speed 90\n      servo4.speed 90\n      delay_servo 2000              # two full seconds max counter clockwise\n      \n      @test_state = 1               # setup for zero speed test/adjust\n      @cycle_time = millis + 20000\n      servo1.speed 0\n      servo2.speed 0\n      servo3.speed 0\n      servo4.speed 0\n      toggle led                    # lights off, OK  you have 20 seconds to adjust\n    end\n\n    if @cycle_time - millis <= 0\n        @test_state = 2\n    else\n        servo_refresh\n    end\n        \n  end\n  \n  \n  def delay_servo(t)\n    t.times do\n      delay 1\n      servo_refresh\n    end\n  end\n  \nend"
  },
  {
    "path": "lib/examples/servo_throttle.rb",
    "content": "class ServoThrottle < ArduinoSketch\n\n     # updated 20080731 \n     # replaced external variables with instance style variables\n     \n     # potentiometer to control servo\n     # with a bit of hysteresis\n     # use analog pin for sensor\n     # need to format the output of sensor_position and sensor_amount\n\n     @sensor_position = 0\n     @servo_amount = 0\n\n     output_pin 5, :as => :my_lcd, :device => :sf_lcd\n     input_pin 1, :as => :sensor\n     output_pin 2, :as => :my_servo, :device => :servo\n\n\n       def loop\n         servo_refresh\n         #delay 9 # comment out if using servo status, since it will add enough delay\n         @sensor_position = analogRead(sensor)\n         @servo_amount = (add_hysteresis(@sensor_position, 10)*0.36)\n         my_servo.position @servo_amount\n         servo_status\n         \n       end\n       \n       def servo_status\n         \n        my_lcd.setxy 0,0\t\t\t# line 0, col 0\n     \t\tmy_lcd.print \"Read  Send\"\n     \t\tmy_lcd.setxy 0,1\t\t# line 1, col 0\n     \t\tmy_lcd.print @sensor_position # need method of blanking out previous reading\n     \t\tmy_lcd.setxy 6,1 \n     \t\tmy_lcd.print @servo_amount\n       end\n\n  \nend"
  },
  {
    "path": "lib/examples/software_serial.rb",
    "content": "class SoftwareSerial < ArduinoSketch\n  output_pin 13, :as => :led\n  software_serial 6, 7, :as => :gps\n  serial_begin\n\n  def loop\n    digitalWrite(led, true)\n    serial_print(gps.read)\n  end\nend"
  },
  {
    "path": "lib/examples/sparkfun_lcd.rb",
    "content": "class SparkfunLcd < ArduinoSketch\n\n\n  input_pin 6, :as => :button_one, :latch => :off\n  input_pin 7, :as => :button_two, :latch => :off\n  input_pin 8, :as => :button_three, :latch => :off\n  output_pin 13, :as => :led\n  \n  swser_LCDsf 5, :as => :my_lcd\n  \n\n\n\n#serial_begin # not necessary when using :device => :sf_lcd or :pa_lcd\n\n  def loop\n   check_buttons\n  end\n  \n\n# need a bit\n\n  def say_hello\n    my_lcd.setxy 0,0\t\t\t# line 0, col 0\n\t\tmy_lcd.print \"All your base   \"\n\t\tmy_lcd.setxy 0,1\t\t# line 1, col 0\n\t\tmy_lcd.print \"are belong to us\"\n  \n  end \n  \n  def\tsay_ruby\n\t\tmy_lcd.setxy 0,0\t\t\t# line 0, col 0\n\t\tmy_lcd.print \" Ruby + Arduino \"\n\t\tmy_lcd.setxy 0,1\t\t# line 1, col 0\n\t\tmy_lcd.print \" RAD 0.2.4+     \"\n\t\t# un comment to change display startup\n\t\t#myLCD.setcmd 0x7C, 10\n\tend\n\n  def check_buttons\n  \tread_and_toggle button_one, led\n  \tsay_hello if read_input button_two\n  \tsay_ruby if read_input button_three\n  \t\n  \t\n  end\n  \nend"
  },
  {
    "path": "lib/examples/spectra_soft_pot.rb",
    "content": "class SpectraSoftPot < ArduinoSketch\n\n  # demonstrate capability to use soft pot as traditional pot\n  # the last pot reading remains \"locked\" to the last touch point\n  # similar same behavior as ipod\n  #\n  # this sketch assumes a pa_lcd operating at 19200 and one \n  # spectra symbol softpot connected to analog pin 3\n  # \n\n  output_pin 5, :as => :my_lcd, :device => :pa_lcd, :rate => 19200, :clear_screen => :true\n  input_pin 3, :as => :sensor_one, :device => :spectra\n\n\n   def setup\n     delay 1000\n     my_lcd.setxy 0,0, \"spectra symbol\"\n     my_lcd.setxy 0,1, \"soft pot\"\n     delay 5000\n     my_lcd.clearscr\n   end\n\n   def loop\n     my_lcd.setxy 0,1\n     # since lcd's have issues clearing tens and hundreds digits when reading ones, \n     # we use pad_int_to_str, which is a hack to display these cleanly\n     # pad_int_to_str takes two arguments: an integer and the final string length\n     # \n     my_lcd.print pad_int_to_str sensor_one.soft_lock, 3\n     delay 100\n   end\n    \n\nend"
  },
  {
    "path": "lib/examples/times_method.rb",
    "content": "class TimesMethod < ArduinoSketch\n\n  def loop\n    5.times { delay 200 }\n  end\n\n  \nend"
  },
  {
    "path": "lib/examples/toggle.rb",
    "content": "class Toggle < ArduinoSketch\n\n    output_pin 13, :as => :led\n\n       def loop\n         led.toggle\n         delay 300\n       end\n\n  end"
  },
  {
    "path": "lib/examples/twitter.rb",
    "content": "class Twitter < ArduinoSketch\n  \n  #include <avr/io.h>\n  #include <string.h>\n\n\n\n  define \"TWEETLEN 141\"\n  define \"HOSTNAME www.twitter.com\"\n  \n  define 'IPADDR \"128.121.146.100\"'  # twitter.com\n  define \"PORT 80\"                 # // HTTP\n  define \"HTTPPATH /atduskgreg/\"    # // the person we want to follow\n  \n\n  define \"TWEETLEN 141\"\n  array \"char linebuffer[256]\" # // our large buffer for data\n  array \"char tweet[TWEETLEN]\" # // the tweet\n  @lines = 0\n\n  \n  define \"XPORT_RXPIN 2\"\n  define \"XPORT_TXPIN 3\"\n  define \"XPORT_RESETPIN 4\"\n  define \"XPORT_DTRPIN 5\"\n  define \"XPORT_CTSPIN 6\"\n  define \"XPORT_RTSPIN 7\"\n  \n\n  @errno = 0\n  @laststatus = 0\n  @currstatus = 0\n\n\n  \n# in setup\n#xport = AF_XPort(XPORT_RX, XPORT_TX, XPORT_RESET, XPORT_DTR, XPORT_RTS, XPORT_CTS)\n  \n  \n  output_pin 10, :as => :shield, :device => :ethernet\n  \n  serial_begin :rate => 57600\n  \n  def loop\n    \n#  local_connect()\n    # kind of a problem... fixed\n    get_tweet\n    fetchtweet\n    delay 30000\n\n\n  end\n  \n\n  \nend"
  },
  {
    "path": "lib/examples/two_wire.rb",
    "content": "class TwoWire < ArduinoSketch\n\n  # just a demo that two_wire loads\n\n  output_pin 19, :as => :wire, :device => :i2c, :enable => :true\n  \n  def loop\n\n\t  x = 4    \n  \n  end\n    \n\nend"
  },
  {
    "path": "lib/libraries/Wire/utility/twi.c",
    "content": "/*\n  twi.c - TWI/I2C library for Wiring & Arduino\n  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n*/\n\n#include <math.h>\n#include <stdlib.h>\n#include <inttypes.h>\n#include <avr/io.h>\n#include <avr/interrupt.h>\n#include <avr/signal.h>\n#include <compat/twi.h>\n\n#ifndef cbi\n#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))\n#endif\n\n#ifndef sbi\n#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))\n#endif\n\n#include \"twi.h\"\n\nstatic volatile uint8_t twi_state;\nstatic uint8_t twi_slarw;\n\nstatic void (*twi_onSlaveTransmit)(void);\nstatic void (*twi_onSlaveReceive)(uint8_t*, int);\n\nstatic uint8_t* twi_masterBuffer;\nstatic volatile uint8_t twi_masterBufferIndex;\nstatic uint8_t twi_masterBufferLength;\n\nstatic uint8_t* twi_txBuffer;\nstatic volatile uint8_t twi_txBufferIndex;\nstatic volatile uint8_t twi_txBufferLength;\n\nstatic uint8_t* twi_rxBuffer;\nstatic volatile uint8_t twi_rxBufferIndex;\n\n/* \n * Function twi_init\n * Desc     readys twi pins and sets twi bitrate\n * Input    none\n * Output   none\n */\nvoid twi_init(void)\n{\n  // initialize state\n  twi_state = TWI_READY;\n\n  #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__)\n    // activate internal pull-ups for twi\n    // as per note from atmega8 manual pg167\n    sbi(PORTC, 4);\n    sbi(PORTC, 5);\n  #else\n    // activate internal pull-ups for twi\n    // as per note from atmega128 manual pg204\n    sbi(PORTD, 0);\n    sbi(PORTD, 1);\n  #endif\n\n  // initialize twi prescaler and bit rate\n  cbi(TWSR, TWPS0);\n  cbi(TWSR, TWPS1);\n  TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;\n\n  /* twi bit rate formula from atmega128 manual pg 204\n  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))\n  note: TWBR should be 10 or higher for master mode\n  It is 72 for a 16mhz Wiring board with 100kHz TWI */\n\n  // enable twi module, acks, and twi interrupt\n\tTWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);\n\t\n\t// allocate buffers\n  twi_masterBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));\n  twi_txBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));\n  twi_rxBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));\n}\n\n/* \n * Function twi_slaveInit\n * Desc     sets slave address and enables interrupt\n * Input    none\n * Output   none\n */\nvoid twi_setAddress(uint8_t address)\n{\n  // set twi slave address (skip over TWGCE bit)\n  TWAR = address << 1;\n}\n\n/* \n * Function twi_readFrom\n * Desc     attempts to become twi bus master and read a\n *          series of bytes from a device on the bus\n * Input    address: 7bit i2c device address\n *          data: pointer to byte array\n *          length: number of bytes to read into array\n * Output   byte: 0 ok, 1 length too long for buffer\n */\nuint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)\n{\n  uint8_t i;\n\n  // ensure data will fit into buffer\n  if(TWI_BUFFER_LENGTH < length){\n    return 1;\n  }\n\n  // wait until twi is ready, become master receiver\n  while(TWI_READY != twi_state){\n    continue;\n  }\n  twi_state = TWI_MRX;\n\n  // initialize buffer iteration vars\n  twi_masterBufferIndex = 0;\n  twi_masterBufferLength = length;\n\n  // build sla+w, slave device address + w bit\n  twi_slarw = TW_READ;\n\ttwi_slarw |= address << 1;\n\n  // send start condition\n\tTWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);\n\n\t// wait for read operation to complete\n\twhile(TWI_MRX == twi_state){\n\t  continue;\n\t}\n\n  // copy twi buffer to data\n  for(i = 0; i < length; ++i){\n    data[i] = twi_masterBuffer[i];\n  }\n\t\n\treturn 0;\n}\n\n/* \n * Function twi_writeTo\n * Desc     attempts to become twi bus master and write a\n *          series of bytes to a device on the bus\n * Input    address: 7bit i2c device address\n *          data: pointer to byte array\n *          length: number of bytes in array\n *          wait: boolean indicating to wait for write or not\n * Output   byte: 0 ok, 1 length too long for buffer\n */\nuint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)\n{\n  uint8_t i;\n\n  // ensure data will fit into buffer\n  if(TWI_BUFFER_LENGTH < length){\n    return 1;\n  }\n\n  // wait until twi is ready, become master transmitter\n  while(TWI_READY != twi_state){\n    continue;\n  }\n  twi_state = TWI_MTX;\n\n  // initialize buffer iteration vars\n  twi_masterBufferIndex = 0;\n  twi_masterBufferLength = length;\n  \n  // copy data to twi buffer\n  for(i = 0; i < length; ++i){\n    twi_masterBuffer[i] = data[i];\n  }\n  \n  // build sla+w, slave device address + w bit\n  twi_slarw = TW_WRITE;\n\ttwi_slarw |= address << 1;\n  \n  // send start condition\n\tTWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);\n\n\t// wait for write operation to complete\n\twhile(wait && (TWI_MTX == twi_state)){\n\t  continue;\n\t}\n\t\n\treturn 0;\n}\n\n/* \n * Function twi_transmit\n * Desc     fills slave tx buffer with data\n *          must be called in slave tx event callback\n * Input    data: pointer to byte array\n *          length: number of bytes in array\n * Output   1 length too long for buffer\n *          2 not slave transmitter\n *          0 ok\n */\nuint8_t twi_transmit(uint8_t* data, uint8_t length)\n{\n  uint8_t i;\n\n  // ensure data will fit into buffer\n  if(TWI_BUFFER_LENGTH < length){\n    return 1;\n  }\n  \n  // ensure we are currently a slave transmitter\n  if(TWI_STX != twi_state){\n    return 2;\n  }\n  \n  // set length and copy data into tx buffer\n  twi_txBufferLength = length;\n  for(i = 0; i < length; ++i){\n    twi_txBuffer[i] = data[i];\n  }\n  \n  return 0;\n}\n\n/* \n * Function twi_attachSlaveRxEvent\n * Desc     sets function called before a slave read operation\n * Input    function: callback function to use\n * Output   none\n */\nvoid twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )\n{\n  twi_onSlaveReceive = function;\n}\n\n/* \n * Function twi_attachSlaveTxEvent\n * Desc     sets function called before a slave write operation\n * Input    function: callback function to use\n * Output   none\n */\nvoid twi_attachSlaveTxEvent( void (*function)(void) )\n{\n  twi_onSlaveTransmit = function;\n}\n\n/* \n * Function twi_reply\n * Desc     sends byte or readys receive line\n * Input    ack: byte indicating to ack or to nack\n * Output   none\n */\nvoid twi_reply(uint8_t ack)\n{\n\t// transmit master read ready signal, with or without ack\n\tif(ack){\n\t  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);\n  }else{\n\t  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);\n  }\n}\n\n/* \n * Function twi_stop\n * Desc     relinquishes bus master status\n * Input    none\n * Output   none\n */\nvoid twi_stop(void)\n{\n  // send stop condition\n  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);\n\n  // wait for stop condition to be exectued on bus\n  // TWINT is not set after a stop condition!\n  while(TWCR & _BV(TWSTO)){\n    continue;\n  }\n\n  // update twi state\n  twi_state = TWI_READY;\n}\n\n/* \n * Function twi_releaseBus\n * Desc     releases bus control\n * Input    none\n * Output   none\n */\nvoid twi_releaseBus(void)\n{\n  // release bus\n  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);\n\n  // update twi state\n  twi_state = TWI_READY;\n}\n\nSIGNAL(SIG_2WIRE_SERIAL)\n{\n  switch(TW_STATUS){\n    // All Master\n    case TW_START:     // sent start condition\n    case TW_REP_START: // sent repeated start condition\n      // copy device address and r/w bit to output register and ack\n      TWDR = twi_slarw;\n      twi_reply(1);\n      break;\n\n    // Master Transmitter\n    case TW_MT_SLA_ACK:  // slave receiver acked address\n    case TW_MT_DATA_ACK: // slave receiver acked data\n      // if there is data to send, send it, otherwise stop \n      if(twi_masterBufferIndex < twi_masterBufferLength){\n        // copy data to output register and ack\n        TWDR = twi_masterBuffer[twi_masterBufferIndex++];\n        twi_reply(1);\n      }else{\n        twi_stop();\n      }\n      break;\n    case TW_MT_SLA_NACK:  // address sent, nack received\n    case TW_MT_DATA_NACK: // data sent, nack received\n      twi_stop();\n      break;\n    case TW_MT_ARB_LOST: // lost bus arbitration\n      twi_releaseBus();\n      break;\n\n    // Master Receiver\n    case TW_MR_DATA_ACK: // data received, ack sent\n      // put byte into buffer\n      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;\n    case TW_MR_SLA_ACK:  // address sent, ack received\n      // ack if more bytes are expected, otherwise nack\n      if(twi_masterBufferIndex < twi_masterBufferLength){\n        twi_reply(1);\n      }else{\n        twi_reply(0);\n      }\n      break;\n    case TW_MR_DATA_NACK: // data received, nack sent\n      // put final byte into buffer\n      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;\n    case TW_MR_SLA_NACK: // address sent, nack received\n      twi_stop();\n      break;\n    // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case\n\n    // Slave Receiver\n    case TW_SR_SLA_ACK:   // addressed, returned ack\n    case TW_SR_GCALL_ACK: // addressed generally, returned ack\n    case TW_SR_ARB_LOST_SLA_ACK:   // lost arbitration, returned ack\n    case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack\n      // enter slave receiver mode\n      twi_state = TWI_SRX;\n      // indicate that rx buffer can be overwritten and ack\n      twi_rxBufferIndex = 0;\n      twi_reply(1);\n      break;\n    case TW_SR_DATA_ACK:       // data received, returned ack\n    case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack\n      // if there is still room in the rx buffer\n      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){\n        // put byte in buffer and ack\n        twi_rxBuffer[twi_rxBufferIndex++] = TWDR;\n        twi_reply(1);\n      }else{\n        // otherwise nack\n        twi_reply(0);\n      }\n      break;\n    case TW_SR_STOP: // stop or repeated start condition received\n      // put a null char after data if there's room\n      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){\n        twi_rxBuffer[twi_rxBufferIndex] = '\\0';\n      }\n      // callback to user defined callback\n      twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);\n      // ack future responses\n      twi_reply(1);\n      // leave slave receiver state\n      twi_state = TWI_READY;\n      break;\n    case TW_SR_DATA_NACK:       // data received, returned nack\n    case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack\n      // nack back at master\n      twi_reply(0);\n      break;\n    \n    // Slave Transmitter\n    case TW_ST_SLA_ACK:          // addressed, returned ack\n    case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack\n      // enter slave transmitter mode\n      twi_state = TWI_STX;\n      // ready the tx buffer index for iteration\n      twi_txBufferIndex = 0;\n      // set tx buffer length to be zero, to verify if user changes it\n      twi_txBufferLength = 0;\n      // request for txBuffer to be filled and length to be set\n      // note: user must call twi_transmit(bytes, length) to do this\n      twi_onSlaveTransmit();\n      // if they didn't change buffer & length, initialize it\n      if(0 == twi_txBufferLength){\n        twi_txBufferLength = 1;\n        twi_txBuffer[0] = 0x00;\n      }\n      // transmit first byte from buffer, fall\n    case TW_ST_DATA_ACK: // byte sent, ack returned\n      // copy data to output register\n      TWDR = twi_txBuffer[twi_txBufferIndex++];\n      // if there is more to send, ack, otherwise nack\n      if(twi_txBufferIndex < twi_txBufferLength){\n        twi_reply(1);\n      }else{\n        twi_reply(0);\n      }\n      break;\n    case TW_ST_DATA_NACK: // received nack, we are done \n    case TW_ST_LAST_DATA: // received ack, but we are done already!\n      // ack future responses\n      twi_reply(1);\n      // leave slave receiver state\n      twi_state = TWI_READY;\n      break;\n\n    // All\n    case TW_NO_INFO:   // no state information\n      break;\n    case TW_BUS_ERROR: // bus error, illegal stop/start\n      twi_stop();\n      break;\n  }\n}\n\n"
  },
  {
    "path": "lib/libraries/Wire/utility/twi.h",
    "content": "/*\n  twi.h - TWI/I2C library for Wiring & Arduino\n  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n*/\n\n#ifndef twi_h\r\n#define twi_h\r\n\n  #include <inttypes.h>\n\n  //#define ATMEGA8\n\n  #ifndef CPU_FREQ\r\n  #define CPU_FREQ 16000000L\n  #endif\n\n  #ifndef TWI_FREQ\r\n  #define TWI_FREQ 100000L\n  #endif\n\n  #ifndef TWI_BUFFER_LENGTH\n  #define TWI_BUFFER_LENGTH 32\n  #endif\n\n  #define TWI_READY 0\n  #define TWI_MRX   1\n  #define TWI_MTX   2\n  #define TWI_SRX   3\n  #define TWI_STX   4\n  \n  void twi_init(void);\n  void twi_setAddress(uint8_t);\n  uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);\n  uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);\n  uint8_t twi_transmit(uint8_t*, uint8_t);\n  void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );\n  void twi_attachSlaveTxEvent( void (*)(void) );\n  void twi_reply(uint8_t);\n  void twi_stop(void);\n  void twi_releaseBus(void);\r\n\r\n#endif\n\n"
  },
  {
    "path": "lib/plugins/bitwise_ops.rb",
    "content": "class BitwiseOps < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n\n  # add to directives\n \n  # add to external variables\n \n  # add the following to the setup method\n  # add_to_setup \n\n\nint build_int(int hibyte, int lobyte) {\n    return((hibyte << 8) + lobyte);\n}\n\nint i_shiftleft(int val, int shift) {\n    return(val << shift);\n}\n\nint i_shiftright(int val, int shift) {\n    return(val >> shift);\n}\n\nbyte b_shiftleft(byte val, byte shift) {\n    return(val << shift);\n}\n\nbyte b_shiftright(byte val, byte shift) {\n    return(val >> shift);\n}\n\nint bit_and(int val, int mask) {\n    return(val & mask);\n}\n\nint bit_or(int val, int mask) {\n    return(val | mask);\n}\n\nint bit_xor(int val, int mask) {\n    return(val ^ mask);\n}\n\nint twos_comp(int val) {\n    return((val ^ 0xffff) + 1);\n}\n\nend"
  },
  {
    "path": "lib/plugins/blink.rb",
    "content": "class Blink < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n\n  # add to directives\n \n  # add to external variables\n \n  # add the following to the setup method\n  # add_to_setup \n\n\n  void blink(int pin, int ms) {\n  \tdigitalWrite( pin, HIGH );\n  \tdelay( ms );\n  \tdigitalWrite( pin, LOW );\n  \tdelay( ms );\n  }\n\nend"
  },
  {
    "path": "lib/plugins/blink_m.rb",
    "content": "class BlinkM < ArduinoPlugin\n\n#\n#\n#  BlinkM_funcs.h -- Arduino library to control BlinkM\n#  --------------\n#\n#\n#  Note: original version of this file lives with the BlinkMTester sketch\n#\n#  2007, Tod E. Kurt, ThingM, http://thingm.com/\n#\n#  version: 20080203\n#\n#  history:\n#   20080101 - initial release\n#   20080203 - added setStartupParam(), bugfix receiveBytes() from Dan Julio\n#   20080727 - ported to rad jd barnhart\n#\n#   first step, declare output pin 19 as i2c\n##  output_pin 19, :as => :wire, :device => :i2c, :enable => :true # reminder, true issues wire.begin\n\n\ninclude_wire\n\nadd_blink_m_struct\n\n\n\n# Not needed when pin is declared with :enable => :true \n# In fact, declaring it twice causes nothing but problems\n\nstatic void BlinkM_begin()\n{\n    Wire.begin();                // join i2c bus (address optional for master)\n}\n\n\n// General version of BlinkM_beginWithPower().\n\nstatic void BlinkM_beginWithPowerPins(byte pwrpin, byte gndpin)\n{\n    DDRC |= _BV(pwrpin) | _BV(gndpin);  // make outputs\n    PORTC &=~ _BV(gndpin);\n    PORTC |=  _BV(pwrpin);\n    delay(100);  // wait for things to stabilize\n\n    Wire.begin();\n}\n\n// Call this first when BlinkM is plugged directly into Arduino\n// The BlinkMs PWR (power) pins should line up with pins 2 and 3 of the connector, \n// while the I2C (communications) pins should line up with pins 4 and 5.\n\nstatic void BlinkM_beginWithPower()\n{\n    BlinkM_beginWithPowerPins( PC3, PC2 );\n}\n\n// sends a generic command\n\nstatic void BlinkM_sendCmd(byte addr, byte* cmd, int cmdlen)\n{\n    Wire.beginTransmission(addr);\n    for( byte i=0; i<cmdlen; i++) \n        Wire.send(cmd[i]);\n    Wire.endTransmission();\n}\n\n// receives generic data\n// returns 0 on success, and -1 if no data available\n// note: responsiblity of caller to know how many bytes to expect\n\nstatic int BlinkM_receiveBytes(byte addr, byte* resp, byte len)\n{\n    Wire.requestFrom(addr, len);\n    if( Wire.available() ) {\n        for( int i=0; i<len; i++) \n            resp[i] = Wire.receive();\n        return 0;\n    }\n    return -1;\n}\n\n// Sets the I2C address of the BlinkM(s)\n// Typically used to setup BlinkM addresses\n// Connect one and call this with an address like 10, \n// then 11 for the next and so on and so forth \n// Uses \"general call\" broadcast address\n\nstatic void BlinkM_setAddress(byte newaddress)\n{\n  Wire.beginTransmission(0x00);  // general call (broadcast address)\n  Wire.send('A');\n  Wire.send(newaddress);\n  Wire.send(0xD0);\n  Wire.send(0x0D);  // dood!\n  Wire.send(newaddress);\n  Wire.endTransmission();\n  delay(50); // just in case\n}\n\n\n// Gets the I2C addrss of the BlinkM\n// Kind of redundant when sent to a specific address\n// but uses to verify BlinkM communication\n\nstatic int BlinkM_getAddress(byte addr)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('a');\n    Wire.endTransmission();\n    Wire.requestFrom(addr, (byte)1);\n    if( Wire.available() ) {\n        byte b = Wire.receive();\n        return b; \n    }\n    return -1;\n}\n\n// Gets the BlinkM firmware version\n\nstatic int BlinkM_getVersion(byte addr)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('Z');\n    Wire.endTransmission();\n    Wire.requestFrom(addr, (byte)2);\n    if( Wire.available() ) {\n        byte major_ver = Wire.receive();\n        byte minor_ver = Wire.receive();\n        return (major_ver<<8) + minor_ver;\n    }\n    return -1;\n}\n\n// Demonstrates how to verify you-re talking to a BlinkM \n// and that you know its address -- message version\n\nstatic char* blink_m_check_address_message(byte addr) // :as => :optional\n{\n    char message[50];\n    char status[5];\n    strcpy(message, \"received 0x\");\n    //Serial.print(\"Checking BlinkM address...\");\n    int b = BlinkM_getAddress(addr);\n    if( b==-1 ) {\n        //Serial.println(\"No response, that's not good\");\n        return \"No response, that's not good\";  // no response\n    } \n    itoa(b, status ,16);\n    \n    //Serial.print(\"received addr: 0x\");\n    //Serial.print(b,HEX);\n    if( b != addr )\n        return \"error, mismatch\"; // error, addr mismatch \n    else \n        return strcat(message, status); // match, everything okay\n}\n\n// Demonstrates how to verify you-re talking to a BlinkM \n// and that you know its address -- digital version\n\nstatic int BlinkM_checkAddress(byte addr)\n{\n    //Serial.print(\"Checking BlinkM address...\");\n    int b = BlinkM_getAddress(addr);\n    if( b==-1 ) {\n        //Serial.println(\"No response, that's not good\");\n        return -1;  // no response\n    } \n    \n    //Serial.print(\"received addr: 0x\");\n    //Serial.print(b,HEX);\n    if( b != addr )\n        return 1; // error, addr mismatch \n    else \n        return 0; // match, everything okay\n}\n\n// Sets the speed of fading between colors.  \n// Higher numbers means faster fading, 255 == instantaneous fading\n\nstatic void BlinkM_setFadeSpeed(byte addr, byte fadespeed)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('f');\n    Wire.send(fadespeed);\n    Wire.endTransmission();  \n}\n\n// Sets the light script playback time adjust\n// The timeadj argument is signed, and is an additive value to all\n// durations in a light script. Set to zero to turn off time adjust.\n\nstatic void BlinkM_setTimeAdj(byte addr, byte timeadj)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('t');\n    Wire.send(timeadj);\n    Wire.endTransmission();  \n}\n\n// Fades to an RGB color\n\nstatic void BlinkM_fadeToRGB(byte addr, byte red, byte grn, byte blu)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('c');\n    Wire.send(red);\n    Wire.send(grn);\n    Wire.send(blu);\n    Wire.endTransmission();\n}\n\n// Fades to an HSB color\n\nstatic void BlinkM_fadeToHSB(byte addr, byte hue, byte saturation, byte brightness)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('h');\n    Wire.send(hue);\n    Wire.send(saturation);\n    Wire.send(brightness);\n    Wire.endTransmission();\n}\n\n// Sets an RGB color immediately\n\nstatic void BlinkM_setRGB(byte addr, byte red, byte grn, byte blu)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('n');\n    Wire.send(red);\n    Wire.send(grn);\n    Wire.send(blu);\n    Wire.endTransmission();\n}\n\n// Fades to a random RGB color\n\nstatic void BlinkM_fadeToRandomRGB(byte addr, byte rrnd, byte grnd, byte brnd)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('C');\n    Wire.send(rrnd);\n    Wire.send(grnd);\n    Wire.send(brnd);\n    Wire.endTransmission();\n}\n// Fades to a random HSB color\n\nstatic void BlinkM_fadeToRandomHSB(byte addr, byte hrnd, byte srnd, byte brnd)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('H');\n    Wire.send(hrnd);\n    Wire.send(srnd);\n    Wire.send(brnd);\n    Wire.endTransmission();\n}\n\nstatic void BlinkM_getRGBColor(byte addr, byte* r, byte* g, byte* b)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('g');\n    Wire.endTransmission();\n    Wire.requestFrom(addr, (byte)3);\n    if( Wire.available() ) {\n        *r = Wire.receive();\n        *g = Wire.receive();\n        *b = Wire.receive();\n    }\n}\n\nstatic void BlinkM_playScript(byte addr, byte script_id, byte reps, byte pos)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('p');\n    Wire.send(script_id);\n    Wire.send(reps);\n    Wire.send(pos);\n    Wire.endTransmission();\n}\n\nstatic void BlinkM_stopScript(byte addr)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('o');\n    Wire.endTransmission();\n}\n\nstatic void BlinkM_setScriptLengthReps(byte addr, byte script_id, \n                                       byte len, byte reps)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('L');\n    Wire.send(script_id);\n    Wire.send(len);\n    Wire.send(reps);\n    Wire.endTransmission();\n}\n\nstatic void BlinkM_writeScriptLine(byte addr, byte script_id, \n                                   byte pos, byte dur,\n                                   byte cmd, byte arg1, byte arg2, byte arg3)\n{\n#ifdef BLINKM_FUNCS_DEBUG\n    Serial.print(\"writing line:\");  Serial.print(pos,DEC);\n    Serial.print(\" with cmd:\"); Serial.print(cmd); \n    Serial.print(\" arg1:\"); Serial.println(arg1,HEX);\n#endif\n    Wire.beginTransmission(addr);\n    Wire.send('W');\n    Wire.send(script_id);\n    Wire.send(pos);\n    Wire.send(dur);\n    Wire.send(cmd);\n    Wire.send(arg1);\n    Wire.send(arg2);\n    Wire.send(arg3);\n    Wire.endTransmission();\n}\n\nstatic void BlinkM_writeScript(byte addr, byte script_id, \n                               byte len, byte reps,\n                               blinkm_script_line* lines)\n{\n#ifdef BLINKM_FUNCS_DEBUG\n    Serial.print(\"writing script to addr:\"); Serial.print(addr,DEC);\n    Serial.print(\", script_id:\"); Serial.println(script_id,DEC);\n#endif\n    for(byte i=0; i < len; i++) {\n        blinkm_script_line l = lines[i];\n        BlinkM_writeScriptLine( addr, script_id, i, l.dur,\n                                l.cmd[0], l.cmd[1], l.cmd[2], l.cmd[3]);\n    }\n    BlinkM_setScriptLengthReps(addr, script_id, len, reps);\n}\n\n\nstatic void BlinkM_setStartupParams(byte addr, byte mode, byte script_id,\n                                    byte reps, byte fadespeed, byte timeadj)\n{\n    Wire.beginTransmission(addr);\n    Wire.send('B');\n    Wire.send(mode);\n    Wire.send(script_id);\n    Wire.send(reps);\n    Wire.send(fadespeed);\n    Wire.send(timeadj);\n    Wire.endTransmission();\n} \n\n\nend"
  },
  {
    "path": "lib/plugins/debounce.rb",
    "content": "class Debounce < ArduinoPlugin\n  \n\n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n  # hack from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209050315\n\n  # plugin_directives \"#undef int\", \"#include <stdio.h>\", \"char _str[32];\", \"#define writeln(...) sprintf(_str, __VA_ARGS__); Serial.println(_str)\"\n  # add to directives\n  #plugin_directives \"#define EXAMPLE 10\"\n\n  # add to external variables\n  # ok, we need to deal with \n  # what about variables \n  # need to loose the colon...\n  # external_variables \"char status_message[40] = \\\"very cool\\\"\", \"char* msg[40]\"\n\n  # add the following to the setup method\n  # add_to_setup \"foo = 1\";, \"bar = 1;\" \"sub_setup();\"\n  \n  # one or more methods may be added and prototypes are generated automatically with rake make:upload\n  \n# call pulse(us) to pulse a servo \n\n#####################\n\n## How this works\n\n##  The cast:\n##   a normally open push button (circuit is closed when button is depressed)\n##    variables [input].\n##    [input]read: or current read -- what we see from the input pin HIGH (1) untouched or LOW (1) depressed\n##    [input]prev: or previous read – assigned to current reading at the end of the method\n##    [input]state: the stored state HIGH (1) or LOW (0)\n##    [input]time: the time when we last had a true\n##    millis: number of milliseconds since the Arduino began running the current program\n\n## So….\n\n##    If HIGH and the [input]read was LOW (button was depressed since the last time we looped) AND If millis() - [input]time  > 200\n##    Flip the state\n##    And assign [input]time millis()\n##    Else Set the pin to [input]state \n##    Assign [input]prev to [input]read\n\n## abstract summary:\n\n##    So 99%+ of the time, we always see a HIGH (unless the button is pushed)\n##    If the button is pushed, we record this LOW to [input]prev, so the next time we enter the loop and the button is not being pushed we see true as long as millis() minus the [input]time of the last toggle is greater the 200 (adjust, which can be set with an adjust option)\n\n\n######################\n\n\nadd_debounce_struct\n\n# increase the debounce_setting, increase if the output flickers \n# need docs..\n# and testing\n#\n# remember these are being called from the loop (typically)\n# \n# NOTE: if two buttons are controlling one output, today, strange\n#       things will happen since each button tries to assert its own state\n#       suggestion: we can fix this with an array of structs for shared outputs\n#       ie: output_pin 5, :as => :yellow_led, :shared => :yes # default no\n#       this would put the state at the output which could be compared to \n#       the inputs_state and override and set it if different\n\n\n\nint toggle(int output)\n{\n  return toggle_output(output);\n}\n\nint toggle_output(int output)\n{\n  if (dbce[output].state == HIGH)\n    dbce[output].state = LOW;\n  else\n    dbce[output].state = HIGH;\n    digitalWrite(output, dbce[output].state);\n\n    return dbce[output].state;\n}\n\n\nint read_input(int input)\n{\n  int state = LOW;\n  dbce[input].read = digitalRead(input);\n\n  if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust)\n     {\n      dbce[input].time = millis();\n      state = HIGH;\n    }\n  else \n    state = LOW;\n    \n      dbce[input].prev = dbce[input].read;\n      return state;\n}\n\n\nint toggle(int input, int output)\n{\n  return read_and_toggle(input, output);\n}\n\nint read_and_toggle(int input, int output)\n{\n  dbce[input].read = digitalRead(input);\n  // did we just release a button which was depressed the last time we checked and over 200 millseconds has passed since this statement was last true?\n  if (dbce[input].read == HIGH && dbce[input].prev == LOW && millis() - dbce[input].time > dbce[input].adjust) {\n    // ... flip the output\n    if (dbce[input].state == HIGH)\n      dbce[input].state = LOW;\n    else\n      dbce[input].state = HIGH;\n\n    /* save time of last press */\n    dbce[input].time = millis();    \n  }\n\n  digitalWrite(output, dbce[input].state);\n\n  dbce[input].prev = dbce[input].read;\n  \n  return dbce[input].state; \n}\n\n    \nend"
  },
  {
    "path": "lib/plugins/debug_output_to_lcd.rb",
    "content": "class DebugOutputToLcd < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n# add to directives\n#plugin_directives \"#define ARY_SIZE 10\"\n  \n# add to external variables\n#external_variables \"unsigned long start_loop_time = 0;\", \"unsigned long total_loop_time = 0;\"\n\n# add the following to the setup method\n#add_to_setup \"scan = &sm_ary[0];\", \"cur = &sm_ary[0];\", \"start = &sm_ary[0];\", \"end = &sm_ary[ARY_SIZE-1];\"\n\n# add an element to the array and return the average\n\n# need a nice home for these\n\n\n\n\n\nvoid send_servo_debug_to_lcd(int servo)\n{\n  lcd_first_line();\n  Serial.print(\"pw \");\n  Serial.print( find_servo_pulse_width(servo));\n  Serial.print(\" lp \");\n  Serial.print( find_servo_last_pulse(servo));\n  Serial.print(\"s\");\n  Serial.print( find_servo_start_pulse(servo));\n//  Serial.print(\" t\");\n//  Serial.print( find_debounce_time(servo));\n\n  lcd_second_line();\n  Serial.print(\"d\");\n//  Serial.print( millis() - find_debounce_time(servo));\n  Serial.print(\" m\");\n  Serial.print(millis());\n  \n}\n\n\nvoid send_button_debug_to_lcd(int button)\n{\n  \n  lcd_first_line();\n  Serial.print(\"r\");\n  Serial.print( find_debounce_read(button));\n  Serial.print(\"p\");\n  Serial.print( find_debounce_prev(button));\n  Serial.print(\"s\");\n  Serial.print( find_debounce_state(button));\n  Serial.print(\" t\");\n  Serial.print( find_debounce_time(button));\n\n  lcd_second_line();\n  Serial.print(\"d\");\n  Serial.print( millis() - find_debounce_time(button));\n  Serial.print(\" m\");\n  Serial.print(millis());\n  \n}\n\n\n\n\nend"
  },
  {
    "path": "lib/plugins/hysteresis.rb",
    "content": "class Hysteresis < ArduinoPlugin\n  \n# jdbarnhart\n# 20080728\n#\n#\n# purpose\n#\n# add hysteresis to analog readings, typically sensors or potentiometers\n#\n# use\n# two steps\n#\n#  one\n#    declare :device => :sensor \n#    example:\n#      input_pin 1, :as => :sensor_one, :device => :sensor\n#\n#  two\n#    instead of:\n#      my_lcd.print analogRead sensor_two\n#      use add_hyst\n#      my_lcd.print sensor_one.with_hyst 4\n#      \n#      # note, 4 is the amount of hysteresis\n#\n#\nvoid with_hysteresis(int pin, int amt)\n{\n  with_hyst(pin, amt);\n}\n\nint with_hyst(int pin, int amt)\n{\n  int read;\n  unsigned int i;\n  read = analogRead(pin);\n  for (i = 0; i < (int) (sizeof(hyst) / sizeof(hyst[0])); i++) {   \n    if (pin == hyst[i].pin) {\n      if (((read - hyst[i].state) > amt ) || ((hyst[i].state - read) > amt )) {\n        hyst[i].state = read;\n        return hyst[i].state;\n      } \n      else\n        return hyst[i].state;      \n    }\n  }\n}\n\n\n\nend"
  },
  {
    "path": "lib/plugins/input_output_state.rb",
    "content": "class InputOutputState < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n# add to directives\n#plugin_directives \"#define ARY_SIZE 10\"\n  \n# add to external variables\n#external_variables \"int *cur, *scan, *start, *end;\", \"int sm_ary[ARY_SIZE];\"\n\n# add the following to the setup method\n#add_to_setup \"scan = &sm_ary[0];\", \"cur = &sm_ary[0];\", \"start = &sm_ary[0];\", \"end = &sm_ary[ARY_SIZE-1];\"\n\n# return states of button and servo output stored in \n# array structs dbcd (debounce) and serv (servo)\n# need error catch ...\n# how about auto generating documentation from plugins\n# at least showing \n\n\n\nint find_debounce_state(int input)\n{\nreturn dbce[input].state;\n}\n\nint find_debounce_read(int input)\n{\nreturn dbce[input].read;\n}\n\nint find_debounce_prev(int input)\n{\nreturn dbce[input].prev;\n}\n\nunsigned long find_debounce_time(int input)\n{\nreturn dbce[input].time;\n}\n\nint find_debounce_adjust(int input)\n{\nreturn dbce[input].adjust;\n}\n\nlong unsigned find_servo_pulse_width(int input)\n{\nreturn serv[input].pulseWidth;\n}\n\nunsigned long find_servo_last_pulse(int input)\n{\nreturn serv[input].lastPulse;\n}\n\nunsigned long find_servo_start_pulse(int input)\n{\nreturn serv[input].startPulse;\n\n}\n\nunsigned long find_servo_refresh_time(int input)\n{\nreturn serv[input].refreshTime;\n}\n\nint find_servo_min(int input)\n{\nreturn serv[input].min;\n}\n\nint find_servo_max(int input)\n{\nreturn serv[input].max;\n\n}\n\n\nend"
  },
  {
    "path": "lib/plugins/lcd_padding.rb",
    "content": "class LCDPadding < ArduinoPlugin\n  \n# jdbarnhart\n# 20080729\n#\n#\n# purpose\n\n# simple integer padding for lcd display pad\n#\n# example\n# my_lcd.print pad_int_to_str 29, 5\n# \n# result\n# \"   29\"\n  \n\n\nstatic char* pad_int_to_str(int num, int length) \n{\n    int i = 0;\n    int start;\n    char plain[20];\n    char space[5] = \"  \";\n    char* pretty = \"        \";    \n    itoa(num, plain ,10);\n    start = length - strlen(plain);\n    while (i <= length) {\n      if (i >= start)\n        pretty[i] = plain[i - start];       \n      else\n        pretty[i] = space[0];\n      i++;\n    }\n    return pretty;\n}\n\nstatic char* pad_int_to_str_w_zeros(int num, int length) \n{\n    int i = 0;\n    int start;\n    char plain[20];\n    char space[5] = \"0 \";    \n    char* pretty = \"        \";    \n    itoa(num, plain ,10);\n    start = length - strlen(plain);\n    while (i <= length) {\n      if (i >= start)\n        pretty[i] = plain[i - start];       \n      else\n        pretty[i] = space[0];\n      i++;\n    }\n    return pretty;\n}\n\n\nend"
  },
  {
    "path": "lib/plugins/mem_test.rb",
    "content": "class MemTest < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n  # add to directives\n  #plugin_directives \"#define EXAMPLE 10\"\n\n  # add to external variables\n  # external_variables \"int foo, bar\"\n\n  # add the following to the setup method\n  # add_to_setup \"foo = 1\";, \"bar = 1;\" \"sub_setup();\"\n  \n  # one or more methods may be added and prototypes are generated automatically with rake make:upload\n  \n  # test the memory on your arduino uncommenting the following:\n  # add_to_setup \"memoryTest();\"\n  # or adding \"memoryTest()\" (no semicolon) to your main sketch\n\nint memoryTest() {\n  int byteCounter = 0; // initialize a counter\n  byte *byteArray; // create a pointer to a byte array\n  while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {\n   byteCounter++; // if allocation was successful, then up the count for the next try\n    free(byteArray); // free memory after allocating it\n }\n\n free(byteArray); // also free memory after the function finishes\"\n return byteCounter; // send back the highest number of bytes successfully allocated\n}\n\n\nend"
  },
  {
    "path": "lib/plugins/midi.rb",
    "content": "class Midi < ArduinoPlugin\n \n \n# reference \n  \n# To send MIDI, attach a MIDI out jack (female DIN-5) to Arduino.\n# DIN-5 pinout is:                               _____ \n#    pin 2 - Gnd                                /     \\\n#    pin 4 - 220 ohm resistor to +5V           | 3   1 |  Female MIDI jack \n#    pin 5 - Arduino D1 (TX)                   |  5 4  |\n#    all other pins - unconnected               \\__2__/\n#  Adapted from Tom Igoe's work at:\n#   http://itp.nyu.edu/physcomp/Labs/MIDIOutput\n#  And Tod E. Kurt <tod@todbot.com\n#   http://todbot.com/\n#\n#  Created 25 October 2008\n#  copyleft 2008 jdbarnhart \n#  http://jdbarnhart.com/\n  \nvoid note_on(char cmd, int data1, char data2) {\n  Serial.print(cmd, BYTE);\n  Serial.print(data1, BYTE);\n  Serial.print(data2, BYTE);\n}\n  \nvoid note_on(int channel, int note, int velocity) {\n  midi_msg( (0x90 | (channel)), note, velocity);\n}\n\nvoid note_on(long int& channel, long int& note, long int& velocity) {\n  midi_msg( (0x90 | (channel)), note, velocity);\n}\n\nvoid note_off(long int& channel, long int& note, long int& velocity) {\n  midi_msg( (0x90 | (channel)), note, velocity);\n}\n\nvoid note_off(byte channel, byte note, byte velocity) {\n  midi_msg( (0x90 | (channel)), note, velocity);\n}\n\nvoid play_note(long int& channel, long int& note, long int& velocity) {\n  midi_msg( (0x90 | (channel)), note, velocity);\n  delay(100);\n  midi_msg( (0x90 | (channel)), note, 0);\n}\n\n\n\nvoid midi_msg(byte cmd, byte data1, byte data2) {\n  digitalWrite(led(), 1); // indicate we're sending MIDI data\n  Serial.print(cmd, BYTE);\n  Serial.print(data1, BYTE);\n  Serial.print(data2, BYTE);\n  digitalWrite(led(), 0); // indicate we're sending MIDI data\n}\n\n\nend"
  },
  {
    "path": "lib/plugins/parallax_ping.rb",
    "content": "class ParallaxPing < ArduinoPlugin\n\n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n  # add to directives\n  # plugin_directives \"#define EXAMPLE 10\"\n\n  # add to external variables\n  # external_variables \"int foo, bar\"\n\n  # add the following to the setup method\n  # add_to_setup \"foo = 1\";, \"bar = 1;\" \"sub_setup();\"\n  \n  # one or more methods may be added and prototypes are\n  \n  # Methods for the Parallax Ping)) UltraSonic Distance Sensor.\n  # \n  # Example:\n  #\n  # class RangeFinder < ArduinoSketch\n  #   serial_begin\n  #   \n  #   external_vars :sig_pin => 'int, 7'\n  #   \n  #   def loop\n  #     serial_println(ping(sig_pin)) \n  #     delay(200) \n  #   end\n  # end\n\n  # Triggers a pulse and returns the delay in microseconds for the echo.\n  int ping(int pin) {\n    pinMode(pin, OUTPUT);\n\n    digitalWrite(pin, LOW);\n    delayMicroseconds(2);\n    digitalWrite(pin, HIGH);\n    delayMicroseconds(5);\n    digitalWrite(pin, LOW);\n\n    pinMode(pin, INPUT);\n\n    return pulseIn(pin, HIGH);\n  }\n\nend"
  },
  {
    "path": "lib/plugins/servo_pulse.rb",
    "content": "class ServoPulse < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n  # add to directives\n  #plugin_directives \"#define EXAMPLE 10\"\n\n  # add to external variables\n  # external_variables \"int foo, bar\"\n\n  # add the following to the setup method\n  # add_to_setup \"foo = 1\";, \"bar = 1;\" \"sub_setup();\"\n  \n  # one or more methods may be added and prototypes are generated automatically with rake make:upload\n  \n# call pulse(us) to pulse a servo  \n# this can be eliminate since we have an identical pulse_servo in servo_setup\n\nvoid pulse(int pin, int us) {\n  digitalWrite( pin, HIGH );\n  delayMicroseconds( us );\n  digitalWrite( pin, LOW );\n  serv[pin].pulseWidth = us;\n}\n    \n\nend"
  },
  {
    "path": "lib/plugins/servo_setup.rb",
    "content": "class ServoSetup < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n  # add to directives\n  #plugin_directives \"#define EXAMPLE 10\"\n\n  # add to external variables\n  # external_variables \"int foo, bar\"\n\n  # add the following to the setup method\n  # add_to_setup \"foo = 1\";, \"bar = 1;\" \"sub_setup();\"\n  \n  # one or more methods may be added and prototypes are generated automatically with rake make:upload\n  \n  \n  # one line servo control \n  #\n  # move_servo my_servo, amount\n  #\n  # example:\n  # \n  #   class MoveServo < ArduinoSketch\n  #\n  #     external_vars :sensor_position => \"int, 0\", :servo_amount => \"int, 0\"\n  #\n  #     output_pin 4, :as => :my_servo, :min => 700, :max => 2200\n  #     input_pin 1, :as => :sensor\n  #     def loop\n  #       sensor_position = analogRead(sensor)\n  #       servo_amount = (sensor_position*2 + 500)\n  #       move_servo my_servo, servo_amount\n  #     end\n  #   end\n  #\n  #\n  #  supports multiple servos by storing variables in the serv struc array that is constructed when\n  #  the :min and :max options are added to the output_pin method\n  \n\nadd_servo_struct\n\nvoid move_servo(int servo_num, int pulse_width)\n{\n  struct servo servo_name = serv[servo_num];\n\n  int pw = pulse_width;\n  /* apply the servo limits */\n  if (pw > servo_name.max)\n    pw = servo_name.max;\n  if (pw < servo_name.min)\n    pw = servo_name.min;\n\n  if (millis() - servo_name.lastPulse >= servo_name.refreshTime)\n    {\n      pulse_servo(servo_name.pin, pw);\n      servo_name.lastPulse = millis();\n      // if (find_total_loop_time() < 10)\n      // for debug:\n      // digitalWrite( 5, HIGH );\n      // 18 seems optimal, but we should let the users adjust with a servo option\n      delay(18);\n    }\n\n}\n\nvoid pulse_servo(int pin, int us) {\n  digitalWrite( pin, HIGH );\n  // pulseWidth\n  delayMicroseconds( us );\n  digitalWrite( pin, LOW );\n  serv[pin].pulseWidth = us;\n}\n\n\n\n\n\n\n    \n\nend"
  },
  {
    "path": "lib/plugins/smoother.rb",
    "content": "class Smoother < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n\n  # add to directives\n  plugin_directives \"#define ARY_SIZE 10\"\n\n  # add to external variables\n  external_variables \"int *cur, *scan, *start, *end;\", \"int sm_ary[ARY_SIZE];\", \"int last_reading = 0;\"\n\n  # add the following to the setup method\n  add_to_setup \"scan = &sm_ary[0];\", \"cur = &sm_ary[0];\", \"start = &sm_ary[0];\", \"end = &sm_ary[ARY_SIZE-1];\"\n\n  # add an element to the array and return the average\n\nint add_hysteresis(int reading, int hysteresis)\n{\n  if ( ((reading - last_reading) > hysteresis) || ((last_reading - reading) > hysteresis)) {\n\n          last_reading = reading;\n          return reading;\n       }\n     else\n       return last_reading;\n}\n\nint smooth_average(int reading)\n{\n  int sum, cnt;\n  cnt = 0;\n  sum = 0;\n  *cur = reading;\n  cur++;\n  for (scan = &sm_ary[0]; scan < &sm_ary[ARY_SIZE-1]; cnt++, scan++)\n    sum += *scan;\n  ptr_reset();\n  return sum/cnt;\n}\n\nvoid ptr_reset(void)\n{\n  if (cur == end)\n  {\n    cur = &sm_ary[0];\n  }\n}\n\n\n\nend"
  },
  {
    "path": "lib/plugins/spark_fun_serial_lcd.rb",
    "content": "class SparkFunSerialLcd < ArduinoPlugin\n  \n  # RAD plugins are c methods, directives, external variables and assignments and calls \n  # that may be added to the main setup method\n  # function prototypes not needed since we generate them automatically\n  \n  # directives, external variables and setup assignments and calls can be added rails style (not c style)\n  # hack from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209050315\n\n  plugin_directives \"#undef int\", \"#include <stdio.h>\", \"char _str[32];\", \"#define writeln(...) sprintf(_str, __VA_ARGS__); Serial.println(_str)\"\n  # add to directives\n  #plugin_directives \"#define EXAMPLE 10\"\n\n  # add to external variables\n  external_variables \"char status_message[40] = \\\"very cool\\\"\", \"char* msg[40]\"\n\n  # add the following to the setup method\n  # add_to_setup \"foo = 1\";, \"bar = 1;\" \"sub_setup();\"\n  \n  # one or more methods may be added and prototypes are generated automatically with rake make:upload\n  \n# methods for sparkfun serial lcd SerLCD v2.5\n\nvoid print_sensor_position_plus(int reading){\n\n\n/*  writeln(\"sensor: %d \", reading); */\n  Serial.print(\"sensor: \");\n  Serial.print(reading);\n\n  \n}\n\nvoid print_sensor_position(long pos){\n  Serial.print(pos);\n}\n\nvoid lcd_first_line(){  //puts the cursor at line 0 char 0.\n   Serial.print(0xFE, BYTE);   //command flag\n   Serial.print(128, BYTE);    //position\n}\n\nvoid lcd_second_line(){  //puts the cursor at line 0 char 0.\n   Serial.print(0xFE, BYTE);   //command flag\n   Serial.print(192, BYTE);    //position\n}\n\nvoid selectLineOne(){  //puts the cursor at line 0 char 0.\n   Serial.print(0xFE, BYTE);   //command flag\n   Serial.print(128, BYTE);    //position\n}\nvoid selectLineTwo(){  //puts the cursor at line 0 char 0.\n   Serial.print(0xFE, BYTE);   //command flag\n   Serial.print(192, BYTE);    //position\n}\nvoid clearLCD(){\n   Serial.print(0xFE, BYTE);   //command flag\n   Serial.print(0x01, BYTE);   //clear command.\n}\nvoid backlightOn(){  //turns on the backlight\n    Serial.print(0x7C, BYTE);   //command flag for backlight stuff\n    Serial.print(157, BYTE);    //light level.\n}\n\nvoid set_backlight_level(int level){  //turns on the backlight\n  if (level > 29)\n    level = 29;\n    Serial.print(0x7C, BYTE);   //command flag for backlight stuff\n    Serial.print(157 + level, BYTE);    //light level.\n}\n\nvoid toggle_backlight(){  //turns off the backlight\n    Serial.print(0x7C, BYTE);   //command flag for backlight stuff\n    Serial.print(\"|\");     //light level for off.\n    Serial.print(1);\n}\n\nvoid set_splash(){\n  selectLineOne();\n  Serial.print(\" Ruby + Auduino\");\n  selectLineTwo();\n  Serial.print(\" RAD 0.2.4+     \");\n  Serial.print(0x7C, BYTE);   // decimal 124, command flag for backlight stuff\n  Serial.print(10, BYTE);\n}\n\nvoid backlightOff(){  //turns off the backlight\n    Serial.print(0x7C, BYTE);   // decimal 124, command flag for backlight stuff\n    Serial.print(128, BYTE);     //light level for off.\n}\nvoid serCommand(){   // decimal 254, a general function to call the command flag for issuing all other commands   \n  Serial.print(0xFE, BYTE);\n}\n\n\n\n\n    \n\nend"
  },
  {
    "path": "lib/plugins/spectra_symbol.rb",
    "content": "class SpectraSymbol < ArduinoPlugin\n  \n# jdbarnhart\n# 20080729\n#\n# crazy experiment in progress\n# purpose\n#\n# retain last reading after finger is removed from spectrasymbol\n# soft pot\n#\n# use\n# two steps\n#\n#  one\n#    declare :device => :sensor \n#    example:\n#      input_pin 1, :as => :sensor_one, :device => :spectra\n#\n#  two\n#    instead of:\n#      my_lcd.print analogRead sensor_two\n#      use soft_lock\n#      my_lcd.print sensor_one.spectra_lock\n#      \n#\n# notes:\n# experimental settings for 100mm spectrasymbol\n# \n# hysteresis is set at 5 \n# amount of sensor drop is set to 3\n# delay time (dtime) is 4\n# cutoff set to 10\n#\nint soft_lock(int pin)\n\n{\n  int hyst = 5;\n  int drop = 3;\n  int dtime = 4;\n  int cutoff = 10;\n  int read;\n  int r1;\n  int r2;\n  int r3;\n  unsigned int i;\n  read = analogRead(pin)/4;\n  delay(dtime);\n  r1 = analogRead(pin)/4;\n  delay(dtime);\n  r2 = analogRead(pin)/4;\n  delay(dtime);\n  r3 = analogRead(pin)/4;\n  delay(dtime);\n  for (i = 0; i < (int) (sizeof(spec) / sizeof(spec[0])); i++) {   \n    if (pin == spec[i].pin) {\n      if (((r3 - r2) > drop) && ((r2 - r1) > drop) && ((r1 - read) > drop)) \n        return spec[i].state - 10;\n      else\n      {\n      if (read < cutoff) \n        return spec[i].state - 10;\n      else\n      {\n          if (((read - spec[i].state) > hyst ) || ((spec[i].state - read) > hyst )) {\n            spec[i].state = read;\n            return spec[i].state - 10;\n          } \n          else\n            return spec[i].state - 10;   \n        } \n      }   \n    } \n  } \n}\n\n\n\nend"
  },
  {
    "path": "lib/plugins/twitter_connect.rb",
    "content": "class TwitterConnect < ArduinoPlugin\n\n\n\n\nvoid get_tweet() {\n  // hack to pull \n}\n\nuint32_t parsenumber(char *str) {\n  uint32_t num = 0;\n  char c;\n  \n  // grabs a number out of a string\n  while (c = str[0]) {\n   if ((c < '0') || (c > '9'))\n     return num;\n   num *= 10;\n   num += c - '0';\n   str++;\n }\n return num;\n}\n\n\nchar * fetchtweet(void) {\n  Serial.print(\"... fetching tweets....\");\n  uint8_t ret;\n  char *found=0, *start=0, *end=0;\n  \n  tweet[0] = 0;  // reset the tweet\n  ret = xport.reset();\n  //Serial.print(\"Ret: \"); Serial.print(ret, HEX);\n  switch (ret) {\n   case  ERROR_TIMEDOUT: { \n      Serial.println(\"Timed out on reset!\"); \n      return 0;\n   }\n   case ERROR_BADRESP:  { \n      Serial.println(\"Bad response on reset!\");\n      return 0;\n   }\n   case ERROR_NONE: { \n    Serial.println(\"Reset OK!\");\n    break;\n   }\n   default:\n     Serial.println(\"Unknown error\"); \n     return 0;\n  }\n  \n  // time to connect...\n \n  ret = xport.connect(IPADDR, PORT);\n    switch (ret) {\n   case  ERROR_TIMEDOUT: { \n      Serial.println(\"Timed out on connect\"); \n      return 0;\n   }\n   case ERROR_BADRESP:  { \n      Serial.println(\"Failed to connect\");\n      return 0;\n   }\n   case ERROR_NONE: { \n     Serial.println(\"Connected...\"); break;\n   }\n   default:\n     Serial.println(\"Unknown error\"); \n     return 0;\n  }\n  \n  // send the HTTP command, ie \"GET /username/\"\n  \n    xport.print(\"GET \"); xport.println(HTTPPATH);\n// the following works with instiki, but not on twitter...\n//  xport.print(\"GET \"); \n//  xport.print(HTTPPATH);\n//  xport.println(\" HTTP/1.1\");\n//  xport.print(\"Host: \"); xport.println(HOSTNAME);\n//  xport.println(\"\");\n    \n  \n\n  while (1) {\n    // read one line from the xport at a time\n    ret = xport.readline_timeout(linebuffer, 255, 4000); // 3s timeout\n    // if we're using flow control, we can actually dump the line at the same time!\n    // Serial.print(linebuffer);\n    \n    // look for an entry (the first one)\n    found = strstr(linebuffer, \"entry-title entry-content\");\n    if (((int)found) != 0) {\n      start = strstr(found, \">\") + 1;\n      end = strstr(found, \"</p>\");\n      if ((start != 0) && (end != 0)) {\n        Serial.println(\"\\n******Found first entry!*******\");\n        end[0] = 0;\n        Serial.print(start);\n        // save the tweet so we can display it later\n        strncpy(tweet, start, TWEETLEN);\n        tweet[TWEETLEN-1] = 0;\n      }\n    }\n    \n    // next we look for a status ID (which should correspond to the previous tweet)e\n    // Serial.print(\".\");\n    // Serial.print(linebuffer);\n    found = strstr(linebuffer, \"<div id=\\\"status_actions_\");  \n    if (((int)found) != 0) {\n      start =  found + 25; // strlen(\"<span id=\\\"status_actions_\")\n      end = strstr(found, \"\\\">\");\n      if ((start != 0) && (end != 0)) {\n        Serial.println(\"\\n******Found status ID!*******\");\n        end[0] = 0;\n        Serial.println(start);\n        // turn the string into a number\n        __currstatus = parsenumber(start);\n        Serial.println(__currstatus, DEC);\n        \n        // check if this is a nu tweet\n        if (__currstatus > __laststatus) {\n           __laststatus = __currstatus;\n           Serial.println(\"New message\");\n           Serial.print(tweet);\n        } else {\n          tweet[0] = 0;\n        }\n       // flush the conn\n       xport.flush(5000); // 5 second timeout\n \n       if (tweet[0] == 0) { return 0; }\n       else {return tweet; }\n      }\n    }\n    \n    if (((__errno == ERROR_TIMEDOUT) && xport.disconnected()) ||\n        ((XPORT_DTRPIN == 0) &&\n         (linebuffer[0] == 'D') && (linebuffer[1] == 0)))  {\n       Serial.println(\"\\nDisconnected...\");\n       return 0;\n    }\n  }\n}\n\nend\n"
  },
  {
    "path": "lib/rad/README.rdoc",
    "content": "=Welcome to RAD (Ruby Arduino Development) Quick Start Documentation\n\nArduinoSketch is the main access point for working with RAD. Sub-classes of ArduinoSketch have access to a wide array of convenient class methods (documented below) for doing the most common kinds of setup needed when programming the Arduino such as configuring input and output pins and establishing serial connections. Here is the canonical 'hello world' example of blinking a single LED in RAD:\n\ntest... to be continued if it works.."
  },
  {
    "path": "lib/rad/antiquated_todo.txt",
    "content": "-framework for translation to C (wrapper for RubyToAnsiC)\n-framework for translation testing (want to test that each Rad method translates to the expected C)\n\n-have to replace symbol & str definitions with \"char name[]\" ?\n\n-maybe can't build rad.c dynamically? can use as helpers in writing it statically rad.rb and RubyToAnsiC as helpers in writing it. . .\n-maybe there's a way to give RubyToC prototypes for the arduino library methods (or maybe include them directly) so that it will be able to figure out the signatures for my methods (otherwise it breaks because, for example, it can't figure out what read returns).\n-speaking of which: all rad methods need to have a statically typed return value or else they won't be translatable to C. For example, as it stands #read may return a bool (if it calls digitalRead) or an int (if it calls analogRead). This may force me to take away much of the syntactic sugar\n\n-how to handle setting up named pins:\n\ndeclare the name with an underscore:\n  int _led = 1;\nand define an accessor for it:\n  int led(){\n    _led;\n  }\nThen, calling the method will get you the int.\n\n-drop read and write custom methods (at least for now)? save time, save a whole step. Make it trivial to implement the whole library. . .\n\n======================================================================================================\n-the Arduino DSL is pretty good. Don't try to reinvent it for the board's api, add value on top of it!\n======================================================================================================\n\n-add constants HIGH, LOW, etc.\n\n-design directory structure\n-->where do we put the sketch files\n-->where do the .c files get compiled to?\n\n-design rad lib directory structure\n/sketch\n  my_sketch.rb\n/build\n  my_sketch.c\n  rad.c\n/rad\n  /lib\n  /specs\n  Rakefile\n\n\n-helper methods like blink\n\n-proof of concept of build process\n\n"
  },
  {
    "path": "lib/rad/arduino_plugin.rb",
    "content": "## RAD plugins -- the start\n\n## June 25, 2008\n## jd@jdbarnhart.com\n## \n\n\n# Disclaimer: This is only a first run at the notion of plugins and started off as just a way to keep from adding everything to ArduinoSketch.  \n# ArduinoPlugin is the RAD class for adding \"plugins\" which add functionality such as servo control, special lcd screen methods, debounce methods, etc.. Sub-classes of ArduinoPlugin (the plugins) add  class methods for doing thing beyond the most common kinds of setup needed when programming the Arduino.  Here is an example of controlling a servo:\n#\n#   class MoveServo < ArduinoSketch\n#\n#     external_vars :sensor_position => \"int, 0\", :servo_amount => \"int, 0\"\n#\n#     output_pin 4, :as => :my_servo, :min => 700, :max => 2200\n#     input_pin 1, :as => :sensor\n#     def loop\n#       sensor_position = analogRead(sensor)\n#       servo_amount = (sensor_position*2 + 500)\n#       move_servo my_servo, servo_amount\n#     end\n#   end\n#\n# \n# Here's one for latching an led\n\n#   output_pin 5, :as => :red_led\n#   input_pin 8, :as => :red_button, :latch => :off, # optional adjustment to amount of time for debounce (default 200) :adjust => 250\n#                                                    # latch sets the led as on or off initially and sets up a array of structs to keep timing and state\n#\n#     def loop\n#       debounce_toggle(red_button, red_led)\n#     end\n#   end\n#\n# Since this is a first pass, there is work to do here, such as \n#   checking if plugin methods are needed and only loading those that are, \n#   more compreshensive plugin organization (more railsish with tests, etc)\n#   a scheme to encourage plugin authors and provide an easy way to avoid method and variable namespace collisions\n#   a scheme to flag when a prerequisite plugin is required\n# on with the show:\n\n\n\nclass ArduinoPlugin\n  \ndef initialize #:nodoc:\n  \n  $plugin_directives = $plugin_directives || []\n  $plugin_external_variables = $plugin_external_variables || []\n  # moved to check_for_plugin_use $plugin_structs = $plugin_structs || {}\n  $plugin_signatures = $plugin_signatures || []\n  $plugin_methods = $plugin_methods || []\n # $plugin_methods_hash = $plugin_methods_hash || {}  ### new\n # $plugins_to_load = $plugins_to_load || []  ### new\n  $add_to_setup = $add_to_setup || []\n  $load_libraries = $load_libraries || []\n\n\nend\n  \n# c declarations are automatic\n# you won't need them in the plugins\n# so, the first thing we can do is gather all the plugin methods, and scan the \n# sketch available plugins...\n# if the sketch has them, we include the plugins in the build...\n# otherwise not..\n\n  def include_wire\n    $load_libraries << \"Wire\" unless $load_libraries.include?(\"Wire\")\n  end\n\n\n  def add_to_setup(*args)\n    if args\n       args.each do |arg|\n         $add_to_setup << arg\n       end\n     end\n  end\n\n\n  def plugin_directives(*args)\n    if args\n       args.each do |arg|\n         $plugin_directives << arg\n       end\n     end\n  end\n\n\n  def external_variables(*args)\n    if args\n       args.each do |arg|\n         puts self.class\n         puts \"\\tadding plugin external variables: #{arg}\"\n         # colons aptional\n         colon  = arg[arg.length - 1, 1] == \";\"  ? '' : ';' \n         $plugin_external_variables << \"#{arg}#{colon}\"\n       end\n     end\n  end\n  \n  def add_blink_m_struct\n    $plugin_structs[:blink_m] = <<-STR\n    typedef struct _blinkm_script_line {\n        uint8_t dur;\n        uint8_t cmd[4];    // cmd,arg1,arg2,arg3\n    } blinkm_script_line;\n    STR\n  end\n  \n  def self.add_blink_m_struct\n    $plugin_structs[:blink_m] = <<-STR\n    typedef struct _blinkm_script_line {\n        uint8_t dur;\n        uint8_t cmd[4];    // cmd,arg1,arg2,arg3\n    } blinkm_script_line;\n    STR\n  end\n  \n  def add_debounce_struct\n    $plugin_structs[:debounce] = <<-STR\n    struct debounce {\n      int state;\n      int read;\n      int prev;\n      unsigned long time;\n      unsigned long adjust;\n    };\n    STR\n  end\n  \n  \n  def add_servo_struct \n    $plugin_structs[:servo] = <<-STR\n    struct servo {\n      int pin;\n      long unsigned pulseWidth;\n      long unsigned lastPulse;\n      long unsigned startPulse;\n      long unsigned refreshTime;\n      int min;\n      int max;\n    };\n    STR\n  end\n  \n  def self.add_debounce_struct\n    $plugin_structs[:debounce] = <<-STR\n    struct debounce {\n      int state;\n      int read;\n      int prev;\n      unsigned long time;\n      unsigned long adjust;\n    };\n    STR\n  end\n  \n  \n  def self.add_servo_struct\n    $plugin_structs[:servo] = <<-STR\n    struct servo {\n      int pin;\n      long unsigned pulseWidth;\n      long unsigned lastPulse;\n      long unsigned startPulse;\n      long unsigned refreshTime;\n      int min;\n      int max;\n    };\n    STR\n  end\n  \n  def self.add_sensor_struct\n    $plugin_structs[:sensor] = <<-STR\n    struct hysteresis {\n      int pin;\n      int state;\n    };\n    STR\n  end\n  \n  def self.add_spectra_struct\n    $plugin_structs[:spectra] = <<-STR\n    struct spectra {\n      int pin;\n      int state;\n      int r1;\n      int r2;\n      int r3;\n    };\n    STR\n  end\n  \n\n  def self.check_for_plugin_use(sketch_string, plugin_string, file_name) # rename klass to filename\n    $plugin_structs = $plugin_structs || {}\n    $plugin_methods_hash = $plugin_methods_hash || {}  \n    $plugins_to_load = $plugins_to_load || []  \n    plugin_signatures = []\n    plugin_methods = []\n    ## need a test for this\n    ## fails on string interpolation, but since ruby_to_c also currently fails ...\n    sketch_string = sketch_string.gsub(/#(?!\\{.*\\}).*/, \"\")\n    plugin_signatures << plugin_string.scan(/^\\s*(((#{PLUGIN_C_VAR_TYPES})\\s*)+\\w*\\(.*\\))/)\n    # gather just the method name and then add to #plugin_methods_hash\n    plugin_signatures[0].map {|sig| \"#{sig[0]}\"}.each {|m| plugin_methods << m.gsub!(/^.*\\s(\\w*)\\(.*\\)/, '\\1')}\n    # we don't know the methods yet, so... \n    $plugin_methods_hash[file_name] = plugin_methods\n    $plugin_methods_hash.each do |k,meths|\n      meths.each do |meth|\n        if sketch_string.include?(meth)\n           # load this plugin... \n           $plugins_to_load << k unless $plugins_to_load.include?(k)\n         end\n      end\n    end\n\n  end\n\n\n  def self.process(plugin_string)\n    plugin_signatures = []\n    first_process = plugin_string \n    # todo: need to add plugin names to the methods, so we can add them as comments in the c code\n    # gather the c methods\n    $plugin_methods << first_process.scan(/^\\s*(((#{PLUGIN_C_VAR_TYPES}).*\\)).*(\\n.*)*^\\s*\\})/)\n    plugin_signatures << first_process.scan(/^\\s((#{PLUGIN_C_VAR_TYPES}).*\\(.*\\))/)\n    $plugin_signatures << plugin_signatures[0].map {|sig| \"#{sig[0]};\"}\n    ## strip out the methods and pass it back \n    result = plugin_string\n    # strip out the c methods so we have only ruby before eval\n    result.gsub(/^\\s*(#{PLUGIN_C_VAR_TYPES}).*(\\n.*)*^\\s*\\}/, \"\"  )\n    \n  end\n  \n  private\n  \n  def add_struct(struct)\n    \n    \n  end\n    \nend"
  },
  {
    "path": "lib/rad/arduino_sketch.rb",
    "content": "# ArduinoSketch is the main access point for working with RAD. Sub-classes of ArduinoSketch have access to a wide array of convenient class methods (documented below) for doing the most common kinds of setup needed when programming the Arduino such as configuring input and output pins and establishing serial connections. Here is the canonical 'hello world' example of blinking a single LED in RAD:\n#\n#   class HelloWorld < ArduinoSketch\n#     output_pin 13, :as => :led\n#     \n#     def loop\n#       blink 13, 500\n#     end\n#   end\n#\n# As you can see from this example, your ArduinoSketch sub-class can be dividied into two-parts: class methods for doing configuration and a loop method which will be run repeatedly at the Arduino's clock rate. Documentation for the various available class methods is below. The ArduinoSketch base class is designed to work with a series of rake tasks to automatically translate your loop method into C++ for compilation by the Arduino toolchain (see link://files/lib/rad/tasks/build_and_make_rake.html for details). See http://rad.rubyforge.org/examples for lots more examples of usage.\n#\n# ==Arduino built-in methods\n# Thanks to this translation process you can take advantage of the complete Arduino software API (full docs here: http://www.arduino.cc/en/Reference/HomePage). What follows is the core of a RAD-Arduino dictionary for translating between RAD methods and the Arduino functionality they invoke, N.B. many Arduino methods have been left out (including the libraries for Time, Math, and Random Numbers, as the translation between them and their RAD counterparts should be relatively straightforward after perusing the examples here). For further details on each method, visit their Arduino documenation.\n#\n# <b>Digital I/O</b>\n#\n# digital_write(pin, value)\n#\n#   Arduino method: digitalWrite(pin, value) \n#\n#   Description: \"Ouputs either HIGH or LOW at a specified pin.\"\n#   \n#   Documentation: http://www.arduino.cc/en/Reference/DigitalWrite\n#   \n# digital_read(pin)\n#\n#   Arduino method: digitalRead(pin) \n#\n#   Description: \"Reads the value from a specified pin, it will be either HIGH or LOW.\"\n#\n#   Documentation: http://www.arduino.cc/en/Reference/DigitalRead\n# \n# <b>Analog I/O</b>\n#\n# analog_read(pin) \n#\n#   Arduino method: analogRead(pin)\n#\n#   Description: \"Reads the value from the specified analog pin. The Arduino board contains a 6 channel \n#     (8 channels on the Mini), 10-bit analog to digital converter. This means that it will map input \n#     voltages between 0 and 5 volts into integer values between 0 and 1023. This yields a resolution\n#     between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit. It takes about 100\n#     us (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.\"\n#\n#   Documentation: http://www.arduino.cc/en/Reference/AnalogRead\n#\n# analog_write(pin, value)\n#\n#   Arduino method: analogWrite(pin, value)\n#\n#   Description: \"Writes an analog value (PWM wave) to a pin. On newer Arduino boards (including the Mini\n#     and BT) with the ATmega168 chip, this function works on pins 3, 5, 6, 9, 10, and 11. Older USB and \n#     serial Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11. Can be used \n#     to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite,\n#     the pin will generate a steady wave until the next call to analogWrite (or a call to digitalRead or \n#     digitalWrite on the same pin).\"\n#\n#   Documentation: http://www.arduino.cc/en/Reference/AnalogWrite\n#\n# <b>Serial Communication</b>\n#\n# serial_available()\n#\n#   Arduino method: Serial.available()\n#   \n#   Description: \"Get the number of bytes (characters) available for reading over the serial port. \n#     Returns the number of bytes available to read in the serial buffer, or 0 if none are \n#     available. If any data has come in, Serial.available() will be greater than 0. The serial buffer\n#     can hold up to 128 bytes.\"\n#\n#   Documentation: http://www.arduino.cc/en/Serial/Available\n#\n# serial_read()\n#\n#   Arduino method: Serial.read()\n#\n#   Description: \"Reads incoming serial data and returns the first byte of incoming serial data \n#     available (or -1 if no data is available)\"\n#\n#   Documentation: http://www.arduino.cc/en/Serial/Read\n#\n# serial_print(data)\n#\n#   Arduino method: Serial.print(data)\n#\n#   Description: \"Prints data to the serial port.\"\n#\n#   Documentation: http://www.arduino.cc/en/Serial/Print\n#\n# serial_println(data)\n#\n#   Arduino method: Serial.println(data)\n#\n#   Description: \"Prints a data to the serial port, followed by a carriage return character \n#     (ASCII 13, or '\\r') and a newline character (ASCII 10, or '\\n'). This command takes the \n#     same forms as Serial.print():\"\n#\n#   Documentation: http://www.arduino.cc/en/Serial/Println\n#\n# serial_flush()\n#\n#   Arduino method: Serial.flush()\n#\n#   Description: \"Flushes the buffer of incoming serial data. That is, any call to Serial.read() \n#     or Serial.available() will return only data received after the most recent call \n#     to Serial.flush().\"\n#\n#   Documentation: http://www.arduino.cc/en/Serial/Flush\n#\n#   June 25, 2008\n#   Added a new external variable method which keeps track \n#   external_vars :sensor_position => \"int, 0\", :feedback => \"int\", :pulseTime => \"unsigned long, 0\"\n# \n#   added ability to write additional methods besides loop in the sketch \n#   since there is quite a bit of work to do with the c translation, it is easy to write a method that\n#   won't compile or even translate into c, but for basics, it works.  \n#   Note: stay basic and mindful that c is picky about variables and must make a decision\n#   which will not always be what you want\n#   also: for now, don't leave empty methods (something like foo = 1 cures this)\n# \n#   Example:\n#\n#   class HelloMethods < ArduinoSketch\n#     output_pin 13, :as => :led\n#     \n#     def loop\n#       blink_it\n#     end\n\n#     def blink_it\n#       blink 13, 500\n#     end\n#\n#   end\n#\n#   \n#   added pin methods for servos and latching which generate an array of structs to contain setup and status\n#   input_pin 12, :as => :back_off_button, :latch => :off\n#   input_pin 8, :as => :red_button, :latch => :off # adjust is optional with default set to 200\n#\n#   added add_to_setup method that takes a string of c code and adds it to setup\n#   colons are options and will be added if not present  \n#   no translation from ruby for now\n#\n#   example:\n#   \n#   add_to_setup \"call_my_new_method();\", \"call_another();\"  \n#\n#   added some checking to c translation that (hopefully) makes it a bit more predictable\n#   most notably, we keep track of all external variables and let the translator know they exist \n#   \n#   \n\nclass ArduinoSketch\n  \n  include ExternalVariableProcessing\n  \n  # find another way to do this\n  @@twowire_inc\t  = FALSE\n  @@hwserial_inc  = FALSE\n\n  \n  def initialize #:nodoc:\n    @servo_settings = [] # need modular way to add this\n    @debounce_settings = [] # need modular way to add this\n    @hysteresis_settings = []\n    @spectra_settings = []\n    @servo_pins = [] \n    @debounce_pins = []\n    @hysteresis_pins = []\n    @spectra_pins = []\n    $external_array_vars = [] \n    $external_vars =[]\n    $external_var_identifiers = []\n    $sketch_methods = []\n    $load_libraries ||= []\n    $defines  ||= []\n    $define_types = {}\n    $array_types = {}\n    $array_index_helpers = ('a'..'zz').to_a\n\n    @declarations = []\n    @pin_modes = {:output => [], :input => []}\n    @pullups = []\n    @other_setup = [] # specifically, Serial.begin\n    @assembler_declarations = []\n    @accessors = []\n    @signatures = [\"int main();\"]\n \n    helper_methods = []\n    @helper_methods = helper_methods.join( \"\\n\" )\n\n  end\n  \n\n  \n  # array \"char buffer[32]\"\n  # result: char buffer[32];\n  # array \"char buffer[32]\"\n  # result: char buffer[32];\n  # todo \n  # need to feed array external array identifiers to rtc if they are in plugins or libraries, (not so sure about this will do more testing)\n  def array(arg)\n    if arg\n        arg = arg.chomp.rstrip.lstrip\n        arg.sub!(\"@\",\"__\")\n        name = arg.scan(/\\s*(\\w*)\\[\\d*\\]?/).first.first\n        # help rad_processor do a better job with array types\n        types = [\"int\", \"long\", \"char*\", \"unsigned int\", \"unsigned long\", \"byte\", \"bool\", \"float\" ]\n        types.each_with_index do |type, i|\n          @type = types[i] if /#{type}/ =~ arg\n        end\n        raise ArgumentError, \"type not currently supported.. got: #{arg}.  Currently supporting #{types.join(\", \")}\" unless @type\n\n        arg = \"#{arg};\" unless arg[-1,1] == \";\"\n        $array_types[name] = @type\n        @type = nil\n        $external_var_identifiers << name unless $external_var_identifiers.include?(name)\n        # add array_name declaration\n        $external_array_vars << arg unless $external_array_vars.include?(arg)\n    end\n  end\n  \n  # define \"DS1307_SEC 0\"\n  # result: #define DS1307_SEC 0\n  # note we send the constant identifiers and type to our rad_type_checker\n  # however, it only knows about long, float, str....\n  # so we don't send ints ...yet..\n  # need more testing\n  def define(arg)\n    if arg\n        arg = arg.chomp.rstrip.lstrip\n        name = arg.split(\" \").first\n        value = arg.gsub!(\"#{name} \",\"\")\n        # negative\n        if value =~ /^-(\\d|x)*$/ \n           type = \"long\"\n         # negative float\n         elsif value =~ /^-(\\d|\\.|x)*$/ \n           type = \"float\" \n         elsif value =~ /[a-zA-Z]/\n           type = \"str\"\n           value = \"\\\"#{value}\\\"\"\n         elsif value !~ /(\\.|x)/\n           type = \"long\"\n         elsif value =~ /(\\d*\\.\\d*)/ # and no \n           type = \"float\"\n         elsif value =~ /0x\\d\\d/\n           type = \"byte\"\n         else \n           raise ArgumentError, \"opps, could not determine the define type, got #{value}\"\n         end\n        $define_types[name] = type\n        arg = \"#define #{name} #{value}\"\n        $defines << arg\n        dummy_for_testing = arg, type\n    end\n  end\n  \n  # Configure a single pin for output and setup a method to refer to that pin, i.e.:\n  #\n  #   output_pin 7, :as => :led\n  #\n  # would configure pin 7 as an output and let you refer to it from the then on by calling\n  # the `led` method in your loop like so:\n  # \n  #   def loop\n  #     digital_write led, ON\n  #   end\n  #\n  def output_pin(num, opts={})\n    raise ArgumentError, \"can only define pin from Fixnum, got #{num.class}\" unless num.is_a?(Fixnum)\n    @pin_modes[:output] << num\n    if opts[:as]\n      if opts[:device]\n        case opts[:device]\n        when :servo\n          servo_setup(num, opts)\n          return # don't use declarations, accessor, signatures below\n        when :pa_lcd || :pa_LCD\n          pa_lcd_setup(num, opts)\n          return \n        when :sf_lcd || :sf_LCD\n          sf_lcd_setup(num, opts)\n          return         \n        when :freq_out || :freq_gen || :frequency_generator\n          frequency_timer(num, opts)\n          return\n        when :i2c\n          two_wire(num, opts) unless @@twowire_inc\n          return #\n        when :i2c_eeprom\n          two_wire(num, opts) unless @@twowire_inc\n          i2c_eeprom(num, opts)\n          return #\n        when :i2c_ds1307\n          two_wire(num, opts) unless @@twowire_inc\n          ds1307(num, opts) \n          return #\n        when :i2c_blinkm\n          two_wire(num, opts) unless @@twowire_inc\n          blinkm\n          return #\n        when :onewire\n          one_wire(num, opts)\n          return #\n        when :ethernet\n          ethernet(num, opts)\n          return #\n        else\n          raise ArgumentError, \"today's device choices are: :servo, :pa_lcd, :sf_lcd, :freq_out,:i2c, :i2c_eeprom, :i2c_ds1307, and :i2c_blinkm  got #{opts[:device]}\"\n        end\n      end\n      \n  # add state variables for outputs with :state => :on or :off -- useful for toggling a light with output_toggle -- need to make this more modular\n      if opts[:state] \n        # add debounce settings to dbce struct array\n        ArduinoPlugin.add_debounce_struct\n        @debounce_pins << num\n        state = opts[:latch] == :on ? 1 : 0\n        prev = opts[:latch] == :on ? 0 : 1\n        adjust = opts[:adjust] ? opts[:adjust] : 200\n        @debounce_settings <<  \"dbce[#{num}].state = #{state}, dbce[#{num}].read = 0, dbce[#{num}].prev = #{prev}, dbce[#{num}].time = 0, dbce[#{num}].adjust = #{adjust}\"\n      end\n      \n      @declarations << \"int _#{opts[ :as ]} = #{num};\"\n      \n      accessor = []\n      accessor << \"int #{opts[ :as ]}() {\"\n      accessor << \"\\treturn _#{opts[ :as ]};\"\n      accessor << \"}\"\n      @accessors << accessor.join( \"\\n\" )\n      \n      @signatures << \"int #{opts[ :as ]}();\"\n    end\n  end\n  \n  \n  # Configure a single pin for input and setup a method to refer to that pin, i.e.:\n  #\n  #   input_pin 3, :as => :button\n  #\n  # would configure pin 3 as an input and let you refer to it from the then on by calling\n  # the `button` method in your loop like so:\n  # \n  #   def loop\n  #     digital_write led if digital_read button\n  #   end\n  #\n  def input_pin(num, opts={})\n    raise ArgumentError, \"can only define pin from Fixnum, got #{num.class}\" unless num.is_a?(Fixnum)\n    @pin_modes[:input] << num\n    if opts[:as]\n      # transitioning to :device => :button syntax\n      if opts[:latch] || opts[:device] == :button\n        if opts[:device] == :button\n          opts[:latch] ||= :off\n        end\n        # add debounce settings to dbce struct array\n        ArduinoPlugin.add_debounce_struct\n        @debounce_pins << num\n        state = opts[:latch] == :on ? 1 : 0\n        prev = opts[:latch] == :on ? 0 : 1\n        adjust = opts[:adjust] ? opts[:adjust] : 200\n        @debounce_settings <<  \"dbce[#{num}].state = #{state}, dbce[#{num}].read = 0, dbce[#{num}].prev = #{prev}, dbce[#{num}].time = 0, dbce[#{num}].adjust = #{adjust}\"\n      end\n      if opts[:device] == :sensor\n        ArduinoPlugin.add_sensor_struct\n        count = @hysteresis_pins.length\n        @hysteresis_pins << num\n        @hysteresis_settings << \"hyst[#{count}].pin = #{num}, hyst[#{count}].state = 0\"\n      end\n      if opts[:device] == :spectra\n        ArduinoPlugin.add_spectra_struct\n        count = @spectra_pins.length\n        @spectra_pins << num\n        @spectra_settings << \"spec[#{count}].pin = #{num}, spec[#{count}].state = 10, spec[#{count}].r1 = 0, spec[#{count}].r2 = 0, spec[#{count}].r3 = 0\"\n      end\n      @declarations << \"int _#{opts[ :as ]} = #{num};\"\n\n      accessor = []\n      accessor << \"int #{opts[ :as ]}() {\"\n      accessor << \"\\treturn _#{opts[ :as ]};\"\n      accessor << \"}\"\n      @accessors << accessor.join( \"\\n\" )\n      \n      @signatures << \"int #{opts[ :as ]}();\"\n    end\n    @pullups << num if opts[:as]\n  end\n  \n  # Like ArduinoSketch#input_pin but configure more than one input pin simultaneously. Takes an array of pin numbers. \n  def input_pins(nums)\n    ar = Array(nums)\n    ar.each {|n| input_pin(n)} \n  end\n  \n  def add(st) #:nodoc:\n    @helper_methods << \"\\n#{st}\\n\"\n  end\n  \n  # Configure Arduino for serial communication. Optionally, set the baud rate:\n  #\n  #   serial_begin :rate => 2400\n  #\n  # default is 9600. See http://www.arduino.cc/en/Serial/Begin for more details.\n  # \n  def serial_begin(opts={})\n    rate = opts[:rate] ? opts[:rate] : 9600\n    @other_setup << \"Serial.begin(#{rate});\"\n    @@hwserial_inc = TRUE\n  end\n  \n\n  def formatted_print(opts={})\n\n    buffer_size = opts[:buffer_size] ? opts[:buffer_size] : 64\n    \n    if opts[:as]\n      @@sprintf_inc ||= FALSE\n      if @@sprintf_inc == FALSE\n        @@sprintf_inc = TRUE\n        accessor = []\n        accessor << \"\\n#undef int\\n#include <stdio.h>\"\n        accessor << \"#define write_line(...) sprintf(#{opts[:as]},__VA_ARGS__);\"\n        @accessors << accessor.join( \"\\n\" )\n        array(\"char #{opts[:as]}[#{buffer_size}]\") \n      end\n    end\n  end\n\n  \n\n\n  def compose_setup #:nodoc: also composes headers and signatures\n\n    declarations = []\n    plugin_directives = []\n    signatures = []\n    external_vars = []\n    setup = []\n    additional_setup =[]\n    helpers = []\n    main = []\n    result = []\n    \n    declarations << comment_box( \"Auto-generated by RAD\" )\n    \n    declarations << \"#include <WProgram.h>\\n\"\n    declarations << \"#include <SoftwareSerial.h>\\n\"\n    $load_libraries.each { |lib| declarations << \"#include <#{lib}.h>\" } unless $load_libraries.nil?\n    $defines.each { |d| declarations << d }\n\n    plugin_directives << comment_box( 'plugin directives' )\n    $plugin_directives.each {|dir| plugin_directives << dir } unless $plugin_directives.nil? ||  $plugin_directives.empty?\n    \n    signatures << comment_box( 'method signatures' )\n    signatures << \"void loop();\"\n    signatures << \"void setup();\"\n    signatures << \"// sketch signatures\"\n    @signatures.each {|sig| signatures << sig}\n    signatures << \"// plugin signatures\"\n    $plugin_signatures.each {|sig| signatures << sig } unless $plugin_signatures.nil? || $plugin_signatures.empty?\n    external_vars << \"\\n\" + comment_box( \"plugin external variables\" )\n    $plugin_external_variables.each { |meth| external_vars << meth } unless $plugin_external_variables.nil? || $plugin_external_variables.empty?\n    \n    signatures << \"\\n\" + comment_box( \"plugin structs\" )\n    $plugin_structs.each { |k,v| signatures << v } unless $plugin_structs.nil? || $plugin_structs.empty?\n\n    external_vars << \"\\n\" + comment_box( \"sketch external variables\" )\n    \n    $external_vars.each {|v| external_vars << v }\n    external_vars << \"\" \n    external_vars << \"// servo_settings array\"\n\n    array_size = @servo_settings.empty? ? 1 : @servo_pins.max + 1 # conserve space if no variables needed\n    external_vars << \"struct servo serv[#{array_size}] = { #{@servo_settings.join(\", \")} };\" if $plugin_structs[:servo]\n    external_vars << \"\" \n\n    external_vars << \"// debounce array\"\n    array_size = @debounce_settings.empty? ? 1 : @debounce_pins.max + 1 # conserve space if no variables needed\n    external_vars << \"struct debounce dbce[#{array_size}] = { #{@debounce_settings.join(\", \")} };\" if $plugin_structs[:debounce]\n    external_vars << \"\"\n    \n    external_vars << \"// hysteresis array\"\n    h_array_size = @hysteresis_settings.empty? ? 1 : @hysteresis_pins.length + 1 # conserve space if no variables needed\n    external_vars << \"struct hysteresis hyst[#{h_array_size}] = { #{@hysteresis_settings.join(\", \")} };\" if $plugin_structs[:sensor]\n    external_vars << \"\"\n    \n    external_vars << \"// spectrasymbol soft pot array\"\n    sp_array_size = @spectra_settings.empty? ? 1 : @spectra_pins.length + 1 # conserve space if no variables needed\n    external_vars << \"struct spectra spec[#{sp_array_size}] = { #{@spectra_settings.join(\", \")} };\" if $plugin_structs[:spectra]\n    external_vars << \"\"\n    \n    $external_array_vars.each { |var| external_vars << var } if $external_array_vars\n\n    external_vars << \"\\n\" + comment_box( \"variable and accessors\" )\n    @declarations.each {|dec| external_vars << dec}\n    external_vars << \"\"     \n    @accessors.each {|ac| external_vars << ac}\n\n    # fix naming\n    external_vars << \"\\n\" + comment_box( \"assembler declarations\" )\n    unless @assembler_declarations.empty?\n      external_vars << <<-CODE\n         extern \"C\" {\n           #{@assembler_declarations.join(\"\\n\")}\n         }\n      CODE\n    end\n\n    external_vars << \"\\n\" + comment_box( \"setup\" )\n    setup << \"void setup() {\"\n    setup << \"\\t// pin modes\"\n    \n    @pin_modes.each do |k,v|\n      v.each do |value| \n        setup << \"\\tpinMode(#{value}, #{k.to_s.upcase});\"\n      end\n    end\n\n    @pullups.each do |pin|\n\t    setup << \"\\tdigitalWrite( #{pin}, HIGH ); // enable pull-up resistor for input\"\n    end\n    \n    unless $add_to_setup.nil? || $add_to_setup.empty?\n      setup << \"\\t// setup from plugins via add_to_setup method\"\n      $add_to_setup.each {|item| setup << \"\\t#{item}\"}\n    end\n    \n    unless @other_setup.empty?\n      setup << \"\\t// other setup\"\n      setup << @other_setup.join( \"\\n\" )\n    end\n    \n    additional_setup << \"}\\n\"\n    \n    helpers << comment_box( \"helper methods\" )\n    helpers << \"\\n// RAD built-in helpers\"\n    helpers << @helper_methods.lstrip\n    \n    helpers << \"\\n\" + comment_box( \"plugin methods\" )  \n    # need to add plugin name to this... \n    $plugin_methods.each { |meth| helpers << \"#{meth[0][0]}\\n\" } unless $plugin_methods.nil? || $plugin_methods.empty?\n    \n    if @@hwserial_inc == TRUE\n      helpers << \"\\n// serial helpers\"\n      helpers << serial_boilerplate.lstrip\n    end\n    \n    main << \"\\n\" + comment_box( \"main() function\" )\n    main << \"int main() {\"\n    main << \"\\tinit();\"\n    main << \"\\tsetup();\"\n    main << \"\\tfor( ;; ) { loop(); }\"\n    main << \"\\treturn 0;\"\n    main << \"}\"\n\n    main << \"\\n\" + comment_box( \"loop!  Autogenerated by RubyToC, sorry it's ugly.\" )\n\n  return [declarations, plugin_directives, signatures, external_vars, setup, additional_setup, helpers, main]\n\n  end\n  \n  \n  # Write inline assembler code. 'Name' is a symbol representing the name of the function to be defined in the assembly code; 'signature' is the function signature for the function being defined; and 'code' is the assembly code itself (both of these last two arguments are strings). See an example here: http://rad.rubyforge.org/examples/assembler_test.html\n  def assembler(name, signature, code)\n    @assembler_declarations << signature\n    assembler_code = <<-CODE\n      .file \"#{name}.S\"\n      .arch #{Makefile.hardware_params['mcu']}\n      .global __do_copy_data\n      .global __do_clear_bss\n      .text\n    .global #{name}\n      .type #{name}, @function\n    #{code}\n    CODE\n            \n    File.open(File.expand_path(\"#{RAD_ROOT}\") + \"/#{PROJECT_DIR_NAME}/#{name}.S\", \"w\"){|f| f << assembler_code}\n  end\n  \n  def self.pre_process(sketch_string) #:nodoc:\n    result = sketch_string \n    # add external vars to each method (needed for better translation, will be removed in make:upload)\n    result.gsub!(/(^\\s*def\\s.\\w*(\\(.*\\))?)/, '\\1' + \" \\n #{$external_vars.join(\"  \\n \")}\"  )\n    # gather method names\n    sketch_methods = result.scan(/^\\s*def\\s.\\w*/)\n    sketch_methods.each {|m| $sketch_methods << m.gsub(/\\s*def\\s*/, \"\") }\n    \n    result.gsub!(\"HIGH\", \"1\")\n    result.gsub!(\"LOW\", \"0\")\n    result.gsub!(\"ON\", \"1\")\n    result.gsub!(\"OFF\", \"0\")\n    result\n  end\n  \n  def self.add_to_setup(meth) \n    meth = meth.gsub(\"setup\", \"additional_setup\")\n    post_process_ruby_to_c_methods(meth)\n  end\n  \n  def self.post_process_ruby_to_c_methods(e)      \n    clean_c_methods = []\n      # need to take a look at the \\(unsigned in the line below not sure if we are really trying to catch something like that\n      if e !~ /^\\s*(#{C_VAR_TYPES})(\\W{1,6}|\\(unsigned\\()(#{$external_var_identifiers.join(\"|\")})/ || $external_var_identifiers.empty?\n        # use the list of identifers the external_vars method of the sketch and remove the parens the ruby2c sometime adds to variables\n        # keep an eye on the gsub!.. are we getting nil errors\n        # and more recently, the \\b\n        e.gsub!(/\\b((#{$external_var_identifiers.join(\"|\")})\\(\\))/, '\\2')  unless $external_var_identifiers.empty?\n        clean_c_methods << e\n      end\n      return clean_c_methods.join( \"\\n\" )\n  end\n  \n\n  def comment_box( content ) #:nodoc:\n    out = []\n    out << \"/\" * 74\n    out << \"// \" + content\n    out << \"/\" * 74\n    \n    return out.join( \"\\n\" )\n  end  \n\n  \nend"
  },
  {
    "path": "lib/rad/darwin_installer.rb",
    "content": "class DarwinInstaller\n  def self.install!\n    puts \"Downloading arduino-0012 for Mac from Arduino.cc\"\n    File.open(\"/Applications/arduino-0012.zip\", \"w\") do |file|\n      pbar = nil\n      file << open(\"http://www.arduino.cc/files/arduino-0012-mac.zip\",\n      :content_length_proc => lambda {|t|\n        if t && 0 < t\n          pbar = ProgressBar.new(\" Progress\", t)\n          pbar.file_transfer_mode\n        end\n      },\n      :progress_proc => lambda {|s|\n        pbar.set s if pbar\n      }).read\n      pbar.finish\n    end\n    puts \"Unzipping...\"\n    `cd /Applications; unzip arduino-0012.zip`\n    `rm /Applications/arduino-0012.zip`\n    puts \"installed Arduino here: /Applications/arduino-0012\"\n  end\nend"
  },
  {
    "path": "lib/rad/generators/makefile/makefile.erb",
    "content": "# Arduino makefile\n#\n# This makefile allows you to build sketches from the command line\n# without the Arduino environment (or Java).\n#\n# The Arduino environment does preliminary processing on a sketch before\n# compiling it.  If you're using this makefile instead, you'll need to do\n# a few things differently:\n#\n#   - Give your program's file a .cpp extension (e.g. foo.cpp).\n#\n#   - Put this line at top of your code: #include <WProgram.h>\n#\n#   - Write prototypes for all your functions (or define them before you\n#     call them).  A prototype declares the types of parameters a\n#     function will take and what type of value it will return.  This\n#     means that you can have a call to a function before the definition\n#     of the function.  A function prototype looks like the first line of\n#     the function, with a semi-colon at the end.  For example:\n#     int digitalRead(int pin);\n#\n#   - Write a main() function for your program that returns an int, calls\n#     init() and setup() once (in that order), and then calls loop()\n#     repeatedly():\n#\n#\tint main()\n#\t{\n#\t\tinit();\n#\t\tsetup();\n#\n#\t\tfor (;;)\n#\t\t\tloop();\n#\n#\t\treturn 0;\n#\t}\n#\n# Instructions for using the makefile:\n#\n#  1. Copy this file into the folder with your sketch.\n#\n#  2. Below, modify the line containing \"TARGET\" to refer to the name of\n#     of your program's file without an extension (e.g. TARGET = foo).\n#\n#  3. Modify the line containg \"ARDUINO\" to point the directory that\n#     contains the Arduino core (for normal Arduino installations, this\n#     is the hardware/cores/arduino sub-directory).\n#\n#  4. Modify the line containing \"PORT\" to refer to the filename\n#     representing the USB or serial connection to your Arduino board\n#     (e.g. PORT = /dev/tty.USB0).  If the exact name of this file\n#     changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).\n#\n#  5. At the command line, change to the directory containing your\n#     program's file and the makefile.\n#\n#  6. Type \"make\" and press enter to compile/verify your program.\n#\n#  7. Type \"make upload\", reset your Arduino board, and press enter  to\n#     upload your program to the Arduino board.\n#\n# $Id$\n\nPORT = <%= params['serial_port'] %>\nTARGET = <%= params['target'] %>\nARDUINO = <%= params['arduino_root'] %>/hardware/cores/arduino\nSOFTWARE_SERIAL = <%= params['arduino_root'] %>/hardware/libraries/SoftwareSerial\nLIBRARY_ROOT = <%= params['libraries_root'] %>\nSRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \\\n$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \\\n$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \\\n$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c <%= params['twi_c'] %>\nCXXSRC = $(ARDUINO)/HardwareSerial.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp $(ARDUINO)/Print.cpp<%= params['libraries'].collect{|l| \" $(LIBRARY_ROOT)/#{ l }/#{l }.cpp\"}.join('') %>\nMCU = <%= params['mcu'] %>\n<% if params['asm_files'] %>ASRC = <%= params['asm_files'].join(' ') %><% end %>\nF_CPU = 16000000\nFORMAT = ihex\nUPLOAD_RATE = 19200\nBIN_DIR = <%= params['arduino_root'] %>/hardware/tools/avr/bin\n\n# Name of this Makefile (used for \"make depend\").\nMAKEFILE = Makefile\n\n# Debugging format.\n# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.\n# AVR (extended) COFF requires stabs, plus an avr-objcopy run.\nDEBUG = stabs\n\nOPT = s\n\n# Place -D or -U options here\nCDEFS = -DF_CPU=$(F_CPU)\nCXXDEFS = -DF_CPU=$(F_CPU)\n\n# Place -I options here\nCINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)<% params['libraries'].each do |l| %> -I$(LIBRARY_ROOT)/<%= l %><% end %>\n+CXXINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)<% params['libraries'].each do |l| %> -I$(LIBRARY_ROOT)/<%= l %><% end %>\n\n# Compiler flag to set the C Standard level.\n# c89   - \"ANSI\" C\n# gnu89 - c89 plus GCC extensions\n# c99   - ISO C99 standard (not yet fully implemented)\n# gnu99 - c99 plus GCC extensions\nCSTANDARD = -std=gnu99\nCDEBUG = -g$(DEBUG)\nCWARN = -Wall -Wstrict-prototypes\nCTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums\n#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)\n\nCFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)\nCXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)\n#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs \nLDFLAGS = -lm\n\n\n# Programming support using avrdude. Settings and variables.\nAVRDUDE_PROGRAMMER = stk500\nAVRDUDE_PORT = $(PORT)\nAVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex\nAVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \\\n  -b $(UPLOAD_RATE) -C <%= params['arduino_root'] %>/hardware/tools/avr/etc/avrdude.conf\n\n# Program settings\nCC = $(BIN_DIR)/avr-gcc\nCXX = $(BIN_DIR)/avr-g++\nOBJCOPY = $(BIN_DIR)/avr-objcopy\nOBJDUMP = $(BIN_DIR)/avr-objdump\nAR  = $(BIN_DIR)/avr-ar\nSIZE = $(BIN_DIR)/avr-size\nNM = $(BIN_DIR)/avr-nm\nAVRDUDE = $(BIN_DIR)/avrdude\nREMOVE = rm -f\nMV = mv -f\n\n# Define all object files.\nOBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)\n\n# Define all listing files.\nLST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)\n\n# Combine all necessary flags and optional flags.\n# Add target processor to flags.\nALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)\nALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)\nALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)\n\n\n# Default target.\nall: build\n\nbuild: elf hex\n\nelf: $(TARGET).elf\nhex: $(TARGET).hex\neep: $(TARGET).eep\nlss: $(TARGET).lss \nsym: $(TARGET).sym\n\n# Program the device.  \nupload: $(TARGET).hex\n\t$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)\n\n\n\n\n# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.\nCOFFCONVERT=$(OBJCOPY) --debugging \\\n--change-section-address .data-0x800000 \\\n--change-section-address .bss-0x800000 \\\n--change-section-address .noinit-0x800000 \\\n--change-section-address .eeprom-0x810000 \n\n\ncoff: $(TARGET).elf\n\t$(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof\n\n\nextcoff: $(TARGET).elf\n\t$(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof\n\n\n.SUFFIXES: .elf .hex .eep .lss .sym\n\n.elf.hex:\n\t$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@\n\n.elf.eep:\n\t-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom=\"alloc,load\" \\\n\t--change-section-lma .eeprom=0 -O $(FORMAT) $< $@\n\n# Create extended listing file from ELF output file.\n.elf.lss:\n\t$(OBJDUMP) -h -S $< > $@\n\n# Create a symbol table from ELF output file.\n.elf.sym:\n\t$(NM) -n $< > $@\n\n\ncore.a: $(OBJ)\n\t@for i in $(OBJ); do echo $(AR) rcs core.a $$i; $(AR) rcs core.a $$i; done\n\n# Link: create ELF output file from library.\n$(TARGET).elf: core.a\n\t$(CC) $(ALL_CFLAGS) -o $@ $(TARGET).cpp -L. core.a $(LDFLAGS)\n\n# Compile: create object files from C++ source files.\n.cpp.o:\n\t$(CXX) -c $(ALL_CXXFLAGS) $< -o $@ \n\n# Compile: create object files from C source files.\n.c.o:\n\t$(CC) -c $(ALL_CFLAGS) $< -o $@ \n\n\n# Compile: create assembler files from C source files.\n.c.s:\n\t$(CC) -S $(ALL_CFLAGS) $< -o $@\n\n\n# Assemble: create object files from assembler source files.\n.S.o:\n\t$(CC) -c $(ALL_ASFLAGS) $< -o $@\n\n\n\n# Target: clean project.\nclean:\n\t$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \\\n\t$(TARGET).map $(TARGET).sym $(TARGET).lss core.a \\\n\t$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)\n\ndepend:\n\tif grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \\\n\tthen \\\n\t\tsed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \\\n\t\t\t$(MAKEFILE).$$$$ && \\\n\t\t$(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \\\n\tfi\n\techo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \\\n\t\t>> $(MAKEFILE); \\\n\t$(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)\n\n.PHONY:\tall build elf hex eep lss sym program coff extcoff clean depend\n"
  },
  {
    "path": "lib/rad/generators/makefile/makefile.rb",
    "content": "require 'erb'\nrequire 'yaml'\n\nclass Makefile\n  class << self\n    \n    # build the sketch Makefile for the given template based on the values in its software and hardware config files\n    def compose_for_sketch(build_dir)\n      params = hardware_params.merge software_params\n      params['target'] = build_dir.split(\"/\").last\n           \n      params['libraries_root'] = \"#{File.expand_path(RAD_ROOT)}/vendor/libraries\"\n      params['libraries'] = $load_libraries # load only libraries used \n      \n      # needed along with ugly hack of including another copy of twi.h in wire, when using the Wire.h library\n      params['twi_c'] = $load_libraries.include?(\"Wire\") ? \"#{params['arduino_root']}/hardware/libraries/Wire/utility/twi.c\" : \"\" \n      \n      params['asm_files'] = Dir.entries( File.expand_path(RAD_ROOT) + \"/\" + PROJECT_DIR_NAME ).select{|e| e =~ /\\.S/}            \n            \n      e = ERB.new File.read(\"#{File.dirname(__FILE__)}/makefile.erb\")\n      \n      File.open(\"#{build_dir}/Makefile\", \"w\") do |f|\n        f << e.result(binding)\n      end\n    end\n        \n    def hardware_params\n      return @hardware_params if @hardware_params\n      return @hardware_params = YAML.load_file( \"#{RAD_ROOT}/config/hardware.yml\")\n    end\n      \n    def software_params\n      return @software_params if @software_params\n      return @software_params = YAML.load_file( \"#{RAD_ROOT}/config/software.yml\" )\n    end\n      \n  end\nend"
  },
  {
    "path": "lib/rad/hardware_library.rb",
    "content": "class HardwareLibrary < ArduinoSketch\n  \n  def initialize\n    super\n  end\n  \n  # Treat a pair of digital I/O pins as a serial line. See: http://www.arduino.cc/en/Tutorial/SoftwareSerial\n  def software_serial(rx, tx, opts={})\n    raise ArgumentError, \"can only define rx from Fixnum, got #{rx.class}\" unless rx.is_a?(Fixnum)\n    raise ArgumentError, \"can only define tx from Fixnum, got #{tx.class}\" unless tx.is_a?(Fixnum)\n\n    output_pin(tx)\n    input_pin(rx)\n\n    rate = opts[:rate] ? opts[:rate] : 9600\n    if opts[:as]\n      @declarations << \"SoftwareSerial _#{opts[ :as ]} = SoftwareSerial(#{rx}, #{tx});\"\n      accessor = <<-STR\n        SoftwareSerial& #{opts[ :as ]}() {\n        return _#{opts[ :as ]};\n        }\n      STR\n      @@swser_inc ||= FALSE\n      if (@@swser_inc == FALSE) # on second instance this stuff can't be repeated\n        @@swser_inc = TRUE\n        accessor += <<-STR\n        int read(SoftwareSerial& s) {\n          return s.read();\n        }\n        void println( SoftwareSerial& s, char* str ) {\n          return s.println( str );\n        }\n        void print( SoftwareSerial& s, char* str ) {\n          return s.print( str );\n        }\n        void println( SoftwareSerial& s, int i ) {\n          return s.println( i );\n        }\n        void print( SoftwareSerial& s, int i ) {\n          return s.print( i );\n        }\n        STR\n      end\n      @accessors << accessor\n\n      @signatures << \"SoftwareSerial& #{opts[ :as ]}();\"\n\n      @other_setup << \"\\t_#{opts[ :as ]}.begin(#{rate});\"\n    end\n  end \t\n  \n  # use the pa lcd library\n  def pa_lcd_setup(num, opts)\n    if opts[:geometry]\n      raise ArgumentError, \"can only define pin from Fixnum, got #{opts[:geometry]}\" unless opts[:geometry].is_a?(Fixnum)\n      raise ArgumentError, \"pa_lcd geometry must be 216, 220, 224, 240, 416, 420, got #{opts[:geometry]}\" unless opts[:geometry].to_s =~ /(216|220|224|240|416|420)/\n    end\n    # move to plugin and load plugin\n    # what's the default?\n     opts[:rate] ||= 9600\n    rate = opts[:rate] ? opts[:rate] : 9600\n    swser_LCDpa(num, opts)\n  end\n\n  def swser_LCDpa(tx, opts={})\n    raise ArgumentError, \"can only define tx from Fixnum, got #{tx.class}\" unless tx.is_a?(Fixnum)\n\n    rate = opts[:rate] ? opts[:rate] : 9600\n    geometry = opts[:geometry] ? opts[:geometry] : 0\n    if opts[:as] \n      @declarations << \"SWSerLCDpa _#{opts[ :as ]} = SWSerLCDpa(#{tx}, #{geometry});\"\n      $load_libraries << \"SWSerLCDpa\"\n      accessor = <<-STR\n        SWSerLCDpa& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@slcdpa_inc ||= FALSE\n      if (@@slcdpa_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n        @@slcdpa_inc = TRUE\n        # ------------------- print generics -------------------------------\n        accessor += <<-STR\t\t\t  \n        void print( SWSerLCDpa& s, uint8_t b ) {\n          return s.print( b );\n        }\n        void print( SWSerLCDpa& s, const char *str ) {\n          return s.print( str );\n        }\n        void print( SWSerLCDpa& s, char c ) {\n          return s.print( c );\n        }\n        void print( SWSerLCDpa& s, int i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDpa& s, unsigned int i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDpa& s, long i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDpa& s, unsigned long i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDpa& s, long i, int b ) {\n          return s.print( i, b );\n        }\n        STR\n        # ------------------ PA-LCD specific functions ---------------------------------\n        accessor += <<-STR\n        void clearscr(SWSerLCDpa& s) {\n          return s.clearscr();\n        }\n        void clearscr(SWSerLCDpa& s, const char *str) {\n          return s.clearscr(str);\n        }\n        void clearscr(SWSerLCDpa& s, int n) {\n          return s.clearscr(n);\n        }\n        void clearscr(SWSerLCDpa& s, long n, int b) {\n          return s.clearscr(n, b);\n        }\n        void clearline(SWSerLCDpa& s, int line) {\n          return s.clearline( line );\n        }\n        void clearline(SWSerLCDpa& s, int line, const char *str) {\n          return s.clearline( line, str );\n        }\n        void clearline(SWSerLCDpa& s, int line, int n) {\n          return s.clearline( line, n );\n        }\n        void clearline(SWSerLCDpa& s, int line, long n,  int b) {\n          return s.clearline( line, n, b );\n        }\n        void home( SWSerLCDpa& s) {\n          return s.home();\n        }\n        void home( SWSerLCDpa& s, const char *str) {\n          return s.home( str );\n        }\n        void home( SWSerLCDpa& s, int n) {\n          return s.home( n );\n        }\n        void home( SWSerLCDpa& s, long n, int b) {\n          return s.home( n, b );\n        }\n        void setxy( SWSerLCDpa& s, int x, int y) {\n          return s.setxy( x, y );\n        }\n        void setxy( SWSerLCDpa& s, int x, int y, const char *str) {\n          return s.setxy( x, y, str );\n        }\n        void setxy( SWSerLCDpa& s, int x, int y, long n, int b) {\n          return s.setxy( x, y, n, b );\n        }\n        void setxy( SWSerLCDpa& s, int x, int y, int n) {\n          return s.setxy( x, y, n );\n        }\n        void setgeo( SWSerLCDpa& s, int g) {\n          return s.setgeo( g );\n        }\n        void setintensity( SWSerLCDpa& s, int i ) {\n          return s.setintensity( i );\n        }\n        void intoBignum(SWSerLCDpa& s) {\n          return s.intoBignum();\n        }\n        void outofBignum(SWSerLCDpa& s) {\n          return s.outofBignum();\n        }\n        STR\n      end\n\n      @accessors << accessor\n\n      @signatures << \"SWSerLCDpa& #{opts[ :as ]}();\"\n\n      @other_setup << \"\\t_#{opts[ :as ]}.begin(#{rate});\"\n      @other_setup << \"\\t_#{opts[ :as ]}.clearscr();\"     if :clear_screen == :true\n\n    end\n  end \t\n\n  \n  # use the sf (sparkfun) library\n  def sf_lcd_setup(num, opts)\n    if opts[:geometry]\n      raise ArgumentError, \"can only define pin from Fixnum, got #{opts[:geometry]}\" unless opts[:geometry].is_a?(Fixnum)\n      raise ArgumentError, \"sf_lcd geometry must be 216, 220, 416, 420, got #{opts[:geometry]}\" unless opts[:geometry].to_s =~ /(216|220|416|420)/\n    end\n    # move to plugin and load plugin\n     opts[:rate] ||= 9600\n    rate = opts[:rate] ? opts[:rate] : 9600\n    swser_LCDsf(num, opts)\n  end\n\n  def swser_LCDsf(tx, opts={})\n    raise ArgumentError, \"can only define tx from Fixnum, got #{tx.class}\" unless tx.is_a?(Fixnum)    \n\n    rate = opts[:rate] ? opts[:rate] : 9600\n    geometry = opts[:geometry] ? opts[:geometry] : 0\n    if opts[:as] \n      @declarations << \"SWSerLCDsf _#{opts[ :as ]} = SWSerLCDsf(#{tx}, #{geometry});\"\n\n      $load_libraries << \"SWSerLCDsf\"\n      accessor = <<-STR\n        SWSerLCDsf& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@slcdsf_inc ||= FALSE # assign only if nil\n      if (@@slcdsf_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n        @@slcdsf_inc = TRUE\n        accessor += <<-STR\n        void print( SWSerLCDsf& s, uint8_t b ) {\n          return s.print( b );\n        }\n        void print( SWSerLCDsf& s, const char *str ) {\n          return s.print( str );\n        }\n        void print( SWSerLCDsf& s, char c ) {\n          return s.print( c );\n        }\n        void print( SWSerLCDsf& s, int i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDsf& s, unsigned int i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDsf& s, long i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDsf& s, unsigned long i ) {\n          return s.print( i );\n        }\n        void print( SWSerLCDsf& s, long i, int b ) {\n          return s.print( i, b );\n        }\n        STR\n        # ------------------ Spark Fun Specific  Functions ---------------------------------\n        accessor += <<-STR\n        void clearscr(SWSerLCDsf& s) {\n          return s.clearscr();\n        }\n        void clearscr(SWSerLCDsf& s, const char *str) {\n          return s.clearscr(str);\n        }\n        void clearscr(SWSerLCDsf& s, int n) {\n          return s.clearscr(n);\n        }\n        void clearscr(SWSerLCDsf& s, long n, int b) {\n          return s.clearscr(n, b);\n        }\n        void home( SWSerLCDsf& s) {\n          return s.home();\n        }\n        void home( SWSerLCDsf& s, const char *str) {\n          return s.home( str );\n        }\n        void home( SWSerLCDsf& s, int n) {\n          return s.home( n );\n        }\n        void home( SWSerLCDsf& s, long n, int b) {\n          return s.home( n, b );\n        }\n        void setxy( SWSerLCDsf& s, int x, int y) {\n          return s.setxy( x, y );\n        }\n        void setxy( SWSerLCDsf& s, int x, int y, const char *str) {\n          return s.setxy( x, y, str );\n        }\n        void setxy( SWSerLCDsf& s, int x, int y, int n) {\n          return s.setxy( x, y, n );\n        }\n        void setxy( SWSerLCDsf& s, int x, int y, long n, int b) {\n          return s.setxy( x, y, n, b );\n        }\n        void setgeo( SWSerLCDsf& s, int g) {\n          return s.setgeo( g );\n        }\n        void setintensity( SWSerLCDsf& s, int i ) {\n          return s.setintensity( i );\n        }\n        void setcmd( SWSerLCDsf& s, uint8_t a, uint8_t b) {\n          return s.setcmd( a, b );\n        }\n        STR\n      end\n      @accessors << accessor\n\n      @signatures << \"SWSerLCDsf& #{opts[ :as ]}();\"\n\n      @other_setup << \"\\t_#{opts[ :as ]}.begin(#{rate});\"\n      @other_setup << \"\\t_#{opts[ :as ]}.clearscr();\"     if :clear_screen == :true\n\n    end\n  end \t\n\n\n  def loop_timer(opts={}) # loop timer methods #\n\n    if opts[:as]\n      @declarations << \"LoopTimer _#{opts[ :as ]} = LoopTimer();\"\n      $load_libraries << \"LoopTimer\"\n      accessor = <<-STR\n        LoopTimer& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@loptim_inc ||= FALSE\n      if (@@loptim_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n        @@limtim_inc = TRUE\n        accessor += <<-STR\n        void track( LoopTimer& s ) {\n          return s.track();\n        }\n        unsigned long get_total( LoopTimer& s ) {\n          return s.get_total();\n        }\n        STR\n      end\n\n      @accessors << accessor\n\n      @signatures << \"LoopTimer& #{opts[ :as ]}();\"\n\n    end\n  end\n\n  # use the servo library\n  def servo_setup(num, opts)\n    if opts[:position]\n      raise ArgumentError, \"position must be an integer from 0 to 360, got #{opts[:position].class}\" unless opts[:position].is_a?(Fixnum)\n      raise ArgumentError, \"position must be an integer from 0 to 360---, got #{opts[:position]}\" if opts[:position] < 0 || opts[:position] > 360\n    end\n    servo(num, opts)\n    # move this to better place ... \n    # should probably go along with servo code into plugin\n    @@servo_dh ||= FALSE\n    if (@@servo_dh == FALSE)\t# on second instance this stuff can't be repeated - BBR\n      @@servo_dh = TRUE\n      @declarations << \"void servo_refresh(void);\"\n      helper_methods = []\n      helper_methods << \"void servo_refresh(void)\"\n      helper_methods << \"{\"\n      helper_methods <<  \"\\tServo::refresh();\"\n      helper_methods << \"}\"\n      @helper_methods += \"\\n#{helper_methods.join(\"\\n\")}\"\n    end\n  end\n  \n  def servo(pin, opts={}) # servo motor routines #\n    raise ArgumentError, \"can only define pin from Fixnum, got #{pin.class}\" unless pin.is_a?(Fixnum)\n\n    minp = opts[:min] ? opts[:min] : 544\n    maxp = opts[:max] ? opts[:max] : 2400\n\n    if opts[:as]\n      @declarations << \"Servo _#{opts[ :as ]} = Servo();\"\n      $load_libraries << \"Servo\"\n      accessor = <<-STR\n        Servo& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@servo_inc ||= FALSE\n      if (@@servo_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n        @@servo_inc = TRUE\n        accessor += <<-STR\n        uint8_t attach( Servo& s, int p ) {\n          return s.attach(p);\n        }\n        uint8_t attach( Servo& s, int p, int pos ) {\n          return s.attach(p, pos );\n        }\n        uint8_t attach( Servo& s, int p, uint16_t mn, uint16_t mx ) {\n          return s.attach(p, mn, mx);\n        }\n        uint8_t attach( Servo& s, int p, int pos, uint16_t mn, uint16_t mx ) {\n          return s.attach(p, pos, mn, mx);\n        }\n        void detach( Servo& s ) {\n          return s.detach();\n        }\n        void position( Servo& s, int b ) {\n          return s.position( b );\n        }\n        void speed( Servo& s, int b ) {\n          return s.speed( b );\n        }\n        uint8_t read( Servo& s ) {\n          return s.read();\n        }\n        uint8_t attached( Servo& s ) {\n          return s.attached();\n        }\n        static void refresh( Servo& s ) {\n          return s.refresh();\n        }\n        STR\n      end\n\n      @accessors << accessor\n\n      @signatures << \"Servo& #{opts[ :as ]}();\"\n\n      @other_setup << \"\\t_#{opts[ :as ]}.attach(#{pin}, #{opts[:position]}, #{minp}, #{maxp});\" if opts[:position]\n      @other_setup << \"\\t_#{opts[ :as ]}.attach(#{pin}, #{minp}, #{maxp});\" unless opts[:position]\n\n    end\n  end\n  \n  def twowire_stepper(pin1, pin2, opts={}) # servo motor routines #\n    raise ArgumentError, \"can only define pin1 from Fixnum, got #{pin1.class}\" unless pin1.is_a?(Fixnum)\n    raise ArgumentError, \"can only define pin2 from Fixnum, got #{pin2.class}\" unless pin2.is_a?(Fixnum)\n\n    st_speed = opts[:speed] ? opts[:speed] : 30\n    st_steps = opts[:steps] ? opts[:steps] : 100\n\n    if opts[:as]\n      @declarations << \"Stepper _#{opts[ :as ]} = Stepper(#{st_steps},#{pin1},#{pin2});\"\n      $load_libraries << \"Stepper\"\n      accessor = <<-STR\n        Stepper& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@stepr_inc ||= FALSE\n      if (@@stepr_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n      @@stepr_inc = TRUE\n      accessor = <<-STR\n        void set_speed( Stepper& s, long sp ) {\n          return s.set_speed( sp );\n        }\n        void set_steps( Stepper& s, int b ) {\n          return s.set_steps( b );\n        }\n        int version( Stepper& s ) {\n          return s.version();\n        }\n        STR\n    end\n\n    @accessors << accessor\n\n    @signatures << \"Stepper& #{opts[ :as ]}();\"\n\n    @other_setup << \"\\t_#{opts[ :as ]}.set_speed(#{st_speed});\" if opts[:speed]\n\n    end\n  end\n  \n  def fourwire_stepper( pin1, pin2, pin3, pin4, opts={}) # servo motor routines #\n    raise ArgumentError, \"can only define pin1 from Fixnum, got #{pin1.class}\" unless pin1.is_a?(Fixnum)\n    raise ArgumentError, \"can only define pin2 from Fixnum, got #{pin2.class}\" unless pin2.is_a?(Fixnum)\n    raise ArgumentError, \"can only define pin3 from Fixnum, got #{pin3.class}\" unless pin3.is_a?(Fixnum)\n    raise ArgumentError, \"can only define pin4 from Fixnum, got #{pin4.class}\" unless pin4.is_a?(Fixnum)\n\n    st_speed = opts[:speed] ? opts[:speed] : 30\n    st_steps = opts[:steps] ? opts[:steps] : 100\n\n    if opts[:as]\n      @declarations << \"Stepper _#{opts[ :as ]} = Stepper(#{st_steps},#{pin1},#{pin2},#{pin3},#{pin4});\"\n      $load_libraries << \"Stepper\"\n      accessor = <<-STR\n        Stepper& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@stepr_inc ||= FALSE\n      if (@@stepr_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n        @@stepr_inc = TRUE\n        accessor += <<-STR\n        void set_speed( Stepper& s, long sp ) {\n          return s.set_speed( sp );\n        }\n        void set_steps( Stepper& s, int b ) {\n          return s.set_steps( b );\n        }\n        int version( Stepper& s ) {\n          return s.version();\n        }\n        STR\n      end\n\n      @accessors << accessor\n\n      @signatures << \"Stepper& #{opts[ :as ]}();\"\n\n      @other_setup << \"\\t_#{opts[ :as ]}.set_speed(#{st_speed});\" if opts[:speed]\n\n    end\n  end\n \t\n  def frequency_timer(pin, opts={}) # frequency timer routines\n\n    @@frequency_inc ||= FALSE\n    raise ArgumentError, \"there can be only one instance of Frequency Timer2\" if @@frequency_inc == TRUE\n    @@frequency_inc = TRUE\n\n    raise ArgumentError, \"can only define pin from Fixnum, got #{pin.class}\" unless pin.is_a?(Fixnum)\n    raise ArgumentError, \"only pin 11 may be used for freq_out, got #{pin}\" unless pin == 11\n\n    if opts[:enable]\n      raise ArgumentError, \"enable option must include the frequency or period option\" unless opts[:frequency] || opts[:period]\n    end\n    if opts[:frequency]\n      raise ArgumentError, \"the frequency option must be an integer, got #{opts[:frequency].class}\" unless opts[:frequency].is_a?(Fixnum)\n    end\n    if opts[:period]\n      raise ArgumentError, \"the frequency option must be an integer, got #{opts[:period].class}\" unless opts[:period].is_a?(Fixnum) \n    end\n    # refer to: http://www.arduino.cc/playground/Code/FrequencyTimer2\n\n    if opts[:as]\n\n      @declarations << \"FrequencyTimer2 _#{opts[ :as ]} = FrequencyTimer2();\"\n\n      $load_libraries << \"FrequencyTimer2\"\n        accessor = <<-STR\n        FrequencyTimer2& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n        void set_frequency( FrequencyTimer2& s, int b ) {\n          return s.setPeriod( 1000000L/b );\n        }\n        void set_period( FrequencyTimer2& s, int b ) {\n          return s.setPeriod( b );\n        }\n        void enable( FrequencyTimer2& s ) {\n          return s.enable();\n        }\n        void disable( FrequencyTimer2& s ) {\n          return s.disable();\n        }\n      STR\n\n      @accessors << accessor\n\n      @signatures << \"FrequencyTimer2& #{opts[ :as ]}();\"\n\n      @other_setup << \"\\tFrequencyTimer2::setPeriod(0L);\" unless opts[:frequency] || opts[:period]\n      @other_setup << \"\\tFrequencyTimer2::setPeriod(1000000L/#{opts[:frequency]});\" if opts[:frequency]\n      @other_setup << \"\\tFrequencyTimer2::setPeriod(#{opts[:period]});\" if opts[:period]\n      @other_setup << \"\\tFrequencyTimer2::enable();\" if opts[:enable] == :true\n    end\n  end\n  \n  def one_wire(pin, opts={})\n    raise ArgumentError, \"can only define pin from Fixnum, got #{pin.class}\" unless pin.is_a?(Fixnum)\n\n    if opts[:as]\n      @declarations << \"OneWire _#{opts[ :as ]} = OneWire(#{pin});\"\n      accessor = []\n      $load_libraries << \"OneWire\"\n      accessor = <<-STR \n        OneWire& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n    STR\n      @@onewire_inc ||= FALSE\n      if (@@onewire_inc == FALSE)     # on second instance this stuff can't be repeated - BBR\n        @@onewire_inc = TRUE\n        accessor += <<-STR\n        uint8_t reset(OneWire& s) {\n          return s.reset();\n        }\n        void skip(OneWire& s) {\n          return s.skip();\n        }\n        void write(OneWire& s, uint8_t v, uint8_t p = 0) {\n          return s.write( v, p );\n        }\n        uint8_t read(OneWire& s) {\n          return s.read();\n        }\n        void write_bit( OneWire& s, uint8_t b ) {\n          return s.write_bit( b );\n        }\n        uint8_t read_bit(OneWire& s) {\n          return s.read_bit();\n        }\n        void depower(OneWire& s) {\n          return s.depower();\n        }\n        STR\n      end\n      @accessors << accessor\n\n      @signatures << \"OneWire& #{opts[ :as ]}();\"\n    end\n  end\n\n  def two_wire (pin, opts={}) # i2c Two-Wire\n\n    raise ArgumentError, \"can only define pin from Fixnum, got #{pin.class}\" unless pin.is_a?(Fixnum)\n    raise ArgumentError, \"only pin 19 may be used for i2c, got #{pin}\" unless pin == 19\n\n    if opts[:as]\n\n      @@twowire_inc = TRUE\n       @declarations << \"TwoWire _wire = TwoWire();\"\n      $load_libraries << \"Wire\"\t\n      accessor = <<-STR\n        TwoWire& wire() {\n          return _wire;\n        }\n        void begin( TwoWire& s) {\n          return s.begin();\n        }\n        void begin( TwoWire& s, uint8_t a) {\n          return s.begin(a);\n        }\n        void begin( TwoWire& s, int a) {\n          return s.begin(a);\n        }\n        void beginTransmission( TwoWire& s, uint8_t a ) {\n          return s.beginTransmission( a );\n        }\n        void beginTransmission( TwoWire& s, int a ) {\n          return s.beginTransmission( a );\n        }\n        void endTransmission( TwoWire& s ) {\n          return s.endTransmission();\n        }\n        void requestFrom( TwoWire& s, uint8_t a, uint8_t q) {\n          return s.requestFrom( a, q );\n        }\n        void requestFrom( TwoWire& s, int a, int q) {\n          return s.requestFrom( a, q );\n        }\n        void send( TwoWire& s, uint8_t d) {\n          return s.send(d);\n        }\n        void send( TwoWire& s, int d) {\n          return s.send(d);\n        }\n        void send( TwoWire& s, char* d) {\n          return s.send(d);\n        }\n        void send( TwoWire& s, uint8_t* d, uint8_t q) {\n          return s.send( d, q );\n        }\n        uint8_t available( TwoWire& s) {\n          return s.available();\n        }\n        uint8_t receive( TwoWire& s) {\n          return s.receive();\n        }\n      STR\n\n      @accessors << accessor\n\n      @signatures << \"TwoWire& wire();\"\n\n      @other_setup << \"\\t_wire.begin();\"    # We never get here a second time. If we go to the trouble \n                                            # of setting up i2c, we gotta start it and it never gets \n                                            # stopped. This is not 'optional!'\n    end\n\n  end\n  \n  # work in progress\n  def ethernet(pin, opts={})\n    raise ArgumentError, \"can only define pin from Fixnum, got #{pin.class}\" unless pin.is_a?(Fixnum)\n    if opts[:as]\n      accessor = []\n      $load_libraries << \"AF_XPort\"\n      $load_libraries << \"AFSoftSerial\"\n      # needs to be more granular:\n      accessor << \"AF_XPort xport = AF_XPort(XPORT_RXPIN, XPORT_TXPIN, XPORT_RESETPIN, XPORT_DTRPIN, XPORT_RTSPIN, XPORT_CTSPIN);\"\n      rate = opts[:rate] ? opts[:rate] : 57600\n      @other_setup << \"xport.begin(#{rate});\"\n      @accessors << accessor.join( \"\\n\" )\n    end\n  end\n  \n  \n  def i2c_eeprom(pin, opts={}) # i2c serial eeprom routines #\n\n    dev_addr = opts[:address] ? opts[:address] : 0\n\n    if opts[:as]\n      @declarations << \"I2CEEPROM _#{opts[ :as ]} = I2CEEPROM(#{dev_addr});\"\n      $load_libraries << \"I2CEEPROM\"\n      accessor = <<-STR\n        I2CEEPROM& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n      STR\n      @@i2cepr_inc ||= FALSE\n      if (@@i2cepr_inc == FALSE)\t# on second instance this stuff can't be repeated - BBR\n        @@i2cepr_inc = TRUE\n        accessor += <<-STR\n        void write_byte( I2CEEPROM& s, unsigned int addr, byte b ) {\n          return s.write_byte( addr, b );\n        }\n        void write_page( I2CEEPROM& s, unsigned int addr, byte* d, int l ) {\n          return s.write_page( addr, d, l );\n        }\n        byte read_byte( I2CEEPROM& s, unsigned int addr ) {\n          return s.read_byte( addr );\n        }\n        void read_buffer( I2CEEPROM& s, unsigned int addr, byte *d, int l ) {\n          return s.read_buffer( addr, d, l );\n        }\n        STR\n      end\n\n      @accessors << accessor\n\n      @signatures << \"I2CEEPROM& #{opts[ :as ]}();\"\n\n    end\n  end\n  \n  \n  \n  def ds1307(pin, opts={}) # DS1307 real time clock routines routines\n\n    @@ds1307_inc ||= FALSE\n    raise ArgumentError, \"only one DS1307  may be used for i2c\" unless @@ds1307_inc == FALSE\n    @@ds1307_inc = TRUE\n    raise ArgumentError, \"can only define pin from Fixnum, got #{pin.class}\" unless pin.is_a?(Fixnum)\n    raise ArgumentError, \"only pin 19 may be used for i2c, got #{pin}\" unless pin == 19\n    if opts[:as]\n        @declarations << \"DS1307 _#{opts[ :as ]} = DS1307();\"\n        $load_libraries << \"DS1307\"\n        accessor = <<-STR\n        DS1307& #{opts[ :as ]}() {\n          return _#{opts[ :as ]};\n        }\n        void get( DS1307& s, byte *buf, boolean r ) {\n          return s.get( buf, r );\n        }\n        byte get( DS1307& s, int b, boolean r ) {\n          return s.get( b, r );\n        }\n        void set( DS1307& s, int b, int r ) {\n          return s.set( b, r );\n        }\n        void start( DS1307& s ) {\n          return s.start();\n        }\n        void stop( DS1307& s ) {\n          return s.stop();\n        }\n        STR\n\n        @accessors << accessor\n\n        @signatures << \"DS1307& #{opts[ :as ]}();\"\n        @other_setup << \"\\t_#{opts[ :as ]}.start();\" if opts[:rtcstart]\n    end\n  end\n  \n  private\n  \n  def serial_boilerplate #:nodoc:\n\n    out = <<-STR\n        int serial_available() {\n          return (Serial.available() > 0);\n        }\n        \n        char serial_read() {\n          return (char) Serial.read();\n        }\n        \n        void serial_flush() {\n          return Serial.flush();\n        }\n\n        void serial_print( char str ) {\n          return Serial.print( str );\n        }\n\n        void serial_print( char* str ) {\n          return Serial.print( str );\n        }\n\n        void serial_print( int i ) {\n          return Serial.print( i );\n        }\n\n        void serial_print( long i ) {\n          return Serial.print( i );\n        }\n\n      \tvoid serial_println( char* str ) {\n          return Serial.println( str );\n        }\n\n        void serial_println( char str ) {\n          return Serial.println( str );\n        }\n\n      \tvoid serial_println( int i ) {\n          return Serial.println( i );\n        }\n\n        void serial_println( long i ) {\n          return Serial.println( i );\n        }\n\n        void serial_print( unsigned long i ) {\n          return Serial.print( i );\n        }\n  STR\n\n    return out\n  end\n  \nend"
  },
  {
    "path": "lib/rad/init.rb",
    "content": "RAD_ROOT = \"#{File.dirname(__FILE__)}/../..\" unless defined?(RAD_ROOT)\n\nunless defined?(PROJECT_DIR_NAME)\n  a = File.expand_path(File.expand_path(\"#{RAD_ROOT}\")).split(\"/\")\n  PROJECT_DIR_NAME = a[a.length-1]\nend\n\nPLUGIN_C_VAR_TYPES = \"int|void|unsigned|long|short|uint8_t|static|byte|char\\\\*|uint8_t\"\n\ngem \"ParseTree\", \"=2.2\"\n\n%w(generators/makefile/makefile.rb rad_processor.rb rad_rewriter.rb rad_type_checker.rb variable_processing.rb arduino_sketch.rb arduino_plugin.rb hardware_library.rb tasks/rad.rb sketch_compiler.rb).each do |path|\n  require File.expand_path(\"#{RAD_ROOT}/vendor/rad/#{path}\")\nend\n\n"
  },
  {
    "path": "lib/rad/linux_installer.rb",
    "content": "class LinuxInstaller\n  \n  # this is the thing we actually run to make something happen\n  def self.install!\n    puts \"Welcome to the RAD Linux Installer!\"\n    puts \"-----------------------------------\"\n    puts \"Let's begin.\"\n    puts\n    \n    check_or_warn_for_usb_driver\n    \n    # of course we need rubygems\n    # maybe just rely on the user installing rubygems, because the ubuntu one sux\n    #check_or_install_package(\"rubygems\")\n    #%x{gem update --system}\n    \n    # we need java to make this ship float\n    check_or_nag_package(\"sun-java5-jre\")\n    \n    # remove a package that interferes with the arduino usb/serial driver\n    check_or_remove_package(\"brltty\")\n    \n    # install pre-requisites\n    check_or_install_package(\"binutils-avr\")\n    check_or_install_package(\"gcc-avr\")\n    check_or_install_package(\"avr-libc\")\n    check_or_install_package(\"unzip\")\n    check_or_install_package(\"wget\")\n    \n    # remove a probably out of date avrdude\n    check_or_remove_package(\"avrdude\")\n    \n    # install pre-requisites for avrdude if we wanted to build from source\n    # nah, it comes with the arduino binary\n    #check_or_install_package(\"gcc\")\n    #check_or_install_package(\"bison\")\n    #check_or_install_package(\"flex\")\n    check_or_install_arduino\n  end\n  \n  def self.check_or_install_package(package_name)\n  \tpackage = %x{dpkg --get-selections | grep #{package_name}}\n  \tif package.include?(\"\\tinstall\")\n  \t\tputs \"#{package_name} installed!\"\n  \telse\n  \t\tputs \"installing #{package_name}...\"\n  \t\t%x{apt-get install -y #{package_name}}\n  \tend\n  end\n  \n  def self.check_or_nag_package(package_name, custom_msg = nil)\n  \tpackage = %x{dpkg --get-selections | grep #{package_name}}\n  \tif package.include?(\"\\tinstall\")\n  \t\tputs \"#{package_name} installed!\"\n  \telse\n  \t\tputs \"you will need to manually install #{package_name}! use the command below.\"\n  \t\tif custom_msg\n  \t\t\tputs custom_msg\n  \t\telse\n  \t\t\tputs \"sudo apt-get install #{package_name}\"\n  \t\tend\t\t\n  \t\texit\n  \tend\n  end\n  \n  def self.check_or_remove_package(package_name)\n  \tpackage = %x{dpkg --get-selections | grep #{package_name}}\n  \n  \t#an easier way to check for installed packages?\n  \tif package.include?(\"\\tinstall\")\n  \t\tputs \"removing #{package_name}...\"\n  \t\t%x{apt-get remove -y #{package_name}}\n  \telse\n  \t\tputs \"#{package_name} previously uninstalled!\"\n  \tend\n  end\n  \n  def self.check_or_warn_for_usb_driver\n  \n  \t# check if usb device recognized by system\n  \tputs \"Please plug in your arduino to your usb port... [hit enter to continue]\"\n  \tSTDIN.gets # we patiently wait\n  \n  \tusb = %x{dmesg | tail | grep \"FTDI USB Serial\" | grep -c \"now attached\"}\n  \n  \tif usb.to_i == 0\n  \t\t# maybe we can be nice here and offer to download and install the driver package\n  \t\tputs \"the system is not recognizing your usb-serial driver, please re-install\"\n  \t\texit\n  \tend\n  end\n  \n  def self.check_or_install_arduino \n  \tif File.exist?(\"/usr/local/arduino-0012\")\n  \t\tputs \"arduino software previously installed at /usr/local/arduino-0012 !\"\n  \telse\n  \t\tputs \"installing arduino software...\"\n  \t\t%x{cd /usr/local/; wget http://arduino.cc/files/arduino-0012-linux.tgz}\n  \t\t%x{tar -C /usr/local -xzf /usr/local/arduino-0012-linux.tgz}\n  \n  \t\t%x{ln -s /usr/local/arduino-0012/arduino ~/Desktop/arduino}\n  \n  \t\t# gotta patch it so it can run from command line or anywhere\n  \t\tarduino_file = File.open(\"/usr/local/arduino-0012/arduino\") {|f| f.read}\n  \t\tnew_doc = arduino_file.split(\"\\n\")\n  \t\tnew_doc[1] = \"cd /usr/local/arduino-0012\"\n  \t\tFile.open(\"/usr/local/arduino-0012/arduino\", \"w\") {|f| f.puts new_doc }\n  \n  \t\t%x{mkdir -p /usr/local/arduino-0012/hardware/tools/avr/bin}\n  \t\t# there is a difference from what the makefile expects to where it is\n  \t\t%x{ln -s /usr/bin/avr-gcc /usr/local/arduino-0012/hardware/tools/avr/bin/avr-gcc}\t\t\n  \t\t%x{ln -s /usr/bin/avr-g++ /usr/local/arduino-0012/hardware/tools/avr/bin/avr-g++}\n  \t\t%x{ln -s /usr/bin/avr-ar /usr/local/arduino-0012/hardware/tools/avr/bin/avr-ar}\n  \t\t%x{ln -s /usr/bin/avr-objcopy /usr/local/arduino-0012/hardware/tools/avr/bin/avr-objcopy}\n  \t\t%x{ln -s /usr/local/arduino-0012/hardware/tools/avrdude /usr/local/arduino-0012/hardware/tools/avr/bin/avrdude}\n  \t\t%x{ln -s /usr/local/arduino-0012/hardware/tools/avrdude.conf /usr/local/arduino-0012/hardware/tools/avr/etc/avrdude.conf}\n  \n  \n  \t\tputs\n  \t\tputs \"************************************************************************\"\n  \t\tputs \"**  please add /usr/local/arduino-0012 to your path!                  **\"\n  \t\tputs \"**  you will also need to run sudo update-alternatives --config java  **\"\n  \t\tputs \"**  to choose java-1.50-sun as the default java                       **\"\n  \t\tputs \"************************************************************************\"\n  \t\tputs\n  \tend\n  \t\n  end\nend\n\n\n\n"
  },
  {
    "path": "lib/rad/progressbar.rb",
    "content": "#\n# Ruby/ProgressBar - a text progress bar library\n#\n# Copyright (C) 2001-2005 Satoru Takabayashi <satoru@namazu.org>\n#     All rights reserved.\n#     This is free software with ABSOLUTELY NO WARRANTY.\n#\n# You can redistribute it and/or modify it under the terms\n# of Ruby's license.\n#\n\nclass ProgressBar\n  VERSION = \"0.9\"\n\n  def initialize (title, total, out = STDERR)\n    @title = title\n    @total = total\n    @out = out\n    @terminal_width = 80\n    @bar_mark = \"o\"\n    @current = 0\n    @previous = 0\n    @finished_p = false\n    @start_time = Time.now\n    @previous_time = @start_time\n    @title_width = 14\n    @format = \"%-#{@title_width}s %3d%% %s %s\"\n    @format_arguments = [:title, :percentage, :bar, :stat]\n    clear\n    show\n  end\n  attr_reader   :title\n  attr_reader   :current\n  attr_reader   :total\n  attr_accessor :start_time\n\n  private\n  def fmt_bar\n    bar_width = do_percentage * @terminal_width / 100\n    sprintf(\"|%s%s|\", \n            @bar_mark * bar_width, \n            \" \" *  (@terminal_width - bar_width))\n  end\n\n  def fmt_percentage\n    do_percentage\n  end\n\n  def fmt_stat\n    if @finished_p then elapsed else eta end\n  end\n\n  def fmt_stat_for_file_transfer\n    if @finished_p then \n      sprintf(\"%s %s %s\", bytes, transfer_rate, elapsed)\n    else \n      sprintf(\"%s %s %s\", bytes, transfer_rate, eta)\n    end\n  end\n\n  def fmt_title\n    @title[0,(@title_width - 1)] + \":\"\n  end\n\n  def convert_bytes (bytes)\n    if bytes < 1024\n      sprintf(\"%6dB\", bytes)\n    elsif bytes < 1024 * 1000 # 1000kb\n      sprintf(\"%5.1fKB\", bytes.to_f / 1024)\n    elsif bytes < 1024 * 1024 * 1000  # 1000mb\n      sprintf(\"%5.1fMB\", bytes.to_f / 1024 / 1024)\n    else\n      sprintf(\"%5.1fGB\", bytes.to_f / 1024 / 1024 / 1024)\n    end\n  end\n\n  def transfer_rate\n    bytes_per_second = @current.to_f / (Time.now - @start_time)\n    sprintf(\"%s/s\", convert_bytes(bytes_per_second))\n  end\n\n  def bytes\n    convert_bytes(@current)\n  end\n\n  def format_time (t)\n    t = t.to_i\n    sec = t % 60\n    min  = (t / 60) % 60\n    hour = t / 3600\n    sprintf(\"%02d:%02d:%02d\", hour, min, sec);\n  end\n\n  # ETA stands for Estimated Time of Arrival.\n  def eta\n    if @current == 0\n      \"ETA:  --:--:--\"\n    else\n      elapsed = Time.now - @start_time\n      eta = elapsed * @total / @current - elapsed;\n      sprintf(\"ETA:  %s\", format_time(eta))\n    end\n  end\n\n  def elapsed\n    elapsed = Time.now - @start_time\n    sprintf(\"Time: %s\", format_time(elapsed))\n  end\n  \n  def eol\n    if @finished_p then \"\\n\" else \"\\r\" end\n  end\n\n  def do_percentage\n    if @total.zero?\n      100\n    else\n      @current  * 100 / @total\n    end\n  end\n\n  def get_width\n    # FIXME: I don't know how portable it is.\n    default_width = 80\n    begin\n      tiocgwinsz = 0x5413\n      data = [0, 0, 0, 0].pack(\"SSSS\")\n      if @out.ioctl(tiocgwinsz, data) >= 0 then\n        rows, cols, xpixels, ypixels = data.unpack(\"SSSS\")\n        if cols >= 0 then cols else default_width end\n      else\n        default_width\n      end\n    rescue Exception\n      default_width\n    end\n  end\n\n  def show\n    arguments = @format_arguments.map {|method| \n      method = sprintf(\"fmt_%s\", method)\n      send(method)\n    }\n    line = sprintf(@format, *arguments)\n\n    width = get_width\n    if line.length == width - 1 \n      @out.print(line + eol)\n      @out.flush\n    elsif line.length >= width\n      @terminal_width = [@terminal_width - (line.length - width + 1), 0].max\n      if @terminal_width == 0 then @out.print(line + eol) else show end\n    else # line.length < width - 1\n      @terminal_width += width - line.length + 1\n      show\n    end\n    @previous_time = Time.now\n  end\n\n  def show_if_needed\n    if @total.zero?\n      cur_percentage = 100\n      prev_percentage = 0\n    else\n      cur_percentage  = (@current  * 100 / @total).to_i\n      prev_percentage = (@previous * 100 / @total).to_i\n    end\n\n    # Use \"!=\" instead of \">\" to support negative changes\n    if cur_percentage != prev_percentage || \n        Time.now - @previous_time >= 1 || @finished_p\n      show\n    end\n  end\n\n  public\n  def clear\n    @out.print \"\\r\"\n    @out.print(\" \" * (get_width - 1))\n    @out.print \"\\r\"\n  end\n\n  def finish\n    @current = @total\n    @finished_p = true\n    show\n  end\n\n  def finished?\n    @finished_p\n  end\n\n  def file_transfer_mode\n    @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]\n  end\n\n  def format= (format)\n    @format = format\n  end\n\n  def format_arguments= (arguments)\n    @format_arguments = arguments\n  end\n\n  def halt\n    @finished_p = true\n    show\n  end\n\n  def inc (step = 1)\n    @current += step\n    @current = @total if @current > @total\n    show_if_needed\n    @previous = @current\n  end\n\n  def set (count)\n    if count < 0 || count > @total\n      raise \"invalid count: #{count} (total: #{@total})\"\n    end\n    @current = count\n    show_if_needed\n    @previous = @current\n  end\n\n  def inspect\n    \"#<ProgressBar:#{@current}/#{@total}>\"\n  end\nend\n\nclass ReversedProgressBar < ProgressBar\n  def do_percentage\n    100 - super\n  end\nend\n\n"
  },
  {
    "path": "lib/rad/rad_processor.rb",
    "content": "require 'rubygems'\nrequire 'ruby_to_ansi_c'\n\nclass RADProcessor < RubyToAnsiC\n\n  def self.translator\n    unless defined? @translator then\n      @translator = CompositeSexpProcessor.new\n      @translator << RADRewriter.new\n      @translator << RADTypeChecker.new\n      @translator << R2CRewriter.new\n      @translator << self.new\n      @translator.on_error_in(:defn) do |processor, exp, err|\n        result = processor.expected.new\n        case result\n        when Array then\n          result << :error\n        end\n        msg = \"// ERROR: #{err.class}: #{err}\"\n        msg += \" in #{exp.inspect}\" unless exp.nil? or $TESTING\n        msg += \" from #{caller.join(', ')}\" unless $TESTING\n        result << msg\n        result\n      end\n    end\n    @translator\n  end\n  \n  def process_iasgn(exp)\n    name = exp.shift\n    val = process exp.shift\n    \"__#{name.to_s.sub(/^@/, '')} = #{val}\"\n  end\n  \n  def process_ivar(exp)\n    name = exp.shift\n    \"__#{name.to_s.sub(/^@/, '')}\"\n  end\n  \n  def process_iter(exp)\n    # the array identifer may be in one of two locations\n    # when using the instance variable (ivar) style it is located at exp[0][1][1]\n    if exp[0][1][1]\n      enum = exp[0][1][1]\n      enum = \"__#{enum.to_s.sub(/^@/, '')}\" if enum.to_s =~ /^@/\n    # for local variables it is located at exp[0][1][2]  \n    elsif exp[0][1][2]\n      enum = exp[0][1][2]\n    end\n    \n    out = []\n    # Only support enums in C-land # not sure if this comment if valid anymore\n    raise UnsupportedNodeError if exp[0][1].nil? # HACK ugly\n    @env.scope do\n      \n      call = process exp.shift\n      var  = process(exp.shift).intern # semi-HACK-y \n      body = process exp.shift\n      \n      # array types from varible_processing>post_process_arrays and arduino_sketch>array\n      $array_types.each do |k,v|\n            @array_type = v if k == enum.to_s.sub(/^__/,\"\")\n      end\n      \n      index_helper = $array_index_helpers.shift\n      index = \"index_#{index_helper}\" # solves redeclaration issue\n\n      body += \";\" unless body =~ /[;}]\\Z/\n      body.gsub!(/\\n\\n+/, \"\\n\")\n\n      out << \"unsigned int #{index};\" # shouldn't need more than int\n      out << \"for (#{index} = 0; #{index} < (int) (sizeof(#{enum}) / sizeof(#{enum}[0])); #{index}++) {\"   \n      out << \"#{@array_type} #{var} = #{enum}[#{index}];\"\n      out << body\n      out << \"}\"\n    end\n\n    return out.join(\"\\n\")\n  end\n    \n  def process_lasgn(exp)\n    out = \"\"\n\n    var = exp.shift\n    value = exp.shift\n    # grab the size of the args, if any, before process converts to a string\n    arg_count = 0\n    arg_count = value.length - 1 if value.first == :array\n    args = value\n\n    exp_type = exp.sexp_type\n    @env.add var.to_sym, exp_type\n    var_type = self.class.c_type exp_type\n\n    if exp_type.list? then\n      assert_type args, :array\n\n      raise \"array must be of one type\" unless args.sexp_type == Type.homo\n\n      # HACK: until we figure out properly what to do w/ zarray\n      # before we know what its type is, we will default to long.\n      array_type = args.sexp_types.empty? ? 'void *' : self.class.c_type(args.sexp_types.first)\n      # we can fix array here..\n      args.shift # :arglist\n      out << \"#{var} = (#{array_type}) malloc(sizeof(#{array_type}) * #{args.length});\\n\"\n      args.each_with_index do |o,i|\n        out << \"#{var}[#{i}] = #{process o};\\n\"\n      end\n    else\n      out << \"#{var} = #{process args}\"\n    end\n\n    out.sub!(/;\\n\\Z/, '')\n\n    return out\n  end\n  \n  def process_str(exp)\n    s = exp.shift.gsub(/\\n/, '\\\\n')\n    if s.size == 1\n      return \"\\'#{s}\\'\"\n    else\n      return \"\\\"#{s}\\\"\"\n    end\n  end\n\n\nend"
  },
  {
    "path": "lib/rad/rad_rewriter.rb",
    "content": "require 'ruby_to_ansi_c'\n\nclass RADRewriter < Rewriter\n  \n  def process_iter(exp)\n    call = process exp.shift\n    var  = process exp.shift\n    body = process exp.shift\n\n    var = s(:dasgn_curr, Unique.next) if var.nil?\n\n    assert_type call, :call\n\n    if call[2] != :each then # TODO: fix call[n] (api)\n      call.shift # :call\n      lhs = call.shift\n      method_name = call.shift\n\n      case method_name\n      when :downto then\n        var.shift # \n        start_value = lhs\n        finish_value = call.pop.pop # not sure about this\n        var_name = var.shift\n        body.find_and_replace_all(:dvar, :lvar)\n        result = s(:dummy,\n                   s(:lasgn, var_name, start_value),\n                   s(:while,\n                     s(:call, s(:lvar, var_name), :>=,\n                       s(:arglist, finish_value)),\n                     s(:block,\n                       body,\n                       s(:lasgn, var_name,\n                         s(:call, s(:lvar, var_name), :-,\n                           s(:arglist, s(:lit, 1))))), true))\n      when :upto then\n        # REFACTOR: completely duped from above and direction changed\n        var.shift # \n        start_value = lhs\n        finish_value = call.pop.pop # not sure about this\n        var_name = var.shift\n        body.find_and_replace_all(:dvar, :lvar)\n        result = s(:dummy,\n                   s(:lasgn, var_name, start_value),\n                   s(:while,\n                     s(:call, s(:lvar, var_name), :<=,\n                       s(:arglist, finish_value)),\n                     s(:block,\n                       body,\n                       s(:lasgn, var_name,\n                         s(:call, s(:lvar, var_name), :+,\n                           s(:arglist, s(:lit, 1))))), true))\n       when :times then\n         # REFACTOR: mostly duped from above and gave default start value of 0\n         # and a finish value that was the start value above\n         var.shift \n         start_value = s(:lit, 0)\n         finish_value = lhs\n         var_name = var.shift\n         body.find_and_replace_all(:dvar, :lvar)\n         result = s(:dummy,\n                    s(:lasgn, var_name, start_value),\n                    s(:while,\n                      s(:call, s(:lvar, var_name), :<,\n                        s(:arglist, finish_value)),\n                      s(:block,\n                        body,\n                        s(:lasgn, var_name,\n                          s(:call, s(:lvar, var_name), :+,\n                            s(:arglist, s(:lit, 1))))), true))\n      when :define_method then\n        # BEFORE: [:iter, [:call, nil, :define_method, [:array, [:lit, :bmethod_added]]], [:dasgn_curr, :x], [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]\n        # we want to get it rewritten for the scope/block context, so:\n        #   - throw call away\n        #   - rewrite to args\n        #   - plop body into a scope\n        # AFTER:  [:block, [:args, :x], [:call, [:lvar, :x], :+, [:arglist, [:lit, 1]]]]\n        var.find_and_replace_all(:dasgn_curr, :args)\n        body.find_and_replace_all(:dvar, :lvar)\n        result = s(:block, var, body)\n      else\n        # HACK we butchered call up top\n        result = s(:iter, s(:call, lhs, method_name, call.shift), var, body)\n      end\n    else\n      if var.nil? then\n        var = s(:lvar, Unique.next)\n      end\n\n      s(:iter, call, var, body)\n    end\n  end\n\nend"
  },
  {
    "path": "lib/rad/rad_type_checker.rb",
    "content": "require 'ruby_to_ansi_c'\n\nclass RADTypeChecker < TypeChecker\n  \n  def process_const(exp)\n    c = exp.shift\n    if c.to_s =~ /^[A-Z]/ then\n      # TODO: validate that it really is a const? \n      # uber hackery\n      # since constants are defined in the arduino_sketch define method and \n      # we can't inject them into the methods \n      # transport them here with a $define_types hash\n\n      $define_types.each do |k,v|\n        if k == c.to_s\n          @const_type = eval \"Type.#{v}\"\n        end\n      end\n      return t(:const, c, @const_type)\n    else\n      raise \"I don't know what to do with const #{c.inspect}. It doesn't look like a class.\"\n    end\n    raise \"need to finish process_const in #{self.class}\"\n  end\n  \nend"
  },
  {
    "path": "lib/rad/sim/arduino_sketch.rb",
    "content": "ON = true\nOFF = !ON\nHIGH = ON\nLOW = !HIGH\n\nclass ArduinoSketch\n  attr_accessor :pins  \n   \n  def initialize\n    @pins = self.class.instance_variable_get(\"@pins\")\n  end\n  \n  def self.output_pin(num, opts)\n    module_eval \"@pins ||= []\"\n    module_eval do \n      @pins <<  Pin.new( num, :type => :output )\n    end\n\n    if opts[:as]\n       module_eval <<-CODE\n         def #{opts[:as]}\n           pins.select{|p| p.num == #{num}}.first\n         end\n       CODE\n     end\n  end\n\n  def loop    \n  end\n  \n  def digitalWrite( pin, value )\n    to_change = pins.select{|p| p.num == pin.num}.first\n    to_change.value = value\n  end\n\n  def delay( millis )\n  end\n  \n  # def serial_read\n  # end\n\n  # def serial_available\n  # end\n\n  # def blink\n  # end\nend\n\nclass Pin\n  attr_accessor :num, :type, :value\n\n  def initialize num, opts\n    @num = num\n    @type = opts[:type]\n    @value = opts[:value] || false\n  end\nend\n"
  },
  {
    "path": "lib/rad/sketch_compiler.rb",
    "content": "# TODO:\n#   compilation\n#   gather pieces of code we need as strings\n#   translate non-loop methods\n#   do plugin stuff\n#   deal with examples/ exception\n#   manage upload process\n#   compose_setup should move in here entirely\n\n# require 'arduino_sketch'\n\nclass SketchCompiler\n  attr_accessor :path, :body, :klass, :target_dir, :name\n  \n  def initialize path_to_sketch \n    @path = File.expand_path(path_to_sketch)\n    @body = open(@path).read\n    @name = @path.split(\"/\").last.split(\".\").first\n    @klass = @name.split(\".\").first.split(\"_\").collect{|c| c.capitalize}.join(\"\")     \n    @target_dir = parent_dir\n  end\n  \n  def parent_dir\n    self.path.split(\"/\")[0..@path.split(\"/\").length-2].join(\"/\")\n  end\n  \n  def build_dir\n    \"#{self.target_dir}/#{self.name}\"\n  end\n\n  def create_build_dir! optional_path_prefix=nil\n    self.target_dir = optional_path_prefix if optional_path_prefix\n    mkdir_p build_dir\n  end\n  \n  def process_constants\n    self.body.gsub!(\"HIGH\", \"1\")\n    self.body.gsub!(\"LOW\", \"0\")\n    self.body.gsub!(\"ON\", \"1\")\n    self.body.gsub!(\"OFF\", \"0\")\n  end\n  \n  def sketch_methods\n    self.body.scan(/^\\s*def\\s.\\w*/).collect{ |m| m.gsub(/\\s*def\\s*/, \"\") }\n  end\n  \nend"
  },
  {
    "path": "lib/rad/tasks/build_and_make.rake",
    "content": "require File.expand_path(File.dirname(__FILE__) + \"/../init.rb\")\nrequire 'ruby_to_ansi_c'\n\nC_VAR_TYPES = \"unsigned|int|long|double|str|char|byte|bool\"\n\n# incredibly primitive tests \n# rake test:compile or rake test:upload\n# runs through all sketches in the example directory\n\ndef run_tests(sketch, type)\n  sh %{rake make:#{type} sketch=examples/#{sketch}}\nend\n\nnamespace :test do\n  \n  desc \"iterate through all the sketches in the example directory\"\n  task :upload => :gather do \n    @examples.each {|e| run_tests(e, \"upload\")}\n  end\n  \n  task :compile => :gather do \n\n    @examples.each {|e| run_tests(e, \"compile\")}\n  end\n  \n  desc \"gather all tests\"\n  task :gather do # => \"make:upload\" do\n    @examples = []\n    if ENV['sketch']\n      @examples << ENV['sketch']\n    else\n      Dir.entries( File.expand_path(\"#{RAD_ROOT}/examples/\") ).each do |f|\n        @examples << f.split('.').first if (f =~ /\\.rb$/)\n      end\n    end\n  end\n\nend\n\n\nnamespace :make do\n  \n  desc \"compile the sketch and then upload it to your Arduino board\"\n  task :upload => :compile do\n    if Makefile.hardware_params['physical_reset']\n      puts \"Reset the Arduino and hit enter.\\n==If your board doesn't need it, you can turn off this prompt in config/software.yml==\"\n      STDIN.gets.chomp\n    end\n    sh %{cd #{@sketch.build_dir}; make upload}\n  end\n    \n  desc \"generate a makefile and use it to compile the .cpp\"\n  task :compile => [:clean_sketch_dir, \"build:sketch\"] do # should also depend on \"build:sketch\"\n    Makefile.compose_for_sketch( @sketch.build_dir )\n\n    # not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}\n    sh %{cd #{@sketch.build_dir}; make depend; make}\n  end\n  \n  desc \"generate a makefile and use it to compile the .cpp using the current .cpp file\"\n  task :compile_cpp => [\"build:sketch_dir\", \"build:gather_required_plugins\", \"build:plugin_setup\", \"build:setup\", :clean_sketch_dir] do # should also depend on \"build:sketch\"\n    Makefile.compose_for_sketch( @sketch.build_dir )\n    # not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}\n    sh %{cd #{@sketch.build_dir}; make depend; make}\n  end\n  \n  desc \"generate a makefile and use it to compile the .cpp and upload it using current .cpp file\"\n  task :upload_cpp => [\"build:sketch_dir\", \"build:gather_required_plugins\", \"build:plugin_setup\", \"build:setup\", :clean_sketch_dir] do # should also depend on \"build:sketch\"\n    Makefile.compose_for_sketch( @sketch.build_dir )\n    # not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}\n    sh %{cd #{@sketch.build_dir}; make depend; make upload}\n  end\n  \n  task :clean_sketch_dir => [\"build:file_list\", \"build:sketch_dir\"] do\n    FileList.new(Dir.entries(\"#{@sketch.build_dir}\")).exclude(\"#{@sketch.name}.cpp\").exclude(/^\\./).each do |f|\n      sh %{rm #{@sketch.build_dir}/#{f}}\n    end\n  end\n  \nend\n\nnamespace :build do\n\n  desc \"actually build the sketch\"\n  task :sketch => [:file_list, :sketch_dir, :gather_required_plugins, :plugin_setup, :setup] do\n    c_methods = []\n    sketch_signatures = []\n    # until we better understand RubyToC let's see what's happening on errors\n    @sketch.sketch_methods.each do |meth|   \n      raw_rtc_meth = RADProcessor.translate(constantize(@sketch.klass), meth)\n      puts \"Translator Error: #{raw_rtc_meth.inspect}\" if raw_rtc_meth =~ /\\/\\/ ERROR:/ \n      c_methods << raw_rtc_meth unless meth == \"setup\"\n      # treat the setup method differently\n      @additional_setup = [] if meth == \"setup\"\n      raw_rtc_meth.each {|m| @additional_setup << ArduinoSketch.add_to_setup(m) } if meth == \"setup\"\n    end\n    c_methods.each {|meth| sketch_signatures << \"#{meth.scan(/^\\w*\\s?\\*?\\n.*\\)/)[0].gsub(\"\\n\", \" \")};\" }\n    clean_c_methods = []\n    # remove external variables that were previously injected\n    c_methods.join(\"\\n\").each { |meth| clean_c_methods << ArduinoSketch.post_process_ruby_to_c_methods(meth) }\n    c_methods_with_timer = clean_c_methods.join.gsub(/loop\\(\\)\\s\\{/,\"loop() {\")\n    # last chance to add/change setup\n    @setup[2] << sketch_signatures.join(\"\\n\") unless sketch_signatures.empty?\n    # add special setup method to existing setup if present\n    if @additional_setup\n      @setup[2] << \"void additional_setup();\" # declaration\n      @setup[4] << \"\\tadditional_setup();\" # call from setup \n      @setup[5] << @additional_setup.join(\"\") # \n    end\n    result = \"#{@setup.join( \"\\n\" )}\\n#{c_methods_with_timer}\\n\"\n    File.open(\"#{@sketch.build_dir}/#{@sketch.name}.cpp\", \"w\"){|f| f << result}\n  end\n\n  # needs to write the library include and the method signatures\n  desc \"build setup function\"\n  task :setup do\n    eval \"class #{@sketch.klass} < ArduinoSketch; end;\"\n    \n    @@as = HardwareLibrary.new\n    \n    delegate_methods = @@as.methods - Object.new.methods\n    delegate_methods.reject!{|m| m == \"compose_setup\"}\n        \n    delegate_methods.each do |meth|\n       constantize(@sketch.klass).module_eval <<-CODE\n       def self.#{meth}(*args)\n       @@as.#{meth}(*args)\n       end\n       CODE\n    end\n    # allow variable declaration without quotes: @foo = int \n    [\"long\",\"unsigned\",\"int\",\"byte\",\"short\"].each do |type|\n      constantize(@sketch.klass).module_eval <<-CODE\n       def self.#{type}\n        return \"#{type}\"\n       end\n       CODE\n    end   \n    \n    @sketch.process_constants\n    \n    eval ArduinoSketch.pre_process(@sketch.body)\n    @@as.process_external_vars(constantize(@sketch.klass))\n    @setup = @@as.compose_setup\n  end\n  \n  desc \"add plugin methods\"\n  task :plugin_setup do\n    $plugins_to_load.each do |name|\n       klass = name.split(\".\").first.split(\"_\").collect{|c| c.capitalize}.join(\"\")\n       eval \"class #{klass} < ArduinoPlugin; end;\"\n    \n       @@ps = ArduinoPlugin.new\n       plugin_delegate_methods = @@ps.methods - Object.new.methods\n       plugin_delegate_methods.reject!{|m| m == \"compose_setup\"}\n    \n       plugin_delegate_methods.each do |meth|\n         constantize(klass).module_eval <<-CODE\n         def self.#{meth}(*args)\n           @@ps.#{meth}(*args)\n         end\n         CODE\n       end\n\n      eval ArduinoPlugin.process(File.read(\"vendor/plugins/#{name}\"))\n      \n    end\n    @@no_plugins = ArduinoPlugin.new if @plugin_names.empty?\n  end\n  \n  desc \"determine which plugins to load based on use of methods in sketch\"\n  task :gather_required_plugins do\n    @plugin_names.each do |name|\n       ArduinoPlugin.check_for_plugin_use(@sketch.body, File.read(\"vendor/plugins/#{name}\"), name )\n    end\n    puts \"#{$plugins_to_load.length} of #{$plugin_methods_hash.length} plugins are being loaded:  #{$plugins_to_load.join(\", \")}\"\n  end\n  \n  desc \"setup target directory named after your sketch class\"\n  task :sketch_dir => [:file_list] do\n    @sketch.create_build_dir!\n  end\n\n  task :file_list do\n    # take another look at this, since if the root directory name is changed, everything breaks\n    # perhaps we generate a constant when the project is generated an pop it here or in the init file\n    if ENV['sketch']\n      @sketch = SketchCompiler.new File.expand_path(\"#{ENV['sketch']}.rb\")\n    else\n      # assume the only .rb file in the sketch dir is the sketch:\n      @sketch = SketchCompiler.new Dir.glob(\"#{File.expand_path(File.dirname(__FILE__))}/../../../*.rb\").first\n    end\n\n    @plugin_names = []\n    Dir.entries( File.expand_path(\"#{RAD_ROOT}/vendor/plugins/\") ).each do |f|\n      if (f =~ /\\.rb$/)\n        @plugin_names << f\n      end\n    end\n  end\nend\n\n#yoinked from Rails\ndef constantize(camel_cased_word)\n  unless /\\A(?:::)?([A-Z]\\w*(?:::[A-Z]\\w*)*)\\z/ =~ camel_cased_word\n    raise NameError, \"#{camel_cased_word.inspect} is not a valid constant name!\"\n  end\n\n  Object.module_eval(\"::#{$1}\", __FILE__, __LINE__)\nend"
  },
  {
    "path": "lib/rad/tasks/rad.rb",
    "content": "require 'rake'\nDir[\"#{File.dirname(__FILE__)}/*.rake\"].each { |ext| load ext }"
  },
  {
    "path": "lib/rad/todo.txt",
    "content": "TODO:\n=====\n\t\nFuture:\n\t- complete library system: script/install library some_library\n\t- bin/rad:\n\t\t- setup and use a ~/.rad for new project defaults\n\t- put repository on git\n\t- project gallery (examples with movies)\n\t- testing framework\n\t- implement wire lib\n\t- subclasses of ArduinoSketch (should just work, but what are they for?)\n\t- simulator"
  },
  {
    "path": "lib/rad/variable_processing.rb",
    "content": "module ExternalVariableProcessing\n  # issues \n  # testing \n  # add checking for colon\n\n    \n    ## need to clean this up\n    ## need to test \n    def process_external_vars(klass)\n      vars = eval \"#{klass}.instance_variables\"\n      local_vars = []\n      vars.each { |v| local_vars << \":#{v.gsub(\"@\", \"\")}\" }\n      loc_vars = local_vars.join(\", \")\n      # add accessors \n      klass.module_eval \"class << self; attr_accessor #{loc_vars} end\"\n      local_vars.each do |symbol|\n        name = symbol.gsub(\":\",\"\")\n        t_var = eval \"#{klass}.#{name}\"\n        pre_process_vars(name, t_var)\n      end\n    end\n    \n    \n    def pre_process_vars(name, var)\n        # puts \n        # puts\n        case var\n        when Integer\n          # puts \"pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} 29\"\n          value = var\n          type = \"int\"\n          post_process_vars(name, type, value)\n        when Float\n          # puts \"pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} 34\"\n          value = var\n          type = \"float\"\n          post_process_vars(name, type, value)\n        when String\n          # puts \"pre_process: #{name}, #{var.inspect} got #{var.class} on 39\"\n          if var.match(\",\").nil? && var =~ /long|byte|unsigned|int|short/\n            # puts \"pre_process #{name}, #{var.inspect} got #{var.class} level three sublevel\"\n            type = var\n            value = nil\n            post_process_vars(name, type, value)\n          else\n            value = var.split(\",\").first.lstrip\n            type = var.split(\",\")[1].nil? ?  nil : var.split(\",\")[1].lstrip\n            translate_variables( name , type, value )\n          end\n        when TrueClass\n          # puts \"pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} on 50\"\n          value = 1\n          type = \"bool\"\n          post_process_vars(name, type, value)\n        when FalseClass\n          # puts \"pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} on 55\"\n          value = 0\n          type = \"bool\"\n          post_process_vars(name, type, value)\n        when Array\n          post_process_arrays(name, var)\n        else\n          raise ArgumentError, \"not sure what to do here...  got #{name} with value #{var} which is a #{var.class}\" \n        end      \n    end     \n    \n    \n    def translate_variables(name, type = nil, value = nil)\n      \n      unless type.nil?\n        check_variable_type(type)\n      end\n\n      # classify the values\n      if value.class == Fixnum \n        # puts \"translate_variables: #{name}, #{value}, #{type} is a fixnum, got #{value.class} on 74\"\n      elsif value.class == Float \n        # puts \"translate_variables: #{name}, #{value}, #{type} is a float, got #{value.class} on 76\"\n      elsif value =~ /^-(\\d|x)*$/ \n        value = value.to_i\n        type = \"int\" if type.nil?\n      elsif value =~ /^-(\\d|\\.|x)*$/ \n        value = value.to_f\n        unless type.nil?\n          raise ArgumentError, \"#{value} should be a float got  #{type}\" unless type == \"float\"\n        end\n        type = \"float\" if type.nil?   \n\n      elsif value[0,1] !~ /\\d/\n        # puts value[0,1]\n        # puts \"translate_variables: #{name}, #{value}, #{type} is a number of some type, got #{value.class} on 79\"\n        type = \"char*\"\n        value = \"\\\"#{value}\\\"\"\n      elsif value !~ /(\\.|x)/\n        # puts \"translate_variables: #{name}, #{value}, #{type} is an integer, got #{value.class} on 83\"\n        value = value.to_i\n        type = \"int\" if type.nil?\n      elsif value =~ /(\\d*\\.\\d*)/ # and no \n        # puts \"translate_variables: #{name}, #{value}, #{type} is a float, got #{value.class} on 87\"\n        value = value.to_f\n        type = \"float\"\n      elsif value =~ /0x\\d\\d/\n        # puts \"translate_variables: #{name}, #{value}, #{type} is a byte, got #{value.class} on 91\"\n        type = \"byte\"\n      else\n        raise ArgumentError, \"not sure what to do with a value of #{value} with a type like #{type}\" \n      end\n     \n      post_process_vars(name, type, value)\n    end\n    \n\n    \n    def post_process_vars(name, type, value = nil)\n      value = \" = #{value}\" if value \n      $external_var_identifiers << \"__#{name}\" unless $external_var_identifiers.include?(\"__#{name}\")\n      $external_vars << \"#{type} __#{name}#{value};\"\n    end\n    \n    def post_process_arrays(name, var)\n      type = c_type(var[0])\n      $array_types[name] = type\n      assignment = var.inspect.gsub(\"[\",\"{\").gsub(\"]\",\"}\")      \n      c_style_array = \"#{type} __#{name}[] = #{assignment};\"\n      $external_var_identifiers << \"__#{name}\" unless $external_var_identifiers.include?(\"__#{name}\")\n      $external_array_vars << c_style_array unless $external_array_vars.include?(c_style_array)\n    end\n    \n    def check_variable_type(type)\n      unless type =~ /#{C_VAR_TYPES}/\n        raise ArgumentError, \"the following variable types are supported \\n #{C_VAR_TYPES.gsub(\"|\",\", \")} got #{type}\" \n      end\n    end\n    \n    def c_type(typ)\n      type = \n        case typ \n        when Integer\n          \"int\"\n        when String\n          \"char*\"\n        when TrueClass\n          \"bool\"\n        when FalseClass\n          \"bool\"\n        else\n          raise \"Bug! Unknown type #{typ.inspect} in c_type\"\n        end\n\n        type\n    end\n   \nend"
  },
  {
    "path": "lib/rad/version.rb",
    "content": "module Rad #:nodoc:\n  module VERSION #:nodoc:\n    MAJOR = 0\n    MINOR = 3\n    TINY  = 1\n\n    STRING = [MAJOR, MINOR, TINY].join('.')\n  end\nend\n"
  },
  {
    "path": "lib/rad.rb",
    "content": "module Rad\nend\n\nrequire 'rad/version'\nrequire 'rad/init'"
  },
  {
    "path": "rad.gemspec",
    "content": "Gem::Specification.new do |s|\n  s.name = %q{rad}\n  s.version = \"0.3.1\"\n  s.date = %q{2008-08-18}\n  s.default_executable = %q{rad}\n  s.summary = \"RAD: Ruby Arduino Development - 0.3.1\"\n  s.email = \"greg@grabb.it\"\n  s.executables = [\"rad\"]\n  s.homepage = \"http://github.com/atduskreg/rad\"  \n  s.description = \"Ruby Arduino Development: a framework for programming the Arduino physcial computing platform using Ruby\"\n  s.has_rdoc = true\n  s.authors = [\"Greg Borenstein\", \"plugins+: JD Barnhart\"]\n  s.extra_rdoc_files = [\"History.txt\", \"License.txt\", \"Manifest.txt\", \"lib/libraries/AFSoftSerial/keywords.txt\", \"lib/libraries/DS1307/keywords.txt\", \"lib/libraries/FrequencyTimer2/keywords.txt\", \"lib/libraries/I2CEEPROM/keywords.txt\", \"lib/libraries/LoopTimer/keywords.txt\", \"lib/libraries/OneWire/keywords.txt\", \"lib/libraries/OneWire/readme.txt\", \"lib/libraries/Stepper/keywords.txt\", \"lib/libraries/Wire/keywords.txt\", \"lib/rad/todo.txt\", \"website/index.txt\"]\n  s.files = [\"History.txt\", \"License.txt\", \"Manifest.txt\", \"README.rdoc\", \"Rakefile\", \"test/hello_world_test/Makefile\", \"test/hello_world_test/hello_world.cpp\", \"bin/rad\", \"lib/examples/add_hysteresis.rb\", \"lib/examples/basic_blink.rb\", \"lib/examples/blink_m_address_assignment.rb\", \"lib/examples/blink_m_hello.rb\", \"lib/examples/blink_m_multi.rb\", \"lib/examples/blink_with_serial.rb\", \"lib/examples/configure_pa_lcd_boot.rb\", \"lib/examples/debounce_methods.rb\", \"lib/examples/external_variable_fu.rb\", \"lib/examples/external_variables.rb\", \"lib/examples/first_sound.rb\", \"lib/examples/frequency_generator.rb\", \"lib/examples/hello_array.rb\", \"lib/examples/hello_array2.rb\", \"lib/examples/hello_array_eeprom.rb\", \"lib/examples/hello_clock.rb\", \"lib/examples/hello_eeprom.rb\", \"lib/examples/hello_eeprom_lcdpa.rb\", \"lib/examples/hello_format_print.rb\", \"lib/examples/hello_lcd_charset.rb\", \"lib/examples/hello_pa_lcd.rb\", \"lib/examples/hello_servos.rb\", \"lib/examples/hello_spectra_sound.rb\", \"lib/examples/hello_world.rb\", \"lib/examples/hello_xbee.rb\", \"lib/examples/hysteresis_duel.rb\", \"lib/examples/i2c_with_clock_chip.rb\", \"lib/examples/midi_beat_box.rb\", \"lib/examples/midi_scales.rb\", \"lib/examples/motor_knob.rb\", \"lib/examples/servo_buttons.rb\", \"lib/examples/servo_calibrate_continuous.rb\", \"lib/examples/servo_throttle.rb\", \"lib/examples/software_serial.rb\", \"lib/examples/sparkfun_lcd.rb\", \"lib/examples/spectra_soft_pot.rb\", \"lib/examples/times_method.rb\", \"lib/examples/toggle.rb\", \"lib/examples/twitter.rb\", \"lib/examples/two_wire.rb\", \"lib/libraries/AFSoftSerial/AFSoftSerial.cpp\", \"lib/libraries/AFSoftSerial/AFSoftSerial.h\", \"lib/libraries/AFSoftSerial/keywords.txt\", \"lib/libraries/AF_XPort/AF_XPort.cpp\", \"lib/libraries/AF_XPort/AF_XPort.h\", \"lib/libraries/DS1307/DS1307.cpp\", \"lib/libraries/DS1307/DS1307.h\", \"lib/libraries/DS1307/keywords.txt\", \"lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp\", \"lib/libraries/FrequencyTimer2/FrequencyTimer2.h\", \"lib/libraries/FrequencyTimer2/keywords.txt\", \"lib/libraries/I2CEEPROM/I2CEEPROM.cpp\", \"lib/libraries/I2CEEPROM/I2CEEPROM.h\", \"lib/libraries/I2CEEPROM/keywords.txt\", \"lib/libraries/LoopTimer/LoopTimer.cpp\", \"lib/libraries/LoopTimer/LoopTimer.h\", \"lib/libraries/LoopTimer/keywords.txt\", \"lib/libraries/OneWire/OneWire.cpp\", \"lib/libraries/OneWire/OneWire.h\", \"lib/libraries/OneWire/keywords.txt\", \"lib/libraries/OneWire/readme.txt\", \"lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp\", \"lib/libraries/SWSerLCDpa/SWSerLCDpa.h\", \"lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp\", \"lib/libraries/SWSerLCDsf/SWSerLCDsf.h\", \"lib/libraries/Servo/Servo.cpp\", \"lib/libraries/Servo/Servo.h\", \"lib/libraries/Stepper/Stepper.cpp\", \"lib/libraries/Stepper/Stepper.h\", \"lib/libraries/Stepper/keywords.txt\", \"lib/libraries/Wire/Wire.cpp\", \"lib/libraries/Wire/Wire.h\", \"lib/libraries/Wire/keywords.txt\", \"lib/libraries/Wire/twi.h\", \"lib/libraries/Wire/utility/twi.c\", \"lib/libraries/Wire/utility/twi.h\", \"lib/plugins/bitwise_ops.rb\", \"lib/plugins/blink.rb\", \"lib/plugins/blink_m.rb\", \"lib/plugins/debounce.rb\", \"lib/plugins/debug_output_to_lcd.rb\", \"lib/plugins/hysteresis.rb\", \"lib/plugins/input_output_state.rb\", \"lib/plugins/lcd_padding.rb\", \"lib/plugins/mem_test.rb\", \"lib/plugins/midi.rb\", \"lib/plugins/parallax_ping.rb\", \"lib/plugins/servo_pulse.rb\", \"lib/plugins/servo_setup.rb\", \"lib/plugins/smoother.rb\", \"lib/plugins/spark_fun_serial_lcd.rb\", \"lib/plugins/spectra_symbol.rb\", \"lib/plugins/twitter_connect.rb\", \"lib/rad.rb\", \"lib/rad/README.rdoc\", \"lib/rad/arduino_plugin.rb\", \"lib/rad/arduino_sketch.rb\", \"lib/rad/generators/makefile/makefile.erb\", \"lib/rad/generators/makefile/makefile.rb\", \"lib/rad/hardware_library.rb\", \"lib/rad/init.rb\", \"lib/rad/progressbar.rb\", \"lib/rad/rad_processor.rb\", \"lib/rad/linux_installer.rb\", \"lib/rad/darwin_installer.rb\", \"lib/rad/rad_rewriter.rb\", \"lib/rad/rad_type_checker.rb\", \"lib/rad/sim/arduino_sketch.rb\", \"lib/rad/sketch_compiler.rb\", \"lib/rad/tasks/build_and_make.rake\", \"lib/rad/tasks/rad.rb\", \"lib/rad/todo.txt\", \"lib/rad/variable_processing.rb\", \"lib/rad/version.rb\", \"scripts/txt2html\", \"setup.rb\", \"spec/examples/hello_world.rb\", \"spec/examples/serial_motor.rb\", \"spec/models/arduino_sketch_spec.rb\", \"spec/models/sketch_compiler_spec.rb\", \"spec/models/spec_helper.rb\", \"spec/sim/hello_world_spec.rb\", \"spec/spec.opts\", \"test/test_array_processing.rb\", \"test/test_plugin_loading.rb\", \"test/test_translation_post_processing.rb\", \"test/test_variable_processing.rb\", \"website/index.html\", \"website/index.txt\", \"website/javascripts/rounded_corners_lite.inc.js\", \"website/stylesheets/screen.css\", \"website/template.rhtml\", \"website/examples/assembler_test.rb.html\", \"website/examples/gps_reader.rb.html\", \"website/examples/hello_world.rb.html\", \"website/examples/serial_motor.rb.html\"]\n  s.test_files = []\n  s.rdoc_options = [\"--main\", \"README.rdoc\"]\n  s.require_paths = [\"lib\"]\n  s.rubyforge_project = %q{rad}\n  s.rubygems_version = %q{1.2.0}\n  s.extra_rdoc_files = [\"History.txt\", \"Manifest.txt\", \"README.rdoc\"]\n  s.add_dependency(\"mime-types\", [\"> 0.0.0\"])\n  \n  if s.respond_to? :specification_version then\n    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION\n    s.specification_version = 2\n\n    if current_version >= 3 then\n      s.add_runtime_dependency(%q<RubyToC>, [\">= 1.0.0\"])\n    else\n      s.add_dependency(%q<RubyToC>, [\">= 1.0.0\"])\n    end\n  else\n    s.add_dependency(%q<RubyToC>, [\">= 1.0.0\"])\n  end\nend\n"
  },
  {
    "path": "scripts/txt2html",
    "content": "#!/usr/bin/env ruby\n\nrequire 'rubygems'\nrequire 'redcloth'\nrequire 'syntax/convertors/html'\nrequire 'erb'\nrequire File.dirname(__FILE__) + '/../lib/rad/version.rb'\n\nversion  = Rad::VERSION::STRING\ndownload = 'http://rubyforge.org/projects/rad'\n\nclass Fixnum\n  def ordinal\n    # teens\n    return 'th' if (10..19).include?(self % 100)\n    # others\n    case self % 10\n    when 1: return 'st'\n    when 2: return 'nd'\n    when 3: return 'rd'\n    else    return 'th'\n    end\n  end\nend\n\nclass Time\n  def pretty\n    return \"#{mday}#{mday.ordinal} #{strftime('%B')} #{year}\"\n  end\nend\n\ndef convert_syntax(syntax, source)\n  return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')\nend\n\nif ARGV.length >= 1\n  src, template = ARGV\n  template ||= File.dirname(__FILE__) + '/../website/template.rhtml'\n  \nelse\n  puts(\"Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html\")\n  exit!\nend\n\ntemplate = ERB.new(File.open(template).read)\n\ntitle = nil\nbody = nil\nFile.open(src) do |fsrc|\n  title_text = fsrc.readline\n  body_text = fsrc.read\n  syntax_items = []\n  body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['\"]([^'\"]+)[^>]*>(.*?)</\u0001>!m){\n    ident = syntax_items.length\n    element, syntax, source = $1, $2, $3\n    syntax_items << \"<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>\"\n    \"syntax-temp-#{ident}\"\n  }\n  title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip\n  body = RedCloth.new(body_text).to_html\n  body.gsub!(%r!(?:<pre><code>)?syntax-temp-(d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }\nend\nstat = File.stat(src)\ncreated = stat.ctime\nmodified = stat.mtime\n\n$stdout << template.result(binding)\n"
  },
  {
    "path": "setup.rb",
    "content": "#\n# setup.rb\n#\n# Copyright (c) 2000-2005 Minero Aoki\n#\n# This program is free software.\n# You can distribute/modify this program under the terms of\n# the GNU LGPL, Lesser General Public License version 2.1.\n#\n\nunless Enumerable.method_defined?(:map)   # Ruby 1.4.6\n  module Enumerable\n    alias map collect\n  end\nend\n\nunless File.respond_to?(:read)   # Ruby 1.6\n  def File.read(fname)\n    open(fname) {|f|\n      return f.read\n    }\n  end\nend\n\nunless Errno.const_defined?(:ENOTEMPTY)   # Windows?\n  module Errno\n    class ENOTEMPTY\n      # We do not raise this exception, implementation is not needed.\n    end\n  end\nend\n\ndef File.binread(fname)\n  open(fname, 'rb') {|f|\n    return f.read\n  }\nend\n\n# for corrupted Windows' stat(2)\ndef File.dir?(path)\n  File.directory?((path[-1,1] == '/') ? path : path + '/')\nend\n\n\nclass ConfigTable\n\n  include Enumerable\n\n  def initialize(rbconfig)\n    @rbconfig = rbconfig\n    @items = []\n    @table = {}\n    # options\n    @install_prefix = nil\n    @config_opt = nil\n    @verbose = true\n    @no_harm = false\n  end\n\n  attr_accessor :install_prefix\n  attr_accessor :config_opt\n\n  attr_writer :verbose\n\n  def verbose?\n    @verbose\n  end\n\n  attr_writer :no_harm\n\n  def no_harm?\n    @no_harm\n  end\n\n  def [](key)\n    lookup(key).resolve(self)\n  end\n\n  def []=(key, val)\n    lookup(key).set val\n  end\n\n  def names\n    @items.map {|i| i.name }\n  end\n\n  def each(&block)\n    @items.each(&block)\n  end\n\n  def key?(name)\n    @table.key?(name)\n  end\n\n  def lookup(name)\n    @table[name] or setup_rb_error \"no such config item: #{name}\"\n  end\n\n  def add(item)\n    @items.push item\n    @table[item.name] = item\n  end\n\n  def remove(name)\n    item = lookup(name)\n    @items.delete_if {|i| i.name == name }\n    @table.delete_if {|name, i| i.name == name }\n    item\n  end\n\n  def load_script(path, inst = nil)\n    if File.file?(path)\n      MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path\n    end\n  end\n\n  def savefile\n    '.config'\n  end\n\n  def load_savefile\n    begin\n      File.foreach(savefile()) do |line|\n        k, v = *line.split(/=/, 2)\n        self[k] = v.strip\n      end\n    rescue Errno::ENOENT\n      setup_rb_error $!.message + \"\\n#{File.basename($0)} config first\"\n    end\n  end\n\n  def save\n    @items.each {|i| i.value }\n    File.open(savefile(), 'w') {|f|\n      @items.each do |i|\n        f.printf \"%s=%s\\n\", i.name, i.value if i.value? and i.value\n      end\n    }\n  end\n\n  def load_standard_entries\n    standard_entries(@rbconfig).each do |ent|\n      add ent\n    end\n  end\n\n  def standard_entries(rbconfig)\n    c = rbconfig\n\n    rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])\n\n    major = c['MAJOR'].to_i\n    minor = c['MINOR'].to_i\n    teeny = c['TEENY'].to_i\n    version = \"#{major}.#{minor}\"\n\n    # ruby ver. >= 1.4.4?\n    newpath_p = ((major >= 2) or\n                 ((major == 1) and\n                  ((minor >= 5) or\n                   ((minor == 4) and (teeny >= 4)))))\n\n    if c['rubylibdir']\n      # V > 1.6.3\n      libruby         = \"#{c['prefix']}/lib/ruby\"\n      librubyver      = c['rubylibdir']\n      librubyverarch  = c['archdir']\n      siteruby        = c['sitedir']\n      siterubyver     = c['sitelibdir']\n      siterubyverarch = c['sitearchdir']\n    elsif newpath_p\n      # 1.4.4 <= V <= 1.6.3\n      libruby         = \"#{c['prefix']}/lib/ruby\"\n      librubyver      = \"#{c['prefix']}/lib/ruby/#{version}\"\n      librubyverarch  = \"#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}\"\n      siteruby        = c['sitedir']\n      siterubyver     = \"$siteruby/#{version}\"\n      siterubyverarch = \"$siterubyver/#{c['arch']}\"\n    else\n      # V < 1.4.4\n      libruby         = \"#{c['prefix']}/lib/ruby\"\n      librubyver      = \"#{c['prefix']}/lib/ruby/#{version}\"\n      librubyverarch  = \"#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}\"\n      siteruby        = \"#{c['prefix']}/lib/ruby/#{version}/site_ruby\"\n      siterubyver     = siteruby\n      siterubyverarch = \"$siterubyver/#{c['arch']}\"\n    end\n    parameterize = lambda {|path|\n      path.sub(/\\A#{Regexp.quote(c['prefix'])}/, '$prefix')\n    }\n\n    if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }\n      makeprog = arg.sub(/'/, '').split(/=/, 2)[1]\n    else\n      makeprog = 'make'\n    end\n\n    [\n      ExecItem.new('installdirs', 'std/site/home',\n                   'std: install under libruby; site: install under site_ruby; home: install under $HOME')\\\n          {|val, table|\n            case val\n            when 'std'\n              table['rbdir'] = '$librubyver'\n              table['sodir'] = '$librubyverarch'\n            when 'site'\n              table['rbdir'] = '$siterubyver'\n              table['sodir'] = '$siterubyverarch'\n            when 'home'\n              setup_rb_error '$HOME was not set' unless ENV['HOME']\n              table['prefix'] = ENV['HOME']\n              table['rbdir'] = '$libdir/ruby'\n              table['sodir'] = '$libdir/ruby'\n            end\n          },\n      PathItem.new('prefix', 'path', c['prefix'],\n                   'path prefix of target environment'),\n      PathItem.new('bindir', 'path', parameterize.call(c['bindir']),\n                   'the directory for commands'),\n      PathItem.new('libdir', 'path', parameterize.call(c['libdir']),\n                   'the directory for libraries'),\n      PathItem.new('datadir', 'path', parameterize.call(c['datadir']),\n                   'the directory for shared data'),\n      PathItem.new('mandir', 'path', parameterize.call(c['mandir']),\n                   'the directory for man pages'),\n      PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),\n                   'the directory for system configuration files'),\n      PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),\n                   'the directory for local state data'),\n      PathItem.new('libruby', 'path', libruby,\n                   'the directory for ruby libraries'),\n      PathItem.new('librubyver', 'path', librubyver,\n                   'the directory for standard ruby libraries'),\n      PathItem.new('librubyverarch', 'path', librubyverarch,\n                   'the directory for standard ruby extensions'),\n      PathItem.new('siteruby', 'path', siteruby,\n          'the directory for version-independent aux ruby libraries'),\n      PathItem.new('siterubyver', 'path', siterubyver,\n                   'the directory for aux ruby libraries'),\n      PathItem.new('siterubyverarch', 'path', siterubyverarch,\n                   'the directory for aux ruby binaries'),\n      PathItem.new('rbdir', 'path', '$siterubyver',\n                   'the directory for ruby scripts'),\n      PathItem.new('sodir', 'path', '$siterubyverarch',\n                   'the directory for ruby extentions'),\n      PathItem.new('rubypath', 'path', rubypath,\n                   'the path to set to #! line'),\n      ProgramItem.new('rubyprog', 'name', rubypath,\n                      'the ruby program using for installation'),\n      ProgramItem.new('makeprog', 'name', makeprog,\n                      'the make program to compile ruby extentions'),\n      SelectItem.new('shebang', 'all/ruby/never', 'ruby',\n                     'shebang line (#!) editing mode'),\n      BoolItem.new('without-ext', 'yes/no', 'no',\n                   'does not compile/install ruby extentions')\n    ]\n  end\n  private :standard_entries\n\n  def load_multipackage_entries\n    multipackage_entries().each do |ent|\n      add ent\n    end\n  end\n\n  def multipackage_entries\n    [\n      PackageSelectionItem.new('with', 'name,name...', '', 'ALL',\n                               'package names that you want to install'),\n      PackageSelectionItem.new('without', 'name,name...', '', 'NONE',\n                               'package names that you do not want to install')\n    ]\n  end\n  private :multipackage_entries\n\n  ALIASES = {\n    'std-ruby'         => 'librubyver',\n    'stdruby'          => 'librubyver',\n    'rubylibdir'       => 'librubyver',\n    'archdir'          => 'librubyverarch',\n    'site-ruby-common' => 'siteruby',     # For backward compatibility\n    'site-ruby'        => 'siterubyver',  # For backward compatibility\n    'bin-dir'          => 'bindir',\n    'bin-dir'          => 'bindir',\n    'rb-dir'           => 'rbdir',\n    'so-dir'           => 'sodir',\n    'data-dir'         => 'datadir',\n    'ruby-path'        => 'rubypath',\n    'ruby-prog'        => 'rubyprog',\n    'ruby'             => 'rubyprog',\n    'make-prog'        => 'makeprog',\n    'make'             => 'makeprog'\n  }\n\n  def fixup\n    ALIASES.each do |ali, name|\n      @table[ali] = @table[name]\n    end\n    @items.freeze\n    @table.freeze\n    @options_re = /\\A--(#{@table.keys.join('|')})(?:=(.*))?\\z/\n  end\n\n  def parse_opt(opt)\n    m = @options_re.match(opt) or setup_rb_error \"config: unknown option #{opt}\"\n    m.to_a[1,2]\n  end\n\n  def dllext\n    @rbconfig['DLEXT']\n  end\n\n  def value_config?(name)\n    lookup(name).value?\n  end\n\n  class Item\n    def initialize(name, template, default, desc)\n      @name = name.freeze\n      @template = template\n      @value = default\n      @default = default\n      @description = desc\n    end\n\n    attr_reader :name\n    attr_reader :description\n\n    attr_accessor :default\n    alias help_default default\n\n    def help_opt\n      \"--#{@name}=#{@template}\"\n    end\n\n    def value?\n      true\n    end\n\n    def value\n      @value\n    end\n\n    def resolve(table)\n      @value.gsub(%r<\\$([^/]+)>) { table[$1] }\n    end\n\n    def set(val)\n      @value = check(val)\n    end\n\n    private\n\n    def check(val)\n      setup_rb_error \"config: --#{name} requires argument\" unless val\n      val\n    end\n  end\n\n  class BoolItem < Item\n    def config_type\n      'bool'\n    end\n\n    def help_opt\n      \"--#{@name}\"\n    end\n\n    private\n\n    def check(val)\n      return 'yes' unless val\n      case val\n      when /\\Ay(es)?\\z/i, /\\At(rue)?\\z/i then 'yes'\n      when /\\An(o)?\\z/i, /\\Af(alse)\\z/i  then 'no'\n      else\n        setup_rb_error \"config: --#{@name} accepts only yes/no for argument\"\n      end\n    end\n  end\n\n  class PathItem < Item\n    def config_type\n      'path'\n    end\n\n    private\n\n    def check(path)\n      setup_rb_error \"config: --#{@name} requires argument\"  unless path\n      path[0,1] == '$' ? path : File.expand_path(path)\n    end\n  end\n\n  class ProgramItem < Item\n    def config_type\n      'program'\n    end\n  end\n\n  class SelectItem < Item\n    def initialize(name, selection, default, desc)\n      super\n      @ok = selection.split('/')\n    end\n\n    def config_type\n      'select'\n    end\n\n    private\n\n    def check(val)\n      unless @ok.include?(val.strip)\n        setup_rb_error \"config: use --#{@name}=#{@template} (#{val})\"\n      end\n      val.strip\n    end\n  end\n\n  class ExecItem < Item\n    def initialize(name, selection, desc, &block)\n      super name, selection, nil, desc\n      @ok = selection.split('/')\n      @action = block\n    end\n\n    def config_type\n      'exec'\n    end\n\n    def value?\n      false\n    end\n\n    def resolve(table)\n      setup_rb_error \"$#{name()} wrongly used as option value\"\n    end\n\n    undef set\n\n    def evaluate(val, table)\n      v = val.strip.downcase\n      unless @ok.include?(v)\n        setup_rb_error \"invalid option --#{@name}=#{val} (use #{@template})\"\n      end\n      @action.call v, table\n    end\n  end\n\n  class PackageSelectionItem < Item\n    def initialize(name, template, default, help_default, desc)\n      super name, template, default, desc\n      @help_default = help_default\n    end\n\n    attr_reader :help_default\n\n    def config_type\n      'package'\n    end\n\n    private\n\n    def check(val)\n      unless File.dir?(\"packages/#{val}\")\n        setup_rb_error \"config: no such package: #{val}\"\n      end\n      val\n    end\n  end\n\n  class MetaConfigEnvironment\n    def initialize(config, installer)\n      @config = config\n      @installer = installer\n    end\n\n    def config_names\n      @config.names\n    end\n\n    def config?(name)\n      @config.key?(name)\n    end\n\n    def bool_config?(name)\n      @config.lookup(name).config_type == 'bool'\n    end\n\n    def path_config?(name)\n      @config.lookup(name).config_type == 'path'\n    end\n\n    def value_config?(name)\n      @config.lookup(name).config_type != 'exec'\n    end\n\n    def add_config(item)\n      @config.add item\n    end\n\n    def add_bool_config(name, default, desc)\n      @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)\n    end\n\n    def add_path_config(name, default, desc)\n      @config.add PathItem.new(name, 'path', default, desc)\n    end\n\n    def set_config_default(name, default)\n      @config.lookup(name).default = default\n    end\n\n    def remove_config(name)\n      @config.remove(name)\n    end\n\n    # For only multipackage\n    def packages\n      raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer\n      @installer.packages\n    end\n\n    # For only multipackage\n    def declare_packages(list)\n      raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer\n      @installer.packages = list\n    end\n  end\n\nend   # class ConfigTable\n\n\n# This module requires: #verbose?, #no_harm?\nmodule FileOperations\n\n  def mkdir_p(dirname, prefix = nil)\n    dirname = prefix + File.expand_path(dirname) if prefix\n    $stderr.puts \"mkdir -p #{dirname}\" if verbose?\n    return if no_harm?\n\n    # Does not check '/', it's too abnormal.\n    dirs = File.expand_path(dirname).split(%r<(?=/)>)\n    if /\\A[a-z]:\\z/i =~ dirs[0]\n      disk = dirs.shift\n      dirs[0] = disk + dirs[0]\n    end\n    dirs.each_index do |idx|\n      path = dirs[0..idx].join('')\n      Dir.mkdir path unless File.dir?(path)\n    end\n  end\n\n  def rm_f(path)\n    $stderr.puts \"rm -f #{path}\" if verbose?\n    return if no_harm?\n    force_remove_file path\n  end\n\n  def rm_rf(path)\n    $stderr.puts \"rm -rf #{path}\" if verbose?\n    return if no_harm?\n    remove_tree path\n  end\n\n  def remove_tree(path)\n    if File.symlink?(path)\n      remove_file path\n    elsif File.dir?(path)\n      remove_tree0 path\n    else\n      force_remove_file path\n    end\n  end\n\n  def remove_tree0(path)\n    Dir.foreach(path) do |ent|\n      next if ent == '.'\n      next if ent == '..'\n      entpath = \"#{path}/#{ent}\"\n      if File.symlink?(entpath)\n        remove_file entpath\n      elsif File.dir?(entpath)\n        remove_tree0 entpath\n      else\n        force_remove_file entpath\n      end\n    end\n    begin\n      Dir.rmdir path\n    rescue Errno::ENOTEMPTY\n      # directory may not be empty\n    end\n  end\n\n  def move_file(src, dest)\n    force_remove_file dest\n    begin\n      File.rename src, dest\n    rescue\n      File.open(dest, 'wb') {|f|\n        f.write File.binread(src)\n      }\n      File.chmod File.stat(src).mode, dest\n      File.unlink src\n    end\n  end\n\n  def force_remove_file(path)\n    begin\n      remove_file path\n    rescue\n    end\n  end\n\n  def remove_file(path)\n    File.chmod 0777, path\n    File.unlink path\n  end\n\n  def install(from, dest, mode, prefix = nil)\n    $stderr.puts \"install #{from} #{dest}\" if verbose?\n    return if no_harm?\n\n    realdest = prefix ? prefix + File.expand_path(dest) : dest\n    realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)\n    str = File.binread(from)\n    if diff?(str, realdest)\n      verbose_off {\n        rm_f realdest if File.exist?(realdest)\n      }\n      File.open(realdest, 'wb') {|f|\n        f.write str\n      }\n      File.chmod mode, realdest\n\n      File.open(\"#{objdir_root()}/InstalledFiles\", 'a') {|f|\n        if prefix\n          f.puts realdest.sub(prefix, '')\n        else\n          f.puts realdest\n        end\n      }\n    end\n  end\n\n  def diff?(new_content, path)\n    return true unless File.exist?(path)\n    new_content != File.binread(path)\n  end\n\n  def command(*args)\n    $stderr.puts args.join(' ') if verbose?\n    system(*args) or raise RuntimeError,\n        \"system(#{args.map{|a| a.inspect }.join(' ')}) failed\"\n  end\n\n  def ruby(*args)\n    command config('rubyprog'), *args\n  end\n  \n  def make(task = nil)\n    command(*[config('makeprog'), task].compact)\n  end\n\n  def extdir?(dir)\n    File.exist?(\"#{dir}/MANIFEST\") or File.exist?(\"#{dir}/extconf.rb\")\n  end\n\n  def files_of(dir)\n    Dir.open(dir) {|d|\n      return d.select {|ent| File.file?(\"#{dir}/#{ent}\") }\n    }\n  end\n\n  DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )\n\n  def directories_of(dir)\n    Dir.open(dir) {|d|\n      return d.select {|ent| File.dir?(\"#{dir}/#{ent}\") } - DIR_REJECT\n    }\n  end\n\nend\n\n\n# This module requires: #srcdir_root, #objdir_root, #relpath\nmodule HookScriptAPI\n\n  def get_config(key)\n    @config[key]\n  end\n\n  alias config get_config\n\n  # obsolete: use metaconfig to change configuration\n  def set_config(key, val)\n    @config[key] = val\n  end\n\n  #\n  # srcdir/objdir (works only in the package directory)\n  #\n\n  def curr_srcdir\n    \"#{srcdir_root()}/#{relpath()}\"\n  end\n\n  def curr_objdir\n    \"#{objdir_root()}/#{relpath()}\"\n  end\n\n  def srcfile(path)\n    \"#{curr_srcdir()}/#{path}\"\n  end\n\n  def srcexist?(path)\n    File.exist?(srcfile(path))\n  end\n\n  def srcdirectory?(path)\n    File.dir?(srcfile(path))\n  end\n  \n  def srcfile?(path)\n    File.file?(srcfile(path))\n  end\n\n  def srcentries(path = '.')\n    Dir.open(\"#{curr_srcdir()}/#{path}\") {|d|\n      return d.to_a - %w(. ..)\n    }\n  end\n\n  def srcfiles(path = '.')\n    srcentries(path).select {|fname|\n      File.file?(File.join(curr_srcdir(), path, fname))\n    }\n  end\n\n  def srcdirectories(path = '.')\n    srcentries(path).select {|fname|\n      File.dir?(File.join(curr_srcdir(), path, fname))\n    }\n  end\n\nend\n\n\nclass ToplevelInstaller\n\n  Version   = '3.4.1'\n  Copyright = 'Copyright (c) 2000-2005 Minero Aoki'\n\n  TASKS = [\n    [ 'all',      'do config, setup, then install' ],\n    [ 'config',   'saves your configurations' ],\n    [ 'show',     'shows current configuration' ],\n    [ 'setup',    'compiles ruby extentions and others' ],\n    [ 'install',  'installs files' ],\n    [ 'test',     'run all tests in test/' ],\n    [ 'clean',    \"does `make clean' for each extention\" ],\n    [ 'distclean',\"does `make distclean' for each extention\" ]\n  ]\n\n  def ToplevelInstaller.invoke\n    config = ConfigTable.new(load_rbconfig())\n    config.load_standard_entries\n    config.load_multipackage_entries if multipackage?\n    config.fixup\n    klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)\n    klass.new(File.dirname($0), config).invoke\n  end\n\n  def ToplevelInstaller.multipackage?\n    File.dir?(File.dirname($0) + '/packages')\n  end\n\n  def ToplevelInstaller.load_rbconfig\n    if arg = ARGV.detect {|arg| /\\A--rbconfig=/ =~ arg }\n      ARGV.delete(arg)\n      load File.expand_path(arg.split(/=/, 2)[1])\n      $\".push 'rbconfig.rb'\n    else\n      require 'rbconfig'\n    end\n    ::Config::CONFIG\n  end\n\n  def initialize(ardir_root, config)\n    @ardir = File.expand_path(ardir_root)\n    @config = config\n    # cache\n    @valid_task_re = nil\n  end\n\n  def config(key)\n    @config[key]\n  end\n\n  def inspect\n    \"#<#{self.class} #{__id__()}>\"\n  end\n\n  def invoke\n    run_metaconfigs\n    case task = parsearg_global()\n    when nil, 'all'\n      parsearg_config\n      init_installers\n      exec_config\n      exec_setup\n      exec_install\n    else\n      case task\n      when 'config', 'test'\n        ;\n      when 'clean', 'distclean'\n        @config.load_savefile if File.exist?(@config.savefile)\n      else\n        @config.load_savefile\n      end\n      __send__ \"parsearg_#{task}\"\n      init_installers\n      __send__ \"exec_#{task}\"\n    end\n  end\n  \n  def run_metaconfigs\n    @config.load_script \"#{@ardir}/metaconfig\"\n  end\n\n  def init_installers\n    @installer = Installer.new(@config, @ardir, File.expand_path('.'))\n  end\n\n  #\n  # Hook Script API bases\n  #\n\n  def srcdir_root\n    @ardir\n  end\n\n  def objdir_root\n    '.'\n  end\n\n  def relpath\n    '.'\n  end\n\n  #\n  # Option Parsing\n  #\n\n  def parsearg_global\n    while arg = ARGV.shift\n      case arg\n      when /\\A\\w+\\z/\n        setup_rb_error \"invalid task: #{arg}\" unless valid_task?(arg)\n        return arg\n      when '-q', '--quiet'\n        @config.verbose = false\n      when '--verbose'\n        @config.verbose = true\n      when '--help'\n        print_usage $stdout\n        exit 0\n      when '--version'\n        puts \"#{File.basename($0)} version #{Version}\"\n        exit 0\n      when '--copyright'\n        puts Copyright\n        exit 0\n      else\n        setup_rb_error \"unknown global option '#{arg}'\"\n      end\n    end\n    nil\n  end\n\n  def valid_task?(t)\n    valid_task_re() =~ t\n  end\n\n  def valid_task_re\n    @valid_task_re ||= /\\A(?:#{TASKS.map {|task,desc| task }.join('|')})\\z/\n  end\n\n  def parsearg_no_options\n    unless ARGV.empty?\n      task = caller(0).first.slice(%r<`parsearg_(\\w+)'>, 1)\n      setup_rb_error \"#{task}: unknown options: #{ARGV.join(' ')}\"\n    end\n  end\n\n  alias parsearg_show       parsearg_no_options\n  alias parsearg_setup      parsearg_no_options\n  alias parsearg_test       parsearg_no_options\n  alias parsearg_clean      parsearg_no_options\n  alias parsearg_distclean  parsearg_no_options\n\n  def parsearg_config\n    evalopt = []\n    set = []\n    @config.config_opt = []\n    while i = ARGV.shift\n      if /\\A--?\\z/ =~ i\n        @config.config_opt = ARGV.dup\n        break\n      end\n      name, value = *@config.parse_opt(i)\n      if @config.value_config?(name)\n        @config[name] = value\n      else\n        evalopt.push [name, value]\n      end\n      set.push name\n    end\n    evalopt.each do |name, value|\n      @config.lookup(name).evaluate value, @config\n    end\n    # Check if configuration is valid\n    set.each do |n|\n      @config[n] if @config.value_config?(n)\n    end\n  end\n\n  def parsearg_install\n    @config.no_harm = false\n    @config.install_prefix = ''\n    while a = ARGV.shift\n      case a\n      when '--no-harm'\n        @config.no_harm = true\n      when /\\A--prefix=/\n        path = a.split(/=/, 2)[1]\n        path = File.expand_path(path) unless path[0,1] == '/'\n        @config.install_prefix = path\n      else\n        setup_rb_error \"install: unknown option #{a}\"\n      end\n    end\n  end\n\n  def print_usage(out)\n    out.puts 'Typical Installation Procedure:'\n    out.puts \"  $ ruby #{File.basename $0} config\"\n    out.puts \"  $ ruby #{File.basename $0} setup\"\n    out.puts \"  # ruby #{File.basename $0} install (may require root privilege)\"\n    out.puts\n    out.puts 'Detailed Usage:'\n    out.puts \"  ruby #{File.basename $0} <global option>\"\n    out.puts \"  ruby #{File.basename $0} [<global options>] <task> [<task options>]\"\n\n    fmt = \"  %-24s %s\\n\"\n    out.puts\n    out.puts 'Global options:'\n    out.printf fmt, '-q,--quiet',   'suppress message outputs'\n    out.printf fmt, '   --verbose', 'output messages verbosely'\n    out.printf fmt, '   --help',    'print this message'\n    out.printf fmt, '   --version', 'print version and quit'\n    out.printf fmt, '   --copyright',  'print copyright and quit'\n    out.puts\n    out.puts 'Tasks:'\n    TASKS.each do |name, desc|\n      out.printf fmt, name, desc\n    end\n\n    fmt = \"  %-24s %s [%s]\\n\"\n    out.puts\n    out.puts 'Options for CONFIG or ALL:'\n    @config.each do |item|\n      out.printf fmt, item.help_opt, item.description, item.help_default\n    end\n    out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',\"running ruby's\"\n    out.puts\n    out.puts 'Options for INSTALL:'\n    out.printf fmt, '--no-harm', 'only display what to do if given', 'off'\n    out.printf fmt, '--prefix=path',  'install path prefix', ''\n    out.puts\n  end\n\n  #\n  # Task Handlers\n  #\n\n  def exec_config\n    @installer.exec_config\n    @config.save   # must be final\n  end\n\n  def exec_setup\n    @installer.exec_setup\n  end\n\n  def exec_install\n    @installer.exec_install\n  end\n\n  def exec_test\n    @installer.exec_test\n  end\n\n  def exec_show\n    @config.each do |i|\n      printf \"%-20s %s\\n\", i.name, i.value if i.value?\n    end\n  end\n\n  def exec_clean\n    @installer.exec_clean\n  end\n\n  def exec_distclean\n    @installer.exec_distclean\n  end\n\nend   # class ToplevelInstaller\n\n\nclass ToplevelInstallerMulti < ToplevelInstaller\n\n  include FileOperations\n\n  def initialize(ardir_root, config)\n    super\n    @packages = directories_of(\"#{@ardir}/packages\")\n    raise 'no package exists' if @packages.empty?\n    @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))\n  end\n\n  def run_metaconfigs\n    @config.load_script \"#{@ardir}/metaconfig\", self\n    @packages.each do |name|\n      @config.load_script \"#{@ardir}/packages/#{name}/metaconfig\"\n    end\n  end\n\n  attr_reader :packages\n\n  def packages=(list)\n    raise 'package list is empty' if list.empty?\n    list.each do |name|\n      raise \"directory packages/#{name} does not exist\"\\\n              unless File.dir?(\"#{@ardir}/packages/#{name}\")\n    end\n    @packages = list\n  end\n\n  def init_installers\n    @installers = {}\n    @packages.each do |pack|\n      @installers[pack] = Installer.new(@config,\n                                       \"#{@ardir}/packages/#{pack}\",\n                                       \"packages/#{pack}\")\n    end\n    with    = extract_selection(config('with'))\n    without = extract_selection(config('without'))\n    @selected = @installers.keys.select {|name|\n                  (with.empty? or with.include?(name)) \\\n                      and not without.include?(name)\n                }\n  end\n\n  def extract_selection(list)\n    a = list.split(/,/)\n    a.each do |name|\n      setup_rb_error \"no such package: #{name}\"  unless @installers.key?(name)\n    end\n    a\n  end\n\n  def print_usage(f)\n    super\n    f.puts 'Inluded packages:'\n    f.puts '  ' + @packages.sort.join(' ')\n    f.puts\n  end\n\n  #\n  # Task Handlers\n  #\n\n  def exec_config\n    run_hook 'pre-config'\n    each_selected_installers {|inst| inst.exec_config }\n    run_hook 'post-config'\n    @config.save   # must be final\n  end\n\n  def exec_setup\n    run_hook 'pre-setup'\n    each_selected_installers {|inst| inst.exec_setup }\n    run_hook 'post-setup'\n  end\n\n  def exec_install\n    run_hook 'pre-install'\n    each_selected_installers {|inst| inst.exec_install }\n    run_hook 'post-install'\n  end\n\n  def exec_test\n    run_hook 'pre-test'\n    each_selected_installers {|inst| inst.exec_test }\n    run_hook 'post-test'\n  end\n\n  def exec_clean\n    rm_f @config.savefile\n    run_hook 'pre-clean'\n    each_selected_installers {|inst| inst.exec_clean }\n    run_hook 'post-clean'\n  end\n\n  def exec_distclean\n    rm_f @config.savefile\n    run_hook 'pre-distclean'\n    each_selected_installers {|inst| inst.exec_distclean }\n    run_hook 'post-distclean'\n  end\n\n  #\n  # lib\n  #\n\n  def each_selected_installers\n    Dir.mkdir 'packages' unless File.dir?('packages')\n    @selected.each do |pack|\n      $stderr.puts \"Processing the package `#{pack}' ...\" if verbose?\n      Dir.mkdir \"packages/#{pack}\" unless File.dir?(\"packages/#{pack}\")\n      Dir.chdir \"packages/#{pack}\"\n      yield @installers[pack]\n      Dir.chdir '../..'\n    end\n  end\n\n  def run_hook(id)\n    @root_installer.run_hook id\n  end\n\n  # module FileOperations requires this\n  def verbose?\n    @config.verbose?\n  end\n\n  # module FileOperations requires this\n  def no_harm?\n    @config.no_harm?\n  end\n\nend   # class ToplevelInstallerMulti\n\n\nclass Installer\n\n  FILETYPES = %w( bin lib ext data conf man )\n\n  include FileOperations\n  include HookScriptAPI\n\n  def initialize(config, srcroot, objroot)\n    @config = config\n    @srcdir = File.expand_path(srcroot)\n    @objdir = File.expand_path(objroot)\n    @currdir = '.'\n  end\n\n  def inspect\n    \"#<#{self.class} #{File.basename(@srcdir)}>\"\n  end\n\n  def noop(rel)\n  end\n\n  #\n  # Hook Script API base methods\n  #\n\n  def srcdir_root\n    @srcdir\n  end\n\n  def objdir_root\n    @objdir\n  end\n\n  def relpath\n    @currdir\n  end\n\n  #\n  # Config Access\n  #\n\n  # module FileOperations requires this\n  def verbose?\n    @config.verbose?\n  end\n\n  # module FileOperations requires this\n  def no_harm?\n    @config.no_harm?\n  end\n\n  def verbose_off\n    begin\n      save, @config.verbose = @config.verbose?, false\n      yield\n    ensure\n      @config.verbose = save\n    end\n  end\n\n  #\n  # TASK config\n  #\n\n  def exec_config\n    exec_task_traverse 'config'\n  end\n\n  alias config_dir_bin noop\n  alias config_dir_lib noop\n\n  def config_dir_ext(rel)\n    extconf if extdir?(curr_srcdir())\n  end\n\n  alias config_dir_data noop\n  alias config_dir_conf noop\n  alias config_dir_man noop\n\n  def extconf\n    ruby \"#{curr_srcdir()}/extconf.rb\", *@config.config_opt\n  end\n\n  #\n  # TASK setup\n  #\n\n  def exec_setup\n    exec_task_traverse 'setup'\n  end\n\n  def setup_dir_bin(rel)\n    files_of(curr_srcdir()).each do |fname|\n      update_shebang_line \"#{curr_srcdir()}/#{fname}\"\n    end\n  end\n\n  alias setup_dir_lib noop\n\n  def setup_dir_ext(rel)\n    make if extdir?(curr_srcdir())\n  end\n\n  alias setup_dir_data noop\n  alias setup_dir_conf noop\n  alias setup_dir_man noop\n\n  def update_shebang_line(path)\n    return if no_harm?\n    return if config('shebang') == 'never'\n    old = Shebang.load(path)\n    if old\n      $stderr.puts \"warning: #{path}: Shebang line includes too many args.  It is not portable and your program may not work.\" if old.args.size > 1\n      new = new_shebang(old)\n      return if new.to_s == old.to_s\n    else\n      return unless config('shebang') == 'all'\n      new = Shebang.new(config('rubypath'))\n    end\n    $stderr.puts \"updating shebang: #{File.basename(path)}\" if verbose?\n    open_atomic_writer(path) {|output|\n      File.open(path, 'rb') {|f|\n        f.gets if old   # discard\n        output.puts new.to_s\n        output.print f.read\n      }\n    }\n  end\n\n  def new_shebang(old)\n    if /\\Aruby/ =~ File.basename(old.cmd)\n      Shebang.new(config('rubypath'), old.args)\n    elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'\n      Shebang.new(config('rubypath'), old.args[1..-1])\n    else\n      return old unless config('shebang') == 'all'\n      Shebang.new(config('rubypath'))\n    end\n  end\n\n  def open_atomic_writer(path, &block)\n    tmpfile = File.basename(path) + '.tmp'\n    begin\n      File.open(tmpfile, 'wb', &block)\n      File.rename tmpfile, File.basename(path)\n    ensure\n      File.unlink tmpfile if File.exist?(tmpfile)\n    end\n  end\n\n  class Shebang\n    def Shebang.load(path)\n      line = nil\n      File.open(path) {|f|\n        line = f.gets\n      }\n      return nil unless /\\A#!/ =~ line\n      parse(line)\n    end\n\n    def Shebang.parse(line)\n      cmd, *args = *line.strip.sub(/\\A\\#!/, '').split(' ')\n      new(cmd, args)\n    end\n\n    def initialize(cmd, args = [])\n      @cmd = cmd\n      @args = args\n    end\n\n    attr_reader :cmd\n    attr_reader :args\n\n    def to_s\n      \"#! #{@cmd}\" + (@args.empty? ? '' : \" #{@args.join(' ')}\")\n    end\n  end\n\n  #\n  # TASK install\n  #\n\n  def exec_install\n    rm_f 'InstalledFiles'\n    exec_task_traverse 'install'\n  end\n\n  def install_dir_bin(rel)\n    install_files targetfiles(), \"#{config('bindir')}/#{rel}\", 0755\n  end\n\n  def install_dir_lib(rel)\n    install_files libfiles(), \"#{config('rbdir')}/#{rel}\", 0644\n  end\n\n  def install_dir_ext(rel)\n    return unless extdir?(curr_srcdir())\n    install_files rubyextentions('.'),\n                  \"#{config('sodir')}/#{File.dirname(rel)}\",\n                  0555\n  end\n\n  def install_dir_data(rel)\n    install_files targetfiles(), \"#{config('datadir')}/#{rel}\", 0644\n  end\n\n  def install_dir_conf(rel)\n    # FIXME: should not remove current config files\n    # (rename previous file to .old/.org)\n    install_files targetfiles(), \"#{config('sysconfdir')}/#{rel}\", 0644\n  end\n\n  def install_dir_man(rel)\n    install_files targetfiles(), \"#{config('mandir')}/#{rel}\", 0644\n  end\n\n  def install_files(list, dest, mode)\n    mkdir_p dest, @config.install_prefix\n    list.each do |fname|\n      install fname, dest, mode, @config.install_prefix\n    end\n  end\n\n  def libfiles\n    glob_reject(%w(*.y *.output), targetfiles())\n  end\n\n  def rubyextentions(dir)\n    ents = glob_select(\"*.#{@config.dllext}\", targetfiles())\n    if ents.empty?\n      setup_rb_error \"no ruby extention exists: 'ruby #{$0} setup' first\"\n    end\n    ents\n  end\n\n  def targetfiles\n    mapdir(existfiles() - hookfiles())\n  end\n\n  def mapdir(ents)\n    ents.map {|ent|\n      if File.exist?(ent)\n      then ent                         # objdir\n      else \"#{curr_srcdir()}/#{ent}\"   # srcdir\n      end\n    }\n  end\n\n  # picked up many entries from cvs-1.11.1/src/ignore.c\n  JUNK_FILES = %w( \n    core RCSLOG tags TAGS .make.state\n    .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb\n    *~ *.old *.bak *.BAK *.orig *.rej _$* *$\n\n    *.org *.in .*\n  )\n\n  def existfiles\n    glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))\n  end\n\n  def hookfiles\n    %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|\n      %w( config setup install clean ).map {|t| sprintf(fmt, t) }\n    }.flatten\n  end\n\n  def glob_select(pat, ents)\n    re = globs2re([pat])\n    ents.select {|ent| re =~ ent }\n  end\n\n  def glob_reject(pats, ents)\n    re = globs2re(pats)\n    ents.reject {|ent| re =~ ent }\n  end\n\n  GLOB2REGEX = {\n    '.' => '\\.',\n    '$' => '\\$',\n    '#' => '\\#',\n    '*' => '.*'\n  }\n\n  def globs2re(pats)\n    /\\A(?:#{\n      pats.map {|pat| pat.gsub(/[\\.\\$\\#\\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')\n    })\\z/\n  end\n\n  #\n  # TASK test\n  #\n\n  TESTDIR = 'test'\n\n  def exec_test\n    unless File.directory?('test')\n      $stderr.puts 'no test in this package' if verbose?\n      return\n    end\n    $stderr.puts 'Running tests...' if verbose?\n    begin\n      require 'test/unit'\n    rescue LoadError\n      setup_rb_error 'test/unit cannot loaded.  You need Ruby 1.8 or later to invoke this task.'\n    end\n    runner = Test::Unit::AutoRunner.new(true)\n    runner.to_run << TESTDIR\n    runner.run\n  end\n\n  #\n  # TASK clean\n  #\n\n  def exec_clean\n    exec_task_traverse 'clean'\n    rm_f @config.savefile\n    rm_f 'InstalledFiles'\n  end\n\n  alias clean_dir_bin noop\n  alias clean_dir_lib noop\n  alias clean_dir_data noop\n  alias clean_dir_conf noop\n  alias clean_dir_man noop\n\n  def clean_dir_ext(rel)\n    return unless extdir?(curr_srcdir())\n    make 'clean' if File.file?('Makefile')\n  end\n\n  #\n  # TASK distclean\n  #\n\n  def exec_distclean\n    exec_task_traverse 'distclean'\n    rm_f @config.savefile\n    rm_f 'InstalledFiles'\n  end\n\n  alias distclean_dir_bin noop\n  alias distclean_dir_lib noop\n\n  def distclean_dir_ext(rel)\n    return unless extdir?(curr_srcdir())\n    make 'distclean' if File.file?('Makefile')\n  end\n\n  alias distclean_dir_data noop\n  alias distclean_dir_conf noop\n  alias distclean_dir_man noop\n\n  #\n  # Traversing\n  #\n\n  def exec_task_traverse(task)\n    run_hook \"pre-#{task}\"\n    FILETYPES.each do |type|\n      if type == 'ext' and config('without-ext') == 'yes'\n        $stderr.puts 'skipping ext/* by user option' if verbose?\n        next\n      end\n      traverse task, type, \"#{task}_dir_#{type}\"\n    end\n    run_hook \"post-#{task}\"\n  end\n\n  def traverse(task, rel, mid)\n    dive_into(rel) {\n      run_hook \"pre-#{task}\"\n      __send__ mid, rel.sub(%r[\\A.*?(?:/|\\z)], '')\n      directories_of(curr_srcdir()).each do |d|\n        traverse task, \"#{rel}/#{d}\", mid\n      end\n      run_hook \"post-#{task}\"\n    }\n  end\n\n  def dive_into(rel)\n    return unless File.dir?(\"#{@srcdir}/#{rel}\")\n\n    dir = File.basename(rel)\n    Dir.mkdir dir unless File.dir?(dir)\n    prevdir = Dir.pwd\n    Dir.chdir dir\n    $stderr.puts '---> ' + rel if verbose?\n    @currdir = rel\n    yield\n    Dir.chdir prevdir\n    $stderr.puts '<--- ' + rel if verbose?\n    @currdir = File.dirname(rel)\n  end\n\n  def run_hook(id)\n    path = [ \"#{curr_srcdir()}/#{id}\",\n             \"#{curr_srcdir()}/#{id}.rb\" ].detect {|cand| File.file?(cand) }\n    return unless path\n    begin\n      instance_eval File.read(path), path, 1\n    rescue\n      raise if $DEBUG\n      setup_rb_error \"hook #{path} failed:\\n\" + $!.message\n    end\n  end\n\nend   # class Installer\n\n\nclass SetupError < StandardError; end\n\ndef setup_rb_error(msg)\n  raise SetupError, msg\nend\n\nif $0 == __FILE__\n  begin\n    ToplevelInstaller.invoke\n  rescue SetupError\n    raise if $DEBUG\n    $stderr.puts $!.message\n    $stderr.puts \"Try 'ruby #{$0} --help' for detailed usage.\"\n    exit 1\n  end\nend\n"
  },
  {
    "path": "spec/examples/hello_world.rb",
    "content": "# Hardware: LED connected on pin 7\n\nclass HelloWorld < ArduinoSketch\n  output_pin 7, :as => :led\n  def loop\n    digitalWrite led, ON\n    delay 500\n    digitalWrite led, OFF\n    delay 500\n  end\nend\n"
  },
  {
    "path": "spec/examples/serial_motor.rb",
    "content": "# Hardware: motor control circuit (i.e. TIP-120 control pin)\n#           connected at pin 7.\n#     Demo: http://www.youtube.com/watch?v=7OguEBfdTe0\n\nclass SerialMotor < ArduinoSketch\n  output_pin 7, :as => :motor\n  serial_begin\n  \n  def loop\n    digitalWrite(motor, serial_read) if serial_available\n  end\nend\n"
  },
  {
    "path": "spec/models/arduino_sketch_spec.rb",
    "content": "require File.dirname(__FILE__) + '/spec_helper.rb'\nrequire File.expand_path(File.dirname(__FILE__) + \"/../../lib/rad/arduino_sketch.rb\")\n\ncontext \"Arduino#serial_begin\" do\n  setup do\n    @as = ArduinoSketch.new\n  end\n  \n  specify \"should default baud_rate to 9600\" do\n    @as.serial_begin\n    @as.instance_variable_get(\"@other_setup\").should include(\"Serial.begin(9600);\")\n  end\n  specify \"should set an alternate baud_rate if told\" do\n    @as.serial_begin :rate => 2400\n    @as.instance_variable_get(\"@other_setup\").should include(\"Serial.begin(2400);\")\n  end\n  specify \"should add the correct function call to the composed_setup\" do\n    @as.serial_begin\n    @as.compose_setup.should match(Regexp.new(Regexp.escape(\"Serial.begin(9600);\")))\n  end\nend\n\n\ncontext \"Arduino Base\" do\n  setup do\n    @as = ArduinoSketch.new\n  end\n  \n  specify \"output_pin method without :as arg. should add the pin to the pin_mode hash's output list and leave the declarations alone\" do\n    @as.output_pin 1\n    @as.instance_variable_get(\"@declarations\").first.should == nil\n    @as.instance_variable_get(\"@pin_modes\")[:output].should include(1)\n  end\n  \n  specify \"output_pin method with :as arg. should add the pin to the pin_mode hash's output list write the appropriate declaration and accessor\" do\n    @as.output_pin 3, :as => :led\n    @as.instance_variable_get(\"@declarations\").first.should == \"int _led = 3;\"\n    @as.instance_variable_get(\"@accessors\").first.should == \"int led(){\\nreturn _led;\\n}\"\n    @as.instance_variable_get(\"@pin_modes\")[:output].should include(3)\n  end\n  \n  specify \"output_pins method should add the pin to the pin_mode hash's output list and leave the declarations and accessors alone\" do\n    @as.output_pins [5,4,3,2]\n    @as.instance_variable_get(\"@pin_modes\")[:output].should include(5)\n    @as.instance_variable_get(\"@pin_modes\")[:output].should include(4)\n    @as.instance_variable_get(\"@pin_modes\")[:output].should include(3)\n    @as.instance_variable_get(\"@pin_modes\")[:output].should include(2)\n    @as.instance_variable_get(\"@declarations\").first.should == nil\n    @as.instance_variable_get(\"@accessors\").first.should == nil\n  end\n  \n  specify \"input_pin method with :as arg. should add the pin to the pin_mode hash's input list write the appropriate declaration and accessor\" do\n    @as.input_pin 1, :as => :knob\n    @as.instance_variable_get(\"@declarations\").first.should == \"int _knob = 1;\"\n    @as.instance_variable_get(\"@accessors\").first.should == \"int knob(){\\nreturn _knob;\\n}\"\n    @as.instance_variable_get(\"@pin_modes\")[:input].should include(1)\n  end\n  \n  specify \"input_pins method should add the pins to the pin_mode hash's input list and leave the declarations and accessors alone\" do\n    @as.input_pins [5,4,3,2]\n    @as.instance_variable_get(\"@pin_modes\")[:input].should include(5)\n    @as.instance_variable_get(\"@pin_modes\")[:input].should include(4)\n    @as.instance_variable_get(\"@pin_modes\")[:input].should include(3)\n    @as.instance_variable_get(\"@pin_modes\")[:input].should include(2)\n    @as.instance_variable_get(\"@declarations\").first.should == nil\n    @as.instance_variable_get(\"@accessors\").first.should == nil\n  end\n  \n  specify \"compose_setup should append each appropriate pinMode statement and :as accessor to the setup_function string with a newline\" do\n    @as.output_pins [1, 2]\n    @as.input_pin 3, :as => :button\n    \n    result = @as.send :compose_setup\n    \n    result.should match(Regexp.new(Regexp.escape(\"pinMode(1, OUTPUT);\\n\")))\n    result.should match(Regexp.new(Regexp.escape(\"pinMode(2, OUTPUT);\\n\")))\n    result.should match(Regexp.new(Regexp.escape(\"pinMode(3, INPUT);\\n\")))\n    result.should match(Regexp.new(Regexp.escape(\"int _button = 3;\\n\")))\n    result.should match(Regexp.new(Regexp.escape(\"int button(){\\nreturn _button;\\n}\")))\n  end\n  \nend"
  },
  {
    "path": "spec/models/sketch_compiler_spec.rb",
    "content": "require File.dirname(__FILE__) + '/spec_helper.rb'\nrequire File.expand_path(File.dirname(__FILE__) + \"/../../lib/rad/sketch_compiler.rb\")\n\ncontext \"SketchCompiler#sketch_methods\" do\n  before do\n    @as = File.expand_path(File.dirname(__FILE__)) + \"/../../lib/examples/i2c_with_clock_chip.rb\"\n    @sc = SketchCompiler.new @as\n  end\n  \n  it \"should locate all the methods defined in the sketch\" do\n    @sc.sketch_methods.should include( \"loop\")\n    @sc.sketch_methods.should include( \"printlz\")\n    @sc.sketch_methods.should include( \"print_hexbyte\")\n    @sc.sketch_methods.should include( \"clear_bottom_line\")\n  end\nend\n\ncontext \"SketchCompiler#process_constants\" do\n  before do\n    @as = File.expand_path(File.dirname(__FILE__)) + \"/../../lib/examples/external_variable_fu.rb\"\n    @sc = SketchCompiler.new @as\n  end\n  \n  it \"should correctly process constants\" do\n    @sc.process_constants\n    @sc.body.should_not match(/HIGH/)\n    @sc.body.should_not match(/LOW/)\n    @sc.body.should_not match(/ON/)\n    @sc.body.should_not match(/OFF/)\n  end\nend\n\ncontext \"SketchCompiler.new\" do\n  before do\n    @as = File.expand_path(File.dirname(__FILE__)) + \"/../../lib/examples/add_hysteresis.rb\"\n  end\n  it \"should correctly absolutize a path with /../ that starts at /\" do\n    SketchCompiler.new(@as).path.should == \"/Users/greg/code/rad/lib/examples/add_hysteresis.rb\"\n  end\n  \n  it \"should correct absolutize a relative path\" do\n    SketchCompiler.new(\"lib/examples/add_hysteresis.rb\").path.should == \"/Users/greg/code/rad/lib/examples/add_hysteresis.rb\"\n  end\n  \n  it \"should load the body of the sketch\" do\n    sc = SketchCompiler.new @as\n    sc.body.should == open(@as).read\n  end\n    \nend\n\ncontext \"SketchCompiler#sketch_class\" do\n  before do\n    @sc = SketchCompiler.new File.expand_path(File.dirname(__FILE__)) + \"/../../lib/examples/add_hysteresis.rb\"\n  end\n  it \"should calculate correctly from the path\" do\n    @sc.klass.should == \"AddHysteresis\"\n  end\nend\n\ncontext \"SketchCompiler#create_build_dir! without a path prefix\" do\n  before do\n    @sc = SketchCompiler.new(\"lib/examples/add_hysteresis.rb\")\n  end\n  it \"should create the sketch dir in the correct place\" do\n    @sc.should_receive( :mkdir_p ).with( \"/Users/greg/code/rad/lib/examples/add_hysteresis\" )\n    @sc.create_build_dir!\n  end\nend\n\ncontext \"SketchCompiler#create_build_dir! with a path prefix\" do\n  before do\n    @sc = SketchCompiler.new(\"lib/examples/add_hysteresis.rb\")\n  end\n  it \"should create the sketch dir in the correct place\" do\n    @sc.should_receive( :mkdir_p ).with( \"prefix/add_hysteresis\" )\n    @sc.create_build_dir! \"prefix\"\n  end\nend\n\ncontext \"SketchCompiler#build_dir\" do\n  before do\n    @sc = SketchCompiler.new(\"lib/examples/add_hysteresis.rb\")\n  end\n  \n  \n  it \"should be correct with a default target_dir\" do\n    @sc.build_dir.should == \"/Users/greg/code/rad/lib/examples/add_hysteresis\"\n  end\n  \n  it \"should be correct with an altered target_dir\" do\n    @sc.target_dir = \"examples\"\n    @sc.build_dir.should == \"examples/add_hysteresis\"\n  end\n  \nend\n"
  },
  {
    "path": "spec/models/spec_helper.rb",
    "content": "require 'rubygems'\nrequire 'spec'\n"
  },
  {
    "path": "spec/sim/hello_world_spec.rb",
    "content": "require File.dirname(__FILE__) + './models/spec_helper.rb'\nrequire File.expand_path(File.dirname(__FILE__) + \"/../../lib/rad/sim/arduino_sketch.rb\")\nrequire File.expand_path(File.dirname(__FILE__) + \"/../examples/hello_world.rb\" )\n\ncontext \"ArduinoSketch running HelloWorld example\" do\n  it \"should successfully make an instance\" do\n    lambda{HelloWorld.new}.should_not raise_error\n  end\nend\n\ncontext \"HelloWorld#led\" do\n  it \"should return a correctly configured Pin\" do\n    p = HelloWorld.new.led\n    p.type.should == :output\n    p.num.should == 7\n    p.value.should == false\n  end\nend\n\ncontext \"HelloWorld#digitalWrite\" do\n  setup do\n    @h = HelloWorld.new\n  end \n\n  it \"should set the value of the pin to true if told to\" do\n    @h.digitalWrite(@h.led, ON)\n    @h.led.value.should == true\n  end\n\n  it \"should set the value of the pin to false if told to\" do\n    @h.digitalWrite(@h.led, OFF)\n    @h.led.value.should == false\n  end\nend\n\ncontext \"HelloWorld#delay\" do\n  it \"should maybe keep track of the time in some way?\"\nend\n\ncontext \"HelloWorld#loop\" do\n  it \"should execute the loop in the context of the instance\"\nend\n"
  },
  {
    "path": "spec/spec.opts",
    "content": "--colour"
  },
  {
    "path": "test/hello_world_test/Makefile",
    "content": "# Arduino makefile\n#\n# This makefile allows you to build sketches from the command line\n# without the Arduino environment (or Java).\n#\n# The Arduino environment does preliminary processing on a sketch before\n# compiling it.  If you're using this makefile instead, you'll need to do\n# a few things differently:\n#\n#   - Give your program's file a .cpp extension (e.g. foo.cpp).\n#\n#   - Put this line at top of your code: #include <WProgram.h>\n#\n#   - Write prototypes for all your functions (or define them before you\n#     call them).  A prototype declares the types of parameters a\n#     function will take and what type of value it will return.  This\n#     means that you can have a call to a function before the definition\n#     of the function.  A function prototype looks like the first line of\n#     the function, with a semi-colon at the end.  For example:\n#     int digitalRead(int pin);\n#\n#   - Write a main() function for your program that returns an int, calls\n#     init() and setup() once (in that order), and then calls loop()\n#     repeatedly():\n#\n#\tint main()\n#\t{\n#\t\tinit();\n#\t\tsetup();\n#\n#\t\tfor (;;)\n#\t\t\tloop();\n#\n#\t\treturn 0;\n#\t}\n#\n# Instructions for using the makefile:\n#\n#  1. Copy this file into the folder with your sketch.\n#\n#  2. Below, modify the line containing \"TARGET\" to refer to the name of\n#     of your program's file without an extension (e.g. TARGET = foo).\n#\n#  3. Modify the line containg \"ARDUINO\" to point the directory that\n#     contains the Arduino core (for normal Arduino installations, this\n#     is the hardware/cores/arduino sub-directory).\n#\n#  4. Modify the line containing \"PORT\" to refer to the filename\n#     representing the USB or serial connection to your Arduino board\n#     (e.g. PORT = /dev/tty.USB0).  If the exact name of this file\n#     changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).\n#\n#  5. At the command line, change to the directory containing your\n#     program's file and the makefile.\n#\n#  6. Type \"make\" and press enter to compile/verify your program.\n#\n#  7. Type \"make upload\", reset your Arduino board, and press enter  to\n#     upload your program to the Arduino board.\n#\n# $Id$\n\nPORT = /dev/tty.usb*\nTARGET = hello_world\nARDUINO = /Applications/arduino-0012/hardware/cores/arduino\nSOFTWARE_SERIAL = /Applications/arduino-0012/hardware/libraries/SoftwareSerial\nSRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \\\n$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \\\n$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \\\n$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c\nCXXSRC = $(ARDUINO)/HardwareSerial.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp $(ARDUINO)/Print.cpp\nMCU = atmega168\nASRC = \nF_CPU = 16000000\nFORMAT = ihex\nUPLOAD_RATE = 19200\nBIN_DIR = /Applications/arduino-0012/hardware/tools/avr/bin\n\n# Name of this Makefile (used for \"make depend\").\nMAKEFILE = Makefile\n\n# Debugging format.\n# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.\n# AVR (extended) COFF requires stabs, plus an avr-objcopy run.\nDEBUG = stabs\n\nOPT = s\n\n# Place -D or -U options here\nCDEFS = -DF_CPU=$(F_CPU)\nCXXDEFS = -DF_CPU=$(F_CPU)\n\n# Place -I options here\nCINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)\n+CXXINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)\n\n# Compiler flag to set the C Standard level.\n# c89   - \"ANSI\" C\n# gnu89 - c89 plus GCC extensions\n# c99   - ISO C99 standard (not yet fully implemented)\n# gnu99 - c99 plus GCC extensions\nCSTANDARD = -std=gnu99\nCDEBUG = -g$(DEBUG)\nCWARN = -Wall -Wstrict-prototypes\nCTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums\n#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)\n\nCFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)\nCXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)\n#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs \nLDFLAGS = -lm\n\n\n# Programming support using avrdude. Settings and variables.\nAVRDUDE_PROGRAMMER = stk500\nAVRDUDE_PORT = $(PORT)\nAVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex\nAVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \\\n  -b $(UPLOAD_RATE) -C /Applications/arduino-0012/hardware/tools/avr/etc/avrdude.conf\n\n# Program settings\nCC = $(BIN_DIR)/avr-gcc\nCXX = $(BIN_DIR)/avr-g++\nOBJCOPY = $(BIN_DIR)/avr-objcopy\nOBJDUMP = $(BIN_DIR)/avr-objdump\nAR  = $(BIN_DIR)/avr-ar\nSIZE = $(BIN_DIR)/avr-size\nNM = $(BIN_DIR)/avr-nm\nAVRDUDE = $(BIN_DIR)/avrdude\nREMOVE = rm -f\nMV = mv -f\n\n# Define all object files.\nOBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)\n\n# Define all listing files.\nLST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)\n\n# Combine all necessary flags and optional flags.\n# Add target processor to flags.\nALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)\nALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)\nALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)\n\n\n# Default target.\nall: build\n\nbuild: elf hex\n\nelf: $(TARGET).elf\nhex: $(TARGET).hex\neep: $(TARGET).eep\nlss: $(TARGET).lss \nsym: $(TARGET).sym\n\n# Program the device.  \nupload: $(TARGET).hex\n\t$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)\n\n\n\n\n# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.\nCOFFCONVERT=$(OBJCOPY) --debugging \\\n--change-section-address .data-0x800000 \\\n--change-section-address .bss-0x800000 \\\n--change-section-address .noinit-0x800000 \\\n--change-section-address .eeprom-0x810000 \n\n\ncoff: $(TARGET).elf\n\t$(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof\n\n\nextcoff: $(TARGET).elf\n\t$(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof\n\n\n.SUFFIXES: .elf .hex .eep .lss .sym\n\n.elf.hex:\n\t$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@\n\n.elf.eep:\n\t-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom=\"alloc,load\" \\\n\t--change-section-lma .eeprom=0 -O $(FORMAT) $< $@\n\n# Create extended listing file from ELF output file.\n.elf.lss:\n\t$(OBJDUMP) -h -S $< > $@\n\n# Create a symbol table from ELF output file.\n.elf.sym:\n\t$(NM) -n $< > $@\n\n\ncore.a: $(OBJ)\n\t@for i in $(OBJ); do echo $(AR) rcs core.a $$i; $(AR) rcs core.a $$i; done\n\n# Link: create ELF output file from library.\n$(TARGET).elf: core.a\n\t$(CC) $(ALL_CFLAGS) -o $@ $(TARGET).cpp -L. core.a $(LDFLAGS)\n\n# Compile: create object files from C++ source files.\n.cpp.o:\n\t$(CXX) -c $(ALL_CXXFLAGS) $< -o $@ \n\n# Compile: create object files from C source files.\n.c.o:\n\t$(CC) -c $(ALL_CFLAGS) $< -o $@ \n\n\n# Compile: create assembler files from C source files.\n.c.s:\n\t$(CC) -S $(ALL_CFLAGS) $< -o $@\n\n\n# Assemble: create object files from assembler source files.\n.S.o:\n\t$(CC) -c $(ALL_ASFLAGS) $< -o $@\n\n\n\n# Target: clean project.\nclean:\n\t$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \\\n\t$(TARGET).map $(TARGET).sym $(TARGET).lss core.a \\\n\t$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)\n\ndepend:\n\tif grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \\\n\tthen \\\n\t\tsed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \\\n\t\t\t$(MAKEFILE).$$$$ && \\\n\t\t$(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \\\n\tfi\n\techo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \\\n\t\t>> $(MAKEFILE); \\\n\t$(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)\n\n.PHONY:\tall build elf hex eep lss sym program coff extcoff clean depend\n# DO NOT DELETE THIS LINE -- make depend depends on it.\npins_arduino.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/pins_arduino.c \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/pins_arduino.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/pgmspace.h\nwiring.o: /Applications/arduino-0012/hardware/cores/arduino/wiring.c \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h\nwiring_analog.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/wiring_analog.c \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/pins_arduino.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/pgmspace.h\nwiring_digital.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/wiring_digital.c \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/pins_arduino.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/pgmspace.h\nwiring_pulse.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/wiring_pulse.c \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/pins_arduino.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/pgmspace.h\nwiring_serial.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/wiring_serial.c \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h\nwiring_shift.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/wiring_shift.c \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h\nWInterrupts.o:  \\\n /Applications/arduino-0012/hardware/cores/arduino/WInterrupts.c \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/inttypes.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdint.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/io.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/sfr_defs.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iom168.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/iomx8.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/portpins.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/common.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/version.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/fuse.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/lock.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/interrupt.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/pgmspace.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stddef.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/stdio.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/include/stdarg.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/WConstants.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/binary.h \\\n  /Applications/arduino-0012/hardware/cores/arduino/wiring_private.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/avr/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay.h \\\n  /Applications/arduino-0012/hardware/tools/avr/bin/../lib/gcc/avr/4.3.0/../../../../avr/include/util/delay_basic.h\n"
  },
  {
    "path": "test/hello_world_test/hello_world.cpp",
    "content": "#include <WProgram.h>\n\nvoid loop();\nvoid setup();\nint main();\n\nvoid setup() {\n\tpinMode(13, OUTPUT);\n}\n\nint main() {\n\tinit();\n\tsetup();\n\tfor( ;; ) { loop(); }\n\treturn 0;\n}\n    \nvoid loop() {\n\tdigitalWrite( 13, HIGH );\n\tdelay( 500 );\n\tdigitalWrite( 13, LOW );\n\tdelay( 500 );\n}"
  },
  {
    "path": "test/test_array_processing.rb",
    "content": "$TESTING = true\n\n# need to tell it where we are\n# lets review these\n# neee to remove this constant from tests and pull it from rad\nC_VAR_TYPES = \"unsigned|int|long|double|str|char|byte|float|bool\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/variable_processing\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/arduino_sketch\"\nrequire 'test/unit'\n\n\nclass TestArrayProcessing < Test::Unit::TestCase\n\n  def setup\n    @t = ArduinoSketch.new\n    # vars\n  end\n  \n  # with July 25 2008 rework of arrays, this needs reworking/pruning\n  \n  def test_int_array\n    name = \"foo_a\"\n    value_string = \"int tomatoes[]\"\n    expected = \"int tomatoes[];\"\n    result = @t.array(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_array_with_semi\n    name = \"foo_b\"\n    value_string = \"int tomatoes[];\"\n    expected = \"int tomatoes[];\"\n    result = @t.array(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_array_with_assignment\n    name = \"foo_c\"\n    value_string = \"int tomatoes[] = {1,2,3,4}\"\n    expected = \"int tomatoes[] = {1,2,3,4};\"\n    result = @t.array(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_array_with_assignment_and_semi\n    name = \"foo_d\"\n    value_string = \"int tomatoes[] = {1,2,3};\"\n    expected = \"int tomatoes[] = {1,2,3};\"\n    result = @t.array(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_unsigned_int_array\n    name = \"foo_e\"\n    value_string = \"unsigned int tomatoes[]\"\n    expected = \"unsigned int tomatoes[];\"\n    result = @t.array(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_unsigned_int_array_with_assignment\n    name = \"foo_f\"\n    value_string = \"unsigned int tomatoes[] = {1,2,3};\"\n    expected = \"unsigned int tomatoes[] = {1,2,3};\"\n    result = @t.array(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  ### adding defines\n  \n  def test_define_numbers\n    name = \"foo_g\"\n    value_string = \"NUMBERS 10\"\n    expected = \"#define NUMBERS 10\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_define_numbers_type\n    name = \"foo_gg\"\n    value_string = \"NUMBERS 10\"\n    expected = \"long\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[1])\n  end\n  \n  def test_define_value_type_long_via_gvar\n    name = \"foo_ggg\"\n    value_string = \"NUMBERS 10\"\n    expected = \"long\"\n    result = @t.define(value_string)\n    assert_equal(expected, $define_types[\"NUMBERS\"])\n  end\n  \n  def test_define_string\n    name = \"foo_h\"\n    value_string = \"TEXT word\"\n    expected = \"#define TEXT \\\"word\\\"\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_define_string_type\n     name = \"foo_hh\"\n     value_string = \"TEXT word\"\n     expected = \"str\"\n     result = @t.define(value_string)\n     assert_equal(expected, result[1])\n   end\n   \n   def test_define_string_type__via_gvar\n     name = \"foo_hhh\"\n     value_string = \"TEXT word\"\n     expected = \"str\"\n     result = @t.define(value_string)\n     assert_equal(expected, $define_types[\"TEXT\"])\n   end\n  \n  def test_define_stings_with_spaces\n    name = \"foo_i\"\n    value_string = \"TEXT words with spaces\"\n    expected = \"#define TEXT \\\"words with spaces\\\"\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_define_stings_with_spaces_type\n    name = \"foo_ii\"\n    value_string = \"TEXT words with spaces\"\n    expected = \"str\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[1])\n  end\n  \n  def test_define_stings_with_spaces_type_via_gvar\n    name = \"foo_iii\"\n    value_string = \"TEXT words with spaces\"\n    expected = \"str\"\n    result = @t.define(value_string)\n    assert_equal(expected, $define_types[\"TEXT\"])\n  end\n  \n  def test_define_float\n    name = \"foo_j\"\n    value_string = \"FLOAT 10.0\"\n    expected = \"#define FLOAT 10.0\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_define_float_type\n    name = \"foo_jj\"\n    value_string = \"FLOAT 10.0\"\n    expected = \"float\"\n    result = @t.define(value_string)\n    assert_equal(expected, result[1])\n  end\n\n  \n  def test_define_float_type_via_gvar\n    name = \"foo_jjj\"\n    value_string = \"FLOAT 10.0\"\n    expected = \"float\"\n    result = @t.define(value_string)\n    assert_equal(expected, $define_types[\"FLOAT\"])\n  end\n  \n#\n  \n  \n  \n  \n  \n  \n  \n  \n  # question for brian... do we need variable assignment with no value when\n  # we have \"\" and 0\nend"
  },
  {
    "path": "test/test_plugin_loading.rb",
    "content": "#!/usr/local/bin/ruby -w\n\n$TESTING = true\n\n# this is a test stub for now\n# lets review these\n# neee to remove this constant from tests and pull it from rad\nPLUGIN_C_VAR_TYPES = \"int|void|unsigned|long|short|uint8_t|static|char\\\\*|byte\"\n\nrequire \"rubygems\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/rad_processor.rb\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/rad_rewriter.rb\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/rad_type_checker.rb\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/variable_processing\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/arduino_sketch\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/arduino_plugin\"\nrequire 'test/unit'\n\n\n\n\nclass TestPluginLoading < Test::Unit::TestCase\n\n  \n\n\n  def setup\n    $external_var_identifiers = [\"__foo\", \"__toggle\", \"wiggle\"]   \n    $define_types = { \"KOOL\" => \"long\", \"ZAK\" => \"str\"}\n    $array_types = { \"my_array\" => \"int\"}  \n    $plugin_directives = []\n    $plugin_external_variables = []\n    $plugin_signatures =[]\n    $plugin_methods = []\n    $add_to_setup = []\n    $load_libraries = []\n    $plugin_structs = {}\n    $plugin_methods_hash = {}  \n    $plugins_to_load = []  \n    plugin_signatures = []\n    plugin_methods = []\n     \n    @plugin_string =<<-STR\n    class PluginTesting < ArduinoPlugin\n\n\n\n     #\n     #\n     #  BlinkM_funcs.h -- Arduino library to control BlinkM\n     #  --------------\n     #\n     #\n     #  Note: original version of this file lives with the BlinkMTester sketch\n     #\n     #  2007, Tod E. Kurt, ThingM, http://thingm.com/\n     #\n     #  version: 20080203\n     #\n     #  history:\n     #   20080101 - initial release\n     #   20080203 - added setStartupParam(), bugfix receiveBytes() from Dan Julio\n     #\t20080727 - ported to rad jd barnhart\n     #\n     #   first step, declare output pin 19 as i2c\n     ##  output_pin 19, :as => :wire, :device => :i2c, :enable => :true # reminder, true issues wire.begin\n\n\n     include_wire\n\n     add_blink_m_struct\n\n\n\n     # Not needed when pin is declared with :enable => :true \n\n     static int BlinkM_sendBack(byte addr)\n     {\n       int num = 0x11;\n       char buf[5];\n       itoa(num, buf, 16);\n       return \"cool\"\n     }\n \n     static char* another_method(byte addr)\n     {\n       int num = 0x11;\n       char buf[5];\n       itoa(num, buf, 16);\n       return \"cool\"\n     }\n\n    end\n    STR\n\n    @sketch_string =<<-STR\n    class SanMiquel < ArduinoSketch\n\n     # looking for hints?  check out the examples directory\n     # example sketches can be uploaded to your arduino with\n     # rake make:upload sketch=examples/hello_world\n     # just replace hello_world with other examples\n\n       def loop\n         delay 100\n         my_lcd.home \"k\"\n         my_lcd.setxy 0,1\n\n         BlinkM_sendBack 10\n         delay 1000\n         test_address\n       end\n\n\n    end\n\n    STR\n    \n  end\n  \n  # remove these external variables and parens on variables\n  # need to actually run code through ruby_to_c for some of these tests\n  \n  def test_int\n    name = \"foo_a\"\n    # check_for_plugin_use(sketch_string, plugin_string, file_name)\n    ArduinoPlugin.check_for_plugin_use(@sketch_string, @plugin_string, \"hello_plugins\")\n    value_string = \"int(__toggle = 0);\"\n    expected =  [\"hello_plugins\"]\n    result = $plugins_to_load\n    assert_equal(expected, result)\n  end\n  \n  def test_two\n    name = \"foo_a\"\n    # check_for_plugin_use(sketch_string, plugin_string, file_name)\n    ArduinoPlugin.check_for_plugin_use(@sketch_string, @plugin_string, \"hello_plugins\")\n    value_string = \"int(__toggle = 0);\"\n    expected = {\"hello_plugins\"=>[\"BlinkM_sendBack\", \"another_method\"]}\n    result = $plugin_methods_hash\n    assert_equal(expected, result)\n  end\n  \n  \n  \n  ## need to look at unsigned long \n  ## need parens removal tests\n  \n\n\nend"
  },
  {
    "path": "test/test_translation_post_processing.rb",
    "content": "#!/usr/local/bin/ruby -w\n\n$TESTING = true\n\n# this is a test stub for now\n# lets review these\n# neee to remove this constant from tests and pull it from rad\nC_VAR_TYPES = \"unsigned|int|long|double|str|char|byte|float|bool\"\nrequire \"rubygems\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/rad_processor.rb\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/rad_rewriter.rb\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/rad_type_checker.rb\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/variable_processing\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/arduino_sketch\"\nrequire 'test/unit'\n\n\nclass TranslationTesting < ArduinoSketch\n\n  def one\n    delay 1\n  end\n  \n  def two\n    delay 1\n    @foo = 1\n  end\n  \n  def three\n    @foo = 1\n    bar = 2\n    baz = wha\n  end\n  \n  def four\n    @foo = 1\n    bar = 2\n    wiggle = wha\n  end\n  \n  def five\n    @foo = 1\n    f = KOOL\n  end\n  \n  def six\n    a = ZAK\n    \n  end\n  \n  def seven(int)\n    # coerce int to long int\n    a = int * 2\n  end\n  \n  def eight(str)\n    # coerce str to string\n    a = ZAK + str\n  end\n  \n  def nine\n    @my_array.each do |a|\n      delay a\n    end\n  end\n  \n\nend\n\n\n\nclass TestTranslationPostProcessing < Test::Unit::TestCase\n\n  \n\n\n  def setup\n    $external_var_identifiers = [\"__foo\", \"__toggle\", \"wiggle\"]   \n    $define_types = { \"KOOL\" => \"long\", \"ZAK\" => \"str\"}\n    $array_types = { \"my_array\" => \"int\"}\n    \n    \n  end\n  \n  # remove these external variables and parens on variables\n  # need to actually run code through ruby_to_c for some of these tests\n  \n  def test_int\n    name = \"foo_a\"\n    value_string = \"int(__toggle = 0);\"\n    expected = \"\"\n    result = ArduinoSketch.post_process_ruby_to_c_methods(value_string)\n    assert_equal(expected, result)\n  end\n  \n  def test_bool\n    name = \"foo_b\"\n    value_string = \"bool(__toggle = 0);\"\n    expected = \"\"\n    result = ArduinoSketch.post_process_ruby_to_c_methods(value_string)\n    assert_equal(expected, result)\n  end\n  \n  def test_long\n    name = \"foo_c\"\n    value_string = \"long(__foo = 0);\"\n    expected = \"\"\n    result = ArduinoSketch.post_process_ruby_to_c_methods(value_string)\n    assert_equal(expected, result)\n  end\n  \n  def test_trans_one\n    name = \"foo_d\"\n    expected = \"void\\none() {\\ndelay(1);\\n}\"    \n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"one\")\n    assert_equal(expected, result)\n  end\n  \n  # notice the nice behavior of @foo\n  def test_trans_two\n    name = \"foo_e\"\n    expected = \"void\\ntwo() {\\ndelay(1);\\n__foo = 1;\\n}\"    \n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"two\")\n    assert_equal(expected, result)\n  end\n  \n  # notice the nice behavior of @foo\n  def test_trans_three\n    name = \"foo_f\"\n    expected = \"void\\nthree() {\\nlong bar;\\nvoid * baz;\\n__foo = 1;\\nbar = 2;\\nbaz = wha();\\n}\"    \n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"three\")\n    assert_equal(expected, result)\n  end\n  \n  # need to take a closer look at this ... include \"void * wiggle\" regex?\n  # \n  def test_trans_four\n    name = \"foo_f\"\n    expected = \"void\\nfour() {\\nlong bar;\\nvoid * wiggle;\\n__foo = 1;\\nbar = 2;\\nwiggle = wha();\\n}\"    \n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"four\")\n    assert_equal(expected, result)\n  end\n  \n  def test_trans_five\n    name = \"foo_f\"\n    expected = \"void\\nfive() {\\nlong f;\\n__foo = 1;\\nf = KOOL;\\n}\"\n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"five\")\n    assert_equal(expected, result)\n  end\n  \n  def test_trans_six\n    name = \"foo_f\"\n    expected = \"void\\nsix() {\\nstr a;\\na = ZAK;\\n}\"\n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"six\")\n    assert_equal(expected, result)\n  end\n  \n  def test_trans_seven\n    name = \"foo_f\"\n    expected = \"void\\nseven(long int) {\\nlong a;\\na = int * 2;\\n}\"\n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"seven\")\n    assert_equal(expected, result)\n  end\n  \n  def test_trans_eight\n    name = \"foo_f\"\n    expected = \"void\\neight(long str) {\\nvoid * a;\\na = ZAK + str;\\n}\"\n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"eight\")\n    assert_equal(expected, result)\n  end\n  \n  def test_trans_nine\n    name = \"foo_f\"\n    expected = \"void\\nnine() {\\nunsigned int index_a;\\nfor (index_a = 0; index_a < (int) (sizeof(__my_array) / sizeof(__my_array[0])); index_a++) {\\nint a = __my_array[index_a];\\ndelay(a);\\n}\\n}\"\n    result = raw_rtc_meth = RADProcessor.translate(TranslationTesting, \"nine\")\n    assert_equal(expected, result)\n  end\n  \n  \n  ## need to look at unsigned long \n  ## need parens removal tests\n  \n\n\nend"
  },
  {
    "path": "test/test_variable_processing.rb",
    "content": "#!/usr/local/bin/ruby -w\n\n$TESTING = true\n\n# need to tell it where we are\n# lets review these\n# neee to remove this constant from tests and pull it from rad\nC_VAR_TYPES = \"unsigned|int|long|double|str|char|byte|float|bool\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/variable_processing\"\nrequire \"#{File.expand_path(File.dirname(__FILE__))}/../lib/rad/arduino_sketch\"\nrequire 'test/unit'\n\n\n\nclass TestVariableProcessing < Test::Unit::TestCase\n\n  def setup\n    @t = ArduinoSketch.new\n  end\n  \n  # question for brian... do we need variable assignment with no value when\n  # we have \"\" and 0\n  \n\n\n  def test_int_as_int\n    name = \"foo_a\"\n    value_string = 1\n    expected = \"int __foo_a = 1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_string_as_int\n    name = \"foo_b\"\n    value_string = \"1\"\n    expected = \"int __foo_b = 1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_float_as_float\n    name = \"foo_c\"\n    value_string = 0.10\n    expected = \"float __foo_c = 0.1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_string_as_float\n    name = \"foo_d\"\n    value_string = \"0.10\"\n    expected = \"float __foo_d = 0.1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_byte # would this to return hex\n    name = \"foo_f\"\n    value_string = 0x00\n    expected = \"int __foo_f = 0;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_byte_with_string_input\n    name = \"foo_g\"\n    value_string = \"0x00\"\n    expected = \"byte __foo_g = 0x00;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_string\n    name = \"foo_h\"\n    value_string = \"arduino\"\n    expected = \"char* __foo_h = \\\"arduino\\\";\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_type\n    name = \"foo_i\"\n    value_string = \"int\"\n    expected = \"int __foo_i;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_odd_name\n    name = \"bacon_j\"\n    value_string = \"arduino\"\n    expected = \"char* __bacon_j = \\\"arduino\\\";\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_type_two\n    name = \"foo_k\"\n    value_string = \"2, int\"\n    expected = \"int __foo_k = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_long\n    name = \"foo_l\"\n    value_string = \"2, int\"\n    expected = \"int __foo_l = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_byte\n    name = \"foo_m\"\n    value_string = \"2, byte\"\n    expected = \"byte __foo_m = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_unsigned_int\n    name = \"foo_n\"\n    value_string = \"2, unsigned int\"\n    expected = \"unsigned int __foo_n = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_unsigned_long\n    name = \"foo_o\"\n    value_string = \"2, unsigned long\"\n    expected = \"unsigned long __foo_o = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_short_int\n    name = \"foo_q\"\n    value_string = \"2, short int\"\n    expected = \"short int __foo_q = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_int_with_unsigned_short_int\n    name = \"foo_r\"\n    value_string = \"2, unsigned short int\"\n    expected = \"unsigned short int __foo_r = 2;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_float_with_type\n    name = \"foo_s\"\n    value_string = \"2.0, float\"\n    expected = \"float __foo_s = 2.0;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_true\n    name = \"foo_t\"\n    value_string = true\n    expected = \"bool __foo_t = 1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_false\n    name = \"foo_v\"\n    value_string = false\n    expected = \"bool __foo_v = 0;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_negative_int_string\n    name = \"foo_w\"\n    value_string = \"-1, int\"\n    expected = \"int __foo_w = -1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_negative_float_string\n    name = \"foo_x\"\n    value_string = \"-0.1, float\"\n    expected = \"float __foo_x = -0.1;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_negative_larger_float_string\n    name = \"foo_y\"\n    value_string = \"-1000.01, float\"\n    expected = \"float __foo_y = -1000.01;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_negative_long_string\n    name = \"foo_z\"\n    value_string = \"-.0991, float\"\n    expected = \"float __foo_z = -0.0991;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_negative_float_string_two\n    name = \"foo_aa\"\n    value_string = \"-.01, float\"\n    expected = \"float __foo_aa = -0.01;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_negative_interter_string\n    name = \"foo_bb\"\n    value_string = \"-.01, float\"\n    expected = \"float __foo_bb = -0.01;\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  def test_dash_string\n    name = \"foo_cc\"\n    value_string = \"-hmmm\"\n    expected = \"char* __foo_cc = \\\"-hmmm\\\";\"\n    result = @t.pre_process_vars(name, value_string)\n    assert_equal(expected, result[0])\n  end\n  \n  \n  \n\n  \nend\n"
  },
  {
    "path": "website/examples/assembler_test.rb.html",
    "content": "<html>\n  <head>\n    <title>assembler_test.rb.html</title\n    <style type=\"text/css\">\n\n\t.ruby .normal {}\n\t.ruby .comment { color: #888; font-style: italic; }\n\t.ruby .keyword { color: #A00; font-weight: bold; }\n\t.ruby .method { color: #077; }\n\t.ruby .class { color: #074; }\n\t.ruby .module { color: #050; }\n\t.ruby .punct { color: #447; font-weight: bold; }\n\t.ruby .symbol { color: #099; }\n\t.ruby .string { color: #944; }\n\t.ruby .char { color: #F07; }\n\t.ruby .ident { color: #004; }\n\t.ruby .constant { color: #07F; }\n\t.ruby .regex { color: #B66; }\n\t.ruby .number { color: #D55; }\n\t.ruby .attribute { color: #377; }\n\t.ruby .global { color: #3B7; }\n\t.ruby .expr { color: #227; }\n    </style>\n  </head>\n  <body>\n    <pre class=\"ruby\">\n<pre><span class=\"comment\"># Hardware: Connect to serial output with screen:</span>\n<span class=\"comment\">#           $ screen /dev/tty/path.to.your.usb 9600</span>\n\n<span class=\"keyword\">class </span><span class=\"class\">AssemblerTest</span> <span class=\"punct\">&lt;</span> <span class=\"constant\">ArduinoSketch</span>\n  <span class=\"ident\">vars</span> <span class=\"symbol\">:a</span> <span class=\"punct\">=&gt;</span> <span class=\"number\">10</span><span class=\"punct\">,</span> <span class=\"symbol\">:b</span> <span class=\"punct\">=&gt;</span> <span class=\"number\">4</span>\n  <span class=\"ident\">serial_begin</span>\n  \n  <span class=\"keyword\">def </span><span class=\"method\">loop</span>\n    <span class=\"ident\">serial_println</span> <span class=\"ident\">product</span><span class=\"punct\">(</span><span class=\"ident\">a</span><span class=\"punct\">,</span><span class=\"ident\">b</span><span class=\"punct\">)</span>\n  <span class=\"keyword\">end</span>\n  \n  <span class=\"ident\">assembler</span><span class=\"punct\">(</span> <span class=\"symbol\">:product</span><span class=\"punct\">,</span> <span class=\"punct\">&quot;</span><span class=\"string\">int product(int a, int b);</span><span class=\"punct\">&quot;,</span>\n    <span class=\"punct\">&lt;&lt;-</span><span class=\"constant\">CODE</span><span class=\"string\">\n    product:\n      \tmov  r18,r24\t; move a to another register\n      \tldi  r24,0\t\t; clear running sum, used to coalesce product\n      \tldi  r25,0\t\t; sum = 0\n      \n      .loop:\n      \ttst  r18\t\t  ; is a = 0? if so, we're done\n      \tbreq .end\n      \n      \tmov  r19,r18\t; copy a\n      \tandi r19,1\t\t; is a % 2 == 0\n      \tbreq .skip\t\t\n      \n      \tadd  r24,r22\t; add b to sum\n      \tadc  r25,r23\n      \n      .skip:\n      \tlsr  r18\t\t  ; divide a by 2\n      \n      \tclc\t\t\t\n      \trol  r22\t\t  ; multiply b by 2\n      \trol  r23\n      \trjmp .loop\n      \n      .end:\n      \tret\n      \t.size product, .-product\n</span><span class=\"constant\">    CODE</span>\n  <span class=\"punct\">)</span>\n<span class=\"keyword\">end</span>\n</pre>\n    </pre>\n  </body>\n</html>\n"
  },
  {
    "path": "website/examples/gps_reader.rb.html",
    "content": "<html>\n  <head>\n    <title>gps_reader.rb.html</title\n    <style type=\"text/css\">\n\n\t.ruby .normal {}\n\t.ruby .comment { color: #888; font-style: italic; }\n\t.ruby .keyword { color: #A00; font-weight: bold; }\n\t.ruby .method { color: #077; }\n\t.ruby .class { color: #074; }\n\t.ruby .module { color: #050; }\n\t.ruby .punct { color: #447; font-weight: bold; }\n\t.ruby .symbol { color: #099; }\n\t.ruby .string { color: #944; }\n\t.ruby .char { color: #F07; }\n\t.ruby .ident { color: #004; }\n\t.ruby .constant { color: #07F; }\n\t.ruby .regex { color: #B66; }\n\t.ruby .number { color: #D55; }\n\t.ruby .attribute { color: #377; }\n\t.ruby .global { color: #3B7; }\n\t.ruby .expr { color: #227; }\n    </style>\n  </head>\n  <body>\n    <pre class=\"ruby\">\n<pre><span class=\"keyword\">class </span><span class=\"class\">GpsReader</span> <span class=\"punct\">&lt;</span> <span class=\"constant\">ArduinoSketch</span>\n  <span class=\"ident\">output_pin</span> <span class=\"number\">13</span><span class=\"punct\">,</span> <span class=\"symbol\">:as</span> <span class=\"punct\">=&gt;</span> <span class=\"symbol\">:led</span>\n  <span class=\"ident\">software_serial</span> <span class=\"number\">6</span><span class=\"punct\">,</span> <span class=\"number\">7</span><span class=\"punct\">,</span> <span class=\"symbol\">:as</span> <span class=\"punct\">=&gt;</span> <span class=\"symbol\">:gps</span>\n  <span class=\"ident\">serial_begin</span>\n\n  <span class=\"keyword\">def </span><span class=\"method\">loop</span>\n    <span class=\"ident\">digitalWrite</span><span class=\"punct\">(</span><span class=\"ident\">led</span><span class=\"punct\">,</span> <span class=\"constant\">true</span><span class=\"punct\">)</span>\n    <span class=\"ident\">serial_print</span><span class=\"punct\">(</span><span class=\"ident\">gps</span><span class=\"punct\">.</span><span class=\"ident\">read</span><span class=\"punct\">)</span>\n  <span class=\"keyword\">end</span>\n<span class=\"keyword\">end</span></pre>\n    </pre>\n  </body>\n</html>\n"
  },
  {
    "path": "website/examples/hello_world.rb.html",
    "content": "<html>\n  <head>\n    <title>hello_world.rb.html</title\n    <style type=\"text/css\">\n\n\t.ruby .normal {}\n\t.ruby .comment { color: #888; font-style: italic; }\n\t.ruby .keyword { color: #A00; font-weight: bold; }\n\t.ruby .method { color: #077; }\n\t.ruby .class { color: #074; }\n\t.ruby .module { color: #050; }\n\t.ruby .punct { color: #447; font-weight: bold; }\n\t.ruby .symbol { color: #099; }\n\t.ruby .string { color: #944; }\n\t.ruby .char { color: #F07; }\n\t.ruby .ident { color: #004; }\n\t.ruby .constant { color: #07F; }\n\t.ruby .regex { color: #B66; }\n\t.ruby .number { color: #D55; }\n\t.ruby .attribute { color: #377; }\n\t.ruby .global { color: #3B7; }\n\t.ruby .expr { color: #227; }\n    </style>\n  </head>\n  <body>\n    <pre class=\"ruby\">\n<pre><span class=\"comment\"># Hardware: LED connected on pin 7</span>\n\n<span class=\"keyword\">class </span><span class=\"class\">HelloWorld</span> <span class=\"punct\">&lt;</span> <span class=\"constant\">ArduinoSketch</span>\n  <span class=\"ident\">output_pin</span> <span class=\"number\">7</span><span class=\"punct\">,</span> <span class=\"symbol\">:as</span> <span class=\"punct\">=&gt;</span> <span class=\"symbol\">:led</span>\n  <span class=\"keyword\">def </span><span class=\"method\">loop</span>\n    <span class=\"ident\">blink</span> <span class=\"ident\">led</span><span class=\"punct\">,</span> <span class=\"number\">500</span>\n  <span class=\"keyword\">end</span>\n<span class=\"keyword\">end</span>\n</pre>\n    </pre>\n  </body>\n</html>\n"
  },
  {
    "path": "website/examples/serial_motor.rb.html",
    "content": "<html>\n  <head>\n    <title>serial_motor.rb.html</title\n    <style type=\"text/css\">\n\n\t.ruby .normal {}\n\t.ruby .comment { color: #888; font-style: italic; }\n\t.ruby .keyword { color: #A00; font-weight: bold; }\n\t.ruby .method { color: #077; }\n\t.ruby .class { color: #074; }\n\t.ruby .module { color: #050; }\n\t.ruby .punct { color: #447; font-weight: bold; }\n\t.ruby .symbol { color: #099; }\n\t.ruby .string { color: #944; }\n\t.ruby .char { color: #F07; }\n\t.ruby .ident { color: #004; }\n\t.ruby .constant { color: #07F; }\n\t.ruby .regex { color: #B66; }\n\t.ruby .number { color: #D55; }\n\t.ruby .attribute { color: #377; }\n\t.ruby .global { color: #3B7; }\n\t.ruby .expr { color: #227; }\n    </style>\n  </head>\n  <body>\n    <pre class=\"ruby\">\n<pre><span class=\"comment\"># Hardware: motor control circuit (i.e. TIP-120 control pin)</span>\n<span class=\"comment\">#           connected at pin 7.</span>\n<span class=\"comment\">#     Demo: http://www.youtube.com/watch?v=7OguEBfdTe0</span>\n\n<span class=\"keyword\">class </span><span class=\"class\">SerialMotor</span> <span class=\"punct\">&lt;</span> <span class=\"constant\">ArduinoSketch</span>\n  <span class=\"ident\">output_pin</span> <span class=\"number\">7</span><span class=\"punct\">,</span> <span class=\"symbol\">:as</span> <span class=\"punct\">=&gt;</span> <span class=\"symbol\">:motor</span>\n  <span class=\"ident\">serial_begin</span>\n  \n  <span class=\"keyword\">def </span><span class=\"method\">loop</span>\n    <span class=\"ident\">digitalWrite</span><span class=\"punct\">(</span><span class=\"ident\">motor</span><span class=\"punct\">,</span> <span class=\"ident\">serial_read</span><span class=\"punct\">)</span> <span class=\"keyword\">if</span> <span class=\"ident\">serial_available</span>\n  <span class=\"keyword\">end</span>\n<span class=\"keyword\">end</span></pre>\n    </pre>\n  </body>\n</html>\n"
  },
  {
    "path": "website/index.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n  <link rel=\"stylesheet\" href=\"stylesheets/screen.css\" type=\"text/css\" media=\"screen\" />\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n  <title>\n      RAD\n  </title>\n  <script src=\"javascripts/rounded_corners_lite.inc.js\" type=\"text/javascript\"></script>\n<style>\n\t.movie {float: left; margin-right: 10px; margin-bottom: 10px;}\n</style>\n  <script type=\"text/javascript\">\n    window.onload = function() {\n      settings = {\n          tl: { radius: 10 },\n          tr: { radius: 10 },\n          bl: { radius: 10 },\n          br: { radius: 10 },\n          antiAlias: true,\n          autoPad: true,\n          validTags: [\"div\"]\n      }\n      var versionBox = new curvyCorners(settings, document.getElementById(\"version\"));\n      versionBox.applyCornersToAll();\n    }\n  </script>\n</head>\n<body>\n<div id=\"main\">\n\t\t<div id=\"metadata\">\n\t\t\t<div id=\"version\" class=\"clickable\" onclick='document.location = \"http://rubyforge.org/projects/rad\"; return false'>\n    \t  <p>Get Version</p>\n    \t  <a href=\"http://rubyforge.org/projects/rad\" class=\"numbers\">0.2.2</a>\n    \t</div>\n\t\t\t<div id=\"buy-arduino\">\n\t\t\t  <h3>Sponsored by:</h3>\n\t\t\t  <h4>The Shoppe at Wulfden</h4>\n\t\t\t  <a href=\"http://www.wulfden.org/freeduino/freeduino.shtml\">\n\t\t\t\t  <img src=\"http://www.wulfden.org/freeduino/freeduino-1.jpg\" /><br />\n\t\t\t\t</a>\n\t\t\t\t<h4><a href=\"http://www.wulfden.org/freeduino/freeduino.shtml\">Totally Open Arduino-Compatible Hardware</a></h4>\n\t\t\t\t\n\n\t\t\t</div>\n\t\t</div>\n    <h1>RAD</h1>\n    <h1>&#x2192; &#8216;Ruby Arduino Development&#8217;</h1>\n\t\t\t\n\t\t\t\n\n\n\t<h2>What?</h2>\n\n\n\t<p><span class=\"caps\">RAD</span> is a framework for programming the Arduino physcial computing platform using Ruby. <span class=\"caps\">RAD</span> converts Ruby scripts written using a set of Rails-like conventions and helpers into C source code which can be compiled and run on the Arduino microcontroller. It also provides a set of Rake tasks for automating the compilation and upload process.</p>\n\n<br style=\"clear:both\" />\n\n\t<h2>Demo: 'Hello World'</h2>\n\n\t<p>Here's a basic demo of <span class=\"caps\">RAD</span> in action. In this movie, we'll write, compile, and upload the universal physical computing 'Hello World': a single flashing LED.\n\t\t<div class=\"movie\"><object width=\"425\" height=\"355\"><param name=\"movie\" value=\"http://www.youtube.com/v/AKbHcMaC_cA&hl=en\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/AKbHcMaC_cA&hl=en\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"355\"></embed></object></div>\n\t\t<em>Note: This movie was made using an old version of the Arduino board which required a hardware reset before being able to accept a new sketch. More recent versions of the board don't have this requirement and hence as of version 0.2.0, <span class=\"caps\">RAD</span> no longer prompts for reset when running 'rake make:upload' (thought the option is still available for older boards.)</em>\n\t</p>\n\t<br style=\"clear:both\" />\n\t<h2>Why?</h2>\n\n\n\t<p>While duplicating the functionality of the well-designed Arduino software interface in Ruby may seem like an odd or redundant goal, <span class=\"caps\">RAD</span> has further ambitions! Bootstrapping the ability to write microcontroller code in a high level dynamic language like Ruby could greatly ease the creation of all the luxurious development aids the users of such a language have come to expect: developer testing, platform independence, easy metaprogramming, etc.</p>\n\n\n\t<h2>Installing</h2>\n\n\n\t<p><code>$ sudo gem install rad</code></p>\n\n\n\t<p>You&#8217;ll also need to have the Arduino environment installed, which you can get from <a href=\"http://www.arduino.cc/en/Main/Software\">the Arduino website</a>.  <span class=\"caps\">RAD</span> currently requires Arduino 0011, but we try to keep it up-to-date with new Arduino releases.</p>\t\n\n\n\t<h2>The Basics</h2>\n\n\n\t<p><code>$ rad my_sketch</code></p>\n\n\n\t<p>This command will create a new <span class=\"caps\">RAD</span> project directory (my_sketch/) inside of the current directory that contains a blank script in which you can write your own <span class=\"caps\">RAD</span> code, as well as a full install of the <span class=\"caps\">RAD</span> support infrastructure (in vendor/). A sample &#8216;hello world&#8217; script in <span class=\"caps\">RAD</span> will look like this:</p>\n\n\n<pre syntax=\"ruby\">\nclass MySketch &lt; ArduinoSketch\n  output_pin 7, :as =&gt; :led\n  def loop\n    blink led, 500\n  end\nend\n</pre>\n\n\t<p>Once your code is written, your relevant local configuration properly setup in <code>config/hardware.rb</code> and <code>config/software.rb</code>, and an Arduino with the corresponding circuit (a 220ohm resistor and an <span class=\"caps\">LED</span> wired in series between Arduino pin 7 and ground) is connected to your computer via serial, run:</p>\n\n\n\t<p><code>$ rake make:upload</code></p>\n\n\n\t<p>This will:</p>\n\n\n\t<ul>\n\t<li>generate the correct Arduino C++ code from your sketch</li>\n\t\t<li>dynamically prepare a localized version of the default Arduino Makefile</li>\n\t\t<li>compile your sketch</li>\n\t\t<li>prompt you to hit the reset button on your Arduino (if necessary!)</li>\n\t\t<li>upload your compiled binary onto your Arduino</li>\n\t</ul>\n\n\n\t<h2>Documentation and The Arduino <span class=\"caps\">API</span></h2>\n\n\n\t<p>Most of <a href=\"http://www.arduino.cc/en/Reference/HomePage\">the Arduino software <span class=\"caps\">API</span></a> should be working correctly at this point. Documentation for RAD's version of things and details about usage of the wider Arduino API are available in the <a href=\"http://rad.rubyforge.org/rdoc\">RAD rDocs</a>.</p>\n\n\t<h2>Demo: Serial Communication</h2>\n\t<p>\n\t\tTo demonstrate some of the more advanced features of <span class=\"caps\">RAD</span>, here's a movie showing how to program the Arduino to listen to serial communication from a computer. \n\t\t<div class=\"movie\">\n\t\t\t<object width=\"425\" height=\"355\"><param name=\"movie\" value=\"http://www.youtube.com/v/7OguEBfdTe0&hl=en\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/7OguEBfdTe0&hl=en\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"355\"></embed></object>\t\t</div>\n\n\t\t\t<em>Note: The same comment from above applies here about the hardware reset. Also, extra points are available if you recognize the logo on the flag in the video.</em>\t\n\t</p>\n\t<br style=\"clear:both\" />\n\t\n\t<p>For more examples of <span class=\"caps\">RAD</span> in action, see <a href=\"http://rad.rubyforge.org/examples\">the RAD example directory</a>.</p>\n\t<h2><span class=\"caps\">RAD</span> Needs You!</h2>\n\n\n\t<p>All the many discipline-crossing skills required for a project like <span class=\"caps\">RAD</span> make for lots of opportunities to help out: Have you written lots of sketches exploring the obscure depths of the Arduino library? Do you run the Arduino development tool chain on an obscure (i.e., non-OS X) platform? Do you develop for other <span class=\"caps\">AVR</span> or <span class=\"caps\">PIC</span> microcontrollers? Are you a C/C++ ninja? Or even C/C++ competent?</p>\n\n\n\t<p>There&#8217;s lots to do.</p>\n\n\n\t<p>If you&#8217;re looking for a place to dive in and don&#8217;t know quite where, <a href=\"mailto:ruby-arduino-development@googlegroups.com\">email the RAD Google Group</a>; we're friendly! If you want to start by taking a look at the code, check out RAD on GitHub: <code>http://github.com/atduskgreg/rad/tree/master</code>.</p>\n\n\n\t<h2>License</h2>\n\n\n\t<p>This code is free to use under the terms of the <span class=\"caps\">GPL</span> 2.0 license, just like the Arduino software library itself.</p>\n\n\n\t<h2>Contact</h2>\n\n\n\t<p>Comments, questions, heckles, attacks, praises, and, (most especially) patches and contributions are welcome! Send email to <a href=\"mailto:ruby-arduino-development@googlegroups.com\">the RAD mailing list</a>.</p>\n\t\n\t\t<h2>Who</h2>\n<p><a href=\"http://urbanhonking.com/ideasfordozens\">Greg Borenstein</a> is RAD's original author and main maintainer with significant contributions from <a href=\"http://blog.bleything.net/\">Ben Bleything</a> and <a href=\"http://www.wulfden.org/TheShoppe.shtml\">Brian Riley</a>, patches from Scott Windsor and David Michael, and the support of the <a href=\"http://groups.google.com/group/ruby-arduino-development\">the Ruby Arduino Development Google Group</a>.</p>\n\t\n    <p class=\"coda\">\n      <a href=\"mailto:drnicwilliams@gmail.com\">Dr Nic</a>, 18th November 2007<br>\n      Theme extended from <a href=\"http://rb2js.rubyforge.org/\">Paul Battley</a>\n    </p>\n</div>\n\n<!-- insert site tracking codes here, like Google Urchin -->\n<script type=\"text/javascript\">\nvar gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www.\");\ndocument.write(unescape(\"%3Cscript src='\" + gaJsHost + \"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E\"));\n</script>\n<script type=\"text/javascript\">\nvar pageTracker = _gat._getTracker(\"UA-3885443-1\");\npageTracker._initData();\npageTracker._trackPageview();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "website/index.txt",
    "content": "h1. RAD\n\nh1. &#x2192; 'Ruby Arduino Development'\n\nh2. What?\n\nRAD is a framework for programming the Arduino physcial computing platform using Ruby. RAD converts Ruby scripts written using a set of Rails-like conventions and helpers into C source code which can be compiled and run on the Arduino microcontroller. It also provides a set of Rake tasks for automating the compilation and upload process.\n\nh2. Why?\n\nWhile duplicating the functionality of the well-designed Arduino software interface in Ruby may seem like an odd or redundant goal, RAD has further ambitions! Bootstrapping the ability to write microcontroller code in a high level dynamic language like Ruby could greatly ease the creation of all the luxurious development aids the users of such a language have come to expect: developer testing, platform independence, easy metaprogramming, etc.\n\nh2. Installing\n\n@$ sudo gem install rad@\n\nYou'll also need to have the Arduino environment installed, which you can get from \"the Arduino website\":http://www.arduino.cc/en/Main/Software.  RAD currently requires Arduino 0010, but we try to keep it up-to-date with new Arduino releases.\n\nh2. The Basics\n\n@$ rad my_sketch@\n\nThis command will create a new RAD project directory (my_sketch/) inside of the current directory that contains a blank script in which you can write your own RAD code, as well as a full install of the RAD support infrastructure (in vendor/). A sample 'hello world' script in RAD will look like this:\n\n<pre syntax=\"ruby\">\nclass MySketch < ArduinoSketch\n  output_pin 7, :as => :led\n  def loop\n    blink led, 500\n  end\nend\n</pre>\n\nOnce your code is written, your relevant local configuration properly setup in @config/hardware.rb@ and @config/software.rb@, and an Arduino with the corresponding circuit (a 220ohm resistor and an LED wired in series between Arduino pin 7 and ground) is connected to your computer via serial, run:\n\n@$ rake make:upload@\n\nThis will:\n\n * generate the correct Arduino C++ code from your sketch\n * dynamically prepare a localized version of the default Arduino Makefile\n * compile your sketch\n * prompt you to hit the reset button on your Arduino (if necessary!)\n * upload your compiled binary onto your Arduino\n\nh2. The Arduino API\n\nWith the exception of the still-experimental Serial interface, most of <a href=\"http://www.arduino.cc/en/Reference/HomePage\">the Arduino software API</a> should be working correctly at this point. Documentation for the Ruby versions of the methods is forthcoming, but it is mostly what you'd expect: methods with identical names and arguments to their Arduino counterparts with the exception of using 'true' and 'false' for HIGH and LOW.\n\nh2. RAD Needs You!\n\nAll the many discipline-crossing skills required for a project like RAD make for lots of opportunities to help out: Have you written lots of sketches exploring the obscure depths of the Arduino library? Do you run the Arduino development tool chain on an obscure (i.e., non-OS X) platform? Do you develop for other AVR or PIC microcontrollers? Are you a C/C++ ninja? Or even C/C++ competent?\n\nThere's lots to do.\n\nIf you're looking for a place to dive in and don't know quite where, \"email Greg\":mailto:greg@grabb.it. If you want to start by taking a log at the code, the trunk repository is @svn://rubyforge.org/var/svn/rad/trunk@ for anonymous access.\n\nh2. License\n\nThis code is free to use under the terms of the GPL 2.0 license, just like the Arduino software library itself.  \n\nh2. Contact\n\nComments, questions, heckles, attacks, praises, and, (most especially) patches and contributions are welcome! Send email to \"Greg Borenstein\":mailto:greg@grabb.it.\n"
  },
  {
    "path": "website/javascripts/rounded_corners_lite.inc.js",
    "content": "\n /****************************************************************\n  *                                                              *\n  *  curvyCorners                                                *\n  *  ------------                                                *\n  *                                                              *\n  *  This script generates rounded corners for your divs.        *\n  *                                                              *\n  *  Version 1.2.9                                               *\n  *  Copyright (c) 2006 Cameron Cooke                            *\n  *  By: Cameron Cooke and Tim Hutchison.                        *\n  *                                                              *\n  *                                                              *\n  *  Website: http://www.curvycorners.net                        *\n  *  Email:   info@totalinfinity.com                             *\n  *  Forum:   http://www.curvycorners.net/forum/                 *\n  *                                                              *\n  *                                                              *\n  *  This library is free software; you can redistribute         *\n  *  it and/or modify it under the terms of the GNU              *\n  *  Lesser General Public License as published by the           *\n  *  Free Software Foundation; either version 2.1 of the         *\n  *  License, or (at your option) any later version.             *\n  *                                                              *\n  *  This library is distributed in the hope that it will        *\n  *  be useful, but WITHOUT ANY WARRANTY; without even the       *\n  *  implied warranty of MERCHANTABILITY or FITNESS FOR A        *\n  *  PARTICULAR PURPOSE. See the GNU Lesser General Public       *\n  *  License for more details.                                   *\n  *                                                              *\n  *  You should have received a copy of the GNU Lesser           *\n  *  General Public License along with this library;             *\n  *  Inc., 59 Temple Place, Suite 330, Boston,                   *\n  *  MA 02111-1307 USA                                           *\n  *                                                              *\n  ****************************************************************/\n  \nvar isIE = navigator.userAgent.toLowerCase().indexOf(\"msie\") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()\n{ if(typeof(arguments[0]) != \"object\") throw newCurvyError(\"First parameter of curvyCorners() must be an object.\"); if(typeof(arguments[1]) != \"object\" && typeof(arguments[1]) != \"string\") throw newCurvyError(\"Second parameter of curvyCorners() must be an object or a class name.\"); if(typeof(arguments[1]) == \"string\")\n{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}\nelse\n{ var startIndex = 1; var boxCol = arguments;}\nvar curvyCornersCol = new Array(); if(arguments[0].validTags)\nvar validElements = arguments[0].validTags; else\nvar validElements = [\"div\"]; for(var i = startIndex, j = boxCol.length; i < j; i++)\n{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)\n{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}\n}\nthis.objects = curvyCornersCol; this.applyCornersToAll = function()\n{ for(var x = 0, k = this.objects.length; x < k; x++)\n{ this.objects[x].applyCorners();}\n}\n}\nfunction curvyObject()\n{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, \"height\", \"height\"); var boxWidth = get_style(this.box, \"width\", \"width\"); var borderWidth = get_style(this.box, \"borderTopWidth\", \"border-top-width\"); var borderColour = get_style(this.box, \"borderTopColor\", \"border-top-color\"); var boxColour = get_style(this.box, \"backgroundColor\", \"background-color\"); var backgroundImage = get_style(this.box, \"backgroundImage\", \"background-image\"); var boxPosition = get_style(this.box, \"position\", \"position\"); var boxPadding = get_style(this.box, \"paddingTop\", \"padding-top\"); this.boxHeight = parseInt(((boxHeight != \"\" && boxHeight != \"auto\" && boxHeight.indexOf(\"%\") == -1)? boxHeight.substring(0, boxHeight.indexOf(\"px\")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != \"\" && boxWidth != \"auto\" && boxWidth.indexOf(\"%\") == -1)? boxWidth.substring(0, boxWidth.indexOf(\"px\")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != \"\" && borderWidth.indexOf(\"px\") !== -1)? borderWidth.slice(0, borderWidth.indexOf(\"px\")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != \"\" && boxPadding.indexOf(\"px\") !== -1)? boxPadding.slice(0, boxPadding.indexOf(\"px\")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + \"px\" + \" solid \" + this.borderColour; this.backgroundImage = ((backgroundImage != \"none\")? backgroundImage : \"\"); this.boxContent = this.box.innerHTML; if(boxPosition != \"absolute\") this.box.style.position = \"relative\"; this.box.style.padding = \"0px\"; if(isIE && boxWidth == \"auto\" && boxHeight == \"auto\") this.box.style.width = \"100%\"; if(this.settings.autoPad == true && this.boxPadding > 0)\nthis.box.innerHTML = \"\"; this.applyCorners = function()\n{ for(var t = 0; t < 2; t++)\n{ switch(t)\n{ case 0:\nif(this.settings.tl || this.settings.tr)\n{ var newMainContainer = document.createElement(\"DIV\"); newMainContainer.style.width = \"100%\"; newMainContainer.style.fontSize = \"1px\"; newMainContainer.style.overflow = \"hidden\"; newMainContainer.style.position = \"absolute\"; newMainContainer.style.paddingLeft = this.borderWidth + \"px\"; newMainContainer.style.paddingRight = this.borderWidth + \"px\"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + \"px\"; newMainContainer.style.top = 0 - topMaxRadius + \"px\"; newMainContainer.style.left = 0 - this.borderWidth + \"px\"; this.topContainer = this.box.appendChild(newMainContainer);}\nbreak; case 1:\nif(this.settings.bl || this.settings.br)\n{ var newMainContainer = document.createElement(\"DIV\"); newMainContainer.style.width = \"100%\"; newMainContainer.style.fontSize = \"1px\"; newMainContainer.style.overflow = \"hidden\"; newMainContainer.style.position = \"absolute\"; newMainContainer.style.paddingLeft = this.borderWidth + \"px\"; newMainContainer.style.paddingRight = this.borderWidth + \"px\"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + \"px\"; newMainContainer.style.bottom = 0 - botMaxRadius + \"px\"; newMainContainer.style.left = 0 - this.borderWidth + \"px\"; this.bottomContainer = this.box.appendChild(newMainContainer);}\nbreak;}\n}\nif(this.topContainer) this.box.style.borderTopWidth = \"0px\"; if(this.bottomContainer) this.box.style.borderBottomWidth = \"0px\"; var corners = [\"tr\", \"tl\", \"br\", \"bl\"]; for(var i in corners)\n{ if(i > -1 < 4)\n{ var cc = corners[i]; if(!this.settings[cc])\n{ if(((cc == \"tr\" || cc == \"tl\") && this.topContainer != null) || ((cc == \"br\" || cc == \"bl\") && this.bottomContainer != null))\n{ var newCorner = document.createElement(\"DIV\"); newCorner.style.position = \"relative\"; newCorner.style.fontSize = \"1px\"; newCorner.style.overflow = \"hidden\"; if(this.backgroundImage == \"\")\nnewCorner.style.backgroundColor = this.boxColour; else\nnewCorner.style.backgroundImage = this.backgroundImage; switch(cc)\n{ case \"tl\":\nnewCorner.style.height = topMaxRadius - this.borderWidth + \"px\"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + \"px\"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + \"px\"; break; case \"tr\":\nnewCorner.style.height = topMaxRadius - this.borderWidth + \"px\"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + \"px\"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = \"-\" + (topMaxRadius + this.borderWidth) + \"px 0px\"; newCorner.style.left = this.borderWidth + \"px\"; break; case \"bl\":\nnewCorner.style.height = botMaxRadius - this.borderWidth + \"px\"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + \"px\"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + \"px\"; newCorner.style.backgroundPosition = \"-\" + (this.borderWidth) + \"px -\" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + \"px\"; break; case \"br\":\nnewCorner.style.height = botMaxRadius - this.borderWidth + \"px\"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + \"px\"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + \"px\"\nnewCorner.style.backgroundPosition = \"-\" + (botMaxRadius + this.borderWidth) + \"px -\" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + \"px\"; break;}\n}\n}\nelse\n{ if(this.masterCorners[this.settings[cc].radius])\n{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}\nelse\n{ var newCorner = document.createElement(\"DIV\"); newCorner.style.height = this.settings[cc].radius + \"px\"; newCorner.style.width = this.settings[cc].radius + \"px\"; newCorner.style.position = \"absolute\"; newCorner.style.fontSize = \"1px\"; newCorner.style.overflow = \"hidden\"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)\n{ if((intx +1) >= borderRadius)\nvar y1 = -1; else\nvar y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)\n{ if((intx) >= borderRadius)\nvar y2 = -1; else\nvar y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)\nvar y3 = -1; else\nvar y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}\nif((intx) >= j)\nvar y4 = -1; else\nvar y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)\n{ for(var inty = (y1 + 1); inty < y2; inty++)\n{ if(this.settings.antiAlias)\n{ if(this.backgroundImage != \"\")\n{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)\n{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}\nelse\n{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}\n}\nelse\n{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}\n}\n}\nif(this.settings.antiAlias)\n{ if(y3 >= y2)\n{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}\n}\nelse\n{ if(y3 >= y1)\n{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}\n}\nvar outsideColour = this.borderColour;}\nelse\n{ var outsideColour = this.boxColour; var y3 = y1;}\nif(this.settings.antiAlias)\n{ for(var inty = (y3 + 1); inty < y4; inty++)\n{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}\n}\n}\nthis.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}\nif(cc != \"br\")\n{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)\n{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf(\"px\"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf(\"px\"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf(\"px\"))); if(cc == \"tl\" || cc == \"bl\"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + \"px\";}\nif(cc == \"tr\" || cc == \"tl\"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + \"px\";}\nswitch(cc)\n{ case \"tr\":\npixelBar.style.backgroundPosition = \"-\" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + \"px -\" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + \"px\"; break; case \"tl\":\npixelBar.style.backgroundPosition = \"-\" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + \"px -\" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + \"px\"; break; case \"bl\":\npixelBar.style.backgroundPosition = \"-\" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + \"px -\" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + \"px\"; break;}\n}\n}\n}\nif(newCorner)\n{ switch(cc)\n{ case \"tl\":\nif(newCorner.style.position == \"absolute\") newCorner.style.top = \"0px\"; if(newCorner.style.position == \"absolute\") newCorner.style.left = \"0px\"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case \"tr\":\nif(newCorner.style.position == \"absolute\") newCorner.style.top = \"0px\"; if(newCorner.style.position == \"absolute\") newCorner.style.right = \"0px\"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case \"bl\":\nif(newCorner.style.position == \"absolute\") newCorner.style.bottom = \"0px\"; if(newCorner.style.position == \"absolute\") newCorner.style.left = \"0px\"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case \"br\":\nif(newCorner.style.position == \"absolute\") newCorner.style.bottom = \"0px\"; if(newCorner.style.position == \"absolute\") newCorner.style.right = \"0px\"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}\n}\n}\n}\nvar radiusDiff = new Array(); radiusDiff[\"t\"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)\nradiusDiff[\"b\"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)\n{ if(z == \"t\" || z == \"b\")\n{ if(radiusDiff[z])\n{ var smallerCornerType = ((this.settings[z + \"l\"].radius < this.settings[z + \"r\"].radius)? z +\"l\" : z +\"r\"); var newFiller = document.createElement(\"DIV\"); newFiller.style.height = radiusDiff[z] + \"px\"; newFiller.style.width = this.settings[smallerCornerType].radius+ \"px\"\nnewFiller.style.position = \"absolute\"; newFiller.style.fontSize = \"1px\"; newFiller.style.overflow = \"hidden\"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)\n{ case \"tl\":\nnewFiller.style.bottom = \"0px\"; newFiller.style.left = \"0px\"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case \"tr\":\nnewFiller.style.bottom = \"0px\"; newFiller.style.right = \"0px\"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case \"bl\":\nnewFiller.style.top = \"0px\"; newFiller.style.left = \"0px\"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case \"br\":\nnewFiller.style.top = \"0px\"; newFiller.style.right = \"0px\"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}\n}\nvar newFillerBar = document.createElement(\"DIV\"); newFillerBar.style.position = \"relative\"; newFillerBar.style.fontSize = \"1px\"; newFillerBar.style.overflow = \"hidden\"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)\n{ case \"t\":\nif(this.topContainer)\n{ if(this.settings.tl.radius && this.settings.tr.radius)\n{ newFillerBar.style.height = topMaxRadius - this.borderWidth + \"px\"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + \"px\"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + \"px\"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != \"\")\nnewFillerBar.style.backgroundPosition = \"-\" + (topMaxRadius + this.borderWidth) + \"px 0px\"; this.topContainer.appendChild(newFillerBar);}\nthis.box.style.backgroundPosition = \"0px -\" + (topMaxRadius - this.borderWidth) + \"px\";}\nbreak; case \"b\":\nif(this.bottomContainer)\n{ if(this.settings.bl.radius && this.settings.br.radius)\n{ newFillerBar.style.height = botMaxRadius - this.borderWidth + \"px\"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + \"px\"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + \"px\"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != \"\")\nnewFillerBar.style.backgroundPosition = \"-\" + (botMaxRadius + this.borderWidth) + \"px -\" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + \"px\"; this.bottomContainer.appendChild(newFillerBar);}\n}\nbreak;}\n}\n}\nif(this.settings.autoPad == true && this.boxPadding > 0)\n{ var contentContainer = document.createElement(\"DIV\"); contentContainer.style.position = \"relative\"; contentContainer.innerHTML = this.boxContent; contentContainer.className = \"autoPadDiv\"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)\ncontentContainer.style.paddingTop = topPadding + \"px\"; if(botMaxRadius < this.boxPadding)\ncontentContainer.style.paddingBottom = botMaxRadius + \"px\"; contentContainer.style.paddingLeft = this.boxPadding + \"px\"; contentContainer.style.paddingRight = this.boxPadding + \"px\"; this.contentDIV = this.box.appendChild(contentContainer);}\n}\nthis.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)\n{ var pixel = document.createElement(\"DIV\"); pixel.style.height = height + \"px\"; pixel.style.width = \"1px\"; pixel.style.position = \"absolute\"; pixel.style.fontSize = \"1px\"; pixel.style.overflow = \"hidden\"; var topMaxRadius = Math.max(this.settings[\"tr\"].radius, this.settings[\"tl\"].radius); if(image == -1 && this.backgroundImage != \"\")\n{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = \"-\" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + \"px -\" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + \"px\";}\nelse\n{ pixel.style.backgroundColor = colour;}\nif (transAmount != 100)\nsetOpacity(pixel, transAmount); pixel.style.top = inty + \"px\"; pixel.style.left = intx + \"px\"; newCorner.appendChild(pixel);}\n}\nfunction insertAfter(parent, node, referenceNode)\n{ parent.insertBefore(node, referenceNode.nextSibling);}\nfunction BlendColour(Col1, Col2, Col1Fraction)\n{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return \"#\" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}\nfunction IntToHex(strNum)\n{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}\nfunction MakeHex(x)\n{ if((x >= 0) && (x <= 9))\n{ return x;}\nelse\n{ switch(x)\n{ case 10: return \"A\"; case 11: return \"B\"; case 12: return \"C\"; case 13: return \"D\"; case 14: return \"E\"; case 15: return \"F\";}\n}\n}\nfunction pixelFraction(x, y, r)\n{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = \"\"; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))\n{ whatsides = \"Left\"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}\nvar intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))\n{ whatsides = whatsides + \"Top\"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}\nvar intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))\n{ whatsides = whatsides + \"Right\"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}\nvar intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))\n{ whatsides = whatsides + \"Bottom\"; xvalues[point] = intersect - x; yvalues[point] = 0;}\nswitch (whatsides)\n{ case \"LeftRight\":\npixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case \"TopRight\":\npixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case \"TopBottom\":\npixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case \"LeftBottom\":\npixelfraction = (yvalues[0]*xvalues[1])/2; break; default:\npixelfraction = 1;}\nreturn pixelfraction;}\nfunction rgb2Hex(rgbColour)\n{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = \"#\" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}\ncatch(e){ alert(\"There was an error converting the RGB value to Hexadecimal in function rgb2Hex\");}\nreturn hexColour;}\nfunction rgb2Array(rgbColour)\n{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(\")\")); var rgbArray = rgbValues.split(\", \"); return rgbArray;}\nfunction setOpacity(obj, opacity)\n{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != \"IFRAME\")\n{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = \"rgba(\" + red + \", \" + green + \", \" + blue + \", \" + opacity/100 + \")\";}\nelse if(typeof(obj.style.opacity) != \"undefined\")\n{ obj.style.opacity = opacity/100;}\nelse if(typeof(obj.style.MozOpacity) != \"undefined\")\n{ obj.style.MozOpacity = opacity/100;}\nelse if(typeof(obj.style.filter) != \"undefined\")\n{ obj.style.filter = \"alpha(opacity:\" + opacity + \")\";}\nelse if(typeof(obj.style.KHTMLOpacity) != \"undefined\")\n{ obj.style.KHTMLOpacity = opacity/100;}\n}\nfunction inArray(array, value)\n{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}\nreturn false;}\nfunction inArrayKey(array, value)\n{ for(key in array){ if(key === value) return true;}\nreturn false;}\nfunction addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}\nelse if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}\nelse { elm['on' + evType] = fn;}\n}\nfunction removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent(\"on\"+evType, fn); return r;} else { alert(\"Handler could not be removed\");}\n}\nfunction format_colour(colour)\n{ var returnColour = \"#ffffff\"; if(colour != \"\" && colour != \"transparent\")\n{ if(colour.substr(0, 3) == \"rgb\")\n{ returnColour = rgb2Hex(colour);}\nelse if(colour.length == 4)\n{ returnColour = \"#\" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}\nelse\n{ returnColour = colour;}\n}\nreturn returnColour;}\nfunction get_style(obj, property, propertyNS)\n{ try\n{ if(obj.currentStyle)\n{ var returnVal = eval(\"obj.currentStyle.\" + property);}\nelse\n{ if(isSafari && obj.style.display == \"none\")\n{ obj.style.display = \"\"; var wasHidden = true;}\nvar returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)\n{ obj.style.display = \"none\";}\n}\n}\ncatch(e)\n{ }\nreturn returnVal;}\nfunction getElementsByClass(searchClass, node, tag)\n{ var classElements = new Array(); if(node == null)\nnode = document; if(tag == null)\ntag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp(\"(^|\\s)\"+searchClass+\"(\\s|$)\"); for (i = 0, j = 0; i < elsLen; i++)\n{ if(pattern.test(els[i].className))\n{ classElements[j] = els[i]; j++;}\n}\nreturn classElements;}\nfunction newCurvyError(errorMessage)\n{ return new Error(\"curvyCorners Error:\\n\" + errorMessage)\n}\n"
  },
  {
    "path": "website/stylesheets/code.css",
    "content": ".ruby .normal {}\n.ruby .comment { color: #888; font-style: italic; }\n.ruby .keyword { color: #A00; font-weight: bold; }\n.ruby .method { color: #077; }\n.ruby .class { color: #074; }\n.ruby .module { color: #050; }\n.ruby .punct { color: #447; font-weight: bold; }\n.ruby .symbol { color: #099; }\n.ruby .string { color: #944; }\n.ruby .char { color: #F07; }\n.ruby .ident { color: #004; }\n.ruby .constant { color: #07F; }\n.ruby .regex { color: #B66; }\n.ruby .number { color: #D55; }\n.ruby .attribute { color: #377; }\n.ruby .global { color: #3B7; }\n.ruby .expr { color: #227; })"
  },
  {
    "path": "website/stylesheets/screen.css",
    "content": "body {\r\n  background-color: #E1D1F1;\r\n  font-family: \"Georgia\", sans-serif;\r\n  font-size: 16px;\r\n  line-height: 1.6em;\r\n  padding: 1.6em 0 0 0;\r\n  color: #333;\r\n}\r\nh1, h2, h3, h4, h5, h6 {\r\n  color: #444;\r\n}\r\nh1 { \r\n  font-family: sans-serif;\r\n  font-weight: normal;\r\n  font-size: 4em;\r\n  line-height: 0.8em;\r\n  letter-spacing: -0.1ex;\r\n\tmargin: 5px;\r\n}\r\nli {\r\n  padding: 0;\r\n  margin: 0;\r\n  list-style-type: square;\r\n}\r\na {\r\n  color: #5E5AFF;\r\n\tbackground-color: #DAC;\r\n  font-weight: normal;\r\n  text-decoration: underline;\r\n}\r\nblockquote {\r\n  font-size: 90%;\r\n  font-style: italic;\r\n  border-left: 1px solid #111;\r\n  padding-left: 1em;\r\n}\r\n\r\n#buy-arduino {\r\n\tfloat:left;\r\n\tmargin-right: 10px;\r\n\tborder: 8px solid #000;\r\n\tbackground-color: #fff;\r\n\tpadding: 5px;\r\n\ttext-align:center;\r\n}\r\n\r\n#buy-arduino h4{\r\n\tfont-size: 12px;\r\n\tmargin: 0;\r\n}\r\n\r\n#buy-arduino a {\r\n\tbackground-color: #fff;\r\n}\r\n\r\n#buy-arduino img{\r\n\twidth: 190px;\r\n\tborder: none;\r\n}\r\n\r\n.caps {\r\n  font-size: 80%;\r\n}\r\n\r\n#main {\r\n  width: 45em;\r\n  padding: 0;\r\n  margin: 0 auto;\r\n}\r\n.coda {\r\n  text-align: right;\r\n  color: #77f;\r\n  font-size: smaller;\r\n}\r\n\r\ntable {\r\n  font-size: 90%;\r\n  line-height: 1.4em;\r\n  color: #ff8;\r\n  background-color: #111;\r\n  padding: 2px 10px 2px 10px;\r\n\tborder-style: dashed;\r\n}\r\n\r\nth {\r\n\tcolor: #fff;\r\n}\r\n\r\ntd {\r\n  padding: 2px 10px 2px 10px;\r\n}\r\n\r\n.success {\r\n\tcolor: #0CC52B;\r\n}\r\n\r\n.failed {\r\n\tcolor: #E90A1B;\r\n}\r\n\r\n.unknown {\r\n\tcolor: #995000;\r\n}\r\npre, code {\r\n  font-family: monospace;\r\n  font-size: 90%;\r\n  line-height: 1.4em;\r\n  color: #ff8;\r\n  background-color: #111;\r\n  padding: 2px 10px 2px 10px;\r\n}\r\n.comment { color: #aaa; font-style: italic; }\r\n.keyword { color: #eff; font-weight: bold; }\r\n.punct { color: #eee; font-weight: bold; }\r\n.symbol { color: #0bb; }\r\n.string { color: #6b4; }\r\n.ident { color: #ff8; }\r\n.constant { color: #66f; }\r\n.regex { color: #ec6; }\r\n.number { color: #F99; }\r\n.expr { color: #227; }\r\n\r\n#metadata {\r\n\t\tfloat: left;\r\n\t\tmargin-right: 20px;\r\n}\r\n\r\n#version {\r\n\twidth:210px;\r\n  text-align: right;\r\n  font-family: sans-serif;\r\n  font-weight: normal;\r\n  background-color: #B3ABFF;\r\n  color: #141331;\r\n  padding: 15px 20px 10px 20px;\r\n  margin: 0 auto;\r\n\tmargin-top: 15px;\r\n  border: 3px solid #141331;\r\n\tmargin-bottom: 20px;\r\n\r\n}\r\n\r\n#version .numbers {\r\n  display: block;\r\n  font-size: 4em;\r\n  line-height: 0.8em;\r\n  letter-spacing: -0.1ex;\r\n\tmargin-bottom: 15px;\r\n}\r\n\r\n#version p {\r\n  text-decoration: none;\r\n\tcolor: #141331;\r\n\tbackground-color: #B3ABFF;\r\n\tmargin: 0;\r\n\tpadding: 0;\r\n}\r\n\r\n#version a {\r\n  text-decoration: none;\r\n\tcolor: #141331;\r\n\tbackground-color: #B3ABFF;\r\n}\r\n\r\n.clickable {\r\n\tcursor:\tpointer; \r\n\tcursor:\thand;\r\n}\r\n\r\n"
  },
  {
    "path": "website/template.rhtml",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n  <link rel=\"stylesheet\" href=\"stylesheets/screen.css\" type=\"text/css\" media=\"screen\" />\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n  <title>\n      <%= title %>\n  </title>\n  <script src=\"javascripts/rounded_corners_lite.inc.js\" type=\"text/javascript\"></script>\n<style>\n\n</style>\n  <script type=\"text/javascript\">\n    window.onload = function() {\n      settings = {\n          tl: { radius: 10 },\n          tr: { radius: 10 },\n          bl: { radius: 10 },\n          br: { radius: 10 },\n          antiAlias: true,\n          autoPad: true,\n          validTags: [\"div\"]\n      }\n      var versionBox = new curvyCorners(settings, document.getElementById(\"version\"));\n      versionBox.applyCornersToAll();\n    }\n  </script>\n</head>\n<body>\n<div id=\"main\">\n\n    <h1><%= title %></h1>\n    <div id=\"version\" class=\"clickable\" onclick='document.location = \"<%= download %>\"; return false'>\n      <p>Get Version</p>\n      <a href=\"<%= download %>\" class=\"numbers\"><%= version %></a>\n    </div>\n    <%= body %>\n    <p class=\"coda\">\n      <a href=\"mailto:drnicwilliams@gmail.com\">Dr Nic</a>, <%= modified.pretty %><br>\n      Theme extended from <a href=\"http://rb2js.rubyforge.org/\">Paul Battley</a>\n    </p>\n</div>\n\n<!-- insert site tracking codes here, like Google Urchin -->\n\n</body>\n</html>\n"
  }
]