diff --git a/README.md b/README.md index 0c53eb79..d8e55e8f 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ formats and allowed extensions is: * Textile: .textile * RDoc: .rdoc * Org Mode: .org + * Creole: .creole * ReStructured Text: .rest.txt, .rst.txt, .rest, .rst * ASCIIDoc: .asciidoc * POD: .pod @@ -69,10 +70,10 @@ or JavaScript. These tags will be stripped from the converted HTML. To link to another Gollum wiki page, use the Gollum Page Link Tag. - [[Frodo]] + [[Frodo Baggins]] The above tag will create a link to the corresponding page file named -`Frodo.ext` where `ext` may be any of the allowed extension types. The +`Frodo-Baggins.ext` where `ext` may be any of the allowed extension types. The conversion is as follows: 1. Replace any spaces (U+0020) with dashes (U+002D) @@ -230,6 +231,10 @@ Initialize the Gollum::Repo object: wiki = Gollum::Wiki.new("my-gollum-repo.git") # => +By default, internal wiki links are all absolute from the root. To specify a different base path, you can send specify the `:base_path` option: + + wiki = Gollum::Wiki.new("my-gollum-repo.git", :base_path => "/wiki") + Get the latest version of the given human or canonical page name: page = wiki.page('page-name') diff --git a/gollum.gemspec b/gollum.gemspec index 62c84760..08022da7 100644 --- a/gollum.gemspec +++ b/gollum.gemspec @@ -24,7 +24,11 @@ Gem::Specification.new do |s| s.extra_rdoc_files = %w[README.md LICENSE] s.add_dependency('grit', [">= 2.0.0", "< 3.0.0"]) + s.add_dependency('github-markup', [">= 0.4.0", "< 1.0.0"]) s.add_dependency('albino', "~> 1.0.0") + s.add_dependency('sinatra', "~> 1.0.0") + s.add_dependency('mustache', [">= 0.11.2", "< 1.0.0"]) + s.add_dependency('sanitize', "~> 1.0.0") s.add_development_dependency('shoulda') s.add_development_dependency('mocha') diff --git a/lib/gollum.rb b/lib/gollum.rb index 77064832..390b778e 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -1,6 +1,7 @@ # external require 'grit' require 'github/markup' +require 'sanitize' # internal require 'gollum/pagination' @@ -12,4 +13,43 @@ require 'gollum/albino' module Gollum VERSION = '0.0.1' -end \ No newline at end of file + + SANITIZATION_OPTIONS = { + :elements => [ + 'a', 'abbr', 'acronym', 'address', 'area', 'b', 'big', + 'blockquote', 'br', 'button', 'caption', 'center', 'cite', + 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', + 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'form', 'h1', + 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input', + 'ins', 'kbd', 'label', 'legend', 'li', 'map', 'menu', + 'ol', 'optgroup', 'option', 'p', 'pre', 'q', 's', 'samp', + 'select', 'small', 'span', 'strike', 'strong', 'sub', + 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', + 'thead', 'tr', 'tt', 'u', 'ul', 'var' + ], + :attributes => { + :all => ['abbr', 'accept', 'accept-charset', + 'accesskey', 'action', 'align', 'alt', 'axis', + 'border', 'cellpadding', 'cellspacing', 'char', + 'charoff', 'charset', 'checked', 'cite', + 'class', 'clear', 'cols', 'colspan', 'color', + 'compact', 'coords', 'datetime', 'dir', + 'disabled', 'enctype', 'for', 'frame', + 'headers', 'height', 'href', 'hreflang', + 'hspace', 'id', 'ismap', 'label', 'lang', + 'longdesc', 'maxlength', 'media', 'method', + 'multiple', 'name', 'nohref', 'noshade', + 'nowrap', 'prompt', 'readonly', 'rel', 'rev', + 'rows', 'rowspan', 'rules', 'scope', + 'selected', 'shape', 'size', 'span', 'src', + 'start', 'summary', 'tabindex', 'target', + 'title', 'type', 'usemap', 'valign', 'value', + 'vspace', 'width'] + }, + :protocols => { + 'a' => {'href' => ['http', 'https', 'mailto', :relative]}, + 'img' => {'href' => ['http', 'https', :relative]} + } + } +end + diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb new file mode 100644 index 00000000..12707337 --- /dev/null +++ b/lib/gollum/frontend/app.rb @@ -0,0 +1,110 @@ +require 'rubygems' + +require 'sinatra' +require 'gollum' +require 'mustache/sinatra' + +require 'gollum/frontend/views/layout' + +$path = "~/dev/sandbox/lotr2" + +module Precious + class App < Sinatra::Base + register Mustache::Sinatra + + dir = File.dirname(File.expand_path(__FILE__)) + + # We want to serve public assets for now + set :public, "#{dir}/public" + set :static, true + + set :mustache, { + # Tell mustache where the Views constant lives + :namespace => Precious, + + # Mustache templates live here + :templates => "#{dir}/templates", + + # Tell mustache where the views are + :views => "#{dir}/views" + } + + # Sinatra error handling + configure :development, :staging do + set :raise_errors, false + set :show_exceptions, true + set :dump_errors, true + set :clean_trace, false + end + + get '/' do + show_page_or_file('Home') + end + + get '/edit/:name' do + @name = params[:name] + wiki = Gollum::Wiki.new($path) + if page = wiki.page(@name) + @content = page.raw_data + mustache :edit + else + mustache :create + end + end + + post '/edit/:name' do + name = params[:name] + wiki = Gollum::Wiki.new($path) + page = wiki.page(name) + commit = { :message => 'commit message', + :name => 'Tom Preston-Werner', + :email => 'tom@github.com' } + wiki.update_page(page, params[:content], commit) + redirect "/#{name}" + end + + post '/create/:page' do + page = params[:page] + wiki = Gollum::Wiki.new($path) + commit = { :message => 'commit message', + :name => 'Tom Preston-Werner', + :email => 'tom@github.com' } + wiki.write_page(page, :markdown, params[:content], commit) + redirect "/#{page}" + end + + get %r{/(.+?)/([0-9a-f]{40})} do + name = params[:captures][0] + wiki = Gollum::Wiki.new($path) + if page = wiki.page(name, params[:captures][1]) + @page = page + @name = name + @content = page.formatted_data + mustache :page + else + halt 404 + end + end + + get '/*' do + show_page_or_file(params[:splat].first) + end + + def show_page_or_file(name) + wiki = Gollum::Wiki.new($path) + if page = wiki.page(name) + @page = page + @name = name + @content = page.formatted_data + mustache :page + elsif file = wiki.file(name) + file.raw_data + else + @name = name + mustache :create + end + end + end +end + +Precious::App.run! diff --git a/lib/gollum/frontend/public/css/global.css b/lib/gollum/frontend/public/css/global.css new file mode 100644 index 00000000..ad11ea44 --- /dev/null +++ b/lib/gollum/frontend/public/css/global.css @@ -0,0 +1,123 @@ +h1, h2, h3, h4, h5, h6 { + color: #f90; + font-weight: bold; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +h1 { + font-size: 36pt; +} + +h2 { + font-size: 32pt; +} + +h3 { + font-size: 28pt; +} + +h4 { + font-size: 24pt; +} + +h5 { + font-size: 20pt; +} + +h6 { + font-size: 16pt; +} + +p { + font-family: Georgia, serif; + font-size: 14pt; + line-height: 22pt; +} + +.highlight { + border: 1px solid #eee; + padding: 0; + margin: 0; + font-size: 12pt; +} + +.highlight pre { + background-color: #f8f8ff; + margin: 0; + padding: .5em; +} + +#nav { + width: 60em; + margin: 0 auto; + color: #666; +} + +#content { + width: 60em; + margin: 0 auto; + color: #666; +} + +a.absent { + color: #a00; +} + +/* Forms */ + +textarea { + width: 100%; + height: 20em; +} + +/* Images */ + +.frame { + margin: 1em 0; + display: inline-block; +} + +.frame img { + display: block; +} + +.frame > span { + display: block; + border: 1px solid #aaa; + padding: 4px; +} + +.frame span span { + display: block; + font-size: 10pt; + margin: 0; + padding: 4px 0 2px 0; + text-align: center; + line-height: 10pt; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +.float-left { + float: left; + padding: .5em 1em .25em 0; +} + +.float-right { + float: right; + padding: .5em 0 .25em 1em; +} + +.align-left { + display: block; + text-align: left; +} + +.align-center { + display: block; + text-align: center; +} + +.align-right { + display: block; + text-align: right; +} \ No newline at end of file diff --git a/lib/gollum/frontend/public/css/gollum.css b/lib/gollum/frontend/public/css/gollum.css new file mode 100644 index 00000000..e594530e --- /dev/null +++ b/lib/gollum/frontend/public/css/gollum.css @@ -0,0 +1,55 @@ +a.absent { + color: #a00; +} + +/* Images */ + +.frame { + margin: 0; + display: inline-block; +} + +.frame img { + display: block; +} + +.frame > span { + display: block; + border: 1px solid #aaa; + padding: 4px; +} + +.frame span span { + display: block; + font-size: 10pt; + margin: 0; + padding: 4px 0 2px 0; + text-align: center; + line-height: 10pt; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +.float-left { + float: left; + padding: .5em 1em .25em 0; +} + +.float-right { + float: right; + padding: .5em 0 .25em 1em; +} + +.align-left { + display: block; + text-align: left; +} + +.align-center { + display: block; + text-align: center; +} + +.align-right { + display: block; + text-align: right; +} \ No newline at end of file diff --git a/lib/gollum/frontend/public/css/screen.css b/lib/gollum/frontend/public/css/screen.css new file mode 100644 index 00000000..dd9dd232 --- /dev/null +++ b/lib/gollum/frontend/public/css/screen.css @@ -0,0 +1,345 @@ +/****************************************************************************/ +/* Base +/****************************************************************************/ + +* { + margin: 0; + padding: 0; +} + +html, body { + height: 100%; + color: black; +} + +body { + background-color: white; + font: 13.34px helvetica, arial, freesans, clean, sans-serif; + *font-size: small; +} + +table { + font-size: inherit; + font: 100%; +} + +select, input[type=text], input[type=password], input[type=image], textarea { + font: 99% helvetica, arial, freesans, sans-serif; +} +select, option { + padding: 0 .25em; +} +optgroup { + margin-top: .5em; +} + +input.text { + padding: 1px 0; +} +pre, code { + font: 12px Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; +} + +body * { + line-height: 1.4em; +} + +p{ margin:1em 0; } + +img { + border: 0; +} + +abbr { + border-bottom: none; +} + +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +* html .clearfix {height: 1%;} +.clearfix {display:inline-block;} +.clearfix {display: block;} + +/* always show vertical scroll bar to prevent page jitter */ +html {overflow-y: scroll;} + +.site { + margin: 2em auto 0 auto; + width: 920px; + padding: 0 15px; +} + +/****************************************************************************/ +/* Guides +/****************************************************************************/ + +#guides { + +} + + /* index */ + + #guides .index { + + } + + #guides h1 { + margin-bottom: .5em; + } + + #guides .index ul { + list-style-type: none; + font-size: 120%; + } + + #guides .index ul li { + padding-left: 1.5em; + background: white url(/images/modules/guides/book.png) no-repeat; + } + + #guides .index .new { + margin-top: 1em; + border-top: 1px solid #ccc; + padding-top: .5em; + } + + #guides .index .new ul li { + background: white url(/images/modules/guides/book_add.png) no-repeat; + } + + #guides .index .new ul li a { + color: #c00; + } + + #guides .write .delete_page { + float: right; + } + + /* guide */ + + #guides .guide { + overflow: hidden; + } + + /* main */ + + #guides .guide .main { + float: left; + width: 50em; + } + + /* sidebar */ + + #guides .guide .sidebar { + float: right; + width: 15em; + border-left: 4px solid #e6e6e6; + margin: 2.1em 0 0 0; + padding-left: 1em; + } + + #guides .guide .sidebar h3 { + margin: 0 0 .5em 0; + } + + #guides .guide .sidebar ul { + list-style-type: none; + margin: 0; + color: #888; + + } + + #guides .guide .sidebar ul li { + padding-left: 12px; + background: white url(/images/modules/guides/sidebar/bullet_blue.png) -4px 0 no-repeat; + margin: .2em 0; + } + + /* admin */ + + #guides .admin { + clear: both; + margin-top: 3em; + border-top: 4px solid #e6e6e6; + padding-top: .3em; + overflow: hidden; + } + + /* write */ + + #guides .write { + + } + + #guides .write label { + font-size: 110%; + color: #666; + display: block; + margin: 1em 0; + } + + #guides .write input.text, + #guides .write textarea { + padding: 5px; + border: 1px solid #888; + } + + #guides .write input.text { + width: 40em; + } + + #guides .write textarea { + width: 100%; + height: 25em; + } + + #guides .write label span.title { + color: black; + font-weight: bold; + } + + #guides .write .actions input { + margin-right: 1em; + } + +/****************************************************************************/ +/* Wiki +/****************************************************************************/ + +.wikistyle h1, .wikistyle h2, .wikistyle h3, .wikistyle h4, .wikistyle h5, .wikistyle h6 { + border: 0 !important; +} + +.wikistyle h1 { + font-size: 170% !important; + border-top: 4px solid #aaa !important; + padding-top: .5em !important; + margin-top: 1.5em !important; +} + + .wikistyle h1:first-child { + margin-top: 0 !important; + padding-top: .25em !important; + border-top: none !important; + } + +.wikistyle h2 { + font-size: 150% !important; + margin-top: 1.5em !important; + border-top: 4px solid #e0e0e0 !important; + padding-top: .5em !important; +} + +.wikistyle h3 { + margin-top: 1em !important; +} + +.wikistyle p { + margin: 1em 0 !important; + line-height: 1.5em !important; +} + +.wikistyle ul { + margin: 1em 0 1em 2em !important; +} + +.wikistyle ol { + margin: 1em 0 1em 2em !important; +} + +.wikistyle ul ul, +.wikistyle ul ol, +.wikistyle ol ol, +.wikistyle ol ul { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.wikistyle blockquote { + margin: 1em 0 !important; + border-left: 5px solid #ddd !important; + padding-left: .6em !important; + color: #555 !important; +} + +.wikistyle dt { + font-weight: bold !important; + margin-left: 1em !important; +} + +.wikistyle dd { + margin-left: 2em !important; + margin-bottom: 1em !important; +} + +.wikistyle table { + margin: 1em 0 !important; +} + + .wikistyle table th { + border-bottom: 1px solid #bbb !important; + padding: .2em 1em !important; + } + + .wikistyle table td { + border-bottom: 1px solid #ddd !important; + padding: .2em 1em !important; + } + +.wikistyle pre { + margin: 1em 0 !important; + font-size: 90% !important; + background-color: #f8f8ff !important; + border: 1px solid #dedede !important; + padding: .5em !important; + line-height: 1.5em !important; + color: #444 !important; + overflow: auto !important; +} + + .wikistyle pre code { + padding: 0 !important; + font-size: 100% !important; + background-color: #f8f8ff !important; + border: none !important; + } + +.wikistyle code { + font-size: 90% !important; + background-color: #f8f8ff !important; + color: #444 !important; + padding: 0 .2em !important; + border: 1px solid #dedede !important; +} + +/* console */ + +.wikistyle pre.console { + margin: 1em 0 !important; + font-size: 90% !important; + background-color: black !important; + padding: .5em !important; + line-height: 1.5em !important; + color: white !important; +} + + .wikistyle pre.console code { + padding: 0 !important; + font-size: 100% !important; + background-color: black !important; + border: none !important; + color: white !important; + } + + .wikistyle pre.console span { + color: #888 !important; + } + + .wikistyle pre.console span.command { + color: yellow !important; + } \ No newline at end of file diff --git a/lib/gollum/frontend/public/css/syntax.css b/lib/gollum/frontend/public/css/syntax.css new file mode 100644 index 00000000..2774b764 --- /dev/null +++ b/lib/gollum/frontend/public/css/syntax.css @@ -0,0 +1,60 @@ +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/lib/gollum/frontend/public/javascript/jquery-1.4.2.min.js b/lib/gollum/frontend/public/javascript/jquery-1.4.2.min.js new file mode 100644 index 00000000..48a88b8f --- /dev/null +++ b/lib/gollum/frontend/public/javascript/jquery-1.4.2.min.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * 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: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(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 X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);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===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},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 f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)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 Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(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(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +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:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.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 fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=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 h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||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,h,l){return!!k(l[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,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";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(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},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){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},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,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===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 Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"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!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).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,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}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,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});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||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).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,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},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,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},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:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+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);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},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=J(),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 f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,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.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;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.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.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(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); \ No newline at end of file diff --git a/lib/gollum/frontend/templates/create.mustache b/lib/gollum/frontend/templates/create.mustache new file mode 100644 index 00000000..4bb9aa76 --- /dev/null +++ b/lib/gollum/frontend/templates/create.mustache @@ -0,0 +1,18 @@ +
+ « Home +

