video_info 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/README.md +63 -63
  4. data/lib/video_info/providers/vkontakte.rb +75 -16
  5. data/lib/video_info/version.rb +1 -1
  6. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_invalid_video/{_available_ → available_}/.yml +2 -2
  7. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_private_video/available_/.yml +382 -0
  8. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_redirect/available_/.yml +210 -0
  9. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_redirect_to_main_page_for_auth/available_/.yml +46 -0
  10. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_valid_video/available_/.yml +1655 -0
  11. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/description/.yml +387 -0
  12. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/duration/.yml +389 -0
  13. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/embed_code/.yml +387 -0
  14. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/embed_url/.yml +388 -0
  15. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/height/.yml +392 -0
  16. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/keywords/.yml +388 -0
  17. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/title/.yml +388 -0
  18. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/view_count/.yml +388 -0
  19. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_kirill_lyanoi_z_video2152699_168591741_2F56fd229a9dfe2dcdbe/width/.yml +389 -0
  20. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video-54799401_165822734/title/.yml +636 -0
  21. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/description/.yml +522 -0
  22. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/duration/.yml +522 -0
  23. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/embed_code/.yml +522 -0
  24. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/embed_url/.yml +521 -0
  25. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/height/.yml +522 -0
  26. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/keywords/.yml +522 -0
  27. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/title/.yml +523 -0
  28. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/view_count/.yml +522 -0
  29. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/width/.yml +522 -0
  30. data/spec/lib/video_info/providers/vkontakte_spec.rb +77 -91
  31. metadata +50 -26
  32. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/_available_/with_valid_video/_available_/.yml +0 -1163
  33. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video-54799401_165822734/_title/.yml +0 -1474
  34. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_description/.yml +0 -1163
  35. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_duration/.yml +0 -1163
  36. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_embed_code/.yml +0 -1163
  37. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_embed_url/.yml +0 -1163
  38. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_height/.yml +0 -1163
  39. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_keywords/.yml +0 -1163
  40. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_title/.yml +0 -1163
  41. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_view_count/.yml +0 -1163
  42. data/spec/fixtures/vcr_cassettes/VideoInfo_Providers_Vkontakte/with_video_video39576223_108370515/_width/.yml +0 -1163
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f40dace9501dc0754efd519f98cf23d6eb037281
4
- data.tar.gz: d486727f7fc75c2246d80686d9ccf44c1f8aa15b
3
+ metadata.gz: d3f2c0c33951520e7ff278cf2a7b266b4e36b198
4
+ data.tar.gz: 5f2039ecb7c7806f98fecbac674e9bc42f6df4d0
5
5
  SHA512:
6
- metadata.gz: faad587f1bfea1c7a37a9d134521b13e3ba7bfd892eda1e6dce7ab3a5b44510f3f7770957206a9139105fa77f3c664daef9134f52e1148a094b13e638b935d5d
7
- data.tar.gz: f0d1f569b0ddafab94d51b0ebef7f0e8a4ec0f1f47cbde0f1fead7a68ee9ceb052b7908c65f053679959e274d72868d63be79a5c0062bbfbb790ded3efab8db3
6
+ metadata.gz: f4fb805ce04d7ff0a250cbec4c56a605e3d1b0b63d4e7e9796b2309e7179a60dd61d0230e249267d1edb882b81cf0670fa53233d25b700bf49e326ec933ca84c
7
+ data.tar.gz: 8ae8fdd233abdc27c6bb2c1d146c957b5458c17d9819ffa0cd1e5510354eb895f75cc1a389d54d98089d0d59912e8b4cd38c12f0b7265c69e80805ebf737b4cb
@@ -4,6 +4,7 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1.0
7
+ - 2.2.0
7
8
  - jruby
8
9
  - rbx
