packages feed

barley (empty) → 0.3

raw patch · 72 files changed

+5777/−0 lines, 72 filesdep +basedep +bytestringdep +containerssetup-changedbinary-added

Dependencies added: base, bytestring, containers, directory, filepath, ghc, ghc-prim, html, plugins, snap-core, snap-server, text, transformers, unix

Files

+ LICENSE view
@@ -0,0 +1,202 @@++                              Apache License+                        Version 2.0, January 2004+                     http://www.apache.org/licenses/++TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION++1. Definitions.++   "License" shall mean the terms and conditions for use, reproduction,+   and distribution as defined by Sections 1 through 9 of this document.++   "Licensor" shall mean the copyright owner or entity authorized by+   the copyright owner that is granting the License.++   "Legal Entity" shall mean the union of the acting entity and all+   other entities that control, are controlled by, or are under common+   control with that entity. For the purposes of this definition,+   "control" means (i) the power, direct or indirect, to cause the+   direction or management of such entity, whether by contract or+   otherwise, or (ii) ownership of fifty percent (50%) or more of the+   outstanding shares, or (iii) beneficial ownership of such entity.++   "You" (or "Your") shall mean an individual or Legal Entity+   exercising permissions granted by this License.++   "Source" form shall mean the preferred form for making modifications,+   including but not limited to software source code, documentation+   source, and configuration files.++   "Object" form shall mean any form resulting from mechanical+   transformation or translation of a Source form, including but+   not limited to compiled object code, generated documentation,+   and conversions to other media types.++   "Work" shall mean the work of authorship, whether in Source or+   Object form, made available under the License, as indicated by a+   copyright notice that is included in or attached to the work+   (an example is provided in the Appendix below).++   "Derivative Works" shall mean any work, whether in Source or Object+   form, that is based on (or derived from) the Work and for which the+   editorial revisions, annotations, elaborations, or other modifications+   represent, as a whole, an original work of authorship. For the purposes+   of this License, Derivative Works shall not include works that remain+   separable from, or merely link (or bind by name) to the interfaces of,+   the Work and Derivative Works thereof.++   "Contribution" shall mean any work of authorship, including+   the original version of the Work and any modifications or additions+   to that Work or Derivative Works thereof, that is intentionally+   submitted to Licensor for inclusion in the Work by the copyright owner+   or by an individual or Legal Entity authorized to submit on behalf of+   the copyright owner. For the purposes of this definition, "submitted"+   means any form of electronic, verbal, or written communication sent+   to the Licensor or its representatives, including but not limited to+   communication on electronic mailing lists, source code control systems,+   and issue tracking systems that are managed by, or on behalf of, the+   Licensor for the purpose of discussing and improving the Work, but+   excluding communication that is conspicuously marked or otherwise+   designated in writing by the copyright owner as "Not a Contribution."++   "Contributor" shall mean Licensor and any individual or Legal Entity+   on behalf of whom a Contribution has been received by Licensor and+   subsequently incorporated within the Work.++2. Grant of Copyright License. Subject to the terms and conditions of+   this License, each Contributor hereby grants to You a perpetual,+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable+   copyright license to reproduce, prepare Derivative Works of,+   publicly display, publicly perform, sublicense, and distribute the+   Work and such Derivative Works in Source or Object form.++3. Grant of Patent License. Subject to the terms and conditions of+   this License, each Contributor hereby grants to You a perpetual,+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable+   (except as stated in this section) patent license to make, have made,+   use, offer to sell, sell, import, and otherwise transfer the Work,+   where such license applies only to those patent claims licensable+   by such Contributor that are necessarily infringed by their+   Contribution(s) alone or by combination of their Contribution(s)+   with the Work to which such Contribution(s) was submitted. If You+   institute patent litigation against any entity (including a+   cross-claim or counterclaim in a lawsuit) alleging that the Work+   or a Contribution incorporated within the Work constitutes direct+   or contributory patent infringement, then any patent licenses+   granted to You under this License for that Work shall terminate+   as of the date such litigation is filed.++4. Redistribution. You may reproduce and distribute copies of the+   Work or Derivative Works thereof in any medium, with or without+   modifications, and in Source or Object form, provided that You+   meet the following conditions:++   (a) You must give any other recipients of the Work or+       Derivative Works a copy of this License; and++   (b) You must cause any modified files to carry prominent notices+       stating that You changed the files; and++   (c) You must retain, in the Source form of any Derivative Works+       that You distribute, all copyright, patent, trademark, and+       attribution notices from the Source form of the Work,+       excluding those notices that do not pertain to any part of+       the Derivative Works; and++   (d) If the Work includes a "NOTICE" text file as part of its+       distribution, then any Derivative Works that You distribute must+       include a readable copy of the attribution notices contained+       within such NOTICE file, excluding those notices that do not+       pertain to any part of the Derivative Works, in at least one+       of the following places: within a NOTICE text file distributed+       as part of the Derivative Works; within the Source form or+       documentation, if provided along with the Derivative Works; or,+       within a display generated by the Derivative Works, if and+       wherever such third-party notices normally appear. The contents+       of the NOTICE file are for informational purposes only and+       do not modify the License. You may add Your own attribution+       notices within Derivative Works that You distribute, alongside+       or as an addendum to the NOTICE text from the Work, provided+       that such additional attribution notices cannot be construed+       as modifying the License.++   You may add Your own copyright statement to Your modifications and+   may provide additional or different license terms and conditions+   for use, reproduction, or distribution of Your modifications, or+   for any such Derivative Works as a whole, provided Your use,+   reproduction, and distribution of the Work otherwise complies with+   the conditions stated in this License.++5. Submission of Contributions. Unless You explicitly state otherwise,+   any Contribution intentionally submitted for inclusion in the Work+   by You to the Licensor shall be under the terms and conditions of+   this License, without any additional terms or conditions.+   Notwithstanding the above, nothing herein shall supersede or modify+   the terms of any separate license agreement you may have executed+   with Licensor regarding such Contributions.++6. Trademarks. This License does not grant permission to use the trade+   names, trademarks, service marks, or product names of the Licensor,+   except as required for reasonable and customary use in describing the+   origin of the Work and reproducing the content of the NOTICE file.++7. Disclaimer of Warranty. Unless required by applicable law or+   agreed to in writing, Licensor provides the Work (and each+   Contributor provides its Contributions) on an "AS IS" BASIS,+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or+   implied, including, without limitation, any warranties or conditions+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A+   PARTICULAR PURPOSE. You are solely responsible for determining the+   appropriateness of using or redistributing the Work and assume any+   risks associated with Your exercise of permissions under this License.++8. Limitation of Liability. In no event and under no legal theory,+   whether in tort (including negligence), contract, or otherwise,+   unless required by applicable law (such as deliberate and grossly+   negligent acts) or agreed to in writing, shall any Contributor be+   liable to You for damages, including any direct, indirect, special,+   incidental, or consequential damages of any character arising as a+   result of this License or out of the use or inability to use the+   Work (including but not limited to damages for loss of goodwill,+   work stoppage, computer failure or malfunction, or any and all+   other commercial damages or losses), even if such Contributor+   has been advised of the possibility of such damages.++9. Accepting Warranty or Additional Liability. While redistributing+   the Work or Derivative Works thereof, You may choose to offer,+   and charge a fee for, acceptance of support, warranty, indemnity,+   or other liability obligations and/or rights consistent with this+   License. However, in accepting such obligations, You may act only+   on Your own behalf and on Your sole responsibility, not on behalf+   of any other Contributor, and only if You agree to indemnify,+   defend, and hold each Contributor harmless for any liability+   incurred by, or claims asserted against, such Contributor by reason+   of your accepting any such warranty or additional liability.++END OF TERMS AND CONDITIONS++APPENDIX: How to apply the Apache License to your work.++   To apply the Apache License to your work, attach the following+   boilerplate notice, with the fields enclosed by brackets "[]"+   replaced with your own identifying information. (Don't include+   the brackets!)  The text should be enclosed in the appropriate+   comment syntax for the file format. We also recommend that a+   file or class name and description of purpose be included on the+   same "printed page" as the copyright notice for easier+   identification within third-party archives.++Copyright [yyyy] [name of copyright owner]++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.
+ LICENSE-CodeMirror view
@@ -0,0 +1,23 @@+ Copyright (c) 2007-2010 Marijn Haverbeke++ This software is provided 'as-is', without any express or implied+ warranty. In no event will the authors be held liable for any+ damages arising from the use of this software.++ Permission is granted to anyone to use this software for any+ purpose, including commercial applications, and to alter it and+ redistribute it freely, subject to the following restrictions:++ 1. The origin of this software must not be misrepresented; you must+    not claim that you wrote the original software. If you use this+    software in a product, an acknowledgment in the product+    documentation would be appreciated but is not required.++ 2. Altered source versions must be plainly marked as such, and must+    not be misrepresented as being the original software.++ 3. This notice may not be removed or altered from any source+    distribution.++ Marijn Haverbeke+ marijnh@gmail.com
+ README.markdown view
@@ -0,0 +1,93 @@+Barley - A seed for learning Haskell+====================================++Barley is an environment for tinkering with [Haskell][1]. It is a web server+with an embedded simple programming environment rendered as web pages.+The environment allows you to easily edit Haskell code and quickly see the+result of running it.++Barley includes a tutorial aimed at people with some programming and web+experience, but it assumes no exposure to Haskell or functional programming.+The tutorial takes the developer from generating a simple web page through+a modest web application with database backend storage. Along the way it+exposes the programmer to the basic idioms needed to do simple programming+tasks.++Barley is based on the [Snap framework][2] for creating web programming in+Haskell. Barley adds a simple web application skeleton to support both the+live development environment and the tutorial projects. After going through+the tutorial, developers can use Barley to create and explore their own+simple web projects. Beyond that, they can smoothly transition to using the+whole Snap framework and the wealth of available Haskell libraries.++[1]: http://www.haskell.org/+[2]: http://snapframework.com/++Status+======++This is in the *very early concept stage*. We aren't even at a 0.1 release!+Read this code at your own risk!++Developers+----------++Barley was conceived during a flurry of Nepalese food by [Johan Tibell][jt]+and [Mark Lentczner][ml]. We got immediate encouragement from others 'round+the table and spent the rest of the night plotting, and in Johan's case coding.+The next morning we found ourselves in a coffee house with other Haskellers+cheering us on as we knocked off the first coding tasks.++[jt]: http://github.com/tibbe+[ml]: http://github.com/mtnviewmark++Running+-------++If you can't hold back and download this code, you can run it like so:++    cabal configure+    cabal build+    ghci -isrc:dist/build/autogen src/Main.hs+    > :main start playground++Note:++* `start` = initialize a new project if needed, then run barley on it.+* `playground` is just the name of a project directory, barley will create+  it if needed.+* If you don't `cabal install` barley, then it won't have access to its+  data directory unless you start it from the root of the dev. tree.+++License+=======++Copyright 2010 Google Inc.++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++     http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+++Additional Credits+------------------++* [jQuery][c1] *-- MIT License*+* [CodeMirror][c2] by Marijn Haverbeke *-- zlib-style license*+* ["A Lady Beetle Perches on Barley"][c3] by T. Voekler+  *-- Creative Commons Attribution-ShareAlike 3.0 Unported*+* [Silk Icons][c4] by Mark James *-- Creative Commons Attribution 2.5*++[c1]: http://jquery.com/+[c2]: http://codemirror.net/+[c3]: http://commons.wikimedia.org/wiki/File:A_lady_beetle_perches_on_barley.JPG+[c4]: http://www.famfamfam.com/lab/icons/silk/
+ SYLLABUS.markdown view
@@ -0,0 +1,295 @@+Barley Syllabus+===============++This document is to collect the ideas for barley's tutorial and included+examples. At present it contains just some ramblings. We need to pull this+into a more researched and clear syllabus soon.++Sources of inspiration for this include:++* [Real World Haskell](http://book.realworldhaskell.org/)+* [Learn You a Haskell for Great Good](http://learnyouahaskell.com/)+    ++Haskell Concepts+----------------++Barley should introduce a short list of Haskell concepts and idioms from a +practical point of view. The aim is to get programmers looking at and+editing examples of these idioms that do something. We are less interested+in explaining the details or the philosophic underpinnings in the tutorial+than getting them to the _"OIC, wow, cool, k thx bai"_ stage.++* Functions+* Numbers+* Strings & Text+* `case`, `if`, patterns, guards+* Lists+* `map`, `filter`, and friends+* List comprehensions+* `Maybe` and `Either`+* `do` syntax, in so far as it can be used with `Maybe`, `Either`, and `List`+* `fmap`, in so far as it can be used with `Maybe`, `Either`, and `List`+* Currying and Point-free style _(gently)_+* `data` types+* `type` and `newtype`+* Parameterized types+* Type classes and instances+* IO+* Modules: importing and exporting+++Web Concepts+------------++The tutorial's aim isn't to teach web programming. This is a list of web+concepts the tutorial should show how to do in Haskell. We are assuming+that most programmers coming to the tutorial have an inkling of how to do+these things in other languages.++* HTML generation+* Interleaving fixed HTML with generated content+* Getting query args+* Forms: generating, getting args and processing+* Referencing static elements+* Cookies+* Logging+* Read/Write simple file storage+* Read/Write SQLite storage+* Make outgoing HTTP requests+* Generate JSON+++Web Projects+------------++All of the above needs to be presented in the context of one or two+extended web projects that the developer builds during the bulk of+the tutorial. In addition, some concepts can be demonstrated in six+to eight examples left for the developer to explore after they've+done the tutorial. This is a list of possible projects:++* Simple twitter-like web site: accounts, sign up, sign in, message,+  render messages per user, front page of recent messages+* Guess the animal game with growing DB of animals.+* Unit conversion, simple calculator page.+* News feed mash up: show reddit, slashdot, tech news headlines on a+  a single page with links+* Polls: admin can create polls, users take 'em+* Blog+* Wiki+* Inventory (recipies, wine, videos, todos, etc...): Item entry, item detail, listing,+query, categories, bools(?)++++An Outline+----------++Ch 1: Static Pages+* Step 1: "Hello World"+    - comments, strings+    - basic html combinators & usage+* Step 2: "Shopping List"+    - lists+    - homogenous types (  [ "foo", bold << "bar" ]+    - toHtml+* Step 3: "Some Style"+    - first function, map, list comprehension+    - attributes, name exceptions+* Step 4: "+    - tuples, zip, ranges +    +    +Ch 2: Guessing Game+* Step 1: Form+    - if/then/else, comparison+    - http request & response objects+* Step 2: Encoding state+    - string functions, appending+    - ++Other Syllabi+-------------+LYAH's "Starting Out"+    numbers, negative numbers+    numeric expressions+    boolean expressions+    == and /=+    succ, min, max+    +    defining a simple function+    if then else+    let (in ghci)+    [1,2,3] notation+    +++    "abc" is a list+    :+    !!+    nested lists+    comparisons on lists+    head, tail, last init+    length+    null+    reverse+    take drop+    +    maximum+    sum+    product+    elem+    `elem` notation+    [1..20] notation, and with chars, and with steps+    +    cycle, repeat, replicate+    +    list comprehension syntax+    +    2-tuples+    fst snd+    zip+    +    +    +RWH's "Starting Out"+    numbers, negative numbers+    numeric expressions+    boolean expressions+    ==, /= comparisons+    +    let (in ghci)+    +    [1,2,3] notation+    []+    [1..] notation, with steps+    ++ :+    strings, chars, lists+    +    script: main, interact, show, lines+    +    +RWH's "Types and Functions"+    Char, Bool, Int, Integer, Double+    function application+    odd, compare, sqrt+    head, tail, +    2-tuples+    take, drop+    fst, snd+    lines+    +    declaration vs. assignment+    +    ++bos' intro+-1-+    * functional is normal: computation / unix pipes+    * brain twisting goodness+    * basic expressions+    * simply program (compile, main)+    * function application+    * module edit/load cycle+    * wordCount program+    * sort program+    * lists+    * numberLines program+    * recursive function+    * HW: fgrep program (via isInfixOf)+-2-+    * list constructors+    * guards over if-then-else+    * pattern match (via myLength)+    * myLength, myHead, myTail+    * pattern match failure+    * strings are lists+    * more pattern matching+    * HW: nth, lastButOne, isPalindrome+-3-+    * types+    * basic types: Int, Char, Boolean, Double, Integer+    * type signatures ::+    * ...are optional+    * function types+    * functions with multiple args+    * tuples+    * fst3, snd3, thd3+    * list types, String+    * type synonyms+    * drop is polymorphic+    * type variables in signatures+    * the type of filter+    * type inference and bizarre outcomes+    * reading types+    * inferring from types+    * HW: myZipWith, ucFirst+-4-+    * data (via Quaternion)+    * constructors+    * using your type in a function+    * pattern match on constructor+    * _+    * :info, :type+    * compare w/C++, Python+    * equality of user type+    * operator as function, function as operator+    * typeclass --- Eq+    * instance of Eq for quaternion+    * class constraint on elem+    * enum-like data+    * Show class+    * deriving, Eq, ord, Bounded, Enum, Show+    * HW: :info those classes+    * HW: angle classification, convexHull+-5-+    * Num and Ord typeclasses, applied to Quaternion+    * typeclass laws... implied+    * failure and Maybe+    * safeDiv, safeHead+    * mapMaybe (where was map?)+    * binary trees+    * map, mapMaybe, mapTree --> Functor!+    * HW: tree insert, tree contains+-6-+    * short circuit operators+    * strict vs. non-strict+    * non-strict... as lazy... as call-by-need... w/memoization+    * finding the commonality in map and bunzip -> foldr+    * func. composition, lambda+    * foldl vs. foldr and stack overflow+    * seq and foldl'+    * HW: writing lots of things with folds+-7-+    * count words over files listed as args+    * do notation+    * imports+    * ++++Chapter Goals+1: a numbered list+    -- syntax+    -- if-then-else+    -- basic functions: head, tail, ++, show+    -- recursion+    -- type annotations+    -- function application+    -- operators++2: a todo list+    -- HTML+    -- version w/if-then-else and recursion+    -- version w/guards+    -- version w/pattern matching+    -- version w/higher order functions (map)+    -- where clause+    -- develop the numbered list in concert with the todo list+    -- write map++3: todo list w/priority+    -- 2-tuple+    -- data types+    -- Maybe+    +    
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ barley.cabal view
@@ -0,0 +1,120 @@+Name:                barley+Version:             0.3+License:             OtherLicense+License-file:        LICENSE+Author:              Johan Tibell, Mark Lentczner+Maintainer:          markl@glyphic.com+Category:            Web+Build-type:          Simple+Cabal-version:       >=1.8+Synopsis:            A web based environment for learning and tinkering with Haskell+Description:+    Barley is an environment for tinkering with Haskell.  It is a web+    server with an embedded simple programming environment rendered as+    web pages.  The environment allows you to easily edit Haskell code+    and quickly see the result of running it.+    +    Barley includes a tutorial aimed at people with some programming+    and web experience, but it assumes no exposure to Haskell or+    functional programming.  The tutorial takes the developer from+    generating a simple web page through a modest web application with+    database backend storage.  Along the way it exposes the programmer+    to the basic idioms needed to do simple programming tasks.++data-files:+	seed/Chapter01.hs+	seed/Chapter02.hs+	seed/Chapter03.hs+	seed/Chapter1/Step_1_1.hs+	seed/Chapter1/Step_1_2.hs+	seed/Chapter1/Step_1_3.hs+	seed/Chapter1/Step_1_4.hs+	seed/Chapter1/Step_1_5.hs+	seed/Chapter1/Step_1_6.hs+	seed/Chapter1/Step_1_7.hs+	seed/Chapter2/Step_2_1.hs+	seed/Chapter2/Step_2_2.hs+	seed/Chapter2/Step_2_3.hs+	seed/Chapter2/Step_2_4.hs+	seed/Chapter2/Step_2_5.hs+	seed/Chapter2/Step_2_6.hs+	seed/Chapter3/Step_3_1.hs+	seed/Chapter3/Step_3_2.hs+	seed/Chapter3/Step_3_3.hs+	seed/Chapter3/Step_3_4.hs+	seed/Chapter3/Step_3_5.hs+	seed/Chapter3/Step_3_6.hs+	seed/Chapter3/Step_3_7.hs+	seed/Documentation.hs+	seed/EchoRequest.hs+	seed/FirstPage.hs+	seed/Index.hs+	seed/lib/DevUtils.hs+	seed/lib/Slides.hs+	seed/lib/Tutorial.hs+	seed/Project.hs+	seed/Source.hs+	seed/Source.js+	seed/static/barley-and-beetle.png+	seed/static/barley-logo.png+	seed/static/barley.css+	seed/static/codemirror.css+	seed/static/codemirror_base_min.js+	seed/static/codemirror_min.js+	seed/static/codemirror_parse_dummy_min.js+	seed/static/codemirror_parse_haskell.js+	seed/static/hslogo-16.png+	seed/static/jquery.js+	seed/static/ribbon.png+	seed/static/silk/arrow_down.png+	seed/static/silk/exclamation.png+	seed/static/silk/folder.png+	seed/static/silk/image.png+	seed/static/silk/lightning.png+	seed/static/silk/link.png+	seed/static/silk/magnifier.png+	seed/static/silk/page_white.png+	seed/static/silk/page_white_code.png+	seed/static/silk/page_white_code_red.png+	seed/static/silk/page_white_world.png+	seed/static/silk/pencil.png+	seed/static/slides.css+	seed/static/Slides.js+	seed/static/stripe.png+	seed/static/switches.png+	seed/Template.hs++extra-source-files:+  LICENSE-CodeMirror+  README.markdown+  SYLLABUS.markdown++Executable barley+  Main-is: Main.hs+  hs-source-dirs: src++  other-modules:+    Barley.AltLoad+    Barley.Loader+    Barley.Project+    Barley.Utils+    +  Build-depends:+    base == 4.*,+    bytestring == 0.9.*,+    containers >= 0.3 && < 0.5,+    directory >= 1.0 && < 1.2,+    filepath >= 1.1 && < 1.3,+    ghc >= 6.10 && < 7.1,+    ghc-prim == 0.2.*,+    plugins >= 1.5.1.4 && < 1.6,+    snap-core == 0.4.*,+    snap-server == 0.4.*,+    html == 1.0.*,+    text >= 0.7 && < 0.12,+    unix == 2.4.*,+    transformers == 0.2.*++  ghc-options: -Wall+  if impl(ghc >= 6.8)+    ghc-options: -fwarn-tabs
+ seed/Chapter01.hs view
@@ -0,0 +1,45 @@+-- This is a file of Haskell code. Don't worry about trying to understand all+-- the details of how it works, or the syntax for now. Just follow along and+-- try stuff. You can always get to the original, pristine version of this file+-- with the links at the left.++-- Frist thing to know is that these are comments. Everything after two dashes+-- and a space to the end of the line is a comment. In these tutorials you should+-- read the comments, because that is where we guide you through.++module Chapter01 where+-- The line above just declares the name of this module, which keeps all the+-- names of things defined here separate from things named in other files which+-- are their own modules. This module is named Step01.++import Text.Html+-- This line imports all the names defined in the Text.Html module locally so+-- that code in this file can use them. Text.Html defines functions that let us+-- build up HTML pages.++--+-- *** LOOK HERE ***+--+-- The code below defines a value called "page". It is what will be retuned when+-- the browser fetches Step01 as a web page.++page = thehtml <<+    [ header << (thetitle << "Step 1")+    , body <<+        [ h1 << "Your First Haskell Page"+        , paragraph << "Look, it worked!"+        , paragraph << "Now go play with the source."+        ]+    ]++--+-- *** TRY THIS ***+--+-- Try editing some string inside double quotes and save it. See what it does.+-- Try adding another paragraph. Just duplicate one of those lines and try it.+-- Add some other common block elements: Try h2 or pre.++-- You can define sections of your own, and add them the same way, such as:++footnote = paragraph << (small << "You are getting sleepy.")+
+ seed/Chapter02.hs view
@@ -0,0 +1,65 @@+module Chapter02 where+import Text.Html+-- The lines above are just boilerplate (for now).++page = thehtml <<+    [ header << (thetitle << "Step 2")+    , body <<+        [ h1 << "Groceries"+		, paragraph << "Stuff to get at the store:"+		, ulist << fruit+        ]+    ]++--+-- *** LISTS ***+--+-- This code defines a list:++fruit = [ li << "Apple", li << "Banana", li << "Cherry" ]++-- The square brackets surround a list of values. The values are separated+-- by commas. And no, you can't have an extra comma after the last value.++--+-- *** TRY THIS ***+-- +-- Add your favorite fruit to the list above. Remove a fruit. Try it with no+-- fruit at all!  Remember that this is a list of <li> elements, and you need+-- the li << code in front of each string to put the string in the <li> element.+++-- If your list is longer, or the items wider, you can add more white space+-- and newlines as you see fit. You just need to be sure that all subsequent+-- lines are indented more than the first. The following are all fine+---alternatives for writing the same list. When we write lists over multiple+-- lines, we tend to use the first style.++altFruit1 =+    [ li << "Apple"+    , li << "Banana"+    , li << "Cherry"+    ]++altFruit2 = [+	li << "Apple",+	li << "Banana",+	li << "Cherry" ]++altFruit3 =+	[+		li << "Apple",+		li << "Banana",+		li << "Cherry"+	]++--+-- *** TRY THIS ***+--+-- Make the fruit really long. Here are some ideas to get your taste buds going:+--+-- Daikon, Eggplant, Fennel, Grapes, Honeydew, Icky, Jalapeño, Honeydew,+-- Kale, Lemon, Melon, Nectarine, Orange, Pippin, Quince, Raspberry, Sultana,+-- Tarragon, Ugh, Valentine, Watermelon, Xfruit, Yarrow, Zzzz+--+-- Hungry yet?
+ seed/Chapter03.hs view
@@ -0,0 +1,43 @@+module Chapter03 where+import Text.Html+-- The lines above are just boilerplate (for now).++page = thehtml <<+    [ header << (thetitle << "Step 3")+    , body <<+        [ h1 << "Groceries"+        , paragraph << "Stuff to get at the store:"+        , ulist << fruit+        ]+    ]++--+-- In Haskell, all the items in the list have to be the same type. In this+-- case they are Html fragments, in particular <li> elements.+-- Here are some more:++aListOfStrings = ["astronaut", "baker", "candlestick maker"]+aListOfNumbers = [6, 42, -1, 1000000]+-- aListThatWon'tCompile = ["answer", 42]++--+-- *** TRY THIS ***+--+-- Try editing some string inside double quotes and save it. See what it does.+-- Try adding another paragraph. Just duplicate one of those lines and try it.+-- Add some other common block elements: Try h2 or pre.++--+-- *** A LIST ***+--++-- That defines a new name, fruit, that is an HTML fragment. Try putting that+-- into the list of items in the body of the page. Just put ", fruit" on a line+-- by itself in there, making sure to line the commas up.++-- You can define sections of your own, and add them the same way, such as:++footnote = paragraph << (small << "You are getting sleepy.")++fruit = map (li <<) $ words "apple banana kiki"+
+ seed/Chapter1/Step_1_1.hs view
@@ -0,0 +1,56 @@+module Step_1_1 where++import Slides++page = slideDeck "Chapter 1: Intro"+    [ titleSlide "Chapter 1"+        [ "What's all this about Haskell?"+        , "Getting your feet wet."+        ]+    , pointSlide "Haskell"+        "Haskell seems scary 'cause:"+        [ "Oh noes! Where's my state?"+        , "Hey, I don't want my program to be lazy!"+        , "Yo, PHP doesn't need no templates or combintors..."+        , "Uhm, I thought dynamic languages were better?"+        , "MONADS!"+        ]+    , pointSlide "Haskell"+        "But these are cool tools:"+        [ "Functional."+        , "Lazy"+        , "Higher order Functions"+        , "Static Types"+        , "...shhhh: monads."+        ]+    , pointSlide "Haskell"+        "This is what got us hooked:"+        [ "It is a new way to thinking about programming"+        , "It twists the brain in delightful way."+        , "It is very expressive, yet concise and clear"+        , "It is beautiful."+        ]+    , codeSlide "Some familiar things"+        "Consider these unix shell commands:"+        [ "cat foo | sort"+        , ""+        , "cat foo | rev | head"+        ]+    , pointSlide "These are functional"+        "What they do:"+        [ "Take input"+        , "Process the input."+        , "Produce produce output."+        , "Produce output as soon as they're able."+        , "Don't modify any state."+        , "In short, they are functional, pure, and lazy." +        ]+     , pointSlide "Onward!"+        "Now you're going to dive into actual coding."+        [ "Be brave..."+        , "Don't let the error messages throw you."+        , "Just try it."+        ]+    ]++        
+ seed/Chapter1/Step_1_2.hs view
@@ -0,0 +1,51 @@+-- This is a file of Haskell code. Don't worry about trying to understand all+-- the details of how it works, or the syntax for now. Just follow along and+-- try stuff.++-- Frist thing to know is that these are comments. Everything after two dashes+-- and a space to the end of the line is a comment. In these tutorials you should+-- READ THE COMMENTS, because that is where we guide you through.++module Step_1_2 where+-- The line above just declares the name of this module, which keeps all the+-- names of things defined here separate from things named in other files which+-- are their own modules. This module is named Step2.++output = "Hello Haskell user!"+-- The Barley environment looks for something defined output and renders that String+-- as a text page when fetched by the browser.++-- TRY IT: Press the "Run" switch in the upper right, above this window. When you're+-- done, press the "Edit" switch to come back here.++-- NEXT++-- In Haskell, variables aren't really variable: Their value can only be defined once.+-- To have this module output something else, comment out the definition of output+-- above, and un-comment this one:++-- output = output1++output1 = "The answer: " ++ show (6 * 7)++-- Several things to notice here:  ++ is the concatenation operator, and it works with+-- Strings. show is a function that takes a value an produces a string representation+-- of it. Multiplication is *, just like in every other langauge.++-- NEXT++-- Change the output line above to be output2, and then play around here, concatenating+-- some other things to output2. Consider some of the examples in the comments.++output2 = "Other stuff: "+    -- ++ "Yo!"+    -- ++ show 42+    -- ++ show [ 23, 13, 4, 700, 8 ]+    -- ++ show (sort [ 23, 13, 4, 700, 8 ])++-- You can just remove the leading dashes. In Haskell, expressions can be continued+-- on the next line so long as they are indented from the starting line.++-- NEXT++-- Now click on the next link in the Tutorial section on the right -->
+ seed/Chapter1/Step_1_3.hs view
@@ -0,0 +1,58 @@+module Step_1_3 where++import Slides++page = slideDeck "Chapter 1: Syntax"+    [ pointSlide "Syntax"+        "Haskell is not that different than most languages:"+        [ "Operators work as you might expect: 2 + 3 * 4 is 14"+        , "Use parentheses to group terms: (2 + 3) * 4 is 20"+        , "It uses indentation and ';' similarly to Python"+        , "The = sign sets the value of an identifier"+        , "String literals are in double quotes with usual escapes."+        ]+    , pointSlide "Functional Application"+        "But the one big difference is in Function application:"+        [ "There are no parenthesis around the arguments."+        , "There are no commas between the arguments."+        ]+    , codeSlide "Function Application"+        "Just drop the parenthesis..."+        [ "length(s) // as in C*/P*/J*"+        , ""+        , "length s  -- Haskell"+        ]+    , codeSlide "Function Application"+        "Just drop the commas..."+        [ "lookup(key, dict) // as in C*/P*/J*"+        , ""+        , "lookup key dict   -- Haskell"+        ]+    , codeSlide "Function Application"+        "Function call still binds tighter than operators"+        [ "lookup(key, dict) + 1 // as in C*/P*/J*"+        , ""+        , "lookup key dict + 1   -- Haskell"+        ]+    , codeSlide "Function Application"+        "But arguments that are expressions will need parenthesis"+        [ "lookup(key + 1, dict) // as in C*/P*/J*"+        , ""+        , "lookup (key + 1) dict -- Haskell"+        ]+    , codeSlide "Function Defintion"+        "This is similar in function difintions, too:"+        [ "f(a,b) = { return 2*a + 3*b; } // as in C*/J*"+        , ""+        , "f a b = 2*a + 3*b              -- Haskell"+        ]+     , pointSlide "Syntax"+        "It's been described as \"crazy moon language\", but..."+        [ "Be brave..."+        , "You'll soon be able to read it easily"+        , "You'll soon love how clear and consise it is"+        , "You'll soon loath to type in those other, verbose languages."+        ]+    ]++        
+ seed/Chapter1/Step_1_4.hs view
@@ -0,0 +1,43 @@+module Step_1_4 where++-- Great! You've run your first Haskell code.++import Data.List+-- This line just makes some utility functions from the Data.List module accessible.++-- Let's write those unix command lines as Haskell code:++input = "`Twas brillig, and the slithy toves\n"+    ++ "Did gyre and gimble in the wabe;\n"+    ++ "All mimsy were the borogoves,\n"+    ++ "And the mome raths outgrabe.\n"++output = output1++output1 = unlines ( sort (lines input))+-- This does just what you think it does!++output2 = unlines ( take 2 ( map reverse ( lines input )))+-- This does just what you think it does!++output3 = show ( length (words input))+-- What does this do?+-- Notice that we had to convert the number result of length to a String with show++output4 = "\t" ++ show ( length (lines input))+    ++ "\t" ++ show ( length (words input))+    ++ "\t" ++ show (length input)+-- how about this?++-- NEXT++-- Most haskell code doesn't have so many parenthesis. Instead, it uses the $ operator like so:++output1' = unlines $ sort $ lines input+output2' = unlines $ take 2 $ map reverse $ lines input+output3' = show $ length $ words input+output4' = "\t" ++ (show $ length $ lines input)+    ++ "\t" ++ (show $ length $ words input)+    ++ "\t" ++ (show $ length input)++-- You can think of $ as parenthesizing everything on the right, even other $ to the right.
+ seed/Chapter1/Step_1_5.hs view
@@ -0,0 +1,72 @@+module Step_1_5 where++import Slides++page = slideDeck "Chapter 1: Types"+    [ pointSlide "Types?"+        "Where are all those types? Isn't Haskell strongly, static typed?"+        [ "They were all there!"+        , "Haskell uses \"type inferencing\", meaning it figures them out."+        , "When we add types to the program, it is mostly for the programmers!"+        , "Which, it turns out, is a good idea."+        , "Sometimes you do need types, and the compiler will let you know, strangely."+        ]+    , codeSlide "Simple Types"+        "Types are named with an initial capital letter:"+        [ "String"+        , "Int Integer Float Double"+        , "Bool"+        ]+    , codeSlide "List Types"+        "Put a type in square backets to make a list of them."+        [ "[String] -- a list of strings"+        , "[Integers] -- a list of integers"+        , "[[String]] -- a list of lists of strings!"+        ]+    , codeSlide "Type Declarations"+        "You can tell the compiler, and other programmers, the type of an identifier:"+        [ "name :: String"+        , "name = \"Inigo Montoya\""+        , ""+        , "e :: Double"+        , "e = 2.718281828459045"+        , ""+        , "nameParts :: [String]"+        , "nameParts = words name"+        ]+    , pointSlide "Type Declarations"+        "In none of those cases was the type declaration needed, but they were all \+        \useful in making sure you know what types you're working with."+        [ +        ]+    , codeSlide "Function Types"+        "Function types are written with arrows:"+        [ "addOne :: Integer -> Integer"+        , "addOne x = x + 1"+        , ""+        , "lines :: String -> [String]"+        , "words :: String -> [String]"+        ]+    , codeSlide "Type variables"+        "Sometimes a function doesn't care what types of list it is working with. \+        \We call these polymorphic functions. In this case, the type is written as \+        \a variable, with a lower case letter:"+        [ "reverse :: [a] -> [a]"+        , "length :: [a] -> Int"+        ]+    , codeSlide "Two or more arguments"+        "Mutliple arguments are written as successive terms with arrows"+        [ "sumSquares :: Integer -> Integer -> Integer"+        , "sumSquares a b = a*a + b*b"+        , ""+        , "(++) :: [a] -> [a] -> [a]"+        ]+     , pointSlide "Types"+        "From now on we'll be putting in type declarations"+        [ "Be brave..."+        , "Think about the types of your data"+        , "There are some very cool types coming your way..."+        ]+    ]++        
+ seed/Chapter1/Step_1_6.hs view
@@ -0,0 +1,57 @@+module Step_1_6 where++import Data.List++-- Playing with lists++fruit :: [String]+fruit = ["apple", "bannana", "orange", "plum", "peach", "grape", "fig", "apricot"]++ages :: [Integer]+ages = [42, 0, 18, 6, 22, 72]++shhhh :: [String]+shhhh = []++-- These are all lists. Try making your own, and showing them here:++output :: String+output = show fruit+    ++ "\n" ++ show ages+    ++ "\n" ++ show shhhh+-- Note: output has the type String, and so you need to use the show function to convert any+-- of your lists into a String. There is no automatic type conversion in Haskell at all. One+-- day you'll come to view this as a good thing, when you realize it has saved you from+-- countless hard to find bugs!+++-- NEXT++-- Play with the following list functions:+{-+    head :: [a] -> a+    tail :: [a] -> [a]+    init :: [a] -> [a]+    last :: [a] -> a+-}++output1 = show $ tail fruit++-- You also have these functions available:+{-+    (++) :: [a] -> [a]+    length :: [a] -> Int+    reverse :: [a] -> [a]+    sort :: [a] -> [a]+-}++-- And these functions for use with String:+{-+    lines :: String -> [String]+    unlines :: [String] -> String+    words :: String -> [String]+    unwords :: [String] -> String+-}++-- Write some expressions using these functions, and tack them onto output above so you can+-- see 'em.
+ seed/Chapter1/Step_1_7.hs view
@@ -0,0 +1,30 @@+module Step_1_7 where++-- Time to write your our first function++input :: String+input = "`Twas brillig, and the slithy toves\n"+    ++ "Did gyre and gimble in the wabe;\n"+    ++ "All mimsy were the borogoves,\n"+    ++ "And the mome raths outgrabe.\n"++output :: String+output = output2++oneNumber :: Int -> String -> String+oneNumber n s = show n ++ ": " ++ s++output1 :: String+output1 = oneNumber 3 "All mimsy..."+++lineNumbers :: Int -> [String] -> [String]+lineNumbers n xs =+    if xs == []+    then []+    else [oneNumber n (head xs)] ++ lineNumbers (n+1) (tail xs)+++output2 :: String+output2 = unlines $ lineNumbers 1 $ lines input+
+ seed/Chapter2/Step_2_1.hs view
@@ -0,0 +1,36 @@+module Step_2_1 where++import Slides++page = slideDeck "Chapter 2"+    [ titleSlide "Chapter 2"+        [ "HTML Output"+        , "Four ways to write a to do list."+        ]+    , codeSlide "Text.Html"+        "From now own, we'll be generating HTML output. \+        \We do this with the Text.Html library, which introduces some new functions:"+        [ "h1 h2 h3 p pre  -- most tags are defined as their own names"+        , "italics thediv  -- some have quirky names"+        , "ulist olist     -- more quirky ones"+        ]+    , codeSlide "Text.Html"+        "You put content inside a tag with the << operator:"+        [ "h1 << \"Heading\" -- content can be a String"+        , "blockquote << paragraph << \"blah blah ...\" -- or another tag"+        , "ulist << [ li << \"Apple\", li << \"Banana\", li << \"Kiki\" ]"+        , "    -- or a list of content"+        ]+    , codeSlide "Text.Html"+        "Some other useful functions:"+        [ "toHtml  -- converts strings or lists to Html content"+        , "+++     -- concatenate Html content"+        , "noHtml  -- an empty Html content"+        ]+    , pointSlide "Onward"+        "Now let's build a To Do list..."+        [ "Be brave"+        , "Read the comments"+        , "Go on to the next tutorial step."+        ]+    ]
+ seed/Chapter2/Step_2_2.hs view
@@ -0,0 +1,52 @@+module Step_2_2 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A poem from last time:"+        , pre << poemText+        , h1 << "A to do list:"+        , thediv << toDoHtml+        ]+    ]+++-- Here's our line number function from last time:+poem :: String+poem = "`Twas brillig, and the slithy toves\n"+    ++ "Did gyre and gimble in the wabe;\n"+    ++ "All mimsy were the borogoves,\n"+    ++ "And the mome raths outgrabe.\n"++oneNumber :: Int -> String -> String+oneNumber n s = show n ++ ": " ++ s++lineNumbers :: Int -> [String] -> [String]+lineNumbers n xs =+    if xs == []+    then []+    else [oneNumber n (head xs)] ++ lineNumbers (n+1) (tail xs)++poemText :: String+poemText = unlines $ lineNumbers 1 $ lines poem++-- NEXT++-- Here's a simple to do list, and some code that converts it into Html+-- It doesn't do a very nice job. Which you can see if you hit Run.++toDoItems :: [String] -- a list of strings+toDoItems = ["Pick up avacados", "Make snacks", "Clean house", "Have party"]++renderToDo :: [String] -> [Html]+renderToDo ts = [toHtml $ show ts]++toDoHtml :: [Html]+toDoHtml = renderToDo toDoItems++-- Rewrite the function renderToDo so that it builds up a ul element with +-- list of li elements as the content. You may want to make a helper function+-- like oneNumber to make the individual li elements.+
+ seed/Chapter2/Step_2_3.hs view
@@ -0,0 +1,55 @@+module Step_2_3 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A poem from last time:"+        , pre << poemText+        , h1 << "A to do list:"+        , thediv << toDoHtml+        ]+    ]+++-- This time we've rewritten the lineNumbers function using "guards":+poem :: String+poem = "`Twas brillig, and the slithy toves\n"+    ++ "Did gyre and gimble in the wabe;\n"+    ++ "All mimsy were the borogoves,\n"+    ++ "And the mome raths outgrabe.\n"++oneNumber :: Int -> String -> String+oneNumber n s = show n ++ ": " ++ s++lineNumbers :: Int -> [String] -> [String]+lineNumbers n xs+    | xs == []  = []+    | otherwise = [oneNumber n (head xs)] ++ lineNumbers (n+1) (tail xs)+-- Notice that instead of a single =, there are now two expressions that have+-- and =, both preceeded by a | and a condition. The first condition that+-- matches will choose the = expression to use. otherwise is just another way+-- of saying True in Haskell.++poemText :: String+poemText = unlines $ lineNumbers 1 $ lines poem++-- NEXT++-- Here's a version of renderToDo written with an if statement.+-- Try converting it to using guards:++toDoItems :: [String] -- a list of strings+toDoItems = ["Pick up avacados", "Make snacks", "Clean house", "Have party"]++renderToDo :: [String] -> [Html]+renderToDo ts = +    if ts == []+    then []+    else [li << head ts] ++ renderToDo (tail ts)++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems++
+ seed/Chapter2/Step_2_4.hs view
@@ -0,0 +1,115 @@+module Step_2_4 where++import Slides++page = slideDeck "Chapter 2: Lists"+    [ titleSlide "All About Lists"+        [ ]+    , codeSlide "Making Lists"+        "Up to now we've been making lists using this syntax:"+        [ "[]        -- the empty list"+        , "[42]      -- a list of one value"+        , "[1, 2, 3] -- a list of three values"+        ]+    , pointSlide "The Truth About Lists"+        "Lists in Haskell are actually linked lists, not arrays, and are \+        \built recursively. A list is always just one of these two forms:"+        [ "The empty list"+        , "The first item in the list, and the rest of the list"+        ]+    , codeSlide "Lists in Haskell"+        "In Haskell, [] is the empty list, and the : operator is used to build\+         \up lists:"+        [ "[]             -- the empty list"+        , "42 : []        -- a list of one value"+        , "1 : 2 : 3 : [] -- a list of three values"+        ]+    , codeSlide "Lists in Lisps"+        "In various Lisp dialects, this would look like:"+        [ "nil                           -- the empty list"+        , "(cons 42 nil)                 -- a list of one value"+        , "(cons 1 (cons 2 (cons 3 []))) -- a list of three values"+        ]+    , codeSlide "Watch out: Haskell's : ≠ Lisp's cons"+        "In Lisp, cons puts any two things together. Not so in Haskell. In \+        \Haskell : always takes an element on the left and a (possibly empty) \+        \list on the right:"+        [ "(cons 42 109)  -- legal in Lisp"+        , "42 : 109       -- NOT legal in Haskell"+        ]+    , codeSlide "Watch out: Haskell's Lists must be homogeneous"+        "In many languages list elements can be different types. Not so in \+        \Haskell. In Haskell all elements of the list must be the same type."+        [ "[2, \"bob\"]          -- legal in Python, Javascript, etc.."+        , "[2, \"bob\"]          -- NOT legal in Haskell"+        , "[[1,2,3], [10,20,30]] -- of course lists of lists are fine!"+        ]+    , codeSlide "Syntatic Sugar"+        "In Haskell, the way we've been writing lists is just syntatic sugar \+        \for their construction with the : operator and []:"+        [ "[42]      == 42 : []"+        , "[1, 2, 3] ==  1 : 2 : 3 : []"+        ]+    , codeSlide "Watch out: Using the right form"+        "It is easy get tripped up with the sugar. Make sure you see how these \+        \pairs of expressions are the same work:"+        [ "[1]   ==  1  : []"+        , "[[1]] == [1] : []"+        , "[1]   == [1] ++ []"+        , "[1, 2]   ==  1  : [2]  ==  1 : 2 : []"+        , ""+        , "1 ++ []  -- illegal, needs a list on both sides to concatenate"+        , "[1] : 2  -- illegal, needs a list on the right"+        , "[] : []  -- legal, but what is it?"+        , "-- remember: list on the left of a : implies list of lists..."+        ]+    , codeSlide "Inspecting Lists"+       "When working with lists, so far we've used functions and guards. \+       \Consider:"+       [ "showFirstNumber :: [Int] -> String"+       , "showFirstNumber is ="+       , "    | is == [] = \"No first number.\""+       , "    | otherwise = \"The first number is \" ++ show (head is) ++ \".\""+       ]+    , codeSlide "Inspecting Lists"+       "Instead, since there are just two forms of list, and those are exactly \+       \what this function is looking for, we can pattern match for them:"+       [ "showFirstNumber :: [Int] -> String"+       , "showFirstNumber []     = \"No first number.\""+       , "showFirstNumber (i:is) = \"The first number is \" ++ show i ++ \".\""+       ]+    , pointSlide "How's That Work?"+       "Haskell will pick the first 'equation' for a function where the \+       \arguments match the given pattern:"+       [ "[] will match only the empty list"+       , "(i:is) will match a list that has a first item (i) and a rest of the \+           \list (is). Careful: Notice that those are parenthesis, not square \+           \brackets around the : expression!"+       ]+    , codeSlide "Some gotchas:"+       "Look at this function to see how NOT to get caught up between matching \+       \the : operator, vs. matching the syntatic sugar lists:"+       [ "funnyFunction :: [Int] -> String"+       , "funnyFunction [] = \"Empty List\""+       , "funnyFunction [i] = \"One element list\""+       , "funnyFunction (i:is) = \"List with at least one element\""+       , "funnyFunction [i,j] = \"Two element list\""+       , "  -- would never match because the clause above matches two element lists as well!"+       , "funnyFunction [i:is] = \"A list with one element that is at least a one element list\""+       , "  -- the last one won't compile because it doesn't match the type of the argument"+       ]+    , pointSlide "Patterns Ahoy!"+       "Using pattern matching is generally more concise and clear (once you \+       \get used to it)."+       [ "Be brave!"+       , "We'll write with patterns from now on where we can."+       ]+    , codeSlide "One more thing..."+       "String is just a list of Char, or technically [Char]. Which means all \+       \the list functions and list patterns work on Strings. Woot!  These are \+       \all the same:"+       [ "\"abc\""+       , "['a', 'b', 'c']"+       , "'a' : 'b' : 'c' : []"+       ]+    ]
+ seed/Chapter2/Step_2_5.hs view
@@ -0,0 +1,59 @@+module Step_2_5 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A poem from last time:"+        , pre << poemText+        , h1 << "A to do list:"+        , thediv << toDoHtml+        ]+    ]+++-- This time we've rewritten the lineNumbers function using "pattern matching":+poem :: String+poem = "`Twas brillig, and the slithy toves\n"+    ++ "Did gyre and gimble in the wabe;\n"+    ++ "All mimsy were the borogoves,\n"+    ++ "And the mome raths outgrabe.\n"++oneNumber :: Int -> String -> String+oneNumber n s = show n ++ ": " ++ s++lineNumbers :: Int -> [String] -> [String]+lineNumbers n []     = []+lineNumbers n (x:xs) = oneNumber n x : lineNumbers (n+1) xs+-- Notice that instead of a single equation (with the function name) =, there+-- are now two. Each repeats the arguments, but with patterns. Like guards, the+-- first equaltion where all the patterns match will be used.++-- Notice something else: The last expression changed:+oldWay n (x:xs) = [oneNumber n x] ++ lineNumbers (n+1) xs+newWay n (x:xs) =  oneNumber n x  :  lineNumbers (n+1) xs+-- Rather than build a one element list (in the brackets) and concatentate (++)+-- it with the rest of the processing, the newWay just constructs (:) the new+-- result list with the element, and the list that is the recursive result.++poemText :: String+poemText = unlines $ lineNumbers 1 $ lines poem++-- NEXT++-- Here's a version of renderToDo written with guards.+-- Try converting it to using patterns:++toDoItems :: [String] -- a list of strings+toDoItems = ["Pick up avacados", "Make snacks", "Clean house", "Have party"]++renderToDo :: [String] -> [Html]+renderToDo ts+    | ts == []  = []+    | otherwise = [li << head ts] ++ renderToDo (tail ts)++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems++
+ seed/Chapter2/Step_2_6.hs view
@@ -0,0 +1,104 @@+module Step_2_6 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A to do list:"+        , thediv << toDoHtml+        , h1 << "Some action:"+        , thediv << comicAction+        ]+    ]+++-- Here's a version of renderToDo written with patterns.+-- Getting simpler, isn't it?++toDoItems :: [String] -- a list of strings+toDoItems = ["Pick up avacados", "Make snacks", "Clean house", "Have party"]++renderToDo :: [String] -> [Html]+renderToDo []     = []+renderToDo (t:ts) = li << t : renderToDo ts++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems++-- Here's another kind of list++comicbookWords :: [String]+comicbookWords = ["Pow", "Blamo", "Zap"]++comicStyle :: String -> Html+comicStyle word = paragraph << bold << ("** " ++ word ++ "! **")++renderAction :: [String] -> [Html]+renderAction []     = []+renderAction (w:ws) = comicStyle w : renderAction ws++comicAction :: Html+comicAction = blockquote << renderAction comicbookWords++-- Look carefully at renderAction and renderToDo. Do they look similar?++-- Each is applying some operation to the first element of the list, and+-- constructing a list from the result and a recursive call over the remainder+-- of the list. When there are no more elements, they return an empty list.++-- Haskellers hate repeating themselves!++-- This pattern is so common there a higher-order function to do this: map++renderToDo' :: [String] -> [Html]+renderToDo' ts = map (li <<) ts++renderAction' :: [String] -> [Html]+renderAction' ws = map comicStyle ws++-- Try changing toDoHtml and comicAction to use these versions and see that they+-- work the same.++-- Oh yeah, we slipped in two more things about Haskell there.+-- 1) You can use ' as a character in names+-- 2) (li <<) is a handy shortcut. It makes a function that takes an argument+--    and applies to the empty side of the operator. You can do this with any+--    operator(*):++addTwo = (+ 2)+dividedByTwo = (/ 2)+twoOver = (2 /)+putStarsInFront = ("**" ++)+putStarsAtEnd = (++ "**")+++-- map is so useful, and makes your code very short. Even more amazing is that+-- there nothing special about the implementation of map. In fact you can easily+-- make your own!++-- The hardest part of myMap is the type signature, so we'll give you that:++myMap :: (a -> b) -> [a] -> [b]++-- Let's break this down:+-- (a -> b) -- the first argument is a function! this function takes any type+--             of argument, let's call it a, and produces some type of result,+--             let's call it b+-- -> [a]   -- the second argument to map is a list of somethings, and they'd+--             better be the same type as the argument to the function argument+-- -> [b]   -- the result is a list of somethings, and they'll be the same type+--             as the function's result++-- Notice that the type signature didn't care about particular types, so it used+-- type variables to talk about them.++-- Now, here's the first clause of myMay. You can write the other:++myMap f []     = []++-- Replace map in the above functions with myMap and see that it works.+++--------------+-- (*) Except - ! You can't because (-3) means negative 3.
+ seed/Chapter3/Step_3_1.hs view
@@ -0,0 +1,39 @@+module Step_3_1 where++import Slides++page = slideDeck "Chapter 3"+    [ titleSlide "Chapter 3"+        [ "Tuples, Types, and Maybe"+        ]+    , codeSlide "Two Things"+        "A 2-Tuple is pair of two values, the fst and the snd \+        \(not a typo!):"+        [ "(43, \"Bob\")     -- a tuple of an Int and String"+        , "(\"Bob\", 43)     -- a tuple of a String and an Int"+        , "(True, [1, 2, 3]) -- a tuple of a Bool and a list"+        , ""+        , "('x', (True, 12)) -- hmmmmm..."+        ]+    , codeSlide "Two Things"+        "When we talk about the type of a tuple, we must specify \+        \the type of the two parts:"+        [ "(Int, String)"+        , "(String, Int)"+        , "(Bool, [Int])"+        , ""+        , "(Char, (Bool, Int))"+        ]+    , codeSlide "Accessing the parts"+        "You can both pattern match, or use functions to access the \+        \parts of a tuple:"+        [ "isAdult (age, name) = age >= 18"+        , ""+        , "isAdult person = fst person >= 18"+        ]+    , codeSlide "Putting them together"+        "You can put them together by using parenthesis and comma:"+        [ "makePerson :: Int -> String -> (Int, String)"+        , "makePerson age name = (age, name)"+        ]+    ]
+ seed/Chapter3/Step_3_2.hs view
@@ -0,0 +1,52 @@+module Step_3_2 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A to do list:"+        , thediv << toDoHtml+        ]+    ]++-- We've changed the type of toDoItems to include a Bool value to+-- indicate if they've been done.++toDoItems :: [(Bool, String)] -- a list of tuples: each a Bool and String+toDoItems =+    [ (True,  "Pick up avacados")+    , (True,  "Make snacks")+    , (False, "Clean house")+    , (False, "Have party")+    ]+    -- Haskellers often format lists with long items in this funny way!+    +renderToDo :: [String] -> [Html]+renderToDo ts = map (li <<) ts++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems++-- Try running this file. You'll find that the it doesn't compile, and gives+-- an error on the line above. Just read the first two lines of the error and+-- see if you can see what the compiler is trying to tell you about the problem+-- with the types.++-- Fix the renderToDo function to fix the problem.++-- NEXT++-- What did you end up doing with the Bool component of the tuple? Did you+-- ignore it? Did you use it in the computation somehow? Did you notice that+-- by having a clear type, you were forced to think about it?++-- Change the renderToDo function to render the items that aren't done bold.++-- NEXT++-- For a challenge, change the renderToDo function to render only the first+-- not done item bold.++hint1 = map pred "Zpv!qspcbcmz!ibwf!up!hp!cbdl!up!opu!vtjoh!nbq/"+hint2 = map pred "Zpv!qspcbcmz!xjmm!offe!bopuifs!ifmqfs!gvodujpo/"
+ seed/Chapter3/Step_3_3.hs view
@@ -0,0 +1,53 @@+module Step_3_3 where++import Slides++page = slideDeck "Chapter 3"+    [ codeSlide "Bigger Tuples"+        "Tuples can be larger: 3 or more elements. Here are some larger tuple \+        \types:"+        [ "(Int, String, Bool)"+        , "(Int, Int, Int, Int) -- you can use the same type more than once"+        , "(Bool, Bool, Bool, Bool,"+        , " Bool, Bool, Bool, Bool) -- a byte? please, no!"+        ]+    , codeSlide "Bigger Tuples"+        "There aren't any accessor functions defined for these, so you have \+        \to pattern match to get their parts. Though you could define:"+        [ "fst3 :: (a, b, c) -> a"+        , "fst3 (a, b, c) = a"+        , ""+        , "snd3 :: (a, b, c) -> b"+        , "snd3 (a, b, c) = b"+        , ""+        , "trd3 :: (a, b, c) -> c"+        , "trd3 (a, b, c) = c"+        ]+    , pointSlide "Lists vs. Tuples"+        "Lists and Tuples are different:"+        [ "In a list the elements are all the same type."+        , "In a tuple members can be different types."+        , ""+        , "A list can have any number of elements."+        , "A tuple always has the number of members indicated by its type."+        ]+    , codeSlide "Type names"+        "You can give a name to a type. This makes things more convient to \+        \use:"+        [ "type Person = (Int, String)"+        , ""+        , "isAdult :: Person -> Bool"+        , "isAdult (age,name) = age >= 18"+        ]+    , codeSlide "Type names"+        "Watch out: The type is just a synonym. amy and bob are still the \+        \same type:"+        [ "type Person = (Int, String)"+        , ""+        , "amy :: Person"+        , "amy = (28, \"Amy\""+        , ""+        , "bob :: (Int, String)"+        , "bob = (26, \"Bob\""+        ]+    ]
+ seed/Chapter3/Step_3_4.hs view
@@ -0,0 +1,32 @@+module Step_3_4 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A to do list:"+        , thediv << toDoHtml+        ]+    ]++-- Rewrite all of this to use a type synonym for the tuple.++toDoItems :: [(Bool, String)] -- a list of tuples: each a Bool and String+toDoItems =+    [ (True,  "Pick up avacados")+    , (True,  "Make snacks")+    , (False, "Clean house")+    , (False, "Have party")+    ]++formatToDo :: (Bool, String) -> Html+formatToDo (True,item) = li << item+formatToDo (False,item) = li << bold << item++renderToDo :: [(Bool, String)] -> [Html]+renderToDo ts = map formatToDo ts++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems+
+ seed/Chapter3/Step_3_5.hs view
@@ -0,0 +1,57 @@+module Step_3_5 where++import Slides++page = slideDeck "Chapter 3"+    [ codeSlide "Not that safe"+        "Type synonyms are quick and easy and often the right choice, but \+        \don't offer as much type saftey as possible. Consider:"+        [ "type Range = (Int, Int)"+        , "inRange :: Range -> Int -> Bool"+        , "inRange (lo,hi) x = lo <= x && x <= hi"+        , ""+        , "type Point = (Int, Int)"+        , "p :: Point"+        , "p = (3,7)"+        , ""+        , "ick = inRange p 4 -- compiles!"+        ]+    , codeSlide "Data Types"+        "Data types let you create a type that is distinct. When you so you \+        \define a constructor that builds values of the type:"+        [ "data Range = Range Int Int"+        , "inRange :: Range -> Int -> Bool"+        , "inRange (Range lo hi) x = lo <= x && x <= hi"+        , ""+        , "data Point = Point Int Int"+        , "p :: Point"+        , "p = Point 3 7"+        , ""+        , "ick = inRange p 4 -- now this is a compile error"+        ]+    , codeSlide "Multiple Constrcutors"+        "Data types are very powerful. They can have more than one constructor \+        \and each constructor can have any number of values:"+        [ "data Direction = North | East | South | West"+        , "  deriving (Eq, Show)"+        , ""+        , "data Weather = Sunny | Rainy Double | Windy Double Direction"+        , "describe :: Weather -> String"+        , "describe Sunny = \"lovely\""+        , "describe (Rainy inches) | inches < 0.2 = \"drizzle\""+        , "                        | otherwise    = \"wet\""+        , "describe (Windy speed dir) = "+        , "    \"blowin' \" ++ show speed ++ \" from \" ++ show dir"+        ]+    , codeSlide "Wait, Deriving What?"+        "The deriving clause on the data declaration is a bit of boilerplate \+        \saver that will make your data do more. Here are some of the things \+        \you can 'derive' for your data automatically:"+        [ "Eq      -- works with == and /= operators"+        , "Ord     -- works with <, >, etc.."+        , "Show    -- works with show"+        , "Read    -- works with read"+        , "Enum    -- convertable to/from integers"+        , "Bounded -- has a min and max value"+        ]+    ]
+ seed/Chapter3/Step_3_6.hs view
@@ -0,0 +1,59 @@+module Step_3_6 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A to do list:"+        , thediv << toDoHtml+        , h1 << "# people invited:"+        , p << show (headcount invited)+        ]+    ]++-- We've written two lists.++data ToDo = ToDo String | Done String++toDoItems :: [ToDo]+toDoItems =+    [ Done "Pick up avacados"+    , Done "Make snacks"+    , ToDo "Clean house"+    , ToDo "Have party"+    ]+++data Invite = Invite String Int++who :: Invite -> String+who (Invite name count) = name++invited :: [Invite]+invited =+    [ Invite "Amy" 1+    , Invite "Bob" 7  -- he's got lots of kids+    , Invite "Cam" 2+    , Invite "Doris" 3+    , Invite "Edgar" 2+    , Invite "Fran" 2+    ]+    +formatToDo :: ToDo -> Html+-- Try writing this++renderToDo :: [ToDo] -> [Html]+renderToDo ts = map formatToDo ts++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems++-- NEXT++-- Write this function++headcount :: [Invite] -> Int+headcount is = 0 -- this list was just a place holder, delete it++
+ seed/Chapter3/Step_3_7.hs view
@@ -0,0 +1,86 @@+module Step_3_7 where++import Text.Html++page = thehtml <<+    [ header << (thetitle << "Output")+    , body <<+        [ h1 << "A to do list:"+        , thediv << toDoHtml+        , reminderHtml+        , h1 << "# people invited:"+        , p << show (headcount invited)+        ]+    ]++data ToDo = ToDo String | Done String++toDoItems :: [ToDo]+toDoItems =+    [ Done "Pick up avacados"+    , Done "Make snacks"+    , ToDo "Clean house"+    , ToDo "Have party"+    ]++-- We need a function to return the next item to do.+-- Something like:+--        whatToDoNext :: [ToDo] -> ToDo++-- But what should it return if they are all done?+-- Enter Maybe:+whatToDoNext :: [ToDo] -> Maybe String++-- The return type is Maybe String -- in the same way [String] is a type 'built'+-- from the String type, Maybe String is a type 'built' from the String type. But+-- rather than a list, values of type Maybe String can have one of two forms:+--         Just someString+--         Nothing+whatToDoNext (Done item : ts) = whatToDoNext ts+whatToDoNext (ToDo item : ts) = Just item+whatToDoNext []               = Nothing++formatNotice :: Maybe String -> Html+formatNotice Nothing = noHtml+formatNotice (Just item) = h1 << ("*** DO THIS: " ++ item ++ " ***")++reminderHtml :: Html+reminderHtml = formatNotice $ whatToDoNext toDoItems++    +formatToDo :: ToDo -> Html+formatToDo (ToDo item) = li << bold << item+formatToDo (Done item) = li << item++renderToDo :: [ToDo] -> [Html]+renderToDo ts = map formatToDo ts++toDoHtml :: Html+toDoHtml = ulist << renderToDo toDoItems++-- Try changing the toDoItems to be all Done and see how this works+++-- NEXT+-- Add an optional partner or spouse to the invite data type.+-- Add a list of invitiees (and optional partners!) to the page.++data Invite = Invite String Int++who :: Invite -> String+who (Invite name count) = name++invited :: [Invite]+invited =+    [ Invite "Amy" 1+    , Invite "Bob" 7  -- he's got lots of kids+    , Invite "Cam" 2+    , Invite "Doris" 3+    , Invite "Edgar" 2+    , Invite "Fran" 2+    ]++headcount :: [Invite] -> Int+headcount [] = 0+headcount (Invite who count : is) = count + headcount is+
+ seed/Documentation.hs view
@@ -0,0 +1,48 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Documentation where++import DevUtils++import Control.Monad (liftM)+import qualified Data.ByteString.Char8 as C+import Data.Maybe+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Snap.Types+import Text.Html++handler :: Snap ()+handler = do+    docparam <- getParam (C.pack "doc")+    let docid = fromMaybe defaultdoc (fmap C.unpack docparam >>= finddoc)+    htmlResponse $ docpage docid++docpage :: Doc -> Html+docpage doc = devpage "Documentation"+    [ tag "iframe" ! [ src (docUrl doc), identifier "documentation" ] << noHtml+    ]+    [] -- modules+    [] -- scripts++finddoc :: String -> Maybe Doc+finddoc x = go documents x+  where+    go (d:ds) x | docId d == x = Just d+                | otherwise    = go ds x+    go [] _ = Nothing++defaultdoc :: Doc+defaultdoc = head documents
+ seed/EchoRequest.hs view
@@ -0,0 +1,18 @@+module EchoRequest where++import qualified Data.ByteString.Char8 as C+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Snap.Types+import Text.Html++handler :: Snap ()+handler = do+    req <- getRequest+    modifyResponse $ setContentType (C.pack "text/html; charset=UTF-8")+    writeBS $ (T.encodeUtf8 . T.pack) $ renderHtml (html req)+  where+    html req = +        header << thetitle << "Echo Request" ++++        body << pre << show req+
+ seed/FirstPage.hs view
@@ -0,0 +1,14 @@+module FirstPage where++import Text.Html++-- FIRST:  Try toggling the Edit/Run button above this editor box back and forth.+-- SECOND: Try editing some text inside quotes, and hit Run.+-- THIRD:  If you are brave, try adding another paragraph, or an ordList.+-- FOURTH: Go back to the Home page (link at top right) and start the tutorial.++page = thehtml <<+    [ h1 << "Hi!"+    , paragraph << "This page was rendered from Haskell."+    , unordList [ bold << "one", italics << "two", tt << "three"]+    ]
+ seed/Index.hs view
@@ -0,0 +1,111 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Index where++import DevUtils+import Tutorial+import Text.Html++page = devpage "Start"+        [ h1 << "Welcome aboard!"+        , p << "Barley is an environment and tutorial for exploring Haskell. \+             \Our aim is to make your first encounter with Haskell fun, \+             \enjoyable, and practical. "+        , steps+        ]+        [ modMessage, tutorialOutlineModule, modTagLine ]+        []+++type Step = (String, [Html])++steps :: Html+steps = ordList $ map mkStep [step1, step2, step3, step4]+  where+    mkStep (title, text) = p << bold << title +++ thediv << text+    +step1 :: Step+step1 = ("Install and run Barley",+  [ p << "If you got here, you've done this step!"+  ])++step2 :: Step+step2 = ("Navigating Barley",+  [ p << "This web site is a small development envinronment for Haskell. \+         \Here are the main navigation elements:"+  , p << (bold << "Top bar:" +++ "The black top bar at the very top of \+         \the page has links to commonly used pages. At the top right, \+         \Home takes you back to this page; Project takes you to a listing \+         \of all the files that make up Barley. Documentation and Help are \+         \what they say they are. In the upper left, the Haskell icon leads \+         \to some common community web pages.")+  , p << (bold << "Right sidebar:" +++ "On the right there are useful operations. \+         \On this page, it includes \+         \a listing of the complete tutorial. On other pages there are actions \+         \relevant to the page you are on. If you are on a tutorial page, that \+         \is where the next and previous steps will be listed.")+  ])++step3 :: Step+step3 = ("A Sample Page",+  [ p << "If you want to try something right now, do this: "+  , unordList+      [ toHtml "Be sure you know how to get back here: The Home link in the upper right."+      , toHtml "Be sure to read all the comments in the code you are about to see. \+               \This is where the instructions will be."+      , toHtml "Be brave."+      , toHtml "Now go to " +++ anchor ! [href "source?file=FirstPage.hs"] << "FirstPage.hs"+      , toHtml "Come back here when you're done."+      ]+  , p << "Congratulations! You're writing Haskell!"+  ])++step4 :: Step+step4 = ("Do the Tutorial",+  [ p << "The tutorial is a sequence of pages written in Barley. Some pages are \+          \a sequence of slides, others are code that you will edit and work on."+  , p << "On the code pages, you should be sure to read the comments in the code, \+          \since that is where the tutorial introduces new ideas, and guides you \+          \along. On these pages you'll see a big Edit/Run switch near the top of \+          \the page that will let you switch back and forth between editing the code \+          \and viewing the page that that code renders."+  , p << ("Start here: " +          +++ anchor ! [href "source?file=Chapter1/Step_1_1.hs&preview=1"] << "Chapter 1, Step 1")+  ])+  +modMessage :: Html+modMessage = (h2 << "pre-Alpha version") ++++    (p << ("Just in case it wasn't totally clear: This is very early, \+          \pre-Alpha software. We're making it up as fast as we can! \+          \In the spirit of open source, we are developing in public, \+          \so please be gentle!" +++ br +++ "— Johan & Mark"))++modSteps :: Html+modSteps = (h2 << "Tutorial Steps") ++++    ordList [ "Step", "Step", "Quick-Step", "Slide" ] ++++    p << "This will be a list of the steps some day…"++modTagLine :: Html+modTagLine = pre << (+    "webSite :: " +++ (bold << "Haskell") +++ "\n\+    \webSite = madeWith\n\+    \  [ haskellPlatform\n\+    \  , snapFramework\n\+    \  , plugins\n\+    \  , ghc\n\+    \  ]"+    )++
+ seed/Project.hs view
@@ -0,0 +1,104 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Project where++import DevUtils++import Control.Monad.IO.Class+import Data.Maybe+import Snap.Types+import System.Directory+import System.FilePath+import Text.Html hiding ((</>))++handler :: Snap ()+handler = liftIO mkProjPage >>= htmlResponse+    ++mkProjPage :: IO Html+mkProjPage = do+    projPath <- getCurrentDirectory+    let projName = takeFileName projPath+    projTree <- loadTree+    return $ devpage ("Project " ++ projName)+        [ h1 << projName+        , p << small << projPath+        , fileList projTree+        ]+        []+        []++fileList :: [SrcTree] -> Html+fileList tree = table ! [identifier "filelist"] <<+                    stripe (concatMap mkEntry tree)+  where+    stripe = zipWith (\c e -> e ! [theclass c]) (cycle ["even", "odd"])+    +    mkEntry (SrcTree si sub) = mkItem si : concatMap mkEntry sub++    mkItem si = tr << map col+        [ ("path", Just $ p << [ dirPart, namePart ])+        , ("op", previewLink si)+        , ("op", editLink si)+        , ("op", downloadLink si)+        , ("op", fileLink si)+        ]+      where+        path = srcPath si+        dirPart = let d = takeDirectory path+                      e = addTrailingPathSeparator d in+            if null d then noHtml else thespan ! [theclass "dir"] << e+        namePart = thespan ! [theclass $ "name " ++ fileType]+                        << takeFileName path+        fileType = case srcClass si of+                    SCPage -> "src-page"+                    SCImage -> "src-image"+                    SCScript -> "src-script"+                    SCText -> "src-text"+                    SCOther -> "src-other"+                    SCDir -> "src-dir"+        col (c, h) = td ! [theclass c] << fromMaybe spaceHtml h+    +{- add links for:+    add+    +    rename+    move+    delete+-}+++data SrcTree = SrcTree SrcInfo [SrcTree]++loadTree :: IO [SrcTree]+loadTree = do+    buildSub ""+  where+    buildSub :: FilePath -> IO [SrcTree]+    buildSub root = do+        names <- getDirectoryContents (if null root then "." else root)+        let names' = filter okName names+        sequence $ map (buildEntry root) names'+    buildEntry :: FilePath -> FilePath -> IO SrcTree+    buildEntry root name = do+        let path = if null root then name else root </> name+        si <- getSrcInfo path+        sub <- if srcClass si == SCDir then buildSub path else return []+        return $ SrcTree si sub+    okName "" = False+    okName ('.':_) = False+    okName _ = True+    +        
+ seed/Source.hs view
@@ -0,0 +1,186 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Source where++import DevUtils+import Tutorial++import Control.Monad (when)+import Control.Monad.IO.Class+import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as C+import Data.Maybe+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Snap.Types+import Text.Html hiding ((</>))+import qualified Text.Html as Html++handler :: Snap ()+handler = do+    fileparam <- getParam (C.pack "file")+    showPreview <- (maybe False (not . C.null))+                    `fmap` getParam (C.pack "preview")+    case maybe Nothing (legalPath . C.unpack) fileparam of+        Nothing -> errorBadRequest+        Just file -> do+            meth <- rqMethod `fmap` getRequest+            when (meth == POST) $ handleSave file+            html <- liftIO $ mkSrcPage file showPreview+            htmlResponse html++handleSave :: FilePath -> Snap()+handleSave file = do+    contents <- getParam (C.pack "contents")+    case contents of+        Nothing -> errorBadRequest+        Just c -> liftIO $ B.writeFile file $ clean c+  where+    clean = T.encodeUtf8 . T.filter (/= '\r') . T.decodeUtf8+    ++mkSrcPage :: FilePath -> Bool -> IO Html+mkSrcPage path showPreview = do+    si <- getSrcInfo path+    contents <- if srcExists si+        then readFile (srcPath si)+        else return $ emptyModule (srcPath si)+    return $ srcPage si contents showPreview++srcPage :: SrcInfo -> String -> Bool -> Html+srcPage si contents showPreview = devpage ("Source of " ++ srcPath si)+    content+    (modules si)+    scriptSrcs+  where+    content = thediv ! [identifier "source-page"] <<+        [ h1 << srcPath si+        , p << small << srcFullPath si+        , rocker+        , preview showPreview si+        , editor contents+        ]+    rocker = thediv ! [identifier "rocker", theclass "button-set"] <<+                [ thediv ! [identifier "rocker-edit-image"] << noHtml+                , thediv ! [identifier "rocker-run-image", displayHidden] << noHtml+                , anchor ! [identifier "rocker-edit", href "#"] << "Edit"+                , anchor ! [identifier "rocker-run", href "#"] << "Run"+                ]++editor :: String -> Html    +editor contents = thediv ! [identifier "editor", displayHidden] <<+    [ errors+    , form ! [Html.method "POST"] << [editorBox, btns, hidden]+    ]+  where+    btns = thediv ! [theclass "button-set"] <<+            [ input ! [thetype "button", value "Cancel", theclass "btn-cancel"]+            , input ! [thetype "submit", value "Save", theclass "btn-save"]+            ]+    editorBox = thediv ! [identifier "editor-box"] <<+                textarea ! [theclass "src", name "contents",+                    identifier "txt-src", strAttr "readonly" "readonly" ]+                << contents+    hidden = input ! [thetype "hidden", name "preview", value "1"]+    +preview :: Bool -> SrcInfo -> Html+preview showPreview = maybe noHtml build . previewPath+  where+    build path = +        thediv ! [ identifier "preview"+                 , theclass "panel with-preview"+                 , displayHidden ] <<+            [ h1 << "Rendering Preview"+            , tag "iframe" ! [ theclass "panel-content" ] << noHtml+            , p ! [ identifier "preview-url", displayHidden ] << path+            , showMarker+            ]+    showMarker =+        if showPreview+        then thediv ! [ identifier "preview-show", displayHidden ] << noHtml+        else noHtml+        +errors :: Html+errors = thediv ! [ identifier "errors"+                  , theclass "panel with-errors"+                  , displayHidden] <<+            [ h1 << "Compilation Errors"+            , pre ! [ theclass "panel-content", displayHidden ] << noHtml+            ]++modules :: SrcInfo -> [Html]+modules si = catMaybes+    [ Just $ modFStat si+    , Just $ modActions si+    , modTutorial si+    , Just modSearch]+     +modFStat :: SrcInfo -> Html+modFStat si = (h2 << "File Info") ++++    if srcExists si+        then [if srcWritable si then noHtml else p << bold << "read only",+              p << show (srcModTime si)]+        else [p << bold << "new file"]++modActions :: SrcInfo -> Html+modActions si = (h2 << "Actions") ++++    ulist << map (li ! [theclass "op"]) (catMaybes+              [ previewLink si+              --, Just $ italics << "Revert"+              , downloadLink si+              , fileLink si+              , Just (anchor ! [ identifier "recompile",+                                    theclass "op-recompile", href "#" ]+                            << "Force Recompile")+              ])++modTutorial :: SrcInfo -> Maybe Html+modTutorial si = previewPath si >>= tutorialModule +    +modSearch :: Html+modSearch = (h2 << "Research") ++++    [ form ! [action "http://holumbus.fh-wedel.de/hayoo/hayoo.html"+                , target "barley-reseach"] <<+        [ input ! [thetype "text", name "query", theclass "research-query"]+        , input ! [thetype "submit", value "Hayoo"]+        ]+    , form ! [action "http://haskell.org/hoogle", target "barley-reseach"] <<+        [ input ! [thetype "text", name "q", theclass "research-query"] +        , input ! [thetype "submit",  value "Hoogle"]+        ]+    ]+              +emptyModule :: FilePath -> String+emptyModule filename = +    "module " ++ modName ++ " where\n\+    \\n\+    \import Text.Html\n\+    \\n\+    \page = body << [\n\+    \    h1 << \"Hi!\",\n\+    \    paragraph << \"testing\"\n\+    \    ]\n"+ where+   modName = filename  -- TODO should replace slashes with dots++scriptSrcs :: [String]+scriptSrcs =+    [ "/static/jquery.js"+    , "/static/codemirror_min.js"+    , "Source.js"+    ]++displayHidden :: HtmlAttr+displayHidden = thestyle "display: none;"
+ seed/Source.js view
@@ -0,0 +1,199 @@+$(document).ready(function () {++var marker = $('#run-source-js-once');+if (marker.length > 0) {+    marker.text(marker.text() + " Bug! ");+    return;+}+$('<div id="run-source-js-once" style="display: none;">Done.</div>').appendTo($('body'));+++var bEnable = function(i) {+    $(i).removeAttr('disabled').animate({opacity: 1.0}, 'fast');+};++var bDisable = function(i) {+    $(i).attr('disabled', 'disabled').animate({opacity: 0.2}, 'fast');+}++var editable = false;++var mkEditable = function() {+    if (!editable) {+        bEnable('.btn-cancel');+        bEnable('.btn-save');+        $('#editor-box').removeClass('readonly').addClass('editable');+        editable = true;+    }+};++var mkReadOnly = function() {+    bDisable('.btn-cancel');+    bDisable('.btn-save');+    $('#editor-box').removeClass('editable').addClass('readonly');+    editable = false;+};++$('.btn-cancel').click(mkReadOnly);+mkReadOnly();+++var buildColumnMarker = function () {+  $('<div class="editor-column-marker"></div>')+    .appendTo($('.CodeMirror-wrapping'));+};++var adjustColumnMarker = function () {+  var m = $('.editor-column-marker');+  var x = "0123456789";+  x = x + x + x + x + x + x + x + x;+  m.text(x);+  var w = m.innerWidth() + $('.CodeMirror-line-numbers').outerWidth();+  m.text('');+  m.css('width', '10em');+  var v = m.width();+  m.css({ left: (w/v*10)+"em", width: '' });+}+++var preview = $('#preview');+var editor = $('#editor');+var editImage = $('#rocker-edit-image');+var runImage = $('#rocker-run-image');++var toggle = function(iIn, iOut) {+    iIn.fadeIn('fast');+    iOut.fadeOut('fast');+}++var showHide = function(pShow, pHide, iIn, iOut) {+    pShow.slideDown('fast');+    pHide.slideUp('fast');+    toggle(iIn, iOut);+}++var mkRun = function () { showHide(preview, editor, runImage, editImage); }+var mkEdit = function() { showHide(editor, preview, editImage, runImage);+                          setTimeout(adjustColumnMarker, 500); }++var run = function() {+        toggle(runImage, editImage);+        if (editable) $('#editor form').submit();+        else          mkRun();+    }+var recompile = function() {+        $('#editor form').submit();+        return false;+    }++$('#rocker-run').click(run);+$('#rocker-edit').click(mkEdit);+$('#recompile').click(recompile);++$('.panel h1').click(function () { $('.panel-content').slideToggle('fast'); });++++var cmEditor = CodeMirror.fromTextArea("txt-src", {+    basefiles: ["/static/codemirror_base_min.js"],+    parserfile: ["/static/codemirror_parse_haskell.js"],+    stylesheet: "/static/codemirror.css",+    autoMatchParens: true,+    textWrapping: false,+    lineNumbers: true,+    indentUnit: 4,+    tabMode: "shift",+    enterMode: "keep",+    minHeight: 160,+    height: "dynamic",+    markParen: ["paren-match", "paren-error"],+    onCursorActivity: function(node) {+        var sel = cmEditor.selection();+        if (!sel) { sel = node.innerText || node.textContent; }+        var mat = sel.match(/\S(.*\S)?/);+        if (mat) { $('.research-query').val(mat[0]); }+        },+    onChange: mkEditable,+    saveFunction: run,+    onLoad: function() { buildColumnMarker(); }+});+++++var previewUrl = $('#preview-url').text();++var setErrorDetailAdjust = function(ln, lnp) {+    ln.hover(function () {+            var w = ln.offset();+            w.top  += ln.height();+            w.left += ln.width() * 1.3;+            lnp.css(w);+            lnp.show('fast');+            },+        function () {+            lnp.hide('fast');+        });+}+var compileResult = function(data, status, xhr) {+    if (data == "OK") {+        if ($('#preview').length > 0) {+            $('#preview .panel-content').hide();+            $('#preview iframe').attr('src', previewUrl);+            setTimeout(function() {+                $('#preview .panel-content').show('fast');+                }, 500);            +            if ($('#preview-show').length > 0)  mkRun();+            else                                mkEdit();+        }+    }+    else {+        setTimeout(function () {+            var lns = $('.CodeMirror-line-numbers div');+            var ln, lnp, lnps = [];+            +            var r = /\.hs:(\d+):(\d+):$/;+            var dataLines = data.split("\n")+            for (var i in dataLines) {+                var e = dataLines[i].match(r);+                if (e) {+                    var n = e[1];+                    if (lnps[n]) {+                        lnp = lnps[n]+                    }+                    else {+                        ln = lns.eq(n-1);+                        ln.addClass('error-line');+                        lnp = $('<pre class="error-details"></pre>')+                        lnp.appendTo($('body'));+                        setErrorDetailAdjust(ln, lnp);+                        lnps[n] = lnp;+                    }+                }+                else if (lnp) {+                    var l = dataLines[i];+                    if (l.slice(0,4) == '    ') { l = l.slice(4); }+                    lnp.text(lnp.text() + l + "\n");+                }+            }+            +        }, 300);+        $('#errors .panel-content').text(data);+        $('#errors .panel-content').hide();+        $('#errors').show('fast');+        mkEdit();+    }+}++if (previewUrl) {+    $.ajax({+        url: previewUrl + "?__compile_only=1",+        success: compileResult,+        dataType: "text"+        });+}+else {+    mkEdit();+}++})
+ seed/Template.hs view
@@ -0,0 +1,9 @@+module Template where
+
+import Text.Html
+
+page = thehtml << [
+    h1 << "Hi!",
+    paragraph << "testing",
+    ulist << map (li <<) [ bold << "one", italics << "two", tt << "three"]
+    ]
+ seed/lib/DevUtils.hs view
@@ -0,0 +1,270 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module DevUtils (+    devpage,+    Doc(..), documents,+    +    legalPath,+    +    SrcInfo(..), getSrcInfo,+    SrcClass(..),+    previewPath,+    previewLink, editLink, downloadLink, fileLink,+    +    htmlResponse,+    finishWithError, errorBadRequest,+    ) where+    +import qualified Data.ByteString.Char8 as C+import qualified Data.Map as M+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Snap.Types+import System.Directory+import System.FilePath ((</>), dropExtension, joinPath,+    splitDirectories, takeExtension)+import System.Time (ClockTime, getClockTime)+import Text.Html hiding ((</>))++--+-- DEV PAGE LAYOUT+--++devpage :: HTML a => String -> a -> [Html] -> [String] -> Html+devpage pageTitle contents modules scriptSrcs =+    header << [+      thelink ! [href "/static/barley.css", rel "stylesheet",+                   thetype "text/css"] << noHtml,+      thetitle << fullTitle+      ] ++++    body ! [theclass "with-topbar"] << [+      h1 ! [identifier "logo"] << "Barley",+      thediv ! ([identifier "content"] ++ withSidebar modules) <<+        (toHtml contents +++ toHtml (sidebar modules)),+      topbar,+      scripts scriptSrcs+      ]+  where+    fullTitle = if null pageTitle then "Barley" else "Barley - " ++ pageTitle++sidebar :: [Html] -> Html+sidebar [] = noHtml+sidebar modules = thediv ! [identifier "sidebar"] <<+    map (thediv ! [theclass "module"]) modules++withSidebar :: [Html] -> [HtmlAttr]+withSidebar [] = []+withSidebar _ = [theclass "with-sidebar"]++topbar :: Html+topbar = thediv ! [identifier "topbar"] << [+    ulist ! [theclass "left"] << li <<+         [ anchor ! [href "http://haskell.org/", theclass "logo"] << "Haskell" +         , unordList $ map makelink communityLinks+         ]+    , ulist ! [theclass "right"] << map li siteLinks+    ]+  where+    makelink (title, url) = anchor ! [href url] << title+    makeDocLink doc = anchor ! [href $ docUrl doc, target "_blank"]+        << docName doc+    communityLinks =+        [ ("Platform", "http://hackage.haskell.org/platform/")+        , ("Hackage", "http://hackage.haskell.org/packages/hackage.html")+        , ("Reddit", "http://www.reddit.com/r/haskell/")+        , ("Stack Overflow",+            "http://stackoverflow.com/questions/tagged?tagnames=haskell")+        ]+    siteLinks =+        [ makelink ("Home", "/")+        , makelink ("Project", "/project")+        , makelink ("Documentation", "/documentation")+          +++ unordList (map makeDocLink documents)+        , makelink ("Help", "/help")+        ]+++scripts :: [String] -> Html+scripts = toHtml . map script+  where+    script s = tag "script" ! [ thetype "text/javascript", src s ] << noHtml+++data Doc = Doc { docId :: String, docName :: String, docUrl :: String }++documents :: [Doc]+documents =+    [ Doc "ghclibs" "Library" "http://www.haskell.org/ghc/docs/6.12.2/html/libraries/frames.html"+    , Doc "html"    "Text.Html" "http://hackage.haskell.org/packages/archive/html/1.0.1.2/doc/html/Text-Html.html"+    , Doc "snap"    "Snap"    "http://snapframework.com/docs/latest/snap-core/index.html"+    ]++docLocalUrl :: Doc -> String+docLocalUrl doc =  "/documentation?doc=" ++ docId doc++++--+-- PROJECT FILE UTILITIES+--++data SrcInfo = SrcInfo { srcPath     :: FilePath -- | path relative to project+                       , srcFullPath :: FilePath -- | absolute path+                       , srcExists   :: Bool+                       , srcWritable :: Bool+                       , srcModTime  :: Maybe ClockTime+                       , srcClass    :: SrcClass+                       }++data SrcClass = SCPage | SCImage | SCScript | SCText | SCOther | SCDir+    deriving (Eq)+    +getSrcInfo :: FilePath -> IO SrcInfo+getSrcInfo path = do+    cwd <- getCurrentDirectory+    isDir <- doesDirectoryExist path+    isFile <- doesFileExist path+    let exists = isDir || isFile+    canWrite <- if exists+        then writable `fmap` getPermissions path +        else return False -- TODO: should be writable of containing dir+    modTime <- if exists+        then Just `fmap` getModificationTime path+        else return Nothing+    let cls = if isDir+            then SCDir+            else M.findWithDefault SCOther (takeExtension path) extToSrcClass+    return SrcInfo { srcPath = path+                   , srcFullPath = cwd </> path+                   , srcExists = exists+                   , srcWritable = canWrite+                   , srcModTime = modTime+                   , srcClass = cls+                   }++extToSrcClass = M.fromList+    [ (".html", SCPage)+    , (".xhtml",SCPage)+    , (".txt",  SCPage)+    , (".hs",   SCScript)+    , (".css",  SCText)+    , (".js",   SCText)+    , (".json", SCText)+    , (".xml",  SCText)+    , (".gif",  SCImage)+    , (".jpeg", SCImage)+    , (".jpg",  SCImage)+    , (".pdf",  SCImage)+    , (".png",  SCImage)+    , (".svg",  SCImage)+    ]+      +previewPath :: SrcInfo -> Maybe FilePath+previewPath si = if not (srcExists si) || libDir+                        then Nothing+                        else pp $ srcClass si+  where+    libDir = case splitDirectories path of+                        ("lib":_) -> True+                        _ -> False+    path = srcPath si+    pp SCPage = Just path+    pp SCScript = Just $ dropExtension path+    pp SCImage = Just path+    pp _ = Nothing++previewLink :: SrcInfo -> Maybe Html+previewLink si = build (srcClass si) `fmap` previewPath si+  where+    build fc p = anchor ! [href p, target "_blank", theclass "op-preview",+                    title ("View the " ++ long fc ++ "in another window")]+                    << thespan << ("View " ++ short fc)+                    +    short SCPage = "Page"+    short SCScript = "Page"+    short SCImage = "Image"+    short SCText = "Text"+    short SCOther = "File"+    short SCDir = "Dir"++    long SCPage = "page"+    long SCScript = "generated page"+    long SCImage = "image"+    long SCText = "text"+    long SCOther = "file"+    long SCDir = "dir"++editLink :: SrcInfo -> Maybe Html+editLink si = build `fmap` ee (srcClass si)+  where+    build n = anchor ! [href src, theclass "op-edit", title ("Edit the " ++ n)]+                << thespan << "Edit"+    src = "source?file=" ++ srcPath si+    ee SCPage = Just "page"+    ee SCScript = Just "script"+    ee SCText = Just "text"+    ee _ = Nothing+    +downloadLink :: SrcInfo -> Maybe Html+downloadLink si = build `fmap` dd (srcClass si)+  where+    build n = anchor ! [href (srcPath si), theclass "op-download",+                    title ("Download the " ++ n)]+                    << thespan << "Download"+    dd SCText = Just "text"+    dd SCScript = Just "script"+    dd _ = Nothing++fileLink :: SrcInfo -> Maybe Html+fileLink si = Just $ anchor ! [href ("file://" ++ srcFullPath si),+                    theclass "op-file",+                    title "Provides a file:// scheme URL to the local file"]+                    << thespan << "Local File"+++-- copied from Barley.Utils for now as there is no way to import it+legalPath :: FilePath -> Maybe FilePath+legalPath p =+    if any illegalComponent components+        then Nothing+        else Just $ joinPath components+  where+    components = splitDirectories p+    illegalComponent "" = True+    illegalComponent ('.':_) = True+    illegalComponent s = any (`elem` "/\\:") s +++--+-- SNAP UTILITIES+--++htmlResponse :: HTML a => a -> Snap ()+htmlResponse html = do+    modifyResponse $ setContentType (C.pack "text/html; charset=UTF-8")+    writeBS $ (T.encodeUtf8 . T.pack) $ renderHtml html++-- copied from Barley.Utils for now as there is no way to import it+  +-- | Immediately finish with an HTTP error status+finishWithError :: Int -> String -> Snap ()+finishWithError status message =+    finishWith $ setResponseStatus status (C.pack message) emptyResponse++-- | Common HTTP error statuses+errorBadRequest :: Snap ()+errorBadRequest = finishWithError 400 "Bad Request"++
+ seed/lib/Slides.hs view
@@ -0,0 +1,71 @@+module Slides (+    slideDeck,+    titleSlide,+    pointSlide,+    codeSlide,+    ) where++import Text.Html++slideDeck :: String -> [Html] -> Html+slideDeck title slides =+    header <<+        [ thetitle << title+        , thelink ! [href "/static/slides.css", rel "stylesheet",+                   thetype "text/css"] << noHtml+        ]+    ++++    body << (slideArea : buttons : scripts)+  where+    buttons = thediv ! [ identifier "controls" ] <<+        [ anchor ! [ identifier "prev-slide", href "#" ] << "prev"+        , anchor ! [ identifier "next-slide", href "#" ] << "next"+        ]+    scripts = map mkScript [ "/static/jquery.js", "/static/Slides.js" ]+    mkScript s = tag "script" ! [ thetype "text/javascript", src s ] << noHtml+    slideArea = thediv ! [ identifier "slides" ] << slides++titleSlide :: String -> [String] -> Html+titleSlide heading subHeadings =+    thediv ! [ theclass "slide title-slide" ] <<+        (h1 << heading : map (h2 <<) subHeadings)++pointSlide :: String -> String -> [String] -> Html+pointSlide heading leadIn points =+    thediv ! [ theclass "slide bullet-slide" ] <<+        [ h1 << heading+        , if null leadIn then noHtml else p << leadIn+        , ulist << map (li <<) points+        ]++codeSlide :: String -> String -> [String] -> Html+codeSlide heading leadIn codeLines =+    thediv ! [ theclass "slide code-slide" ] <<+        [ h1 << heading+        , if null leadIn then noHtml else p << leadIn+        , pre << unlines codeLines+        ]++class SlideItem a where+    render :: a -> Html+    renderList :: [a] -> Html++instance (SlideItem a) => SlideItem [a] where+    render = renderList+    renderList as = ulist << map ((li <<).render) as+    +instance SlideItem Char where +    render = toHtml . (:[])+    renderList = toHtml++instance SlideItem Html where+    render = id+    renderList hs = ulist << map (li <<) hs++slide :: (SlideItem a) => String -> String -> a -> Html+slide heading leadIn content = +    thediv ! [ theclass "slide" ] <<+        [ if null heading then noHtml else h1 << heading+        , if null leadIn then noHtml else p << leadIn+        , render content+        ]
+ seed/lib/Tutorial.hs view
@@ -0,0 +1,121 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Tutorial(+    isTutorialPage,+    tutorialPrev,+    tutorialNext,+    tutorialModule,+    tutorialOutlineModule,+    ) where++import Control.Monad (join)+import Data.List (groupBy)+import Text.Html++data StepType = Slides | Code+data Step = Step { stepCh, stepSt :: Int, stepType :: StepType }++stepUrl :: Step -> String+stepUrl s = "Chapter" ++ cn ++ "/Step_" ++ cn ++ "_" ++ sh+  where+   cn = show $ stepCh s+   sh = show $ stepSt s++stepHref :: Step -> String+stepHref s = "source?file=" ++ stepUrl s ++ ".hs" ++ p (stepType s)+  where+    p Code = ""+    p Slides = "&preview=1"++stepLongName :: Step -> String+stepLongName (Step ch st _) = "Chapter " ++ show ch ++ ", Step " ++ show st++stepShortName :: Step -> String+stepShortName (Step _ st _ ) = "Step " ++ show st++stepLink :: Step -> Html+stepLink s = anchor ! [href $ stepHref s] << stepLongName s+++-- | The list of URL paths that are in the tutorial, in order.+steps :: [Step]+steps =+    [ Step 1 1 Slides+    , Step 1 2 Code+    , Step 1 3 Slides+    , Step 1 4 Code+    , Step 1 5 Slides+    , Step 1 6 Code+    , Step 1 7 Code+    , Step 2 1 Slides+    , Step 2 2 Code+    , Step 2 3 Code+    , Step 2 4 Slides+    , Step 2 5 Code+    , Step 2 6 Code+    , Step 3 1 Slides+    , Step 3 2 Code+    , Step 3 3 Slides+    , Step 3 4 Code+    , Step 3 5 Slides+    , Step 3 6 Code+    , Step 3 7 Code+    ]++stepUrls :: [String]+stepUrls = map stepUrl steps++-- | A assoc list that maps URLs in the tutorial to the previous and next URLs+-- in the list+pagePrevNext :: [(String, (Maybe Step, Maybe Step))]+pagePrevNext = zip stepUrls $ zip prevList nextList+  where+    prevList = Nothing : justSteps+    nextList = tail justSteps ++ [Nothing]+    justSteps = map Just steps++lookupIn :: (Eq k) => [(k, v)] -> k -> Maybe v+lookupIn = flip lookup+++isTutorialPage :: String -> Bool+isTutorialPage t = t `elem` stepUrls++tutorialPrev :: String -> Maybe Step+tutorialPrev = join . fmap fst . lookupIn pagePrevNext++tutorialNext :: String -> Maybe Step+tutorialNext = join . fmap snd  . lookupIn pagePrevNext++tutorialModule :: String -> Maybe Html+tutorialModule t =+    if isTutorialPage t then Just modHtml else Nothing+  where+    modHtml = (h2 << "Tutorial") ++++        [ p << (toHtml "Prev: " +++ linkTo (tutorialPrev t))+        , p << (toHtml "Next: " +++ linkTo (tutorialNext t))+        ]+    linkTo = maybe (toHtml "--none--") stepLink+    +tutorialOutlineModule :: Html+tutorialOutlineModule = (h2 << "Tutorial") +++ map section groupedSteps+  where+    groupedSteps = groupBy (\a b -> stepCh a == stepCh b) steps+    section ss@((Step ch _ _):_) = heading +++ list+      where+        heading = p << ("Chapter " ++ show ch)+        list = unordList (map stepLink ss)+        stepLink s = anchor ! [href $ stepHref s] << stepShortName s+
+ seed/static/Slides.js view
@@ -0,0 +1,40 @@+var slides = $('.slide');++var currSlide = 0;+var numSlides = slides.length;++var fullWidth = slides.eq(0).outerWidth() + 32; // space between slides++var inState       = { left: 0 }+var outRightState = { left: fullWidth }+var outLeftState  = { left: -fullWidth }+var speed = 'fast';++for (i in slides) {+    if (i > 0) slides.eq(i).css({left: fullWidth});+}++var out+var gotoSlide = function (nextSlide) {+    if (nextSlide < 0) nextSlide = 0;+    if (nextSlide >= numSlides) nextSlide = numSlides - 1;+    if (nextSlide == currSlide) return;+    +    var cs = slides.eq(currSlide);+    var ns = slides.eq(nextSlide);+    +    if (nextSlide > currSlide) {+        ns.css(outRightState);+        cs.animate(outLeftState, speed);+    }+    else {+        ns.css(outLeftState);+        cs.animate(outRightState, speed);+    }+    ns.animate(inState, speed);+    +    currSlide = nextSlide;+}++$('#prev-slide').click(function(){ gotoSlide(currSlide - 1); return false; })+$('#next-slide').click(function(){ gotoSlide(currSlide + 1); return false; })
+ seed/static/barley-and-beetle.png view

binary file changed (absent → 30063 bytes)

+ seed/static/barley-logo.png view

binary file changed (absent → 34396 bytes)

+ seed/static/barley.css view
@@ -0,0 +1,494 @@+/* @override +	http://localhost:8080/static/barley.css+*/++* {+  margin: 0;+  padding: 0;+}++/* @group Basics & Layout */++body {+  background: #fff url(ribbon.png) repeat-x scroll 0 0;+  min-width: 400px;+  position: relative;+}++#logo {+  position: absolute;+  text-indent: -9000em;+  background: url(barley-logo.png) no-repeat;+  width: 250px;+  height: 80px;+}++#content {+  position: relative;+  padding: 100px 15px 0;+  background: url(barley-and-beetle.png) no-repeat right top;+}++p {+  margin: 0.5em 0;+}++ul, ol, dl {+  margin: 0.5em 3em;+}++pre {+  margin: 1em 0;+  overflow: auto;+}++.src {+  padding: 0.5em 1em;+  background: rgb(229,237,244);+}++select, input, button, textarea {+  color: #424242;+}++/* @end */++/* @group Fonts & Sizes */++/* Basic technique & IE workarounds from YUI 3+   For reasons, see:+      http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css+ */+ +body {+  font:13px/1.4 "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;;+  *font-size:small; /* for IE */+  *font:x-small; /* for IE in quirks mode */+  color: #424242;+}++h1, h2, h3, h4, h5, h6, b {+  color: #cc2900;+}++h1, h2, h3, h4, h5, h6 {+  font-family: Skia, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;+}++h1 { font-size: 146.5%; /* 19pt */ } +h2 { font-size: 131%;   /* 17pt */ }+h3 { font-size: 116%;   /* 15pt */ }+h4 { font-size: 100%;   /* 13pt */ }+h5 { font-size: 100%;   /* 13pt */ }++b {+  font-weight: normal;+}++p small {+  font-size: 85%; /* 11pt */+}+select, input, button, textarea {+  font:99% sans-serif;+}++table {+  font-size:inherit;+  font:100%;+}++pre, code, kbd, samp, tt, .src {+  font-family:monospace;+  *font-size:108%;+  line-height: 124%;+}++/* @end */++/* @group Sidebar */++#content.with-sidebar {+  padding-right: 15em;+}++#sidebar {+  width: 14em;+  position: absolute;+  top: 100px;+  right: 0;+  border-left: 1px dashed #cc2900;+}++#sidebar .module {+  font-size: 85%; /* 11pt */+  line-height: 1.25em;+  margin: 0 1.5em;+}++#sidebar .module + .module {+  margin-top: 1.5em;+  padding-top: 1.5em;+  border-top: 1px dashed #cc2900;+}++#sidebar pre {+  overflow: hidden;+  font-size: 100%;+}++#sidebar form {+  margin-top: 0.5em;+}+#sidebar input[type=text] {+  width: 8em;+  margin-right: 1em;+}+#sidebar input[type=submit] {+  font-size: 85%; /* 11pt */+}++#sidebar ul {+  margin: 0.5em 0;+}++#sidebar li {+  padding: 0 0 2px;+  margin: 0 0 0 1.5em;+}++#sidebar li a {+  text-decoration: none;+}++#sidebar li.op {+  list-style-type: none;+}+#sidebar li.op a {+  background-repeat: no-repeat;+  padding: 0 0 0 22px;+  display: block;+  height: 16px;+}++/* @end */++/* @group Topbar */++body.with-topbar {+  border-top: 29px solid rgb(78,98,114);+  background-position: 0 29px;+}++#topbar {+  background: rgb(41,56,69);+  color: #white;+  position: absolute;+  top: -22px;+  right: 0;+  left: 0;+  height: 22px;+  font: 12px/22px sans-serif;+}++#topbar ul {+  list-style: none;+  display: inline-table;+  margin: 0;+}++#topbar ul.left {+  float: left;+}++#topbar ul.right {+  float: right;+}++#topbar ul li {+  display: inline;+  white-space: nowrap;+  position: relative;+}++#topbar ul li + li {+  border-left: 1px solid #d5d5d5; +}++#topbar ul li ul {+  position: absolute;+  top: 17px;+  background-color: rgba(0,0,0,0.5);+}++#topbar ul.left li ul { left: -9999em; }+#topbar ul.left li:hover ul { left: 0; }+#topbar ul.right li ul { right: 9999em; }+#topbar ul.right li:hover ul { right: 0; }++#topbar ul li a {+  padding: 4px 6px;+}++#topbar ul li a.logo {+  padding-left: 36px;+  background: url(hslogo-16.png) no-repeat 8px 3px;+}++#topbar a:link,+#topbar a:visited {+  text-decoration: none;+  color: white;+}++#topbar a:hover,+#topbar ul li a.logo:hover {+  background-color: rgba(255,255,255,0.25);+}++/* @end */++/* @group Source View */++#source-page {+  position: relative;+}++.button-set {+  text-align: right;+}++#rocker {+  position: absolute;+  width: 104px;+  text-align: right;+  top: 0;+  right: 0;+}++#rocker a {+  display: inline-block;+  width: 52;+  text-align: center;+  padding-top: 34px;+  text-decoration: none;+}++#rocker-run-image,+#rocker-edit-image {+  background-image: url(switches.png);+  background-repeat: no-repeat;+  position: absolute;+  top: 0;+  left: 0;+  width: 104px;+  height: 36px;+  z-index: -1;+}++#rocker-edit-image { background-position: 0 -36px; } +#rocker-run-image { background-position: 0 0px; } +++.button-set button,+.button-set input[type=button] {+  padding: 0 0.75em;+  margin: 0 0.25em;+}+++#editor {+  margin: 0.5em 0 1em;+}+++#editor-box {+  font-family:monospace;+  font-size: 93%; /* 12pt */+  line-height: 124%;+  margin: 1em 0;+  overflow: auto;+  background: #ffffe5;+  border: 1px solid #b1b18e;+  padding-left: 0.75em;+}++#editor-box.editable {+  background: #ff0 url(stripe.png);+}++#editor-box textarea,+#editor-box .CodeMirror-wrapping {+  padding-left: 3.72em;+}++#editor-box .CodeMirror-line-numbers {+  text-align: right;+  padding: 1em 1em 1em 0;+  width: 3em;+  color: #a9a9a9;+}++#editor-box .CodeMirror-line-numbers div.error-line {+  color: #ff4d4d;+  font-weight: bold;+  background: url(silk/exclamation.png) no-repeat -1px -1px;+  position: relative;+}++.error-details {+  display: none;+  position: absolute;+  text-align: left;+  background-color: #ffe5e5;+  margin: 0;+  padding: 4px;+  color: #7f3500;+  font-size: 92.3%;+  border: 1px solid #b1b18e;+}++#editor-box textarea.src {+  width: 100%;+}++#editor-box .CodeMirror-wrapping div,+#editor-box .CodeMirror-wrapping iframe {+  background: #ffffe5;+}++#editor-box .CodeMirror-wrapping .editor-column-marker {+  position: absolute;+  top: 0;+  height: 100%;+  left: 4em;+  background-color: transparent;+  border-left: 1px dashed #e0e0b4;+}+.panel {+  background-color: #eee7b9;+  width: 99%;+  padding: 4px 6px 4px 4px;+  margin: 1em 0;+  text-align: left;+}++.panel.with-errors{+  background-color: #ffe5e5;+}++.panel h1 {+  margin: 0.25em 0.25em 0 0.25em;+  font-weight: normal;+}++.panel-content {+  background: white;+  width: 100%;+  overflow: visible;+  margin: 0.5em 0 0;+  border: 1px solid #919191;+}++#preview iframe {+  height: 40em;+}++#errors pre {+  font-size: 93%; /* 12pt */+  line-height: 124%;+}++/* @end */++/* @group Project View */++table#filelist {+  margin: 1em 0;+  padding: 0;+  border-collapse: collapse;+  width: 100%;+  border: 1px solid #c0c0c0;+}++#filelist .even {+  background-color: #f4f4f4;+}+#filelist .odd {+  background-color: #fafafa;+}++#filelist tr:hover {+  background-color: #ffc;+}++#filelist tr {+}+#filelist td {+  padding: 0.25em 0.5em;+}++#filelist p {+  margin: 0;+}++#filelist .dir {+  font-style: italic;+  color: #7b9bcc;+  font-size: 85%; /* 11pt */+  padding-right: 0.5em;+}++#filelist .name {+  padding-left: 20px;+  padding-top: 2px;+  background-repeat: no-repeat;+  background-position: left center;+}+#filelist .src-page { background-image: url(silk/page_white_world.png); }+#filelist .src-text { background-image: url(silk/page_white_code.png); }+#filelist .src-image { background-image: url(silk/image.png); }+#filelist .src-script { background-image: url(silk/page_white_code_red.png); }+#filelist .src-other { background-image: url(silk/page_white.png); }+#filelist .src-dir { background-image: url(silk/folder.png); }++#filelist .op { +  padding: 0;+  width: 30px;+}+#filelist .op a {+  font-size: 16px;+  background-repeat: no-repeat;+  padding: 0 0 0 16px;+}++#filelist a span {+  display: none;+}+/* @end */++/* @group Op Icons */++.op-preview { background-image: url(silk/magnifier.png); }+.op-edit { background-image: url(silk/pencil.png); }+.op-download { background-image: url(silk/arrow_down.png); }+.op-file { background-image: url(silk/link.png); }+.op-recompile { background-image: url(silk/lightning.png); }++/* @end */++/* @group Documentation View */++#documentation {+  position: fixed;+  width: 100%;+  height: 100%;+  left: 0;+  top: 112px;+  border-style: none;+  border-top: 2px solid #c0c0c0;+}++++/* @end */+
+ seed/static/codemirror.css view
@@ -0,0 +1,47 @@+/* @override http://localhost:8080/static/codemirror.css */++* {+  margin: 0;+  padding: 0;+}++body {+  font:12px/14px monospace;+  overflow: auto;+  padding: 1em 0;+}++.paren-match { background-color: #9cc2fd; }+.paren-error {+  background-color: #ff4d4d;+  color: #fff;+  font-weight: bold;+}++.hs-char,+.hs-float,+.hs-integer,+.hs-string 	{ color: #7f7519;}++.hs-comment { color: #236E25; font-style: italic; }+.hs-pragma	{ }++.hs-prelude-varid,+.hs-prelude-varsym,+.hs-special,+.hs-varid,+.hs-varsym	{ }++.hs-conid,+.hs-consym	{ color: #cc2900; }++.hs-reservedid,+.hs-reservedop { color: #7f3500; font-weight: bold; }++.hs-qualifier { color: #5e5e5e;}+.hs-error	{ background-color: #ffe5e5; }++.hs-prelude-varid,+.hs-prelude-varsym,+.hs-prelude-conid { color: #250087; }+
+ seed/static/codemirror_base_min.js view
@@ -0,0 +1,88 @@+function method(f,l){return function(){f[l].apply(f,arguments)}}var StopIteration={toString:function(){return"StopIteration"}};function forEach(f,l){if(f.next)try{for(;;)l(f.next())}catch(k){if(k!=StopIteration)throw k;}else for(var m=0;m<f.length;m++)l(f[m])}function map(f,l){var k=[];forEach(f,function(m){k.push(l(m))});return k}function matcher(f){return function(l){return f.test(l)}}function hasClass(f,l){var k=f.className;return k&&RegExp("(^| )"+l+"($| )").test(k)}+function removeClass(f,l){f.className=f.className.replace(RegExp(" "+l+"\\b","g"),"");return f}function insertAfter(f,l){l.parentNode.insertBefore(f,l.nextSibling);return f}function removeElement(f){f.parentNode&&f.parentNode.removeChild(f)}function clearElement(f){for(;f.firstChild;)f.removeChild(f.firstChild)}function isAncestor(f,l){for(;l=l.parentNode;)if(f==l)return true;return false}var nbsp="\u00a0",matching={"{":"}","[":"]","(":")","}":"{","]":"[",")":"("};+function normalizeEvent(f){if(!f.stopPropagation){f.stopPropagation=function(){this.cancelBubble=true};f.preventDefault=function(){this.returnValue=false}}if(!f.stop)f.stop=function(){this.stopPropagation();this.preventDefault()};if(f.type=="keypress"){f.code=f.charCode==null?f.keyCode:f.charCode;f.character=String.fromCharCode(f.code)}return f}+function addEventHandler(f,l,k,m){function q(p){k(normalizeEvent(p||window.event))}if(typeof f.addEventListener=="function"){f.addEventListener(l,q,false);if(m)return function(){f.removeEventListener(l,q,false)}}else{f.attachEvent("on"+l,q);if(m)return function(){f.detachEvent("on"+l,q)}}}function nodeText(f){return f.textContent||f.innerText||f.nodeValue||""}function nodeTop(f){for(var l=0;f.offsetParent;){l+=f.offsetTop;f=f.offsetParent}return l}+function isBR(f){f=f.nodeName;return f=="BR"||f=="br"}function isSpan(f){f=f.nodeName;return f=="SPAN"||f=="span"};var stringStream=function(f){function l(){for(;m==k.length;){q+=k;k="";m=0;try{k=f.next()}catch(p){if(p!=StopIteration)throw p;else return false}}return true}var k="",m=0,q="";return{peek:function(){if(!l())return null;return k.charAt(m)},next:function(){if(!l())if(q.length>0)throw"End of stringstream reached without emptying buffer ('"+q+"').";else throw StopIteration;return k.charAt(m++)},get:function(){var p=q;q="";if(m>0){p+=k.slice(0,m);k=k.slice(m);m=0}return p},push:function(p){k=k.slice(0,+m)+p+k.slice(m)},lookAhead:function(p,w,a,d){function g(i){return d?i.toLowerCase():i}p=g(p);var b=false,c=q,e=m;for(a&&this.nextWhileMatches(/[\s\u00a0]/);;){a=m+p.length;var h=k.length-m;if(a<=k.length){b=p==g(k.slice(m,a));m=a;break}else if(p.slice(0,h)==g(k.slice(m))){q+=k;k="";try{k=f.next()}catch(j){if(j!=StopIteration)throw j;break}m=0;p=p.slice(h)}else break}if(!(b&&w)){k=q.slice(c.length)+k;m=e;q=c}return b},lookAheadRegex:function(p,w){if(p.source.charAt(0)!="^")throw Error("Regexps passed to lookAheadRegex must start with ^");+for(;k.indexOf("\n",m)==-1;)try{k+=f.next()}catch(a){if(a!=StopIteration)throw a;break}var d=k.slice(m).match(p);if(d&&w)m+=d[0].length;return d},more:function(){return this.peek()!==null},applies:function(p){var w=this.peek();return w!==null&&p(w)},nextWhile:function(p){for(var w;(w=this.peek())!==null&&p(w);)this.next()},matches:function(p){var w=this.peek();return w!==null&&p.test(w)},nextWhileMatches:function(p){for(var w;(w=this.peek())!==null&&p.test(w);)this.next()},equals:function(p){return p===+this.peek()},endOfLine:function(){var p=this.peek();return p==null||p=="\n"}}};var select={};+(function(){function f(b,c){for(;b&&b.parentNode!=c;)b=b.parentNode;return b}function l(b,c){for(;!b.previousSibling&&b.parentNode!=c;)b=b.parentNode;return f(b.previousSibling,c)}function k(b){var c=b.nextSibling;if(c){for(;c.firstChild;)c=c.firstChild;return c.nodeType==3||isBR(c)?c:k(c)}else{for(b=b.parentNode;b&&!b.nextSibling;)b=b.parentNode;return b&&k(b)}}select.ie_selection=document.selection&&document.selection.createRangeCollection;select.scrollToNode=function(b,c){if(b){for(var e=b,h=document.body,+j=document.documentElement,i=!e.nextSibling||!e.nextSibling.nextSibling||!e.nextSibling.nextSibling.nextSibling,n=0;e&&!e.offsetTop;){n++;e=e.previousSibling}if(n==0)i=false;if(!(webkit&&e&&e.offsetTop==5&&e.offsetLeft==5)){n=n*(e?e.offsetHeight:0);var r=0,t=b?b.offsetWidth:0;for(e=e;e&&e.offsetParent;){n+=e.offsetTop;isBR(e)||(r+=e.offsetLeft);e=e.offsetParent}e=h.scrollLeft||j.scrollLeft||0;h=h.scrollTop||j.scrollTop||0;var o=false,u=window.innerWidth||j.clientWidth||0;if(c||t<u){if(c){var x=select.offsetInNode(b),+s=nodeText(b).length;if(s)r+=t*(x/s)}t=r-e;if(t<0||t>u){e=r;o=true}}r=n-h;if(r<0||i||r>(window.innerHeight||j.clientHeight||0)-50){h=i?1E6:n;o=true}o&&window.scrollTo(e,h)}}};select.scrollToCursor=function(b){select.scrollToNode(select.selectionTopNode(b,true)||b.firstChild,true)};var m=null;select.snapshotChanged=function(){if(m)m.changed=true};select.snapshotReplaceNode=function(b,c,e,h){function j(i){if(b==i.node){m.changed=true;if(e&&i.offset>e)i.offset-=e;else{i.node=c;i.offset+=h||0}}else if(select.ie_selection&&+i.offset==0&&i.node==k(b))m.changed=true}if(m){j(m.start);j(m.end)}};select.snapshotMove=function(b,c,e,h,j){function i(n){if(b==n.node&&(!j||n.offset==0)){m.changed=true;n.node=c;n.offset=h?Math.max(0,n.offset+e):e}}if(m){i(m.start);i(m.end)}};if(select.ie_selection){var q=function(){var b=document.selection;if(!b)return null;return b.createRange?b.createRange():b.createTextRange()},p=function(b){function c(t){for(var o=null;!o&&t;){o=t.nextSibling;t=t.parentNode}return e(o)}function e(t){for(;t&&+t.firstChild;)t=t.firstChild;return{node:t,offset:0}}var h=q();h.collapse(b);b=h.parentElement();if(!isAncestor(document.body,b))return null;if(!b.firstChild)return e(b);var j=h.duplicate();j.moveToElementText(b);j.collapse(true);for(var i=b.firstChild;i;i=i.nextSibling){if(i.nodeType==3){var n=i.nodeValue.length;j.move("character",n)}else{j.moveToElementText(i);j.collapse(false)}var r=h.compareEndPoints("StartToStart",j);if(r==0)return c(i);if(r!=1){if(i.nodeType!=3)return e(i);j.setEndPoint("StartToEnd",+h);return{node:i,offset:n-j.text.length}}}return c(b)};select.markSelection=function(){m=null;if(document.selection){var b=p(true),c=p(false);if(b&&c)m={start:b,end:c,changed:false}}};select.selectMarked=function(){function b(h){var j=document.body.createTextRange(),i=h.node;if(i)if(i.nodeType==3){j.moveToElementText(i.parentNode);for(h=h.offset;i.previousSibling;){i=i.previousSibling;h+=(i.innerText||"").length}j.move("character",h)}else{j.moveToElementText(i);j.collapse(true)}else{j.moveToElementText(document.body);+j.collapse(false)}return j}if(m&&m.changed){var c=b(m.start),e=b(m.end);c.setEndPoint("StartToEnd",e);c.select()}};select.offsetInNode=function(b){var c=q();if(!c)return 0;var e=c.duplicate();try{e.moveToElementText(b)}catch(h){return 0}c.setEndPoint("StartToStart",e);return c.text.length};select.selectionTopNode=function(b,c){function e(o,u){if(u.nodeType==3){for(var x=0,s=u.previousSibling;s&&s.nodeType==3;){x+=s.nodeValue.length;s=s.previousSibling}if(s){try{o.moveToElementText(s)}catch(v){return false}o.collapse(false)}else o.moveToElementText(u.parentNode);+x&&o.move("character",x)}else try{o.moveToElementText(u)}catch(y){return false}return true}var h=q();if(!h)return false;var j=h.duplicate();h.collapse(c);var i=h.parentElement();if(i&&isAncestor(b,i)){j.moveToElementText(i);if(h.compareEndPoints("StartToStart",j)==1)return f(i,b)}c=0;for(i=b.childNodes.length-1;c<i;){var n=Math.ceil((i+c)/2),r=b.childNodes[n];if(!r)return false;if(!e(j,r))return false;if(h.compareEndPoints("StartToStart",j)==1)c=n;else i=n-1}if(c==0){h=q();j=h.duplicate();try{j.moveToElementText(b)}catch(t){return null}if(h.compareEndPoints("StartToStart",+j)==0)return null}return b.childNodes[c]||null};select.focusAfterNode=function(b,c){var e=document.body.createTextRange();e.moveToElementText(b||c);e.collapse(!b);e.select()};select.somethingSelected=function(){var b=q();return b&&b.text!=""};var w=function(b){var c=q();if(c){c.pasteHTML(b);c.collapse(false);c.select()}};select.insertNewlineAtCursor=function(){w("<br>")};select.insertTabAtCursor=function(){w("\u00a0\u00a0\u00a0\u00a0")};select.cursorPos=function(b,c){var e=q();if(!e)return null;for(var h=+select.selectionTopNode(b,c);h&&!isBR(h);)h=h.previousSibling;var j=e.duplicate();e.collapse(c);if(h){j.moveToElementText(h);j.collapse(false)}else{try{j.moveToElementText(b)}catch(i){return null}j.collapse(true)}e.setEndPoint("StartToStart",j);return{node:h,offset:e.text.length}};select.setCursorPos=function(b,c,e){function h(i){var n=document.body.createTextRange();if(i.node){n.moveToElementText(i.node);n.collapse(false)}else{n.moveToElementText(b);n.collapse(true)}n.move("character",i.offset);+return n}var j=h(c);e&&e!=c&&j.setEndPoint("EndToEnd",h(e));j.select()};select.getBookmark=function(b){var c=select.cursorPos(b,true);b=select.cursorPos(b,false);if(c&&b)return{from:c,to:b}};select.setBookmark=function(b,c){c&&select.setCursorPos(b,c.from,c.to)}}else{var a=function(b,c){for(;b.nodeType!=3&&!isBR(b);){var e=b.childNodes[c]||b.nextSibling;for(c=0;!e&&b.parentNode;){b=b.parentNode;e=b.nextSibling}b=e;if(!e)break}return{node:b,offset:c}};select.markSelection=function(){var b=window.getSelection();+if(!b||b.rangeCount==0)return m=null;b=b.getRangeAt(0);m={start:a(b.startContainer,b.startOffset),end:a(b.endContainer,b.endOffset),changed:false}};select.selectMarked=function(){function b(){if(e.start.node==e.end.node&&e.start.offset==e.end.offset){var j=window.getSelection();if(!j||j.rangeCount==0)return true;j=j.getRangeAt(0);j=a(j.startContainer,j.startOffset);return e.start.node!=j.node||e.start.offset!=j.offset}}function c(j,i){if(j.node)j.offset==0?h["set"+i+"Before"](j.node):h["set"+i](j.node,+j.offset);else h.setStartAfter(document.body.lastChild||document.body)}var e=m;if(e&&(e.changed||webkit&&b())){var h=document.createRange();c(e.end,"End");c(e.start,"Start");d(h)}};var d=function(b){var c=window.getSelection();if(c){c.removeAllRanges();c.addRange(b)}},g=function(){var b=window.getSelection();return!b||b.rangeCount==0?false:b.getRangeAt(0)};select.selectionTopNode=function(b,c){var e=g();if(!e)return false;var h=c?e.startContainer:e.endContainer,j=c?e.startOffset:e.endOffset;window.opera&&+!c&&e.endContainer==b&&e.endOffset==e.startOffset+1&&b.childNodes[e.startOffset]&&isBR(b.childNodes[e.startOffset])&&j--;return h.nodeType==3?j>0?f(h,b):l(h,b):h.nodeName.toUpperCase()=="HTML"?j==1?null:b.lastChild:h==b?j==0?null:h.childNodes[j-1]:j==h.childNodes.length?f(h,b):j==0?l(h,b):f(h.childNodes[j-1],b)};select.focusAfterNode=function(b,c){var e=document.createRange();e.setStartBefore(c.firstChild||c);if(b&&!b.firstChild)e.setEndAfter(b);else b?e.setEnd(b,b.childNodes.length):e.setEndBefore(c.firstChild||+c);e.collapse(false);d(e)};select.somethingSelected=function(){var b=g();return b&&!b.collapsed};select.offsetInNode=function(b){var c=g();if(!c)return 0;c=c.cloneRange();c.setStartBefore(b);return c.toString().length};select.insertNodeAtCursor=function(b){var c=g();if(c){c.deleteContents();c.insertNode(b);webkitLastLineHack(document.body);if(window.opera&&isBR(b)&&isSpan(b.parentNode)){c=b.nextSibling;var e=b.parentNode,h=e.parentNode;h.insertBefore(b,e.nextSibling);for(e="";c&&c.nodeType==3;c=c.nextSibling){e+=+c.nodeValue;removeElement(c)}h.insertBefore(makePartSpan(e,document),b.nextSibling)}c=document.createRange();c.selectNode(b);c.collapse(false);d(c)}};select.insertNewlineAtCursor=function(){select.insertNodeAtCursor(document.createElement("BR"))};select.insertTabAtCursor=function(){select.insertNodeAtCursor(document.createTextNode("\u00a0\u00a0\u00a0\u00a0"))};select.cursorPos=function(b,c){var e=g();if(e){for(var h=select.selectionTopNode(b,c);h&&!isBR(h);)h=h.previousSibling;e=e.cloneRange();e.collapse(c);+h?e.setStartAfter(h):e.setStartBefore(b);e=e.toString();return{node:h,offset:e.length}}};select.setCursorPos=function(b,c,e){function h(i,n,r){function t(s){s.nodeType==3?o.push(s):forEach(s.childNodes,t)}if(n==0&&i&&!i.nextSibling){j["set"+r+"After"](i);return true}if(i=i?i.nextSibling:b.firstChild){if(n==0){j["set"+r+"Before"](i);return true}for(var o=[];;){for(;i&&!o.length;){t(i);i=i.nextSibling}var u=o.shift();if(!u)return false;var x=u.nodeValue.length;if(x>=n){j["set"+r](u,n);return true}n-=+x}}}var j=document.createRange();e=e||c;h(e.node,e.offset,"End")&&h(c.node,c.offset,"Start")&&d(j)}}})();function UndoHistory(f,l,k,m){this.container=f;this.maxDepth=l;this.commitDelay=k;this.editor=m;this.last=this.first=f={text:"",from:null,to:null};this.firstTouched=false;this.history=[];this.redoHistory=[];this.touched=[];this.lostundo=0}+UndoHistory.prototype={scheduleCommit:function(){var f=this;parent.clearTimeout(this.commitTimeout);this.commitTimeout=parent.setTimeout(function(){f.tryCommit()},this.commitDelay)},touch:function(f){this.setTouched(f);this.scheduleCommit()},undo:function(){this.commit();if(this.history.length){var f=this.history.pop();this.redoHistory.push(this.updateTo(f,"applyChain"));this.notifyEnvironment();return this.chainNode(f)}},redo:function(){this.commit();if(this.redoHistory.length){var f=this.redoHistory.pop();+this.addUndoLevel(this.updateTo(f,"applyChain"));this.notifyEnvironment();return this.chainNode(f)}},clear:function(){this.history=[];this.redoHistory=[];this.lostundo=0},historySize:function(){return{undo:this.history.length,redo:this.redoHistory.length,lostundo:this.lostundo}},push:function(f,l,k){for(var m=[],q=0;q<k.length;q++){var p=q==k.length-1?l:document.createElement("br");m.push({from:f,to:p,text:cleanText(k[q])});f=p}this.pushChains([m],f==null&&l==null);this.notifyEnvironment()},pushChains:function(f,+l){this.commit(l);this.addUndoLevel(this.updateTo(f,"applyChain"));this.redoHistory=[]},chainNode:function(f){for(var l=0;l<f.length;l++){var k=f[l][0];if(k=k&&(k.from||k.to))return k}},reset:function(){this.history=[];this.redoHistory=[];this.lostundo=0},textAfter:function(f){return this.after(f).text},nodeAfter:function(f){return this.after(f).to},nodeBefore:function(f){return this.before(f).from},tryCommit:function(){!window||!window.parent||!window.UndoHistory||(this.editor.highlightDirty()?this.commit(true):+this.scheduleCommit())},commit:function(f){parent.clearTimeout(this.commitTimeout);f||this.editor.highlightDirty(true);f=this.touchedChains();if(f.length){this.addUndoLevel(this.updateTo(f,"linkChain"));this.redoHistory=[];this.notifyEnvironment()}},updateTo:function(f,l){for(var k=[],m=[],q=0;q<f.length;q++){k.push(this.shadowChain(f[q]));m.push(this[l](f[q]))}l=="applyChain"&&this.notifyDirty(m);return k},notifyDirty:function(f){forEach(f,method(this.editor,"addDirtyNode"));this.editor.scheduleHighlight()},+notifyEnvironment:function(){this.onChange&&this.onChange(this.editor);window.frameElement&&window.frameElement.CodeMirror.updateNumbers&&window.frameElement.CodeMirror.updateNumbers()},linkChain:function(f){for(var l=0;l<f.length;l++){var k=f[l];if(k.from)k.from.historyAfter=k;else this.first=k;if(k.to)k.to.historyBefore=k;else this.last=k}},after:function(f){return f?f.historyAfter:this.first},before:function(f){return f?f.historyBefore:this.last},setTouched:function(f){if(f){if(!f.historyTouched){this.touched.push(f);+f.historyTouched=true}}else this.firstTouched=true},addUndoLevel:function(f){this.history.push(f);if(this.history.length>this.maxDepth){this.history.shift();lostundo+=1}},touchedChains:function(){function f(a,d){if(a)a.historyTemp=d;else q=d}function l(a){for(var d=[],g=a?a.nextSibling:m.container.firstChild;g&&(!isBR(g)||g.hackBR);g=g.nextSibling)!g.hackBR&&g.currentText&&d.push(g.currentText);return{from:a,to:g,text:cleanText(d.join(""))}}function k(a,d){for(var g=d+"Sibling",b=a[g];b&&!isBR(b);)b=+b[g];return b}var m=this,q=null,p=[];m.firstTouched&&m.touched.push(null);forEach(m.touched,function(a){if(!(a&&(a.parentNode!=m.container||a.hackBR))){if(a)a.historyTouched=false;else m.firstTouched=false;var d=l(a),g=m.after(a);if(!g||g.text!=d.text||g.to!=d.to){p.push(d);f(a,d)}}});var w=[];m.touched=[];forEach(p,function(a){if(a.from?a.from.historyTemp:q){for(var d=[],g=a.from,b=true;;){var c=g?g.historyTemp:q;if(!c)if(b)break;else c=l(g);d.unshift(c);f(g,null);if(!g)break;b=m.after(g);g=k(g,+"previous")}g=a.to;for(b=m.before(a.from);;){if(!g)break;c=g?g.historyTemp:q;if(!c)if(b)break;else c=l(g);d.push(c);f(g,null);b=m.before(g);g=k(g,"next")}w.push(d)}});return w},shadowChain:function(f){var l=[],k=this.after(f[0].from);for(f=f[f.length-1].to;;){l.push(k);k=k.to;if(!k||k==f)break;else k=k.historyAfter||this.before(f)}return l},applyChain:function(f){var l=select.cursorPos(this.container,false),k=this,m=f[0].from,q=f[f.length-1].to;(function(b,c){for(var e=b?b.nextSibling:k.container.firstChild;e!=+c;){var h=e.nextSibling;removeElement(e);e=h}})(m,q);for(var p=0;p<f.length;p++){var w=f[p];p>0&&k.container.insertBefore(w.from,q);var a=makePartSpan(fixSpaces(w.text));k.container.insertBefore(a,q);if(l&&l.node==w.from){a=0;var d=this.after(w.from);if(d&&p==f.length-1){for(var g=0;g<l.offset&&w.text.charAt(g)==d.text.charAt(g);g++);if(l.offset>g)a=w.text.length-d.text.length}select.setCursorPos(this.container,{node:w.from,offset:Math.max(0,l.offset+a)})}else l&&p==f.length-1&&l.node&&l.node.parentNode!=+this.container&&select.setCursorPos(this.container,{node:w.from,offset:w.text.length})}this.linkChain(f);return m}};var internetExplorer=document.selection&&window.ActiveXObject&&/MSIE/.test(navigator.userAgent),webkit=/AppleWebKit/.test(navigator.userAgent),safari=/Apple Computer, Inc/.test(navigator.vendor),gecko=navigator.userAgent.match(/gecko\/(\d{8})/i);if(gecko)gecko=Number(gecko[1]);var mac=/Mac/.test(navigator.platform),brokenOpera=window.opera&&/Version\/10.[56]/.test(navigator.userAgent),slowWebkit=/AppleWebKit\/533/.test(navigator.userAgent);+function makeWhiteSpace(f){for(var l=[],k=true;f>0;f--){l.push(k||f==1?nbsp:" ");k^=true}return l.join("")}function fixSpaces(f){if(f.charAt(0)==" ")f=nbsp+f.slice(1);return f.replace(/\t/g,function(){return makeWhiteSpace(indentUnit)}).replace(/[ \u00a0]{2,}/g,function(l){return makeWhiteSpace(l.length)})}function cleanText(f){return f.replace(/\u00a0/g," ").replace(/\u200b/g,"")}+function makePartSpan(f){var l=f;if(f.nodeType==3)l=f.nodeValue;else f=document.createTextNode(l);var k=document.createElement("span");k.isPart=true;k.appendChild(f);k.currentText=l;return k}function alwaysZero(){return 0}var webkitLastLineHack=webkit?function(f){var l=f.lastChild;if(!l||!l.hackBR){l=document.createElement("br");l.hackBR=true;f.appendChild(l)}}:function(){};+function asEditorLines(f){var l=makeWhiteSpace(indentUnit);return map(f.replace(/\t/g,l).replace(/\u00a0/g," ").replace(/\r\n?/g,"\n").split("\n"),fixSpaces)}+var Editor=function(){function f(a,d){function g(e,h){if(e.nodeType==3){if((e.nodeValue=fixSpaces(e.nodeValue.replace(/[\r\u200b]/g,"").replace(/\n/g," "))).length)c=false;b.push(e)}else if(isBR(e)&&e.childNodes.length==0){c=true;b.push(e)}else{for(var j=e.firstChild;j;j=j.nextSibling)g(j);if(!c&&w.hasOwnProperty(e.nodeName.toUpperCase())){c=true;if(!d||!h)b.push(document.createElement("br"))}}}var b=[],c=true;g(a,true);return b}function l(a){function d(e){var h=e.parentNode,j=e.nextSibling;return function(i){h.insertBefore(i,+j)}}var g=[],b=null,c=true;return{next:function(){if(!a)throw StopIteration;var e=a;a=e.nextSibling;var h;if(e.isPart&&e.childNodes.length==1&&e.firstChild.nodeType==3){h=e.firstChild.nodeValue;e.dirty=e.dirty||h!=e.currentText;e.currentText=h;h=!/[\n\t\r]/.test(e.currentText)}else h=false;if(h){g.push(e);c=false;return e.currentText}else if(isBR(e)){c&&window.opera&&e.parentNode.insertBefore(makePartSpan(""),e);g.push(e);c=true;return"\n"}else{h=!e.nextSibling;b=d(e);removeElement(e);e=f(e,h);for(h=+0;h<e.length;h++){var j=e,i=h,n=e[h],r="\n";if(n.nodeType==3){select.snapshotChanged();n=makePartSpan(n);r=n.currentText;c=false}else{c&&window.opera&&b(makePartSpan(""));c=true}n.dirty=true;g.push(n);b(n);j[i]=r}return e.join("")}},nodes:g}}function k(a){for(;a&&!isBR(a);)a=a.previousSibling;return a}function m(a,d){if(a){if(isBR(a))a=a.nextSibling}else a=d.firstChild;for(;a&&!isBR(a);)a=a.nextSibling;return a}function q(a,d,g,b){function c(i){i=cleanText(a.history.textAfter(i));return b?i.toLowerCase():+i}this.editor=a;this.history=a.history;this.history.commit();this.valid=!!d;this.atOccurrence=false;if(b==undefined)b=typeof d=="string"&&d==d.toLowerCase();var e={node:null,offset:0},h=this;if(g&&typeof g=="object"&&typeof g.character=="number"){a.checkLine(g.line);g={node:g.line,offset:g.character};this.pos={from:g,to:g}}else this.pos=g?{from:select.cursorPos(a.container,true)||e,to:select.cursorPos(a.container,false)||e}:{from:e,to:e};if(typeof d!="string")this.matches=function(i,n,r){if(i){i=+c(n).slice(0,r);var t=i.match(d);for(r=0;t;){var o=i.indexOf(t[0]);r+=o;i=i.slice(o+1);if(o=i.match(d))t=o;else break}}else{i=c(n).slice(r);r=(t=i.match(d))&&r+i.indexOf(t[0])}if(t){h.currentMatch=t;return{from:{node:n,offset:r},to:{node:n,offset:r+t[0].length}}}};else{if(b)d=d.toLowerCase();var j=d.split("\n");this.matches=j.length==1?function(i,n,r){var t=c(n),o=d.length,u;if(i?r>=o&&(u=t.lastIndexOf(d,r-o))!=-1:(u=t.indexOf(d,r))!=-1)return{from:{node:n,offset:u},to:{node:n,offset:u+o}}}:function(i,+n,r){var t=i?j.length-1:0,o=j[t],u=c(n),x=i?u.indexOf(o)+o.length:u.lastIndexOf(o);if(!(i?x>=r||x!=o.length:x<=r||x!=u.length-o.length))for(r=n;;){if(i&&!r)break;r=i?this.history.nodeBefore(r):this.history.nodeAfter(r);if(!i&&!r)break;u=c(r);o=j[i?--t:++t];if(t>0&&t<j.length-1)if(u!=o)break;else continue;t=i?u.lastIndexOf(o):u.indexOf(o)+o.length;if(i?t!=u.length-o.length:t!=o.length)break;return{from:{node:i?r:n,offset:i?t:x},to:{node:i?n:r,offset:i?x:t}}}}}}function p(a){this.options=a;window.indentUnit=+a.indentUnit;var d=this.container=document.body;this.history=new UndoHistory(d,a.undoDepth,a.undoDelay,this);var g=this;if(!p.Parser)throw"No parser loaded.";a.parserConfig&&p.Parser.configure&&p.Parser.configure(a.parserConfig);!a.readOnly&&!internetExplorer&&select.setCursorPos(d,{node:null,offset:0});this.dirty=[];this.importCode(a.content||"");this.history.onChange=a.onChange;if(a.readOnly){if(!a.textWrapping)d.style.whiteSpace="nowrap"}else{if(a.continuousScanning!==false){this.scanner=this.documentScanner(a.passTime);+this.delayScanning()}var b=function(){if(document.body.contentEditable!=undefined&&internetExplorer)document.body.contentEditable="true";else document.designMode="on";if(internetExplorer&&a.height!="dynamic")document.body.style.minHeight=window.frameElement.clientHeight-2*document.body.offsetTop-5+"px";document.documentElement.style.borderWidth="0";if(!a.textWrapping)d.style.whiteSpace="nowrap"};try{b()}catch(c){var e=addEventHandler(document,"focus",function(){e();b()},true)}addEventHandler(document,+"keydown",method(this,"keyDown"));addEventHandler(document,"keypress",method(this,"keyPress"));addEventHandler(document,"keyup",method(this,"keyUp"));var h=function(){g.cursorActivity(false)};addEventHandler(internetExplorer?document.body:window,"mouseup",h);addEventHandler(document.body,"cut",h);gecko&&addEventHandler(window,"pagehide",function(){g.unloaded=true});addEventHandler(document.body,"paste",function(j){h();var i=null;try{var n=j.clipboardData||window.clipboardData;if(n)i=n.getData("Text")}catch(r){}if(i!==+null){j.stop();g.replaceSelection(i);select.scrollToCursor(g.container)}});this.options.autoMatchParens&&addEventHandler(document.body,"click",method(this,"scheduleParenHighlight"))}}var w={P:true,DIV:true,LI:true};q.prototype={findNext:function(){return this.find(false)},findPrevious:function(){return this.find(true)},find:function(a){function d(){var h={node:c,offset:e};g.pos={from:h,to:h};return g.atOccurrence=false}if(!this.valid)return false;var g=this,b=a?this.pos.from:this.pos.to,c=b.node,+e=b.offset;if(c&&!c.parentNode){c=null;e=0}for(;;){if(this.pos=this.matches(a,c,e))return this.atOccurrence=true;if(a){if(!c)return d();c=this.history.nodeBefore(c);e=this.history.textAfter(c).length}else{b=this.history.nodeAfter(c);if(!b){e=this.history.textAfter(c).length;return d()}c=b;e=0}}},select:function(){if(this.atOccurrence){select.setCursorPos(this.editor.container,this.pos.from,this.pos.to);select.scrollToCursor(this.editor.container)}},replace:function(a){if(this.atOccurrence){var d=+this.currentMatch;if(d)a=a.replace(/\\(\d)/,function(g,b){return d[b]});this.pos.to=this.editor.replaceRange(this.pos.from,this.pos.to,a);this.atOccurrence=false}},position:function(){if(this.atOccurrence)return{line:this.pos.from.node,character:this.pos.from.offset}}};p.prototype={importCode:function(a){var d=asEditorLines(a);if(!this.options.incrementalLoading||d.length<1E3){this.history.push(null,null,d);this.history.reset()}else{var g=0,b=this,c=function(){var e=d.slice(g,g+1E3);e.push("");b.history.push(b.history.nodeBefore(null),+null,e);b.history.reset();g+=1E3;g<d.length&&parent.setTimeout(c,1E3)};c()}},getCode:function(){if(!this.container.firstChild)return"";var a=[];select.markSelection();forEach(l(this.container.firstChild),method(a,"push"));select.selectMarked();webkit&&this.container.lastChild.hackBR&&a.pop();webkitLastLineHack(this.container);return cleanText(a.join(""))},checkLine:function(a){if(a===false||!(a==null||a.parentNode==this.container||a.hackBR))throw parent.CodeMirror.InvalidLineHandle;},cursorPosition:function(a){if(a==+null)a=true;return(a=select.cursorPos(this.container,a))?{line:a.node,character:a.offset}:{line:null,character:0}},firstLine:function(){return null},lastLine:function(){var a=this.container.lastChild;if(a)a=k(a);if(a&&a.hackBR)a=k(a.previousSibling);return a},nextLine:function(a){this.checkLine(a);a=m(a,this.container);return!a||a.hackBR?false:a},prevLine:function(a){this.checkLine(a);if(a==null)return false;return k(a.previousSibling)},visibleLineCount:function(){for(var a=this.container.firstChild;a&&+isBR(a);)a=a.nextSibling;if(!a)return false;return Math.floor((window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)/a.offsetHeight)},selectLines:function(a,d,g,b){this.checkLine(a);a={node:a,offset:d};d=null;if(b!==undefined){this.checkLine(g);d={node:g,offset:b}}select.setCursorPos(this.container,a,d);select.scrollToCursor(this.container)},lineContent:function(a){var d=[];for(a=a?a.nextSibling:this.container.firstChild;a&&!isBR(a);a=a.nextSibling)d.push(nodeText(a));+return cleanText(d.join(""))},setLineContent:function(a,d){this.history.commit();this.replaceRange({node:a,offset:0},{node:a,offset:this.history.textAfter(a).length},d);this.addDirtyNode(a);this.scheduleHighlight()},removeLine:function(a){for(var d=a?a.nextSibling:this.container.firstChild;d;){var g=d.nextSibling;removeElement(d);if(isBR(d))break;d=g}this.addDirtyNode(a);this.scheduleHighlight()},insertIntoLine:function(a,d,g){var b=null;if(d=="end")b=m(a,this.container);else for(var c=a?a.nextSibling:+this.container.firstChild;c;c=c.nextSibling){if(d==0){b=c;break}var e=nodeText(c);if(e.length>d){b=c.nextSibling;g=e.slice(0,d)+g+e.slice(d);removeElement(c);break}d-=e.length}d=asEditorLines(g);for(g=0;g<d.length;g++){g>0&&this.container.insertBefore(document.createElement("BR"),b);this.container.insertBefore(makePartSpan(d[g]),b)}this.addDirtyNode(a);this.scheduleHighlight()},selectedText:function(){var a=this.history;a.commit();var d=select.cursorPos(this.container,true),g=select.cursorPos(this.container,+false);if(!d||!g)return"";if(d.node==g.node)return a.textAfter(d.node).slice(d.offset,g.offset);var b=[a.textAfter(d.node).slice(d.offset)];for(d=a.nodeAfter(d.node);d!=g.node;d=a.nodeAfter(d))b.push(a.textAfter(d));b.push(a.textAfter(g.node).slice(0,g.offset));return cleanText(b.join("\n"))},replaceSelection:function(a){this.history.commit();var d=select.cursorPos(this.container,true),g=select.cursorPos(this.container,false);if(d&&g){g=this.replaceRange(d,g,a);select.setCursorPos(this.container,+g);webkitLastLineHack(this.container)}},cursorCoords:function(a,d){function g(i,n){var r=-(document.body.scrollTop||document.documentElement.scrollTop||0),t=-(document.body.scrollLeft||document.documentElement.scrollLeft||0)+n;forEach([i,d?null:window.frameElement],function(o){for(;o;){t+=o.offsetLeft;r+=o.offsetTop;o=o.offsetParent}});return{x:t,y:r,yBot:r+i.offsetHeight}}function b(i,n){var r=document.createElement("SPAN");r.appendChild(document.createTextNode(i));try{return n(r)}finally{r.parentNode&&+r.parentNode.removeChild(r)}}var c=select.cursorPos(this.container,a);if(!c)return null;for(var e=c.offset,h=c.node,j=this;e;){h=h?h.nextSibling:this.container.firstChild;c=nodeText(h);if(e<c.length)return b(c.substr(0,e),function(i){i.style.position="absolute";i.style.visibility="hidden";i.className=h.className;j.container.appendChild(i);return g(h,i.offsetWidth)});e-=c.length}return h&&isSpan(h)?g(h,h.offsetWidth):h&&h.nextSibling&&isSpan(h.nextSibling)?g(h.nextSibling,0):b("\u200b",function(i){h?+h.parentNode.insertBefore(i,h.nextSibling):j.container.insertBefore(i,j.container.firstChild);return g(i,0)})},reroutePasteEvent:function(){if(!(this.capturingPaste||window.opera||gecko&&gecko>=20101026)){this.capturingPaste=true;var a=window.frameElement.CodeMirror.textareaHack,d=this.cursorCoords(true,true);a.style.top=d.y+"px";if(internetExplorer)if(d=select.getBookmark(this.container))this.selectionSnapshot=d;parent.focus();a.value="";a.focus();var g=this;parent.setTimeout(function(){g.capturingPaste=+false;window.focus();g.selectionSnapshot&&window.select.setBookmark(g.container,g.selectionSnapshot);var b=a.value;if(b){g.replaceSelection(b);select.scrollToCursor(g.container)}},10)}},replaceRange:function(a,d,g){g=asEditorLines(g);g[0]=this.history.textAfter(a.node).slice(0,a.offset)+g[0];var b=g[g.length-1];g[g.length-1]=b+this.history.textAfter(d.node).slice(d.offset);d=this.history.nodeAfter(d.node);this.history.push(a.node,d,g);return{node:this.history.nodeBefore(d),offset:b.length}},getSearchCursor:function(a,+d,g){return new q(this,a,d,g)},reindent:function(){this.container.firstChild&&this.indentRegion(null,this.container.lastChild)},reindentSelection:function(a){if(select.somethingSelected()){var d=select.selectionTopNode(this.container,true),g=select.selectionTopNode(this.container,false);d===false||g===false||this.indentRegion(d,g,a)}else this.indentAtCursor(a)},grabKeys:function(a,d){this.frozen=a;this.keyFilter=d},ungrabKeys:function(){this.frozen="leave"},setParser:function(a,d){p.Parser=window[a];+(d=d||this.options.parserConfig)&&p.Parser.configure&&p.Parser.configure(d);if(this.container.firstChild){forEach(this.container.childNodes,function(g){if(g.nodeType!=3)g.dirty=true});this.addDirtyNode(this.firstChild);this.scheduleHighlight()}},keyDown:function(a){if(this.frozen=="leave")this.keyFilter=this.frozen=null;if(this.frozen&&(!this.keyFilter||this.keyFilter(a.keyCode,a))){a.stop();this.frozen(a)}else{var d=a.keyCode;this.delayScanning();this.options.autoMatchParens&&this.scheduleParenHighlight();+if(d==13){if(a.ctrlKey&&!a.altKey)this.reparseBuffer();else{select.insertNewlineAtCursor();d=this.options.enterMode;if(d!="flat")this.indentAtCursor(d=="keep"?"keep":undefined);select.scrollToCursor(this.container)}a.stop()}else if(d==9&&this.options.tabMode!="default"&&!a.ctrlKey){this.handleTab(!a.shiftKey);a.stop()}else if(d==32&&a.shiftKey&&this.options.tabMode=="default"){this.handleTab(true);a.stop()}else if(d==36&&!a.shiftKey&&!a.ctrlKey)this.home()&&a.stop();else if(d==35&&!a.shiftKey&&!a.ctrlKey)this.end()&&+a.stop();else if(d==33&&!a.shiftKey&&!a.ctrlKey&&!gecko)this.pageUp()&&a.stop();else if(d==34&&!a.shiftKey&&!a.ctrlKey&&!gecko)this.pageDown()&&a.stop();else if((d==219||d==221)&&a.ctrlKey&&!a.altKey){this.highlightParens(a.shiftKey,true);a.stop()}else if(a.metaKey&&!a.shiftKey&&(d==37||d==39)){var g=select.selectionTopNode(this.container);if(!(g===false||!this.container.firstChild)){if(d==37)select.focusAfterNode(k(g),this.container);else{d=m(g,this.container);select.focusAfterNode(d?d.previousSibling:+this.container.lastChild,this.container)}a.stop()}}else if((a.ctrlKey||a.metaKey)&&!a.altKey)if(a.shiftKey&&d==90||d==89){select.scrollToNode(this.history.redo());a.stop()}else if(d==90||safari&&d==8){select.scrollToNode(this.history.undo());a.stop()}else if(d==83&&this.options.saveFunction){this.options.saveFunction();a.stop()}else d==86&&!mac&&this.reroutePasteEvent()}},keyPress:function(a){var d=this.options.electricChars&&p.Parser.electricChars,g=this;if(this.frozen&&(!this.keyFilter||this.keyFilter(a.keyCode||+a.code,a))||a.code==13||a.code==9&&this.options.tabMode!="default"||a.code==32&&a.shiftKey&&this.options.tabMode=="default")a.stop();else if(mac&&(a.ctrlKey||a.metaKey)&&a.character=="v")this.reroutePasteEvent();else if(d&&d.indexOf(a.character)!=-1)parent.setTimeout(function(){g.indentAtCursor(null)},0);else if(brokenOpera)if(a.code==8){var b=select.selectionTopNode(this.container);g=this;var c=b?b.nextSibling:this.container.firstChild;b!==false&&c&&isBR(c)&&parent.setTimeout(function(){select.selectionTopNode(g.container)==+c&&select.focusAfterNode(c.previousSibling,g.container)},20)}else{if(a.code==46){b=select.selectionTopNode(this.container);g=this;b&&isBR(b)&&parent.setTimeout(function(){select.selectionTopNode(g.container)!=b&&select.focusAfterNode(b,g.container)},20)}}else if(slowWebkit){c=(b=select.selectionTopNode(this.container))?b.nextSibling:this.container.firstChild;if(b&&c&&isBR(c)&&!isBR(b)){var e=document.createTextNode("\u200b");this.container.insertBefore(e,c);parent.setTimeout(function(){if(e.nodeValue==+"\u200b")removeElement(e);else e.nodeValue=e.nodeValue.replace("\u200b","")},20)}}webkit&&!this.options.textWrapping&&setTimeout(function(){var h=select.selectionTopNode(g.container,true);h&&h.nodeType==3&&h.previousSibling&&isBR(h.previousSibling)&&h.nextSibling&&isBR(h.nextSibling)&&h.parentNode.replaceChild(document.createElement("BR"),h.previousSibling)},50)},keyUp:function(a){this.cursorActivity(a.keyCode>=16&&a.keyCode<=18||a.keyCode>=33&&a.keyCode<=40)},indentLineAfter:function(a,d){function g(n){n=+n?n.nextSibling:b.container.firstChild;if(!n||!hasClass(n,"whitespace"))return null;return n}var b=this,c=g(a),e=0,h=c?c.currentText.length:0,j=c?c.nextSibling:a?a.nextSibling:this.container.firstChild;if(d=="keep"){if(a){var i=g(k(a.previousSibling));if(i)e=i.currentText.length}}else{i=a&&j&&j.currentText?j.currentText:"";if(d!=null&&this.options.tabMode!="indent")e=d?h+indentUnit:Math.max(0,h-indentUnit);else if(a)e=a.indentation(i,h,d,j);else if(p.Parser.firstIndentation)e=p.Parser.firstIndentation(i,+h,d,j)}h=e-h;if(h<0)if(e==0){if(j)select.snapshotMove(c.firstChild,j.firstChild||j,0);removeElement(c);c=null}else{select.snapshotMove(c.firstChild,c.firstChild,h,true);c.currentText=makeWhiteSpace(e);c.firstChild.nodeValue=c.currentText}else if(h>0)if(c){c.currentText=makeWhiteSpace(e);c.firstChild.nodeValue=c.currentText;select.snapshotMove(c.firstChild,c.firstChild,h,true)}else{c=makePartSpan(makeWhiteSpace(e));c.className="whitespace";a?insertAfter(c,a):this.container.insertBefore(c,this.container.firstChild);+select.snapshotMove(j&&(j.firstChild||j),c.firstChild,e,false,true)}else c&&select.snapshotMove(c.firstChild,c.firstChild,e,false);h!=0&&this.addDirtyNode(a)},highlightAtCursor:function(){var a=select.selectionTopNode(this.container,true),d=select.selectionTopNode(this.container,false);if(a===false||d===false)return false;select.markSelection();if(this.highlight(a,m(d,this.container),true,20)===false)return false;select.selectMarked();return true},handleTab:function(a){this.options.tabMode=="spaces"&&+!select.somethingSelected()?select.insertTabAtCursor():this.reindentSelection(a)},home:function(){var a=select.selectionTopNode(this.container,true),d=a;if(a===false||!(!a||a.isPart||isBR(a))||!this.container.firstChild)return false;for(;a&&!isBR(a);)a=a.previousSibling;var g=a?a.nextSibling:this.container.firstChild;g&&g!=d&&g.isPart&&hasClass(g,"whitespace")?select.focusAfterNode(g,this.container):select.focusAfterNode(a,this.container);select.scrollToCursor(this.container);return true},end:function(){var a=+select.selectionTopNode(this.container,true);if(a===false)return false;a=m(a,this.container);if(!a)return false;select.focusAfterNode(a.previousSibling,this.container);select.scrollToCursor(this.container);return true},pageUp:function(){var a=this.cursorPosition().line,d=this.visibleLineCount();if(a===false||d===false)return false;d-=2;for(var g=0;g<d;g++){a=this.prevLine(a);if(a===false)break}if(g==0)return false;select.setCursorPos(this.container,{node:a,offset:0});select.scrollToCursor(this.container);+return true},pageDown:function(){var a=this.cursorPosition().line,d=this.visibleLineCount();if(a===false||d===false)return false;d-=2;for(var g=0;g<d;g++){var b=this.nextLine(a);if(b===false)break;a=b}if(g==0)return false;select.setCursorPos(this.container,{node:a,offset:0});select.scrollToCursor(this.container);return true},scheduleParenHighlight:function(){this.parenEvent&&parent.clearTimeout(this.parenEvent);var a=this;this.parenEvent=parent.setTimeout(function(){a.highlightParens()},300)},highlightParens:function(a,+d){function g(u,x){if(u)if(j)if(j.call)j(u,x);else u.className+=" "+j[x?0:1];else{u.style.fontWeight="bold";u.style.color=x?"#8F8":"#F88"}}function b(u){if(u)if(j&&!j.call)removeClass(removeClass(u,j[0]),j[1]);else if(h.options.unmarkParen)h.options.unmarkParen(u);else{u.style.fontWeight="";u.style.color=""}}function c(u){if(u.currentText)return(u=u.currentText.match(/^[\s\u00a0]*([\(\)\[\]{}])[\s\u00a0]*$/))&&u[1]}function e(){for(var u=[],x,s=true,v=n;v;v=t?v.nextSibling:v.previousSibling)if(v.className==+r&&isSpan(v)&&(x=c(v))){if(/[\(\[\{]/.test(x)==t)u.push(x);else if(u.length){if(u.pop()!=matching[x])s=false}else s=false;if(!u.length)break}else if(v.dirty||!isSpan(v)&&!isBR(v))return{node:v,status:"dirty"};return{node:v,status:v&&s}}var h=this,j=this.options.markParen;if(typeof j=="string")j=[j,j];if(!d&&h.highlighted){b(h.highlighted[0]);b(h.highlighted[1])}if(!(!window||!window.parent||!window.select)){this.parenEvent&&parent.clearTimeout(this.parenEvent);this.parenEvent=null;var i,n=select.selectionTopNode(this.container,+true);if(n&&this.highlightAtCursor())if((n=select.selectionTopNode(this.container,true))&&((i=c(n))||(n=n.nextSibling)&&(i=c(n))))for(var r=n.className,t=/[\(\[\{]/.test(i);;){var o=e();if(o.status=="dirty"){this.highlight(o.node,m(o.node));o.node.dirty=false}else{g(n,o.status);g(o.node,o.status);if(d)parent.setTimeout(function(){b(n);b(o.node)},500);else h.highlighted=[n,o.node];a&&o.node&&select.focusAfterNode(o.node.previousSibling,this.container);break}}}},indentAtCursor:function(a){if(this.container.firstChild)if(this.highlightAtCursor()){var d=+select.selectionTopNode(this.container,false);if(d!==false){select.markSelection();this.indentLineAfter(k(d),a);select.selectMarked()}}},indentRegion:function(a,d,g){var b=a=k(a),c=a&&k(a.previousSibling);isBR(d)||(d=m(d,this.container));this.addDirtyNode(a);do{var e=m(b,this.container);b&&this.highlight(c,e,true);this.indentLineAfter(b,g);c=b;b=e}while(b!=d);select.setCursorPos(this.container,{node:a,offset:0},{node:d,offset:0})},cursorActivity:function(a){if(this.unloaded){window.document.designMode=+"off";window.document.designMode="on";this.unloaded=false}if(internetExplorer){this.container.createTextRange().execCommand("unlink");clearTimeout(this.saveSelectionSnapshot);var d=this;this.saveSelectionSnapshot=setTimeout(function(){var c=select.getBookmark(d.container);if(c)d.selectionSnapshot=c},200)}var g=this.options.onCursorActivity;if(!a||g){var b=select.selectionTopNode(this.container,false);if(!(b===false||!this.container.firstChild)){b=b||this.container.firstChild;g&&g(b);if(!a){this.scheduleHighlight();+this.addDirtyNode(b)}}}},reparseBuffer:function(){forEach(this.container.childNodes,function(a){a.dirty=true});this.container.firstChild&&this.addDirtyNode(this.container.firstChild)},addDirtyNode:function(a){if(a=a||this.container.firstChild){for(var d=0;d<this.dirty.length;d++)if(this.dirty[d]==a)return;if(a.nodeType!=3)a.dirty=true;this.dirty.push(a)}},allClean:function(){return!this.dirty.length},scheduleHighlight:function(){var a=this;parent.clearTimeout(this.highlightTimeout);this.highlightTimeout=+parent.setTimeout(function(){a.highlightDirty()},this.options.passDelay)},getDirtyNode:function(){for(;this.dirty.length>0;){var a=this.dirty.pop();try{for(;a&&a.parentNode!=this.container;)a=a.parentNode;if(a&&(a.dirty||a.nodeType==3))return a}catch(d){}}return null},highlightDirty:function(a){if(!window||!window.parent||!window.select)return false;this.options.readOnly||select.markSelection();for(var d,g=a?null:(new Date).getTime()+this.options.passTime;((new Date).getTime()<g||a)&&(d=this.getDirtyNode());){var b=+this.highlight(d,g);b&&b.node&&b.dirty&&this.addDirtyNode(b.node.nextSibling)}this.options.readOnly||select.selectMarked();d&&this.scheduleHighlight();return this.dirty.length==0},documentScanner:function(a){var d=this,g=null;return function(){if(!(!window||!window.parent||!window.select)){if(g&&g.parentNode!=d.container)g=null;select.markSelection();var b=d.highlight(g,(new Date).getTime()+a,true);select.selectMarked();b=b?b.node&&b.node.nextSibling:null;g=g==b?null:b;d.delayScanning()}}},delayScanning:function(){if(this.scanner){parent.clearTimeout(this.documentScan);+this.documentScan=parent.setTimeout(this.scanner,this.options.continuousScanning)}},highlight:function(a,d,g,b){function c(s){if(s){var v=s.oldNextSibling;if(o||v===undefined||s.nextSibling!=v)h.history.touch(s);s.oldNextSibling=s.nextSibling}else{v=h.container.oldFirstChild;if(o||v===undefined||h.container.firstChild!=v)h.history.touch(null);h.container.oldFirstChild=h.container.firstChild}}var e=this.container,h=this,j=this.options.activeTokens,i=typeof d=="number"?d:null;if(!e.firstChild)return false;+for(;a&&(!a.parserFromHere||a.dirty);){if(b!=null&&isBR(a)&&--b<0)return false;a=a.previousSibling}if(a&&!a.nextSibling)return false;var n=l(a?a.nextSibling:e.firstChild);b=stringStream(n);var r=a?a.parserFromHere(b):p.Parser.make(b),t={current:null,get:function(){if(!this.current)this.current=n.nodes.shift();return this.current},next:function(){this.current=null},remove:function(){e.removeChild(this.get());this.current=null},getNonEmpty:function(){for(var s=this.get();s&&isSpan(s)&&s.currentText==+"";)if(window.opera&&(s.previousSibling==null||isBR(s.previousSibling))&&(s.nextSibling==null||isBR(s.nextSibling))){this.next();s=this.get()}else{var v=s;this.remove();s=this.get();select.snapshotMove(v.firstChild,s&&(s.firstChild||s),0)}return s}},o=false,u=true,x=0;forEach(r,function(s){var v=t.getNonEmpty();if(s.value=="\n"){if(!isBR(v))throw"Parser out of sync. Expected BR.";if(v.dirty||!v.indentation)o=true;c(a);a=v;v.parserFromHere=r.copy();v.indentation=s.indentation||alwaysZero;v.dirty=false;+if(i==null&&v==d)throw StopIteration;if(i!=null&&(new Date).getTime()>=i||!o&&!u&&x>1&&!g)throw StopIteration;u=o;o=false;x=0;t.next()}else{if(!isSpan(v))throw"Parser out of sync. Expected SPAN.";if(v.dirty)o=true;x++;if(!v.reduced&&v.currentText==s.value&&v.className==s.style){j&&v.dirty&&j(v,s,h);v.dirty=false;t.next()}else{o=true;var y=makePartSpan(s.value);y.className=s.style;e.insertBefore(y,v);j&&j(y,s,h);s=s.value.length;for(var A=0;s>0;){v=t.get();var z=v.currentText.length;select.snapshotReplaceNode(v.firstChild,+y.firstChild,s,A);if(z>s){v=v;v.currentText=v.currentText.substring(s);v.reduced=true;s=0}else{s-=z;A+=z;t.remove()}}}}});c(a);webkitLastLineHack(this.container);return{node:t.getNonEmpty(),dirty:o}}};return p}();addEventHandler(window,"load",function(){var f=window.frameElement.CodeMirror;f.editor=new Editor(f.options);parent.setTimeout(method(f,"init"),0)});function tokenizer(f,l){function k(q){return q!="\n"&&/^[\s\u00a0]*$/.test(q)}var m={state:l,take:function(q){if(typeof q=="string")q={style:q,type:q};q.content=(q.content||"")+f.get();/\n$/.test(q.content)||f.nextWhile(k);q.value=q.content+f.get();return q},next:function(){if(!f.more())throw StopIteration;var q;if(f.equals("\n")){f.next();return this.take("whitespace")}if(f.applies(k))q="whitespace";else for(;!q;)q=this.state(f,function(p){m.state=p});return this.take(q)}};return m};
+ seed/static/codemirror_min.js view
@@ -0,0 +1,23 @@+var CodeMirrorConfig=window.CodeMirrorConfig||{},CodeMirror=function(){function D(a,b){for(var c in b)a.hasOwnProperty(c)||(a[c]=b[c])}function E(a,b){for(var c=0;c<a.length;c++)b(a[c])}function s(a){return document.createElementNS&&document.documentElement.namespaceURI!==null?document.createElementNS("http://www.w3.org/1999/xhtml",a):document.createElement(a)}function F(a,b){var c=s("div"),e=s("div");c.style.position="absolute";c.style.height="100%";if(c.style.setExpression)try{c.style.setExpression("height",+"this.previousSibling.offsetHeight + 'px'")}catch(f){}c.style.top="0px";c.style.left="0px";c.style.overflow="hidden";a.appendChild(c);e.className="CodeMirror-line-numbers";c.appendChild(e);e.innerHTML="<div>"+b+"</div>";return c}function G(a){if(typeof a.parserfile=="string")a.parserfile=[a.parserfile];if(typeof a.basefiles=="string")a.basefiles=[a.basefiles];if(typeof a.stylesheet=="string")a.stylesheet=[a.stylesheet];var b=' spellcheck="'+(a.disableSpellcheck?"false":"true")+'"',c=['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html'++b+"><head>"];c.push('<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>');var e=a.noScriptCaching?"?nocache="+(new Date).getTime().toString(16):"";E(a.stylesheet,function(f){c.push('<link rel="stylesheet" type="text/css" href="'+f+e+'"/>')});E(a.basefiles.concat(a.parserfile),function(f){/^https?:/.test(f)||(f=a.path+f);c.push('<script type="text/javascript" src="'+f+e+'"><\/script>')});c.push('</head><body style="border-width: 0;" class="editbox"'+b+"></body></html>");return c.join("")}+function t(a,b){this.options=b=b||{};D(b,CodeMirrorConfig);if(b.dumbTabs)b.tabMode="spaces";else if(b.normalTab)b.tabMode="default";if(b.cursorActivity)b.onCursorActivity=b.cursorActivity;var c=this.frame=s("iframe");if(b.iframeClass)c.className=b.iframeClass;c.frameBorder=0;c.style.border="0";c.style.width="100%";c.style.height="100%";c.style.display="block";var e=this.wrapping=s("div");e.style.position="relative";e.className="CodeMirror-wrapping";e.style.width=b.width;e.style.height=b.height=="dynamic"?+b.minHeight+"px":b.height;var f=this.textareaHack=s("textarea");e.appendChild(f);f.style.position="absolute";f.style.left="-10000px";f.style.width="10px";f.tabIndex=1E5;c.CodeMirror=this;if(b.domain&&H){this.html=G(b);c.src="javascript:(function(){document.open();"+(b.domain?'document.domain="'+b.domain+'";':"")+"document.write(window.frameElement.CodeMirror.html);document.close();})()"}else c.src="javascript:;";a.appendChild?a.appendChild(e):a(e);e.appendChild(c);if(b.lineNumbers)this.lineNumbers=+F(e,b.firstLineNumber);this.win=c.contentWindow;if(!b.domain||!H){this.win.document.open();this.win.document.write(G(b));this.win.document.close()}}D(CodeMirrorConfig,{stylesheet:[],path:"",parserfile:[],basefiles:["util.js","stringstream.js","select.js","undo.js","editor.js","tokenize.js"],iframeClass:null,passDelay:200,passTime:50,lineNumberDelay:200,lineNumberTime:50,continuousScanning:false,saveFunction:null,onLoad:null,onChange:null,undoDepth:50,undoDelay:800,disableSpellcheck:true,textWrapping:true,+readOnly:false,width:"",height:"300px",minHeight:100,autoMatchParens:false,markParen:null,unmarkParen:null,parserConfig:null,tabMode:"indent",enterMode:"indent",electricChars:true,reindentOnLoad:false,activeTokens:null,onCursorActivity:null,lineNumbers:false,firstLineNumber:1,onLineNumberClick:null,indentUnit:2,domain:null,noScriptCaching:false,incrementalLoading:false});var H=document.selection&&window.ActiveXObject&&/MSIE/.test(navigator.userAgent);t.prototype={init:function(){this.options.initCallback&&+this.options.initCallback(this);this.options.onLoad&&this.options.onLoad(this);this.options.lineNumbers&&this.activateLineNumbers();this.options.reindentOnLoad&&this.reindent();this.options.height=="dynamic"&&this.setDynamicHeight()},getCode:function(){return this.editor.getCode()},setCode:function(a){this.editor.importCode(a)},selection:function(){this.focusIfIE();return this.editor.selectedText()},reindent:function(){this.editor.reindent()},reindentSelection:function(){this.focusIfIE();this.editor.reindentSelection(null)},+focusIfIE:function(){this.win.select.ie_selection&&document.activeElement!=this.frame&&this.focus()},focus:function(){this.win.focus();this.editor.selectionSnapshot&&this.win.select.setBookmark(this.win.document.body,this.editor.selectionSnapshot)},replaceSelection:function(a){this.focus();this.editor.replaceSelection(a);return true},replaceChars:function(a,b,c){this.editor.replaceChars(a,b,c)},getSearchCursor:function(a,b,c){return this.editor.getSearchCursor(a,b,c)},undo:function(){this.editor.history.undo()},+redo:function(){this.editor.history.redo()},historySize:function(){return this.editor.history.historySize()},clearHistory:function(){this.editor.history.clear()},grabKeys:function(a,b){this.editor.grabKeys(a,b)},ungrabKeys:function(){this.editor.ungrabKeys()},setParser:function(a,b){this.editor.setParser(a,b)},setSpellcheck:function(a){this.win.document.body.spellcheck=a},setStylesheet:function(a){if(typeof a==="string")a=[a];for(var b={},c={},e=this.win.document.getElementsByTagName("link"),f=0,+d;d=e[f];f++)if(d.rel.indexOf("stylesheet")!==-1)for(var g=0;g<a.length;g++){var n=a[g];if(d.href.substring(d.href.length-n.length)===n){b[d.href]=true;c[n]=true}}for(f=0;d=e[f];f++)if(d.rel.indexOf("stylesheet")!==-1)d.disabled=!(d.href in b);for(g=0;g<a.length;g++){n=a[g];if(!(n in c)){d=this.win.document.createElement("link");d.rel="stylesheet";d.type="text/css";d.href=n;this.win.document.getElementsByTagName("head")[0].appendChild(d)}}},setTextWrapping:function(a){if(a!=this.options.textWrapping){this.win.document.body.style.whiteSpace=+a?"":"nowrap";this.options.textWrapping=a;if(this.lineNumbers){this.setLineNumbers(false);this.setLineNumbers(true)}}},setIndentUnit:function(a){this.win.indentUnit=a},setUndoDepth:function(a){this.editor.history.maxDepth=a},setTabMode:function(a){this.options.tabMode=a},setEnterMode:function(a){this.options.enterMode=a},setLineNumbers:function(a){if(a&&!this.lineNumbers){this.lineNumbers=F(this.wrapping,this.options.firstLineNumber);this.activateLineNumbers()}else if(!a&&this.lineNumbers){this.wrapping.removeChild(this.lineNumbers);+this.wrapping.style.paddingLeft="";this.lineNumbers=null}},cursorPosition:function(a){this.focusIfIE();return this.editor.cursorPosition(a)},firstLine:function(){return this.editor.firstLine()},lastLine:function(){return this.editor.lastLine()},nextLine:function(a){return this.editor.nextLine(a)},prevLine:function(a){return this.editor.prevLine(a)},lineContent:function(a){return this.editor.lineContent(a)},setLineContent:function(a,b){this.editor.setLineContent(a,b)},removeLine:function(a){this.editor.removeLine(a)},+insertIntoLine:function(a,b,c){this.editor.insertIntoLine(a,b,c)},selectLines:function(a,b,c,e){this.win.focus();this.editor.selectLines(a,b,c,e)},nthLine:function(a){for(var b=this.firstLine();a>1&&b!==false;a--)b=this.nextLine(b);return b},lineNumber:function(a){for(var b=0;a!==false;){b++;a=this.prevLine(a)}return b},jumpToLine:function(a){if(typeof a=="number")a=this.nthLine(a);this.selectLines(a,0);this.win.focus()},currentLine:function(){return this.lineNumber(this.cursorLine())},cursorLine:function(){return this.cursorPosition().line},+cursorCoords:function(a){return this.editor.cursorCoords(a)},activateLineNumbers:function(){function a(){if(d.offsetWidth!=0){for(var h=d;h.parentNode;h=h.parentNode);if(!i.parentNode||h!=document||!g.Editor){try{z()}catch(k){}clearInterval(J)}else if(i.offsetWidth!=A){A=i.offsetWidth;d.parentNode.style.paddingLeft=A+"px"}}}function b(){i.scrollTop=q.scrollTop||n.documentElement.scrollTop||0}function c(h){var k=l.firstChild.offsetHeight;if(k!=0){k=Math.ceil((50+Math.max(q.offsetHeight,Math.max(d.offsetHeight,+q.scrollHeight||0)))/k);for(var o=l.childNodes.length;o<=k;o++){var w=s("div");w.appendChild(document.createTextNode(h?String(o+j.options.firstLineNumber):"\u00a0"));l.appendChild(w)}}}function e(){function h(){c(true);b()}j.updateNumbers=h;var k=g.addEventHandler(g,"scroll",b,true),o=g.addEventHandler(g,"resize",h,true);z=function(){k();o();if(j.updateNumbers==h)j.updateNumbers=null};h()}function f(){function h(p,B){r||(r=l.appendChild(s("div")));I&&I(r,B,p);u.push(r);u.push(p);x=r.offsetHeight++r.offsetTop;r=r.nextSibling}function k(){for(var p=0;p<u.length;p+=2)u[p].innerHTML=u[p+1];u=[]}function o(){if(!(!l.parentNode||l.parentNode!=j.lineNumbers)){for(var p=(new Date).getTime()+j.options.lineNumberTime;m;){for(h(C++,m.previousSibling);m&&!g.isBR(m);m=m.nextSibling)for(var B=m.offsetTop+m.offsetHeight;l.offsetHeight&&B-3>x;){var K=x;h("&nbsp;");if(x<=K)break}if(m)m=m.nextSibling;if((new Date).getTime()>p){k();v=setTimeout(o,j.options.lineNumberDelay);return}}for(;r;)h(C++);k();b()}}function w(p){b();+c(p);m=q.firstChild;r=l.firstChild;x=0;C=j.options.firstLineNumber;o()}function y(){v&&clearTimeout(v);if(j.editor.allClean())w();else v=setTimeout(y,200)}var m,r,C,x,u=[],I=j.options.styleNumbers;w(true);var v=null;j.updateNumbers=y;var L=g.addEventHandler(g,"scroll",b,true),M=g.addEventHandler(g,"resize",y,true);z=function(){v&&clearTimeout(v);if(j.updateNumbers==y)j.updateNumbers=null;L();M()}}var d=this.frame,g=d.contentWindow,n=g.document,q=n.body,i=this.lineNumbers,l=i.firstChild,j=this,A=null;+i.onclick=function(h){var k=j.options.onLineNumberClick;if(k){h=(h||window.event).target||(h||window.event).srcElement;var o=h==i?NaN:Number(h.innerHTML);isNaN(o)||k(o,h)}};var z=function(){};a();var J=setInterval(a,500);(this.options.textWrapping||this.options.styleNumbers?f:e)()},setDynamicHeight:function(){function a(){for(var q=0,i=f.lastChild,l;i&&e.isBR(i);){i.hackBR||q++;i=i.previousSibling}if(i){d=i.offsetHeight;l=i.offsetTop+(1+q)*d}else if(d)l=q*d;if(l)b.wrapping.style.height=Math.max(n++l,b.options.minHeight)+"px"}var b=this,c=b.options.onCursorActivity,e=b.win,f=e.document.body,d=null,g=null,n=2*b.frame.offsetTop;f.style.overflowY="hidden";e.document.documentElement.style.overflowY="hidden";this.frame.scrolling="no";setTimeout(a,300);b.options.onCursorActivity=function(q){c&&c(q);clearTimeout(g);g=setTimeout(a,100)}}};t.InvalidLineHandle={toString:function(){return"CodeMirror.InvalidLineHandle"}};t.replace=function(a){if(typeof a=="string")a=document.getElementById(a);return function(b){a.parentNode.replaceChild(b,+a)}};t.fromTextArea=function(a,b){function c(){a.value=d.getCode()}if(typeof a=="string")a=document.getElementById(a);b=b||{};if(a.style.width&&b.width==null)b.width=a.style.width;if(a.style.height&&b.height==null)b.height=a.style.height;if(b.content==null)b.content=a.value;if(a.form){typeof a.form.addEventListener=="function"?a.form.addEventListener("submit",c,false):a.form.attachEvent("onsubmit",c);var e=a.form.submit,f=function(){c();a.form.submit=e;a.form.submit();a.form.submit=f};a.form.submit=+f}a.style.display="none";var d=new t(function(g){a.nextSibling?a.parentNode.insertBefore(g,a.nextSibling):a.parentNode.appendChild(g)},b);d.save=c;d.toTextArea=function(){c();a.parentNode.removeChild(d.wrapping);a.style.display="";if(a.form){a.form.submit=e;typeof a.form.removeEventListener=="function"?a.form.removeEventListener("submit",c,false):a.form.detachEvent("onsubmit",c)}};return d};t.isProbablySupported=function(){var a;return window.opera?Number(window.opera.version())>=9.52:/Apple Computer, Inc/.test(navigator.vendor)&&+(a=navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./))?Number(a[1])>=3:document.selection&&window.ActiveXObject&&(a=navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/))?Number(a[1])>=6:(a=navigator.userAgent.match(/gecko\/(\d{8})/i))?Number(a[1])>=20050901:(a=navigator.userAgent.match(/AppleWebKit\/(\d+)/))?Number(a[1])>=525:null};return t}();
+ seed/static/codemirror_parse_dummy_min.js view
@@ -0,0 +1,1 @@+var DummyParser=Editor.Parser=function(){function d(b){for(;!b.endOfLine();)b.next();return"text"}return{make:function(b){function f(a){return function(){return a}}b=tokenizer(b,d);var c=0,e={next:function(){var a=b.next();if(a.type=="whitespace")if(a.value=="\n")a.indentation=f(c);else c=a.value.length;return a},copy:function(){var a=c;return function(g){c=a;b=tokenizer(g,d);return e}}};return e}}}();
+ seed/static/codemirror_parse_haskell.js view
@@ -0,0 +1,279 @@+var HaskellParser = Editor.Parser = (function() {+  var tokenizeHaskell = (function() {+  +    // These should all be Unicode extended, as per the Haskell 2010 report+    var smallRE = /[a-z_]/;+    var largeRE = /[A-Z]/;+    var digitRE = /[0-9]/;+    var hexitRE = /[0-9A-Fa-f]/;+    var octitRE = /[0-7]/;+    var idRE = /[a-z_A-Z0-9']/;+    var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/;+    var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer+    +    +    function nextIfLiteralChar(delimiter) {+      if (source.endOfLine()) return false;+      if (source.equals(delimiter)) return false;+      if (source.equals('\\')) {+        source.next();+        source.next();+      }+      else {+        source.next();+      }+      return true+    }++    function normal(source, setState) {+      var ch = source.next();+      +      if (/[(),;[\]`{}]/.test(ch)) {+        if (ch == '{' && source.equals('-')) {+          source.next();+          var t = "hs-comment";+          if (source.equals('#')) {+            source.next();+            t = "hs-pragma";+          }+          setState(ncomment(t, 1));+          return null;+        }+        return "hs-special";+      }+      +      if (ch == '\'') {+        if (source.next == '\\') {+          source.next();  // should do more here+          if (source.equals('\'')) {+            source.next();+            return "hs-char";+          }+        }+        return "hs-error";+      }+      +      if (ch == '"') {+        setState(stringLiteral);+        return null;+      }+      +      if (largeRE.test(ch)) {+        source.nextWhileMatches(idRE);+        if (source.equals('.')) {+          source.next();+          return "hs-qualifier";+        }+        return "hs-conid";+      }+      +      if (smallRE.test(ch)) {+        source.nextWhileMatches(idRE);+        return "hs-varid";+      }+      +      if (digitRE.test(ch)) {+        if (ch == '0') {+          if (source.matches(/[xX]/)) {+            source.next();+            source.nextWhileMatches(hexitRE); // should require at least 1+            return "hs-integer";+          }+          if (source.matches(/[oO]/)) {+            source.next();+            source.nextWhileMatches(octitRE); // should require at least 1+            return "hs-integer";+          }+        }+        source.nextWhileMatches(digitRE);+        var t = "hs-integer";+        if (source.equals('.')) {+          t = "hs-float";+          source.next();+          source.nextWhileMatches(digitRE); // should require at least 1+        }+        if (source.matches(/[eE]/)) {+          t = "hs-float";+          source.next();+          if (source.matches(/[-+]/)) {+            source.next();+          }+          source.nextWhileMatches(digitRE); // should require at least 1+        }+        return t;+      }+      +      if (symbolRE.test(ch)) {+        if (ch == '-' && source.matches(/-/)) {+          source.nextWhileMatches(/-/);+          if (!source.matches(symbolRE)) {+            while (!source.endOfLine()) {+              source.next();+            }+            return "hs-comment";+          }+        }+        var t = "hs-varsym";+        if (ch == ':') {+          t = "hs-consym";+        }+        source.nextWhileMatches(symbolRE);+        return t;    +      }+      +      return "hs-error";+    }+    +    function ncomment(type, nest) {+      if (nest == 0) {+        return normal;+      }+      return function(source, setState) {+        while (source.more() && !source.endOfLine()) {+          ch = source.next();+          if (ch == '{' && source.equals('-')) {+            source.next();+            setState(ncomment(type, nest+1));+            return null;+          }+          else if (ch == '-' && source.equals('}')) {+            source.next();+            setState(ncomment(type, nest-1));+            return (nest == 1) ? type : null;+          }+        }+        return type;+      }+    }+    +    function stringLiteral(source, setState) {+      while (!source.endOfLine()) {+        var ch = source.next();+        if (ch == '"') {+          setState(normal);+          return "hs-string";+        }+        if (ch == '\\') {+          if (source.endOfLine() || source.matches(whiteCharRE)) {+            setState(stringGap);+            return "hs-string";+          }+          if (source.equals('&')) {+            source.next();+          }+          else {+            source.next(); // could do more complicated matching here+          }+        }+      }+      setState(normal);+      return "hs-error";+    }+    +    function stringGap(source, setState) {+      if (source.equals('\\')) {+        source.next();+        setState(stringLiteral);+        return null; //"hs-gap";+      }+      source.next();+      setState(normal);+      return "hs-error";+    }+    +    return function(source, state) {+      return tokenizer(source, state || normal);+    };+  })(); +  +  var wellKnownWords = (function() {+    var wkw = {};+    function setType(t) {+      return function () {+        for (var i = 0; i < arguments.length; i++)+          wkw[arguments[i]] = t;+      }+    }+    +    setType("hs-reservedid")(+      "case", "class", "data", "default", "deriving", "do", "else", "foreign",+      "if", "import", "in", "infix", "infixl", "infixr", "instance", "let",+      "module", "newtype", "of", "then", "type", "where", "_");+      +    setType("hs-reservedop")(+      "\.\.", ":", "::", "=", "\\", "\"", "<-", "->", "@", "~", "=>");+      +    setType("hs-prelude-varsym")(+      "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<",+      "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*", "**");+      +    setType("hs-prelude-conid")(+      "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq",+      "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT",+      "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left",+      "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read",+      "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS",+      "String", "True");+      +    setType("hs-prelude-varid")(+      "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf",+      "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling",+      "compare", "concat", "concatMap", "const", "cos", "cosh", "curry",+      "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either",+      "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",+      "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter",+      "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap",+      "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger",+      "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents",+      "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized",+      "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last",+      "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map",+      "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound",+      "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or",+      "otherwise", "pi", "pred", "print", "product", "properFraction",+      "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile",+      "readIO", "readList", "readLn", "readParen", "reads", "readsPrec",+      "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse",+      "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq",+      "sequence", "sequence_", "show", "showChar", "showList", "showParen",+      "showString", "shows", "showsPrec", "significand", "signum", "sin",+      "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum",+      "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger",+      "toRational", "truncate", "uncurry", "undefined", "unlines", "until",+      "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",+      "zip3", "zipWith", "zipWith3");+      +    return wkw;+  })()+  +  function parseHaskell(source) {+    function indentTo(n) {return function() {return n;}}+    var tokens = tokenizeHaskell(source);+    var space = 0;++    var iter = {+      next: function() {+        var tok = tokens.next();+        if (tok.type == "whitespace") {+          if (tok.value == "\n") tok.indentation = indentTo(space);+          else space = tok.value.length;+        }+        else if (tok.content in wellKnownWords) {+          tok.style = wellKnownWords[tok.content];+        }+        return tok;+      },+      copy: function() {+        var _space = space;+        var _tokensState = tokens.state;+        return function(_source) {+          space = _space;+          tokens = tokenizeHaskell(_source, _tokensState);+          return iter;+        };+      }+    };+    return iter;+  }+  return {make: parseHaskell};+})();
+ seed/static/hslogo-16.png view

binary file changed (absent → 1684 bytes)

+ seed/static/jquery.js view
@@ -0,0 +1,166 @@+/*!+ * jQuery JavaScript Library v1.4.3+ * http://jquery.com/+ *+ * Copyright 2010, John Resig+ * Dual licensed under the MIT or GPL Version 2 licenses.+ * http://jquery.org/license+ *+ * Includes Sizzle.js+ * http://sizzlejs.com/+ * Copyright 2010, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ *+ * Date: Thu Oct 14 23:10:06 2010 -0400+ */+(function(E,A){function U(){return false}function ba(){return true}function ja(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ga(a){var b,d,e=[],f=[],h,k,l,n,s,v,B,D;k=c.data(this,this.nodeType?"events":"__events__");if(typeof k==="function")k=k.events;if(!(a.liveFired===this||!k||!k.live||a.button&&a.type==="click")){if(a.namespace)D=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var H=k.live.slice(0);for(n=0;n<H.length;n++){k=H[n];k.origType.replace(X,+"")===a.type?f.push(k.selector):H.splice(n--,1)}f=c(a.target).closest(f,a.currentTarget);s=0;for(v=f.length;s<v;s++){B=f[s];for(n=0;n<H.length;n++){k=H[n];if(B.selector===k.selector&&(!D||D.test(k.namespace))){l=B.elem;h=null;if(k.preType==="mouseenter"||k.preType==="mouseleave"){a.type=k.preType;h=c(a.relatedTarget).closest(k.selector)[0]}if(!h||h!==l)e.push({elem:l,handleObj:k,level:B.level})}}}s=0;for(v=e.length;s<v;s++){f=e[s];if(d&&f.level>d)break;a.currentTarget=f.elem;a.data=f.handleObj.data;+a.handleObj=f.handleObj;D=f.handleObj.origHandler.apply(f.elem,arguments);if(D===false||a.isPropagationStopped()){d=f.level;if(D===false)b=false}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(Ha,"`").replace(Ia,"&")}function ka(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Ja.test(b))return c.filter(b,+e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function la(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this,e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var k in e[h])c.event.add(this,h,e[h][k],e[h][k].data)}}})}function Ka(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}+function ma(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?La:Ma,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a,"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function ca(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Na.test(a)?e(a,h):ca(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?+e(a,""):c.each(b,function(f,h){ca(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(na.concat.apply([],na.slice(0,b)),function(){d[this]=a});return d}function oa(a){if(!da[a]){var b=c("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";da[a]=d}return da[a]}function ea(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var u=E.document,c=function(){function a(){if(!b.isReady){try{u.documentElement.doScroll("left")}catch(i){setTimeout(a,+1);return}b.ready()}}var b=function(i,r){return new b.fn.init(i,r)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,k=/\S/,l=/^\s+/,n=/\s+$/,s=/\W/,v=/\d/,B=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,D=/^[\],:{}\s]*$/,H=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,G=/(?:^|:|,)(?:\s*\[)+/g,M=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,j=/(msie) ([\w.]+)/,o=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,+q=[],t,x=Object.prototype.toString,C=Object.prototype.hasOwnProperty,P=Array.prototype.push,N=Array.prototype.slice,R=String.prototype.trim,Q=Array.prototype.indexOf,L={};b.fn=b.prototype={init:function(i,r){var y,z,F;if(!i)return this;if(i.nodeType){this.context=this[0]=i;this.length=1;return this}if(i==="body"&&!r&&u.body){this.context=u;this[0]=u.body;this.selector="body";this.length=1;return this}if(typeof i==="string")if((y=h.exec(i))&&(y[1]||!r))if(y[1]){F=r?r.ownerDocument||r:u;if(z=B.exec(i))if(b.isPlainObject(r)){i=+[u.createElement(z[1])];b.fn.attr.call(i,r,true)}else i=[F.createElement(z[1])];else{z=b.buildFragment([y[1]],[F]);i=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this,i)}else{if((z=u.getElementById(y[2]))&&z.parentNode){if(z.id!==y[2])return f.find(i);this.length=1;this[0]=z}this.context=u;this.selector=i;return this}else if(!r&&!s.test(i)){this.selector=i;this.context=u;i=u.getElementsByTagName(i);return b.merge(this,i)}else return!r||r.jquery?(r||f).find(i):b(r).find(i);+else if(b.isFunction(i))return f.ready(i);if(i.selector!==A){this.selector=i.selector;this.context=i.context}return b.makeArray(i,this)},selector:"",jquery:"1.4.3",length:0,size:function(){return this.length},toArray:function(){return N.call(this,0)},get:function(i){return i==null?this.toArray():i<0?this.slice(i)[0]:this[i]},pushStack:function(i,r,y){var z=b();b.isArray(i)?P.apply(z,i):b.merge(z,i);z.prevObject=this;z.context=this.context;if(r==="find")z.selector=this.selector+(this.selector?" ":+"")+y;else if(r)z.selector=this.selector+"."+r+"("+y+")";return z},each:function(i,r){return b.each(this,i,r)},ready:function(i){b.bindReady();if(b.isReady)i.call(u,b);else q&&q.push(i);return this},eq:function(i){return i===-1?this.slice(i):this.slice(i,+i+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(i){return this.pushStack(b.map(this,function(r,y){return i.call(r,+y,r)}))},end:function(){return this.prevObject||b(null)},push:P,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var i=arguments[0]||{},r=1,y=arguments.length,z=false,F,I,K,J,fa;if(typeof i==="boolean"){z=i;i=arguments[1]||{};r=2}if(typeof i!=="object"&&!b.isFunction(i))i={};if(y===r){i=this;--r}for(;r<y;r++)if((F=arguments[r])!=null)for(I in F){K=i[I];J=F[I];if(i!==J)if(z&&J&&(b.isPlainObject(J)||(fa=b.isArray(J)))){if(fa){fa=false;clone=K&&b.isArray(K)?K:[]}else clone=+K&&b.isPlainObject(K)?K:{};i[I]=b.extend(z,clone,J)}else if(J!==A)i[I]=J}return i};b.extend({noConflict:function(i){E.$=e;if(i)E.jQuery=d;return b},isReady:false,readyWait:1,ready:function(i){i===true&&b.readyWait--;if(!b.readyWait||i!==true&&!b.isReady){if(!u.body)return setTimeout(b.ready,1);b.isReady=true;if(!(i!==true&&--b.readyWait>0)){if(q){for(var r=0;i=q[r++];)i.call(u,b);q=null}b.fn.triggerHandler&&b(u).triggerHandler("ready")}}},bindReady:function(){if(!p){p=true;if(u.readyState==="complete")return setTimeout(b.ready,+1);if(u.addEventListener){u.addEventListener("DOMContentLoaded",t,false);E.addEventListener("load",b.ready,false)}else if(u.attachEvent){u.attachEvent("onreadystatechange",t);E.attachEvent("onload",b.ready);var i=false;try{i=E.frameElement==null}catch(r){}u.documentElement.doScroll&&i&&a()}}},isFunction:function(i){return b.type(i)==="function"},isArray:Array.isArray||function(i){return b.type(i)==="array"},isWindow:function(i){return i&&typeof i==="object"&&"setInterval"in i},isNaN:function(i){return i==+null||!v.test(i)||isNaN(i)},type:function(i){return i==null?String(i):L[x.call(i)]||"object"},isPlainObject:function(i){if(!i||b.type(i)!=="object"||i.nodeType||b.isWindow(i))return false;if(i.constructor&&!C.call(i,"constructor")&&!C.call(i.constructor.prototype,"isPrototypeOf"))return false;for(var r in i);return r===A||C.call(i,r)},isEmptyObject:function(i){for(var r in i)return false;return true},error:function(i){throw i;},parseJSON:function(i){if(typeof i!=="string"||!i)return null;i=b.trim(i);+if(D.test(i.replace(H,"@").replace(w,"]").replace(G,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(i):(new Function("return "+i))();else b.error("Invalid JSON: "+i)},noop:function(){},globalEval:function(i){if(i&&k.test(i)){var r=u.getElementsByTagName("head")[0]||u.documentElement,y=u.createElement("script");y.type="text/javascript";if(b.support.scriptEval)y.appendChild(u.createTextNode(i));else y.text=i;r.insertBefore(y,r.firstChild);r.removeChild(y)}},nodeName:function(i,r){return i.nodeName&&i.nodeName.toUpperCase()===+r.toUpperCase()},each:function(i,r,y){var z,F=0,I=i.length,K=I===A||b.isFunction(i);if(y)if(K)for(z in i){if(r.apply(i[z],y)===false)break}else for(;F<I;){if(r.apply(i[F++],y)===false)break}else if(K)for(z in i){if(r.call(i[z],z,i[z])===false)break}else for(y=i[0];F<I&&r.call(y,F,y)!==false;y=i[++F]);return i},trim:R?function(i){return i==null?"":R.call(i)}:function(i){return i==null?"":i.toString().replace(l,"").replace(n,"")},makeArray:function(i,r){var y=r||[];if(i!=null){var z=b.type(i);i.length==+null||z==="string"||z==="function"||z==="regexp"||b.isWindow(i)?P.call(y,i):b.merge(y,i)}return y},inArray:function(i,r){if(r.indexOf)return r.indexOf(i);for(var y=0,z=r.length;y<z;y++)if(r[y]===i)return y;return-1},merge:function(i,r){var y=i.length,z=0;if(typeof r.length==="number")for(var F=r.length;z<F;z++)i[y++]=r[z];else for(;r[z]!==A;)i[y++]=r[z++];i.length=y;return i},grep:function(i,r,y){var z=[],F;y=!!y;for(var I=0,K=i.length;I<K;I++){F=!!r(i[I],I);y!==F&&z.push(i[I])}return z},map:function(i,+r,y){for(var z=[],F,I=0,K=i.length;I<K;I++){F=r(i[I],I,y);if(F!=null)z[z.length]=F}return z.concat.apply([],z)},guid:1,proxy:function(i,r,y){if(arguments.length===2)if(typeof r==="string"){y=i;i=y[r];r=A}else if(r&&!b.isFunction(r)){y=r;r=A}if(!r&&i)r=function(){return i.apply(y||this,arguments)};if(i)r.guid=i.guid=i.guid||r.guid||b.guid++;return r},access:function(i,r,y,z,F,I){var K=i.length;if(typeof r==="object"){for(var J in r)b.access(i,J,r[J],z,F,y);return i}if(y!==A){z=!I&&z&&b.isFunction(y);+for(J=0;J<K;J++)F(i[J],r,z?y.call(i[J],J,F(i[J],r)):y,I);return i}return K?F(i[0],r):A},now:function(){return(new Date).getTime()},uaMatch:function(i){i=i.toLowerCase();i=M.exec(i)||g.exec(i)||j.exec(i)||i.indexOf("compatible")<0&&o.exec(i)||[];return{browser:i[1]||"",version:i[2]||"0"}},browser:{}});b.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(i,r){L["[object "+r+"]"]=r.toLowerCase()});m=b.uaMatch(m);if(m.browser){b.browser[m.browser]=true;b.browser.version=+m.version}if(b.browser.webkit)b.browser.safari=true;if(Q)b.inArray=function(i,r){return Q.call(r,i)};if(!/\s/.test("\u00a0")){l=/^[\s\xA0]+/;n=/[\s\xA0]+$/}f=b(u);if(u.addEventListener)t=function(){u.removeEventListener("DOMContentLoaded",t,false);b.ready()};else if(u.attachEvent)t=function(){if(u.readyState==="complete"){u.detachEvent("onreadystatechange",t);b.ready()}};return E.jQuery=E.$=b}();(function(){c.support={};var a=u.documentElement,b=u.createElement("script"),d=u.createElement("div"),+e="script"+c.now();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],k=u.createElement("select"),l=k.appendChild(u.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),+hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:l.selected,optDisabled:false,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};k.disabled=true;c.support.optDisabled=!l.disabled;b.type="text/javascript";try{b.appendChild(u.createTextNode("window."+e+"=1;"))}catch(n){}a.insertBefore(b,+a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function s(){c.support.noCloneEvent=false;d.detachEvent("onclick",s)});d.cloneNode(true).fireEvent("onclick")}d=u.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=u.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var s=u.createElement("div");+s.style.width=s.style.paddingLeft="1px";u.body.appendChild(s);c.boxModel=c.support.boxModel=s.offsetWidth===2;if("zoom"in s.style){s.style.display="inline";s.style.zoom=1;c.support.inlineBlockNeedsLayout=s.offsetWidth===2;s.style.display="";s.innerHTML="<div style='width:4px;'></div>";c.support.shrinkWrapBlocks=s.offsetWidth!==2}s.innerHTML="<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";var v=s.getElementsByTagName("td");c.support.reliableHiddenOffsets=v[0].offsetHeight===+0;v[0].style.display="";v[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&v[0].offsetHeight===0;s.innerHTML="";u.body.removeChild(s).style.display="none"});a=function(s){var v=u.createElement("div");s="on"+s;var B=s in v;if(!B){v.setAttribute(s,"return;");B=typeof v[s]==="function"}return B};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",+cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var pa={},Oa=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?pa:a;var e=a.nodeType,f=e?a[c.expando]:null,h=c.cache;if(!(e&&!f&&typeof b==="string"&&d===A)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=+c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==A)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?pa:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando);else if(d)delete f[e];else for(var k in a)delete a[k]}},acceptData:function(a){if(a.nodeName){var b=+c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){if(typeof a==="undefined")return this.length?c.data(this[0]):null;else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===A){var e=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(e===A&&this.length){e=c.data(this[0],a);if(e===A&&this[0].nodeType===1){e=this[0].getAttribute("data-"+a);if(typeof e===+"string")try{e=e==="true"?true:e==="false"?false:e==="null"?null:!c.isNaN(e)?parseFloat(e):Oa.test(e)?c.parseJSON(e):e}catch(f){}else e=A}}return e===A&&d[1]?this.data(d[0]):e}else return this.each(function(){var h=c(this),k=[d[0],b];h.triggerHandler("setData"+d[1]+"!",k);c.data(this,a,b);h.triggerHandler("changeData"+d[1]+"!",k)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e=c.data(a,b);if(!d)return e||+[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===A)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,+a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var qa=/[\n\t]/g,ga=/\s+/,Pa=/\r/g,Qa=/^(?:href|src|style)$/,Ra=/^(?:button|input)$/i,Sa=/^(?:button|input|object|select|textarea)$/i,Ta=/^a(?:rea)?$/i,ra=/^(?:radio|checkbox)$/i;c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,+a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(s){var v=c(this);v.addClass(a.call(this,s,v.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ga),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1)if(f.className){for(var h=" "+f.className+" ",k=f.className,l=0,n=b.length;l<n;l++)if(h.indexOf(" "+b[l]+" ")<0)k+=" "+b[l];f.className=c.trim(k)}else f.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(n){var s=+c(this);s.removeClass(a.call(this,n,s.attr("class")))});if(a&&typeof a==="string"||a===A)for(var b=(a||"").split(ga),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1&&f.className)if(a){for(var h=(" "+f.className+" ").replace(qa," "),k=0,l=b.length;k<l;k++)h=h.replace(" "+b[k]+" "," ");f.className=c.trim(h)}else f.className=""}return this},toggleClass:function(a,b){var d=typeof a,e=typeof b==="boolean";if(c.isFunction(a))return this.each(function(f){var h=c(this);h.toggleClass(a.call(this,+f,h.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var f,h=0,k=c(this),l=b,n=a.split(ga);f=n[h++];){l=e?l:!k.hasClass(f);k[l?"addClass":"removeClass"](f)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(qa," ").indexOf(a)>-1)return true;return false},+val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one";if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h<e;h++){var k=f[h];if(k.selected&&(c.support.optDisabled?!k.disabled:k.getAttribute("disabled")===null)&&(!k.parentNode.disabled||!c.nodeName(k.parentNode,"optgroup"))){a=c(k).val();if(b)return a;d.push(a)}}return d}if(ra.test(b.type)&&+!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Pa,"")}return A}var l=c.isFunction(a);return this.each(function(n){var s=c(this),v=a;if(this.nodeType===1){if(l)v=a.call(this,n,s.val());if(v==null)v="";else if(typeof v==="number")v+="";else if(c.isArray(v))v=c.map(v,function(D){return D==null?"":D+""});if(c.isArray(v)&&ra.test(this.type))this.checked=c.inArray(s.val(),v)>=0;else if(c.nodeName(this,"select")){var B=c.makeArray(v);c("option",this).each(function(){this.selected=+c.inArray(c(this).val(),B)>=0});if(!B.length)this.selectedIndex=-1}else this.value=v}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return A;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==A;b=e&&c.props[b]||b;if(a.nodeType===1){var h=Qa.test(b);if((b in a||a[b]!==A)&&e&&!h){if(f){b==="type"&&Ra.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");+if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Sa.test(a.nodeName)||Ta.test(a.nodeName)&&a.href?0:A;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return A;a=!c.support.hrefNormalized&&e&&+h?a.getAttribute(b,2):a.getAttribute(b);return a===null?A:a}}});var X=/\.(.*)$/,ha=/^(?:textarea|input|select)$/i,Ha=/\./g,Ia=/ /g,Ua=/[^\w\s.|`]/g,Va=function(a){return a.replace(Ua,"\\$&")},sa={focusin:0,focusout:0};c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var k=a.nodeType?"events":"__events__",l=h[k],n=h.handle;if(typeof l===+"function"){n=l.handle;l=l.events}else if(!l){a.nodeType||(h[k]=h=function(){});h.events=l={}}if(!n)h.handle=n=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(n.elem,arguments):A};n.elem=a;b=b.split(" ");for(var s=0,v;k=b[s++];){h=f?c.extend({},f):{handler:d,data:e};if(k.indexOf(".")>-1){v=k.split(".");k=v.shift();h.namespace=v.slice(0).sort().join(".")}else{v=[];h.namespace=""}h.type=k;if(!h.guid)h.guid=d.guid;var B=l[k],D=c.event.special[k]||{};if(!B){B=l[k]=[];+if(!D.setup||D.setup.call(a,e,v,n)===false)if(a.addEventListener)a.addEventListener(k,n,false);else a.attachEvent&&a.attachEvent("on"+k,n)}if(D.add){D.add.call(a,h);if(!h.handler.guid)h.handler.guid=d.guid}B.push(h);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,k=0,l,n,s,v,B,D,H=a.nodeType?"events":"__events__",w=c.data(a),G=w&&w[H];if(w&&G){if(typeof G==="function"){w=G;G=G.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||+typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in G)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[k++];){v=f;l=f.indexOf(".")<0;n=[];if(!l){n=f.split(".");f=n.shift();s=RegExp("(^|\\.)"+c.map(n.slice(0).sort(),Va).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(B=G[f])if(d){v=c.event.special[f]||{};for(h=e||0;h<B.length;h++){D=B[h];if(d.guid===D.guid){if(l||s.test(D.namespace)){e==null&&B.splice(h--,1);v.remove&&v.remove.call(a,D)}if(e!=null)break}}if(B.length===0||e!=null&&B.length===1){if(!v.teardown||+v.teardown.call(a,n)===false)c.removeEvent(a,f,w.handle);delete G[f]}}else for(h=0;h<B.length;h++){D=B[h];if(l||s.test(D.namespace)){c.event.remove(a,v,D.handler,h);B.splice(h--,1)}}}if(c.isEmptyObject(G)){if(b=w.handle)b.elem=null;delete w.events;delete w.handle;if(typeof w==="function")c.removeData(a,H);else c.isEmptyObject(w)&&c.removeData(a)}}}}},trigger:function(a,b,d,e){var f=a.type||a;if(!e){a=typeof a==="object"?a[c.expando]?a:c.extend(c.Event(f),a):c.Event(f);if(f.indexOf("!")>=0){a.type=+f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return A;a.result=A;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===+false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){e=a.target;var k,l=f.replace(X,""),n=c.nodeName(e,"a")&&l==="click",s=c.event.special[l]||{};if((!s._default||s._default.call(d,a)===false)&&!n&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[l]){if(k=e["on"+l])e["on"+l]=null;c.event.triggered=true;e[l]()}}catch(v){}if(k)e["on"+l]=k;c.event.triggered=false}}},handle:function(a){var b,d,e;+d=[];var f,h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var k=d.length;f<k;f++){var l=d[f];if(b||e.test(l.namespace)){a.handler=l.handler;a.data=+l.data;a.handleObj=l;l=l.handler.apply(this,h);if(l!==A){a.result=l;if(l===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),+fix:function(a){if(a[c.expando])return a;var b=a;a=c.Event(b);for(var d=this.props.length,e;d;){e=this.props[--d];a[e]=b[e]}if(!a.target)a.target=a.srcElement||u;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=u.documentElement;d=u.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(a.which==null&&(a.charCode!=null||a.keyCode!=null))a.which=a.charCode!=null?a.charCode:a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==A)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,Y(a.origType,a.selector),c.extend({},a,{handler:Ga,guid:a.handler.guid}))},remove:function(a){c.event.remove(this,+Y(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,d){if(c.isWindow(this))this.onbeforeunload=d},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.removeEvent=u.removeEventListener?function(a,b,d){a.removeEventListener&&a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent&&a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=+c.now();this[c.expando]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a)if(a.preventDefault)a.preventDefault();else a.returnValue=false},stopPropagation:function(){this.isPropagationStopped=ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:U,isPropagationStopped:U,isImmediatePropagationStopped:U};+var ta=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},ua=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?ua:ta,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?ua:ta)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(){if(this.nodeName.toLowerCase()!==+"form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length){a.liveFired=A;return ja("submit",this,arguments)}});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13){a.liveFired=A;return ja("submit",this,arguments)}})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};if(!c.support.changeBubbles){var V,+va=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ha.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=va(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===A||f===e))if(e!=null||f){a.type="change";a.liveFired=+A;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",va(a))}},setup:function(){if(this.type===+"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ha.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ha.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}u.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){sa[b]++===0&&u.addEventListener(a,d,true)},teardown:function(){--sa[b]===+0&&u.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=A}var k=b==="one"?c.proxy(f,function(n){c(this).unbind(n,k);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var l=this.length;h<l;h++)c.event.add(this[h],d,k,e)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var d in a)this.unbind(d,+a[d]);else{d=0;for(var e=this.length;d<e;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,e){return this.live(b,d,e,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var d=c.Event(a);d.preventDefault();d.stopPropagation();c.event.trigger(d,b,this[0]);return d.result}},toggle:function(a){for(var b=arguments,d=+1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(e){var f=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,f+1);e.preventDefault();return b[f].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var wa={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,e,f,h){var k,l=0,n,s,v=h||this.selector;h=h?this:c(this.context);if(typeof d===+"object"&&!d.preventDefault){for(k in d)h[b](k,e,d[k],v);return this}if(c.isFunction(e)){f=e;e=A}for(d=(d||"").split(" ");(k=d[l++])!=null;){n=X.exec(k);s="";if(n){s=n[0];k=k.replace(X,"")}if(k==="hover")d.push("mouseenter"+s,"mouseleave"+s);else{n=k;if(k==="focus"||k==="blur"){d.push(wa[k]+s);k+=s}else k=(wa[k]||k)+s;if(b==="live"){s=0;for(var B=h.length;s<B;s++)c.event.add(h[s],"live."+Y(k,v),{data:e,selector:v,handler:f,origType:k,origHandler:f,preType:n})}else h.unbind("live."+Y(k,v),f)}}return this}});+c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d,e){if(e==null){e=d;d=null}return arguments.length>0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});+(function(){function a(g,j,o,m,p,q){p=0;for(var t=m.length;p<t;p++){var x=m[p];if(x){x=x[g];for(var C=false;x;){if(x.sizcache===o){C=m[x.sizset];break}if(x.nodeType===1&&!q){x.sizcache=o;x.sizset=p}if(x.nodeName.toLowerCase()===j){C=x;break}x=x[g]}m[p]=C}}}function b(g,j,o,m,p,q){p=0;for(var t=m.length;p<t;p++){var x=m[p];if(x){x=x[g];for(var C=false;x;){if(x.sizcache===o){C=m[x.sizset];break}if(x.nodeType===1){if(!q){x.sizcache=o;x.sizset=p}if(typeof j!=="string"){if(x===j){C=true;break}}else if(l.filter(j,+[x]).length>0){C=x;break}}x=x[g]}m[p]=C}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,k=true;[0,0].sort(function(){k=false;return 0});var l=function(g,j,o,m){o=o||[];var p=j=j||u;if(j.nodeType!==1&&j.nodeType!==9)return[];if(!g||typeof g!=="string")return o;var q=[],t,x,C,P,N=true,R=l.isXML(j),Q=g,L;do{d.exec("");if(t=d.exec(Q)){Q=t[3];q.push(t[1]);if(t[2]){P=t[3];+break}}}while(t);if(q.length>1&&s.exec(g))if(q.length===2&&n.relative[q[0]])x=M(q[0]+q[1],j);else for(x=n.relative[q[0]]?[j]:l(q.shift(),j);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();x=M(g,x)}else{if(!m&&q.length>1&&j.nodeType===9&&!R&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){t=l.find(q.shift(),j,R);j=t.expr?l.filter(t.expr,t.set)[0]:t.set[0]}if(j){t=m?{expr:q.pop(),set:D(m)}:l.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&j.parentNode?j.parentNode:j,R);x=t.expr?l.filter(t.expr,+t.set):t.set;if(q.length>0)C=D(x);else N=false;for(;q.length;){t=L=q.pop();if(n.relative[L])t=q.pop();else L="";if(t==null)t=j;n.relative[L](C,t,R)}}else C=[]}C||(C=x);C||l.error(L||g);if(f.call(C)==="[object Array]")if(N)if(j&&j.nodeType===1)for(g=0;C[g]!=null;g++){if(C[g]&&(C[g]===true||C[g].nodeType===1&&l.contains(j,C[g])))o.push(x[g])}else for(g=0;C[g]!=null;g++)C[g]&&C[g].nodeType===1&&o.push(x[g]);else o.push.apply(o,C);else D(C,o);if(P){l(P,p,o,m);l.uniqueSort(o)}return o};l.uniqueSort=function(g){if(w){h=+k;g.sort(w);if(h)for(var j=1;j<g.length;j++)g[j]===g[j-1]&&g.splice(j--,1)}return g};l.matches=function(g,j){return l(g,null,null,j)};l.matchesSelector=function(g,j){return l(j,null,null,[g]).length>0};l.find=function(g,j,o){var m;if(!g)return[];for(var p=0,q=n.order.length;p<q;p++){var t=n.order[p],x;if(x=n.leftMatch[t].exec(g)){var C=x[1];x.splice(1,1);if(C.substr(C.length-1)!=="\\"){x[1]=(x[1]||"").replace(/\\/g,"");m=n.find[t](x,j,o);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=j.getElementsByTagName("*"));+return{set:m,expr:g}};l.filter=function(g,j,o,m){for(var p=g,q=[],t=j,x,C,P=j&&j[0]&&l.isXML(j[0]);g&&j.length;){for(var N in n.filter)if((x=n.leftMatch[N].exec(g))!=null&&x[2]){var R=n.filter[N],Q,L;L=x[1];C=false;x.splice(1,1);if(L.substr(L.length-1)!=="\\"){if(t===q)q=[];if(n.preFilter[N])if(x=n.preFilter[N](x,t,o,q,m,P)){if(x===true)continue}else C=Q=true;if(x)for(var i=0;(L=t[i])!=null;i++)if(L){Q=R(L,x,i,t);var r=m^!!Q;if(o&&Q!=null)if(r)C=true;else t[i]=false;else if(r){q.push(L);C=true}}if(Q!==+A){o||(t=q);g=g.replace(n.match[N],"");if(!C)return[];break}}}if(g===p)if(C==null)l.error(g);else break;p=g}return t};l.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=l.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,+POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,j){var o=typeof j==="string",m=o&&!/\W/.test(j);o=o&&!m;if(m)j=j.toLowerCase();m=0;for(var p=g.length,q;m<p;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=o||q&&q.nodeName.toLowerCase()===+j?q||false:q===j}o&&l.filter(j,g,true)},">":function(g,j){var o=typeof j==="string",m,p=0,q=g.length;if(o&&!/\W/.test(j))for(j=j.toLowerCase();p<q;p++){if(m=g[p]){o=m.parentNode;g[p]=o.nodeName.toLowerCase()===j?o:false}}else{for(;p<q;p++)if(m=g[p])g[p]=o?m.parentNode:m.parentNode===j;o&&l.filter(j,g,true)}},"":function(g,j,o){var m=e++,p=b,q;if(typeof j==="string"&&!/\W/.test(j)){q=j=j.toLowerCase();p=a}p("parentNode",j,m,g,q,o)},"~":function(g,j,o){var m=e++,p=b,q;if(typeof j==="string"&&!/\W/.test(j)){q=+j=j.toLowerCase();p=a}p("previousSibling",j,m,g,q,o)}},find:{ID:function(g,j,o){if(typeof j.getElementById!=="undefined"&&!o)return(g=j.getElementById(g[1]))&&g.parentNode?[g]:[]},NAME:function(g,j){if(typeof j.getElementsByName!=="undefined"){for(var o=[],m=j.getElementsByName(g[1]),p=0,q=m.length;p<q;p++)m[p].getAttribute("name")===g[1]&&o.push(m[p]);return o.length===0?null:o}},TAG:function(g,j){return j.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,j,o,m,p,q){g=" "+g[1].replace(/\\/g,+"")+" ";if(q)return g;q=0;for(var t;(t=j[q])!=null;q++)if(t)if(p^(t.className&&(" "+t.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))o||m.push(t);else if(o)j[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var j=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=j[1]+(j[2]||1)-0;g[3]=j[3]-0}g[0]=e++;return g},ATTR:function(g,j,o,+m,p,q){j=g[1].replace(/\\/g,"");if(!q&&n.attrMap[j])g[1]=n.attrMap[j];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,j,o,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=l(g[3],null,null,j);else{g=l.filter(g[3],j,o,true^p);o||m.push.apply(m,g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===+true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,j,o){return!!l(o[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===+g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,j){return j===0},last:function(g,j,o,m){return j===m.length-1},even:function(g,j){return j%2===0},odd:function(g,j){return j%2===1},lt:function(g,j,o){return j<o[3]-0},gt:function(g,j,o){return j>o[3]-0},nth:function(g,j,o){return o[3]-+0===j},eq:function(g,j,o){return o[3]-0===j}},filter:{PSEUDO:function(g,j,o,m){var p=j[1],q=n.filters[p];if(q)return q(g,o,j,m);else if(p==="contains")return(g.textContent||g.innerText||l.getText([g])||"").indexOf(j[3])>=0;else if(p==="not"){j=j[3];o=0;for(m=j.length;o<m;o++)if(j[o]===g)return false;return true}else l.error("Syntax error, unrecognized expression: "+p)},CHILD:function(g,j){var o=j[1],m=g;switch(o){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(o===+"first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":o=j[2];var p=j[3];if(o===1&&p===0)return true;var q=j[0],t=g.parentNode;if(t&&(t.sizcache!==q||!g.nodeIndex)){var x=0;for(m=t.firstChild;m;m=m.nextSibling)if(m.nodeType===1)m.nodeIndex=++x;t.sizcache=q}m=g.nodeIndex-p;return o===0?m===0:m%o===0&&m/o>=0}},ID:function(g,j){return g.nodeType===1&&g.getAttribute("id")===j},TAG:function(g,j){return j==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===+j},CLASS:function(g,j){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(j)>-1},ATTR:function(g,j){var o=j[1];o=n.attrHandle[o]?n.attrHandle[o](g):g[o]!=null?g[o]:g.getAttribute(o);var m=o+"",p=j[2],q=j[4];return o==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&o!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,j,o,m){var p=n.setFilters[j[2]];+if(p)return p(g,o,j,m)}}},s=n.match.POS,v=function(g,j){return"\\"+(j-0+1)},B;for(B in n.match){n.match[B]=RegExp(n.match[B].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[B]=RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[B].source.replace(/\\(\d+)/g,v))}var D=function(g,j){g=Array.prototype.slice.call(g,0);if(j){j.push.apply(j,g);return j}return g};try{Array.prototype.slice.call(u.documentElement.childNodes,0)}catch(H){D=function(g,j){var o=j||[],m=0;if(f.call(g)==="[object Array]")Array.prototype.push.apply(o,+g);else if(typeof g.length==="number")for(var p=g.length;m<p;m++)o.push(g[m]);else for(;g[m];m++)o.push(g[m]);return o}}var w,G;if(u.documentElement.compareDocumentPosition)w=function(g,j){if(g===j){h=true;return 0}if(!g.compareDocumentPosition||!j.compareDocumentPosition)return g.compareDocumentPosition?-1:1;return g.compareDocumentPosition(j)&4?-1:1};else{w=function(g,j){var o=[],m=[],p=g.parentNode,q=j.parentNode,t=p;if(g===j){h=true;return 0}else if(p===q)return G(g,j);else if(p){if(!q)return 1}else return-1;+for(;t;){o.unshift(t);t=t.parentNode}for(t=q;t;){m.unshift(t);t=t.parentNode}p=o.length;q=m.length;for(t=0;t<p&&t<q;t++)if(o[t]!==m[t])return G(o[t],m[t]);return t===p?G(g,m[t],-1):G(o[t],j,1)};G=function(g,j,o){if(g===j)return o;for(g=g.nextSibling;g;){if(g===j)return-1;g=g.nextSibling}return 1}}l.getText=function(g){for(var j="",o,m=0;g[m];m++){o=g[m];if(o.nodeType===3||o.nodeType===4)j+=o.nodeValue;else if(o.nodeType!==8)j+=l.getText(o.childNodes)}return j};(function(){var g=u.createElement("div"),+j="script"+(new Date).getTime();g.innerHTML="<a name='"+j+"'/>";var o=u.documentElement;o.insertBefore(g,o.firstChild);if(u.getElementById(j)){n.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:A:[]};n.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}o.removeChild(g);+o=g=null})();(function(){var g=u.createElement("div");g.appendChild(u.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(j,o){var m=o.getElementsByTagName(j[1]);if(j[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(j){return j.getAttribute("href",2)};g=null})();u.querySelectorAll&&+function(){var g=l,j=u.createElement("div");j.innerHTML="<p class='TEST'></p>";if(!(j.querySelectorAll&&j.querySelectorAll(".TEST").length===0)){l=function(m,p,q,t){p=p||u;if(!t&&!l.isXML(p))if(p.nodeType===9)try{return D(p.querySelectorAll(m),q)}catch(x){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var C=p.id,P=p.id="__sizzle__";try{return D(p.querySelectorAll("#"+P+" "+m),q)}catch(N){}finally{if(C)p.id=C;else p.removeAttribute("id")}}return g(m,p,q,t)};for(var o in g)l[o]=g[o];+j=null}}();(function(){var g=u.documentElement,j=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,o=false;try{j.call(u.documentElement,":sizzle")}catch(m){o=true}if(j)l.matchesSelector=function(p,q){try{if(o||!n.match.PSEUDO.test(q))return j.call(p,q)}catch(t){}return l(q,null,null,[p]).length>0}})();(function(){var g=u.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===+0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(j,o,m){if(typeof o.getElementsByClassName!=="undefined"&&!m)return o.getElementsByClassName(j[1])};g=null}}})();l.contains=u.documentElement.contains?function(g,j){return g!==j&&(g.contains?g.contains(j):true)}:function(g,j){return!!(g.compareDocumentPosition(j)&16)};l.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var M=function(g,+j){for(var o=[],m="",p,q=j.nodeType?[j]:j;p=n.match.PSEUDO.exec(g);){m+=p[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;p=0;for(var t=q.length;p<t;p++)l(g,q[p],o);return l.filter(m,o)};c.find=l;c.expr=l.selectors;c.expr[":"]=c.expr.filters;c.unique=l.uniqueSort;c.text=l.getText;c.isXMLDoc=l.isXML;c.contains=l.contains})();var Wa=/Until$/,Xa=/^(?:parents|prevUntil|prevAll)/,Ya=/,/,Ja=/^.[^:#\[\.,]*$/,Za=Array.prototype.slice,$a=c.expr.match.POS;c.fn.extend({find:function(a){for(var b=this.pushStack("",+"find",a),d=0,e=0,f=this.length;e<f;e++){d=b.length;c.find(a,this[e],b);if(e>0)for(var h=d;h<b.length;h++)for(var k=0;k<d;k++)if(b[k]===b[h]){b.splice(h--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,e=b.length;d<e;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(ka(this,a,false),"not",a)},filter:function(a){return this.pushStack(ka(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,+b){var d=[],e,f,h=this[0];if(c.isArray(a)){var k={},l,n=1;if(h&&a.length){e=0;for(f=a.length;e<f;e++){l=a[e];k[l]||(k[l]=c.expr.match.POS.test(l)?c(l,b||this.context):l)}for(;h&&h.ownerDocument&&h!==b;){for(l in k){e=k[l];if(e.jquery?e.index(h)>-1:c(h).is(e))d.push({selector:l,elem:h,level:n})}h=h.parentNode;n++}}return d}k=$a.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e<f;e++)for(h=this[e];h;)if(k?k.index(h)>-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||+!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});+c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",+d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Wa.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||Ya.test(e))&&Xa.test(a))f=f.reverse();return this.pushStack(f,a,Za.call(arguments).join(","))}});+c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===A||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var xa=/ jQuery\d+="(?:\d+|null)"/g,+$=/^\s+/,ya=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,za=/<([\w:]+)/,ab=/<tbody/i,bb=/<|&#?\w+;/,Aa=/<(?:script|object|embed|option|style)/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,cb=/\=([^="'>\s]+\/)>/g,O={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],+area:[1,"<map>","</map>"],_default:[0,"",""]};O.optgroup=O.option;O.tbody=O.tfoot=O.colgroup=O.caption=O.thead;O.th=O.td;if(!c.support.htmlSerialize)O._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==A)return this.empty().append((this[0]&&this[0].ownerDocument||u).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,+d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},+unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=+c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));+c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(xa,"").replace(cb,'="$1">').replace($,+"")],e)[0]}else return this.cloneNode(true)});if(a===true){la(this,b);la(this.find("*"),b.find("*"))}return b},html:function(a){if(a===A)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(xa,""):null;else if(typeof a==="string"&&!Aa.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!O[(za.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ya,"<$1></$2>");try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(e){this.empty().append(a)}}else c.isFunction(a)?+this.each(function(f){var h=c(this);h.html(a.call(this,f,h.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),e=d.html();d.replaceWith(a.call(this,b,e))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,+true)},domManip:function(a,b,d){var e,f,h=a[0],k=[],l;if(!c.support.checkClone&&arguments.length===3&&typeof h==="string"&&Ba.test(h))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(h))return this.each(function(s){var v=c(this);a[0]=h.call(this,s,b?v.html():A);v.domManip(a,b,d)});if(this[0]){e=h&&h.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:c.buildFragment(a,this,k);l=e.fragment;if(f=l.childNodes.length===1?l=l.firstChild:+l.firstChild){b=b&&c.nodeName(f,"tr");f=0;for(var n=this.length;f<n;f++)d.call(b?c.nodeName(this[f],"table")?this[f].getElementsByTagName("tbody")[0]||this[f].appendChild(this[f].ownerDocument.createElement("tbody")):this[f]:this[f],f>0||e.cacheable||this.length>1?l.cloneNode(true):l)}k.length&&c.each(k,Ka)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:u;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===u&&!Aa.test(a[0])&&(c.support.checkClone||+!Ba.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=+d.length;f<h;f++){var k=(f>0?this.clone(true):this).get();c(d[f])[b](k);e=e.concat(k)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||u;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||u;for(var f=[],h=0,k;(k=a[h])!=null;h++){if(typeof k==="number")k+="";if(k){if(typeof k==="string"&&!bb.test(k))k=b.createTextNode(k);else if(typeof k==="string"){k=k.replace(ya,"<$1></$2>");var l=(za.exec(k)||["",""])[1].toLowerCase(),n=O[l]||O._default,+s=n[0],v=b.createElement("div");for(v.innerHTML=n[1]+k+n[2];s--;)v=v.lastChild;if(!c.support.tbody){s=ab.test(k);l=l==="table"&&!s?v.firstChild&&v.firstChild.childNodes:n[1]==="<table>"&&!s?v.childNodes:[];for(n=l.length-1;n>=0;--n)c.nodeName(l[n],"tbody")&&!l[n].childNodes.length&&l[n].parentNode.removeChild(l[n])}!c.support.leadingWhitespace&&$.test(k)&&v.insertBefore(b.createTextNode($.exec(k)[0]),v.firstChild);k=v.childNodes}if(k.nodeType)f.push(k);else f=c.merge(f,k)}}if(d)for(h=0;f[h];h++)if(e&&+c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,k=0,l;(l=a[k])!=null;k++)if(!(l.nodeName&&c.noData[l.nodeName.toLowerCase()]))if(d=l[c.expando]){if((b=e[d])&&b.events)for(var n in b.events)f[n]?+c.event.remove(l,n):c.removeEvent(l,n,b.handle);if(h)delete l[c.expando];else l.removeAttribute&&l.removeAttribute(c.expando);delete e[d]}}});var Ca=/alpha\([^)]*\)/i,db=/opacity=([^)]*)/,eb=/-([a-z])/ig,fb=/([A-Z])/g,Da=/^-?\d+(?:px)?$/i,gb=/^-?\d/,hb={position:"absolute",visibility:"hidden",display:"block"},La=["Left","Right"],Ma=["Top","Bottom"],W,ib=u.defaultView&&u.defaultView.getComputedStyle,jb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===A)return this;+return c.access(this,a,b,true,function(d,e,f){return f!==A?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),k=a.style,l=c.cssHooks[h];b=c.cssProps[h]||+h;if(d!==A){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!l||!("set"in l)||(d=l.set(a,d))!==A)try{k[b]=d}catch(n){}}}else{if(l&&"get"in l&&(f=l.get(a,false,e))!==A)return f;return k[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==A)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=+e[f]},camelCase:function(a){return a.replace(eb,jb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=ma(d,b,f);else c.swap(d,hb,function(){h=ma(d,b,f)});return h+"px"}},set:function(d,e){if(Da.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return db.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":+b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=d.filter||"";d.filter=Ca.test(f)?f.replace(Ca,e):d.filter+" "+e}};if(ib)W=function(a,b,d){var e;d=d.replace(fb,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return A;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};else if(u.documentElement.currentStyle)W=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],+h=a.style;if(!Da.test(f)&&gb.test(f)){d=h.left;e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f};if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var kb=c.now(),lb=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,+mb=/^(?:select|textarea)/i,nb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ob=/^(?:GET|HEAD|DELETE)$/,Na=/\[\]$/,T=/\=\?(&|$)/,ia=/\?/,pb=/([?&])_=[^&]*/,qb=/^(\w+:)?\/\/([^\/?#]+)/,rb=/%20/g,sb=/#.*$/,Ea=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ea)return Ea.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=+b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(k,l){if(l==="success"||l==="notmodified")h.html(f?c("<div>").append(k.responseText.replace(lb,"")).find(f):k.responseText);d&&h.each(d,[k.responseText,l,k])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&+!this.disabled&&(this.checked||mb.test(this.nodeName)||nb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})},+getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html",+script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),k=ob.test(h);b.url=b.url.replace(sb,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ia.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data||+!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+kb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var l=E[d];E[d]=function(m){f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);if(c.isFunction(l))l(m);else{E[d]=A;try{delete E[d]}catch(p){}}v&&v.removeChild(B)}}if(b.dataType==="script"&&b.cache===null)b.cache=+false;if(b.cache===false&&h==="GET"){var n=c.now(),s=b.url.replace(pb,"$1_="+n);b.url=s+(s===b.url?(ia.test(b.url)?"&":"?")+"_="+n:"")}if(b.data&&h==="GET")b.url+=(ia.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");n=(n=qb.exec(b.url))&&(n[1]&&n[1]!==location.protocol||n[2]!==location.host);if(b.dataType==="script"&&h==="GET"&&n){var v=u.getElementsByTagName("head")[0]||u.documentElement,B=u.createElement("script");if(b.scriptCharset)B.charset=b.scriptCharset;B.src=+b.url;if(!d){var D=false;B.onload=B.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);B.onload=B.onreadystatechange=null;v&&B.parentNode&&v.removeChild(B)}}}v.insertBefore(B,v.firstChild);return A}var H=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!k||a&&a.contentType)w.setRequestHeader("Content-Type",+b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}n||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(G){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&&+c.triggerGlobal(b,"ajaxSend",[w,b]);var M=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){H||c.handleComplete(b,w,e,f);H=true;if(w)w.onreadystatechange=c.noop}else if(!H&&w&&(w.readyState===4||m==="timeout")){H=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d||+c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&g.call&&g.call(w);M("abort")}}catch(j){}b.async&&b.timeout>0&&setTimeout(function(){w&&!H&&M("timeout")},b.timeout);try{w.send(k||b.data==null?null:b.data)}catch(o){c.handleError(b,w,null,o);c.handleComplete(b,w,e,f)}b.async||M();return w}},param:function(a,b){var d=[],e=function(h,k){k=c.isFunction(k)?k():k;d[d.length]=encodeURIComponent(h)++"="+encodeURIComponent(k)};if(b===A)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)ca(f,a[f],b,e);return d.join("&").replace(rb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess",[b,a])},handleComplete:function(a,+b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),e=a.getResponseHeader("Etag");+if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}});if(E.ActiveXObject)c.ajaxSettings.xhr=+function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var da={},tb=/^(?:toggle|show|hide)$/,ub=/^([+\-]=)?([\d+.\-]+)(.*)$/,aa,na=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show",3),a,b,d);else{a=+0;for(b=this.length;a<b;a++){if(!c.data(this[a],"olddisplay")&&this[a].style.display==="none")this[a].style.display="";this[a].style.display===""&&c.css(this[a],"display")==="none"&&c.data(this[a],"olddisplay",oa(this[a].nodeName))}for(a=0;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b,d){if(a||a===0)return this.animate(S("hide",3),a,b,d);else{a=0;for(b=this.length;a<b;a++){d=c.css(this[a],"display");d!=="none"&&c.data(this[a],"olddisplay",d)}for(a=+0;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b,d){var e=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||e?this.each(function(){var f=e?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(S("toggle",3),a,b,d);return this},fadeTo:function(a,b,d,e){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d,e)},animate:function(a,b,d,e){var f=c.speed(b,d,e);if(c.isEmptyObject(a))return this.each(f.complete);+return this[f.queue===false?"each":"queue"](function(){var h=c.extend({},f),k,l=this.nodeType===1,n=l&&c(this).is(":hidden"),s=this;for(k in a){var v=c.camelCase(k);if(k!==v){a[v]=a[k];delete a[k];k=v}if(a[k]==="hide"&&n||a[k]==="show"&&!n)return h.complete.call(this);if(l&&(k==="height"||k==="width")){h.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(c.css(this,"display")==="inline"&&c.css(this,"float")==="none")if(c.support.inlineBlockNeedsLayout)if(oa(this.nodeName)===+"inline")this.style.display="inline-block";else{this.style.display="inline";this.style.zoom=1}else this.style.display="inline-block"}if(c.isArray(a[k])){(h.specialEasing=h.specialEasing||{})[k]=a[k][1];a[k]=a[k][0]}}if(h.overflow!=null)this.style.overflow="hidden";h.curAnim=c.extend({},a);c.each(a,function(B,D){var H=new c.fx(s,h,B);if(tb.test(D))H[D==="toggle"?n?"show":"hide":D](a);else{var w=ub.exec(D),G=H.cur(true)||0;if(w){var M=parseFloat(w[2]),g=w[3]||"px";if(g!=="px"){c.style(s,B,(M||1)+g);+G=(M||1)/H.cur(true)*G;c.style(s,B,G+g)}if(w[1])M=(w[1]==="-="?-1:1)*M+G;H.custom(G,M,g)}else H.custom(G,D,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var e=d.length-1;e>=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b,+d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a*+Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(h){return f.step(h)}+this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var f=this;a=c.fx;e.elem=this.elem;if(e()&&c.timers.push(e)&&!aa)aa=setInterval(a.tick,a.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;+this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(l,n){f.style["overflow"+n]=h.overflow[l]})}this.options.hide&&c(this.elem).hide();if(this.options.hide||+this.options.show)for(var k in this.options.curAnim)c.style(this.elem,k,this.options.orig[k]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=+c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},interval:13,stop:function(){clearInterval(aa);aa=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===+b.elem}).length};var vb=/^t(?:able|d|h)$/i,Fa=/^(?:body|html)$/i;c.fn.offset="getBoundingClientRect"in u.documentElement?function(a){var b=this[0],d;if(a)return this.each(function(k){c.offset.setOffset(this,a,k)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);try{d=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,h=f.documentElement;if(!d||!c.contains(h,b))return d||{top:0,left:0};b=f.body;f=ea(f);return{top:d.top+(f.pageYOffset||c.support.boxModel&&+h.scrollTop||b.scrollTop)-(h.clientTop||b.clientTop||0),left:d.left+(f.pageXOffset||c.support.boxModel&&h.scrollLeft||b.scrollLeft)-(h.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,e=b.ownerDocument,f,h=e.documentElement,k=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;+for(var l=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==k&&b!==h;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;f=e?e.getComputedStyle(b,null):b.currentStyle;l-=b.scrollTop;n-=b.scrollLeft;if(b===d){l+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&vb.test(b.nodeName))){l+=parseFloat(f.borderTopWidth)||0;n+=parseFloat(f.borderLeftWidth)||0}d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&f.overflow!=="visible"){l+=+parseFloat(f.borderTopWidth)||0;n+=parseFloat(f.borderLeftWidth)||0}f=f}if(f.position==="relative"||f.position==="static"){l+=k.offsetTop;n+=k.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){l+=Math.max(h.scrollTop,k.scrollTop);n+=Math.max(h.scrollLeft,k.scrollLeft)}return{top:l,left:n}};c.offset={initialize:function(){var a=u.body,b=u.createElement("div"),d,e,f,h=parseFloat(c.css(a,"marginTop"))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",+height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);d=b.firstChild;e=d.firstChild;f=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=e.offsetTop!==5;this.doesAddBorderForTableAndCells=+f.offsetTop===5;e.style.position="fixed";e.style.top="20px";this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15;e.style.position=e.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==h;a.removeChild(b);c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.css(a,+"marginTop"))||0;d+=parseFloat(c.css(a,"marginLeft"))||0}return{top:b,left:d}},setOffset:function(a,b,d){var e=c.css(a,"position");if(e==="static")a.style.position="relative";var f=c(a),h=f.offset(),k=c.css(a,"top"),l=c.css(a,"left"),n=e==="absolute"&&c.inArray("auto",[k,l])>-1;e={};var s={};if(n)s=f.position();k=n?s.top:parseInt(k,10)||0;l=n?s.left:parseInt(l,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+k;if(b.left!=null)e.left=b.left-h.left+l;"using"in b?b.using.call(a,+e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Fa.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||u.body;a&&!Fa.test(a.nodeName)&&+c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==A)return this.each(function(){if(h=ea(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=ea(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();+c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(h){var k=c(this);k[d](e.call(this,h,k[d]()))});return c.isWindow(f)?f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b]:f.nodeType===9?Math.max(f.documentElement["client"++b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]):e===A?parseFloat(c.css(f,d)):this.css(d,typeof e==="string"?e:e+"px")}})})(window);
+ seed/static/ribbon.png view

binary file changed (absent → 36162 bytes)

+ seed/static/silk/arrow_down.png view

binary file changed (absent → 379 bytes)

+ seed/static/silk/exclamation.png view

binary file changed (absent → 701 bytes)

+ seed/static/silk/folder.png view

binary file changed (absent → 537 bytes)

+ seed/static/silk/image.png view

binary file changed (absent → 516 bytes)

+ seed/static/silk/lightning.png view

binary file changed (absent → 634 bytes)

+ seed/static/silk/link.png view

binary file changed (absent → 343 bytes)

+ seed/static/silk/magnifier.png view

binary file changed (absent → 615 bytes)

+ seed/static/silk/page_white.png view

binary file changed (absent → 294 bytes)

+ seed/static/silk/page_white_code.png view

binary file changed (absent → 603 bytes)

+ seed/static/silk/page_white_code_red.png view

binary file changed (absent → 587 bytes)

+ seed/static/silk/page_white_world.png view

binary file changed (absent → 734 bytes)

+ seed/static/silk/pencil.png view

binary file changed (absent → 450 bytes)

+ seed/static/slides.css view
@@ -0,0 +1,109 @@+/* @override http://localhost:8080/static/slides.css */++/* @group Basics */++* {+  margin: 0;+  padding: 0;+}++p {+  margin: 1em 0;+}++ul, ol, dl {+  margin: 1em 3em;+}++pre {+  margin: 1em 0;+  overflow: auto;+}++.src {+  padding: 0.5em 1em;+  background: rgb(229,237,244);+}++/* @end */++/* @group Fonts & Sizes */++/* Basic technique & IE workarounds from YUI 3+   For reasons, see:+      http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css+ */++body {+  font:16px/1.375 "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;;+  *font-size:small; /* for IE */+  *font:x-small; /* for IE in quirks mode */+  color: #424242;+  background: #ddddcf;+}++h1 {+  color: #cc2900;+}+h1, h2, h3 {+  font-family: Skia, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;+}++h1 { font-size: 150%;   /* 24pt */ } +h2 { font-size: 112.5%; /* 18pt */ }+h3 { font-size: 100%;   /* 16pt */ }++p small {+  font-size: 81.25%; /* 13pt */+}++pre, code, kbd, samp, tt, .src {+  font-family:monospace;+  *font-size:108%;+  line-height: 124%;+}++/* @end */++#slides {+  width: 36em;+  height: 27em;+  margin: 2em;+  position: relative;+  overflow: hidden;+  padding: 1px;+}++.slide {+  background: #fff;+  border: 1px solid #818181;+  width: 35em;+  height: 26em;+  padding: 0.5em;+  position: absolute;+  top: 0;+  left: 0;+}++.title-slide {+  text-align: center;+}++.title-slide h1 {+  font-size: 200%;  /* 32pt */+  margin-top: 3em;+  margin-bottom: 0.5em;+}++#controls {+  margin: 2em;+  text-align: right;+  width: 36em;+  position: absolute;+  top: 28em;+  left: 0;+}++#prev-slide {+  float: left;+} 
+ seed/static/stripe.png view

binary file changed (absent → 7402 bytes)

+ seed/static/switches.png view

binary file changed (absent → 8235 bytes)

+ src/Barley/AltLoad.hs view
@@ -0,0 +1,765 @@+{-# LANGUAGE CPP                        #-}+{-# LANGUAGE MagicHash                  #-}+{-# LANGUAGE UnboxedTuples              #-}+{-# LANGUAGE ForeignFunctionInterface   #-}++-- NOTE: This file is a copy of System.Plugins.Load. It has been patched to+-- expose some internal functionality (loadObjectFile, which used to be part+-- of load). When the patch is integrated into the plugins package, this file+-- can be removed.+--+-- Copyright (C) 2004-5 Don Stewart - http://www.cse.unsw.edu.au/~dons+-- +-- This library is free software; you can redistribute it and/or+-- modify it under the terms of the GNU Lesser General Public+-- License as published by the Free Software Foundation; either+-- version 2.1 of the License, or (at your option) any later version.+-- +-- This library is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+-- Lesser General Public License for more details.+-- +-- You should have received a copy of the GNU Lesser General Public+-- License along with this library; if not, write to the Free Software+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307+-- USA+-- ++-- | An interface to the GHC runtime's dynamic linker, providing runtime+-- loading and linking of Haskell object files, commonly known as+-- /plugins/.++module Barley.AltLoad (++      -- * The @LoadStatus@ type+      LoadStatus(..)++      -- * High-level interface+      , load+      , load_+      , dynload+      , pdynload +      , pdynload_+      , unload+      , unloadAll+      , reload+      , Module(..)++      -- * Low-level interface+      , initLinker      -- start it up+      , loadObjectFile  -- load and resolve a .o and all its dependencies+      , loadModule      -- load a vanilla .o+      , loadFunction    -- retrieve a function from an object+      , loadFunction_   -- retrieve a function from an object+      , loadPackageFunction+      , loadPackage     -- load a ghc library and its cbits+      , unloadPackage   -- unload a ghc library and its cbits+      , loadPackageWith -- load a pkg using the package.conf provided+      , loadShared      -- load a .so object file+      , resolveObjs     -- and resolve symbols++      , loadRawObject   -- load a bare .o. no dep chasing, no .hi file reading++      , Symbol++      , getImports++  ) where++-- #include "../../../config.h"++import System.Plugins.Make             ( build )+import System.Plugins.Env+import System.Plugins.Utils+import System.Plugins.Consts           ( sysPkgSuffix, hiSuf, prefixUnderscore )+import System.Plugins.LoadTypes++-- import Language.Hi.Parser+import BinIface+import HscTypes+import Module (moduleName, moduleNameString, packageIdString)+import HscMain (newHscEnv)+import TcRnMonad (initTcRnIf)++import Data.Dynamic          ( fromDynamic, Dynamic )+import Data.Typeable         ( Typeable )++import Data.List                ( isSuffixOf, nub, nubBy )+import Control.Monad            ( when, filterM, liftM )+import System.Directory         ( doesFileExist, removeFile )+import Foreign.C.String         ( CString, withCString, peekCString )++import GHC                      ( defaultCallbacks )+import GHC.Ptr                  ( Ptr(..), nullPtr )+import GHC.Exts                 ( addrToHValue# )+import GHC.Prim                 ( unsafeCoerce# )++#if DEBUG+import System.IO                ( hFlush, stdout )+#endif+import System.IO                ( hClose )++ifaceModuleName :: ModIface -> String+ifaceModuleName = moduleNameString . moduleName . mi_module++readBinIface' :: FilePath -> IO ModIface+readBinIface' hi_path = do+    -- kludgy as hell+    e <- newHscEnv defaultCallbacks undefined+    initTcRnIf 'r' e undefined undefined (readBinIface IgnoreHiWay QuietBinIFaceReading hi_path)++-- TODO need a loadPackage p package.conf :: IO () primitive++--+-- | The @LoadStatus@ type encodes the return status of functions that+-- perform dynamic loading in a type isomorphic to 'Either'. Failure+-- returns a list of error strings, success returns a reference to a+-- loaded module, and the Haskell value corresponding to the symbol that+-- was indexed.+--+data LoadStatus a+        = LoadSuccess Module a+        | LoadFailure Errors++--+-- | 'load' is the basic interface to the dynamic loader. A call to+-- 'load' imports a single object file into the caller's address space,+-- returning the value associated with the symbol requested. Libraries+-- and modules that the requested module depends upon are loaded and+-- linked in turn.+--+-- The first argument is the path to the object file to load, the second+-- argument is a list of directories to search for dependent modules.+-- The third argument is a list of paths to user-defined, but+-- unregistered, /package.conf/ files. The 'Symbol' argument is the+-- symbol name of the value you with to retrieve.+--+-- The value returned must be given an explicit type signature, or+-- provided with appropriate type constraints such that Haskell compiler+-- can determine the expected type returned by 'load', as the return+-- type is notionally polymorphic.+-- +-- Example:+--+-- > do mv <- load "Plugin.o" ["api"] [] "resource"+-- >    case mv of+-- >        LoadFailure msg -> print msg+-- >        LoadSuccess _ v -> return v+--+load :: FilePath                -- ^ object file+     -> [FilePath]              -- ^ any include paths+     -> [PackageConf]           -- ^ list of package.conf paths+     -> Symbol                  -- ^ symbol to find+     -> IO (LoadStatus a)++load obj incpaths pkgconfs sym = do+    m <- loadObjectFile obj incpaths pkgconfs+    v <- loadFunction m sym+    return $ case v of +        Nothing -> LoadFailure ["load: couldn't find symbol <<"++sym++">>"]+        Just a  -> LoadSuccess m a++--+-- | Like load, but doesn't want a package.conf arg (they are rarely used)+--+load_ :: FilePath -> [FilePath] -> Symbol -> IO (LoadStatus a)+load_ o i s = load o i [] s++--+-- A work-around for Dynamics. The keys used to compare two TypeReps are+-- somehow not equal for the same type in hs-plugin's loaded objects.+-- Solution: implement our own dynamics...+--+-- The problem with dynload is that it requires the plugin to export+-- a value that is a Dynamic (in our case a (TypeRep,a) pair). If this+-- is not the case, we core dump. Use pdynload if you don't trust the+-- user to supply you with a Dynamic+--+dynload :: Typeable a    +        => FilePath  +        -> [FilePath]+        -> [PackageConf]+        -> Symbol+        -> IO (LoadStatus a)++dynload obj incpaths pkgconfs sym = do+    s <- load obj incpaths pkgconfs sym+    case s of e@(LoadFailure _)   -> return e+              LoadSuccess m dyn_v -> return $+                    case fromDynamic (unsafeCoerce# dyn_v :: Dynamic) of+                        Just v' -> LoadSuccess m v'+                        Nothing -> LoadFailure ["Mismatched types in interface"]++------------------------------------------------------------------------+--+-- The super-replacement for dynload+--+-- Use GHC at runtime so we get staged type inference, providing full+-- power dynamics, *on module interfaces only*. This is quite suitable+-- for plugins, of coures :)+--+-- TODO where does the .hc file go in the call to build() ?+--++pdynload :: FilePath                    -- ^ object to load+         -> [FilePath]                  -- ^ include paths+         -> [PackageConf]               -- ^ package confs+         -> Type                        -- ^ API type+         -> Symbol                      -- ^ symbol+         -> IO (LoadStatus a)++pdynload object incpaths pkgconfs ty sym = do +#if DEBUG+        putStr "Checking types ... " >> hFlush stdout+#endif+        errors <- unify object incpaths [] ty sym+#if DEBUG+        putStrLn "done"+#endif+        if null errors +                then load object incpaths pkgconfs sym+                else return $ LoadFailure errors++--+-- | Like pdynload, but you can specify extra arguments to the+-- typechecker.+--+pdynload_ :: FilePath       -- ^ object to load+          -> [FilePath]     -- ^ include paths for loading+          -> [PackageConf]  -- ^ any extra package.conf files+          -> [Arg]          -- ^ extra arguments to ghc, when typechecking+          -> Type           -- ^ expected type+          -> Symbol         -- ^ symbol to load+          -> IO (LoadStatus a)++pdynload_ object incpaths pkgconfs args ty sym = do+#if DEBUG+        putStr "Checking types ... " >> hFlush stdout+#endif+        errors <- unify object incpaths args ty sym+#if DEBUG+        putStrLn "done"+#endif+        if null errors +                then load object incpaths pkgconfs sym+                else return $ LoadFailure errors++------------------------------------------------------------------------+-- run the typechecker over the constraint file+--+-- Problem: if the user depends on a non-auto package to build the+-- module, then that package will not be in scope when we try to build+-- the module, when performing `unify'. Normally make() will handle this+-- (as it takes extra ghc args). pdynload ignores these, atm -- but it+-- shouldn't. Consider a pdynload() that accepts extra -package flags?+--+-- Also, pdynload() should accept extra in-scope modules.+-- Maybe other stuff we want to hack in here.+--+unify :: FilePath -> [[Char]] -> [String] -> String -> String -> IO [String]+unify obj incs args ty sym = do+        (tmpf,hdl)   <- mkTemp+        (tmpf1,hdl1) <- mkTemp  -- and send .hi file here.+        hClose hdl1++        let nm  = mkModid (basename tmpf) +            src = mkTest nm (hierize' . mkModid . hierize $ obj)+                                (fst $ break (=='.') ty) ty sym+            is  = map ("-i"++) incs             -- api+            i   = "-i" ++ dirname obj           -- plugin++        hWrite hdl src++        e <- build tmpf tmpf1 (i:is++args++["-fno-code","-ohi "++tmpf1])+        mapM_ removeFile [tmpf,tmpf1]+        return e++        where+            -- fix up hierarchical names+            hierize []       = []+            hierize ('/':cs) = '\\' : hierize cs+            hierize (c:cs)   = c    : hierize cs++            hierize'[]        = []+            hierize' ('\\':cs) = '.' : hierize' cs+            hierize' (c:cs)   = c    : hierize' cs++mkTest :: String -> String -> String -> String -> String -> String+mkTest modnm plugin api ty sym = +       "module "++ modnm ++" where" +++       "\nimport qualified " ++ plugin  +++       "\nimport qualified " ++ api     +++       "{-# LINE 1 \"<typecheck>\" #-}" +++       "\n_ = "++ plugin ++"."++ sym ++" :: "++ty++------------------------------------------------------------------------+{-+--+-- old version that tried to rip stuff from .hi files+--+pdynload obj incpaths pkgconfs sym ty = do+        (m, v) <- load obj incpaths pkgconfs sym+        ty'    <- mungeIface sym obj+        if ty == ty' +                then return $ Just (m, v)+                else return Nothing             -- mismatched types++   where +        -- grab the iface output from GHC. find the line relevant to our+        -- symbol. grab the string rep of the type.+        mungeIface sym o = do+                let hi = replaceSuffix o hiSuf+                (out,_) <- exec ghc ["--show-iface", hi]+                case find (\s -> (sym ++ " :: ") `isPrefixOf` s) out of+                        Nothing -> return undefined+                        Just v  -> do let v' = drop 3 $ dropWhile (/= ':') v+                                      return v'++-}++{-+--+-- a version of load the also unwraps and types a Dynamic object+--+dynload2 :: Typeable a => +           FilePath -> +           FilePath -> +           Maybe [PackageConf] ->+           Symbol ->  +           IO (Module, a)++dynload2 obj incpath pkgconfs sym = do+        (m, v) <- load obj incpath pkgconfs sym+        case fromDynamic v of+            Nothing -> panic $ "load: couldn't type "++(show v)+            Just a  -> return (m,a)+-}++------------------------------------------------------------------------+--+-- | unload a module (not its dependencies)+-- we have the dependencies, so cascaded unloading is possible+--+-- once you unload it, you can't 'load' it again, you have to 'reload'+-- it. Cause we don't unload all the dependencies+--+unload  :: Module -> IO ()+unload m = rmModuleDeps m >> unloadObj m++------------------------------------------------------------------------+--+-- | unload a module and its dependencies+-- we have the dependencies, so cascaded unloading is possible+--+unloadAll :: Module -> IO ()+unloadAll m = do moduleDeps <- getModuleDeps m+                 rmModuleDeps m+                 mapM_ unloadAll moduleDeps+                 unload m+++--+-- | this will be nice for panTHeon, needs thinking about the interface+-- reload a single object file. don't care about depends, assume they+-- are loaded. (should use state to store all this)+--+-- assumes you've already done a 'load'+--+-- should factor the code+--+reload :: Module -> Symbol -> IO (LoadStatus a)+reload m@(Module{path = p, iface = hi}) sym = do+        unloadObj m     -- unload module (and delete)+#if DEBUG+        putStr ("Reloading "++(mname m)++" ... ") >> hFlush stdout+#endif+        m_ <- loadObject p . Object . ifaceModuleName $ hi   -- load object at path p+        let m' = m_ { iface = hi }+    +        resolveObjs (unloadAll m)+#if DEBUG+        putStrLn "done" >> hFlush stdout+#endif+        v <- loadFunction m' sym+        return $ case v of +                Nothing -> LoadFailure ["load: couldn't find symbol <<"++sym++">>"]+                Just a  -> LoadSuccess m' a+++++++--+-- This is a stripped-down version of Andre Pang's runtime_loader,+-- which in turn is based on GHC's ghci\/ObjLinker.lhs binding+--+--  Load and unload\/Haskell modules at runtime.  This is not really+--  \'dynamic loading\', as such -- that implies that you\'re working+--  with proper shared libraries, whereas this is far more simple and+--  only loads object files.  But it achieves the same goal: you can+--  load a Haskell module at runtime, load a function from it, and run+--  the function.  I have no idea if this works for types, but that+--  doesn\'t mean that you can\'t try it :).+--+-- read $fptools\/ghc\/compiler\/ghci\/ObjLinker.lhs for how to use this stuff+--+++-- | Call the initLinker function first, before calling any of the other+-- functions in this module - otherwise you\'ll get unresolved symbols.++-- initLinker :: IO ()+-- our initLinker transparently calls the one in GHC++++--+-- | This is a mid-level interface to the dynamic loader. A call to+-- 'loadObjectFile' imports a single object file into the caller's address,+-- space returning the 'Module' associated with it. Libraries and modules that+-- the requested module depends upon are loaded and linked in turn.+--+-- The first argument is the path to the object file to load, the second+-- argument is a list of directories to search for dependent modules.+-- The third argument is a list of paths to user-defined, but+-- unregistered, /package.conf/ files. +loadObjectFile :: FilePath       -- ^ object file+               -> [FilePath]     -- ^ any include paths+               -> [PackageConf]  -- ^ list of package.conf paths+               -> IO Module++loadObjectFile obj incpaths pkgconfs = do+    initLinker++    -- load extra package information+    mapM_ addPkgConf pkgconfs+    (hif,moduleDeps) <- loadDepends obj incpaths++    -- why is this the package name?+#if DEBUG+    putStr (' ':(decode $ ifaceModuleName hif)) >> hFlush stdout+#endif++    m' <- loadObject obj . Object . ifaceModuleName $ hif+    let m = m' { iface = hif }+    resolveObjs (mapM_ unloadAll (m:moduleDeps))++#if DEBUG+    putStrLn " ... done" >> hFlush stdout+#endif+    addModuleDeps m' moduleDeps+    return m+++--+-- | Load a function from a module (which must be loaded and resolved first).+--++loadFunction :: Module          -- ^ The module the value is in+             -> String          -- ^ Symbol name of value+             -> IO (Maybe a)    -- ^ The value you want+loadFunction (Module { iface = i }) valsym+    = loadFunction_ (ifaceModuleName i) valsym++loadFunction_ :: String+              -> String+              -> IO (Maybe a)+loadFunction_ = loadFunction__ Nothing++loadFunction__ :: Maybe String+              -> String+              -> String+              -> IO (Maybe a)+loadFunction__ pkg m valsym+   = do let symbol = prefixUnderscore++(maybe "" (\p -> encode p++"_") pkg)+                     ++encode m++"_"++(encode valsym)++"_closure"+#if DEBUG+        putStrLn $ "Looking for <<"++symbol++">>"+#endif+        ptr@(Ptr addr) <- withCString symbol c_lookupSymbol+        if (ptr == nullPtr)+            then return Nothing+            else case addrToHValue# addr of+                (# hval #) -> return ( Just hval )+++-- | Loads a function from a package module, given the package name,+--   module name and symbol name.+loadPackageFunction :: String -- ^ Package name, including version number.+                    -> String -- ^ Module name+                    -> String -- ^ Symbol to lookup in the module+                    -> IO (Maybe a)+loadPackageFunction pkgName modName functionName =+    do loadPackage pkgName+       resolveObjs (unloadPackage pkgName)+       loadFunction__ (Just pkgName) modName functionName++--+-- | Load a GHC-compiled Haskell vanilla object file.+-- The first arg is the path to the object file+--+-- We make it idempotent to stop the nasty problem of loading the same+-- .o twice. Also the rts is a very special package that is already+-- loaded, even if we ask it to be loaded. N.B. we should insert it in+-- the list of known packages.+--+-- NB the environment stores the *full path* to an object. So if you+-- want to know if a module is already loaded, you need to supply the+-- *path* to that object, not the name.+-- +-- NB -- let's try just the module name.+--+-- loadObject loads normal .o objs, and packages too. .o objs come with+-- a nice canonical Z-encoded modid. packages just have a simple name.+-- Do we want to ensure they won't clash? Probably.+--++--+-- the second argument to loadObject is a string to use as the unique+-- identifier for this object. For normal .o objects, it should be the+-- Z-encoded modid from the .hi file. For archives\/packages, we can+-- probably get away with the package name+--+++loadObject :: FilePath -> Key -> IO Module+loadObject p ky@(Object k)  = loadObject' p ky k +loadObject p ky@(Package k) = loadObject' p ky k ++loadObject' :: FilePath -> Key -> String -> IO Module+loadObject' p ky k+    | ("HSrts"++sysPkgSuffix) `isSuffixOf` p = return (emptyMod p)++    | otherwise +    = do alreadyLoaded <- isLoaded k+         when (not alreadyLoaded) $ do+              r <- withCString p c_loadObj+              when (not r) (panic $ "Could not load module `"++p++"'")+         addModule k (emptyMod p)   -- needs to Z-encode module name+         return (emptyMod p)++    where emptyMod q = Module q (mkModid q) Vanilla undefined ky++--+-- load a single object. no dependencies. You should know what you're+-- doing.+--+loadModule :: FilePath -> IO Module+loadModule obj = do+    let hifile = replaceSuffix obj hiSuf+    exists <- doesFileExist hifile+    if (not exists)+        then error $ "No .hi file found for "++show obj+        else do hiface <- readBinIface' hifile+                loadObject obj (Object (ifaceModuleName hiface))++--+-- | Load a generic .o file, good for loading C objects.+-- You should know what you're doing..+-- Returns a fairly meaningless iface value.+--+loadRawObject :: FilePath -> IO Module+loadRawObject obj = loadObject obj (Object k)+    where+        k = encode (mkModid obj)  -- Z-encoded module name++--+-- | Resolve (link) the modules loaded by the 'loadObject' function.+--+resolveObjs :: IO a -> IO ()+resolveObjs unloadLoaded+    = do r <- c_resolveObjs+         when (not r) $ unloadLoaded >> panic "resolvedObjs failed."+++-- | Unload a module+unloadObj :: Module -> IO () +unloadObj (Module { path = p, kind = k, key = ky }) = case k of+        Vanilla -> withCString p $ \c_p -> do+                removed <- rmModule name+                when (removed) $ do r <- c_unloadObj c_p +                                    when (not r) (panic "unloadObj: failed")+        Shared  -> return () -- can't unload .so?+    where name = case ky of Object s -> s ; Package pk -> pk+--+-- | from ghci\/ObjLinker.c+--+-- Load a .so type object file.+--+loadShared :: FilePath -> IO Module+loadShared str = do+#if DEBUG+    putStrLn $ " shared: " ++ str+#endif+    maybe_errmsg <- withCString str $ \dll -> c_addDLL dll+    if maybe_errmsg == nullPtr +        then return (Module str (mkModid str) Shared undefined (Package (mkModid str)))+        else do e <- peekCString maybe_errmsg+                panic $ "loadShared: couldn't load `"++str++"\' because "++e+++--+-- Load a -package that we might need, implicitly loading the cbits too+-- The argument is the name of package (e.g.  \"concurrent\")+--+-- How to find a package is determined by the package.conf info we store+-- in the environment. It is just a matter of looking it up.+--+-- Not printing names of dependent pkgs+--+loadPackage :: String -> IO ()+loadPackage p = do+#if DEBUG+        putStr (' ':p) >> hFlush stdout+#endif+        (libs,dlls) <- lookupPkg p+        mapM_ (\l -> loadObject l (Package (mkModid l))) libs+#if DEBUG+        putStr (' ':show libs) >> hFlush stdout+        putStr (' ':show dlls) >> hFlush stdout+#endif+        mapM_ loadShared dlls++++--+-- Unload a -package, that has already been loaded. Unload the cbits+-- too. The argument is the name of the package.+--+-- May need to check if it exists.+--+-- Note that we currently need to unload everything. grumble grumble.+--+-- We need to add the version number to the package name with 6.4 and+-- over. "yi-0.1" for example. This is a bug really.+--+unloadPackage :: String -> IO ()+unloadPackage pkg = do+    let pkg' = takeWhile (/= '-') pkg   -- in case of *-0.1+    libs <- liftM (\(a,_) -> (filter (isSublistOf pkg') ) a) (lookupPkg pkg)+    flip mapM_ libs $ \p -> withCString p $ \c_p -> do+                        r <- c_unloadObj c_p +                        when (not r) (panic "unloadObj: failed")+                        rmModule (mkModid p)      -- unrecord this module ++--+-- load a package using the given package.conf to help+-- TODO should report if it doesn't actually load the package, instead+-- of mapM_ doing nothing like above.+--+loadPackageWith :: String -> [PackageConf] -> IO ()+loadPackageWith p pkgconfs = do+#if DEBUG+        putStr "Loading package" >> hFlush stdout+#endif+        mapM_ addPkgConf pkgconfs+        loadPackage p+#if DEBUG+        putStrLn " done"+#endif+        ++-- ---------------------------------------------------------------------+-- module dependency loading+--+-- given an Foo.o vanilla object file, supposed to be a plugin compiled+-- by our library, find the associated .hi file. If this is found, load+-- the dependencies, packages first, then the modules. If it doesn't+-- exist, assume the user knows what they are doing and continue. The+-- linker will crash on them anyway. Second argument is any include+-- paths to search in+--+-- ToDo problem with absolute and relative paths, and different forms of+-- relative paths. A user may cause a dependency to be loaded, which+-- will search the incpaths, and perhaps find "./Foo.o". The user may+-- then explicitly load "Foo.o". These are the same, and the loader+-- should ignore the second load request. However, isLoaded will say+-- that "Foo.o" is not loaded, as the full string is used as a key to+-- the modenv fm. We need a canonical form for the keys -- is basename+-- good enough?+--+loadDepends :: FilePath -> [FilePath] -> IO (ModIface,[Module])+loadDepends obj incpaths = do+    let hifile = replaceSuffix obj hiSuf+    exists <- doesFileExist hifile+    if (not exists)+        then do+#if DEBUG+                putStrLn "No .hi file found." >> hFlush stdout+#endif+                return (undefined,[])   -- could be considered fatal++        else do hiface <- readBinIface' hifile+                let ds = mi_deps hiface++                -- remove ones that we've already loaded+                ds' <- filterM loaded . map (moduleNameString . fst) . dep_mods $ ds++                -- now, try to generate a path to the actual .o file+                -- fix up hierachical names+                let mods_ = map (\s -> (s, map (\c -> +                        if c == '.' then '/' else c) $ s)) ds'++                -- construct a list of possible dependent modules to load+                let mods = concatMap (\p -> +                            map (\(hi,m) -> (hi,p </> m++".o")) mods_) incpaths++                -- remove modules that don't exist+                mods' <- filterM (\(_,y) -> doesFileExist y) $+                                nubBy (\v u -> snd v == snd u)  mods++                -- now remove duplicate valid paths to the same object+                let mods'' = nubBy (\v u -> fst v == fst u)  mods'++                -- and find some packages to load, as well.+                let ps = dep_pkgs ds+                ps' <- filterM loaded . map packageIdString . nub $ ps++#if DEBUG+                when (not (null ps')) $+                        putStr "Loading package" >> hFlush stdout+#endif+                mapM_ loadPackage ps'+#if DEBUG+                when (not (null ps')) $+                        putStr " ... linking ... " >> hFlush stdout+#endif+                resolveObjs (mapM_ unloadPackage ps')+#if DEBUG+                when (not (null ps')) $ putStrLn "done" +                putStr "Loading object" +                mapM_ (\(m,_) -> putStr (" "++ m) >> hFlush stdout) mods''+#endif+                moduleDeps <- mapM (\(hi,m) -> loadObject m (Object hi)) mods''+                return (hiface,moduleDeps)++-- ---------------------------------------------------------------------+-- Nice interface to .hi parser+--+getImports :: String -> IO [String]+getImports m = do+        hi <- readBinIface' (m ++ hiSuf)+        return . map (moduleNameString . fst) . dep_mods . mi_deps $ hi++-- ---------------------------------------------------------------------+-- C interface+--+foreign import ccall safe "lookupSymbol"+   c_lookupSymbol :: CString -> IO (Ptr a)++foreign import ccall unsafe "loadObj"+   c_loadObj :: CString -> IO Bool++foreign import ccall unsafe "unloadObj"+   c_unloadObj :: CString -> IO Bool++foreign import ccall unsafe "resolveObjs"+   c_resolveObjs :: IO Bool++foreign import ccall unsafe "addDLL"+   c_addDLL :: CString -> IO CString++foreign import ccall unsafe "initLinker"+   initLinker :: IO ()
+ src/Barley/Loader.hs view
@@ -0,0 +1,123 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Barley.Loader (+    EntryPoint(),+    entryPoint,+    +    compileAndLoadFirst,+    )+    where++import Barley.AltLoad -- instead of System.Plugins.Load+import Control.Monad (when)+import Data.IORef+import qualified Data.Map as M+import System.Directory (createDirectoryIfMissing)+import System.IO.Unsafe (unsafePerformIO)+import System.Plugins.Make+import System.Plugins.Utils (newer)++++-- | An representation of a possible entry point in a file that, when+-- loaded, run, returns an a value of type a+newtype EntryPoint a = EntryPoint { loadEntryPoint :: Module -> IO (Maybe a) }++-- | Builds an entry point. The entry point is named with the given symbol+-- and returns a value of type a. The supplied transformer function is used+-- to supply a value of some type b. This is so that all entry points can+-- return the same type.+entryPoint :: String -> (a -> b) -> EntryPoint b+entryPoint symbol xform = EntryPoint (loadWith symbol xform)+++-- | A mapping between source files and the module objects that are loaded+-- While System.Plugins should keep this information, it doesn't, so we have to.+type ModuleMap = M.Map FilePath Module++theModMap :: IORef ModuleMap+theModMap = unsafePerformIO $ newIORef M.empty+{-# NOINLINE theModMap #-}+++-- | Given a file, try to make sure it is built and up-to-date+-- Can't use recompileAll here because it "hunts" for the source files (rather+-- than having Module remember them), and we store the objects in a different+-- directory than the sources. Hence, our test doesn't recursively look at+-- dependent modules. Fie!+compileModule :: FilePath -> IO (Either String Module)+compileModule srcFile = do+    mm <- readIORef theModMap+    let existingModule = M.lookup srcFile mm+    +    needBuild <- case existingModule of+        Just m -> srcFile `newer` path m+        Nothing -> return True        +    makeStatus <- case (needBuild, existingModule) of+        (False, Just m) -> return (MakeSuccess NotReq $ path m)+        _ -> noteMakeAll >> makeAll srcFile makeArgs++    case (makeStatus, existingModule) of+        (MakeSuccess NotReq _, _     ) -> return ()+        (_                   , Just m) -> noteUnloadAll >> unloadAll m+        (_                   , _     ) -> return ()+    +    case (makeStatus, existingModule) of+        (MakeFailure errs, _) -> do+            noteFailure errs+            writeIORef theModMap (M.delete srcFile mm)+            return $ Left $ unlines errs+        (MakeSuccess NotReq _, Just m) -> do+            noteNothing+            return (Right m)+        (MakeSuccess _ objFile, _) -> do+            noteLoading+            m <- loadObjectFile objFile [buildDir] []+            writeIORef theModMap (M.insert srcFile m mm)+            return (Right m)+  where+    buildDir = ".build"+    makeArgs =      +        [ "-ilib" -- users can put non-served source here +        , "-outputdir", buildDir -- sets odir, hidir, and stubdir in one go+        , "-odir", buildDir -- plugins only looks for odir, not outputdir+        ]+        +    debug = False+    noteMakeAll      = when debug $ putStrLn ("makeAll of " ++ srcFile)+    noteUnloadAll    = when debug $ putStrLn "unloading..."+    noteFailure errs = when debug $ putStrLn ("failed: " ++ concat errs)+    noteNothing      = when debug $ putStrLn "nothin' to do"+    noteLoading      = when debug $ putStrLn "loading..."+    ++-- | Given a file, compile and load the file, then load the value from the+-- first entry point that succeeds (Right). If either the compilation fails,+-- or the the loading fails, then an error string is returned (Left).+compileAndLoadFirst :: FilePath -> [EntryPoint a] -> IO (Either String a)+compileAndLoadFirst srcFile eps = do+    createDirectoryIfMissing False ".build" -- plugins needs it to pre-exist+    cs <- compileModule srcFile+    case cs of+        Right m -> tryEntryPoints m eps+        Left errs -> return $ Left errs++tryEntryPoints :: Module -> [EntryPoint a] -> IO (Either String a)+tryEntryPoints m (ep:eps) =+    loadEntryPoint ep m >>= maybe (tryEntryPoints m eps) (return . Right)+tryEntryPoints _ [] = return (Left "No matching entry points found.")++loadWith :: String -> (a -> b) -> Module -> IO (Maybe b)+loadWith sym xfn m = (xfn `fmap`) `fmap` loadFunction m sym
+ src/Barley/Project.hs view
@@ -0,0 +1,126 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Barley.Project+    ( ProjectDir(..)+    , enter+    , init+    ) where++import Control.Monad (unless, when)+import Paths_barley -- generated by cabal+import Prelude hiding (init)+import System.Directory+import System.Exit+import System.FilePath++-- | A specification of a project directory+data ProjectDir = CurrentDir | ProjectDir FilePath++projectPath :: ProjectDir -> FilePath+projectPath CurrentDir = "."  -- FIXME: The use of "." is probably not right+projectPath (ProjectDir fp) = fp+    +-- | The presence of this file indicates a directory is a barley project.+-- In the future we might store information in it.+markerFile :: FilePath+markerFile = ".barley-project"++-- | Change into the project directory.+-- Fails if the directory can't be entered.+enter :: ProjectDir -> IO ()+enter projectDir = do+    exists <- case projectDir of+        CurrentDir -> return True+        ProjectDir fp -> doesDirectoryExist fp+    unless exists $+        putStrLn ("Project directory doesn't exist: " ++ pdPath) >>+        exitFailure+    hasMarker <- doesFileExist (pdPath </> markerFile)+    unless hasMarker $+        putStrLn "Directory doesn't appear to be a Barely project." >>+        putStrLn ("Missing .barley-project file in directory: " ++ pdPath) >>+        exitFailure+    case projectDir of+        CurrentDir -> return ()+        ProjectDir fp -> setCurrentDirectory fp+  where+    pdPath = projectPath projectDir++-- | Create a project directory structure.+init :: Bool -> ProjectDir -> IO ()+init warnIfNotEmpty projectDir = nothingHere >>= \b -> if b+    then copyInitialProject projectDir+    else when warnIfNotEmpty $+        putStrLn "** This directory is not empty. Not initializing."+  where+    nothingHere = whatsHere >>= return . null . filter notDot+    whatsHere = case projectDir of+        CurrentDir -> getCurrentDirectory >>= getDirectoryContents +        ProjectDir fp -> do+            exists <- doesDirectoryExist fp+            if exists+                then getDirectoryContents fp+                else return []+    notDot ('.':_) = False+    notDot _ = True++-- | Copy the initial project skeleton to the project directory.+copyInitialProject :: ProjectDir -> IO ()+copyInitialProject projectDir = do+    fromDir <- getSeedDir+    let toDir = projectPath projectDir+    putStrLn "Creating default project files..."+    copyTree fromDir toDir+    writeFile (toDir </> markerFile) ""+    putStrLn "...done."++-- | Locate seed dir in current dir, or data dir, or if neither, fail.+getSeedDir :: IO FilePath+getSeedDir = findFirstSeed [ getCurrentDirectory, getDataDir ]+  where+    findFirstSeed (g:gs) = do+        s <- g >>= return . (</> "seed")+        exists <- doesDirectoryExist s+        if exists+            then return s+            else findFirstSeed gs+    findFirstSeed [] = do+        putStrLn "** No seed directory found."+        putStrLn "** You should try reinstalling Barley."+        exitFailure++-- | Copy a directory tree from one place to another. The destination, or+-- the subtrees needn't exist. If they do, existing files with the same names+-- as the source will be overwritten. Other files will be left alone.+copyTree :: FilePath -> FilePath -> IO ()+copyTree from to = pick+    [(doesFileExist,        doFile),+     (doesDirectoryExist,   doDir)]+  where+    pick ((test, act):rest) = do+        bool <- test from+        if bool+            then putStrLn ("   " ++ to) >> act+            else pick rest+    pick [] =+        putStrLn $ "** Skipping funny thing in skeleton tree: " ++ from++    doFile = copyFile from to +    doDir = do+        createDirectoryIfMissing False to+        getDirectoryContents from >>= mapM_ dive . filter notSpecial+        +    dive item = copyTree (from </> item) (to </> item)+    notSpecial item = item /= "." && item /= ".."
+ src/Barley/Utils.hs view
@@ -0,0 +1,125 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Barley.Utils (+    -- File Utilties+    legalPath,+    +    -- Snap Utilities+    finish,+    routeWhen, routeWhenIO,++    finishWithError,+    errorBadRequest, errorForbidden, errorNotFound, errorMethodNotAllowed,+    +    processModificationTime,+    ) where++import Control.Monad (unless, when)+import Control.Monad.IO.Class+import qualified Data.ByteString.Char8 as C+import Data.CIByteString (toCI)+import Snap.Types+import System.FilePath (joinPath, splitDirectories)+import System.Posix.Time (epochTime)+import System.Posix.Types (EpochTime)++-- | Sanitize a file path for serving.+-- If the path contains any illegal path components, then Nothing is returned.+-- Otherwise a new FilePath, built from the dissected components is returned.+--+-- Illegal path components are any that start with a period, including "." and+-- "..", as well as those that contain any of '/', '\', or ':', or are empty.+legalPath :: FilePath -> Maybe FilePath+legalPath p =+    if any illegalComponent components+        then Nothing+        else Just $ joinPath components+  where+    components = splitDirectories p+    illegalComponent "" = True+    illegalComponent ('.':_) = True+    illegalComponent s = any (`elem` "/\\:") s +++--+-- These should be in Snap+--++-- | Immediately exit with what ever response was set in the Snap monad.+finish :: Snap a+finish = getResponse >>= finishWith    ++-- | If the test is true, then finish immediately with the given action.+routeWhen :: Bool -> Snap () -> Snap ()+routeWhen f act = if f then act >> finish else return ()++-- | Like routeWhen, but test is provided in the IO monad.+routeWhenIO :: IO Bool -> Snap () -> Snap ()+routeWhenIO fio act = do+    f <- liftIO fio+    if f then act else return ()+++-- | Immediately finish with an HTTP error status+finishWithError :: Int -> String -> Snap ()+finishWithError status message =+    finishWith $ setResponseStatus status (C.pack message) emptyResponse++-- | Common HTTP error statuses+errorBadRequest, errorForbidden, errorNotFound, errorMethodNotAllowed :: Snap ()+errorBadRequest = finishWithError 400 "Bad Request"+errorForbidden = finishWithError 403 "Forbidden"+errorNotFound = finishWithError 404 "Not Found"+errorMethodNotAllowed = finishWithError 405 "Method Not Allowed"+++-- | Process requests for resources that have a known modification time and+-- optional maximum age. Note: This may finish processing if the request+-- includes validators that can be satisfied.++processModificationTime :: EpochTime -> Maybe Int -> Snap ()+processModificationTime modTime maxAge = do+    req <- getRequest+    maybeM_ validateIfModifiedSince $ (getHeader (toCI $ C.pack "If-Modified-Since")) req+    maybeM_ validateIfUnmodifiedSince $ (getHeader (toCI $ C.pack "If-Unmodified-Since")) req++    modTimeS <- liftIO $ formatHttpTime modTime+    modifyResponse $ setHeader (toCI $ C.pack "Last-Modified") modTimeS++    maybeM_ setCacheControlMaxAge maxAge+    maybeM_ setExpires maxAge+  where+    validateIfModifiedSince ims = do+        imsTime <- liftIO $ parseHttpTime ims+        unless (modTime > imsTime) $ do+            modifyResponse clearContentLength+            finishWithError 304 "Not Modified"+    validateIfUnmodifiedSince ius = do+        iusTime <- liftIO $ parseHttpTime ius+        when (modTime > iusTime) $ do+            modifyResponse clearContentLength+            finishWithError 412 "Precondition Failed"+    setCacheControlMaxAge ma =+        modifyResponse $ setHeader (toCI $ C.pack "Cache-Control")+            (C.pack $ "max-age=" ++ show ma)+    setExpires ma = do+        now <- liftIO $ epochTime+        expTimeS <- liftIO $ formatHttpTime (now + fromIntegral ma)+        modifyResponse $ setHeader (toCI $ C.pack "Expires") expTimeS++maybeM_ :: (Monad m) => (a -> m ()) -> Maybe a -> m ()+maybeM_ = maybe (return ())  +    +    
+ src/Main.hs view
@@ -0,0 +1,186 @@+-- Copyright 2010 Google Inc.+-- +-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+-- +--      http://www.apache.org/licenses/LICENSE-2.0+-- +-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++module Main (main) where++import Barley.Loader+import Barley.Project+import Barley.Utils+import Control.Monad.IO.Class+import qualified Data.ByteString.Char8 as C+import qualified Data.Map as M+import Data.Maybe+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import Prelude hiding (init, mod)+import Snap.Http.Server+import Snap.Types+import System.Directory (doesDirectoryExist, doesFileExist,+            getCurrentDirectory)+import System.Environment+import System.Exit+import System.FilePath ((<.>), (</>), takeExtension)+import System.Posix.Files (getFileStatus, modificationTime)+import Text.Html hiding ((</>), address, content, start)++main :: IO ()+main = do+    args <- parseArgs+    case args of+        Just ("start", pd) -> start pd+        Just ("init", pd) -> init True pd+        Just ("run", pd) -> run pd+        Just (cmd, _) -> do putStrLn $ "unknown command: " ++ cmd+                            exitFailure+        Nothing -> do putStrLn "Usage: barley <command> [project dir]"+                      exitFailure++parseArgs :: IO (Maybe (String, ProjectDir))+parseArgs = do+    args <- getArgs+    case args of+        [] -> return Nothing+        [cmd] -> return $ Just (cmd, CurrentDir)+        [cmd,fp] -> return $ Just (cmd, ProjectDir fp)+        _ -> putStrLn "Too many arguments." >> return Nothing++-- | Create a project directory structure and run the web server.+start :: ProjectDir -> IO ()+start pd = init False pd >> run pd++-- | Run the web server.+run :: ProjectDir -> IO ()+run pd = do+    enter pd+    let address = "*"+        port = 8080+        config = foldr ($) emptyConfig+            [ addListen (ListenHttp (C.pack address) port)+            , setAccessLog (Just "access.log")+            , setErrorLog (Just "error.log")+            ]+    putStrLn $ "Running on http://localhost:" ++ show port ++ "/"+    httpServe config genericHandler+++type CompiledTemplate = Either String (Snap ())+-- | Compile a template to either an error string, or a Snap action+compileTemplate :: FilePath -> IO CompiledTemplate+compileTemplate filename = compileAndLoadFirst filename templateEntryPoints+  where+    templateEntryPoints =+        [ entryPoint "handler" id+        , entryPoint "page" htmlResult+        , entryPoint "output" stringResult+        ]+  +-- | Run a compiled template as a Snap action.+runTemplate :: FilePath -> CompiledTemplate -> Snap ()+runTemplate filename compilation = do+    either errorResult id $ compilation+  where+    errorResult errs = liftIO (errorHtml errs filename) >>= htmlResult++htmlResult :: Html -> Snap ()+htmlResult html = do+    modifyResponse $ setContentType (C.pack "text/html; charset=UTF-8")+    writeBS $ (T.encodeUtf8 . T.pack) $ renderHtml html+        -- warning: renderHTML wraps an additional HTML element around the+        -- content (for some ungodly reason)++stringResult :: String -> Snap ()+stringResult s = do+    modifyResponse $ setContentType (C.pack "text/plain; charset=UTF-8")+    writeBS $ (T.encodeUtf8 . T.pack) s++serveTemplate :: FilePath -> Snap ()+serveTemplate filename = do+    compilation <- liftIO $ compileTemplate filename+    compileOnly <- getParam (C.pack "__compile_only")+    case C.unpack `fmap` compileOnly of+        Just c | c == "1"  -> stringResult $ either id (const "OK") compilation+               | otherwise -> errorBadRequest+        Nothing            -> runTemplate filename compilation++data TypeInfo = TI { tiMimeType :: String, tiMaxAge :: Maybe Int }++extToTypeInfo :: M.Map String TypeInfo+extToTypeInfo = M.fromList+    [ (".css",  srcType "text/css")+    , (".gif",  imgType "image/gif")+    , (".html", srcType "text/html")+    , (".jpeg", imgType "image/jpeg")+    , (".jpg",  imgType "image/jpeg")+    , (".js",   srcType "application/javascript")+    , (".json", srcType "application/json")+    , (".pdf",  imgType "application/pdf")+    , (".png",  imgType "image/png")+    , (".svg",  imgType "image/svg+xml")+    , (".txt",  srcType "text/plain")+    , (".xhtml",srcType "application/xhtml+xml")+    , (".xml",  srcType "application/xml")+    ]+  where+    srcType s = TI s (Just 30)   -- revalidate things we might edit every 30 seconds+    imgType s = TI s (Just 3600) -- images are stable for at least an hour++defTypeInfo :: TypeInfo+defTypeInfo = TI "application/octet-stream" Nothing++serveStatic :: FilePath -> Snap ()+serveStatic filename = do+    fstat <- liftIO $ getFileStatus filename+    processModificationTime (modificationTime fstat) (tiMaxAge typeInfo)+    modifyResponse $ setContentType (C.pack $ tiMimeType typeInfo)+    sendFile filename+  where+    typeInfo = M.findWithDefault defTypeInfo extension extToTypeInfo+    extension = takeExtension filename++        +-- | Given a URL, render the corresponding template.+genericHandler :: Snap ()+genericHandler = do+    mpath <- (legalPath . C.unpack . rqPathInfo) `fmap` getRequest+    case mpath of+        Nothing -> errorNotFound+        Just relpath -> do+            cwd <- liftIO getCurrentDirectory+            let fullpath = cwd </> relpath+            routeWhenIO (doesFileExist fullpath)      $ serveStatic fullpath+            routeWhenIO (doesDirectoryExist fullpath) $ serveIndex fullpath+            serveTemplateIfExists $ fullpath <.> "hs"+  where+    serveIndex :: FilePath -> Snap ()+    serveIndex fullpath = serveTemplateIfExists $ fullpath </> "index.hs"+    serveTemplateIfExists :: FilePath -> Snap ()+    serveTemplateIfExists tmplpath = do+        routeWhenIO (doesFileExist tmplpath) $ serveTemplate tmplpath++-- | Given a list of errors and a template, create an HTML page that+-- displays the errors.+errorHtml :: String -> FilePath -> IO Html+errorHtml errs filename = do+    content <- readFile filename+    length content `seq` return ()+    let html = thehtml <<+               body << [+                   thediv ! [theclass "errors"] << [+                        h2 << "Errors",+                        pre << errs+                        ],+                   pre ! [theclass "sourcefile"] << content+               ]+    return html+