Create a new page

+ +
+ + +
+ +
+
+
\ No newline at end of file diff --git a/lib/gollum/frontend/templates/edit.mustache b/lib/gollum/frontend/templates/edit.mustache new file mode 100644 index 00000000..3d6ae8d7 --- /dev/null +++ b/lib/gollum/frontend/templates/edit.mustache @@ -0,0 +1,14 @@ +
+ « Back +

Editing “{{name}}”

+ +
+ +
+ +
+
+
\ No newline at end of file diff --git a/lib/gollum/frontend/templates/layout.mustache b/lib/gollum/frontend/templates/layout.mustache new file mode 100644 index 00000000..10e3276c --- /dev/null +++ b/lib/gollum/frontend/templates/layout.mustache @@ -0,0 +1,22 @@ + + + + + + Gollum - {{title}} + + + + \ No newline at end of file diff --git a/lib/gollum/frontend/views/create.rb b/lib/gollum/frontend/views/create.rb new file mode 100644 index 00000000..30417379 --- /dev/null +++ b/lib/gollum/frontend/views/create.rb @@ -0,0 +1,11 @@ +module Precious + module Views + class Create < Layout + attr_reader :page + + def title + "Create a new page" + end + end + end +end diff --git a/lib/gollum/frontend/views/edit.rb b/lib/gollum/frontend/views/edit.rb new file mode 100644 index 00000000..01153767 --- /dev/null +++ b/lib/gollum/frontend/views/edit.rb @@ -0,0 +1,11 @@ +module Precious + module Views + class Edit < Layout + attr_reader :page, :content + + def title + "Edit" + end + end + end +end diff --git a/lib/gollum/frontend/views/layout.rb b/lib/gollum/frontend/views/layout.rb new file mode 100644 index 00000000..4fba39c3 --- /dev/null +++ b/lib/gollum/frontend/views/layout.rb @@ -0,0 +1,14 @@ +module Precious + module Views + class Layout < Mustache + include Rack::Utils + alias_method :h, :escape_html + + attr_reader :name + + def title + "Home" + end + end + end +end diff --git a/lib/gollum/frontend/views/page.rb b/lib/gollum/frontend/views/page.rb new file mode 100644 index 00000000..95ef8f13 --- /dev/null +++ b/lib/gollum/frontend/views/page.rb @@ -0,0 +1,35 @@ +module Precious + module Views + class Page < Layout + attr_reader :content, :page + + def human_name + @name.gsub(/-/, ' ') + end + + def title + "A Page" + end + + def author + @page.version.author.name + end + + def date + @page.version.authored_date.strftime("%Y-%m-%d %H:%M:%S") + end + + def versions + i = @page.versions.size + 1 + @page.versions.map do |v| + i -= 1 + { :id => v.id, + :id7 => v.id[0..6], + :num => i, + :selected => @page.version.id == v.id, + :author => v.author.name } + end + end + end + end +end diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index c7ad7bd9..f8246058 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -22,11 +22,14 @@ module Gollum # # Returns the formatted String content. def render - data = extract_tags(@data) - data = extract_code(data) + data = extract_code(@data) + data = extract_tags(data) data = GitHub::Markup.render(@name, data) rescue '' data = process_tags(data) data = process_code(data) + data = Sanitize.clean(data, SANITIZATION_OPTIONS) + data = data.gsub(/

