easy-rack-open-id 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/.gitignore +2 -0
  2. data/{README → README.rdoc} +19 -7
  3. data/Rakefile +22 -10
  4. data/VERSION +1 -0
  5. data/config.ru +4 -1
  6. data/lib/easy_rack_open_id.rb +21 -16
  7. data/lib/easy_rack_open_id_processing.rb +149 -0
  8. data/lib/nice_openid_form.html.erb +57 -0
  9. data/public/easy-rack-openid-assets/openid-selector/css/openid.css +45 -0
  10. data/public/easy-rack-openid-assets/openid-selector/demo.html +57 -0
  11. data/public/easy-rack-openid-assets/openid-selector/images/aol.gif +0 -0
  12. data/public/easy-rack-openid-assets/openid-selector/images/blogger.ico +0 -0
  13. data/public/easy-rack-openid-assets/openid-selector/images/claimid.ico +0 -0
  14. data/public/easy-rack-openid-assets/openid-selector/images/facebook.gif +0 -0
  15. data/public/easy-rack-openid-assets/openid-selector/images/flickr.ico +0 -0
  16. data/public/easy-rack-openid-assets/openid-selector/images/google.gif +0 -0
  17. data/public/easy-rack-openid-assets/openid-selector/images/livejournal.ico +0 -0
  18. data/public/easy-rack-openid-assets/openid-selector/images/myopenid.ico +0 -0
  19. data/public/easy-rack-openid-assets/openid-selector/images/openid-inputicon.gif +0 -0
  20. data/public/easy-rack-openid-assets/openid-selector/images/openid.gif +0 -0
  21. data/public/easy-rack-openid-assets/openid-selector/images/technorati.ico +0 -0
  22. data/public/easy-rack-openid-assets/openid-selector/images/verisign.ico +0 -0
  23. data/public/easy-rack-openid-assets/openid-selector/images/vidoop.ico +0 -0
  24. data/public/easy-rack-openid-assets/openid-selector/images/wordpress.ico +0 -0
  25. data/public/easy-rack-openid-assets/openid-selector/images/yahoo.gif +0 -0
  26. data/public/easy-rack-openid-assets/openid-selector/js/jquery-1.2.6.min.js +32 -0
  27. data/public/easy-rack-openid-assets/openid-selector/js/openid-jquery.js +229 -0
  28. metadata +42 -18
  29. data/Manifest +0 -6
  30. data/easy-rack-open-id.gemspec +0 -33
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Manifest
2
+ pkg/*
@@ -1,10 +1,10 @@
1
- EasyRackOpenID. Simplifies OpenID login for Rack apps.
1
+ = EasyRackOpenID. Simplifies OpenID login for Rack apps.
2
2
 
3
- Get Rack::OpenID of http://github.com/josh/rack-openid
4
- gem install rack-openid
3
+ == Installation
5
4
  gem install easy-rack-open-id
5
+ (depends on rack-openid which depends on ruby-openid)
6
6
 
7
- You:
7
+ Then, you:
8
8
  require 'rack/openid'
9
9
  use Rack::Session::Cookie
10
10
  use Rack::OpenID
@@ -15,8 +15,17 @@ There's an example in config.ru
15
15
 
16
16
 
17
17
  Basically, slap EasyRackOpenID in front of the App you want to protect. Rack::OpenID needs to be above it.
18
- Rack:OpenID with noo arguments uses an in memory OpenID store. This is ok for trying out with rackup, but won't work in a variety of scenarios including using shotgun. You can pass it a different store like so:
19
- use Rack::OpenID, OpenID::Store::Memcache.new
18
+
19
+ == OpenID stores
20
+
21
+ OpenID needs some storage to remember cryptographic nuts and bolts. Rack:OpenID with no arguments uses an in memory OpenID store. This is ok for trying out with rackup, but won't work in a variety of scenarios including using shotgun and multiple servers. You can pass it a different store like so:
22
+
23
+ require 'openid_mongodb_store' # http://github.com/samsm/openid_mongodb_store
24
+ MongoMapper.database = 'testorama'
25
+ MongoMapper.database.authorize('username','password')
26
+ use Rack::OpenID, OpenidMongodbStore::Store.new
27
+
28
+ == Options
20
29
 
21
30
  With no arguments, EasyRackOpenID will only allow users with a verified OpenID to proceed. It won't care what that identity is.
22
31
 
@@ -32,4 +41,7 @@ Right now allowed_identifiers and identity_match cannot both be used at once.
32
41
 
33
42
  :logout_path (optional, defaults to /logout) path that, when visited will clear the login session
34
43
 
35
- :after_logout_path (optional) After a user logs out, send them here. (don't want the user sitting on the logout path)
44
+ :after_logout_path (optional) After a user logs out, send them here. (don't want the user sitting on the logout path)
45
+
46
+ == OpenID Selector
47
+ This package includes a pretty default login form from the "openid-selector" project. This gem will serve the necessary javascript/images, but it may be more efficient to copy public/easy-rack-openid-assets into your application's public directory so that Apache/Nginx/whatever can serve those file directly.
data/Rakefile CHANGED
@@ -1,16 +1,28 @@
1
1
  # Rakefile
2
2
  require 'rubygems'
3
3
  require 'rake'
4
- require 'echoe'
5
4
 
6
- Echoe.new('easy-rack-open-id', '0.0.2') do |p|
7
- p.summary = "Super easy OpenID protection for Rack."
8
- p.description = "You supply OpenIDs, this keeps anyone but people with access to those ids from getting through."
9
- p.url = "http://samsm.com/"
10
- p.author = "Sam Schenkman-Moore"
11
- p.email = "samsm@samsm.com"
12
- p.ignore_pattern = ["tmp/*", "script/*"]
13
- p.runtime_dependencies = ['rack-openid']
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "easy-rack-open-id"
9
+ gem.summary = "Super easy OpenID protection for Rack."
10
+ gem.description = "You supply OpenIDs, this keeps anyone but people with access to those ids from getting through. You don't even have to make a form. :)"
11
+ gem.email = "samsm@samsm.com"
12
+ gem.homepage = "http://github.com/samsm/Easy-Rack-OpenID"
13
+ gem.authors = ["Sam Schenkman-Moore"]
14
+ gem.add_development_dependency "yard", ">= 0"
15
+ gem.add_runtime_dependency 'rack-openid'
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
14
19
  end
15
20
 
16
- Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
21
+ begin
22
+ require 'yard'
23
+ YARD::Rake::YardocTask.new
24
+ rescue LoadError
25
+ task :yardoc do
26
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
27
+ end
28
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/config.ru CHANGED
@@ -12,7 +12,10 @@ class HelloWorld
12
12
  end
13
13
 
14
14
 
15
+ # require 'openid_mongodb_store'
16
+ # MongoMapper.database = 'testorama'
17
+
15
18
  use Rack::Session::Cookie
16
- use Rack::OpenID
19
+ use Rack::OpenID #, OpenidMongodbStore::Store.new
17
20
  use EasyRackOpenID, :allowed_identifiers => ['http://example.com/'], :after_logout_path => '/login'
18
21
  run HelloWorld.new
@@ -1,6 +1,7 @@
1
+ require File.dirname(__FILE__) + '/easy_rack_open_id_processing'
1
2
  class EasyRackOpenID
2
3
 
3
- attr_accessor :env, :options
4
+ # attr_accessor :env, :options
4
5
 
5
6
  def initialize(app, options ={})
6
7
  @app = app
@@ -8,18 +9,19 @@ class EasyRackOpenID
8
9
  end
9
10
 
10
11
  def call(env)
11
- @env = env
12
- if logout_path == path
13
- logout_result = logout
14
- return logout_result if logout_result
15
- end
16
- if allowed?
17
- # pass through
18
- @app.call(env)
19
- else
20
- # break chain, start open_id_login
21
- open_id_login
22
- end
12
+ EasyRackOpenIDProcessing.new(@app,@options).call(env)
13
+ end
14
+
15
+ def asset?
16
+ 0 == path.index(asset_prefix)
17
+ end
18
+
19
+ def asset_prefix
20
+ '/easy-rack-openid-assets'
21
+ end
22
+
23
+ def gem_public_path
24
+ File.dirname(__FILE__) + '/../public/'
23
25
  end
24
26
 
25
27
  def open_id_login
@@ -52,7 +54,8 @@ class EasyRackOpenID
52
54
  forward_to(login_path)
53
55
  else
54
56
  dir = File.dirname(__FILE__)
55
- form = IO.read(dir + '/generic_openid_form.html.erb')
57
+ # form = IO.read(dir + '/generic_openid_form.html.erb')
58
+ form = IO.read(dir + '/nice_openid_form.html.erb')
56
59
  ok(form)
57
60
  end
58
61
  end
@@ -126,8 +129,10 @@ class EasyRackOpenID
126
129
  options[:default_return_to] || '/'
127
130
  end
128
131
 
129
- def ok(text)
130
- [200,{"Content-Type" => 'text/html', 'Content-Length'=> text.length},text]
132
+ def ok(text, content_type = 'text/html')
133
+ puts
134
+ puts "2. Content type: #{content_type} for #{path}"
135
+ [200,{"Content-Type" => content_type, 'Content-Length'=> text.length},[text]]
131
136
  end
132
137
 
133
138
  end
@@ -0,0 +1,149 @@
1
+ class EasyRackOpenIDProcessing
2
+
3
+ attr_accessor :env, :options
4
+
5
+ def initialize(app, options ={})
6
+ @app = app
7
+ @options = options
8
+ end
9
+
10
+ def call(env)
11
+ @env = env
12
+ if logout_path == path
13
+ logout_result = logout
14
+ return logout_result if logout_result
15
+ end
16
+ if asset?
17
+ content_type_lookup = {'css' => 'text/css','html'=> 'text/html','js'=>'text/javascript','gif'=>'image/gif','ico' => 'image/vnd.microsoft.icon'}
18
+ ok(IO.read(gem_public_path + path), content_type_lookup[File.extname(path)[1..-1]])
19
+ elsif allowed?
20
+ # pass through
21
+ @app.call(env)
22
+ else
23
+ # break chain, start open_id_login
24
+ open_id_login
25
+ end
26
+ end
27
+
28
+ def asset?
29
+ 0 == path.index(asset_prefix)
30
+ end
31
+
32
+ def asset_prefix
33
+ '/easy-rack-openid-assets'
34
+ end
35
+
36
+ def gem_public_path
37
+ File.dirname(__FILE__) + '/../public/'
38
+ end
39
+
40
+ def open_id_login
41
+ if resp = env["rack.openid.response"]
42
+ case resp.status
43
+ when :success
44
+ #... save id and forward to ...
45
+ self.verified_identity = resp.identity_url
46
+ forward_to(protected_path)
47
+ when :failure
48
+ present_login_options
49
+ end
50
+ else
51
+ if identitifier_to_verify
52
+ self.protected_path = path
53
+ [401, {"WWW-Authenticate" => "OpenID identifier=\"#{identitifier_to_verify}\""}, []]
54
+ else
55
+ present_login_options
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ def path
62
+ env['REQUEST_PATH']
63
+ end
64
+
65
+ def present_login_options
66
+ if login_path
67
+ forward_to(login_path)
68
+ else
69
+ dir = File.dirname(__FILE__)
70
+ # form = IO.read(dir + '/generic_openid_form.html.erb')
71
+ form = IO.read(dir + '/nice_openid_form.html.erb')
72
+ ok(form)
73
+ end
74
+ end
75
+
76
+ def forward_to(url)
77
+ [302, {'Location' => url}, ["Forwarding to #{url}"]]
78
+ end
79
+
80
+ def allowed?
81
+ if allowed_identifiers
82
+ allowed_identifiers.include? verified_identity
83
+ elsif identity_match
84
+ identity_match === verified_identity
85
+ else
86
+ verified_identity
87
+ end
88
+ end
89
+
90
+ def identity_match
91
+ options[:identity_match]
92
+ end
93
+
94
+ def allowed_identifiers
95
+ options[:allowed_identifiers]
96
+ end
97
+
98
+ def logout_path
99
+ options[:logout_path] || '/logout'
100
+ end
101
+
102
+ def logout
103
+ self.verified_identity = nil
104
+ if after_logout_path
105
+ forward_to(after_logout_path)
106
+ end
107
+ end
108
+
109
+ def after_logout_path
110
+ options[:after_logout_path]
111
+ end
112
+
113
+ def login_path
114
+ options[:login_path]
115
+ end
116
+
117
+ def identitifier_to_verify
118
+ env["rack.request.query_hash"]["openid_identifier"]
119
+ end
120
+
121
+ def verified_identity=(url)
122
+ session['verified_identity'] = url
123
+ end
124
+
125
+ def verified_identity
126
+ session['verified_identity']
127
+ end
128
+
129
+ def session
130
+ env['rack.session']
131
+ end
132
+
133
+ def protected_path=(path)
134
+ session['return_to'] = path
135
+ end
136
+
137
+ def protected_path
138
+ session['return_to'] || default_return_to
139
+ end
140
+
141
+ def default_return_to
142
+ options[:default_return_to] || '/'
143
+ end
144
+
145
+ def ok(text, content_type = 'text/html')
146
+ [200,{"Content-Type" => content_type, 'Content-Length'=> text.length},[text]]
147
+ end
148
+
149
+ end
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <title>Log In!</title>
6
+
7
+ <!-- Simple OpenID Selector -->
8
+ <link rel="stylesheet" href="/easy-rack-openid-assets/openid-selector/css/openid.css" />
9
+ <script type="text/javascript" src="/easy-rack-openid-assets/openid-selector/js/jquery-1.2.6.min.js"></script>
10
+ <script type="text/javascript" src="/easy-rack-openid-assets/openid-selector/js/openid-jquery.js"></script>
11
+ <script type="text/javascript">
12
+ $(document).ready(function() {
13
+ openid.init('openid_identifier');
14
+ });
15
+ </script>
16
+ <!-- /Simple OpenID Selector -->
17
+
18
+ <style type="text/css">
19
+ /* Basic page formatting. */
20
+ body {
21
+ font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
22
+ }
23
+ </style>
24
+ </head>
25
+
26
+ <body>
27
+
28
+ <h2>Log in with OpenID</h2>
29
+ <p>Click the icon of the account you want to use, or enter your OpenID if you know it.</p>
30
+ <br/>
31
+
32
+ <!-- Simple OpenID Selector -->
33
+ <form action="" method="get" id="openid_form">
34
+ <input type="hidden" name="action" value="verify" />
35
+
36
+ <fieldset>
37
+ <legend>Sign-in or Create New Account</legend>
38
+
39
+ <div id="openid_choice">
40
+ <p>Please click your account provider:</p>
41
+ <div id="openid_btns"></div>
42
+ </div>
43
+
44
+ <div id="openid_input_area">
45
+ <input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
46
+ <input id="openid_submit" type="submit" value="Sign-In"/>
47
+ </div>
48
+ <noscript>
49
+ <p>OpenID is service that allows you to log-on to many different websites using a single indentity.
50
+ Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
51
+ </noscript>
52
+ </fieldset>
53
+ </form>
54
+ <!-- /Simple OpenID Selector -->
55
+
56
+ </body>
57
+ </html>
@@ -0,0 +1,45 @@
1
+ #openid_form {
2
+ width: 470px;
3
+ }
4
+ #openid_form legend {
5
+ font-weight: bold;
6
+ }
7
+ #openid_choice {
8
+ display: none;
9
+ }
10
+ #openid_input_area {
11
+ clear: both;
12
+ padding: 10px;
13
+ }
14
+ #openid_btns, #openid_btns br {
15
+ clear: both;
16
+ }
17
+ #openid_highlight {
18
+ padding: 3px;
19
+ background-color: #FFFCC9;
20
+ float: left;
21
+ }
22
+ .openid_large_btn {
23
+ width: 100px;
24
+ height: 60px;
25
+ border: 1px solid #DDD;
26
+ margin: 3px;
27
+ float: left;
28
+ }
29
+ .openid_small_btn {
30
+ width: 24px;
31
+ height: 24px;
32
+ border: 1px solid #DDD;
33
+ margin: 3px;
34
+ float: left;
35
+ }
36
+ a.openid_large_btn:focus {
37
+ outline: none;
38
+ }
39
+ a.openid_large_btn:focus
40
+ {
41
+ -moz-outline-style: none;
42
+ }
43
+ .openid_selected {
44
+ border: 4px solid #DDD;
45
+ }
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <title>JQuery Simple OpenID Selector Demo</title>
6
+
7
+ <!-- Simple OpenID Selector -->
8
+ <link rel="stylesheet" href="css/openid.css" />
9
+ <script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
10
+ <script type="text/javascript" src="js/openid-jquery.js"></script>
11
+ <script type="text/javascript">
12
+ $(document).ready(function() {
13
+ openid.init('openid_identifier');
14
+ });
15
+ </script>
16
+ <!-- /Simple OpenID Selector -->
17
+
18
+ <style type="text/css">
19
+ /* Basic page formatting. */
20
+ body {
21
+ font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
22
+ }
23
+ </style>
24
+ </head>
25
+
26
+ <body>
27
+
28
+ <h2>JQuery Simple OpenID Selector Demo</h2>
29
+ <p>This is a simple example to show how you can include the Javascript into your page.</p>
30
+ <br/>
31
+
32
+ <!-- Simple OpenID Selector -->
33
+ <form action="examples/consumer/try_auth.php" method="get" id="openid_form">
34
+ <input type="hidden" name="action" value="verify" />
35
+
36
+ <fieldset>
37
+ <legend>Sign-in or Create New Account</legend>
38
+
39
+ <div id="openid_choice">
40
+ <p>Please click your account provider:</p>
41
+ <div id="openid_btns"></div>
42
+ </div>
43
+
44
+ <div id="openid_input_area">
45
+ <input id="openid_identifier" name="openid_identifier" type="text" value="http://" />
46
+ <input id="openid_submit" type="submit" value="Sign-In"/>
47
+ </div>
48
+ <noscript>
49
+ <p>OpenID is service that allows you to log-on to many different websites using a single indentity.
50
+ Find out <a href="http://openid.net/what/">more about OpenID</a> and <a href="http://openid.net/get/">how to get an OpenID enabled account</a>.</p>
51
+ </noscript>
52
+ </fieldset>
53
+ </form>
54
+ <!-- /Simple OpenID Selector -->
55
+
56
+ </body>
57
+ </html>
@@ -0,0 +1,32 @@
1
+ /*
2
+ * jQuery 1.2.6 - New Wave Javascript
3
+ *
4
+ * Copyright (c) 2008 John Resig (jquery.com)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
9
+ * $Rev: 5685 $
10
+ */
11
+ (function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
12
+ return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
13
+ return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
14
+ selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}return values;}else
15
+ return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
16
+ this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
17
+ return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
18
+ jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){var src=target[name],copy=options[name];if(target===copy)continue;if(deep&&copy&&typeof copy=="object"&&!copy.nodeType)target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);else if(copy!==undefined)target[name]=copy;}return target;};var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
19
+ script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){var name,i=0,length=object.length;if(args){if(length==undefined){for(name in object)if(callback.apply(object[name],args)===false)break;}else
20
+ for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
21
+ for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
22
+ jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i<stack.length;i++)if(color(stack[i])){swap[i]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";for(i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem+='';if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
23
+ ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&&notxml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else
24
+ while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
25
+ while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!=null)ret[ret.length]=value;}return ret.concat.apply([],ret);}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
26
+ for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i<args.length)jQuery.event.proxy(fn,args[i++]);return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;event.preventDefault();return args[this.lastToggle++].apply(this,arguments)||false;}));},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
27
+ jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(typeof url!='string')return this._load(url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else
28
+ xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
29
+ jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
30
+ for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
31
+ s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
32
+ e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();
@@ -0,0 +1,229 @@
1
+ /*
2
+ Simple OpenID Plugin
3
+ http://code.google.com/p/openid-selector/
4
+
5
+ This code is licenced under the New BSD License.
6
+ */
7
+
8
+ var providers_large = {
9
+ google: {
10
+ name: 'Google',
11
+ url: 'https://www.google.com/accounts/o8/id'
12
+ },
13
+ yahoo: {
14
+ name: 'Yahoo',
15
+ url: 'http://yahoo.com/'
16
+ },
17
+ aol: {
18
+ name: 'AOL',
19
+ label: 'Enter your AOL screenname.',
20
+ url: 'http://openid.aol.com/{username}/'
21
+ },
22
+ openid: {
23
+ name: 'OpenID',
24
+ label: 'Enter your OpenID.',
25
+ url: null
26
+ }
27
+ };
28
+ var providers_small = {
29
+ myopenid: {
30
+ name: 'MyOpenID',
31
+ label: 'Enter your MyOpenID username.',
32
+ url: 'http://{username}.myopenid.com/'
33
+ },
34
+ livejournal: {
35
+ name: 'LiveJournal',
36
+ label: 'Enter your Livejournal username.',
37
+ url: 'http://{username}.livejournal.com/'
38
+ },
39
+ flickr: {
40
+ name: 'Flickr',
41
+ label: 'Enter your Flickr username.',
42
+ url: 'http://flickr.com/{username}/'
43
+ },
44
+ technorati: {
45
+ name: 'Technorati',
46
+ label: 'Enter your Technorati username.',
47
+ url: 'http://technorati.com/people/technorati/{username}/'
48
+ },
49
+ wordpress: {
50
+ name: 'Wordpress',
51
+ label: 'Enter your Wordpress.com username.',
52
+ url: 'http://{username}.wordpress.com/'
53
+ },
54
+ blogger: {
55
+ name: 'Blogger',
56
+ label: 'Your Blogger account',
57
+ url: 'http://{username}.blogspot.com/'
58
+ },
59
+ verisign: {
60
+ name: 'Verisign',
61
+ label: 'Your Verisign username',
62
+ url: 'http://{username}.pip.verisignlabs.com/'
63
+ },
64
+ vidoop: {
65
+ name: 'Vidoop',
66
+ label: 'Your Vidoop username',
67
+ url: 'http://{username}.myvidoop.com/'
68
+ },
69
+ verisign: {
70
+ name: 'Verisign',
71
+ label: 'Your Verisign username',
72
+ url: 'http://{username}.pip.verisignlabs.com/'
73
+ },
74
+ claimid: {
75
+ name: 'ClaimID',
76
+ label: 'Your ClaimID username',
77
+ url: 'http://claimid.com/{username}'
78
+ }
79
+ };
80
+ var providers = $.extend({}, providers_large, providers_small);
81
+
82
+ var openid = {
83
+
84
+ cookie_expires: 6*30, // 6 months.
85
+ cookie_name: 'openid_provider',
86
+ cookie_path: '/',
87
+
88
+ img_path: '/easy-rack-openid-assets/openid-selector/images/',
89
+
90
+ input_id: null,
91
+ provider_url: null,
92
+
93
+ init: function(input_id) {
94
+
95
+ var openid_btns = $('#openid_btns');
96
+
97
+ this.input_id = input_id;
98
+
99
+ $('#openid_choice').show();
100
+ $('#openid_input_area').empty();
101
+
102
+ // add box for each provider
103
+ for (id in providers_large) {
104
+
105
+ openid_btns.append(this.getBoxHTML(providers_large[id], 'large', '.gif'));
106
+ }
107
+ if (providers_small) {
108
+ openid_btns.append('<br/>');
109
+
110
+ for (id in providers_small) {
111
+
112
+ openid_btns.append(this.getBoxHTML(providers_small[id], 'small', '.ico'));
113
+ }
114
+ }
115
+
116
+ $('#openid_form').submit(this.submit);
117
+
118
+ var box_id = this.readCookie();
119
+ if (box_id) {
120
+ this.signin(box_id, true);
121
+ }
122
+ },
123
+ getBoxHTML: function(provider, box_size, image_ext) {
124
+
125
+ var box_id = provider["name"].toLowerCase();
126
+ return '<a title="'+provider["name"]+'" href="javascript: openid.signin(\''+ box_id +'\');"' +
127
+ ' style="background: #FFF url(' + this.img_path + box_id + image_ext+') no-repeat center center" ' +
128
+ 'class="' + box_id + ' openid_' + box_size + '_btn"></a>';
129
+
130
+ },
131
+ /* Provider image click */
132
+ signin: function(box_id, onload) {
133
+
134
+ var provider = providers[box_id];
135
+ if (! provider) {
136
+ return;
137
+ }
138
+
139
+ this.highlight(box_id);
140
+ this.setCookie(box_id);
141
+
142
+ // prompt user for input?
143
+ if (provider['label']) {
144
+
145
+ this.useInputBox(provider);
146
+ this.provider_url = provider['url'];
147
+
148
+ } else {
149
+
150
+ this.setOpenIdUrl(provider['url']);
151
+ if (! onload) {
152
+ $('#openid_form').submit();
153
+ }
154
+ }
155
+ },
156
+ /* Sign-in button click */
157
+ submit: function() {
158
+
159
+ var url = openid.provider_url;
160
+ if (url) {
161
+ url = url.replace('{username}', $('#openid_username').val());
162
+ openid.setOpenIdUrl(url);
163
+ }
164
+ return true;
165
+ },
166
+ setOpenIdUrl: function (url) {
167
+
168
+ var hidden = $('#'+this.input_id);
169
+ if (hidden.length > 0) {
170
+ hidden.value = url;
171
+ } else {
172
+ $('#openid_form').append('<input type="hidden" id="' + this.input_id + '" name="' + this.input_id + '" value="'+url+'"/>');
173
+ }
174
+ },
175
+ highlight: function (box_id) {
176
+
177
+ // remove previous highlight.
178
+ var highlight = $('#openid_highlight');
179
+ if (highlight) {
180
+ highlight.replaceWith($('#openid_highlight a')[0]);
181
+ }
182
+ // add new highlight.
183
+ $('.'+box_id).wrap('<div id="openid_highlight"></div>');
184
+ },
185
+ setCookie: function (value) {
186
+
187
+ var date = new Date();
188
+ date.setTime(date.getTime()+(this.cookie_expires*24*60*60*1000));
189
+ var expires = "; expires="+date.toGMTString();
190
+
191
+ document.cookie = this.cookie_name+"="+value+expires+"; path=" + this.cookie_path;
192
+ },
193
+ readCookie: function () {
194
+ var nameEQ = this.cookie_name + "=";
195
+ var ca = document.cookie.split(';');
196
+ for(var i=0;i < ca.length;i++) {
197
+ var c = ca[i];
198
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
199
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
200
+ }
201
+ return null;
202
+ },
203
+ useInputBox: function (provider) {
204
+
205
+ var input_area = $('#openid_input_area');
206
+
207
+ var html = '';
208
+ var id = 'openid_username';
209
+ var value = '';
210
+ var label = provider['label'];
211
+ var style = '';
212
+
213
+ if (label) {
214
+ html = '<p>' + label + '</p>';
215
+ }
216
+ if (provider['name'] == 'OpenID') {
217
+ id = this.input_id;
218
+ value = 'http://';
219
+ style = 'background:#FFF url('+this.img_path+'openid-inputicon.gif) no-repeat scroll 0 50%; padding-left:18px;';
220
+ }
221
+ html += '<input id="'+id+'" type="text" style="'+style+'" name="'+id+'" value="'+value+'" />' +
222
+ '<input id="openid_submit" type="submit" value="Sign-In"/>';
223
+
224
+ input_area.empty();
225
+ input_area.append(html);
226
+
227
+ $('#'+id).focus();
228
+ }
229
+ };
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy-rack-open-id
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Schenkman-Moore
@@ -9,9 +9,19 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-17 00:00:00 -05:00
12
+ date: 2009-12-15 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: yard
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
15
25
  - !ruby/object:Gem::Dependency
16
26
  name: rack-openid
17
27
  type: :runtime
@@ -22,36 +32,50 @@ dependencies:
22
32
  - !ruby/object:Gem::Version
23
33
  version: "0"
24
34
  version:
25
- description: You supply OpenIDs, this keeps anyone but people with access to those ids from getting through.
35
+ description: You supply OpenIDs, this keeps anyone but people with access to those ids from getting through. You don't even have to make a form. :)
26
36
  email: samsm@samsm.com
27
37
  executables: []
28
38
 
29
39
  extensions: []
30
40
 
31
41
  extra_rdoc_files:
32
- - README
33
- - lib/easy_rack_open_id.rb
34
- - lib/generic_openid_form.html.erb
42
+ - README.rdoc
35
43
  files:
36
- - Manifest
37
- - README
44
+ - .gitignore
45
+ - README.rdoc
38
46
  - Rakefile
47
+ - VERSION
39
48
  - config.ru
40
49
  - lib/easy_rack_open_id.rb
50
+ - lib/easy_rack_open_id_processing.rb
41
51
  - lib/generic_openid_form.html.erb
42
- - easy-rack-open-id.gemspec
52
+ - lib/nice_openid_form.html.erb
53
+ - public/easy-rack-openid-assets/openid-selector/css/openid.css
54
+ - public/easy-rack-openid-assets/openid-selector/demo.html
55
+ - public/easy-rack-openid-assets/openid-selector/images/aol.gif
56
+ - public/easy-rack-openid-assets/openid-selector/images/blogger.ico
57
+ - public/easy-rack-openid-assets/openid-selector/images/claimid.ico
58
+ - public/easy-rack-openid-assets/openid-selector/images/facebook.gif
59
+ - public/easy-rack-openid-assets/openid-selector/images/flickr.ico
60
+ - public/easy-rack-openid-assets/openid-selector/images/google.gif
61
+ - public/easy-rack-openid-assets/openid-selector/images/livejournal.ico
62
+ - public/easy-rack-openid-assets/openid-selector/images/myopenid.ico
63
+ - public/easy-rack-openid-assets/openid-selector/images/openid-inputicon.gif
64
+ - public/easy-rack-openid-assets/openid-selector/images/openid.gif
65
+ - public/easy-rack-openid-assets/openid-selector/images/technorati.ico
66
+ - public/easy-rack-openid-assets/openid-selector/images/verisign.ico
67
+ - public/easy-rack-openid-assets/openid-selector/images/vidoop.ico
68
+ - public/easy-rack-openid-assets/openid-selector/images/wordpress.ico
69
+ - public/easy-rack-openid-assets/openid-selector/images/yahoo.gif
70
+ - public/easy-rack-openid-assets/openid-selector/js/jquery-1.2.6.min.js
71
+ - public/easy-rack-openid-assets/openid-selector/js/openid-jquery.js
43
72
  has_rdoc: true
44
- homepage: http://samsm.com/
73
+ homepage: http://github.com/samsm/Easy-Rack-OpenID
45
74
  licenses: []
46
75
 
47
76
  post_install_message:
48
77
  rdoc_options:
49
- - --line-numbers
50
- - --inline-source
51
- - --title
52
- - Easy-rack-open-id
53
- - --main
54
- - README
78
+ - --charset=UTF-8
55
79
  require_paths:
56
80
  - lib
57
81
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -64,11 +88,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
88
  requirements:
65
89
  - - ">="
66
90
  - !ruby/object:Gem::Version
67
- version: "1.2"
91
+ version: "0"
68
92
  version:
69
93
  requirements: []
70
94
 
71
- rubyforge_project: easy-rack-open-id
95
+ rubyforge_project:
72
96
  rubygems_version: 1.3.5
73
97
  signing_key:
74
98
  specification_version: 3
data/Manifest DELETED
@@ -1,6 +0,0 @@
1
- Manifest
2
- README
3
- Rakefile
4
- config.ru
5
- lib/easy_rack_open_id.rb
6
- lib/generic_openid_form.html.erb
@@ -1,33 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- Gem::Specification.new do |s|
4
- s.name = %q{easy-rack-open-id}
5
- s.version = "0.0.2"
6
-
7
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Sam Schenkman-Moore"]
9
- s.date = %q{2009-11-17}
10
- s.description = %q{You supply OpenIDs, this keeps anyone but people with access to those ids from getting through.}
11
- s.email = %q{samsm@samsm.com}
12
- s.extra_rdoc_files = ["README", "lib/easy_rack_open_id.rb", "lib/generic_openid_form.html.erb"]
13
- s.files = ["Manifest", "README", "Rakefile", "config.ru", "lib/easy_rack_open_id.rb", "lib/generic_openid_form.html.erb", "easy-rack-open-id.gemspec"]
14
- s.homepage = %q{http://samsm.com/}
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Easy-rack-open-id", "--main", "README"]
16
- s.require_paths = ["lib"]
17
- s.rubyforge_project = %q{easy-rack-open-id}
18
- s.rubygems_version = %q{1.3.5}
19
- s.summary = %q{Super easy OpenID protection for Rack.}
20
-
21
- if s.respond_to? :specification_version then
22
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
- s.specification_version = 3
24
-
25
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
- s.add_runtime_dependency(%q<rack-openid>, [">= 0"])
27
- else
28
- s.add_dependency(%q<rack-openid>, [">= 0"])
29
- end
30
- else
31
- s.add_dependency(%q<rack-openid>, [">= 0"])
32
- end
33
- end