9
10
  matrix:
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/video_info.png)](http://badge.fury.io/rb/video_info) [![Build Status](https://travis-ci.org/thibaudgg/video_info.png?branch=master)](https://travis-ci.org/thibaudgg/video_info) [![Dependency Status](https://gemnasium.com/thibaudgg/video_info.png)](https://gemnasium.com/thibaudgg/video_info) [![Code Climate](https://codeclimate.com/github/thibaudgg/video_info.png)](https://codeclimate.com/github/thibaudgg/video_info) [![Coverage Status](https://coveralls.io/repos/thibaudgg/video_info/badge.png?branch=master)](https://coveralls.io/r/thibaudgg/video_info)
4
4
 
5
- Simple Ruby Gem to get video info from Dailymotion, Vimeo (with playlist support), VK and YouTube (with playlist support).
5
+ Simple Ruby Gem to get video info from Dailymotion, VK, Vimeo (with playlist), Wistia and YouTube (with playlist).
6
6
 
7
7
  Tested against Ruby 1.9.3, 2.0.0, 2.1.0 and the latest versions of JRuby & Rubinius.
8
8
 
@@ -17,87 +17,87 @@ Usage
17
17
  -----
18
18
 
19
19
  ``` ruby
20
- video = VideoInfo.new("http://www.dailymotion.com/video/x7lni3")
20
+ video = VideoInfo.new('http://www.dailymotion.com/video/x7lni3')
21
21
  # video.available? => true
22
- # video.video_id => "x7lni3"
23
- # video.provider => "Dailymotion"
24
- # video.title => "Mario Kart (Rémi Gaillard)"
25
- # video.description => "Super Rémi Kart est un jeu vidéo de course développé et édité par N'Importe Quoi TV."
22
+ # video.video_id => 'x7lni3'
23
+ # video.provider => 'Dailymotion'
24
+ # video.title => 'Mario Kart (Rémi Gaillard)'
25
+ # video.description => 'Super Rémi Kart est un jeu vidéo de course développé et édité par N'Importe Quoi TV.'
26
26
  # video.duration => 136 (in seconds)
27
27
  # video.date => Mon Mar 03 16:29:31 UTC 2008
28
- # video.thumbnail_small => "http://s2.dmcdn.net/BgWxI/x60-kbf.jpg"
29
- # video.thumbnail_medium => "http://s2.dmcdn.net/BgWxI/x240-b83.jpg"
30
- # video.thumbnail_large => "http://s2.dmcdn.net/BgWxI/x720-YcV.jpg"
31
- # video.embed_url => "http://www.dailymotion.com/embed/video/x7lni3"
32
- # video.embed_code => "'<iframe src="//www.dailymotion.com/embed/video/x7lni3" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'"
28
+ # video.thumbnail_small => 'http://s2.dmcdn.net/BgWxI/x60-kbf.jpg'
29
+ # video.thumbnail_medium => 'http://s2.dmcdn.net/BgWxI/x240-b83.jpg'
30
+ # video.thumbnail_large => 'http://s2.dmcdn.net/BgWxI/x720-YcV.jpg'
31
+ # video.embed_url => 'http://www.dailymotion.com/embed/video/x7lni3'
32
+ # video.embed_code => "<iframe src='//www.dailymotion.com/embed/video/x7lni3' frameborder='0' allowfullscreen='allowfullscreen'></iframe>"
33
33
 
34
34
  video = VideoInfo.new("http://vimeo.com/898029")
35
35
  # video.available? => true
36
- # video.video_id => "898029"
37
- # video.provider => "Vimeo"
38
- # video.title => "Cherry Bloom - King Of The Knife"
39
- # video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
40
- # video.keywords => "alternative, bloom, cherry, clip, drum, guitar, king, knife, of, Paris-Forum, rock, the, tremplin"
36
+ # video.video_id => '898029'
37
+ # video.provider => 'Vimeo'
38
+ # video.title => 'Cherry Bloom - King Of The Knife'
39
+ # video.description => 'The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net'
40
+ # video.keywords => 'alternative, bloom, cherry, clip, drum, guitar, king, knife, of, Paris-Forum, rock, the, tremplin'
41
41
  # video.duration => 175 (in seconds)
42
42
  # video.date => Mon Apr 14 13:10:39 +0200 2008
43
43
  # video.width => 640
44
44
  # video.height => 360
45
- # video.thumbnail_small => "http://b.vimeocdn.com/ts/343/731/34373130_100.jpg"
46
- # video.thumbnail_medium => "http://b.vimeocdn.com/ts/343/731/34373130_200.jpg"
47
- # video.thumbnail_large => "http://b.vimeocdn.com/ts/343/731/34373130_640.jpg"
48
- # video.embed_url => "http://player.vimeo.com/video/898029"
49
- # video.embed_code => "'<iframe src="//player.vimeo.com/video/898029?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0" frameborder="0"></iframe>'"
45
+ # video.thumbnail_small => 'http://b.vimeocdn.com/ts/343/731/34373130_100.jpg'
46
+ # video.thumbnail_medium => 'http://b.vimeocdn.com/ts/343/731/34373130_200.jpg'
47
+ # video.thumbnail_large => 'http://b.vimeocdn.com/ts/343/731/34373130_640.jpg'
48
+ # video.embed_url => 'http://player.vimeo.com/video/898029'
49
+ # video.embed_code => "<iframe src='//player.vimeo.com/video/898029?title=0&amp;byline=0&amp;portrait=0&amp;autoplay=0' frameborder='0'></iframe>"
50
50
 
51
51
  video = VideoInfo.new("http://fast.wistia.com/embed/medias/pxonqr42is")
52
52
  # video.available? => true
53
- # video.provider => "Wistia"
54
- # video.video_id => "pxonqr42is"
55
- # video.title => "Understanding Analytics"
53
+ # video.provider => 'Wistia'
54
+ # video.video_id => 'pxonqr42is'
55
+ # video.title => 'Understanding Analytics'
56
56
  # video.duration => 250 (in seconds)
57
57
  # video.width => 960
58
58
  # video.height => 568
59
- # video.thumbnail_small => "https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540"
60
- # video.thumbnail_medium => "https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540"
61
- # video.thumbnail_large => "https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540"
62
- # video.embed_url => "//fast.wistia.net/embed/iframe/pxonqr42is"
63
- # video.embed_code => "'<iframe src="//fast.wistia.net/embed/iframe/pxonqr42is" frameborder="0"></iframe>'"
59
+ # video.thumbnail_small => 'https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540'
60
+ # video.thumbnail_medium => 'https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540'
61
+ # video.thumbnail_large => 'https://embed-ssl.wistia.com/deliveries/0fccbdc60ade35723f79f1c002bc61b135b610fa.jpg?image_crop_resized=960x540'
62
+ # video.embed_url => '//fast.wistia.net/embed/iframe/pxonqr42is'
63
+ # video.embed_code => "<iframe src='//fast.wistia.net/embed/iframe/pxonqr42is' frameborder='0'></iframe>"
64
64
 
65
65
  video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4")
66
66
  # video.available? => true
67
- # video.video_id => "mZqGqE0D0n4"
68
- # video.provider => "YouTube"
69
- # video.title => "Cherry Bloom - King Of The Knife"
70
- # video.description => "The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net"
67
+ # video.video_id => 'mZqGqE0D0n4'
68
+ # video.provider => 'YouTube'
69
+ # video.title => 'Cherry Bloom - King Of The Knife'
70
+ # video.description => 'The first video from the upcoming album Secret Sounds, to download in-stores April 14. Checkout http://www.cherrybloom.net'
71
71
  # video.duration => 175 (in seconds)
72
72
  # video.date => Sat Apr 12 22:25:35 UTC 2008
73
- # video.thumbnail_small => "http://i.ytimg.com/vi/mZqGqE0D0n4/default.jpg"
74
- # video.thumbnail_medium => "http://i.ytimg.com/vi/mZqGqE0D0n4/mqdefault.jpg"
75
- # video.thumbnail_large => "http://i.ytimg.com/vi/mZqGqE0D0n4/hqdefault.jpg"
76
- # video.embed_url => "http://www.youtube.com/embed/mZqGqE0D0n4"
77
- # video.embed_code => "'<iframe src="//www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'"
73
+ # video.thumbnail_small => 'http://i.ytimg.com/vi/mZqGqE0D0n4/default.jpg'
74
+ # video.thumbnail_medium => 'http://i.ytimg.com/vi/mZqGqE0D0n4/mqdefault.jpg'
75
+ # video.thumbnail_large => 'http://i.ytimg.com/vi/mZqGqE0D0n4/hqdefault.jpg'
76
+ # video.embed_url => 'http://www.youtube.com/embed/mZqGqE0D0n4'
77
+ # video.embed_code => "<iframe src='//www.youtube.com/embed/mZqGqE0D0n4' frameborder='0' allowfullscreen='allowfullscreen'></iframe>"
78
78
 
79
79
  playlist = VideoInfo.new("http://www.youtube.com/playlist?p=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr")
80
80
  # playlist.available? => true
81
- # playlist.playlist_id => "PL9hW1uS6HUftLdHI6RIsaf"
82
- # playlist.provider => "YouTube"
83
- # playlist.title => "YouTube Policy and Copyright"
84
- # playlist.thumbnail_small => "http://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg"
85
- # playlist.thumbnail_medium => "http://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg"
86
- # playlist.thumbnail_large => "http://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg"
87
- # playlist.embed_url => "http://www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr"
88
- # playlist.embed_code => "<iframe src="//www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr" frameborder="0" allowfullscreen="allowfullscreen"></iframe>"
81
+ # playlist.playlist_id => 'PL9hW1uS6HUftLdHI6RIsaf'
82
+ # playlist.provider => 'YouTube'
83
+ # playlist.title => 'YouTube Policy and Copyright'
84
+ # playlist.thumbnail_small => 'http://i.ytimg.com/vi/8b0aEoxqqC0/default.jpg'
85
+ # playlist.thumbnail_medium => 'http://i.ytimg.com/vi/8b0aEoxqqC0/mqdefault.jpg'
86
+ # playlist.thumbnail_large => 'http://i.ytimg.com/vi/8b0aEoxqqC0/hqdefault.jpg'
87
+ # playlist.embed_url => 'http://www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr'
88
+ # playlist.embed_code => "<iframe src='//www.youtube.com/embed/videoseries?list=PL9hW1uS6HUftLdHI6RIsaf-iXTm09qnEr' frameborder='0' allowfullscreen='allowfullscreen'></iframe>"
89
89
  # playlist.videos => [VideoInfo.new('http://www.youtube.com/watch?v=_Bt3-WsHfB0'), VideoInfo.new('http://www.youtube.com/watch?v=9g2U12SsRns'), VideoInfo.new('http://www.youtube.com/watch?v=8b0aEoxqqC0'), VideoInfo.new('http://www.youtube.com/watch?v=6c3mHikRz0I'), VideoInfo.new('http://www.youtube.com/watch?v=OQVHWsTHcoc')]
90
90
 
91
91
  playlist = VideoInfo.new("http://vimeo.com/album/2755718")
92
92
  # playlist.available? => true
93
- # playlist.playlist_id => "2755718"
94
- # playlist.provider => "Vimeo"
95
- # playlist.title => "The Century Of Self"
96
- # playlist.thumbnail_small => "http://b.vimeocdn.com/ts/443/595/443595474_100.jpg"
97
- # playlist.thumbnail_medium => "http://b.vimeocdn.com/ts/443/595/443595474_200.jpg"
98
- # playlist.thumbnail_large => "http://b.vimeocdn.com/ts/443/595/443595474_640.jpg"
99
- # playlist.embed_url => "player.vimeo.com/hubnut/album/2755718"
100
- # playlist.embed_code => "<iframe src="//player.vimeo.com/hubnut/album/2755718?autoplay=0&byline=0&portrait=0&title=0" frameborder="0"></iframe>"
93
+ # playlist.playlist_id => '2755718'
94
+ # playlist.provider => 'Vimeo'
95
+ # playlist.title => 'The Century Of Self'
96
+ # playlist.thumbnail_small => 'http://b.vimeocdn.com/ts/443/595/443595474_100.jpg'
97
+ # playlist.thumbnail_medium => 'http://b.vimeocdn.com/ts/443/595/443595474_200.jpg'
98
+ # playlist.thumbnail_large => 'http://b.vimeocdn.com/ts/443/595/443595474_640.jpg'
99
+ # playlist.embed_url => 'player.vimeo.com/hubnut/album/2755718'
100
+ # playlist.embed_code => "<iframe src='//player.vimeo.com/hubnut/album/2755718?autoplay=0&byline=0&portrait=0&title=0' frameborder='0'></iframe>"
101
101
  # playlist.videos => [VideoInfo.new('http://vimeo.com/67977038'), VideoInfo.new('http://vimeo.com/68843810'), VideoInfo.new('http://vimeo.com/69949597'), VideoInfo.new('http://vimeo.com/70388245')]
102
102
  ```
103
103
 
@@ -105,16 +105,16 @@ Options
105
105
  -------
106
106
 
107
107
  ``` ruby
108
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "User-Agent" => "My YouTube Mashup Robot/1.0")
109
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/")
110
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", "Referer" => "http://my-youtube-mashup.com/",
111
- "User-Agent" => "My YouTube Mashup Robot/1.0")
108
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', 'User-Agent' => 'My YouTube Mashup Robot/1.0')
109
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', 'Referer' => 'http://my-youtube-mashup.com/')
110
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', 'Referer' => 'http://my-youtube-mashup.com/',
111
+ 'User-Agent' => 'My YouTube Mashup Robot/1.0')
112
112
  ```
113
113
  You can also use **symbols** instead of strings (any non-word (`/[^a-z]/i`) character would be converted to hyphen).
114
114
 
115
115
  ``` ruby
116
- video = VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4", :referer => "http://my-youtube-mashup.com/",
117
- user_agent: "My YouTube Mashup Robot/1.0")
116
+ video = VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4', referer: 'http://my-youtube-mashup.com/',
117
+ user_agent: 'My YouTube Mashup Robot/1.0')
118
118
  ```
119
119
 
120
120
  User-Agent when empty defaults to "VideoInfo/VERSION" - where version is current VideoInfo version, e.g. **"VideoInfo/0.2.7"**.
@@ -124,10 +124,10 @@ It supports all openURI header fields (options), for more information see: [open
124
124
  You can also include an `iframe_attributes` or `url_attributes` hash to the `embed_code` method to include arbitrary attributes in the iframe embed code or as additional URL params:
125
125
 
126
126
  ``` ruby
127
- VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4").embed_code(iframe_attributes: { width: 800, height: 600, "data-key" => "value" })
128
- => '<iframe src="//www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen" width="800" height="600" data-key="value"></iframe>
127
+ VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4').embed_code(iframe_attributes: { width: 800, height: 600, 'data-key' => 'value' })
128
+ => '<iframe src="//www.youtube.com/embed/mZqGqE0D0n4" frameborder="0" allowfullscreen="allowfullscreen" width="800" height="600" data-key="value"></iframe>'
129
129
 
130
- 'VideoInfo.new("http://www.youtube.com/watch?v=mZqGqE0D0n4").embed_code(url_attributes: { autoplay: 1 })
130
+ 'VideoInfo.new('http://www.youtube.com/watch?v=mZqGqE0D0n4').embed_code(url_attributes: { autoplay: 1 })
131
131
  => '<iframe src="//www.youtube.com/embed/mZqGqE0D0n4?autoplay=1" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'
132
132
  ```
133
133
 
@@ -1,14 +1,22 @@
1
1
  # encoding: UTF-8
2
2
  require 'htmlentities'
3
- require 'iconv' if RUBY_VERSION.to_i < 2
3
+ require 'net/http'
4
4
 
5
5
  class VideoInfo
6
6
  module Providers
7
7
  class Vkontakte < Provider
8
8
  attr_accessor :video_owner
9
9
 
10
+ def initialize(url, options = {})
11
+ super(url, options)
12
+ @url.strip!
13
+ end
14
+
10
15
  def self.usable?(url)
11
- url =~ /(vk\.com)|(vkontakte\.ru)/
16
+ url.strip!
17
+ vkontakte = !!(url =~ /\A(http|https):\/\/(vk\.com)|(vkontakte\.ru)\z/)
18
+ valid = !!(url =~ /\A#{URI::regexp(['http', 'https'])}\z/)
19
+ vkontakte && valid
12
20
  end
13
21
 
14
22
  def provider
@@ -16,7 +24,7 @@ class VideoInfo
16
24
  end
17
25
 
18
26
  def description
19
- content = data[/<meta name="description" content="(.*)" \/>/, 1]
27
+ content = data[/"desc":"(.*?)",/, 1]
20
28
  HTMLEntities.new.decode(content)
21
29
  end
22
30
  alias_method :keywords, :description
@@ -26,7 +34,7 @@ class VideoInfo
26
34
  360 => 480,
27
35
  480 => 640,
28
36
  720 => 1280
29
- }[height]
37
+ }[height].to_i
30
38
  end
31
39
 
32
40
  def height
@@ -34,36 +42,87 @@ class VideoInfo
34
42
  end
35
43
 
36
44
  def title
37
- data[/<title>(.*)<\/title>/, 1].gsub(' | ВКонтакте', '')
45
+ data[/\="mv_title">(.*)<\/div>/, 1].gsub(' | ВКонтакте', '')
38
46
  end
39
47
 
40
48
  def view_count
41
- data[/mv_num_views\\">.*?(\d+)/, 1].to_i
49
+ data[/mv_views_count_number\">.*?(\d+)/, 1].to_i
42
50
  end
43
51
 
44
52
  def embed_url
45
- "//vk.com/video_ext.php?oid=#{video_owner}&id=#{video_id}&hash=#{_data_hash}"
53
+ youtube = data[
54
+ /iframe\ id=\"video_player\".*src=\"(.*)\"\ frameborder=/, 1
55
+ ]
56
+ if youtube
57
+ VideoInfo::Providers::Youtube.new(
58
+ URI.unescape(youtube.gsub(/\\/, ''))
59
+ ).embed_url
60
+ else
61
+ "//vk.com/video_ext.php?oid=#{video_owner}" +
62
+ "&id=#{video_id}&hash=#{_data_hash}"
63
+ end
46
64
  end
47
65
 
48
66
  def duration
49
67
  data[/"duration":(\d+)/, 1].to_i
50
68
  end
51
69
 
70
+ def available?
71
+ !%w[403 404 302 401].include?(_response_code)
72
+ end
73
+
52
74
  private
53
75
 
76
+ def _make_request(url, options)
77
+ request = Net::HTTP::Post.new(url.path)
78
+ request.body = URI.encode_www_form(options)
79
+ conn = Net::HTTP.new(url.host, url.port)
80
+ conn.use_ssl = true
81
+ resp = conn.request(request)
82
+ resp.body.force_encoding('cp1251').encode('UTF-8', undef: :replace)
83
+ end
84
+
54
85
  def _set_data_from_api
55
- uri = open(url, options)
56
- if RUBY_VERSION.to_i < 2
57
- Iconv.iconv('utf-8', 'cp1251', uri.read)[0]
86
+ url = URI('https://vk.com/al_video.php')
87
+ options['act'] = 'show'
88
+ options['al'] = '1'
89
+ options['video'] = "#{@video_owner}_#{@video_id}"
90
+ _make_request(url, options)
91
+ end
92
+
93
+ def _error_found?(response)
94
+ title = response.body[
95
+ /<title>(.*)<\/title>/, 1
96
+ ].force_encoding(
97
+ 'cp1251'
98
+ ).encode(
99
+ 'UTF-8', undef: :replace
100
+ )
101
+ !!title.index('Ошибка')
102
+ end
103
+
104
+ def _get_response_code(response)
105
+ if response.header['location'] == '/'
106
+ '401'
107
+ elsif response.code == '302'
108
+ '302'
109
+ elsif _error_found? response
110
+ '403'
58
111
  else
59
- uri.read.encode('UTF-8')
112
+ response.code
60
113
  end
61
114
  end
62
115
 
63
116
  def _response_code
64
- response = nil
65
- Net::HTTP.start(_api_base, 80) { |http| response = http.get(_api_path) }
66
- response.code
117
+ response = Net::HTTP.get_response(_api_base, _api_path, 80)
118
+ code = _get_response_code response
119
+ if code == '302'
120
+ _get_response_code Net::HTTP.get_response(
121
+ URI.parse(response.header['location'])
122
+ )
123
+ else
124
+ code
125
+ end
67
126
  end
68
127
 
69
128
  def _api_base
@@ -75,7 +134,7 @@ class VideoInfo
75
134
  end
76
135
 
77
136
  def _data_hash
78
- data[/hash2\\":\\"(\w+)/, 1]
137
+ data[/"hash2":"(\w+)/, 1]
79
138
  end
80
139
 
81
140
  def _set_video_id_from_url
@@ -83,7 +142,7 @@ class VideoInfo
83
142
  end
84
143
 
85
144
  def _url_regex
86
- /(?:vkontakte\.ru\/video|vk\.com\/video)(-?\d+_\d+)/i
145
+ /(?:vkontakte\.ru\/video|vk\.com\/video|vk\.com\/.*?=video)(-?\d+_\d+)/i
87
146
  end
88
147
 
89
148
  def _default_iframe_attributes
@@ -1,3 +1,3 @@
1
1
  class VideoInfo
2
- VERSION = '2.4.0'
2
+ VERSION = '2.4.1'
3
3
  end
@@ -21,7 +21,7 @@ http_interactions:
21
21
  Server:
22
22
  - Apache
23
23
  Date:
24
- - Tue, 09 Dec 2014 19:27:32 GMT
24
+ - Sun, 08 Mar 2015 12:11:00 GMT
25
25
  Content-Type:
26
26
  - text/html
27
27
  Content-Length:
@@ -42,5 +42,5 @@ http_interactions:
42
42
  </body>
43
43
  </html>
44
44
  http_version:
45
- recorded_at: Tue, 09 Dec 2014 19:27:32 GMT
45
+ recorded_at: Sun, 08 Mar 2015 12:11:00 GMT
46
46
  recorded_with: VCR 2.9.3
@@ -0,0 +1,382 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://vk.com/video9491528_165193133
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - Apache
23
+ Date:
24
+ - Sun, 08 Mar 2015 15:03:48 GMT
25
+ Content-Type:
26
+ - text/html; charset=windows-1251
27
+ Content-Length:
28
+ - '5374'
29
+ Connection:
30
+ - keep-alive
31
+ X-Powered-By:
32
+ - PHP/3.11903
33
+ Set-Cookie:
34
+ - remixlang=0; expires=Wed, 02 Mar 2016 22:20:23 GMT; path=/; domain=.vk.com
35
+ Pragma:
36
+ - no-cache
37
+ Cache-Control:
38
+ - no-store
39
+ X-Frame-Options:
40
+ - deny
41
+ body:
42
+ encoding: ASCII-8BIT
43
+ string: !binary |-
44
+ PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAg
45
+ U3RyaWN0Ly9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQv
46
+ eGh0bWwxLXN0cmljdC5kdGQiPgo8aHRtbCB4bWxucz0iaHR0cDovL3d3dy53
47
+ My5vcmcvMTk5OS94aHRtbCIgeG1sOmxhbmc9InJ1IiBsYW5nPSJydSI+Cjxo
48
+ ZWFkPgo8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRl
49
+ bnQ9IklFPWVkZ2UiIC8+CjxsaW5rIHJlbD0ic2hvcnRjdXQgaWNvbiIgaHJl
50
+ Zj0iL2ltYWdlcy9mYXZpY29ubmV3Lmljbz8zIiAvPgoKPGxpbmsgcmVsPSJh
51
+ cHBsZS10b3VjaC1pY29uIiBocmVmPSIvaW1hZ2VzL3NhZmFyaV82MC5wbmci
52
+ Pgo8bGluayByZWw9ImFwcGxlLXRvdWNoLWljb24iIHNpemVzPSI3Nng3NiIg
53
+ aHJlZj0iL2ltYWdlcy9zYWZhcmlfNzYucG5nIj4KPGxpbmsgcmVsPSJhcHBs
54
+ ZS10b3VjaC1pY29uIiBzaXplcz0iMTIweDEyMCIgaHJlZj0iL2ltYWdlcy9z
55
+ YWZhcmlfMTIwLnBuZyI+CjxsaW5rIHJlbD0iYXBwbGUtdG91Y2gtaWNvbiIg
56
+ c2l6ZXM9IjE1MngxNTIiIGhyZWY9Ii9pbWFnZXMvc2FmYXJpXzE1Mi5wbmci
57
+ PgoKPG1ldGEgaHR0cC1lcXVpdj0iY29udGVudC10eXBlIiBjb250ZW50PSJ0
58
+ ZXh0L2h0bWw7IGNoYXJzZXQ9d2luZG93cy0xMjUxIiAvPgo8bWV0YSBuYW1l
59
+ PSJkZXNjcmlwdGlvbiIgY29udGVudD0iIiAvPgoKPHRpdGxlPs746OHq4CB8
60
+ IMLK7u3y4Ory5TwvdGl0bGU+Cgo8bm9zY3JpcHQ+PG1ldGEgaHR0cC1lcXVp
61
+ dj0icmVmcmVzaCIgY29udGVudD0iMDsgVVJMPS9iYWRicm93c2VyLnBocCI+
62
+ PC9ub3NjcmlwdD4KCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4K
63
+ dmFyIHZrID0gewogIGFkc19yb3RhdGVfaW50ZXJ2YWw6IDEyMDAwMCwKICBh
64
+ bDogcGFyc2VJbnQoJzQnKSB8fCA0LAogIGlkOiAwLAogIGludG5hdDogJycg
65
+ PyB0cnVlIDogZmFsc2UsCiAgaG9zdDogJ3ZrLmNvbScsCiAgbGFuZzogMCwK
66
+ ICBydGw6IHBhcnNlSW50KCcnKSB8fCAwLAogIHZlcnNpb246IDE3MDczLAog
67
+ IHN0RG9tYWluczogMywKICB6ZXJvOiBmYWxzZSwKICBjb250bGVuOiA1NTA1
68
+ LAogIGxvZ2luc2NoZW1lOiAnaHR0cHMnLAogIGlwX2g6ICcyODA1YWU2ODk3
69
+ OWIzYzQ4NTInLAogIHZjX2g6ICcyY2ViOTk5ZjU1YmU1MzI4NjY4NTk1Yzk5
70
+ MmM3NzhkMicsCiAgbmF2UHJlZml4OiAnLycsCiAgZHQ6IHBhcnNlSW50KCcw
71
+ JykgfHwgMCwKICBmczogcGFyc2VJbnQoJzExJykgfHwgMTEsCiAgdHM6IDE0
72
+ MjU4MjcwMjgsCiAgdHo6IDEwODAwLAogIHBkOiAwLAogIHBhZHM6IDEsCiAg
73
+ dGltZTogWzIwMTUsIDMsIDgsIDE4LCAzLCA0OF0KfQoKd2luZG93LmxvY0Rv
74
+ bWFpbiA9IHZrLmhvc3QubWF0Y2goL1thLXpBLVpdK1wuW2EtekEtWl0rXC4/
75
+ JC8pWzBdOwp2YXIgX3VhID0gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2Vy
76
+ Q2FzZSgpOwppZiAoL29wZXJhL2kudGVzdChfdWEpIHx8ICEvbXNpZSA2L2ku
77
+ dGVzdChfdWEpIHx8IGRvY3VtZW50LmRvbWFpbiAhPSBsb2NEb21haW4pIGRv
78
+ Y3VtZW50LmRvbWFpbiA9IGxvY0RvbWFpbjsKdmFyIF9fX2h0ZXN0ID0gKGxv
79
+ Y2F0aW9uLnRvU3RyaW5nKCkubWF0Y2goLyMoLiopLykgfHwge30pWzFdIHx8
80
+ ICcnLCBfX190bzsKaWYgKHZrLmFsICE9IDEgJiYgX19faHRlc3QubGVuZ3Ro
81
+ ICYmIF9fX2h0ZXN0LnN1YnN0cigwLCAxKSA9PSB2ay5uYXZQcmVmaXgpIHsK
82
+ ICBpZiAodmsuYWwgIT0gMyB8fCB2ay5uYXZQcmVmaXggIT0gJyEnKSB7CiAg
83
+ ICBfX190byA9IF9fX2h0ZXN0LnJlcGxhY2UoL14oXC98ISkvLCAnJyk7CiAg
84
+ ICBpZiAoX19fdG8ubWF0Y2goL14oW15cP10qXC5waHB8bG9naW4pKFteYS16
85
+ MC05XC5dfCQpLykpIF9fX3RvID0gJyc7CiAgICBsb2NhdGlvbi5yZXBsYWNl
86
+ KGxvY2F0aW9uLnByb3RvY29sICsgJy8vJyArIGxvY2F0aW9uLmhvc3QgKyAn
87
+ LycgKyBfX190byk7CiAgfQp9Cgp2YXIgU3RhdGljRmlsZXMgPSB7CiAgJ2Nv
88
+ bW1vbi5qcycgOiB7djogMTExNn0sCiAgJ2NvbW1vbi5jc3MnOiB7djogNDkz
89
+ fSwKICAnaWU2LmNzcycgICA6IHt2OiAyNn0sCiAgJ2llNy5jc3MnICAgOiB7
90
+ djogMTh9CiAgLCdsYW5nMF8wLmpzJzp7djo2NTk1fSwndmlkZW8uY3NzJzp7
91
+ djoxNDB9LCd2aWRlby5qcyc6e3Y6MTYyfSwnaW5kZXhlci5qcyc6e3Y6MTl9
92
+ LCd1aV9jb250cm9scy5qcyc6e3Y6MTc4fSwndWlfY29udHJvbHMuY3NzJzp7
93
+ djo1OX0sJ3ZpZGVvdmlldy5qcyc6e3Y6MjQ2fSwndmlkZW92aWV3LmNzcyc6
94
+ e3Y6MTQ0fSwndmlkZW9fdXBsb2FkLmpzJzp7djoxOX0sJ3NlYXJjaC5qcyc6
95
+ e3Y6MTEyfSwncXNvcnRlci5qcyc6e3Y6Mjl9LCdwYWdlLmNzcyc6e3Y6NzI1
96
+ fSwncGFnZS5qcyc6e3Y6ODY4fSwndW5jb21tb24uY3NzJzp7djo5MH0KfQo8
97
+ L3NjcmlwdD4KCjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9j
98
+ c3MiIGhyZWY9Imh0dHA6Ly9zdDAudmsubWUvY3NzL2FsL2NvbW1vbi5jc3M/
99
+ NDkzIiAvPgo8IS0tW2lmIGx0ZSBJRSA2XT48c3R5bGUgdHlwZT0idGV4dC9j
100
+ c3MiIG1lZGlhPSJzY3JlZW4iPi8qIDwhW0NEQVRBWyAqLyBAaW1wb3J0IHVy
101
+ bChodHRwOi8vc3QwLnZrLm1lL2Nzcy9hbC9pZTYuY3NzPzI2KTsgLyogXV0+
102
+ ICovPC9zdHlsZT48IVtlbmRpZl0tLT4KPCEtLVtpZiBJRSA3XT48c3R5bGUg
103
+ dHlwZT0idGV4dC9jc3MiIG1lZGlhPSJzY3JlZW4iPi8qIDwhW0NEQVRBWyAq
104
+ LyBAaW1wb3J0IHVybChodHRwOi8vc3QwLnZrLm1lL2Nzcy9hbC9pZTcuY3Nz
105
+ PzE4KTsgLyogXV0+ICovPC9zdHlsZT48IVtlbmRpZl0tLT4KPGxpbmsgdHlw
106
+ ZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cDovL3N0
107
+ MC52ay5tZS9jc3MvYWwvdmlkZW8uY3NzPzE0MCI+PC9saW5rPjxsaW5rIHR5
108
+ cGU9InRleHQvY3NzIiByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHA6Ly9z
109
+ dDAudmsubWUvY3NzL3VpX2NvbnRyb2xzLmNzcz81OSI+PC9saW5rPjxsaW5r
110
+ IHR5cGU9InRleHQvY3NzIiByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHA6
111
+ Ly9zdDAudmsubWUvY3NzL2FsL3ZpZGVvdmlldy5jc3M/MTQ0Ij48L2xpbms+
112
+ PGxpbmsgdHlwZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0i
113
+ aHR0cDovL3N0MC52ay5tZS9jc3MvYWwvcGFnZS5jc3M/NzI1Ij48L2xpbms+
114
+ PGxpbmsgdHlwZT0idGV4dC9jc3MiIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0i
115
+ aHR0cDovL3N0MC52ay5tZS9jc3MvYWwvdW5jb21tb24uY3NzPzkwIj48L2xp
116
+ bms+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iL2pzL2xv
117
+ YWRlcl9uYXYxNzA3M18wLmpzIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRl
118
+ eHQvamF2YXNjcmlwdCIgc3JjPSJodHRwOi8vc3QyLnZrLm1lL2pzL2FsL2Nv
119
+ bW1vbi5qcz8xMTE2XzEzNCI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0
120
+ L2phdmFzY3JpcHQiIHNyYz0iL2pzL2xhbmcwXzAuanM/NjU5NSI+PC9zY3Jp
121
+ cHQ+PG1ldGEgbmFtZT0icm9ib3RzIiBjb250ZW50PSJub2luZGV4IiAvPjxz
122
+ Y3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHA6Ly9zdDIu
123
+ dmsubWUvanMvYWwvdmlkZW8uanM/MTYyIj48L3NjcmlwdD48c2NyaXB0IHR5
124
+ cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJodHRwOi8vc3QzLnZrLm1lL2pz
125
+ L2FsL2luZGV4ZXIuanM/MTkiPjwvc2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4
126
+ dC9qYXZhc2NyaXB0IiBzcmM9Imh0dHA6Ly9zdDMudmsubWUvanMvbGliL3Vp
127
+ X2NvbnRyb2xzLmpzPzE3OCI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0
128
+ L2phdmFzY3JpcHQiIHNyYz0iaHR0cDovL3N0MS52ay5tZS9qcy9hbC92aWRl
129
+ b3ZpZXcuanM/MjQ2Ij48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2
130
+ YXNjcmlwdCIgc3JjPSJodHRwOi8vc3QyLnZrLm1lL2pzL2FsL3ZpZGVvX3Vw
131
+ bG9hZC5qcz8xOSI+PC9zY3JpcHQ+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFz
132
+ Y3JpcHQiIHNyYz0iaHR0cDovL3N0Mi52ay5tZS9qcy9hbC9zZWFyY2guanM/
133
+ MTEyIj48L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIg
134
+ c3JjPSJodHRwOi8vc3QxLnZrLm1lL2pzL2FsL3Fzb3J0ZXIuanM/MjkiPjwv
135
+ c2NyaXB0PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Imh0
136
+ dHA6Ly9zdDEudmsubWUvanMvYWwvcGFnZS5qcz84NjgiPjwvc2NyaXB0PgoK
137
+ PC9oZWFkPgoKPGJvZHkgb25yZXNpemU9Im9uQm9keVJlc2l6ZSgpIiBjbGFz
138
+ cz0iaXNfcnRsIGZvbnRfZGVmYXVsdCBwYWRzICI+CiAgPGRpdiBpZD0ic3lz
139
+ dGVtX21zZyIgY2xhc3M9ImZpeGVkIj48L2Rpdj4KICA8ZGl2IGlkPSJ1dGls
140
+ cyI+PC9kaXY+CgogIDxkaXYgaWQ9ImxheWVyX2JnIiBjbGFzcz0iZml4ZWQi
141
+ PjwvZGl2PjxkaXYgaWQ9ImxheWVyX3dyYXAiIGNsYXNzPSJzY3JvbGxfZml4
142
+ X3dyYXAgZml4ZWQiPjxkaXYgaWQ9ImxheWVyIj48L2Rpdj48L2Rpdj4KICA8
143
+ ZGl2IGlkPSJib3hfbGF5ZXJfYmciIGNsYXNzPSJmaXhlZCI+PC9kaXY+PGRp
144
+ diBpZD0iYm94X2xheWVyX3dyYXAiIGNsYXNzPSJzY3JvbGxfZml4X3dyYXAg
145
+ Zml4ZWQiPjxkaXYgaWQ9ImJveF9sYXllciI+PGRpdiBpZD0iYm94X2xvYWRl
146
+ ciI+PGRpdiBjbGFzcz0ibG9hZGVyIj48L2Rpdj48ZGl2IGNsYXNzPSJiYWNr
147
+ Ij48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj4KCiAgPGRpdiBpZD0ic3RsX2xl
148
+ ZnQiPjwvZGl2PjxkaXYgaWQ9InN0bF9zaWRlIj48L2Rpdj4KCiAgPHNjcmlw
149
+ dCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPmRvbVN0YXJ0ZWQoKTs8L3Njcmlw
150
+ dD4KCiAgPGRpdiBjbGFzcz0ic2Nyb2xsX2ZpeF93cmFwIiBpZD0icGFnZV93
151
+ cmFwIj48ZGl2IGlkPSJyZWdfYmFyIiBjbGFzcz0idG9wX2luZm9fd3JhcCBm
152
+ aXhlZCI+CiAgPGRpdiBjbGFzcz0ic2Nyb2xsX2ZpeCI+CiAgICA8ZGl2IGlk
153
+ PSJyZWdfYmFyX2NvbnRlbnQiPgogICAgICDP8Ojx7uXk6O3/6fLl8fwsIPfy
154
+ 7uH7IOLx5ePk4CDu8fLg4uDy/PH/IOIg6u7t8uDq8uUg8SDk8PPn/P/s6CDo
155
+ IOHr6Ofq6OzoCiAgICAgIDxkaXYgY2xhc3M9ImJ1dHRvbl9ibHVlIiBpZD0i
156
+ cmVnX2Jhcl9idXR0b24iPjxhIGNsYXNzPSJidXR0b25fbGluayIgaHJlZj0i
157
+ L2pvaW4iIG9uY2xpY2s9InJldHVybiAhc2hvd0JveCgnam9pbi5waHAnLCB7
158
+ YWN0OiAnYm94JywgZnJvbTogbmF2LnN0ckxvY30sIHt9LCBldmVudCkiPjxi
159
+ dXR0b24gaWQ9InJlZ19iYXJfYnRuIj48c3BhbiBpZD0icmVnX2Jhcl93aXRo
160
+ X2FyciI+x+Dw5ePo8fLw6PDu4uDy/PH/PC9zcGFuPjwvYnV0dG9uPjwvYT48
161
+ L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPGRpdj48ZGl2IGNs
162
+ YXNzPSJzY3JvbGxfZml4Ij4KICA8ZGl2IGlkPSJwYWdlX2xheW91dCIgc3R5
163
+ bGU9IndpZHRoOiA3OTFweDsiPgogICAgPGRpdiBpZD0icGFnZV9oZWFkZXIi
164
+ IGNsYXNzPSJwX2hlYWQgcF9oZWFkX2wwIj4KICAgICAgPGRpdiBjbGFzcz0i
165
+ YmFjayI+PC9kaXY+CiAgICAgIDxkaXYgY2xhc3M9ImxlZnQiPjwvZGl2Pgog
166
+ ICAgICA8ZGl2IGNsYXNzPSJyaWdodCI+PC9kaXY+CiAgICAgIDxkaXYgY2xh
167
+ c3M9ImNvbnRlbnQiPgogICAgICAgIDxkaXYgaWQ9InRvcF9uYXYiIGNsYXNz
168
+ PSJoZWFkX25hdiI+CiAgPGRpdiBpZD0idG9wX2xvZ29fZG93biIgY2xhc3M9
169
+ ImZsX2wiPjwvZGl2PgogIDxhIGlkPSJ0b3BfaG9tZV9saW5rIiBjbGFzcz0i
170
+ dG9wX2hvbWVfbGluayBmbF9sIiBocmVmPSIvIiBvbm1vdXNlZG93bj0iYWRk
171
+ Q2xhc3MoJ3RvcF9sb2dvX2Rvd24nLCd0bGRfZCcpOyIgb25jbGljaz0icmV0
172
+ dXJuIG5hdi5nbyh0aGlzLCBldmVudCk7Ij48L2E+CiAgPGRpdiBpZD0idG9w
173
+ X2xpbmtzIj4KICAgIDxkaXYgY2xhc3M9ImZsX3IiIGlkPSJ0b3BfbWVudV93
174
+ cmFwIiBzdHlsZT0iIj4KICAgICAgPGEgaWQ9InRvcF9yZWdfbGluayIgY2xh
175
+ c3M9ImZsX3IgdG9wX25hdl9saW5rIiBocmVmPSIvam9pbiIgc3R5bGU9IiIg
176
+ b25jbGljaz0icmV0dXJuICFzaG93Qm94KCdqb2luLnBocCcsIHthY3Q6ICdi
177
+ b3gnLCBmcm9tOiBuYXYuc3RyTG9jfSwge30sIGV2ZW50KSIgb25tb3VzZWRv
178
+ d249InRuQWN0aXZlKHRoaXMpIj7w5ePo8fLw4Pbo/zwvYT4KICAgICAgPGEg
179
+ aWQ9InRvcF9zd2l0Y2hfbGFuZyIgY2xhc3M9ImZsX3IgdG9wX25hdl9saW5r
180
+ IiAgc3R5bGU9ImRpc3BsYXk6IG5vbmU7IiBvbmNsaWNrPSJhamF4LnBvc3Qo
181
+ J2FsX2luZGV4LnBocCcsIHthY3Q6ICdjaGFuZ2VfbGFuZycsIGxhbmdfaWQ6
182
+ IDMsIGhhc2g6ICcnfSk7IiBvbm1vdXNlZG93bj0idG5BY3RpdmUodGhpcyki
183
+ PlN3aXRjaCB0byBFbmdsaXNoPC9hPgogICAgPC9kaXY+CiAgICA8YSBjbGFz
184
+ cz0iZmxfbCB0b3BfbmF2X2xpbmsiIGhyZWY9IiIgaWQ9InRvcF9iYWNrX2xp
185
+ bmsiIG9uY2xpY2s9InJldHVybiBuYXYuZ28odGhpcywgZXZlbnQsIHtiYWNr
186
+ OiB0cnVlfSkiIG9ubW91c2Vkb3duPSJ0bkFjdGl2ZSh0aGlzKSI+PC9hPgog
187
+ IDwvZGl2Pgo8L2Rpdj4KICAgICAgPC9kaXY+CiAgICA8L2Rpdj4KCiAgICA8
188
+ ZGl2IGlkPSJzaWRlX2JhciIgY2xhc3M9ImZsX2wiIHN0eWxlPSIiPgogICAg
189
+ ICA8ZGl2IGlkPSJxdWlja19sb2dpbiI+CiAgPGZvcm0gbWV0aG9kPSJQT1NU
190
+ IiBuYW1lPSJsb2dpbiIgaWQ9InF1aWNrX2xvZ2luX2Zvcm0iIGFjdGlvbj0i
191
+ aHR0cHM6Ly9sb2dpbi52ay5jb20vP2FjdD1sb2dpbiIgb25zdWJtaXQ9Imlm
192
+ ICh2a2xvZ2luKSB7cmV0dXJuIHRydWV9IGVsc2Uge3F1aWNrX2xvZ2luKCk7
193
+ cmV0dXJuIGZhbHNlO30iPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFt
194
+ ZT0iYWN0IiB2YWx1ZT0ibG9naW4iIC8+CiAgICA8aW5wdXQgdHlwZT0iaGlk
195
+ ZGVuIiBuYW1lPSJyb2xlIiB2YWx1ZT0iYWxfZnJhbWUiIC8+CiAgICA8aW5w
196
+ dXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJleHBpcmUiIGlkPSJxdWlja19leHBp
197
+ cmVfaW5wdXQiIHZhbHVlPSIiIC8+CiAgICA8aW5wdXQgdHlwZT0iaGlkZGVu
198
+ IiBuYW1lPSJjYXB0Y2hhX3NpZCIgaWQ9InF1aWNrX2NhcHRjaGFfc2lkIiB2
199
+ YWx1ZT0iIiAvPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iY2Fw
200
+ dGNoYV9rZXkiIGlkPSJxdWlja19jYXB0Y2hhX2tleSIgdmFsdWU9IiIgLz4K
201
+ ICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9Il9vcmlnaW4iIHZhbHVl
202
+ PSJodHRwOi8vdmsuY29tIiAvPgogICAgPGlucHV0IHR5cGU9ImhpZGRlbiIg
203
+ bmFtZT0iaXBfaCIgdmFsdWU9IjI4MDVhZTY4OTc5YjNjNDg1MiIgLz4KICAg
204
+ IDxkaXYgY2xhc3M9ImxhYmVsIj7S5evl9O7tIOjr6CBlbWFpbDwvZGl2Pgog
205
+ ICAgPGRpdiBjbGFzcz0ibGFiZWxlZCI+PGlucHV0IHR5cGU9InRleHQiIG5h
206
+ bWU9ImVtYWlsIiBjbGFzcz0idGV4dCIgaWQ9InF1aWNrX2VtYWlsIiAvPjwv
207
+ ZGl2PgogICAgPGRpdiBjbGFzcz0ibGFiZWwiPs/g8O7r/DwvZGl2PgogICAg
208
+ PGRpdiBjbGFzcz0ibGFiZWxlZCI+PGlucHV0IHR5cGU9InBhc3N3b3JkIiBu
209
+ YW1lPSJwYXNzIiBjbGFzcz0idGV4dCIgaWQ9InF1aWNrX3Bhc3MiIG9ua2V5
210
+ dXA9InRvZ2dsZSgncXVpY2tfZXhwaXJlJywgISF0aGlzLnZhbHVlKTt0b2dn
211
+ bGUoJ3F1aWNrX2ZvcmdvdCcsICF0aGlzLnZhbHVlKSIgLz48L2Rpdj4KICAg
212
+ IDxpbnB1dCB0eXBlPSJzdWJtaXQiIGNsYXNzPSJzdWJtaXQiIC8+CiAgPC9m
213
+ b3JtPgogIDxidXR0b24gY2xhc3M9ImZsYXRfYnV0dG9uIGJ1dHRvbl93aWRl
214
+ IGJ1dHRvbl9iaWciIGlkPSJxdWlja19sb2dpbl9idXR0b24iPsLu6fLoPC9i
215
+ dXR0b24+CiAgPGJ1dHRvbiBjbGFzcz0iZmxhdF9idXR0b24gYnV0dG9uX3dp
216
+ ZGUgYnV0dG9uX2JpZyIgaWQ9InF1aWNrX3JlZ19idXR0b24iIHN0eWxlPSIi
217
+ IG9uY2xpY2s9InRvcC5zaG93Qm94KCdqb2luLnBocCcsIHthY3Q6ICdib3gn
218
+ LCBmcm9tOiBuYXYuc3RyTG9jfSkiPtDl4+jx8vDg9uj/PC9idXR0b24+CiAg
219
+ PGRpdiBjbGFzcz0iY2xlYXIgZm9yZ290Ij48YSBpZD0icXVpY2tfZm9yZ290
220
+ IiBocmVmPSIvcmVzdG9yZSIgdGFyZ2V0PSJfdG9wIj7H4OH76+gg7+Dw7uv8
221
+ PzwvYT48ZGl2IGNsYXNzPSJjaGVja2JveCB0YV9sIiBpZD0icXVpY2tfZXhw
222
+ aXJlIiBvbmNsaWNrPSJjaGVja2JveCh0aGlzKTtnZSgncXVpY2tfZXhwaXJl
223
+ X2lucHV0JykudmFsdWU9aXNDaGVja2VkKHRoaXMpPzE6Jyc7Ij48ZGl2Pjwv
224
+ ZGl2Ptfz5u7pIOru7O/8/vLl8DwvZGl2PjwvZGl2Pgo8L2Rpdj4KICAgIDwv
225
+ ZGl2PgoKICAgIDxkaXYgaWQ9InBhZ2VfYm9keSIgY2xhc3M9ImZsX3IiIHN0
226
+ eWxlPSJ3aWR0aDogNjMxcHg7Ij4KICAgICAgPGRpdiBpZD0iaGVhZGVyX3dy
227
+ YXAyIj4KICAgICAgICA8ZGl2IGlkPSJoZWFkZXJfd3JhcDEiPgogICAgICAg
228
+ ICAgPGRpdiBpZD0iaGVhZGVyIiBzdHlsZT0iIj4KICAgICAgICAgICAgPGgx
229
+ IGlkPSJ0aXRsZSI+zvjo4ergPC9oMT4KICAgICAgICAgIDwvZGl2PgogICAg
230
+ ICAgIDwvZGl2PgogICAgICA8L2Rpdj4KICAgICAgPGRpdiBpZD0id3JhcF9i
231
+ ZXR3ZWVuIj48L2Rpdj4KICAgICAgPGRpdiBpZD0id3JhcDMiPjxkaXYgaWQ9
232
+ IndyYXAyIj4KICA8ZGl2IGlkPSJ3cmFwMSI+CiAgICA8ZGl2IGlkPSJjb250
233
+ ZW50Ij48ZGl2IGNsYXNzPSJtZXNzYWdlX3BhZ2UiPgogIDxkaXYgY2xhc3M9
234
+ InRpdGxlIj7O+Ojh6uA8L2Rpdj4KICA8ZGl2IGNsYXNzPSJib2R5Ij4KICAg
235
+ IM746OHq4CDk7vHy8+/gCiAgICA8ZGl2IGNsYXNzPSJidXR0b25fYmx1ZSI+
236
+ PGJ1dHRvbiBpZD0ibXNnX2JhY2tfYnV0dG9uIj7N4Ofg5DwvYnV0dG9uPjwv
237
+ ZGl2PgogIDwvZGl2Pgo8L2Rpdj48L2Rpdj4KICA8L2Rpdj4KPC9kaXY+PC9k
238
+ aXY+CiAgICA8L2Rpdj4KCiAgICA8ZGl2IGlkPSJmb290ZXJfd3JhcCIgY2xh
239
+ c3M9ImZsX3IiIHN0eWxlPSJ3aWR0aDogNjYxcHg7Ij4KICAgICAgPGRpdiBp
240
+ ZD0iYm90dG9tX25hdiI+CiAgPGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL2Fi
241
+ b3V0Ij7uIPHg6fLlPC9hPgogIDxhIGNsYXNzPSJibmF2X2EiIGhyZWY9Ii9z
242
+ dXBwb3J0P2FjdD1uZXciIG9uY2xpY2s9InJldHVybiBuYXYuZ28odGhpcywg
243
+ ZXZlbnQpOyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij7v7uzu+fw8L2E+CiAg
244
+ PGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL3Rlcm1zIj7v8ODi6OvgPC9hPgog
245
+ IDxhIGNsYXNzPSJibmF2X2EiIGhyZWY9Ii9hZHMiPvDl6uvg7OA8L2E+CiAg
246
+ PGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL3Blb3BsZSI+6/7k6DwvYT48YSBj
247
+ bGFzcz0iYm5hdl9hIiBocmVmPSIvY29tbXVuaXRpZXMiPvHu7uH55fHy4uA8
248
+ L2E+CiAgPGEgY2xhc3M9ImJuYXZfYSIgaHJlZj0iL2RldiI+8ODn8ODh7vL3
249
+ 6Org7DwvYT4KICA8YSBjbGFzcz0iYm5hdl9hIiBocmVmPSIvam9icyIgc3R5
250
+ bGU9ImRpc3BsYXk6IG5vbmU7Ij7i4Org7fHo6DwvYT4KPC9kaXY+CjxkaXYg
251
+ aWQ9ImZvb3RlciIgY2xhc3M9ImNsZWFyIj4KICA8ZGl2IGNsYXNzPSJjb3B5
252
+ X2xhbmciPjxhIGhyZWY9Ii9hYm91dCI+wsru7fLg6vLlPC9hPiAmY29weTsg
253
+ MjAxNSA8YSBjbGFzcz0iYm5hdl9sYW5nIiBvbmNsaWNrPSJhamF4LnBvc3Qo
254
+ J2FsX2luZGV4LnBocCcsIHthY3Q6ICdjaGFuZ2VfbGFuZycsIGxhbmdfaWQ6
255
+ IDMsIGhhc2g6ICdiZjQyMDQyZjg2OTJkNzkzZjMnfSkiPkVuZ2xpc2g8L2E+
256
+ PGEgY2xhc3M9ImJuYXZfbGFuZyIgb25jbGljaz0iYWpheC5wb3N0KCdhbF9p
257
+ bmRleC5waHAnLCB7YWN0OiAnY2hhbmdlX2xhbmcnLCBsYW5nX2lkOiAwLCBo
258
+ YXNoOiAnYmY0MjA0MmY4NjkyZDc5M2YzJ30pIj7Q8/Hx6ujpPC9hPjxhIGNs
259
+ YXNzPSJibmF2X2xhbmciIG9uY2xpY2s9ImFqYXgucG9zdCgnYWxfaW5kZXgu
260
+ cGhwJywge2FjdDogJ2NoYW5nZV9sYW5nJywgbGFuZ19pZDogMSwgaGFzaDog
261
+ J2JmNDIwNDJmODY5MmQ3OTNmMyd9KSI+0+rw4L/t8fzq4DwvYT48YSBjbGFz
262
+ cz0iYm5hdl9sYW5nIiBvbmNsaWNrPSJpZiAodmsuYWwpIHsgc2hvd0JveCgn
263
+ bGFuZy5waHAnLCB7YWN0OiAnbGFuZ19kaWFsb2cnLCBhbGw6IDF9LCB7cGFy
264
+ YW1zOiB7ZGFyazogdHJ1ZSwgYm9keVN0eWxlOiAncGFkZGluZzogMHB4J30s
265
+ IG5vcmVsb2FkOiB0cnVlfSk7IH0gZWxzZSB7IGNoYW5nZUxhbmcoMSk7IH0g
266
+ cmV0dXJuIGZhbHNlOyI+4vHlIP/n++roICZyYXF1bzs8L2E+PC9kaXY+CiAg
267
+ CiAgPGRpdj4KICAgIAogICAgCiAgPC9kaXY+CjwvZGl2PgogICAgPC9kaXY+
268
+ CiAgICA8ZGl2IGNsYXNzPSJjbGVhciI+PC9kaXY+CiAgPC9kaXY+CjwvZGl2
269
+ PjwvZGl2Pjxub3NjcmlwdD48ZGl2IHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0
270
+ ZTtsZWZ0Oi0xMDAwMHB4OyI+CjxpbWcgc3JjPSIvL3RvcC1md3oxLm1haWwu
271
+ cnUvY291bnRlcj9pZD0yNTc5NDM3O2pzPW5hIiBzdHlsZT0iYm9yZGVyOjA7
272
+ IiBoZWlnaHQ9IjEiIHdpZHRoPSIxIiBhbHQ9ItDl6fLo7eNATWFpbC5ydSIg
273
+ Lz4KPC9kaXY+PC9ub3NjcmlwdD48L2Rpdj4KICA8ZGl2IGNsYXNzPSJwcm9n
274
+ cmVzcyIgaWQ9Imdsb2JhbF9wcmciPjwvZGl2PgoKICA8c2NyaXB0IHR5cGU9
275
+ InRleHQvamF2YXNjcmlwdCI+CiAgICBpZiAocGFyZW50ICYmIHBhcmVudCAh
276
+ PSB3aW5kb3cgJiYgKGJyb3dzZXIubXNpZSB8fCBicm93c2VyLm9wZXJhIHx8
277
+ IGJyb3dzZXIubW96aWxsYSB8fCBicm93c2VyLmNocm9tZSB8fCBicm93c2Vy
278
+ LnNhZmFyaSB8fCBicm93c2VyLmlwaG9uZSkpIHsKICAgICAgZG9jdW1lbnQu
279
+ Z2V0RWxlbWVudHNCeVRhZ05hbWUoJ2JvZHknKVswXS5pbm5lckhUTUwgPSAn
280
+ JzsKICAgIH0gZWxzZSB7CiAgICAgIGRvbVJlYWR5KCk7CiAgICAgIHVwZGF0
281
+ ZU1vbmV5KDApOwpnU2VhcmNoLmluaXQoKTsKaWYgKHdpbmRvdy5xQXJyICYm
282
+ IHFBcnJbNV0pIHFBcnJbNV0gPSBbNSwgIu/uIPLu4uDw4OwiLCAiIiwgImdv
283
+ b2RzIiwgMHgwMDAwMDEwMF07CmlmIChicm93c2VyLmlwaG9uZSB8fCBicm93
284
+ c2VyLmlwYWQgfHwgYnJvd3Nlci5pcG9kKSB7CiAgc2V0U3R5bGUoYm9keU5v
285
+ ZGUsIHt3ZWJraXRUZXh0U2l6ZUFkanVzdDogJ25vbmUnfSk7Cn12YXIgcWYg
286
+ PSBnZSgncXVpY2tfbG9naW5fZm9ybScpLCBxbCA9IGdlKCdxdWlja19sb2dp
287
+ bicpLCBxZSA9IGdlKCdxdWlja19lbWFpbCcpLCBxcCA9IGdlKCdxdWlja19w
288
+ YXNzJyk7CnZhciBxbGIgPSBnZSgncXVpY2tfbG9naW5fYnV0dG9uJyksIHBy
289
+ Z0J0biA9IHFsYjsKCnZhciBxaW5pdCA9IGZ1bmN0aW9uKCkgewogIHNldFRp
290
+ bWVvdXQoZnVuY3Rpb24oKSB7CiAgICBxbC5pbnNlcnRCZWZvcmUoY2UoJ2Rp
291
+ dicsIHtpbm5lckhUTUw6ICc8aWZyYW1lIGNsYXNzPSJ1cGxvYWRfZnJhbWUi
292
+ IGlkPSJxdWlja19sb2dpbl9mcmFtZSIgbmFtZT0icXVpY2tfbG9naW5fZnJh
293
+ bWUiPjwvaWZyYW1lPid9KSwgcWYpOwogICAgcWYudGFyZ2V0ID0gJ3F1aWNr
294
+ X2xvZ2luX2ZyYW1lJzsKICB9LCAxKTsKfQoKaWYgKHdpbmRvdy50b3AgJiYg
295
+ d2luZG93LnRvcCAhPSB3aW5kb3cpIHsKICB3aW5kb3cub25sb2FkID0gcWlu
296
+ aXQ7Cn0gZWxzZSB7CiAgc2V0VGltZW91dChxaW5pdCwgMCk7Cn0KCnFmLm9u
297
+ c3VibWl0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKCFnZSgncXVpY2tfbG9naW5f
298
+ ZnJhbWUnKSkgcmV0dXJuIGZhbHNlOwogIGlmICghdHJpbShxZS52YWx1ZSkp
299
+ IHsKICAgIG5vdGFCZW5lKHFlKTsKICAgIHJldHVybiBmYWxzZTsKICB9IGVs
300
+ c2UgaWYgKCF0cmltKHFwLnZhbHVlKSkgewogICAgbm90YUJlbmUocXApOwog
301
+ ICAgcmV0dXJuIGZhbHNlOwogIH0KICBsb2NrQnV0dG9uKHdpbmRvdy5fX3Fm
302
+ QnRuID0gcHJnQnRuKTsKICBwcmdCdG4gPSBxbGI7CiAgY2xlYXJUaW1lb3V0
303
+ KF9fcWxUaW1lcik7CiAgX19xbFRpbWVyID0gc2V0VGltZW91dChsb2dpblN1
304
+ Ym1pdEVycm9yLCAzMDAwMCk7CiAgZG9tRkMoZG9tUFMocWYpKS5vbmxvYWQg
305
+ PSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dChfX3FsVGltZXIpOwog
306
+ ICAgX19xbFRpbWVyID0gc2V0VGltZW91dChsb2dpblN1Ym1pdEVycm9yLCAy
307
+ NTAwKTsKICB9CiAgcmV0dXJuIHRydWU7Cn0KCndpbmRvdy5sb2dpblN1Ym1p
308
+ dEVycm9yID0gZnVuY3Rpb24oKSB7CiAgc2hvd0Zhc3RCb3goJ8/w5eTz7/Dl
309
+ 5uTl7ehlJywgJ83lIPPk4OXy8f8g7/Du6fLoIODi8u7w6Ofg9uj+IO/uIOfg
310
+ +ej55e3t7uzzIPHu5eTo7eXt6P4uINfg+eUg4vHl4+4g/fLuIO/w7ujx9e7k
311
+ 6PIsIOru4+TgIO3gIMLg+OXsIOru7O/8/vLl8OUg8/Hy4O3u4uvl7fsg7eXv
312
+ 8ODi6Ov87fvlIPLl6vP56OUg5ODy4CDoIOLw5ez/LiDP7ubg6/Pp8fLgLCDv
313
+ 8O7i5fD88uUg7eDx8vDu6eroIOTg8vsg6CDi8OXs5e3oIOIg8ejx8uXs5SDo
314
+ IO/l8OXn4O/z8fLo8uUg4fDg8+fl8C4nKTsKfQp3aW5kb3cuZm9jdXNMb2dp
315
+ bklucHV0ID0gZnVuY3Rpb24oKSB7CiAgc2Nyb2xsVG9Ub3AoMCk7CiAgbm90
316
+ YUJlbmUoJ3F1aWNrX2VtYWlsJyk7Cn0Kd2luZG93LmNoYW5nZVF1aWNrUmVn
317
+ QnV0dG9uID0gZnVuY3Rpb24obm9TaG93KSB7CiAgaWYgKG5vU2hvdykgewog
318
+ ICAgaGlkZSgndG9wX3JlZ19saW5rJywgJ3F1aWNrX3JlZ19idXR0b24nKTsK
319
+ ICAgIHNob3coJ3RvcF9zZWFyY2hfbGluaycpOwogIH0gZWxzZSB7CiAgICBo
320
+ aWRlKCd0b3Bfc2VhcmNoX2xpbmsnKTsKICAgIHNob3coJ3RvcF9yZWdfbGlu
321
+ aycsICdxdWlja19yZWdfYnV0dG9uJyk7CiAgfQogIHRvZ2dsZSgndG9wX3N3
322
+ aXRjaF9sYW5nJywgbm9TaG93ICYmIHdpbmRvdy5sYW5nQ29uZmlnICYmIHdp
323
+ bmRvdy5sYW5nQ29uZmlnLmlkICE9IDMpOwp9CndpbmRvdy5zdWJtaXRRdWlj
324
+ a0xvZ2luRm9ybSA9IGZ1bmN0aW9uKGVtYWlsLCBwYXNzLCBvcHRzKSB7CiAg
325
+ c2V0UXVpY2tMb2dpbkRhdGEoZW1haWwsIHBhc3MsIG9wdHMpOwogIGlmIChv
326
+ cHRzICYmIG9wdHMucHJnKSBwcmdCdG4gPSBvcHRzLnByZzsKICBpZiAocWYu
327
+ b25zdWJtaXQoKSkgcWYuc3VibWl0KCk7Cn0Kd2luZG93LnNldFF1aWNrTG9n
328
+ aW5EYXRhID0gZnVuY3Rpb24oZW1haWwsIHBhc3MsIG9wdHMpIHsKICBpZiAo
329
+ ZW1haWwgIT09IHVuZGVmaW5lZCkgZ2UoJ3F1aWNrX2VtYWlsJykudmFsdWUg
330
+ PSBlbWFpbDsKICBpZiAocGFzcyAhPT0gdW5kZWZpbmVkKSBnZSgncXVpY2tf
331
+ cGFzcycpLnZhbHVlID0gcGFzczsKICB2YXIgcGFyYW1zID0gb3B0cyAmJiBv
332
+ cHRzLnBhcmFtcyB8fCB7fTsKICBmb3IgKHZhciBpIGluIHBhcmFtcykgewog
333
+ ICAgdmFyIGVsID0gZ2UoJ3F1aWNrX2xvZ2luXycgKyBpKTsKICAgIGlmIChl
334
+ bCkgewogICAgICB2YWwoZWwsIHBhcmFtc1tpXSk7CiAgICB9IGVsc2Ugewog
335
+ ICAgICBxZi5hcHBlbmRDaGlsZChjZSgnaW5wdXQnLCB7dHlwZTogJ2hpZGRl
336
+ bicsIG5hbWU6IGksIGlkOiAncXVpY2tfbG9naW5fJyArIGksIHZhbHVlOiBw
337
+ YXJhbXNbaV19KSk7CiAgICB9CiAgfQp9CgppZiAocWxiKSB7CiAgcWxiLm9u
338
+ Y2xpY2sgPSBmdW5jdGlvbigpIHsgaWYgKHFmLm9uc3VibWl0KCkpIHFmLnN1
339
+ Ym1pdCgpOyB9Owp9CgppZiAoYnJvd3Nlci5vcGVyYV9tb2JpbGUpIHNob3co
340
+ J3F1aWNrX2V4cGlyZScpOwoKaWYgKDEpIHsKICBoaWRlKCdzdXBwb3J0X2xp
341
+ bmtfdGQnKTsKfQp2YXIgdHNfaW5wdXQgPSBnZSgndHNfaW5wdXQnKSwgb2xk
342
+ RkYgPSBicm93c2VyLm1vemlsbGEgJiYgcGFyc2VJbnQoYnJvd3Nlci52ZXJz
343
+ aW9uKSA8IDg7CmlmIChicm93c2VyLm1vemlsbGEgJiYgIW9sZEZGKSB7CiAg
344
+ c2V0U3R5bGUodHNfaW5wdXQsIHtwYWRkaW5nOiAodmsucnRsID8gJzNweCAy
345
+ MHB4IDZweCA0MHB4JyA6ICczcHggNDFweCA2cHggMjBweCcpfSk7Cn0KcGxh
346
+ Y2Vob2xkZXJTZXR1cCh0c19pbnB1dCwge2JhY2s6IGZhbHNlLCByZWxvYWQ6
347
+ IHRydWV9KTsKaWYgKGJyb3dzZXIub3BlcmEgfHwgYnJvd3Nlci5tc2llIHx8
348
+ IGJyb3dzZXIubW96aWxsYSkgewogIHNldFN0eWxlKHRzX2lucHV0LCB7cGFk
349
+ ZGluZzogKHZrLnJ0bCA/ICc0cHggMjBweCA1cHggNDBweCcgOiAnNHB4IDQx
350
+ cHggNXB4IDIwcHgnKX0pOwp9IGVsc2UgaWYgKGJyb3dzZXIuY2hyb21lIHx8
351
+ IGJyb3dzZXIuc2FmYXJpKSB7CiAgc2V0U3R5bGUodHNfaW5wdXQsIHtwYWRk
352
+ aW5nOiAodmsucnRsID8gJzRweCAyMXB4IDVweCA0MHB4JyA6ICc0cHggNDBw
353
+ eCA1cHggMjFweCcpfSk7Cn0KClRvcFNlYXJjaC5pbml0KCk7CmlmIChicm93
354
+ c2VyLm1zaWU4IHx8IGJyb3dzZXIubXNpZTcpIHsKICB2YXIgc3QgPSB7Ym9y
355
+ ZGVyOiAnMXB4IHNvbGlkICNhNmI2YzYnfTsKICBpZiAoaGFzQ2xhc3MoZ2Uo
356
+ J3RzX3dyYXAnKSwgJ3ZrJykpIHsKICAgIGlmICh2ay5ydGwpIHN0LmxlZnQg
357
+ PSAnMXB4JzsKICAgIGVsc2Ugc3QucmlnaHQgPSAnMHB4JzsKICB9IGVsc2Ug
358
+ ewogICAgaWYgKHZrLnJ0bCkgc3QucmlnaHQgPSAnMTQ2cHgnOwogICAgZWxz
359
+ ZSBzdC5sZWZ0ID0gJzE0NnB4JzsKICB9CiAgc2V0U3R5bGUoZ2UoJ3RzX2Nv
360
+ bnRfd3JhcCcpLCBzdCk7Cn0Kd2luZG93LnRzSGludHNFbmFibGVkID0gMTsK
361
+ c2V0VGltZW91dCh6TmF2LnBiaW5kKHt9LCB7cXVldWU6MX0pLCAwKTsKaGFu
362
+ ZGxlUGFnZVBhcmFtcyh7ImlkIjowLCJwYWRzIjoxLCJub19hZHMiOjEsImxv
363
+ YyI6Ij9hY3Q9cyZvaWQ9OTQ5MTUyOCZ2aWQ9MTY1MTkzMTMzIiwid3JhcF9w
364
+ YWdlIjoxLCJ3aWR0aCI6NzkxLCJ3aWR0aF9kZWMiOjE2MCwid2lkdGhfZGVj
365
+ X2Zvb3RlciI6MTMwLCJib2R5X2NsYXNzIjoiaXNfcnRsIGZvbnRfZGVmYXVs
366
+ dCBwYWRzICIsImNvdW50ZXJzIjoiIiwicHZiaWciOjAsInB2ZGFyayI6MX0p
367
+ O2FkZEV2ZW50KGRvY3VtZW50LCAnY2xpY2snLCBvbkRvY3VtZW50Q2xpY2sp
368
+ O2dlKCdtc2dfYmFja19idXR0b24nKS5vbmNsaWNrID0gZnVuY3Rpb24oKSB7
369
+ CiAgaGlzdG9yeS5nbygtMSk7Cn07CjsoZnVuY3Rpb24gKGQsIHcpIHsKdmFy
370
+ IHRzID0gZC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKTsgdHMudHlwZSA9ICJ0
371
+ ZXh0L2phdmFzY3JpcHQiOyB0cy5hc3luYyA9IHRydWU7CnRzLnNyYyA9IChk
372
+ LmxvY2F0aW9uLnByb3RvY29sID09ICJodHRwczoiID8gImh0dHBzOiIgOiAi
373
+ aHR0cDoiKSArICIvL3RvcC1md3oxLm1haWwucnUvanMvY29kZS5qcyI7CnZh
374
+ ciBmID0gZnVuY3Rpb24gKCkge3ZhciBzID0gZC5nZXRFbGVtZW50c0J5VGFn
375
+ TmFtZSgic2NyaXB0IilbMF07IHMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUo
376
+ dHMsIHMpO307CmlmICh3Lm9wZXJhID09ICJbb2JqZWN0IE9wZXJhXSIpIHsg
377
+ ZC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgZiwgZmFs
378
+ c2UpOyB9IGVsc2UgeyBmKCk7IH0KfSkoZG9jdW1lbnQsIHdpbmRvdyk7CiAg
379
+ ICB9CiAgPC9zY3JpcHQ+CjwvYm9keT4KCjwvaHRtbD4=
380
+ http_version:
381
+ recorded_at: Sun, 08 Mar 2015 15:03:49 GMT
382
+ recorded_with: VCR 2.9.3