<\/p>/, '') + data end ######################################################################### @@ -41,10 +44,16 @@ module Gollum # # Returns the placeholder'd String data. def extract_tags(data) - data.gsub(/\[\[(.+?)\]\]/) do - id = Digest::SHA1.hexdigest($1) - @tagmap[id] = $1 - id + data.gsub(/(.?)\[\[(.+?)\]\](.?)/m) do + if $1 == "'" && $3 != "'" + "[[#{$2}]]#{$3}" + elsif $2.include?('][') + $& + else + id = Digest::SHA1.hexdigest($2) + @tagmap[id] = $2 + "#{$1}#{id}#{$3}" + end end end @@ -85,22 +94,28 @@ module Gollum def process_image_tag(tag) parts = tag.split('|') name = parts[0].strip + path = nil if file = find_file(name) + path = "/#{file.path}" + elsif name =~ /^https?:\/\/.+(jpg|png|gif|svg|bmp)$/ + path = name + end + + if path opts = parse_image_tag_options(tag) containered = false classes = [] # applied to whatever the outermost container is attrs = [] # applied to the image - styles = [] # applied to the image align = opts['align'] if opts['float'] containered = true align ||= 'left' if %w{left right}.include?(align) - classes << "float-#{align};" + classes << "float-#{align}" end elsif %w{top texttop middle absmiddle bottom absbottom baseline}.include?(align) attrs << %{align="#{align}"} @@ -113,13 +128,13 @@ module Gollum if width = opts['width'] if width =~ /^\d+(\.\d+)?(em|px)$/ - styles << "max-width: #{width};" + attrs << %{width="#{width}"} end end if height = opts['height'] if height =~ /^\d+(\.\d+)?(em|px)$/ - styles << "max-height: #{height};" + attrs << %{height="#{height}"} end end @@ -129,21 +144,16 @@ module Gollum attr_string = attrs.size > 0 ? attrs.join(' ') + ' ' : '' - style_string = '' - unless styles.empty? - style_string = %{ style="#{styles.join(' ')}"} - end - if opts['frame'] || containered classes << 'frame' if opts['frame'] - %{

} + - %{
} + - %{} + - (alt ? %{

#{alt}

} : '') + - %{
} + - %{
} + %{} + + %{} + + %{} + + (alt ? %{#{alt}} : '') + + %{} + + %{} else - %{} + %{} end end end @@ -192,7 +202,9 @@ module Gollum parts = tag.split('|') name = parts[0].strip cname = Page.cname((parts[1] || parts[0]).strip) - %{#{name}} + link = ::File.join(@wiki.base_path, cname) + presence = @wiki.page(cname) ? "present" : "absent" + %{#{name}} end # Find the given file in the repo. @@ -221,7 +233,7 @@ module Gollum # # Returns the placeholder'd String data. def extract_code(data) - data.gsub(/^``` ?(.+)\n(.+)\n```$/m) do + data.gsub(/^``` ?(.+?)\r?\n(.+?)\r?\n```\r?$/m) do id = Digest::SHA1.hexdigest($2) @codemap[id] = { :lang => $1, :code => $2 } id diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index fd6f119d..ee142520 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -4,7 +4,7 @@ module Gollum Wiki.page_class = self - VALID_PAGE_RE = /^(.+)\.(md|mkdn?|mdown|markdown|textile|rdoc|org|re?st(\.txt)?|asciidoc|pod|\d)$/i + VALID_PAGE_RE = /^(.+)\.(md|mkdn?|mdown|markdown|textile|rdoc|org|creole|re?st(\.txt)?|asciidoc|pod|\d)$/i # Public: Initialize a page. # @@ -57,6 +57,8 @@ module Gollum :rdoc when /\.(org)$/i :org + when /\.(creole)$/i + :creole when /\.(re?st(\.txt)?)$/i :rest when /\.(asciidoc)$/i @@ -117,6 +119,7 @@ module Gollum when :textile then 'textile' when :rdoc then 'rdoc' when :org then 'org' + when :creole then 'creole' when :rest then 'rest' when :asciidoc then 'asciidoc' when :pod then 'pod' diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index 7065a218..07ec00f4 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -33,6 +33,11 @@ module Gollum end + # The String base path to prefix to internal links. For example, when set + # to "/wiki", the page "Hobbit" will be linked as "/wiki/Hobbit". Defaults + # to "/". + attr_reader :base_path + # Public: Initialize a new Gollum Repo. # # repo - The String path to the Git repository that holds the Gollum @@ -45,6 +50,7 @@ module Gollum def initialize(path, options = {}) @path = path @repo = Grit::Repo.new(path) + @base_path = options[:base_path] || "/" @page_class = options[:page_class] || self.class.page_class @file_class = options[:file_class] || self.class.file_class end @@ -94,7 +100,7 @@ module Gollum if pcommit = @repo.commit('master') map = tree_map(pcommit.tree) end - map[path] = data + map[path] = normalize(data) index = tree_map_to_index(map) parents = pcommit ? [pcommit] : [] @@ -117,7 +123,7 @@ module Gollum pcommit = @repo.commit('master') map = tree_map(pcommit.tree) index = tree_map_to_index(map) - index.add(page.path, data) + index.add(page.path, normalize(data)) actor = Grit::Actor.new(commit[:name], commit[:email]) index.commit(commit[:message], [pcommit], actor) @@ -187,6 +193,15 @@ module Gollum # Returns the String path. attr_reader :path + # Normalize the data. + # + # data - The String data to be normalized. + # + # Returns the normalized data String. + def normalize(data) + data.gsub(/\r/, '') + end + # Fill an array with a list of pages. # # tree - The Grit::Tree to start with. diff --git a/templates/formatting.html b/templates/formatting.html new file mode 100644 index 00000000..dd0b3df5 --- /dev/null +++ b/templates/formatting.html @@ -0,0 +1,92 @@ + + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. + +

+
+ +

Google

+
+
+ +Fusce ullamcorper orci enim. Duis lectus elit, convallis ac convallis sit amet, euismod imperdiet dolor. Nunc egestas nisi quis magna feugiat vitae fringilla elit fermentum. + +
+
+ +

Google

+
+
+ +Vivamus sollicitudin dolor sit amet elit mollis ultricies. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit eros felis. Nunc non enim at dolor malesuada pellentesque a quis nibh. Aliquam sit amet pretium ante.

+ +

+
+ +

Google

+
+
+ +

Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

+ +
+
+ +

Google

+
+
+ +

Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

+ +

+

+
+ +
+
+

+ +

Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

+
+ +
+
Phasellus porta dignissim leo vel hendrerit. Nulla pellentesque nisi ac nunc malesuada aliquam. Nullam et cursus augue. Sed rhoncus pharetra odio, vel dictum diam facilisis et. Etiam molestie justo ut purus elementum rhoncus. Fusce nec augue lectus. Proin a nisl ac lectus facilisis tempus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent blandit tempus libero, in interdum odio dignissim quis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec quis arcu a metus tincidunt scelerisque eget sed mauris. Nullam pellentesque faucibus sodales. Integer ullamcorper enim id nibh tempor ultricies.

\ No newline at end of file diff --git a/test/examples/lotr.git/objects/01/676dc56d35c1999c6fe9043fe8b78d52a0e797 b/test/examples/lotr.git/objects/01/676dc56d35c1999c6fe9043fe8b78d52a0e797 new file mode 100644 index 00000000..6ff4cb89 Binary files /dev/null and b/test/examples/lotr.git/objects/01/676dc56d35c1999c6fe9043fe8b78d52a0e797 differ diff --git a/test/examples/lotr.git/objects/07/9a5887755dc6fbacfdb672abc168b0cce698fa b/test/examples/lotr.git/objects/07/9a5887755dc6fbacfdb672abc168b0cce698fa new file mode 100644 index 00000000..682d6357 Binary files /dev/null and b/test/examples/lotr.git/objects/07/9a5887755dc6fbacfdb672abc168b0cce698fa differ diff --git a/test/examples/lotr.git/objects/11/5bbf9fe8004aa6a06274b44ab93a84a06e3204 b/test/examples/lotr.git/objects/11/5bbf9fe8004aa6a06274b44ab93a84a06e3204 new file mode 100644 index 00000000..25024714 Binary files /dev/null and b/test/examples/lotr.git/objects/11/5bbf9fe8004aa6a06274b44ab93a84a06e3204 differ diff --git a/test/examples/lotr.git/objects/14/78ebf7ad4dc6a06c76cdb4aca0eba7f78796aa b/test/examples/lotr.git/objects/14/78ebf7ad4dc6a06c76cdb4aca0eba7f78796aa new file mode 100644 index 00000000..e9ffb999 Binary files /dev/null and b/test/examples/lotr.git/objects/14/78ebf7ad4dc6a06c76cdb4aca0eba7f78796aa differ diff --git a/test/examples/lotr.git/objects/1e/716a3178a76fe39ee7b88f0cf2dc4a447566f6 b/test/examples/lotr.git/objects/1e/716a3178a76fe39ee7b88f0cf2dc4a447566f6 new file mode 100644 index 00000000..42fc7843 Binary files /dev/null and b/test/examples/lotr.git/objects/1e/716a3178a76fe39ee7b88f0cf2dc4a447566f6 differ diff --git a/test/examples/lotr.git/objects/28/bb2f40d2e4c82a4ae62ef619a80a4b555e23ee b/test/examples/lotr.git/objects/28/bb2f40d2e4c82a4ae62ef619a80a4b555e23ee new file mode 100644 index 00000000..36693312 Binary files /dev/null and b/test/examples/lotr.git/objects/28/bb2f40d2e4c82a4ae62ef619a80a4b555e23ee differ diff --git a/test/examples/lotr.git/objects/2c/b9156ad383914561a8502fc70f5a1d887e48ad b/test/examples/lotr.git/objects/2c/b9156ad383914561a8502fc70f5a1d887e48ad new file mode 100644 index 00000000..9d786ae3 Binary files /dev/null and b/test/examples/lotr.git/objects/2c/b9156ad383914561a8502fc70f5a1d887e48ad differ diff --git a/test/examples/lotr.git/objects/37/fcc52509fb09142cafccaada0252f3de81873c b/test/examples/lotr.git/objects/37/fcc52509fb09142cafccaada0252f3de81873c new file mode 100644 index 00000000..88edefe5 Binary files /dev/null and b/test/examples/lotr.git/objects/37/fcc52509fb09142cafccaada0252f3de81873c differ diff --git a/test/examples/lotr.git/objects/4c/770a352f1e86071b680f879a89874bf59008fa b/test/examples/lotr.git/objects/4c/770a352f1e86071b680f879a89874bf59008fa new file mode 100644 index 00000000..0307e9c6 Binary files /dev/null and b/test/examples/lotr.git/objects/4c/770a352f1e86071b680f879a89874bf59008fa differ diff --git a/test/examples/lotr.git/objects/4f/de706c7c8d3b30b6caec8c82ff4c01261350f2 b/test/examples/lotr.git/objects/4f/de706c7c8d3b30b6caec8c82ff4c01261350f2 new file mode 100644 index 00000000..78a9ea4e --- /dev/null +++ b/test/examples/lotr.git/objects/4f/de706c7c8d3b30b6caec8c82ff4c01261350f2 @@ -0,0 +1,3 @@ +xK +1]}ɯ{":iy +^̐vIِCɖBXBRy4Fim`,uՔs+p!tqӐvi䘥AZ9Yt9v^յ3F}ɆJ \ No newline at end of file diff --git a/test/examples/lotr.git/objects/71/4323c104239440a5c66ab12a67ed07a83c404f b/test/examples/lotr.git/objects/71/4323c104239440a5c66ab12a67ed07a83c404f new file mode 100644 index 00000000..b003ac7f Binary files /dev/null and b/test/examples/lotr.git/objects/71/4323c104239440a5c66ab12a67ed07a83c404f differ diff --git a/test/examples/lotr.git/objects/79/8f6564abb42d7ed34621d53595cbbe84638949 b/test/examples/lotr.git/objects/79/8f6564abb42d7ed34621d53595cbbe84638949 new file mode 100644 index 00000000..df9cf90a --- /dev/null +++ b/test/examples/lotr.git/objects/79/8f6564abb42d7ed34621d53595cbbe84638949 @@ -0,0 +1 @@ +xA@ 9ϯMO ı 8P8TrObe2K]0f Gʀp SNh[~-nN}ނ-rL 0&YRiN_+8/%L|d0+,Vl=YGhu-G)A$ЩLrבR2ILaH?.R-+u+#FU_<3&Tկ۶/7u=GmWg.P +%]7`K{ O/7ppXߎ=6v+ŋ /n>O1x? fݎR3h+n}Dnoml \ No newline at end of file diff --git a/test/examples/lotr.git/objects/d9/e379fdea55b6ff3b71c110b3d2d7b55bbfd5ee b/test/examples/lotr.git/objects/d9/e379fdea55b6ff3b71c110b3d2d7b55bbfd5ee new file mode 100644 index 00000000..721127b6 Binary files /dev/null and b/test/examples/lotr.git/objects/d9/e379fdea55b6ff3b71c110b3d2d7b55bbfd5ee differ diff --git a/test/examples/lotr.git/objects/e3/415337d9ae2c0b4b00054a93727f4a7d3c3ca5 b/test/examples/lotr.git/objects/e3/415337d9ae2c0b4b00054a93727f4a7d3c3ca5 new file mode 100644 index 00000000..5f5e49e0 Binary files /dev/null and b/test/examples/lotr.git/objects/e3/415337d9ae2c0b4b00054a93727f4a7d3c3ca5 differ diff --git a/test/examples/lotr.git/objects/f2/5eccd98e9b667f9e22946f3e2f945378b8a72d b/test/examples/lotr.git/objects/f2/5eccd98e9b667f9e22946f3e2f945378b8a72d new file mode 100644 index 00000000..8b7776d1 --- /dev/null +++ b/test/examples/lotr.git/objects/f2/5eccd98e9b667f9e22946f3e2f945378b8a72d @@ -0,0 +1,2 @@ +xKj0@))#{$@hd&,k|CiuK͞q#EDn<ҐmBjׅE!jQ +TZJl1uU;|٧n/ x?hZ]Y`@4'=/)zsmp<`.ϣ5,L \ No newline at end of file diff --git a/test/examples/lotr.git/objects/f4/46205ac9df5b6a40c00785f06827f4a4dbd727 b/test/examples/lotr.git/objects/f4/46205ac9df5b6a40c00785f06827f4a4dbd727 new file mode 100644 index 00000000..15bedfdd --- /dev/null +++ b/test/examples/lotr.git/objects/f4/46205ac9df5b6a40c00785f06827f4a4dbd727 @@ -0,0 +1 @@ +xKj0@))#i,KPJEk}fhd&8^`).9&AO#)5-КGM(,F"-E"By T,V=VW9x]xla Bilbo Baggins b

\n}, output + assert_equal %{

a Bilbo Baggins b

}, output + end + + test "absent page link" do + @wiki.write_page("Tolkien", :markdown, "a [[J. R. R. Tolkien]]'s b", @commit) + + page = @wiki.page("Tolkien") + output = Gollum::Markup.new(page).render + assert_equal %{

a J. R. R. Tolkien's b

}, output + end + + test "page link with custom base path" do + ["/wiki", "/wiki/"].each do |path| + @wiki = Gollum::Wiki.new(@path, :base_path => path) + @wiki.write_page("Bilbo Baggins", :markdown, "a [[Bilbo Baggins]] b", @commit) + + page = @wiki.page("Bilbo Baggins") + output = Gollum::Markup.new(page).render + assert_equal %{

a Bilbo Baggins b

}, output + end + end + + test "image with http url" do + ['http', 'https'].each do |scheme| + @wiki.write_page("Bilbo Baggins", :markdown, "a [[#{scheme}://example.com/bilbo.jpg]] b", @commit) + + page = @wiki.page("Bilbo Baggins") + output = Gollum::Markup.new(page).render + assert_equal %{

a b

}, output + end end test "image with absolute path" do @@ -32,7 +61,7 @@ context "Markup" do page = @wiki.page("Bilbo Baggins") output = Gollum::Markup.new(page).render - assert_equal %{

a b

\n}, output + assert_equal %{

a b

}, output end test "image with relative path" do @@ -43,12 +72,12 @@ context "Markup" do page = @wiki.page("Bilbo Baggins") output = Gollum::Markup.new(page).render - assert_equal %{

a b

\n}, output + assert_equal %{

a b

}, output end test "image with alt" do content = "a [[alpha.jpg|alt=Alpha Dog]] b" - output = %{

a Alpha Dog b

\n} + output = %{

a Alpha Dog b

} relative_image(content, output) end @@ -56,7 +85,7 @@ context "Markup" do %w{em px}.each do |unit| %w{width height}.each do |dim| content = "a [[alpha.jpg|#{dim}=100#{unit}]] b" - output = "

