diff --git a/doc/app/ApplicationController.html b/doc/app/ApplicationController.html
new file mode 100644
index 0000000..b73cfb6
--- /dev/null
+++ b/doc/app/ApplicationController.html
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+ Class: ApplicationController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ApplicationController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/ApplicationHelper.html b/doc/app/ApplicationHelper.html
new file mode 100644
index 0000000..05cf608
--- /dev/null
+++ b/doc/app/ApplicationHelper.html
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+ Module: ApplicationHelper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ApplicationHelper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ camelCaseString (phrase)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+26: def camelCaseString phrase
+27: phrase .gsub! (/^[a-z]|\s+[a-z]/ ) { | a | a .upcase }
+28: return phrase
+29: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ get_album_info (album, artist)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+17: def get_album_info album , artist
+18: @result = LastFM :: Album .getInfo (album , artist )
+19: @result .album
+20: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ trimString (str, length)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+22: def trimString str , length
+23: truncate str , :length => length .to_i , :omission => "…"
+24: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ validate_img_url (image, type, size)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 4: def validate_img_url image , type , size
+ 5: @attr = (type == "gallery" ) ? "name" : "size"
+ 6: image .each do | img |
+ 7: if img [@attr ] == size .to_s
+ 8: if img ["#text" ].blank?
+ 9: return "/images/placeholder/#{type.to_s}.png"
+10: end
+11: return img ["#text" ]
+12: end
+13: end
+14:
+15: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/Artist.html b/doc/app/Artist.html
new file mode 100644
index 0000000..bd3d63f
--- /dev/null
+++ b/doc/app/Artist.html
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+ Class: Artist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Artist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/ArtistsController.html b/doc/app/ArtistsController.html
new file mode 100644
index 0000000..c0cdccb
--- /dev/null
+++ b/doc/app/ArtistsController.html
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+ Class: ArtistsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ArtistsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ album_info ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+46: def album_info
+47: @album = LastFM :: Album .getInfo CGI .unescape (params [:album ]), CGI .unescape (params [:artist ])
+48: LastFM :: Request .run_queue!
+49:
+50: render :partial= > "album_info" , :locals= > {:album= > @album }
+51: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ index ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+25: def index
+26: redirect_to :root
+27: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ more_albums ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+38: def more_albums
+39: prepare params
+40: @albums = LastFM :: Artist .getTopAlbums params [:q ], @@limit [:albums ], (params [:size ] / @@limit [:albums ] + 1 )
+41: LastFM :: Request .run_queue!
+42:
+43: render :partial= > "more_albums" , :locals= > {:albums= > @albums }
+44: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ more_tracks ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+30: def more_tracks
+31: prepare params
+32: @tracks = LastFM :: Artist .getTopTracks params [:q ], @@limit [:tracks ], (params [:size ] / @@limit [:tracks ] + 1 )
+33: LastFM :: Request .run_queue!
+34:
+35: render :partial= > "more_tracks" , :locals= > {:tracks= > @tracks }
+36: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ prepare (params)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+53: def prepare params
+54: params [:q ] = CGI .unescape params [:q ]
+55: params [:size ] = params [:size ].to_i
+56: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ show ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 7: def show
+ 8: artist = CGI .unescape params [:artist ]
+ 9:
+10: @artist = LastFM :: Artist .getInfo artist
+11: @tracks = LastFM :: Artist .getTopTracks artist , @@limit [:tracks ]
+12: @albums = LastFM :: Artist .getTopAlbums artist , @@limit [:albums ]
+13: @related = LastFM :: Artist .getSimilar artist , @@limit [:similar ]
+14:
+15: LastFM :: Request .run_queue!
+16:
+17: render :partial= > "show" , :locals= > {
+18: :artist= > @artist ,
+19: :tracks= > @tracks ,
+20: :albums= > @albums ,
+21: :related= > @related
+22: }
+23: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/ChartsController.html b/doc/app/ChartsController.html
new file mode 100644
index 0000000..ff80042
--- /dev/null
+++ b/doc/app/ChartsController.html
@@ -0,0 +1,291 @@
+
+
+
+
+
+
+ Class: ChartsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
ChartsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ index ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+3: def index
+4: @charts = LastFM :: Chart .getTopArtists 20
+5: LastFM :: Request .run_queue!
+6:
+7: render :partial= > "index"
+8: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ more ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+11: def more
+12: params [:size ] = params [:size ].to_i
+13:
+14: @charts = LastFM :: Chart .getTopArtists 20 , (params [:size ] / 20 + 1 )
+15: LastFM :: Request .run_queue!
+16:
+17: render :partial= > "more_charts" , :locals= > {:charts= > @charts }
+18: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/DeviseAuth.html b/doc/app/DeviseAuth.html
new file mode 100644
index 0000000..6b0b886
--- /dev/null
+++ b/doc/app/DeviseAuth.html
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+ Module: DeviseAuth
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
DeviseAuth
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/DeviseAuth/RegistrationsController.html b/doc/app/DeviseAuth/RegistrationsController.html
new file mode 100644
index 0000000..d726297
--- /dev/null
+++ b/doc/app/DeviseAuth/RegistrationsController.html
@@ -0,0 +1,335 @@
+
+
+
+
+
+
+ Class: DeviseAuth::RegistrationsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
DeviseAuth::RegistrationsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ create ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+12: def create
+13: build_resource
+14:
+15: if resource .save
+16: if resource .active_for_authentication?
+17: set_flash_message :notice , :signed_up if is_navigational_format?
+18: sign_in (resource_name , resource )
+19: redirect_to user_path (resource )
+20: else
+21: set_flash_message :notice , :inactive_signed_up , :reason => resource .inactive_message .to_s if is_navigational_format?
+22: expire_session_data_after_sign_in!
+23: redirect_to user_path (resource )
+24: end
+25: else
+26: clean_up_passwords (resource )
+27: respond_with_navigational (resource ) { render :partial => "devise/registrations/new" }
+28: end
+29: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ edit ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 8: def edit
+ 9: render :partial => "devise/registrations/edit"
+10: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ new ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+3: def new
+4: resource = build_resource ({})
+5: respond_with_navigational (resource ) { render :partial => "devise/registrations/new" }
+6: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/DeviseAuth/SessionsController.html b/doc/app/DeviseAuth/SessionsController.html
new file mode 100644
index 0000000..f93112d
--- /dev/null
+++ b/doc/app/DeviseAuth/SessionsController.html
@@ -0,0 +1,288 @@
+
+
+
+
+
+
+ Class: DeviseAuth::SessionsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
DeviseAuth::SessionsController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ create ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 9: def create
+10: resource = warden .authenticate! (:scope => resource_name , :recall => "#{controller_path}#new" )
+11: set_flash_message (:notice , :signed_in ) if is_navigational_format?
+12: sign_in (resource_name , resource )
+13: redirect_to "/#!/home" , :partial => "devise/registrations/new"
+14: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ new ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+3: def new
+4: resource = build_resource
+5: clean_up_passwords (resource )
+6: respond_with_navigational (resource , stub_options (resource )){ render :partial => "devise/sessions/new" }
+7: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/HomeController.html b/doc/app/HomeController.html
new file mode 100644
index 0000000..f9d6e82
--- /dev/null
+++ b/doc/app/HomeController.html
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+ Class: HomeController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
HomeController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ show ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+3: def show
+4: @charts = LastFM :: Chart .getTopArtists 10
+5: LastFM :: Request .run_queue!
+6:
+7: render :partial= > "index"
+8: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM.html b/doc/app/LastFM.html
new file mode 100644
index 0000000..6cbbd46
--- /dev/null
+++ b/doc/app/LastFM.html
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+ Module: LastFM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM/Album.html b/doc/app/LastFM/Album.html
new file mode 100644
index 0000000..fc7b6f7
--- /dev/null
+++ b/doc/app/LastFM/Album.html
@@ -0,0 +1,335 @@
+
+
+
+
+
+
+ Class: LastFM::Album
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM::Album
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getInfo (album, artist)
+ click to toggle source
+
+
+
+
+
+
+return: album name, artist, (top)tags, tracks ( name, duration (in sec) )
+mbid (album), release date, image urls ( different sizes )
+
+
+
+
+
+
+
+14: def self .getInfo album , artist
+15: RedisQueryable .look_up_key (:artist , { :hashable => [album , artist ] }) do
+16: album_request "getInfo" , "album" , album , artist do | info |
+17: info = LastFM :: Validator .validate_mash info , "tracks"
+18: info = Hashie :: Mash .new ({ :tracks => [] }) if info .blank?
+19: update_results [current_class_name , __method__ ], info
+20: RedisQueryable .store :artist , { :hashable => [album , artist ] }, info .to_json
+21: end
+22: end
+23: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopTags (album, artist)
+ click to toggle source
+
+
+
+
+
+
+return: tags ( name, tag´s last.fm-url ) ordered by popularity
+
+
+
+
+
+
+
+26: def self .getTopTags album , artist
+27: album_request "getTopTags" , "toptags" , album , artist
+28: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ search (query, limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 5: def self .search query , limit = nil , page = nil
+ 6: album_request "search" , "albummatches" , query , nil , limit , page do | result |
+ 7: result = LastFM :: Validator .validate_mash result
+ 8: result = Hashie :: Mash .new ({ :album => [] }) if result .blank?
+ 9: update_results [current_class_name , __method__ ], result
+10: end
+11: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM/Artist.html b/doc/app/LastFM/Artist.html
new file mode 100644
index 0000000..71b4537
--- /dev/null
+++ b/doc/app/LastFM/Artist.html
@@ -0,0 +1,509 @@
+
+
+
+
+
+
+ Class: LastFM::Artist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM::Artist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getImages (artist, limit = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+63: def self .getImages artist , limit = nil
+64: artist_request "getImages" , "images" , artist , limit do | images |
+65: images = LastFM :: Validator .validate_mash images , "image"
+66: images = Hashie :: Mash .new ({ :image => [] }) if images .total == "0"
+67: update_results [current_class_name , __method__ ], images
+68: end
+69: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getInfo (artist)
+ click to toggle source
+
+
+
+
+
+
+return: artist name, tags, similar artists, artist bio (summary / long),
+mbid, image urls ( different sizes )
+
+
+
+
+
+
+
+14: def self .getInfo artist
+15: RedisQueryable .look_up_key (:artist , { :hashable => artist , :type => :info }) do
+16: artist_request "getInfo" , "artist" , artist do | info |
+17: info = LastFM :: Validator .validate_mash info , "tag" , "image"
+18: update_results [current_class_name , __method__ ], info
+19: RedisQueryable .store :artist , { :hashable => artist , :type => :info }, info .to_json
+20: end
+21: end
+22: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getSimilar (artist, limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+return: artists ( name, mbid, image urls ( different sizes ) )
+
+
+
+
+
+
+
+25: def self .getSimilar artist , limit = nil , page = nil
+26: RedisQueryable .look_up_key (:artist , { :hashable => artist , :type => :similar }) do
+27: artist_request "getSimilar" , "similarartists" , artist , limit do | similar |
+28: similar = LastFM :: Validator .validate_mash similar , "tag" , "image"
+29: update_results [current_class_name , __method__ ], similar
+30: RedisQueryable .store :artist , { :hashable => artist , :type => :similar }, similar .to_json
+31: end
+32: end
+33: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopAlbums (artist, limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+return: albums ( name, mbid, album url, image urls ( different sizes ) )
+ordered by popularity
+
+
+
+
+
+
+
+52: def self .getTopAlbums artist , limit = nil , page = nil
+53: RedisQueryable .look_up_key (:artist , { :hashable => artist , :type => :albums , :page => page }) do
+54: artist_request "getTopAlbums" , "topalbums" , artist , limit , page do | albums |
+55: albums = LastFM :: Validator .validate_mash albums , "album"
+56: albums = Hashie :: Mash .new ({ :album => [] }) if albums .total == "0"
+57: update_results [current_class_name , __method__ ], albums
+58: RedisQueryable .store :artist , { :hashable => artist , :type => :albums , :page => page }, albums .to_json
+59: end
+60: end
+61: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopTags (artist)
+ click to toggle source
+
+
+
+
+
+
+return: tags ( name, tag´s last.fm-url ) ordered by popularity
+
+
+
+
+
+
+
+36: def self .getTopTags artist
+37: artist_request "getTopTags" , "toptags" , artist
+38: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopTracks (artist, limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+return: tracks ( name, image urls ( different sizes ) ) ordered by
+popularity
+
+
+
+
+
+
+
+41: def self .getTopTracks artist , limit = nil , page = nil
+42: RedisQueryable .look_up_key (:artist , { :hashable => artist , :type => :tracks , :page => page }) do
+43: artist_request "getTopTracks" , "toptracks" , artist , limit , page do | tracks |
+44: tracks = LastFM :: Validator .validate_mash tracks , "tag" , "image"
+45: update_results [current_class_name , __method__ ], tracks
+46: RedisQueryable .store :artist , { :hashable => artist , :type => :tracks , :page => page }, tracks .to_json
+47: end
+48: end
+49: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ search (query, limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 5: def self .search query , limit = nil , page = nil
+ 6: artist_request "search" , "artistmatches" , query , limit , page do | result |
+ 7: result = LastFM :: Validator .validate_mash result
+ 8: result = Hashie :: Mash .new ({ :artist => [] }) if result .blank?
+ 9: update_results [current_class_name , __method__ ], result
+10: end
+11: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM/Chart.html b/doc/app/LastFM/Chart.html
new file mode 100644
index 0000000..bf22022
--- /dev/null
+++ b/doc/app/LastFM/Chart.html
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+ Class: LastFM::Chart
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM::Chart
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopArtists (limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 4: def self .getTopArtists limit = nil , page = nil
+ 5: RedisQueryable .look_up_key (:chart , { :type => :artists , :page => page }) do
+ 6: chart_request "getTopArtists" , "artists" , limit , page do | artists |
+ 7: artists = LastFM :: Validator .validate_mash artists , "image"
+ 8: update_results [current_class_name , __method__ ], artists
+ 9: RedisQueryable .store :chart , { :type => :artists , :page => page }, artists .to_json
+10: end
+11: end
+12: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopTracks (limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+14: def self .getTopTracks limit = nil , page = nil
+15: RedisQueryable .look_up_key (:chart , { :type => :tracks , :page => page }) do
+16: chart_request "getTopTracks" , "tracks" , limit , page do | tracks |
+17: tracks = LastFM :: Validator .validate_mash tracks
+18: update_results [current_class_name , __method__ ], tracks
+19: RedisQueryable .store :chart , { :type => :tracks , :page => page }, tracks .to_json
+20: end
+21: end
+22: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM/Request.html b/doc/app/LastFM/Request.html
new file mode 100644
index 0000000..68ddb3f
--- /dev/null
+++ b/doc/app/LastFM/Request.html
@@ -0,0 +1,716 @@
+
+
+
+
+
+
+ Class: LastFM::Request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM::Request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ album_request (method, node, q, artist = nil, limit = nil, page = nil, &block)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+42: def self .album_request method , node , q , artist = nil , limit = nil , page = nil , &block
+43: request_params = default_params .merge ( :method => "#{current_class_name}.#{method}" , :album => q , :artist => artist , :limit => limit , :page => page )
+44: create_and_queue_request method , node , block , request_params
+45: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ api_key= (key)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+13: def self .api_key= (key )
+14: @@api_key = key
+15: @@default_params [:api_key ] = key
+16: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ artist_request (method, node, q, limit = nil, page = nil, &block)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+37: def self .artist_request method , node , q , limit = nil , page = nil , &block
+38: request_params = default_params .merge ( :method => "#{current_class_name}.#{method}" , :artist => q , :limit => limit , :page => page )
+39: create_and_queue_request method , node , block , request_params
+40: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ base_uri ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+18: def self .base_uri
+19: @@base_uri
+20: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ chart_request (method, node, limit = nil, page = nil, &block)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+52: def self .chart_request method , node , limit = nil , page = nil , &block
+53: request_params = default_params .merge ( :method => "#{current_class_name}.#{method}" , :limit => limit , :page => page )
+54: create_and_queue_request method , node , block , request_params
+55: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ default_params ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+22: def self .default_params
+23: @@default_params
+24: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ results (keys = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+26: def self .results keys = nil
+27: return @@results if keys .nil?
+28: @@results [("#{keys[0]}_#{keys[1]}" .to_sym )]
+29: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ run_queue! ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+31: def self .run_queue!
+32: puts "=> lastfm: Started request queue"
+33: @@hydra .run
+34: puts "=> lastfm: Queue finished"
+35: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ track_request (method, node, q, artist = nil, limit = nil, page = nil, &block)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+47: def self .track_request method , node , q , artist = nil , limit = nil , page = nil , &block
+48: request_params = default_params .merge ( :method => "#{current_class_name}.#{method}" , :track => q , :artist => artist , :limit => limit , :page => page )
+49: create_and_queue_request method , node , block , request_params
+50: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ current_class_name ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+63: def self .current_class_name
+64: self .name .split ('::' ).last .downcase!
+65: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ update_results (keys, hash)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+59: def self .update_results keys , hash
+60: @@results [("#{keys[0]}_#{keys[1]}" .to_sym )].update hash
+61: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ create_and_queue_request (method, node, block, request_params)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+69: def self .create_and_queue_request method , node , block , request_params
+70: request = Typhoeus :: Request .new (base_uri , :params => request_params )
+71: handle_response request , method , node , block
+72:
+73: puts "=> lastfm: '#{current_class_name}.#{method}' request is queued" if @@hydra .queue request
+74: @@results ["#{current_class_name}_#{method}" .to_sym ] = Hashie :: Mash .new
+75: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handle_response (request, method, node, block)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+77: def self .handle_response request , method , node , block
+78: request .on_complete do | response |
+79: if response .success?
+80: puts "=> lastfm: '#{current_class_name}.#{method}' (#{response.time}s)"
+81:
+82: hash = Hashie :: Mash .new (JSON .parse (response .body ))
+83: hash = method .to_s == "search" ? hash .results .send (node .to_sym ) : hash .send (node .to_sym )
+84:
+85: update_results [current_class_name , method ], hash if hash .present? and block .nil?
+86: block .call ( hash ) unless block .nil?
+87:
+88: elsif response .timed_out?
+89: puts "=> lastfm: '#{current_class_name}.#{method}' timed out"
+90: end
+91: end
+92: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM/Track.html b/doc/app/LastFM/Track.html
new file mode 100644
index 0000000..29144f2
--- /dev/null
+++ b/doc/app/LastFM/Track.html
@@ -0,0 +1,367 @@
+
+
+
+
+
+
+ Class: LastFM::Track
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM::Track
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getInfo (track, artist)
+ click to toggle source
+
+
+
+
+
+
+return: track name, id, (top)tags, artist, duration (in msec), album (
+artist, title, image urls ( different sizes) ), mbid
+
+
+
+
+
+
+
+13: def self .getInfo track , artist
+14: track_request "getInfo" , nil , track , artist
+15: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getSimilar (track, artist, limit = nil)
+ click to toggle source
+
+
+
+
+
+
+return: tracks ( name, artist (name, mbid), duration (in msec), image urls
+(sometimes) )
+
+
+
+
+
+
+
+18: def self .getSimilar track , artist , limit = nil
+19: track_request "getSimilar" , "similartracks" , track , artist , limit
+20: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getTopTags (track, artist)
+ click to toggle source
+
+
+
+
+
+
+return: tags ( name, tag´s last.fm-url ) ordered by popularity
+
+
+
+
+
+
+
+23: def self .getTopTags track , artist
+24: track_request "getTopTags" , "toptags" , track , artist
+25: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ search (query, limit = nil, page = nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 4: def self .search query , limit = nil , page = nil
+ 5: track_request "search" , "trackmatches" , query , nil , limit , page do | result |
+ 6: result = LastFM :: Validator .validate_mash result
+ 7: result = Hashie :: Mash .new ({ :track => [] }) if result .blank?
+ 8: update_results [current_class_name , __method__ ], result
+ 9: end
+10: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/LastFM/Validator.html b/doc/app/LastFM/Validator.html
new file mode 100644
index 0000000..ca076bf
--- /dev/null
+++ b/doc/app/LastFM/Validator.html
@@ -0,0 +1,257 @@
+
+
+
+
+
+
+ Module: LastFM::Validator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LastFM::Validator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ validate_mash (mash, *args)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 5: def self .validate_mash mash , *args
+ 6: args .flatten!
+ 7:
+ 8: return [] if mash .blank?
+ 9:
+10: mash .each do | key , value |
+11: if args .include? key .to_s || value .is_a? (Array )
+12: mash [key ] = Array .wrap value
+13: mash [key ].map do | mashie |
+14: validate_mash mashie , args
+15: end
+16: elsif value .is_a? Hashie :: Mash
+17: mash [key ] = validate_mash mash [key ], args
+18: end
+19: mash [key ] = "" if value .blank? && value .is_a? (String )
+20: mash [key ] = [] if value .blank? && value .is_a? (Array )
+21: end
+22:
+23: return mash
+24: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/Playlist.html b/doc/app/Playlist.html
new file mode 100644
index 0000000..29248d4
--- /dev/null
+++ b/doc/app/Playlist.html
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+ Class: Playlist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Playlist
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/PlaylistsTracks.html b/doc/app/PlaylistsTracks.html
new file mode 100644
index 0000000..ef46176
--- /dev/null
+++ b/doc/app/PlaylistsTracks.html
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+ Class: PlaylistsTracks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
PlaylistsTracks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/RedisQueryable.html b/doc/app/RedisQueryable.html
new file mode 100644
index 0000000..a92c312
--- /dev/null
+++ b/doc/app/RedisQueryable.html
@@ -0,0 +1,459 @@
+
+
+
+
+
+
+ Module: RedisQueryable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
RedisQueryable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ get (namespace, key_hash)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+18: def self .get namespace , key_hash
+19: key = build_key key_hash .values
+20: redis = switch_to_namespace namespace
+21: json = redis .get key
+22: Hashie :: Mash .new (JSON .parse (json ))
+23: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ look_up_key (namespace, key_hash, &block)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+25: def self .look_up_key namespace , key_hash , &block
+26: if exists_key? namespace , key_hash
+27: get namespace , key_hash
+28: else
+29: block .call
+30: end
+31: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ store (namespace, key_hash, value)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+10: def self .store namespace , key_hash , value
+11: key = build_key key_hash .values
+12: redis = switch_to_namespace namespace
+13:
+14: expires = key_hash .has_key? (:type ) ? EXPIRATION [namespace ][key_hash [:type ]] : EXPIRATION [namespace ]
+15: redis .setex key , expires .to_i .days , value
+16: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ build_key (key_array)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+42: def self .build_key key_array
+43: key_array .flatten .map do | value |
+44: value .is_a? (String ) ? Digest :: SHA1 .hexdigest (value ) : value .to_s
+45: end .join (":" )
+46: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ exists_key? (namespace, key_hash)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+36: def self .exists_key? namespace , key_hash
+37: key = build_key key_hash .values
+38: redis = switch_to_namespace namespace
+39: redis .exists key
+40: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ switch_to_namespace (namespace)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+48: def self .switch_to_namespace namespace
+49: return Redis :: Namespace .new (namespace , :redis => $redis ) if VALID_NAMESPACES .include? namespace
+50: $redis
+51: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/SearchController.html b/doc/app/SearchController.html
new file mode 100644
index 0000000..2c2a695
--- /dev/null
+++ b/doc/app/SearchController.html
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+ Class: SearchController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SearchController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ autocomplete ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+21: def autocomplete
+22: q = params [:q ].to_s .lstrip
+23:
+24: @artists = $sevendigital_client .artist .search q , { :pagesize= > 5 }
+25:
+26: render :partial= > "autocomplete" , :locals= > { :artists= > @artists }
+27: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ more_artists ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+29: def more_artists
+30: @artists = LastFM :: Artist .search params [:q ].to_s .lstrip , @@limit [:artists ], (params [:size ].to_i / @@limit [:artists ] + 1 )
+31: LastFM :: Request .run_queue!
+32:
+33: render :partial= > "more_artists" , :locals= > {:artists= > @artists }
+34: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ show ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 5: def show
+ 6: @q = params [:id ].to_s .lstrip
+ 7:
+ 8: @artists = LastFM :: Artist .search @q , @@limit [:artists ]
+ 9: @tracks = LastFM :: Track .search @q , @@limit [:tracks ]
+10: @albums = LastFM :: Album .search @q , @@limit [:albums ]
+11:
+12: LastFM :: Request .run_queue!
+13:
+14: render :partial= > "show" , :locals= > {
+15: :artist= > @artist ,
+16: :tracks= > @tracks ,
+17: :albums= > @albums
+18: }
+19: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/Track.html b/doc/app/Track.html
new file mode 100644
index 0000000..4f8e3d8
--- /dev/null
+++ b/doc/app/Track.html
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+ Class: Track
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Track
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/TracksController.html b/doc/app/TracksController.html
new file mode 100644
index 0000000..5d26117
--- /dev/null
+++ b/doc/app/TracksController.html
@@ -0,0 +1,286 @@
+
+
+
+
+
+
+ Class: TracksController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
TracksController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ index ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+2: def index
+3: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ search_video ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 5: def search_video
+ 6:
+ 7: @video = @youtube_client .videos_by (:query => "#{CGI.unescape(params[:artist])} #{CGI.unescape(params[:track])} official" , :page => 1 , :per_page => 1 , :order_by => "relevance" )
+ 8: @id = @video .videos .first .unique_id
+ 9:
+10: render :partial= > "video_id" , :locals= > {:id= > @id }
+11: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/User.html b/doc/app/User.html
new file mode 100644
index 0000000..591585d
--- /dev/null
+++ b/doc/app/User.html
@@ -0,0 +1,333 @@
+
+
+
+
+
+
+ Class: User
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
User
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ find_for_facebook_oauth (access_token, signed_in_resource=nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+21: def self .find_for_facebook_oauth (access_token , signed_in_resource =nil )
+22: data = access_token ['extra' ]['user_hash' ]
+23: if user = User .find_by_email (data ["email" ])
+24: user
+25: else
+26: User .create! (:email => data ["email" ], :password => Devise .friendly_token [0 ,20 ])
+27: end
+28: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ find_for_open_id (access_token, signed_in_resource=nil)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+30: def self .find_for_open_id (access_token , signed_in_resource =nil )
+31: data = access_token ['user_info' ]
+32: if user = User .find_by_email (data ["email" ])
+33: user
+34: else
+35: User .create! (:email => data ["email" ], :password => Devise .friendly_token [0 ,20 ])
+36: end
+37: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ new_with_session (params, session)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+13: def self .new_with_session (params , session )
+14: super .tap do | user |
+15: if data = session ["devise.facebook_data" ] && session ["devise.facebook_data" ]["extra" ]["user_hash" ]
+16: user .email = data ["email" ]
+17: end
+18: end
+19: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/Users.html b/doc/app/Users.html
new file mode 100644
index 0000000..a4bc7ca
--- /dev/null
+++ b/doc/app/Users.html
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+ Module: Users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/Users/OmniauthCallbacksController.html b/doc/app/Users/OmniauthCallbacksController.html
new file mode 100644
index 0000000..5cc2bcc
--- /dev/null
+++ b/doc/app/Users/OmniauthCallbacksController.html
@@ -0,0 +1,336 @@
+
+
+
+
+
+
+ Class: Users::OmniauthCallbacksController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Users::OmniauthCallbacksController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ facebook ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+ 3: def facebook
+ 4:
+ 5: @user = User .find_for_facebook_oauth (env ["omniauth.auth" ], current_user )
+ 6:
+ 7: if @user .persisted?
+ 8: flash [:notice ] = I18n .t "devise.omniauth_callbacks.success" , :kind => "Facebook"
+ 9: sign_in_and_redirect @user , :event => :authentication
+10: else
+11: session ["devise.facebook_data" ] = env ["omniauth.auth" ]
+12: redirect_to new_user_registration_url
+13: end
+14: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ open_id ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+16: def open_id
+17:
+18: @user = User .find_for_open_id (env ["omniauth.auth" ], current_user )
+19: if @user .persisted?
+20: flash [:notice ] = I18n .t "devise.omniauth_callbacks.success" , :kind => "Google"
+21: sign_in_and_redirect @user , :event => :authentication
+22: else
+23: session ["devise.open:id_data" ] = env ["openid.ext1" ]
+24: redirect_to new_user_registration_url
+25: end
+26: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ passthru ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+28: def passthru
+29: render :file => "#{Rails.root}/public/404.html" , :status => 404 , :layout => false
+30: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/UsersController.html b/doc/app/UsersController.html
new file mode 100644
index 0000000..e1ec194
--- /dev/null
+++ b/doc/app/UsersController.html
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+ Class: UsersController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
UsersController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ show ()
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+2: def show
+3: @user = User .find params [:id ]
+4: puts @user .inspect
+5: render :partial => "show" , :locals => { :user => @user }
+6: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/UsersHelper.html b/doc/app/UsersHelper.html
new file mode 100644
index 0000000..76e4bf8
--- /dev/null
+++ b/doc/app/UsersHelper.html
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+ Module: UsersHelper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
UsersHelper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ validate_avatar_url (url)
+ click to toggle source
+
+
+
+
+
+
+
+
+
+
+
+
+3: def validate_avatar_url url
+4: return url if url .present? and FileTest .exists? url
+5: "examples/user-big.jpg"
+6: end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/YoutubeVideoRating.html b/doc/app/YoutubeVideoRating.html
new file mode 100644
index 0000000..33aea44
--- /dev/null
+++ b/doc/app/YoutubeVideoRating.html
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+ Class: YoutubeVideoRating
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
YoutubeVideoRating
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Disabled; run with --debug to generate this.
+
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/application_controller_rb.html b/doc/app/app/controllers/application_controller_rb.html
new file mode 100644
index 0000000..f8428e1
--- /dev/null
+++ b/doc/app/app/controllers/application_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: application_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/artists_controller_rb.html b/doc/app/app/controllers/artists_controller_rb.html
new file mode 100644
index 0000000..6819fa2
--- /dev/null
+++ b/doc/app/app/controllers/artists_controller_rb.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+ File: artists_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/charts_controller_rb.html b/doc/app/app/controllers/charts_controller_rb.html
new file mode 100644
index 0000000..4eec18a
--- /dev/null
+++ b/doc/app/app/controllers/charts_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: charts_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/devise_auth/registrations_controller_rb.html b/doc/app/app/controllers/devise_auth/registrations_controller_rb.html
new file mode 100644
index 0000000..bc54481
--- /dev/null
+++ b/doc/app/app/controllers/devise_auth/registrations_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: registrations_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/devise_auth/sessions_controller_rb.html b/doc/app/app/controllers/devise_auth/sessions_controller_rb.html
new file mode 100644
index 0000000..5277ea0
--- /dev/null
+++ b/doc/app/app/controllers/devise_auth/sessions_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: sessions_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/home_controller_rb.html b/doc/app/app/controllers/home_controller_rb.html
new file mode 100644
index 0000000..73233cd
--- /dev/null
+++ b/doc/app/app/controllers/home_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: home_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/search_controller_rb.html b/doc/app/app/controllers/search_controller_rb.html
new file mode 100644
index 0000000..95a3e1d
--- /dev/null
+++ b/doc/app/app/controllers/search_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: search_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/tracks_controller_rb.html b/doc/app/app/controllers/tracks_controller_rb.html
new file mode 100644
index 0000000..67fc2fe
--- /dev/null
+++ b/doc/app/app/controllers/tracks_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: tracks_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/users/omniauth_callbacks_controller_rb.html b/doc/app/app/controllers/users/omniauth_callbacks_controller_rb.html
new file mode 100644
index 0000000..0da18ff
--- /dev/null
+++ b/doc/app/app/controllers/users/omniauth_callbacks_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: omniauth_callbacks_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/controllers/users_controller_rb.html b/doc/app/app/controllers/users_controller_rb.html
new file mode 100644
index 0000000..7147ed2
--- /dev/null
+++ b/doc/app/app/controllers/users_controller_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: users_controller.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/helpers/application_helper_rb.html b/doc/app/app/helpers/application_helper_rb.html
new file mode 100644
index 0000000..b88e026
--- /dev/null
+++ b/doc/app/app/helpers/application_helper_rb.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ File: application_helper.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+encoding: UTF-8
+
+
+
+
+
+
+
+
diff --git a/doc/app/app/helpers/users_helper_rb.html b/doc/app/app/helpers/users_helper_rb.html
new file mode 100644
index 0000000..7eb8da8
--- /dev/null
+++ b/doc/app/app/helpers/users_helper_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: users_helper.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/models/artist_rb.html b/doc/app/app/models/artist_rb.html
new file mode 100644
index 0000000..2f5c2bc
--- /dev/null
+++ b/doc/app/app/models/artist_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: artist.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/models/playlist_rb.html b/doc/app/app/models/playlist_rb.html
new file mode 100644
index 0000000..96e6527
--- /dev/null
+++ b/doc/app/app/models/playlist_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: playlist.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/models/playlists_tracks_rb.html b/doc/app/app/models/playlists_tracks_rb.html
new file mode 100644
index 0000000..a04f74e
--- /dev/null
+++ b/doc/app/app/models/playlists_tracks_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: playlists_tracks.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/models/track_rb.html b/doc/app/app/models/track_rb.html
new file mode 100644
index 0000000..e80bc2f
--- /dev/null
+++ b/doc/app/app/models/track_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: track.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/models/user_rb.html b/doc/app/app/models/user_rb.html
new file mode 100644
index 0000000..e9aa1c4
--- /dev/null
+++ b/doc/app/app/models/user_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: user.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/app/models/youtube_video_rating_rb.html b/doc/app/app/models/youtube_video_rating_rb.html
new file mode 100644
index 0000000..437c3e8
--- /dev/null
+++ b/doc/app/app/models/youtube_video_rating_rb.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+ File: youtube_video_rating.rb [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
diff --git a/doc/app/created.rid b/doc/app/created.rid
new file mode 100644
index 0000000..7806ac3
--- /dev/null
+++ b/doc/app/created.rid
@@ -0,0 +1,27 @@
+Mon, 13 Jun 2011 14:50:55 +0200
+doc/README_FOR_APP Mon, 02 May 2011 20:00:11 +0200
+app/controllers/application_controller.rb Sun, 12 Jun 2011 16:26:41 +0200
+app/controllers/artists_controller.rb Sun, 12 Jun 2011 16:22:34 +0200
+app/controllers/charts_controller.rb Sun, 12 Jun 2011 01:46:19 +0200
+app/controllers/devise_auth/registrations_controller.rb Fri, 10 Jun 2011 02:24:59 +0200
+app/controllers/devise_auth/sessions_controller.rb Fri, 10 Jun 2011 02:24:59 +0200
+app/controllers/home_controller.rb Fri, 10 Jun 2011 00:41:53 +0200
+app/controllers/search_controller.rb Fri, 10 Jun 2011 01:00:15 +0200
+app/controllers/tracks_controller.rb Thu, 09 Jun 2011 06:14:15 +0200
+app/controllers/users/omniauth_callbacks_controller.rb Mon, 06 Jun 2011 14:10:23 +0200
+app/controllers/users_controller.rb Fri, 10 Jun 2011 02:24:59 +0200
+app/helpers/application_helper.rb Wed, 08 Jun 2011 22:33:20 +0200
+app/helpers/users_helper.rb Fri, 10 Jun 2011 02:24:59 +0200
+app/models/artist.rb Mon, 06 Jun 2011 14:10:23 +0200
+app/models/playlist.rb Fri, 10 Jun 2011 02:24:59 +0200
+app/models/playlists_tracks.rb Mon, 06 Jun 2011 14:10:23 +0200
+app/models/track.rb Wed, 08 Jun 2011 03:11:10 +0200
+app/models/user.rb Fri, 10 Jun 2011 02:24:59 +0200
+app/models/youtube_video_rating.rb Mon, 06 Jun 2011 14:10:23 +0200
+lib/last_fm/album.rb Fri, 10 Jun 2011 02:24:59 +0200
+lib/last_fm/artist.rb Fri, 10 Jun 2011 02:24:59 +0200
+lib/last_fm/chart.rb Fri, 10 Jun 2011 02:24:59 +0200
+lib/last_fm/request.rb Mon, 13 Jun 2011 14:46:39 +0200
+lib/last_fm/track.rb Fri, 10 Jun 2011 00:41:53 +0200
+lib/last_fm/validator.rb Wed, 08 Jun 2011 03:11:10 +0200
+lib/redis_queryable.rb Fri, 10 Jun 2011 02:24:59 +0200
diff --git a/doc/app/doc/README_FOR_APP.html b/doc/app/doc/README_FOR_APP.html
new file mode 100644
index 0000000..fee587a
--- /dev/null
+++ b/doc/app/doc/README_FOR_APP.html
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+ File: README_FOR_APP [Rails Application Documentation]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Use this README file to introduce your application and point to useful
+places in the API for learning more.
Run “rake doc:app” to
+generate API documentation for your models, controllers, helpers, and
+libraries.
+
+
+
+
+
+
+
+
diff --git a/doc/app/images/brick.png b/doc/app/images/brick.png
new file mode 100644
index 0000000..7851cf3
Binary files /dev/null and b/doc/app/images/brick.png differ
diff --git a/doc/app/images/brick_link.png b/doc/app/images/brick_link.png
new file mode 100644
index 0000000..9ebf013
Binary files /dev/null and b/doc/app/images/brick_link.png differ
diff --git a/doc/app/images/bug.png b/doc/app/images/bug.png
new file mode 100644
index 0000000..2d5fb90
Binary files /dev/null and b/doc/app/images/bug.png differ
diff --git a/doc/app/images/bullet_black.png b/doc/app/images/bullet_black.png
new file mode 100644
index 0000000..5761970
Binary files /dev/null and b/doc/app/images/bullet_black.png differ
diff --git a/doc/app/images/bullet_toggle_minus.png b/doc/app/images/bullet_toggle_minus.png
new file mode 100644
index 0000000..b47ce55
Binary files /dev/null and b/doc/app/images/bullet_toggle_minus.png differ
diff --git a/doc/app/images/bullet_toggle_plus.png b/doc/app/images/bullet_toggle_plus.png
new file mode 100644
index 0000000..9ab4a89
Binary files /dev/null and b/doc/app/images/bullet_toggle_plus.png differ
diff --git a/doc/app/images/date.png b/doc/app/images/date.png
new file mode 100644
index 0000000..783c833
Binary files /dev/null and b/doc/app/images/date.png differ
diff --git a/doc/app/images/find.png b/doc/app/images/find.png
new file mode 100644
index 0000000..1547479
Binary files /dev/null and b/doc/app/images/find.png differ
diff --git a/doc/app/images/loadingAnimation.gif b/doc/app/images/loadingAnimation.gif
new file mode 100644
index 0000000..82290f4
Binary files /dev/null and b/doc/app/images/loadingAnimation.gif differ
diff --git a/doc/app/images/macFFBgHack.png b/doc/app/images/macFFBgHack.png
new file mode 100644
index 0000000..c6473b3
Binary files /dev/null and b/doc/app/images/macFFBgHack.png differ
diff --git a/doc/app/images/package.png b/doc/app/images/package.png
new file mode 100644
index 0000000..da3c2a2
Binary files /dev/null and b/doc/app/images/package.png differ
diff --git a/doc/app/images/page_green.png b/doc/app/images/page_green.png
new file mode 100644
index 0000000..de8e003
Binary files /dev/null and b/doc/app/images/page_green.png differ
diff --git a/doc/app/images/page_white_text.png b/doc/app/images/page_white_text.png
new file mode 100644
index 0000000..813f712
Binary files /dev/null and b/doc/app/images/page_white_text.png differ
diff --git a/doc/app/images/page_white_width.png b/doc/app/images/page_white_width.png
new file mode 100644
index 0000000..1eb8809
Binary files /dev/null and b/doc/app/images/page_white_width.png differ
diff --git a/doc/app/images/plugin.png b/doc/app/images/plugin.png
new file mode 100644
index 0000000..6187b15
Binary files /dev/null and b/doc/app/images/plugin.png differ
diff --git a/doc/app/images/ruby.png b/doc/app/images/ruby.png
new file mode 100644
index 0000000..f763a16
Binary files /dev/null and b/doc/app/images/ruby.png differ
diff --git a/doc/app/images/tag_green.png b/doc/app/images/tag_green.png
new file mode 100644
index 0000000..83ec984
Binary files /dev/null and b/doc/app/images/tag_green.png differ
diff --git a/doc/app/images/wrench.png b/doc/app/images/wrench.png
new file mode 100644
index 0000000..5c8213f
Binary files /dev/null and b/doc/app/images/wrench.png differ
diff --git a/doc/app/images/wrench_orange.png b/doc/app/images/wrench_orange.png
new file mode 100644
index 0000000..565a933
Binary files /dev/null and b/doc/app/images/wrench_orange.png differ
diff --git a/doc/app/images/zoom.png b/doc/app/images/zoom.png
new file mode 100644
index 0000000..908612e
Binary files /dev/null and b/doc/app/images/zoom.png differ
diff --git a/doc/app/index.html b/doc/app/index.html
new file mode 100644
index 0000000..6158d4f
--- /dev/null
+++ b/doc/app/index.html
@@ -0,0 +1,244 @@
+
+
+
+
+
+
+
+ Rails Application Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+ Rails Application Documentation
+
+
+ This is the API documentation for 'Rails Application Documentation'.
+
+
+
+
+ Files
+
+
+
+ Classes/Modules
+
+
+ Methods
+
+
+
+
+
diff --git a/doc/app/js/darkfish.js b/doc/app/js/darkfish.js
new file mode 100644
index 0000000..84565c1
--- /dev/null
+++ b/doc/app/js/darkfish.js
@@ -0,0 +1,116 @@
+/**
+ *
+ * Darkfish Page Functions
+ * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $
+ *
+ * Author: Michael Granger
+ *
+ */
+
+/* Provide console simulation for firebug-less environments */
+if (!("console" in window) || !("firebug" in console)) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+ "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {};
+};
+
+
+/**
+ * Unwrap the first element that matches the given @expr@ from the targets and return them.
+ */
+$.fn.unwrap = function( expr ) {
+ return this.each( function() {
+ $(this).parents( expr ).eq( 0 ).after( this ).remove();
+ });
+};
+
+
+function showSource( e ) {
+ var target = e.target;
+ var codeSections = $(target).
+ parents('.method-detail').
+ find('.method-source-code');
+
+ $(target).
+ parents('.method-detail').
+ find('.method-source-code').
+ slideToggle();
+};
+
+function hookSourceViews() {
+ $('.method-description,.method-heading').click( showSource );
+};
+
+function toggleDebuggingSection() {
+ $('.debugging-section').slideToggle();
+};
+
+function hookDebuggingToggle() {
+ $('#debugging-toggle img').click( toggleDebuggingSection );
+};
+
+function hookQuickSearch() {
+ $('.quicksearch-field').each( function() {
+ var searchElems = $(this).parents('.section').find( 'li' );
+ var toggle = $(this).parents('.section').find('h3 .search-toggle');
+ // console.debug( "Toggle is: %o", toggle );
+ var qsbox = $(this).parents('form').get( 0 );
+
+ $(this).quicksearch( this, searchElems, {
+ noSearchResultsIndicator: 'no-class-search-results',
+ focusOnLoad: false
+ });
+ $(toggle).click( function() {
+ // console.debug( "Toggling qsbox: %o", qsbox );
+ $(qsbox).toggle();
+ });
+ });
+};
+
+function highlightTarget( anchor ) {
+ console.debug( "Highlighting target '%s'.", anchor );
+
+ $("a[name=" + anchor + "]").each( function() {
+ if ( !$(this).parent().parent().hasClass('target-section') ) {
+ console.debug( "Wrapping the target-section" );
+ $('div.method-detail').unwrap( 'div.target-section' );
+ $(this).parent().wrap( '
' );
+ } else {
+ console.debug( "Already wrapped." );
+ }
+ });
+};
+
+function highlightLocationTarget() {
+ console.debug( "Location hash: %s", window.location.hash );
+ if ( ! window.location.hash || window.location.hash.length == 0 ) return;
+
+ var anchor = window.location.hash.substring(1);
+ console.debug( "Found anchor: %s; matching %s", anchor, "a[name=" + anchor + "]" );
+
+ highlightTarget( anchor );
+};
+
+function highlightClickTarget( event ) {
+ console.debug( "Highlighting click target for event %o", event.target );
+ try {
+ var anchor = $(event.target).attr( 'href' ).substring(1);
+ console.debug( "Found target anchor: %s", anchor );
+ highlightTarget( anchor );
+ } catch ( err ) {
+ console.error( "Exception while highlighting: %o", err );
+ };
+};
+
+
+$(document).ready( function() {
+ hookSourceViews();
+ hookDebuggingToggle();
+ hookQuickSearch();
+ highlightLocationTarget();
+
+ $('ul.link-list a').bind( "click", highlightClickTarget );
+});
diff --git a/doc/app/js/jquery.js b/doc/app/js/jquery.js
new file mode 100644
index 0000000..afe9e74
--- /dev/null
+++ b/doc/app/js/jquery.js
@@ -0,0 +1,32 @@
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-09-25 09:50:52 -0700 (Thu, 25 Sep 2008) $
+ * $Rev: 38 $
+ */
+(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
+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
+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
+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=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
+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
+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
+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-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
+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]*?)\/>/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("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,""]||!tags.indexOf(""," "]||(!tags.indexOf(""," "]||!tags.indexOf(""," "]||jQuery.browser.msie&&[1,"div","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=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
+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&¬xml&&!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&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&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
+while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",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 im[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=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=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=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
+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=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("
").append(res.responseText.replace(/
+
+
+
+
+
+
+
+
+
+
+
+
Description
+
+
+
+
+
+