a b

\n" + output = "

a b

" relative_image(content, output) end end @@ -65,7 +94,7 @@ context "Markup" do test "image with bogus dimension" do %w{width height}.each do |dim| content = "a [[alpha.jpg|#{dim}=100]] b" - output = "

a b

\n" + output = "

a b

" relative_image(content, output) end end @@ -73,7 +102,7 @@ context "Markup" do test "image with vertical align" do %w{top texttop middle absmiddle bottom absbottom baseline}.each do |align| content = "a [[alpha.jpg|align=#{align}]] b" - output = "

a b

\n" + output = "

a b

" relative_image(content, output) end end @@ -81,34 +110,34 @@ context "Markup" do test "image with horizontal align" do %w{left center right}.each do |align| content = "a [[alpha.jpg|align=#{align}]] b" - output = "

a

b

\n" + output = "

a b

" relative_image(content, output) end end test "image with float" do content = "a\n\n[[alpha.jpg|float]]\n\nb" - output = "

a

\n\n

\n\n

b

\n" + output = "

a

\n\n

\n\n

b

" relative_image(content, output) end test "image with float and align" do %w{left right}.each do |align| content = "a\n\n[[alpha.jpg|float|align=#{align}]]\n\nb" - output = "

a

\n\n

\n\n

b

\n" + output = "

a

\n\n

\n\n

b

" relative_image(content, output) end end test "image with frame" do content = "a\n\n[[alpha.jpg|frame]]\n\nb" - output = "

a

\n\n

\n\n

b

\n" + output = "

a

\n\n

\n\n

b

" relative_image(content, output) end test "image with frame and alt" do content = "a\n\n[[alpha.jpg|frame|alt=Alpha]]\n\nb" - output = "

a

\n\n

\"Alpha\"

Alpha

\n\n

b

\n" + output = "

a

\n\n

\"Alpha\"Alpha

\n\n

b

" relative_image(content, output) end @@ -120,7 +149,7 @@ context "Markup" do page = @wiki.page("Bilbo Baggins") output = Gollum::Markup.new(page).render - assert_equal %{

a Alpha b

\n}, output + assert_equal %{

a Alpha b

}, output end test "file link with relative path" do @@ -131,14 +160,14 @@ context "Markup" do page = @wiki.page("Bilbo Baggins") output = Gollum::Markup.new(page).render - assert_equal %{

a Alpha b

\n}, output + assert_equal %{

a Alpha b

}, output end test "code blocks" do content = "a\n\n```ruby\nx = 1\n```\n\nb" - output = "

a

\n\n

" +
+    output = "

a

\n\n
" +
              "x = " +
-             "1\n
\n

\n\n

b

\n" + "1\n
\n
\n\n

b

" index = @wiki.repo.index index.add("Bilbo-Baggins.md", content) @@ -149,6 +178,49 @@ context "Markup" do assert_equal output, rendered end + test "code blocks with carriage returns" do + content = "a\r\n\r\n```ruby\r\nx = 1\r\n```\r\n\r\nb" + output = "

a

\n\n
" +
+             "x = " +
+             "1\n
\n
\n\n

b

" + + index = @wiki.repo.index + index.add("Bilbo-Baggins.md", content) + index.commit("Add alpha.jpg") + + page = @wiki.page("Bilbo Baggins") + rendered = Gollum::Markup.new(page).render + assert_equal output, rendered + end + + test "escaped wiki link" do + content = "a '[[Foo]], b" + output = "

a [[Foo]], b

" + compare(content, output) + end + + test "quoted wiki link" do + content = "a '[[Foo]]', b" + output = "

a 'Foo', b

" + compare(content, output) + end + + test "org mode style double links" do + content = "a [[http://google.com][Google]] b" + output = "

a Google b

" + compare(content, output, 'org') + end + + def compare(content, output, ext = "md") + index = @wiki.repo.index + index.add("Bilbo-Baggins.#{ext}", content) + index.commit("Add baggins") + + page = @wiki.page("Bilbo Baggins") + rendered = Gollum::Markup.new(page).render + assert_equal output, rendered + end + def relative_image(content, output) index = @wiki.repo.index index.add("greek/alpha.jpg", "hi") diff --git a/test/test_page.rb b/test/test_page.rb index 45b19b91..b5dac678 100644 --- a/test/test_page.rb +++ b/test/test_page.rb @@ -28,7 +28,7 @@ context "Page" do test "page versions" do page = @wiki.page('Bilbo Baggins') - assert_equal ['5bc1aaec6149e854078f1d0f8b71933bbc6c2e43'], + assert_equal ["f25eccd98e9b667f9e22946f3e2f945378b8a72d", "5bc1aaec6149e854078f1d0f8b71933bbc6c2e43"], page.versions.map { |v| v.id } end diff --git a/test/test_wiki.rb b/test/test_wiki.rb index 8d3ceded..2bb913de 100644 --- a/test/test_wiki.rb +++ b/test/test_wiki.rb @@ -17,25 +17,27 @@ context "Wiki" do test "shows paginated log with no page" do Gollum::Wiki.per_page = 3 assert_equal %w( - f01428b3138994aab19d5f880b6f37336ddf1f24 - fbabba862dfa7ac35b39042dd4ad780c9f67b8cb - df26e61e707116f81ebc6b935ec6d1676b7e96c4), + 4fde706c7c8d3b30b6caec8c82ff4c01261350f2 + 1e716a3178a76fe39ee7b88f0cf2dc4a447566f6 + afe2034d400ba21e13361f38f74900c51dbc7fde), @wiki.log.map { |c| c.id } end test "shows paginated log with 1st page" do Gollum::Wiki.per_page = 3 assert_equal %w( - f01428b3138994aab19d5f880b6f37336ddf1f24 - fbabba862dfa7ac35b39042dd4ad780c9f67b8cb - df26e61e707116f81ebc6b935ec6d1676b7e96c4), + 4fde706c7c8d3b30b6caec8c82ff4c01261350f2 + 1e716a3178a76fe39ee7b88f0cf2dc4a447566f6 + afe2034d400ba21e13361f38f74900c51dbc7fde), @wiki.log(:page => 1).map { |c| c.id } end test "shows paginated log with next page" do Gollum::Wiki.per_page = 3 assert_equal %w( - 5bc1aaec6149e854078f1d0f8b71933bbc6c2e43), + f25eccd98e9b667f9e22946f3e2f945378b8a72d + b0d108328459e44fff4a76cd19b10ddc34adce4b + f01428b3138994aab19d5f880b6f37336ddf1f24), @wiki.log(:page => 2).map { |c| c.id } end end