From a4f82408d9a3d921d9c2af7e4d757f44737dc7ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rog=C3=A9rio=20Brito?= Date: Wed, 6 Aug 2014 15:35:56 -0300 Subject: [PATCH 1/1] Imported Upstream version 2014.08.05 --- README.md | 73 +-- README.txt | 75 ++-- test/helper.py | 11 +- test/swftests/.gitignore | 1 + test/swftests/ArrayAccess.as | 19 + test/swftests/ArrayAccess.swf | Bin 0 -> 589 bytes test/swftests/ClassCall.as | 17 + test/swftests/ClassCall.swf | Bin 0 -> 584 bytes test/swftests/ClassConstruction.as | 15 + test/swftests/ClassConstruction.swf | Bin 0 -> 556 bytes test/swftests/LocalVars.as | 13 + test/swftests/LocalVars.swf | Bin 0 -> 520 bytes test/swftests/PrivateCall.as | 21 + test/swftests/PrivateCall.swf | Bin 0 -> 595 bytes test/swftests/StaticAssignment.as | 13 + test/swftests/StaticAssignment.swf | Bin 0 -> 522 bytes test/swftests/StaticRetrieval.as | 16 + test/swftests/StaticRetrieval.swf | Bin 0 -> 521 bytes test/test_all_urls.py | 1 - test/test_download.py | 2 - test/test_playlists.py | 53 +-- test/test_swfinterp.py | 77 ++++ test/test_youtube_signature.py | 70 ++- youtube-dl | Bin 509479 -> 534378 bytes youtube-dl.1 | 75 ++-- youtube-dl.bash-completion | 2 +- youtube_dl/FileDownloader.py | 12 - youtube_dl/YoutubeDL.py | 24 +- youtube_dl/__init__.py | 117 +++-- youtube_dl/downloader/f4m.py | 11 +- youtube_dl/extractor/__init__.py | 17 + youtube_dl/extractor/abc.py | 48 ++ youtube_dl/extractor/adultswim.py | 139 ++++++ youtube_dl/extractor/allocine.py | 4 +- youtube_dl/extractor/ard.py | 116 +++-- youtube_dl/extractor/blinkx.py | 2 +- youtube_dl/extractor/bloomberg.py | 5 +- youtube_dl/extractor/br.py | 13 +- youtube_dl/extractor/cbs.py | 42 +- youtube_dl/extractor/chilloutzone.py | 2 +- youtube_dl/extractor/cnet.py | 6 +- youtube_dl/extractor/comedycentral.py | 6 +- youtube_dl/extractor/common.py | 34 +- youtube_dl/extractor/cracked.py | 65 +++ youtube_dl/extractor/dfb.py | 44 ++ youtube_dl/extractor/dropbox.py | 12 +- youtube_dl/extractor/firedrive.py | 1 - youtube_dl/extractor/francetv.py | 40 +- youtube_dl/extractor/funnyordie.py | 2 +- youtube_dl/extractor/gamestar.py | 74 ++++ youtube_dl/extractor/gdcvault.py | 42 +- youtube_dl/extractor/generic.py | 11 +- youtube_dl/extractor/godtube.py | 58 +++ youtube_dl/extractor/izlesene.py | 97 ++++ youtube_dl/extractor/justintv.py | 17 +- youtube_dl/extractor/kickstarter.py | 37 +- youtube_dl/extractor/krasview.py | 59 +++ youtube_dl/extractor/livestream.py | 84 +++- youtube_dl/extractor/mlb.py | 116 +++++ youtube_dl/extractor/nbc.py | 28 +- youtube_dl/extractor/npo.py | 2 +- youtube_dl/extractor/pbs.py | 15 +- youtube_dl/extractor/redtube.py | 4 +- youtube_dl/extractor/rtbf.py | 2 +- youtube_dl/extractor/rtlnow.py | 11 +- youtube_dl/extractor/rtve.py | 2 +- youtube_dl/extractor/sapo.py | 119 +++++ youtube_dl/extractor/savefrom.py | 2 +- youtube_dl/extractor/shared.py | 57 +++ youtube_dl/extractor/snotr.py | 68 +++ youtube_dl/extractor/sockshare.py | 80 ++++ youtube_dl/extractor/soundcloud.py | 4 +- youtube_dl/extractor/steam.py | 2 +- youtube_dl/extractor/streamcloud.py | 30 +- youtube_dl/extractor/swrmediathek.py | 16 +- youtube_dl/extractor/tagesschau.py | 10 - youtube_dl/extractor/teachertube.py | 20 +- youtube_dl/extractor/tenplay.py | 2 - youtube_dl/extractor/tvplay.py | 85 ++++ youtube_dl/extractor/ubu.py | 56 +++ youtube_dl/extractor/vevo.py | 1 + youtube_dl/extractor/vidme.py | 68 +++ youtube_dl/extractor/vimeo.py | 21 +- youtube_dl/extractor/vodlocker.py | 2 +- youtube_dl/extractor/vube.py | 79 +++- youtube_dl/extractor/wdr.py | 12 +- youtube_dl/extractor/youtube.py | 539 ++++------------------- youtube_dl/jsinterp.py | 89 ++-- youtube_dl/postprocessor/ffmpeg.py | 8 +- youtube_dl/swfinterp.py | 609 ++++++++++++++++++++++++++ youtube_dl/utils.py | 47 +- youtube_dl/version.py | 2 +- 92 files changed, 3061 insertions(+), 942 deletions(-) create mode 100644 test/swftests/.gitignore create mode 100644 test/swftests/ArrayAccess.as create mode 100644 test/swftests/ArrayAccess.swf create mode 100644 test/swftests/ClassCall.as create mode 100644 test/swftests/ClassCall.swf create mode 100644 test/swftests/ClassConstruction.as create mode 100644 test/swftests/ClassConstruction.swf create mode 100644 test/swftests/LocalVars.as create mode 100644 test/swftests/LocalVars.swf create mode 100644 test/swftests/PrivateCall.as create mode 100644 test/swftests/PrivateCall.swf create mode 100644 test/swftests/StaticAssignment.as create mode 100644 test/swftests/StaticAssignment.swf create mode 100644 test/swftests/StaticRetrieval.as create mode 100644 test/swftests/StaticRetrieval.swf create mode 100644 test/test_swfinterp.py delete mode 100644 youtube_dl/FileDownloader.py create mode 100644 youtube_dl/extractor/abc.py create mode 100644 youtube_dl/extractor/adultswim.py create mode 100644 youtube_dl/extractor/cracked.py create mode 100644 youtube_dl/extractor/dfb.py create mode 100644 youtube_dl/extractor/gamestar.py create mode 100644 youtube_dl/extractor/godtube.py create mode 100644 youtube_dl/extractor/izlesene.py create mode 100644 youtube_dl/extractor/krasview.py create mode 100644 youtube_dl/extractor/mlb.py create mode 100644 youtube_dl/extractor/sapo.py create mode 100644 youtube_dl/extractor/shared.py create mode 100644 youtube_dl/extractor/snotr.py create mode 100644 youtube_dl/extractor/sockshare.py create mode 100644 youtube_dl/extractor/tvplay.py create mode 100644 youtube_dl/extractor/ubu.py create mode 100644 youtube_dl/extractor/vidme.py create mode 100644 youtube_dl/swfinterp.py diff --git a/README.md b/README.md index bc5e0f7..a42dfb8 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ To install it right away for all UNIX users (Linux, OS X, etc.), type: If you do not have curl, you can alternatively use a recent wget: - sudo wget https://yt-dl.org/downloads/2014.05.13/youtube-dl -O /usr/local/bin/youtube-dl + sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl sudo chmod a+x /usr/local/bin/youtube-dl Windows users can [download a .exe file](https://yt-dl.org/latest/youtube-dl.exe) and place it in their home directory or any other location on their [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). @@ -38,12 +38,6 @@ which means you can modify it, redistribute it or use it however you like. playlist or the command line) if an error occurs --dump-user-agent display the current browser identification - --user-agent UA specify a custom user agent - --referer REF specify a custom referer, use if the video - access is restricted to one domain - --add-header FIELD:VALUE specify a custom HTTP header and its value, - separated by a colon ':'. You can use this - option multiple times --list-extractors List all supported extractors and the URLs they would handle --extractor-descriptions Output descriptions of all supported @@ -51,35 +45,22 @@ which means you can modify it, redistribute it or use it however you like. --proxy URL Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy "") for direct connection - --no-check-certificate Suppress HTTPS certificate validation. - --prefer-insecure Use an unencrypted connection to retrieve - information about the video. (Currently - supported only for YouTube) - --cache-dir DIR Location in the filesystem where youtube-dl - can store some downloaded information - permanently. By default $XDG_CACHE_HOME - /youtube-dl or ~/.cache/youtube-dl . At the - moment, only YouTube player files (for - videos with obfuscated signatures) are - cached, but that may change. - --no-cache-dir Disable filesystem caching --socket-timeout None Time to wait before giving up, in seconds - --bidi-workaround Work around terminals that lack - bidirectional text support. Requires bidiv - or fribidi executable in PATH --default-search PREFIX Use this prefix for unqualified URLs. For example "gvsearch2:" downloads two videos from google videos for youtube-dl "large apple". Use the value "auto" to let - youtube-dl guess. The default value "error" - just throws an error. + youtube-dl guess ("auto_warning" to emit a + warning when guessing). "error" just throws + an error. The default value "fixup_error" + repairs broken URLs, but emits an error if + this is not possible instead of searching. --ignore-config Do not read configuration files. When given in the global configuration file /etc /youtube-dl.conf: do not read the user configuration in ~/.config/youtube-dl.conf (%APPDATA%/youtube-dl/config.txt on Windows) - --encoding ENCODING Force the specified encoding (experimental) ## Video Selection: --playlist-start NUMBER playlist video to start at (default is 1) @@ -125,9 +106,9 @@ which means you can modify it, redistribute it or use it however you like. of SIZE. ## Filesystem Options: - -t, --title use title in file name (default) + -a, --batch-file FILE file containing URLs to download ('-' for + stdin) --id use only video ID in file name - -l, --literal [deprecated] alias of --title -A, --auto-number number downloaded files starting from 00000 -o, --output TEMPLATE output filename template. Use %(title)s to get the title, %(uploader)s for the @@ -160,18 +141,15 @@ which means you can modify it, redistribute it or use it however you like. --restrict-filenames Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames - -a, --batch-file FILE file containing URLs to download ('-' for - stdin) - --load-info FILE json file containing the video information - (created with the "--write-json" option) + -t, --title [deprecated] use title in file name + (default) + -l, --literal [deprecated] alias of --title -w, --no-overwrites do not overwrite files -c, --continue force resume of partially downloaded files. By default, youtube-dl will resume downloads if possible. --no-continue do not resume partially downloaded files (restart from beginning) - --cookies FILE file to read cookies from and dump cookie - jar in --no-part do not use .part files --no-mtime do not use the Last-modified header to set the file modification time @@ -181,6 +159,19 @@ which means you can modify it, redistribute it or use it however you like. --write-annotations write video annotations to a .annotation file --write-thumbnail write thumbnail image to disk + --load-info FILE json file containing the video information + (created with the "--write-json" option) + --cookies FILE file to read cookies from and dump cookie + jar in + --cache-dir DIR Location in the filesystem where youtube-dl + can store some downloaded information + permanently. By default $XDG_CACHE_HOME + /youtube-dl or ~/.cache/youtube-dl . At the + moment, only YouTube player files (for + videos with obfuscated signatures) are + cached, but that may change. + --no-cache-dir Disable filesystem caching + --rm-cache-dir Delete all filesystem cache files ## Verbosity / Simulation Options: -q, --quiet activates quiet mode @@ -210,6 +201,22 @@ which means you can modify it, redistribute it or use it however you like. problems --print-traffic Display sent and read HTTP traffic +## Workarounds: + --encoding ENCODING Force the specified encoding (experimental) + --no-check-certificate Suppress HTTPS certificate validation. + --prefer-insecure Use an unencrypted connection to retrieve + information about the video. (Currently + supported only for YouTube) + --user-agent UA specify a custom user agent + --referer REF specify a custom referer, use if the video + access is restricted to one domain + --add-header FIELD:VALUE specify a custom HTTP header and its value, + separated by a colon ':'. You can use this + option multiple times + --bidi-workaround Work around terminals that lack + bidirectional text support. Requires bidiv + or fribidi executable in PATH + ## Video Format Options: -f, --format FORMAT video format code, specify the order of preference using slashes: "-f 22/17/18". diff --git a/README.txt b/README.txt index 5555b2a..4f41be2 100644 --- a/README.txt +++ b/README.txt @@ -15,7 +15,7 @@ To install it right away for all UNIX users (Linux, OS X, etc.), type: If you do not have curl, you can alternatively use a recent wget: - sudo wget https://yt-dl.org/downloads/2014.05.13/youtube-dl -O /usr/local/bin/youtube-dl + sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl sudo chmod a+x /usr/local/bin/youtube-dl Windows users can download a .exe file and place it in their home @@ -50,12 +50,6 @@ OPTIONS playlist or the command line) if an error occurs --dump-user-agent display the current browser identification - --user-agent UA specify a custom user agent - --referer REF specify a custom referer, use if the video - access is restricted to one domain - --add-header FIELD:VALUE specify a custom HTTP header and its value, - separated by a colon ':'. You can use this - option multiple times --list-extractors List all supported extractors and the URLs they would handle --extractor-descriptions Output descriptions of all supported @@ -63,35 +57,22 @@ OPTIONS --proxy URL Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy "") for direct connection - --no-check-certificate Suppress HTTPS certificate validation. - --prefer-insecure Use an unencrypted connection to retrieve - information about the video. (Currently - supported only for YouTube) - --cache-dir DIR Location in the filesystem where youtube-dl - can store some downloaded information - permanently. By default $XDG_CACHE_HOME - /youtube-dl or ~/.cache/youtube-dl . At the - moment, only YouTube player files (for - videos with obfuscated signatures) are - cached, but that may change. - --no-cache-dir Disable filesystem caching --socket-timeout None Time to wait before giving up, in seconds - --bidi-workaround Work around terminals that lack - bidirectional text support. Requires bidiv - or fribidi executable in PATH --default-search PREFIX Use this prefix for unqualified URLs. For example "gvsearch2:" downloads two videos from google videos for youtube-dl "large apple". Use the value "auto" to let - youtube-dl guess. The default value "error" - just throws an error. + youtube-dl guess ("auto_warning" to emit a + warning when guessing). "error" just throws + an error. The default value "fixup_error" + repairs broken URLs, but emits an error if + this is not possible instead of searching. --ignore-config Do not read configuration files. When given in the global configuration file /etc /youtube-dl.conf: do not read the user configuration in ~/.config/youtube-dl.conf (%APPDATA%/youtube-dl/config.txt on Windows) - --encoding ENCODING Force the specified encoding (experimental) Video Selection: ---------------- @@ -143,9 +124,9 @@ Download Options: Filesystem Options: ------------------- - -t, --title use title in file name (default) + -a, --batch-file FILE file containing URLs to download ('-' for + stdin) --id use only video ID in file name - -l, --literal [deprecated] alias of --title -A, --auto-number number downloaded files starting from 00000 -o, --output TEMPLATE output filename template. Use %(title)s to get the title, %(uploader)s for the @@ -178,18 +159,15 @@ Filesystem Options: --restrict-filenames Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames - -a, --batch-file FILE file containing URLs to download ('-' for - stdin) - --load-info FILE json file containing the video information - (created with the "--write-json" option) + -t, --title [deprecated] use title in file name + (default) + -l, --literal [deprecated] alias of --title -w, --no-overwrites do not overwrite files -c, --continue force resume of partially downloaded files. By default, youtube-dl will resume downloads if possible. --no-continue do not resume partially downloaded files (restart from beginning) - --cookies FILE file to read cookies from and dump cookie - jar in --no-part do not use .part files --no-mtime do not use the Last-modified header to set the file modification time @@ -199,6 +177,19 @@ Filesystem Options: --write-annotations write video annotations to a .annotation file --write-thumbnail write thumbnail image to disk + --load-info FILE json file containing the video information + (created with the "--write-json" option) + --cookies FILE file to read cookies from and dump cookie + jar in + --cache-dir DIR Location in the filesystem where youtube-dl + can store some downloaded information + permanently. By default $XDG_CACHE_HOME + /youtube-dl or ~/.cache/youtube-dl . At the + moment, only YouTube player files (for + videos with obfuscated signatures) are + cached, but that may change. + --no-cache-dir Disable filesystem caching + --rm-cache-dir Delete all filesystem cache files Verbosity / Simulation Options: ------------------------------- @@ -230,6 +221,24 @@ Verbosity / Simulation Options: problems --print-traffic Display sent and read HTTP traffic +Workarounds: +------------ + + --encoding ENCODING Force the specified encoding (experimental) + --no-check-certificate Suppress HTTPS certificate validation. + --prefer-insecure Use an unencrypted connection to retrieve + information about the video. (Currently + supported only for YouTube) + --user-agent UA specify a custom user agent + --referer REF specify a custom referer, use if the video + access is restricted to one domain + --add-header FIELD:VALUE specify a custom HTTP header and its value, + separated by a colon ':'. You can use this + option multiple times + --bidi-workaround Work around terminals that lack + bidirectional text support. Requires bidiv + or fribidi executable in PATH + Video Format Options: --------------------- diff --git a/test/helper.py b/test/helper.py index 230d2bd..b7299fb 100644 --- a/test/helper.py +++ b/test/helper.py @@ -137,8 +137,8 @@ def expect_info_dict(self, expected_dict, got_dict): def assertRegexpMatches(self, text, regexp, msg=None): - if hasattr(self, 'assertRegexpMatches'): - return self.assertRegexpMatches(text, regexp, msg) + if hasattr(self, 'assertRegexp'): + return self.assertRegexp(text, regexp, msg) else: m = re.match(regexp, text) if not m: @@ -148,3 +148,10 @@ def assertRegexpMatches(self, text, regexp, msg=None): else: msg = note + ', ' + msg self.assertTrue(m, msg) + + +def assertGreaterEqual(self, got, expected, msg=None): + if not (got >= expected): + if msg is None: + msg = '%r not greater than or equal to %r' % (got, expected) + self.assertTrue(got >= expected, msg) diff --git a/test/swftests/.gitignore b/test/swftests/.gitignore new file mode 100644 index 0000000..da97ff7 --- /dev/null +++ b/test/swftests/.gitignore @@ -0,0 +1 @@ +*.swf diff --git a/test/swftests/ArrayAccess.as b/test/swftests/ArrayAccess.as new file mode 100644 index 0000000..e22caa3 --- /dev/null +++ b/test/swftests/ArrayAccess.as @@ -0,0 +1,19 @@ +// input: [["a", "b", "c", "d"]] +// output: ["c", "b", "a", "d"] + +package { +public class ArrayAccess { + public static function main(ar:Array):Array { + var aa:ArrayAccess = new ArrayAccess(); + return aa.f(ar, 2); + } + + private function f(ar:Array, num:Number):Array{ + var x:String = ar[0]; + var y:String = ar[num % ar.length]; + ar[0] = y; + ar[num] = x; + return ar; + } +} +} diff --git a/test/swftests/ArrayAccess.swf b/test/swftests/ArrayAccess.swf new file mode 100644 index 0000000000000000000000000000000000000000..3f5b32e103138a665498c7aed1e50a54a543d661 GIT binary patch literal 589 zcmV-T0S5pa50{{Sc+Fg;)Zqq;z#%H~2yD1W+YE?=RQh-Xikl0DNBuXs;Aq5Ua zLPA2Ex?Zo7Q2&#?Cg}+-@Dv;oJOO7O01ioz;KYR!kHM}}n!rkH?R@*2Z^p9|Ain@E zegN1((A&5I0IxQ`Ab?Kl`RymYeq|B{QP!5xL3JoZ(zdMecw8Uv*W+|xHCnBfWjC#6 zvnGjJb{YvfsYTh%s#6&Bc*fFEB1UmkQ89JnTpU!ZXRaPQH%;<1C@ei@@qmXs5}DPg zH>8or+J2mdR5&zAf)S(2&YIM+Va!g(^d+zP0nLUTYYD0xF%kiHx?b$^NOLUQJOJN$v)tY{*k5k4~a^yeP3$6~j_a zMf@-ES5x-^jRrX#aOeI}ad#dUJyOA)M|n_b+PCCx++MVy)QZ?se7=t53mbA{_$gmmt?S#Lo*v5c*Y$3i($g+uJj>wo)|S*1;-@s^4Jboh(IwCe z%s9$Jm!}t2a*W6B3(f@cNk~VL5%6drhUPZfAv#<}yJT0_42+1T8zmEICc-8nCelr8 zn8>_}Othw}3JA%n8bTT@7s8~Z0Y*9k4Un;c5h7AUpi3MRJhcxMgfS^k?de^3jla)l zds<)D9!M{&6aB{2p6!8ezWFhm&-}Ib^2CT#Ttdy+{G0qpQrYT;ba)8TkH{wQrK!!~ bnApeU8C)A;DVI0ZR90toN5+2u1Z?J)h*%jQ literal 0 HcmV?d00001 diff --git a/test/swftests/ClassCall.as b/test/swftests/ClassCall.as new file mode 100644 index 0000000..aef58da --- /dev/null +++ b/test/swftests/ClassCall.as @@ -0,0 +1,17 @@ +// input: [] +// output: 121 + +package { +public class ClassCall { + public static function main():int{ + var f:OtherClass = new OtherClass(); + return f.func(100,20); + } +} +} + +class OtherClass { + public function func(x: int, y: int):int { + return x+y+1; + } +} diff --git a/test/swftests/ClassCall.swf b/test/swftests/ClassCall.swf new file mode 100644 index 0000000000000000000000000000000000000000..2f1b31b5074a15bdd4c2d4b45a0bcf7542c59d25 GIT binary patch literal 584 zcmV-O0=NA`S5pag0{{Sc+Fen zBqW4{)Qf#dOdZ>@&m>GR@mDZ(g1>;79hMY{k%fsrf`L0HjZ;oK`QG=v_x$d=1<>CB zJD&h52nKrx0PwE-9RYM>ciee47*-cEKS(+f_3Be0qK;wA=kw5Rj8#)QqH$oCwk?2JVtnTF2AoW0?VvCooe*T{)VBRt`A``8UfygKyxqIy(4 z&h;64MNwoo4{C2+lPPu631>zWhi>Y~Ok-)4iMJ)nB1%WTmrQwVr@=)K&R4(4tBT{q zoQd!z%l69s&dpBZ$Zk##Ca8kq!tEN|xq{^dgwh^3r@oPbs{o zKd)+TZGWiY$C)?P3QKeO1SFB<8Y(4PacN%txU8W|$<%Hz3sOk#EKLsQ#5^Z2;Bbns W&**SUC1t0qQs*OmDA7M$hUl;(@*&dz literal 0 HcmV?d00001 diff --git a/test/swftests/ClassConstruction.as b/test/swftests/ClassConstruction.as new file mode 100644 index 0000000..436479f --- /dev/null +++ b/test/swftests/ClassConstruction.as @@ -0,0 +1,15 @@ +// input: [] +// output: 0 + +package { +public class ClassConstruction { + public static function main():int{ + var f:Foo = new Foo(); + return 0; + } +} +} + +class Foo { + +} diff --git a/test/swftests/ClassConstruction.swf b/test/swftests/ClassConstruction.swf new file mode 100644 index 0000000000000000000000000000000000000000..51e2ad83460b7e1ea210d3005e61383cd2036c75 GIT binary patch literal 556 zcmV+{0@M9NS5paJ0{{Sc+GSDCiqk+C|0Xj@+y!Nql~R?3z%KM+leFulr5jvYySfJj zK@dUMX)o}@`Hv~84OtNXHhC5o>;1;BVLH(Mq}w3_*bTBk;Ro|;5#g4Q`B7bShmn&X(}Vb56+l}1D&X5LA_N6Z?=Y-Sxe!E^UiqDaH!=G=Wv&Io)UzYgKCv_OdH#@wAh u0ZG9tHdzC7$;0>NE`xLIp5vFWA8MCpv>y^lsqLwVn=^YTyZ-=(n&`Nw_8Dpb literal 0 HcmV?d00001 diff --git a/test/swftests/LocalVars.as b/test/swftests/LocalVars.as new file mode 100644 index 0000000..b2911a9 --- /dev/null +++ b/test/swftests/LocalVars.as @@ -0,0 +1,13 @@ +// input: [1, 2] +// output: 3 + +package { +public class LocalVars { + public static function main(a:int, b:int):int{ + var c:int = a + b + b; + var d:int = c - b; + var e:int = d; + return e; + } +} +} diff --git a/test/swftests/LocalVars.swf b/test/swftests/LocalVars.swf new file mode 100644 index 0000000000000000000000000000000000000000..3e9344f6638aaccc8c59ff15b80a799852244219 GIT binary patch literal 520 zcmV+j0{8txS5pb`0ssJb+FemSZxcZfoxNS#N{Wyu5QPHiBnnFr_MIIXTh56HlK?^> zAwY;K>%FyoWbgKLyO%Q+9lwGiH1G?M=;)y_rl6vs;%BgXHg;g8k>=yQH#0jEAin@M z-UI9+=x<#GfY;k!5kM~shuz2hBX<&uM0HJcP#!Rif#nk*MqSpcLqH#j+^XkxX10(}B$OLA}0E4cSsO%`;I-hRoxF$2`%>Yc*R& zC}iEC%wnnonx-OR)XI62h8jzDTF^7z7z(P!J#PiH935%FgTqh`xO*h{#NBrfSNsw^ zhgfj98Z@}DCbjG)ld+d(GR&EoX=tQM@Mo}4DKn73GEErw;BYWXkX zZ_d^QO-4B#@!-zGvbK!N8L8&M{am9O&@tUr*9if1%a@cHs5Q?YN#8INxmcZ(x z!As6GiD{JJ9kh#~QbSG+;Tj?}R3Vn*AhhUIKIGsv2OQ&&EsPLG4naV`cmz-VV+*Ka za%Jj&o1M?j)sOG9cWRFjW0kw57^zgJ{`4LgC^jL!H1#>0VE+U^hihZUq&K#0!__vo KO!Nm^gVbmq(gb+` literal 0 HcmV?d00001 diff --git a/test/swftests/PrivateCall.as b/test/swftests/PrivateCall.as new file mode 100644 index 0000000..f1c110a --- /dev/null +++ b/test/swftests/PrivateCall.as @@ -0,0 +1,21 @@ +// input: [] +// output: 9 + +package { +public class PrivateCall { + public static function main():int{ + var f:OtherClass = new OtherClass(); + return f.func(); + } +} +} + +class OtherClass { + private function pf():int { + return 9; + } + + public function func():int { + return this.pf(); + } +} diff --git a/test/swftests/PrivateCall.swf b/test/swftests/PrivateCall.swf new file mode 100644 index 0000000000000000000000000000000000000000..55d9eac1333e8293a5570030be1b624c696fe24d GIT binary patch literal 595 zcmV-Z0<8T*S5pa-0{{Sc+Fg;)Zqq;z#%KT7Zh{1@icnEiDH4@(A+eKkX_Q)22`ThI z5fTU?A$4P~8@G;a+3O~p;KWmKh9}_61Hd61IC9|xZ^5k7HYt`?-kJG*-_Gt#f&T`$ z`3YcyK!5En0K8lOMgY2*A9SAg2es)qit`Red-ai0X~(uFlSy;3(@e4xyS2N!YddYb z-EJV!$lu0FOdD~2ukMxxeVKb%n5r;|YdRLgq)>bH`h~0SU74mu7L}I1XUj;AWvp_$ z)oh`W?{$JC8w=%%G>t+}Xghn_$VZ8HHWBBt5kw*%b?pVHH7Zn*boc#aC~JdAPHQ{0 z{e`}y=ZJ>=MWgQ0HHB6;y<}{sS>hKS_7tF1DPERni?kRT=poGbPtQD)^_gWYCV{@p|f54zt_IV-~e6dul`|O z=+O@!KfkUroUn+ zgff0>=DgvD9NzPvKL!RoMl(XVVa}Y{6F`V9c&-b^%-OCWW$3^{YG7)Sc}--Y2iu%E h5{{X3%wECPh+gi=)`%mrx~?y<{MrvO{s#=4>^&b?Cu{%! literal 0 HcmV?d00001 diff --git a/test/swftests/StaticAssignment.as b/test/swftests/StaticAssignment.as new file mode 100644 index 0000000..b061c21 --- /dev/null +++ b/test/swftests/StaticAssignment.as @@ -0,0 +1,13 @@ +// input: [1] +// output: 1 + +package { +public class StaticAssignment { + public static var v:int; + + public static function main(a:int):int{ + v = a; + return v; + } +} +} diff --git a/test/swftests/StaticAssignment.swf b/test/swftests/StaticAssignment.swf new file mode 100644 index 0000000000000000000000000000000000000000..b28450adf34757bfd281fa240f99b395c50ac557 GIT binary patch literal 522 zcmV+l0`>hvS5pZD0{{Sc+GUYJZ__Xo$DiY*5j{Ys0U8ISNE~{hb=plrt-6ScvH=H> zKuCxKs_QsSSmH#9vy>AzJ_Tp^1Un)=0GI3oaN)$qz)s6Lh9ygW@BRLNKl`n~`~`6R z3&0+N+0GpR__+H60Zei~7{8nyIjbZV#aKm$-B8MGOh{E#{c69T=1VddjYh;BlHstY zh+gqQNV@8Y;$GKl3}(Dwd6da06^@SSA}!@%x4Uum*@bCV=5b@`Gs0t@a3Kpa=ns^U z&&ENTCscYg%i@SpZAVtUB23vyMNfGzh-nc{$QINZ8OfM?Q$JmB=P2eYXWyA_^$op7 zH0*C1^)5Y=YIUEb3CZ%*FPZ8oP*#ojvP4^Co#GRjO zZLB8TQX9ihHD$fd9-O^CR_F8fE2+MQO^YI03OxY$e)F3GG#BJF;REPEUrTJjk&vCM zeCx&HJ!jHPXe7`nzK!-Uv}|P92;0cCk!7Qnsr3kL?rs(`@HGPr0K?qD$Wm267#Su4 zQ=PGiYxh`F1~%KZ`_4M2*4%ocaD+^&RlD_5P<5x*{#6*4Y2(U z;1I!h?;!wu+W(0FMwvewUXIV~DiU!%RM|-; zaF%2dl^#t~5i+XnNaf@~!mdlY;Lc3YJQ$HRQEOx<1@}( z{(4aF&YD!KyDW)Fnk9b0)J!vF)rjv(v_)D>MVJRX^NRR7PReDAHL5u*<5VX9GyY+^ zE@(V2=$v~mUN^PdyqS?o?!796-FKg;+k3hkL!%?I@!BgyeV_;9-9LB)&yCMtzkk@m z>WACvV)&(gS)VW7k9X%PuD9Mw^)&2~%PiyzD&XeeM%6WKmeGj!U>CYtVF3zEYvoej;qGY*ueJ;FaQj552F?!1PCL;L}02I zo49t*6-$TPwL59uR|_1$#Sywt5`@fFyLRiBpg35ic&BzbOt3q_@8MBkDEMGsx7%Fp LnZo`8(vQ@(Pi_X~ literal 0 HcmV?d00001 diff --git a/test/test_all_urls.py b/test/test_all_urls.py index 2bc81f0..0ff47cf 100644 --- a/test/test_all_urls.py +++ b/test/test_all_urls.py @@ -15,7 +15,6 @@ from youtube_dl.extractor import ( FacebookIE, gen_extractors, JustinTVIE, - PBSIE, YoutubeIE, ) diff --git a/test/test_download.py b/test/test_download.py index f171c10..d654058 100644 --- a/test/test_download.py +++ b/test/test_download.py @@ -10,7 +10,6 @@ from test.helper import ( get_params, gettestcases, expect_info_dict, - md5, try_rm, report_warning, ) @@ -24,7 +23,6 @@ import socket import youtube_dl.YoutubeDL from youtube_dl.utils import ( compat_http_client, - compat_str, compat_urllib_error, compat_HTTPError, DownloadError, diff --git a/test/test_playlists.py b/test/test_playlists.py index 1a38a66..4f18834 100644 --- a/test/test_playlists.py +++ b/test/test_playlists.py @@ -11,6 +11,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from test.helper import ( assertRegexpMatches, + assertGreaterEqual, expect_info_dict, FakeYDL, ) @@ -71,8 +72,8 @@ class TestPlaylists(unittest.TestCase): ie = DailymotionUserIE(dl) result = ie.extract('https://www.dailymotion.com/user/nqtv') self.assertIsPlaylist(result) + assertGreaterEqual(self, len(result['entries']), 100) self.assertEqual(result['title'], 'Rémi Gaillard') - self.assertTrue(len(result['entries']) >= 100) def test_vimeo_channel(self): dl = FakeYDL() @@ -111,7 +112,7 @@ class TestPlaylists(unittest.TestCase): ie = VineUserIE(dl) result = ie.extract('https://vine.co/Visa') self.assertIsPlaylist(result) - self.assertTrue(len(result['entries']) >= 47) + assertGreaterEqual(self, len(result['entries']), 47) def test_ustream_channel(self): dl = FakeYDL() @@ -119,7 +120,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://www.ustream.tv/channel/channeljapan') self.assertIsPlaylist(result) self.assertEqual(result['id'], '10874166') - self.assertTrue(len(result['entries']) >= 54) + assertGreaterEqual(self, len(result['entries']), 54) def test_soundcloud_set(self): dl = FakeYDL() @@ -127,7 +128,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('https://soundcloud.com/the-concept-band/sets/the-royal-concept-ep') self.assertIsPlaylist(result) self.assertEqual(result['title'], 'The Royal Concept EP') - self.assertTrue(len(result['entries']) >= 6) + assertGreaterEqual(self, len(result['entries']), 6) def test_soundcloud_user(self): dl = FakeYDL() @@ -135,7 +136,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('https://soundcloud.com/the-concept-band') self.assertIsPlaylist(result) self.assertEqual(result['id'], '9615865') - self.assertTrue(len(result['entries']) >= 12) + assertGreaterEqual(self, len(result['entries']), 12) def test_soundcloud_likes(self): dl = FakeYDL() @@ -143,7 +144,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('https://soundcloud.com/the-concept-band/likes') self.assertIsPlaylist(result) self.assertEqual(result['id'], '9615865') - self.assertTrue(len(result['entries']) >= 1) + assertGreaterEqual(self, len(result['entries']), 1) def test_soundcloud_playlist(self): dl = FakeYDL() @@ -153,7 +154,7 @@ class TestPlaylists(unittest.TestCase): self.assertEqual(result['id'], '4110309') self.assertEqual(result['title'], 'TILT Brass - Bowery Poetry Club, August \'03 [Non-Site SCR 02]') assertRegexpMatches( - self, result['description'], r'TILT Brass - Bowery Poetry Club') + self, result['description'], r'.*?TILT Brass - Bowery Poetry Club') self.assertEqual(len(result['entries']), 6) def test_livestream_event(self): @@ -162,7 +163,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://new.livestream.com/tedx/cityenglish') self.assertIsPlaylist(result) self.assertEqual(result['title'], 'TEDCity2.0 (English)') - self.assertTrue(len(result['entries']) >= 4) + assertGreaterEqual(self, len(result['entries']), 4) def test_livestreamoriginal_folder(self): dl = FakeYDL() @@ -170,7 +171,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('https://www.livestream.com/newplay/folder?dirId=a07bf706-d0e4-4e75-a747-b021d84f2fd3') self.assertIsPlaylist(result) self.assertEqual(result['id'], 'a07bf706-d0e4-4e75-a747-b021d84f2fd3') - self.assertTrue(len(result['entries']) >= 28) + assertGreaterEqual(self, len(result['entries']), 28) def test_nhl_videocenter(self): dl = FakeYDL() @@ -187,15 +188,15 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://bambuser.com/channel/pixelversity') self.assertIsPlaylist(result) self.assertEqual(result['title'], 'pixelversity') - self.assertTrue(len(result['entries']) >= 60) + assertGreaterEqual(self, len(result['entries']), 60) def test_bandcamp_album(self): dl = FakeYDL() ie = BandcampAlbumIE(dl) - result = ie.extract('http://mpallante.bandcamp.com/album/nightmare-night-ep') + result = ie.extract('http://nightbringer.bandcamp.com/album/hierophany-of-the-open-grave') self.assertIsPlaylist(result) - self.assertEqual(result['title'], 'Nightmare Night EP') - self.assertTrue(len(result['entries']) >= 4) + self.assertEqual(result['title'], 'Hierophany of the Open Grave') + assertGreaterEqual(self, len(result['entries']), 9) def test_smotri_community(self): dl = FakeYDL() @@ -204,7 +205,7 @@ class TestPlaylists(unittest.TestCase): self.assertIsPlaylist(result) self.assertEqual(result['id'], 'kommuna') self.assertEqual(result['title'], 'КПРФ') - self.assertTrue(len(result['entries']) >= 4) + assertGreaterEqual(self, len(result['entries']), 4) def test_smotri_user(self): dl = FakeYDL() @@ -213,7 +214,7 @@ class TestPlaylists(unittest.TestCase): self.assertIsPlaylist(result) self.assertEqual(result['id'], 'inspector') self.assertEqual(result['title'], 'Inspector') - self.assertTrue(len(result['entries']) >= 9) + assertGreaterEqual(self, len(result['entries']), 9) def test_AcademicEarthCourse(self): dl = FakeYDL() @@ -232,7 +233,7 @@ class TestPlaylists(unittest.TestCase): self.assertIsPlaylist(result) self.assertEqual(result['id'], 'dvoe_iz_lartsa') self.assertEqual(result['title'], 'Двое из ларца (2006 - 2008)') - self.assertTrue(len(result['entries']) >= 24) + assertGreaterEqual(self, len(result['entries']), 24) def test_ivi_compilation_season(self): dl = FakeYDL() @@ -241,7 +242,7 @@ class TestPlaylists(unittest.TestCase): self.assertIsPlaylist(result) self.assertEqual(result['id'], 'dvoe_iz_lartsa/season1') self.assertEqual(result['title'], 'Двое из ларца (2006 - 2008) 1 сезон') - self.assertTrue(len(result['entries']) >= 12) + assertGreaterEqual(self, len(result['entries']), 12) def test_imdb_list(self): dl = FakeYDL() @@ -260,7 +261,7 @@ class TestPlaylists(unittest.TestCase): self.assertEqual(result['id'], 'cryptography') self.assertEqual(result['title'], 'Journey into cryptography') self.assertEqual(result['description'], 'How have humans protected their secret messages through history? What has changed today?') - self.assertTrue(len(result['entries']) >= 3) + assertGreaterEqual(self, len(result['entries']), 3) def test_EveryonesMixtape(self): dl = FakeYDL() @@ -277,7 +278,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://rutube.ru/tags/video/1800/') self.assertIsPlaylist(result) self.assertEqual(result['id'], '1800') - self.assertTrue(len(result['entries']) >= 68) + assertGreaterEqual(self, len(result['entries']), 68) def test_rutube_person(self): dl = FakeYDL() @@ -285,7 +286,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://rutube.ru/video/person/313878/') self.assertIsPlaylist(result) self.assertEqual(result['id'], '313878') - self.assertTrue(len(result['entries']) >= 37) + assertGreaterEqual(self, len(result['entries']), 37) def test_multiple_brightcove_videos(self): # https://github.com/rg3/youtube-dl/issues/2283 @@ -322,7 +323,7 @@ class TestPlaylists(unittest.TestCase): self.assertIsPlaylist(result) self.assertEqual(result['id'], '10') self.assertEqual(result['title'], 'Who are the hackers?') - self.assertTrue(len(result['entries']) >= 6) + assertGreaterEqual(self, len(result['entries']), 6) def test_toypics_user(self): dl = FakeYDL() @@ -330,7 +331,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://videos.toypics.net/Mikey') self.assertIsPlaylist(result) self.assertEqual(result['id'], 'Mikey') - self.assertTrue(len(result['entries']) >= 17) + assertGreaterEqual(self, len(result['entries']), 17) def test_xtube_user(self): dl = FakeYDL() @@ -338,7 +339,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://www.xtube.com/community/profile.php?user=greenshowers') self.assertIsPlaylist(result) self.assertEqual(result['id'], 'greenshowers') - self.assertTrue(len(result['entries']) >= 155) + assertGreaterEqual(self, len(result['entries']), 155) def test_InstagramUser(self): dl = FakeYDL() @@ -346,7 +347,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://instagram.com/porsche') self.assertIsPlaylist(result) self.assertEqual(result['id'], 'porsche') - self.assertTrue(len(result['entries']) >= 2) + assertGreaterEqual(self, len(result['entries']), 2) test_video = next( e for e in result['entries'] if e['id'] == '614605558512799803_462752227') @@ -385,7 +386,7 @@ class TestPlaylists(unittest.TestCase): self.assertEqual(result['id'], '152147') self.assertEqual( result['title'], 'Brace Yourself - Today\'s Weirdest News') - self.assertTrue(len(result['entries']) >= 10) + assertGreaterEqual(self, len(result['entries']), 10) def test_TeacherTubeUser(self): dl = FakeYDL() @@ -393,7 +394,7 @@ class TestPlaylists(unittest.TestCase): result = ie.extract('http://www.teachertube.com/user/profile/rbhagwati2') self.assertIsPlaylist(result) self.assertEqual(result['id'], 'rbhagwati2') - self.assertTrue(len(result['entries']) >= 179) + assertGreaterEqual(self, len(result['entries']), 179) if __name__ == '__main__': unittest.main() diff --git a/test/test_swfinterp.py b/test/test_swfinterp.py new file mode 100644 index 0000000..b42cd74 --- /dev/null +++ b/test/test_swfinterp.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python + +# Allow direct execution +import os +import sys +import unittest +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + + +import errno +import io +import json +import re +import subprocess + +from youtube_dl.swfinterp import SWFInterpreter + + +TEST_DIR = os.path.join( + os.path.dirname(os.path.abspath(__file__)), 'swftests') + + +class TestSWFInterpreter(unittest.TestCase): + pass + + +def _make_testfunc(testfile): + m = re.match(r'^(.*)\.(as)$', testfile) + if not m: + return + test_id = m.group(1) + + def test_func(self): + as_file = os.path.join(TEST_DIR, testfile) + swf_file = os.path.join(TEST_DIR, test_id + '.swf') + if ((not os.path.exists(swf_file)) + or os.path.getmtime(swf_file) < os.path.getmtime(as_file)): + # Recompile + try: + subprocess.check_call(['mxmlc', '-output', swf_file, as_file]) + except OSError as ose: + if ose.errno == errno.ENOENT: + print('mxmlc not found! Skipping test.') + return + raise + + with open(swf_file, 'rb') as swf_f: + swf_content = swf_f.read() + swfi = SWFInterpreter(swf_content) + + with io.open(as_file, 'r', encoding='utf-8') as as_f: + as_content = as_f.read() + + def _find_spec(key): + m = re.search( + r'(?m)^//\s*%s:\s*(.*?)\n' % re.escape(key), as_content) + if not m: + raise ValueError('Cannot find %s in %s' % (key, testfile)) + return json.loads(m.group(1)) + + input_args = _find_spec('input') + output = _find_spec('output') + + swf_class = swfi.extract_class(test_id) + func = swfi.extract_function(swf_class, 'main') + res = func(input_args) + self.assertEqual(res, output) + + test_func.__name__ = str('test_swf_' + test_id) + setattr(TestSWFInterpreter, test_func.__name__, test_func) + + +for testfile in os.listdir(TEST_DIR): + _make_testfunc(testfile) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py index d955339..604e76a 100644 --- a/test/test_youtube_signature.py +++ b/test/test_youtube_signature.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +from __future__ import unicode_literals + # Allow direct execution import os import sys @@ -16,35 +18,65 @@ from youtube_dl.utils import compat_str, compat_urlretrieve _TESTS = [ ( - u'https://s.ytimg.com/yts/jsbin/html5player-vflHOr_nV.js', - u'js', + 'https://s.ytimg.com/yts/jsbin/html5player-vflHOr_nV.js', + 'js', 86, - u'>=<;:/.-[+*)(\'&%$#"!ZYX0VUTSRQPONMLKJIHGFEDCBA\\yxwvutsrqponmlkjihgfedcba987654321', + '>=<;:/.-[+*)(\'&%$#"!ZYX0VUTSRQPONMLKJIHGFEDCBA\\yxwvutsrqponmlkjihgfedcba987654321', ), ( - u'https://s.ytimg.com/yts/jsbin/html5player-vfldJ8xgI.js', - u'js', + 'https://s.ytimg.com/yts/jsbin/html5player-vfldJ8xgI.js', + 'js', 85, - u'3456789a0cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS[UVWXYZ!"#$%&\'()*+,-./:;<=>?@', + '3456789a0cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS[UVWXYZ!"#$%&\'()*+,-./:;<=>?@', ), ( - u'https://s.ytimg.com/yts/jsbin/html5player-vfle-mVwz.js', - u'js', + 'https://s.ytimg.com/yts/jsbin/html5player-vfle-mVwz.js', + 'js', 90, - u']\\[@?>=<;:/.-,+*)(\'&%$#"hZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjiagfedcb39876', + ']\\[@?>=<;:/.-,+*)(\'&%$#"hZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjiagfedcb39876', + ), + ( + 'https://s.ytimg.com/yts/jsbin/html5player-en_US-vfl0Cbn9e.js', + 'js', + 84, + 'O1I3456789abcde0ghijklmnopqrstuvwxyzABCDEFGHfJKLMN2PQRSTUVW@YZ!"#$%&\'()*+,-./:;<=', + ), + ( + 'https://s.ytimg.com/yts/jsbin/html5player-en_US-vflXGBaUN.js', + 'js', + '2ACFC7A61CA478CD21425E5A57EBD73DDC78E22A.2094302436B2D377D14A3BBA23022D023B8BC25AA', + 'A52CB8B320D22032ABB3A41D773D2B6342034902.A22E87CDD37DBE75A5E52412DC874AC16A7CFCA2', ), ( - u'https://s.ytimg.com/yts/jsbin/html5player-en_US-vfl0Cbn9e.js', - u'js', + 'http://s.ytimg.com/yts/swfbin/player-vfl5vIhK2/watch_as3.swf', + 'swf', + 86, + 'O1I3456789abcde0ghijklmnopqrstuvwxyzABCDEFGHfJKLMN2PQRSTUVWXY\\!"#$%&\'()*+,-./:;<=>?' + ), + ( + 'http://s.ytimg.com/yts/swfbin/player-vflmDyk47/watch_as3.swf', + 'swf', + 'F375F75BF2AFDAAF2666E43868D46816F83F13E81C46.3725A8218E446A0DECD33F79DC282994D6AA92C92C9', + '9C29AA6D499282CD97F33DCED0A644E8128A5273.64C18E31F38361864D86834E6662FAADFA2FB57F' + ), + ( + 'https://s.ytimg.com/yts/jsbin/html5player-en_US-vflBb0OQx.js', + 'js', 84, - u'O1I3456789abcde0ghijklmnopqrstuvwxyzABCDEFGHfJKLMN2PQRSTUVW@YZ!"#$%&\'()*+,-./:;<=', + '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ0STUVWXYZ!"#$%&\'()*+,@./:;<=>' ), ( - u'https://s.ytimg.com/yts/jsbin/html5player-en_US-vflXGBaUN.js', - u'js', - u'2ACFC7A61CA478CD21425E5A57EBD73DDC78E22A.2094302436B2D377D14A3BBA23022D023B8BC25AA', - u'A52CB8B320D22032ABB3A41D773D2B6342034902.A22E87CDD37DBE75A5E52412DC874AC16A7CFCA2', + 'https://s.ytimg.com/yts/jsbin/html5player-en_US-vfl9FYC6l.js', + 'js', + 83, + '123456789abcdefghijklmnopqr0tuvwxyzABCDETGHIJKLMNOPQRS>UVWXYZ!"#$%&\'()*+,-./:;<=F' ), + ( + 'https://s.ytimg.com/yts/jsbin/html5player-en_US-vflCGk6yw/html5player.js', + 'js', + '4646B5181C6C3020DF1D9C7FCFEA.AD80ABF70C39BD369CCCAE780AFBB98FA6B6CB42766249D9488C288', + '82C8849D94266724DC6B6AF89BBFA087EACCD963.B93C07FBA084ACAEFCF7C9D1FD0203C6C1815B6B' + ) ] @@ -57,12 +89,12 @@ class TestSignature(unittest.TestCase): def make_tfunc(url, stype, sig_input, expected_sig): - basename = url.rpartition('/')[2] - m = re.match(r'.*-([a-zA-Z0-9_-]+)\.[a-z]+$', basename) - assert m, '%r should follow URL format' % basename + m = re.match(r'.*-([a-zA-Z0-9_-]+)(?:/watch_as3|/html5player)?\.[a-z]+$', url) + assert m, '%r should follow URL format' % url test_id = m.group(1) def test_func(self): + basename = 'player-%s.%s' % (test_id, stype) fn = os.path.join(self.TESTDATA_DIR, basename) if not os.path.exists(fn): diff --git a/youtube-dl b/youtube-dl index 73304fea2d5a7b72201c315456252900fdb584c9..bb583eaecbe95b7b66fe932698c50e9a882e91e8 100755 GIT binary patch delta 184040 zcmV(=K-s^ij34UGAdnyqqrCY<+v7?(#y0=}+vAgi0U`$i&eBtSA<>hp0Udw5z{bnf z%T7+1!z8+T#7bm|B~tNC(JUP7VwMXN3#RkpamOixcw zPfvGGPtX0Y9&Fp@!Mvy*i0UTV+;ywEI=CMl{pKiI)Ok@|9Y@=4dGsIn=HOu2)axis zm)maJh%}9g^`>sRD4Vx+x$S>M%D<=4wkn{uNXw!VO;)xC2eRa%E=#fKin?mmt32yO zSFDBlEt;mP)sI5|^-~Lo$-m2bk(IhatwC+dtXtO2TK#TxnRd19ic0fvHgN<3&WD7CR7T3_7B{Vy$vbBg#PNKN#;^Tt|9@Wk6ZX$lDlP=0aRGss_?c8$PrYwtj3IwZz9~$xVR4k&lfMBzJGn5zI}gw{{87|Sxvy$u8T^f;)87C zd3{@zb(UMeMTLy;vM7HA5{uux_<)q`>c%RE!v>ho?>f=iZ_dP`u5$V6N^~hUn%)+9 zx8iptj$EEDp#^@i&aOrJ-TC?HS-Q%qycDv9@3RjIzxJKT7AukShtupzLUimv#lAVhx+0N})~=t|Lg?>p$k z?FwF{MYSlmZE+(%ysxsGtSGa2DgIvMqPCiVQBUVtYeBhfVE&~zb1eGsOBia6?mudn z&vWto^>;SCpl=&dq^RtyTb2$RSsoHLf z4ttcE&$9dm219>NRnywbm+OtV`d&0wqB%X4C2vH7NUAbvDqp1O!NI|z%-YuUGpXl4 zffSnXoV|DNp8gV1$=QKRmx#-^QPzm4TZyQyL<`cT-GCe`0P(0^MhbTzE0!S$(D!Xt zMmIQ85e`8F6s8ftQU!>VI?9XoIs$ouaJMZGW|bjqn!0}?XQ=`rHCxwErL95Y)KIhm z7HO~BS@f!k)looo<&bv7#-lKD#|2k@87+i z5(3uvMn--GqPcZ*XJ~4&Z>l5#ySuv6jQ|5=OpT6@YYqKvvle&@@^LShsR+5%8*STdL_b z4$y%ljktoj4rD@{p)OORZlKSz=!X^j4dYU@gqWm%W(ee?5V4GDIPP!;#-)z@)gg zFmuzuL{&}XZ8K0jU~OU8e0KY=T$niy%D_CW5@R!kY$dv8;UXK+yHJB_+_^o`%%OFwZgdI@WrqYUh;d4q z5X6jK4kO9+e%=ESI=#*tL=JT0S6t2z^acP zF1ctIO+nmt+^b}Lw5ljg>3F!ms)*gtmU%r`OMSG;qt}{#ZT69)*_VfeqZvjJunznDoy&jF2eib5T@vi7b)m|CS6qR>>VO3^Ft_eh9bAl> zJFW#>)U7u*mqh1cjruIlU--TOMnj58j6k;miMHqzA%Qz(PiT3K?)~q3q{_6L3@0E6 zC(>@HD61@2Row_OO%!KK0Bu)qV3ju{;X-OY)G!4}MOD>K8vzS6Oa=LYM_GT<4tjA{ zf+TCZtdS%+m9Iefi8ar-46W48tpUodqDZd>eADHDnv0b?XVhW`{eZQQ3h23`DTphR zQ|%qS(j9M!_QA?!eFeI$!w|3QD@TfCR0t~0UQ=O`V_CHj8bSwZA*>u4j1PgoD*1;? zuPvEq4BXlI1HQ62*!s#C&Fp_SOQjhQB%Cp3O6`V(-xOXs*aI(2TSy)<76XR0}9|Y*p3o2dl&6bK5nn*lLZ? zRAxPzQ96jiPlBdK0rTDK7AlWDY$wcHINe+{(0pbLjILxrDUHP-qQ8F`(RU_aDFJrT zHr<1Ee)Hg_>n@`t7t3s0b|>(5;({nMwR$2J*lB#TB{r87aOkP#A3?bmVnb+|$@VvR z<;m$NTY`3m+HZHX(Y^ugJ!#NYVgNif{u8O7PK~r9iJ{EB4Zcbd1S)4BMe!{`lMBjq zvC&2`H*f~8m|NJkG=P7X9@6X)B1cDI%aYf%)O=(OD#9XFp+Gi6kr)!j=@uw1h@F6}VEs@G(3XRA=!+YNHC*2^4`~Qvo9jrE#!5 z9k*Bu;oON#tuuk=eWlzG%4kw-D{W-}f~qx+$wo+haa~mDO(B17+x_r?;-Dg|Bdh|e z`nKwJPtf(Y?byyOlr_}xN;>zD2|R!2o}f*Hs-)GfV>hD3P~K*D?GPMoh=6@WBagJH z>WIcdEt4NUi4@rfj}*H)p^ck0XcjORH=t|b0A-c=1Z3Hx3;zwMrHZ6k1IzynN{^RH zgW^d*a_5%(IVgWujn;tegGGz1u(K;!*}$y2izM;w`K{<>VLJpYyUGfw8?(n6>l*_? z3Px9bfVr%FVCv{+m(MAH>ZG|I%W)D%JCE0%ZB+1cyJ`r2Ba z*A&EtSZo_Y2CY2w``WUE{J=P08ZiF~apU+)28s8Sr{#aTMi;_V8_y)V+wBG&H_(Ck z9h&mzV9L*wf9=DaYXhRoMM_!v8i72z;Ry_)iA6l^JfyhK06a(4&*5(@a+?($vCg(q zzDDT43Kk)BYg7P?eB%UWUgSjzX7P2_0K?K+@dNyd_-8cVUR~Wq?6A*D!{S)2;SCvB zOFHpkaQc79eov+6XW2l_c_DWK0DMZuQP*Tk7^dS>ZM_oP;jl|5OwMB@3$m?%F78~U zz}&_NmWu>2Jm4$JQnp2EK-vnNI8^+U9o0Nc?AOMHBSYbXW)0ZKIC{iUU?L6AnHW`_ zm?$nlg{jfg6kTnt#a_AjJ>LSgtiIXoN4f_sibsF#Ml67Xamo@X^aL$yG^VhQaeC=# z2@IlmOuCEMH$;BOJ1QoNXm1$KMB|4$Rx5Bu!?sZyZByWeCAtBNf5P9`Ns>!bTFht} zrw=I4&96>xB%xi0?-v9byG?vELT0kPS*G zGqquGAYEJN0gO&a$kUq?1>Z?@aml|n8~c}*`9Lx>>79zzcAXj-Z+`*PNC+Mo^oMtXXoY$!`S%dW)+F7q9U!^NpW`ZRGWPa!s@rmt!cS(K$Q+UR<@idZu zgXMgA!JVF6i7tsPgFBu^FG0wPiH{k4Q!ot}w~VHv^e*@5&&_%AUN`BEO4r;S_gH^i zZI*X;y-({5z0lCf67|g!EHkS?xWd25q*t1DVWE_}EgL8ZxO3Sc>p0**AG-2JRXqaw zw@=OZ=oZKU3qeBfCw)lmCcVCu#nFqG1fjz46xE4|6_}mAI(-qA7|a|eM7F^aFxDq7 zAM_~|95AX+71>djs*ReH$i@x_D%^h)d@hJ(ZsN=6Yl~jf=r_O7)Ckt?<0wARhRxeE z+I#+D=z@lU7{gG;M+^M_`}3Da|1pMtA5{m91y~A|C;^SSoh@@}Uom{#%wxB@+e_3z z>Ja-;Ac&Yz&tUQE#qBtoPNpbdzmdZ=2|UojyJPZWafId~oVD z87z{HluA&vsm*uVEBWI|lsuVE*kKGGRUk$5)kzeC3h?A{tal?FqTP|OGoA&dVkHwq z`6ABRML`Vm^v&6;^#4AYeRBo$==Z+`lQR!B1^VW9-?+1F4+#N(Uyz2C-n<}%9s2u% zRZ{XQaDCdy=c(4*Vc(%Wl4s~w(BO~?q;VoCrqa*ah#1X3(};q!P+D;%ZV48$1dNU8 zw4t)5J`p+Cmx2_#K2?d8B^7M$FGN@&A~*qZN)Sn4-US%S9%|5pw@rn^>9C+Orrnw? zk8F6nkRb!{4cq{K+iq^)*8rOafurSJ&_dvO<<1MVSi&& z3`A&A1?Cu7D{77beEo5=*)eMfOWUMTNUr)wN;eXfjj(K#fKX~cK$myyoKhZZS|UuN zlK{Ss8KqHQS*WF+jUh3UTZk5Vz{5qu)vVV--(8yL{x4%58c^X2FcM#uC*Q)S}um zUTl+?Vy5GXFKmOLmgTm!t)_3iL4Lc!Hn?r8G8KAcm`VRGj8Gs_)_2c3d{Xyk=~;9m2SXxT^CoY zPVL}U0+#}eM};Q;OLpnMfFV2pY9|l%5WqnlvGJ6_0sPK1e&e`O+j-N zjoiGj5T{B3Zs=($SkQs@!P*P?4Y>q8s9}0f4n_s6+4BbdQ0^r5tv0Hr4|Ea!w#nar zf!v(?qKlM}Y1GXFTQ<+t`6`U`k%4h|EC_em@!WzA`~hte0Iws|;VHmHLwQacqqN6X zshA@xq#RFR%wb?~hi+M1Z5tUfPNAC`h!>|R*L=AvE)QO;vpeYlBflehPAS01Y;GXU z2yqDox8at!l1x=>m5CGE>jA&C~wWlpLHUAX}fy3vcdw%8^=|#s|_Y@V%8T z#3C|o++T!|=JVlQ4}^3Fv+%=$EZJmo@$m8(Cm?*7NrtgTDJx5%<0zDadX5L+f?7Yc zjAlge8#JITEEj`Em!Mgx-?4GpIz{v^M0n7L4+wm13>iI2Ga1CJ`6T(xa08Qnutme5 zjfND2o&+ind$PMZ2I6HvvmPvTSXeDcheJy8Fw}@eec5-09dO(jKI`U_of6-UsveN| zA)cZ^{Bq;1KFV#)a80LHcoYWVxJw%DIJiemjn1su#xuMFd%}a2bi|x&y0V6c>3Zxgq+3 zoSuPbfRSd;m6v*~af^_68Xa^-eN0~MEvbW8F6sV)8*Z6ARw2C-`b^j;r8;>oicfdR z@DS6=!EoV=7{+U{qK!^i8xjn)o8kX_4FRJJtL=IYrVqx^DHn@>Ek3;>o?91#8$B3< zDrUd2Z-QW?&)VcznR{~u{p%paHOA8O~VgBKe zx|nzcxzWq14?wnmb{W!|!|4Ay{Mt=m02C5?;~+`+St$HTQYcIy&r>WjctE`}ThH?> zx}HWi$NkJ6{jd(pPPv)%ie91>AGGiod@8JuA0D z$DiR*&i?Z1sE08ZM&}+cda7xlloaVuki>YDm|%ANh6i+#UOpRGyRh)YTY)6rUMw;l zWksi6b2q+!JV)=SK8s4=h^5)IHit%x9$*5l@u9;~?6{+qR<^)Hs(hi|>jDF0W2$LS z4s?fd4J4Vaq7Hny=dU_tz)uuySY#!dcf~BoCgRNKD~rB>#bbkFWmn=Iy%|&z_#W7!ay*^y7QT zH;gRs$UXUIUT~-#0gqtHbOH)fS*v$gA@+DmAD9mH-TFM(dHc+DsQ0GlR>^;1*QtLZ zmw32+x4Y+do{oR^IN3TI3jK8@C3Hod84c?|xjugyprk&rih@rS^p#ZAgxqV^0EcXO zvYi-zX9qVGaiHufC)pVNnt(-Ev!gAUOifD@YsQOP9kbz)$$Se@$*MU>D}97BIOEjE zz6x&YS)fUgvs(R6>xAeaG&V5^Pr!9)p1+`DX~=eu;`vWS2$SlLh1x@(C$(n zV~34Qok1>gO8uwLr3UUadN}A0vk2nL7mGLrpJz5oW8c{VO+rht-E_zgpiY@m zqAZ4k^tQ--;DIq3!Jk`9yRhI5BCR7}xEs08*|V#WnnvcW>&;S8$=Bkp<-HG6Qmxv5 zq|wR^EiFR!cIP=N@WyQDYIYMX|CuvBM1z@5{sPn76}nxU7)1tF?Pr1 zVJ4Fw6H8}%h`onHV~sKua8nB{=rBC@z+nuII)&H0Sxt)==nXPAKmy|$n851n%@j5YBYSNW}SjB^FyLmWVY(75 z{V~jsc67KcuMJ%aK{75l$Wm;Ls?fala=}!?wOdd^$XOc#ZlS@WNh;_)^#x9(Eo?Ux zEl!`DIP$3sR6ucwIX7?dfE8H&V$lWCB=ik&%j1&^)M|y=OV-=Sp^f8zK5t4q1IcRx zS_GZN3ieV(WT0Xdjzjp2t>(SDkG=2aC%d=mKV`P=I*&G7F5ok%FkO?({Nf(8L0O9_ z9N2atZg(`9zzoqxUi^9D1tR&1kg4EGfmp9`G?!(#gE}TO1jSJG z82qkN1am?ClO*?m#=pQx4wPTquhcSul&WIkIF!(#tL{o#eA`e+i*dmg(V z1ZPZ=il?Qp$`d^dq_yoT<|Pl1)M{0(;Gk>I?wn%?=uTY_l9$8lwe#q8Z@=QwsPOoO z--b2|f{!%~Lt{99M0i}ysunk9dz<(7^@&S6cM=(JWFM^OBF{PX$(2iW6#~?w=dkXn z2>i*!2=?3JL3vg~*P;xe0xm(61kDlw z*jEbLLU#h~Sc)cK%l^;VB7=Yk0mnW#!Qj zQ^j5hCKNK`Pr;t`IZzj;uWd<;ap{F-7wrE@xTh*m^s2Cr#Lv1`xpm?9pT~v+x(t;9y@(Wn(Jm?~*QqVwCSq`HHVEjS= z0yeF#6Doh!sw z8L_E<&2;^SzVwhicZY@znO`+9W+WUK5su=Wc?1)7KZX7J_z+q~ zmm5%DsMMY|SnuhpH=hZ}SBm<5^%Vn^5W?=Iw-FqWf|xPR0~AvA`X1S!S~jepQnb;s z_^{n1&5#7~oD@x%b|WtL&z-AO`Pa->AHctA&bqz&jCqUC$3E|_EhT+!4PEG%^v)VqeqwSH1ylJt()Ei9EA38 z2QWl9+vbJuSEP3eN{~;M#ud_QHncc@EM;{8`d7y-4HklrO3yDa?~c7TX@cYm!TyJ zXhG1S4$5ige7+e5Qf2xaEF!Dqd#BeS{VCSwFbshG`ySZK8Z z+MDJ{{5=O-MfZyQ9t?&ka~)kp+o;?PH>6I*UH_`~2*!AmPMg}o+tKWO-1sZ#_Df8j z?p{jbj=c%z*1#|A?A;>;t&@8tI{VV16McL4O#iX%7P!l&VFkAB>@yImMb8atm9f#so?E|XZPzU6jAeZI zkHht0ZqImmaKlPPDQ{Pm7fi7-PMK9!Vhz7;L>r`{WAt(6;eXWI>uv1iLMY57zyn69 zwsV}|*Wg~c{%UvV2Mox6zl}D<;yU8wv`Xzz+uhE=nGv2)`-B507Lj(GHfa|Gv&t)DLCQ9;Z3csz>-Z+mYJ_y#`r;S8asVsFdsm2 zXt^?7uJTCh61>_NMv-1lS=4cJ_Dwk1C6W|M9>^Qe`l`eD+6N$i?qNJLpUNluGob|~ zl2P%+q_>m7P1y{9(q!b&Di`uJDf>8M(Nl%`ZS3Cw%k^K1{9|+!{Q|xE_zMt8e2itJ zSlGv1GAW<3wZQwTfjxj13T)zB*!+rbQG7 z_RIb4u&3$@zKjlk{p-X~bYe~`+I%R*TvlTZ3Tf867*2IZYT>3G^rPv{vWIC_*0(05 zwW&RPw8H)#I;!K`Y&sw-I1f*DEkO2xI!^Zn;hji*z8JIvzB+MQQWMuT!zS)3^7i@L z=o$KwvNA#?3g_Qd4Hg56$b)_-(8Mz5p9VBczD!CUZqTBCPf8b+tgCK{t3us5%t{08 zFW*I0ucJ~d{jj{BEvJn6H3Kz&x`6R|5cjQ@X35Lx&%-ViK1NCg zebU6UumAMp*YH1}WV76nltPZ#ZS5)=@}!j_QCVEWOnda?cV9nx^84@^4k^GMY2Wc< z?BG&$?CXIn&}vv^d>v<&c0JNQc>;&TyuP`F; z0i!np2v4FvMuAAA-Yzxr(0s*tr;S+^cG4Fg48fB^ z#7~bjRCLDI4=N>l59?UfG-YXdVK_Rjn9m;S>+5hWiGJSdlXBRrp|fPxLaj|>2TO+v z=;7(#r{UV@&It(XFi1EFhP-S7^fP%8vOXxF501^8^8vrYyNly90O4rF%1yPq%_mIEYo0Gg(4;FOb-o7Ykbw`D2wXN)J+kkhbV0%zglhYyEceIw8> zjvxL0cX$z5Je$p8+g6~v!qaAVFiE?S$-(hLl)vi0shCC8{6PVh21m1i` zz>TkKhj{60owO4lE6Xpcq;f5bRzHa zoJOzS(jSw3v#M=UldX3O8nOtEky=Z#G7082Gq3-8~5xEeHG$8W^# zH~a(i&Dcpc0$t6S?qpwrK*^FQYP$4zfCd-`6I<6pshhVrc>okCLfOZhF~l^;e1X_* z!LO+!nfPzwPIB=%DE`dHyN~7DiA5UmBj1PU5{GZV3f}%YG=KI@2M|Bwt4OH@r&-#; z*fl77Pa*d_VrU9siT)ISvg*w~tjjMqjkx(wo<sS^EpWHZ4Ro<}qol~0|2+eEUPC2H*)mY$WRPV=T{ITfoZF@Hvw`y@xpe7P^91)gGxWL#c=i>!?n220x&x7nS(3Zg~s$9p=jYP^hxQiyI_buYxWvNmr#UeT+ zEv+TTZQ~0N-b|XOWd_)weyJ+WFbP{Qht+n@x4Uz>3st-C+2s)(4hXb;0TCAn>sj!htZhPC&u&WkPp_3(D03etmJ_Z0MqOoZW=kThqaj*kOh) zZPSak1}Tg~wU03hsQZw2oQjMJb6T9ENGTDH$o}w z+XM0O)8;Cmj7eB#)!02(C@HIjLU48aSIrt1zo9jw$Jlt@8}|&)6$wI9X5h59_t+G5 z4uAVz=ugRi$~TCxeYjhXUxXVhUmRO}2Int6+oe*bwoOSZ)-Fe~|Il(rHQjN=)osp; z8GTreuVw9O+Z81x3qlC>{HJ8QoXV=htq&4i2|z<|lyh{1aTJezi9L;cHV*3{Qou=1 z8W6cG<}ABr@87+aQcr$eb=@Xilm#&I?7Q>xQ+*(R6BM3$aVrurw?A~i% zpOx=T5$E1vd+$@ps}yyDtQ&^vVL-@i)kj7gk!yP!SmlL*5gevQ`w z_sa7!;VG~q0BDH@DJK0@X&TKHS`8;oQa8IB8Vt_`v~D&lvTJCMk<#qqmi?-(uLp9L z8cgVaT)9&v*{p^e3k}S`U7`NtZ4Sg2bTRv7^s2h4F_*A?lPf4JhYbaNqc&$9&>3t& z-8_=d6c~FfhRh*v-R=ik?GXZpk9D_)6VlkD!7#ts&ssEBbi>=rm+OtV`ksECo=UC= z&Z=u6Hof~m0zIaiEC}8#MHUnv#A3^tpm&Ua-==Om84ZH&gwcLdUqjO9AN7`_1dZck zy)C<9g9_WuRZ+#x(v5%1CDH~Di)S}rVc$sS6$TQt9bGLu+XEtB+$O=^*42+3%u6K7 z2LccA8Mid?>C=npK1{WxI#g>(+dfNKvs_BrS@#4$TNQHi^(-;h_E-K1@ zZoz^7$x><(OU^yuhP;mhwQdlUDLe0ATe#uqG$=7!$!{UuO+rV386#hGEfak}-i zKxU**-TuJ|lgb(MY5aEzHDx3t@cABN6d;>5UFkZqPvDya4=mnSGIsZg3DneoYEP@K z>qxyke)sO(Q#L6~V@|V7r*G;d1xz^?iT=84=3wL!3{%utV2ChsO0Vznp^pBOaC=3V z!NvnT@f?(&e2r(%8H_yI0z7N<4R^XEF1mmwBA~GKPMn80?f$E7_-2u?x6VoZ+q-E% z-#{Cf>jUn;{bZN#PW*)Y`vXpY#_#3jMSKq`a*w6{(z2s&cna+qazcCk+Rm2RyVbnU z-6{GV__7poK3WmU+Rif_aeVSlAy6)wAt$`&vXIIY1vAkEvs9z-#l(SIASx#dGsoO} zL*m>3??Sb*VaZK1>7KN*Wc7lL>`J3X%+P)?_k0QL$cNfY-YV!e8f-*=UUVU#c(a-t zOsPdJX+d>iRq?dCuqxu-g|H{*I7@-dP-PYb;UCt)d#bmUK0@s&@qD&k%1+vVv1O*C zb_-8yq|-Dp)}heRU<@4^ahxi}KM=FowCQ4%6_smu@dY%7A$r>5i2bTT&Pegj70MwU zbkave)sjw!jpd;rkHiL(FEAZ{(cZ5!tob^l;?){Zq#f|%o5T3rhwss%6j=i-yC~@J z^PRxUdIavp)60BV+uj>NDQN;a&cH<~{dGpn*6o$E(7PQax15f09C1^G9e+X2@YkW| z0_cJQNFOJr4Ij`*lT8Lz$I&&4D{N|_?t2g0fOQLx%m%BJCiAUm2?*CJrg zWG0C~nxox_SedLScT$CagaMWl`mh?iBMR$~x2&TftAqk{HF0boBCzw@;1Gu{Hyj@2 zWffA%eE=@qm(^%LX&yTF5o1~qb9%;Q!0-tgS!ri8JLx&BS`j~%Xx`_n`z@<6El!~v zj;FvSs>GBN<|fF2lCpzX7_;*fn}m*}afgRRy6m*$=9S_@N)JSTvZ(uW0N$bdqN>rR zp+9CX-n@PB=6p|u$Qn*$uOS=q-^pUXg16)$L9Xa3_B~$6KAjirFEW@$;t2Eh$4ZIf z@a3OFIaj9YVj@7Ix~_n5_TGq>PNkpbGB|r;%3?`bHsT>rRzk56y-)3w$owaE7P2A0 zDqGsFe5U+s);JbOV2iW+3@SFTPBD%|6XsC8M08(9Y zH42y$bcgu|8}u(6)rho_fp73J?;NZW3oSjS_1^+_9z8sSL zy?%SrpXoe*Bm=3VN8h$qM>Bu4{ZZO62%kG;IBoP0h4&k?KOa7E1}z&Kw019$QF8cg z{@p((Hq>?)DtR`Ge~t>l&z+4dEona`Q4&-&XRUhvc&RdJwgIE>!;;Z4eOp*B^jYm2OdK?eEn*@d=?5^Kb4FIOF^qAQG({QPR`LMAeNh` zRD{HT0tsb0pTq-Tj~?v_7c-`~fH6JG#LAbk5*WRdl3{tmeC*wRYlwLqIpZ)@*_UD+ z2H~agu{HH$=a;^!koB!&TutELk81YtAZTC%+d5Cx#*>w4w85atAFIO_{~HMs>}Tt- zNHHZ#YW7oIm;^qp4i&^1uYyonE;Qn2*C8K&ozdNGSry@CzuDiieece000I*YZ~FkW zX@n_t>utxWGE>ws-b6Hx&0KSl=+GDipGjisF?bFgf&@1|P(+Ip73wS9g#knF5$AJzCm{iR zM?*);7+oE_t1!nc&Q!4hkxnsn8j>Y{9{Jb=dXV6QO%=;$!AV5jiJCeUHO0(WE2@*1 zF-_&KG}Rsq1+KqYx#6>Aa;Il@N)x8nuZ#GKQk;Uwxj6!+Z%JAm9Z^IG{`uXDr_Y0H zB2nzbZsFDG3rutfGpp&n@6})2<|lrx1@$|dxA~6{wJR={iG>{KX`H6vP#Xlbkmuz*$On`M&MxxvQ+rI#2{<0lZQepyRzs zfsxV;tH4KDYbNVV_M;U-0i|hk>?hFB@V!oxyQhWaVI%wFuQYOXN^i1Y5RSWs#Xg$u zX8`cqhYxA>v7oBN`J~b;VMXl{>$5dD^#)e#MO|MPl$|Gpj`?b#LiLD$0Kr>R@q>4x zh2K)pr%aHz&`()o@^|Z3vuE_zU!6J8x0H9o`M&;VQI?qj*JB?K;hxX{ag|X7TjG_R z;-`1%+rJG-4}%2-OIUQ`FR9+2H<-()Nf|Rtp^=RHsVbX{P+-y<2_CyKo6;U)bW4UO z7+?PRi<>Ak?7Fau$EfCifHrH|fT>KXkMr{5$PgQ7VG5D5Kt(+1c|ST69jTjVEFw_p zA?*`q40N1BK=#+f{^Q}dJ?7vJQk;aulP?dUE~=Pm4VP#!%Bo&;gdnY8Gx$(G9kJ!d3d9vT~e39+?sp*wNjG^LEF@3NpN8;vdAWi%Wjg8SuT^h%RAUJ}NVxg7D03yo9ps(P zPTg^s_9pU_@Us(yQltatu9N!*m}H?j%C0ahmrazZygB2x-j=zQHa**HO56jtz~Syc z-Y<=*K2XD7Y}>AXUNc{-5y@*o7X?9Aad#Bh9(T|!Ajz2!(cXOj=*h$1(=wim4sVw6 ziHhfsxF6n;5__#j4UPUVYbOV6sB==Tg=Srg3}yp)t-|i3mM$ZZXGs}iKC%O?YR#<1 zeTCms;-dGUbwXJ(aD)l9@uP_`Mp~z>w0__z-RK!z?Qw@*BgUqRwis|LVp&|td~$de z2H1nx<>*M4sVOwxI}BrmVIn!5UU-^_1{7Gt)i*EDL)8eb-xj=prRH1o>dV3Z2T)4` z1QY-O00;odbOl93(;ODZEC2v+s{jBN034T)Ne3B!2>=5+(BM-#(BM;bcnbgl1n2_* z00ig*006{XOOG2zlD_w^$Zf+Q=^@#c;hi;vZ3DELt!}AbXi}2BvQS7?CCOA*RnnPR z?4|}ghq>)<*wX@g*~47tvPZ%HYa{YiReaOq#RxODDj$(wL`FnLL?->kKb;gxo{V^Y z!tyzPnJx5G$XxE5(bexP!ZmaTX6k^TA?az|%UXzE*kUotsi>4IEll1+W%y_kIdAISyzK?12j zV9HZIn~@7TVHx8}GwHhqpZ_LVP6mJ?{lt9hYc>beHWbss&LYp%fu6WAk>S5uVUs0Yha!utg#pl1~>=QYE zXHtItuRP&F+^^VpOkPM)r~vs^(TtMUQ-GNGwrd_wDND&anpRl8?vkIV5@JN&q$!;) z&3RR%90YPMDNdGUJ8a>CTnjRIq=Dz&6HvbqG!A@ z1(hP7kc%S7_)=vE_L_bC{MR78fd*E8L3Tek?h7tK;Gj0IXvS1nFi#{^qz^(brIV(N z%wbl-BrqR{U8C~mg1loaQ}vPW=p-+x zzA8YzFS_J5<#Q^_{kWzYlwEA(pcx>Y2~j~B3xxXlKjyNkdZ4Xf zjY4KZ1`%9{kBnTgQX~nG8-gl-PidBw3%z7QPROgz|2@rlP}_T&ju9ZZzF_gye^a1yk()HO|Gk!zM~-g(E<3Zp|YLIL~$S{N9klN6NUmB=aAT$L(9 zWy%zJF=b))1yza~XAw}GiIEiQ*T2w5^6URDMna+oX`!c1dCYRfz*C=pf}s_lQ!zOc z83?y=bi}h63`G~uV&%WM@P89CJ)=^w@EyiTnkORjUuv4Nr}CrFJPlt9b#!zzmLelv zY*)l}*h3>0*^KIF!eAk#+SRrh$X?r)GpgA=%_q!#_Ro87u7=U=o8j>K?#ea-2f)Sc zOoN5m79bjdPs^f5p6IE6n<^gjRM4a^rI6*Yn8s6@0~!RL9e(kg4Nh03HbZJ*%t)dIHB&thr7dCrT&L6lOE&W5x^sFi98 zSVY2lJvk{dFlu#wdLweydhXP3Od?bStAVOH2HEGJ1JP)qnQG$zTBQ2){RcM#|7f`= zKk$z*v&UeoV#e|%BCRl#J;iLM$>pult~v?HbRl!U9wA>4j2?0gagci8Gs4FN$r5lj zxzMQ73VJs~f_{MW{zI*C4Evc9I4B+9`V>Fy52w~Obkz)h4!&mEM%%Wc8_I%}{ET@{ z({#Nox^XHLYnFo@gRsC+UG#6@L<3zIH!Bi;N+uCF;W3{?Qvop(2v&6=#^n%NbiwqS zjUUfmMlWt}&M#j^7q{2_M!673YH4~MVByw7GqZ%jZ%w-&1<#vH6WgS*u*T8BgOoIE zUu7}3Aa03&C&U$QRI|EFYgN#{6-5_2Dgaoj4&cv!u%{Uu1vs+V_;aHLD|8)e{~(qR z1hy;%Pa4S9%(=Q`n;64CswzsD2WEx6bD9cMqe>rD3pILIYe_65U8mA(Fw>)yk2jx}cwsE;U!jzW@3|YaO)|vfMq1g`vx| z;DpD2L8?W*C(qW<;gADJ-Fya;fd94Dai!@4Q_-BJ1)R3eYs)vtmkR#xM`jQwK}OeF z*{S1Wr$~sTvR!!WQ;1k0n1awXv5P3TeG0N~&VJ1?UM}58{1cPP^6ZX`sEWYZ2 zjb`vaJo|vj-oM`6U%u@P``3N)agn~ z%aiY}b4Un!t*5f69v-3pPo=YR=~V-N{{Fn0ZIy1eG4^O1Fa(yZbQLH~Y;JrBDc6L& zcgFRBKu${D!#}#+?uSNY20HST$2yvVvrjEe*awjO+?P!L-6FMCRu!Q=Pwq^6^Q*5O z9$S91?XqMdMKMz@!Ooeasb6=6%1a#TEV+&47(3h@SuQGqY?sA`@?JztUPuOieq5bX zcVKOlgyVFaj&0lQbZpzUZJcyEw%xI9+qP}n&U|w?z@8pBndR=O{^12nK{SU34`fgXS0BSBv=Y*Ddgb z4_;wd!FN`@sJ~TJD2ozEUYHkq-U%%|&ic zF9=I8HGxWsjxZBgGO;6>2K+#_Nw_<48CHzv1U3tpIjB09P8?7~=fuU^^H@&ulcGEj zHH5syH1J^R4FqyL6Z<(<{M_*FBSx8nJ(gDE7fS;AO`OdKG&vG z=l9jlzz<5Xa|*30lq%#3QB8?3DfalipVK_i#9)NH+rS6|(e=N&)HZ&TOf1_>3u66T z17a;G_H0A;q}P2F{5{X)AoGTzuI#iZvVbYp;43Q!+lrZ(mB8ypK z6r8h(8y1)}<#uN_E;g>w>YOOsEwzBZrNAb29us`W7BDvHI}UA4ZHz-71Tm=_lq-MP zz`-9Zi7ZAZnxeCHKWLZ!v%UE|%?NA|IXkP>Fas=kw0HWj>1+4`s@Fz3=)cZyP3%g6 z`wy-bI;IfuUB0B&%+w#u)V>Vyvs+)Hv7bn+Y|oW9x)+Sm2`E;-HczY48*Eqc;-eQkzKq(IkwS|x1RN%dT(1& zd!TJe$y!%EdidvX7cunl_&-dMl<1a`X7zOL1)|t};m_dZqAA$D0 zu@hy=mr+;k=Gth2fj2Z&n841;>sK?DMWTdgb`4ARg$AYy?Ug~;XdYGV@1O;Y59T|9% zbO33oq=>N=S1CnF<6SuD{AV_hrEsuEG(2(;`WU)%_yf~XW$2JcpRk`-NLd=g(g zmS$NgwNo~P)5&dfygV`LwgH7DS(-!Qs`mfbzpkl+R&O`}<6GEO!Hr(0J;!%GBKLW^kd+{eaEvlPij^5P_SnZ#iwLU~0W<2ne3 zVEYp}#Vz3GoxPB^5Hp=$WZ}dW$l_X@L{?YzOT>nIW&BM|P^D0M&5t2*iNVSpjt zH?WZKkk@`>Xa8y=queaLUY_d_RH@EseJUY>)UEPO`KPTFYPg<5)_uRudl6fD=&4V= zo`aXWZ&b0>XVWs6mkdwJ!2+L=+6lEyQJ)~H*EU_fDE?FFKXbmD^Pk;}^$74tA}tuT z0BVgH<=<&)O~7io-{9$Wpqm}Sf(k!kGUF7@p%rssSG@jJH{qVNd@q{LB_2ecPG z*)ug#3m&sF*lQ!CCo7o%6Y*FukrS;{MIeLlAjeL^aMM1~jN#SU0?idu#T2L|52pcG z{gNSk?xFBD=sF^66I^SBTs}!^EEARRD~&*;?WLzQ5zq}bewH=;JrBE{xE+XYW^4m#UqctIPH?ZUAp>3L^Y8?UmSnf zq`q(d41^=?8KEQ-=LdEEP_uQu(0>X!9+)RhmqR-cLyG*^F!1y)0_;2}HGW%{!f9$* zlH5+Ui7cq9=XxJHw6t|}(M>~fIeDm=ko#ErStX#}C&2lb>@f5Q@m)5S7Q1%0K4DK$ zL_Q;uid6axruw`tKdMT1_rH&S5rIrZ*qH1y1Dqbh2;EMsH;-;Q{}h>r40_ctmUHSp zamx~>qH|E0A!}E;p>@EYnBlBb21*RZJeqy@rJU?4_2nV4qPu=^i zm>lme^law|M4wmfrye7eF656D${p0m4KVy$`7ajZSysom#QOSHz>jL-%8S2M5yQ(_ z54iAHI-k=UxAAym^Kf=|-zJ35i}+gnSKl-yT`s%Y_I;|YQ9g&PQV87dJzd-#9ZEs& z>Wp~2qHLmS=>J{;M>!GuWqK=2Ig}UZS>O9qj(b4D!kYg!QF#~uYQl;_s_T8NpBC0W zhMHk>6|*IJ^&-H_P~c5@ffG^Z=>DRo1ZX&iAhxL=5LvdS=JGOR8|{c>$#)5jz5Y}(4pHlNrlBEc&id{>S))nKhcXes^w_IO|##ssitA|OP&VgIJr5ym>s4ctcUpqIak1d zRF}}K9cExM?TxrxN_fnNNutkRtk4R+T4d^l7h1~<` zVWOugz7+CBrbtPaNxed2*(98Y0HEX5zyxULo0OS+{$n4oGK!s{L5#?Wo)PyzB)$#@ z7!(f6BRZcEL2to15Qgqekf?rfOsrAU@n7$BvKi1;b0Gz^du}oG zEV)_VBSBqe1>y&Ld=`A}{P+IOJ~`c$_yo{)hzf8iE`?|=+Bck@dJWt$T-0)_GU^x= z^x@VBkHpXYCZz9U&X6H{sIAQ|0^Y0~yp^LG+D&?}PFRMqD3!9*u6mU_7 zWZz@!#eIB$5numQgK*T{`d}&<_e}0gKV)phFwP#PiH_Ut8!m5BfNS_dL4;v zrpF-IWT_abDbNxGh#D%NmG{TCqd+xrUjW;T322DRk=@CTa16U^B_D%-cG;XkfR_Q6 zttiN6K@wY)QIIv-bTE+cT@kLQ83lQ#WQBM)v&H#YPXB}lDSo$#ecz2zU&`bT0U~nA zG(x0sAwFOpL`V*2JhX%0GCm?gE9C+{sx9yyiHBcigO*~OZ~}hs}P77 z)w-=$tcDDhghHRw$u-v0i+=|3ezy4YKHTumTo{qB6*JyiaZEArv}d*3S=FND)5)7( zbTEisB`Q<{r14n@?FXC+(+FWWUFT~3m73+rn$WSO+~P8UieV%3yny+-2&oT@&!J`F z$-c4V)0TU*>1y}$y$_H4eO_W_*<(aLbBuxw{lvpPapHC|6AA7tf}2emO5UZ<|6LH0 zRtu}^n#my-Zjl^~0?kS_tXSjpkQPgQz2nkKN*n767>C%g;H6va?@IQKzgmbM88KnQ zZ>;Fuwx~&H_6ayLi@Q$`h5HzvwpAR=PpF7_75%NRFUZKu@&)c*it7`=(U$Q(oLpyC z=UfD;JYNCaoLP+r!#w2z1{tP?80yUBlASY3=;G<`g*ixNz`v-yk((K+v%7ctd|6$6 zGD-s=H0JJTC*7Vh0sU0i8V!BQ}Q z+l+^Z`@tu5i}(8%8{QongG?l94V@aPhFWKl-BpB>Q%tCmE#iF+&%Xc9mncv^*Y>p8 zp(bjrJ}5_a`Xe&*4G=9*@EBR16F#0^;T&mT&hR(oNSZl3@DMM}T!0gAKfls!q_aaS z^i;L~6Q@Y{og#tR**(rjCdOQTcu8VcgOGms$>8jcfk$_YxA@vGbaZ}O~pYkj!{o?OcE6~rf-cMZ_Go%Lp?dPHkSuT zW3q4e65X@czxA$3RBA4zQQlb+&^(}BqVK`>xqZ4DjDRqH5@N)1j$iWqs_`ei*x6nU ztkOCnHDgxgeAkJy?jm{i5$Jt;6!jz=f}DUZTO7*PuoN)EP2a3ZKZKIbqJS?p8W)8g zS?*)bHj+@+u-deXsHuf1W{gDb2xbN*$Z#z#?+KO~KQL=QjeeCp30V(VNNW7;Bp6UJ zW^yCh=T-XZquH8}c+tRt=Ab+&e?-0)->UH(JIi33G<^cAR z_IUp2cS40hg+Vt{`29;X#=}Seet*p+I?5xy9d$}6u{uv2$`7CFzhy}pjnsltCxQg6 z{J*m$i^pjkItX+84`-r*el4wKdTzZV`4EW=hb+=X+&1QvAP%CNp+8x2hGd4r-v+vfF z8i(euA$c3p*NpuJe&ZTk{p0dyE7q1R&0b7=S?0w3BNRgiqGvFZEtdkMrpCk_rHSlu zLSFN|%+6ya1?g2luN@k2!HOlP&V;0HI+*+t{q-Ya$+kVOA-yr@p#HvIkd!j_Mp|mli%wxL^It5)cb7X6K z|H=75$%lWVCGOT{Zb{pY(wk~@&`Xa8m0Bg%qu<^#ssCcbpVL?Xo|Lq|R!`jXci%Sw zM!BKpu6_NX^V{`0-nTX#r$+c)9^-3&FVY1+TLZ2Q=0RmhME_U!wtk1#?G-1XFSPmX zH$(U@- z>4!RBFeR%HH!Mtun|q1;sF^EL8VFTSyNsS_5rmvld?VUe>b}jdo+&Stt`bySwx(%QP z(gNM-s?%s*O7N#6(yt_HvMcT8E_UqPsOx?OR_5KH!%z!JC{US!XijKlHx!V&|=6b>r6Tmn0}6_zGubSe9@kgU#LXVsLPbJl@3jaPch!|?$3q^k7 zbepuf&Pv6UEG&r%m@J~Yn%03yOxTEfCU5|7#cn(T`WPhba!HQ}Bz1uarW$peey|78N1 zMGZZ!3`GBS5KgL;=3O34UC}g4?3wzp7!`yIng_K!*;nh)Q!1Q8!?P=BDmS22h^pH# z53nC4l_XoBTjD? zfq&=#MV`X?GpeGSYtvwO3Hhh7Gh?>Mb^=E|M;OALbLii++(rC1jP34AF5Cc6s|5FU zc1PP5A?8rW;c`2uEM2Zt9kSk*u~ZyDJam*!dESO!#id@Z^FS4sy}hXzpJ$_hr$0SO z?QB9aC@t``qw-9Je2_UIlcH~4SnAm`w8*~eHSlh*ug_WacC+nc_eh1{w-Ov3R zGUL#26ZNSJxGMCO+2bQA+Fc>qh^>fo&|u`h(wA^L?*EALvzi_8*=D!_>4b~B&&$il z>TA8v#G!g2W<1J5o+JxBKJHn#{Gu0e-+-@_jDu@zsm;dA==v7 z{Jdd~L(ZGskQGF^2qYJPT4QsM!lR_~lgr1!%R|P$Da+l3aTSr^Up}80%6;~8vt|gG zl%ppK3w4sTEy&k!;la}|N3Ac2OQ6Y75=z~Y_pcE2TbOWinl+Ls8H@2QEQ@@fwn1P_ z2oZHOGW(*n19QYazOZs~ebGivI2$En?hn_eFwa(hZ5B&DFYvkm%2jsl;m6yjV%{gB zQv*4+4VGvoaSC=PdzWsiT?eL3H>*RT3WISEYpizr7AAViN$$*0(_9-W0kE+XF!7rX zffPj4RdN#|S-MW{VQa(WSXsYK^l&BM&4P5jG{y=N;uktxpG?E=Q5I9SfOxH*2RA$s z6f_89e3UwNozHUMcMn-)5*1n9a`J>{j8r7ysj-;rqh8D&}3w^s!){y}-%le4RvJ zOZ)Z2qaAis1^+{5 ziW*kJ=)qWHGMGn^Qidtextr2Hhez*q8N1x>mKI@IxX!VMK;=AD_2#~s&1`XR8K+*X z&T|5%%yt50%d(j>QvDEbbC5+>Wq*uy!y+?M@6hk!qA597HgY>in+>nnS9@$$ZK zr%65?JX#J&+diJUFCyh&m&*t-?-c%Snv>*>C!B8FFiZlE$fH8^*a+nZ@1JIxSWws? zAPB#qaq(nNHP58fd|o)nQ4_BLduI+@#Up%oCW@*%igP0yk8m$wPIYrzv zAT0uza$tVi#>9TxA>g(~#)3s<+>bGxb!ACej-Q3w|cLSbXU@+PR2bJ7krNG@3g(Q(1(i z99@!n6A8Fpc$DViYK;<(keUM~b)#|Xmqa(YK9r76m1a4e#80sIv})!CG` zwC4zOApSF;wE+Aix;^E$+B5QQAI<@X5FkyxBp}A`MQyePXz~{fN1OajC zD%<);utUM9Y(yLj31GKiFQaVUg>Iyhk4>-7KVu9p?}$7EbczIA83MYLfm9Mmsy}pZ zPC&VRuDu(7$9{>1YDqi8^Pwq+CUD74M;ABeBg_p8! zBni-fpp&!{!oqhjbng5oy6Kknh{CZpWk|KAdrhvrs5ePc&xWY6MWcrG%-_ zoc8@-5{pF;$Q>EhsY~UakPXu-j2QJ&>;Zo_qFp zmQTv)Nv5hv-#6E1{=NlRE05Ys%1iEQ!XIZBZj`XVmgP*k*&y6Gu5dPzmui+vIe$GY zLi>uHTwpp0l+^9Wl=XTAy;&gK{T?B{z#OJ=fC@s+l0t8hLRpu8vAhqy%!=Yt|Lxv! z-&g1uwWzestEbQ7Y_$y&X`9=eajxlgp;zTQ7a0cgN1)z-$cCacE`Y7LWh{qOrX&7K3FJ4z1&#MzURA zq1>zFjf`=f<8sKoRfR&6&m|v`eNQbUNZ9noE}UH|w{Z!Lb2rigfbky+7O&TBR@#UjfUi&24;=0nH;m7bFd97Wh3j(M|+ufFaq^2S`;x7z?6pyKrUh zNPYu1JZ_HIRslu}+JdW-2ssF_ ztwIoCs^2HuGW(?Tgg0~g|Cu$UczGYWezDQX$iYRLR4%ug1cYgaolOCjamoZo0W2sNbx{?K1tenmqyjz#j3^2h0zhfyn6WVbZ@azhG?4iwPdIb7<00*admD zv%y{1aU;+vWLbl=({ighG+TGT5^4kmtu*Er$M-B-M%4E)U-0y7lg};O36G0};f4gU z6ly^(KfzNR#i4QPr%mWl5CgbgMJTTpyZ|T=5F4xnSa)JT_;6OaXlCaByQ&+p{wo0C zc-YhzBtjsgh>pFowY)T-;xT~afj@5wSuGQkZs?CrhEQ^gH+y~lC#)-}=!jwf70(rN z>_^E-vmLi+RnPbwUacl_5w4SDk{w1S|0)$8PfPJ=qD1I3@44io?!&T5lK*=U35+x_E{(emsVAC_S~Sa&%g@6Fkyi0hkyf58P1@Frjmf$n**5HIND%7K5asV0;GQb`S#ZF zyHl3|=Jvibj-Ea}<_}cOvFoFV>T#@`@l-wNgAEjOUlk@{5LxRnBDPlX1k^;VG%YR5uDsC$m ziP^I4LZH57h$<+bp$1}MjXzCrVH|eFfr>0w6zX;gg&;soc|wK%w^kcSB31(w;NjR4 z*g4iQY=NzyHAYHTQ|JhkzFG_4n!tZ?R<=GQ$xhBsmXH0A!D`Yjj>M}PG2HvPlB70F zbrt6F&qe4<;aNB3=W4P*7_01mzR66S1Q(q_jQtyvsl8?MA|qRMRMoTdB)%!t`d?Gq zXNjQ%F#p0U{hi#?O~?rYu`4ebG*DSIH)?+N=`|6%ZOo>eZAt$DlUSCmNuuV3sYcTcP}IJa-`dSz_c z!7P2mQWEuqh4Bl*7Ipp&!R|q5OXDTk27ydapG$cV76))y+-#BhZP%V>zzM@~`59LN1d+NHnyY_T(2f`{@Ly;g2>_jVPg6 zQknoyd2sACOM=YDZN_AEK8qTio4Ze-b_F-ue;kROV#Z7W=-VgobQrzM4vGa*=6qRnnchn2-) zq&NoR#Yn1t^duckWBQ!Z=9ZYD{!S{AZ`BMxfaHn9i5Z;X-l6%8vRZ8Nq{gws!%mE+ zWzNx0-8yOy@Yi1uq@+rP2nERH=)nOZNi&~ zR8Zxt{G_M3%i9wa&j&+udqT>PI)A~G5szbkj(NL_+nOZpaN7~xd#OlxVmhtdy-NSy zd+gdzBG5h=h4hs6odSiN4FA0sy9NzU*Hv`Hqc(vF6xY7Car7K}{OO!yc*?ULdrMMU zVvL`2p>UE~VjLmy0kuf3;7pY^Y?cB=d#a)q%08Tu9dcWG3Y-Y>o{j4b^uG9$9#y#R zF_~JQObEnfyzblRJmJ-e*joLoOe*n3!{z{iHZ&}OephfNNH?}m{fKPin91`d6!@BW z=;|2;NVDSQ^}Uu!oXWr?{I}Ras)?tv)N}=Q2=jH#O&SXyv;Kh0{PMM!O3V;c2(0lD zW=np{)XP3A{GHJ|eFv%vf>VX6mO5kyp?FL$0_ks~q~MTt=DA`*e4yilXs&)U?_q&0 zX1*+KwX)wV?j^Q4jBfDqvL)~+ zt%I`hnB7uE7;_&LZ)i4d#sg_e*$3N&7P;~}WP6%^ywuoh2gg#~LNyENhcM|b*u#%l z@nM*x-+V{{l{=pest;q8N|D%Y7OYw_7?6nd80a=-Thx))%ihHERa7`z^U>@y1T$MV z!1*QXUphN%RnN$8p0LQA{jl|+YnAVI4-d>{m<>FIiG4%hilrT$?-A4&<~x1H^A7V} z%{2cx`oJEC@UBxvwz%JApljB%$0bVbK3S6=A+qCE$3fVg><)vI_5;f*qzcwW{IbK5 z6!M`P;cj_qX-O8orne)>4^veBr?8PZz>*y7i4lAzAQ_c(?Za5UICLuWyw%@wPj>YW zvV{;)Fk=+>KRhTB<5|QdEL5G~CkV);DhLQB2p)*1y{n6>k*U6k4WqNWnWdeJsgnbP zgQu#>f5?yo^tAH-&i_M(4)Ls=ahq@3{UBKYf~4V8GYP3C)5W{UeXh!)#(6P0R%NkH z?mL0gy?uOdBu%OH@2yQp2k0FKq_@SQK^c=UjSJj&kRF>lmvJ9J8N+nQH(PXFHyyn~ zCeIbei9Z@P3)0cgfrxU+67SyiXQ5=(?{KBZbwh z=TKfIz8R^T#ZNFEV@|l@dug{|yp9N62WxtH0;re&)0)ubQdJ%(UB3f50-P}bp!-iN$tMduzo#X77{dC74+ZiLaAXJ z&fm$q)`Uaj1kU^r&i#nhnJa!ZJ!@YtVcd)FFG$gwtQb^Zc5PeZZ&j8 z3u1V-7ffN-7A;TATdoClcE}Ve zhT*2x0|=1}SNM3=?^k`j&Yta$Yc>AA#@^JQq@RH#@r2}xyYG5a`;&nHB&T+EvQ%0}%fBjp2Ik}@R3<(wujo2annKiS9e%Ch`#?j_R85BEvs2D*;yDdi_M*pr}IDg*Y ziFrHgTzMQVQc;lgduY+)117sZg5$gs!(;`!Pz+(R{%UUIy1I;Gd7VWfJbq|f;oCOe zWty=XpKB1Y2}c9Tn9G*H$v(u{IpMdH9C+8$YP4&6yKGwM0G+=~Nd{3wfT~O)J0`L3 zBGfvReJkU`yixtoPz}>VS_j8p7SBR91nHsbJiPd5#=+#|IAE1x7M+*g-B7_nK0q$l zZ}n))W24Nv5ri}1)KBjc+$>Lqwa9Io{zxDr`N*YutR)n=W%(S~5|gxm3(o%2d6T`1 zqu2Ge8)HAE&ksDtV`K?+admWxsH$_RDkcebfil1{<`0m@nI4d_Dn{#yXXL%Xkv}W$ z!K3g!6Id;%A42s&WKnI69A?hK_496d^jul22g5I@q9uk>Yqn`AZT;k{zT z^7+!VRE!F?q0Ix7tYax=bvmH#_SSp}{;{A0gcec|G*aS+vlE3`!B>cEflaO$%=YA+RW)4 zCacE43y$V-W2-FK?mPx{x6v|zRf+L~PX2T{E!6zsKMn~jja{r_*ZwLROYSkNkDH3Q zMEuzXesm4X=NWu8SVJaNC3EDgh)7ttI_p@lEQcq*_)L*PKGGN zuamT?+>nPn;3v3Uy~kvx1{WF zK7np^sAaCjI?_QhYkIK)P;2SsHK&!eHS+(cU-wODW#~MHU+HtXhqA2S!R8BG+aYHs z$8Yw~=LC;wP~n&g(SquczA8A&Ff`OYKS8Hvw6s)ZvE6iwHCD3GZ&oIZEzo6Oy?5!> zW0RqPIVO7b24@`$_SWX!O3nlsAnalVD!T2j{|VX4Fe-BnJm|&oDy???Y3X4&zbdmsm{h+XNd7au0TXzJwG1 zvA2d!NVA5+e#tGJl}Obgddy<6w(3JujXF9|@-_IXudip&Ze)=7JuyY3d z_S(6KtS~)I)c~76+HO>`S(F)xXIW<>*>4XuJtzY_c2(+;6RhcnCy(PP+b`4I-0bpyUZJ2k$AE_G0N!s`7|bBmAv8Gm$d}`Uoe}Y}SF^B&%+bRhFjbV31x!2REZf zKdTMn?aP5uWIa%aRkjn-!dFCF>L3eHA^rc_$s`D$+EH`(AF)xgRyJ+vce5pcYm&M~ z$<`E6gfDk=H*h=LKXq2k&urQgVe?^jS;lW83*}e0G;}tk-pf#i3J`A$xkylEeyAOa z7p*jKNp7cB%5xf_XJ}3KmB$V`?7;fozyvDq5iQUxu zEykpl!!}@vbWO|#0eK@%;3um9>t&NjdXcAy^xB5Xs{>4EFZ0fE{HAH1}}U_(JvNt2@8%#A~0BoktkEa+Ns(Xz_+cT$|pWYRnNrIn;i6&oMA6$yy7{A?-RF=#15VLGdKEj7ffZS+# z*A4CVUL_{1GPjFTOie0}%8iXlgTtjdM^uPYGsQHBCv6r9V&VmG4o_<-znA@||<)RF<72Ge~-Ffp>jVlG+ z_N-7f_Ae39v(LN%BI63Q74;VC3&a$~-Ow13JPz8eFQx2!@@Y-9lNaB&(nO~sPfcb-?;IzR#Yz!w5Q??|722_~ z&rQ{dDXI(iC0-zXM2Bm`Wz>HZ8inDT(fv`g1NX{pQ{S(q4lSFw#MDNmxv?#+`BMCk z?udI58KL%D4loURt4qpJ_VuP}qhMYnB#GLDP>e#Pww>K*`hijh_CzQp;+86pbbmz4 z_FuT`s%|CVcln_NfO9Tp(3W!S+kjiiXWreA%&ieVuUvb=t2zv7ZvE(8+PrgXD}pn| z|1aWAoinF+&lI}SrT`Hi_PH^zZi1o==}gp$xLn*c<%I*BD3I%B_|7%`M*4|-U9QpJ zh9%T<>caNKctWN%sZjXqIo^9bSU1zJz!oh^SlJG^MSPJ}<7r!Vp{&nzGrUm1M|6;Y z^c^~iDP0fcfXs0%%5te6Wut_(j}m@qfF`kA9%&5QIm6W2s_jhxsUpjfMY%sM_QKT-6$`Qv&&@zX3xKY zOMrS00kg-7v1C(oQK8UoKa!U~T9e0zE?NU18W?VePs~D}Wc9<_gr4DQq8C?enCnFM zLuj&ub5kUkJ<^&)jpEa3$<)Q6bIa>#2d@o&xiI`0QUd}Bqaeol_W4B+Pb|E?x{zy8LvM|0blgj^QG1LjaJjG@$<2nD-an8 zF%xX$_}Ujz?eVQM=Au^9+|MBQp}f*-tGLhl0;*oaD%U0Eb3`*$NgPJ9EAZ?g+DheZ z$%{x$2)d@$HdfH%nAdDHK)6)CK*sJixT$!shD{ZaO; zWqbG*&{pJ4${jWxRT8(bbEK7uu8f#TL~(_~+;r{r9uUP7vw4`oA9@dz!1E3sMV-YI zCdD_=+(A?p#wWMVx+(orh1{x>+i$0-hA*%{Fe{4d#~?2c{jU(jqS`78FV5;_2g}y~ zn1KEmD%-?6Z|sDja?N$`!q@=VUYI8s?O28}_VZRE_RMXa@*klF(GZ! zd#1(@4H;_ipNj7#)BM;RjX|r$%CQE^MC$TQ*m)-Z6O({{9CHMageKFr^}fhUJnWE4 zlfk~&;v_rXTdteO9^dSb-D}uf(^7#Gf8KPbyZ{OxHb#Q!rR3gjO)(ZV4eD)!6Le%B ztG|N+&cE^ncfurld=0jQ41W9f_?V$!72t^)FbDQ*kU2CU{mCbWzz`!|Gy>PX_rz*DrAIiye;ulA%^RlS(T>n-pSTrcI}impnKlgJ8!s?l zeJH8X($rU+8HWCb`aeZxvF#xN!IuV_gmpsszp4N2O9O*=!wM#9LjIhI@L!R+T1$dk zFaeNnxuN{O^Z%5XfnV0{>l}64kF*Njx=KwVud@YVDBQBj=A7p9WRz}Rgmry|R1!uq zaj=4KaZTT!Q}7@tMAZCk&l~3n8YKSM@KErs*zCnn3e( zp9=S%q2VMuR`6@4AnT4y9c-!h^}=hFnv)IcI&`eCd=k9um+KT^d0p|o+n#h{a5CO0-2rP<4M+| zZ1h;Ot**EVK;94wuYSK4PRKf_mc0Ry`-Eh$9hggXOFOn^l$nnR1z==Asn-dZ>H}+= zOZw(nILlPx#XSdtKm#tj?0}w!AL0g_tiQJ-YyKhb$*V!fS0d%?5}J2+eLCQlA@CxL z3uHsaSNpEM5g{H}XM9p*xk1Jy=aPM2^h-{vB-&O2fi_BTEU3?YYjVjP=}8La2EL?z znhDmMZwh-?F)eZiha7Ct`f`5W&!?B#IC;n_e|;RHx^Q~M=n&QBHJRuPwMP7qvs@-o zInjx_U*|Gz#|uLD37o4kuR7t4?iwZTCy%7u?8#6bE;zU_Kj=j$`G!!j|2tuXD`ygr zmZFjZl>0kF!dEWjLh*;(2@W=FM$yWyJ4hE&apYD4#a8G&D61zh3V$|S-Tc9!q-x+9 z;Ll0s{=V-(V99bsKzOH6Y(UX^|B-5?gGycI39NSA8M5&Bswlh>IH3f-mqao2&HFjWK10^UtfRGv#n5tsE`m;`KnRZ5 zp=ZW5Iy5p$7%#_F5wV?IX{82BY#v3?h10-A{+{h`siCwChwJ)q!U!2;v#6YvLnElH z9hF+ZUJaj73A<6oKM-)(5uDg~GTFEP;p&`Ydx^S!U$>{$scqY~ZQHinU+wnPwr$(C zjZ@p!Ja)WsjJLRRU#T2mf z#1`2Yv4EgR2-B{KIJ|`WW{m*#?L^UfQdN7^r^8_4{ewAV3% zXOlRnMWHlk57V=;`pZF#M-9-bQrOX7F>PK6Z)@OOm87LL+3&kjFv{=2sO0iJVD%W? ze5Bwk9i1;an7oxZh$Y5b39B=$@RO^}nc<;^*|z&*v)0^cXI+_J!mRX;7C`A%rPW@q8KUKwvq1SQ>KR@!81%j{p%o9Rb(%Mm?V!3$!xf(Ya7xwtXiaU#t zyWOve;0i@6UY~+Xb_lXDNXN=yTnbO{DQhLWO!BVEBrzy06!Liu(_@MDj2p&q5srp5 zw1$pXa092S40;e{yaL<=>VI$`F(e#Mwv~F#^8?9+2Y-?xm}MoMxo2#>fmL4h>HwK% z6FU3J_KG^4{_Jmac+cnp{_sIwZQ|mIG!c5#95CtRkigEO)YcZumX#PXU%cdEzPi>#OrUFUI!j zej5%Pc$43tRT57Es(&ep6zm;hXuVgTR#asya-Q8Fk@pj^2+5^RkeJcF7$LJq1!t@e zb|A(JpwMte?~3%p@#LZQi7{SFw{BRguv>Cxn+P43YwT@pzp_tM0hUfYmQMT&ev@f# zk(x5;8Bq?u5&&|ckle#D{#_-bC5VcBGn4*;csw2+f%7E(f%Nf2u|&d>hHt+S=z>ds z70OeSi_vK0wZqwRwmHnm$<5-(lPS`{Cub`yV`*f|o7dJa%rRCYySQ>;WN$;si~jXX zno@qwY8UVRvMbbR41FYa4>@BriINnLF>%--fKNLV)CZh7cVtgg?QjVa2yi-;%Qip@ z>%%Z_Ehv;V*e6U>>Aaj4jb;9>{72}4q7z&iJLT!8xB+{!r(kV zOp*-$sE=ZJ-kLQ4ODTz16w z>E7WePBwMe5(Jjed)Cyeh}92VcN%sg;9j|9iAD~SPU;(5z27rxI3qJ)nZ*%7;)T{O zEB+9Kj8w?hbMCPId)#G6m^R~JsIvS>|4{TqpQ?4&YDmB0692uaFs?V8iY?A0M!lXT zTmWb`5A_FA<^741Pskz_rt!e<7Ik-0DqPIaI0HcahMkE~typRI=akG?}vm!2UK zmFYT4eTn>;E(xKEJrkb8dD5I3#(^myR)Ct%T;(_rbP9+Kgo^SE^kZaO_Ck68OwdGx z5wx9xann~0k;xFt`VNtFRI~ToRT0H@#HU63>g0&WGjt`|%lS$gZDx|C30fxs` zxBj2=k`oLK_^OeL9)*wJT3ERPtK}A9#Vl*3py(J1 z<#p409W+Uwgbu?vx7#316>bAsxrZ3A;3-torpq{#%dYl`vYOYb4^JdiQvjuXH*2CK zaP>w41cpLR`6K{Mh+-J%+#;^FMxQ$Zd0EI`A}wK%(SE4qmm!^HJir=%r+Yj^T5IY* zr4{3Hy05K2>h4}<5)E}szj>Y)T1Y!JH@1!KQH}})Ebh}tCxx8ssgzp(@x9BDT#N=gBD=(0@4SMq0$X)}>qXPMTZoo*f1s6h1yXo3=9=!kp4M8b`eSz#_) zeUIiIX;rlq(v7UiHXx{|hmxI4j&o#>R)WNK(2rTDcUh>(CNY-A+RK<6ulR8+S$~sr zjk|7*DN7r@ou!B)2UtJ^*pN%z5qCVqn(nX3@fR7e)}x)J_m`L9e_0LfuSC>f|RUJiM*h@ zLZ^}$)aty%C^VgET|$x5x&y`N%nk~lhy|Jge;j)qDv~LIZnObwWsK?@YbyyrG_K2OhWZ8i&URb5yP9T{Z zCXR0nUUXBOp2|#c38f^p3XwBlbqU_rgAriNZKN9v*pEyXn1_dInTwvWA%=Bq&qtAU}T1! z*~j4CMtsUbsZv6IULk@enmfr9$lrZen2tSNC4nLn44|2>(1uKNJ>EdIh5Fd}3}nOF zywz)u#960-gUJ%d#%&H@g_eRmvkUMAkz(bnepD;GFg)z-hWgi{Xhw4dbu}4TjOlAB z-l}q@fW5CY(8XQe!mLRT53ZY-aB4GLn+X3=&w+Fo`F!-utpk9!vEBWd0sf^t4%G=X zp8zwL4(rlfu?cF%8`&g=-=FA^j1H>j(UlmPj13S|4yjUN(uu9DD{pkx&OdDwt)%MC zZxp$-iX12EIBcM*m*kR)VLEK?Xt@0;6TSCfJ{A<>(9NW-tt+H?jvxs= z&GnhfuT5D(I-^pBKR7O~_l*)Nx^uqa>Yj$hx zFA9h=e*FUkrgm2XA0`0$+N(zJ+Jy(;%elmB6|iqqc4m=E(~UXR$#xCYEFaXp_!oW^Qe9noe8c<)ot{L zFzh!}Hpa-jk)-%;nAmgW|;Pr=XnII$eFe)RgMAiFByy; znl-BoC-=_&o;BM)x?a~oia4Wz1K0r)u2}-f**dXjOadLy|g~FxjrDy6hL#Am*F?#Elzy4{I+QL;2nV~*-3J8W1 z=T$szzH)cFyx;D6FS*G(;H?B?quy{5?Nado^HH&#XPNHz_sf-ui+a^fvI$F+nWs}~`qu|e1v*sfBkE_Q zdUrv%gSXyT(`E$uX^RmP=p*g=lE91ff(it?Ya>?sCR)(uJRW{LTU`7<2RMFuS-Cd= zxxO*f8Me<7W7@9X?Jk%S00SvS*#5xNCDWqSwd&RA^Tvvh*pXS2qdY(B#n@!HaSD z=es9rx7Wklx~{w+;-?U6r@(tO$V3c*z~zo6#EyR0r8-5d%=kCtN*Rk=T6O*(HRMG_ zY$f34oX0ejbPjd&wL&Chkja}Q2iDxex5G%hZL?8tcb}4*#ECR)zzty%pD5O0J0p6b zI>EmOdfmzEcn?b@jih8j;n=}#wSPm&P==L_8(0{mOfiH4^~y9CbQ^q(58PE8So5Ye^M$WvX_LV*aNLc-~-v>h(2CtY+*yl{4*ekE|%KsfJm}qAY6q;!;ka5 zrX|j}^Lwv8!nN`XAWAaY-wr31ui*Ag%d?P-fhqmRJZOg5q9b@Z3OjcCBV?jDQ}B18U{F1WscP(Um`j$6pigaC2vk_D`MZGVW_x#~0ZzXsSx zdXz;d!2OK%*@bEWPba>0Zpr)4mSk2g%-t zh`WA)7YDZQFc>{=dmRUdf4MWLf3frrd=3v61`hAW&pclvvtH=7%l0za29UzXpL;6d zPOQCZ`@eP`FzSsm`WDqYvJQO&L7HwIDGS|G05p|o)|g-y$~|j>PB=+iYS*(2rMDFN zz+17NO-V=DfM3jd@~Q!U7$5*rkMqiQ-HGDE*q+yHe`@N%r>Ta7J?_$;N7KLf1^Nrf*Y!2qz?Obozjd^=8hfCnK0Yumi-4)6bULXI2OWj1~ZM z=dON;)7a$W!PsB|r|F97x4Jj|QEkXf zY}NM(8$gD@pVGbpav^HyH!16Tb+Yb>s0xy7Ov^^+aWGwFugVO{$VieXLI5651fXIo z)jpdqKCY1pkZl`PdU(uglr8%ZIQ_zw3^u>Tyrx~tj)H_^bAWl$KkXPx<)#AC%X(Gw z7jqYF6qk6F2ts>D7bG*QFfGdFuTE=%Wvi?=HsD-z1GABwlzpqGUKMcY?4D#e>}ToqaeALn{NoN`mLLohn-w{SA#7MDa{2wI;9GbKPvRX*DEZuN|PP__Xxf|A#M7d!x~SX-WZA$pp51)K_PQsVko{ zC?k{7O-C<_f8=_I8%4($dO>O*cjR2R@cqigfYr^JqJv*%c0JS3hb^n0Eim+Kt=eO9 zz%h5K#IX+41~wJC7~C>oL6ONSs9_A=5Kw_glfzhQv%0|vf11K6Xz6G}csfOfNr&$J zbPGJsgai5*;tFvKTw{JoHD&vfok8S8&BPokpgcFx)7C`RoATUQe7o$Lte*BEg;0ZO zKG_%dx*>wHW-@N3Bka;lp-at~+t<1^`rc zbc~G@QHS{m+Rq86l66#JPx?134ci~88*f!(zwjp$>@B#~Zql)f-7y(`=AMZLe4}h< z0@+JcK(%ex!^n-_-(QB75YtdnLA#xO@A;_J!Igrf_8krMJTgjo+8Ge`4fM5^pE@u6 z+CnmHRW{FU^xn2&68>n)uy)n119-996SLt8WHLw9atN>E+ae;dfVmk2rjaAKHHuJm zic-^G4W3jeSwJP)V@(XLvLLzz-{#q!>PznVvJ^jPX#Kyc>xCrEdzv{!IQ(a;kHI}!y2}r@;K~nz9Is-)Lp-8gAwYLAPfjT_$<@;&aw7$+k#EOAnkY_@%~jhW@IvVw_1VIX&{#W35Isxb+oMe$Z2);G1J(}Ny6X5#v$3WS z0EvsgD{8GMc9}OD>TTD4O0WaHdxOm;LC=k3^2l_`Q56$?bj*r*msBh>NB@9X4(5Br z{VmuH!Zug4i7Uc$zj0xkHtc|(fkLIZdXnPh+3=SzwCdYQ)g>}YlKq7=;8d1CP(ofs zs>~Z(l_g3^T~O0d1CU8dh%T=ahu-qSsEKypeq_Rbgfje798|=LpEVt7nNMZkIhs8} zp3GZ4Hme9H%(UkNdlmE*oSAC9gNmZ$-Im<%i&?W%*O=+P0%!PAFAr&sZY7Nr8EE41EP5f&!(IslWosH}*1Sefoh29i1#sZe^}!+LW}7Mbvu@u- zOi_ay|C#(}*vfW`x}kE9pjQYS)DfRqLf^rak~n72A{QMK-$-<16^KQ*kT|B5VDA@% zIm5Vk-%wh!xc;|V0sR?fF1Z))IFz`>h8=Cz1e}hC?9d^ZAcH%#sWl|7S6Ab+_x<(q z%Dmx`)VHSbU%*cL+zL;DVFoceh;MqH!>@EKQzByL?wB@!?Kx}es@k*Rll28=9Fg+3vVrKu4b7sqz(Gb6Gjj!f%2~hpb7ENVM z=l4RkKRLO%R1b*=*vx|C!PZ6>C85C>Y=$4O+HkUp$W^g}tC1vZ!{{lKu+$quiN`r} zDLk9_2Y^xm(){u^@)G_ZSb9eDPl#_pw`iFUeK(* z-{yqxb&Y9aBiX9^8GaaAJc7);h$~AL2Gxc3K`}$xA9J?vaBUh~VJMuv zO};iygvKh(?ys{ud4TTs(@AMm)lSJ3IGvpZBtVxkQX#?8t`OXgUbLYO4bO>*5S$NsbUc0tk z17G<47q0F5s%8u!HP3Npv79N406qoZp}t-_G@)&A2TQdfvb(XFXVueIMFMxJ_6+|| zIUw7xDvc~Omu9(KHkSMt(H;4=#Zu|kUXi=8bw6(k;M>uL8lOzJPSMvAJltsDe~NrntIlghJ)6=TwNXogxksu9LmPcInodCTg7*}Vmb zg=(Vb<9Xk(+^>cC=j}Z_Zgf&xs-M!^3{ayOheCsmuJQa7ws2tm%@`|L2woaH{T>|$ zS;@tPa0Zd5Tw+-r6Jxhi@eR!l#T6F|mTOkOT#*J{;ZDdlc0zF@B$AByX z_q&M-FQh8vg2q=oBzZcx!#DZdD?HVEdm(NoxLWP^n2K02TWS}~azmjXYW<`YA|M#% zh8w1EM(AepZ)->^H4Ha3Ojv$+6EUwg>BW*=&^JgBQ$PJP3wv@?VC;3E_sWpUe0CZA zjJV>TClM28IWan;ZwbF74J&y&InBQs+ZV~iVuxD8Le`>mtqVIZx9jWcYp>|)h;d?6 z^GOC8O|ORmPRBxx6z$BbGCIbYn}C+=RXi}5+@RA}3tYKxzjWDO=t(yO#wKL$he>TantJnU&5y;h!b z1q*V1sy1(7*_K0I`UlWtnnNUyuG-jdXrpZgwbO^_ith#}p34DU3|^PK-T?X8JR{aG zYv>vPCF|{ED0}^j7&MO(_&4K=ZP#2cYyaO*)K*h_KYDu_<`ZjT53E(0Tuvf5_p2?- ze>S2hIfA)*pb;>{7^jhIg_I1zZssA)b|{LP*Y5X?j_7fymCkEr_=u$|s1dG*kDf`ADP&}mY${J<}Qvvw|sdh|%MPSHv*FIPTcYBAMkj&SG-!q}bo(;bI?3RpkH z2Sd>GiH4ES4X?5@1;0DRo7oi!_lOunPz4qtRK7mz?q?o1;;)G zz3*{KLA3_35xvqe&Kld6zsGoq0_Q)uroGQ(FAfz?lAhhlZjUciQ+z+UK-|9mUcfoH zSC`pzFVUH%?d19~^0JPMA2R^6L0J8|`)k2p_-JS~e@Y9e9Rj~I&9oY5-MaE7jQ z53>L34iX~KbABmyA|DVkg|4b*4MxO+RqUY2VxD~<3Z72Fjmd|gJu`5;koVQ&T$41P z50vQDEzJGdahHB&(1>P05#geAxEh3%57*N~eMp2T4(#1usWO4!NKvuGqXUa2nN1)||fLtvD%v+U=?mb9?54=LS9{}tbHa)R0@F~nomHRU{Q&8Ye zxlT`2R)v|d7$C{9MF%4};O7e*A|cDN*pn?KB@^~6%L0|!Z(Leyk(|z%-2|^fWdH6N_MN*a9hp<70PbL97COt1O=>Fev zKY_b2$!mL$MmUrxcQeu$6*=rgE^mU18&(JN&nmL$q?!V?9Ai8oXX7iW!4F{Er2>B* zTqB}`%I9qooD*e5#cP>}!$a#AG%kvpUXZ9cMggu@&tzJp|P22KlQRsCZKKOUZW#v=t zO<0Dw61pp9WL0}J^OsseRj)3$z|h*o@bIwd&36Cs%+5Sn_t$Sd>WX4wx1sAje%1-U znzzB@S<9%hO|0JLkIjwe6|sRQvfBfX#(!!$X<9K*wn!_D)nEH{h9OAW53ea?U4UTq ziwhxc7&*q-oy|LT1qX(B*0GB7z0tkg?>wZYa_$K^+*e?xt=L2m*B4hL;Fg{rMSC%Z zZd%%o=Z@kD5)E!#S7SF`*^#$4?hF#JK5s~Dk|`884c)Ed*WZ}nLIQS8Ht{GZqU9iH zE_WRWxsfK<4jJ+-h*-e2oz2OJQh=(aC`Ni3#ezUYNIjm47JJf9IKhj6#&-Xheeu- z{c=<9hIW;q;|r~#zut{?F&&Yot^7mo_A3GrLEYxefKChqwgOl7I{!u~l4VvfhGOD3 z>dD-2JH%agtt^Qcre208xl^kLvLP0zywHIAlp3Q-@`uLXfGW_7ho)h_;myEa8nAaN#E`m!9f=cbJ+^^3H=eT!b!&x>z=y z=Wq$X4$W3kS)x5=jhR&j{c@dD&Q}W;@rt-T-6(wSkgATPxk`v~R0W`Ezo(eVcTBLV zkf@TUon)MKh;`IVE^Ph8?xUkJ{4dpej{>7z%VsCcl)OIz}C!kLucNN+$Vlbiu`%?)#6##-O}6J zp5GQeXvxSObi4+uETkAcIi&dVmwbT%$8a0hzwNU zfNyg6m^4Fx&9PVQUHMvYxQQ#Pe0o}`!WM(qX`mz24Agjl&!)^aW z(BW=_?c2I7Nn&GX`NGhuzi}(&-Jh4i+kJ{*Cp)G?vwoGlu%-|PyCqxy3%lJBHj@s| z>^Y(H6fY}4xCzAAO8%=xw21M9?nK9%;_1#qgIn+UL27^>F!jCrCvZ{M9V4s~#$YJX z&`;ETv&W}O9UUNm*!>~ey||hJR{6Is!T0_?SlG+K^2WTK3@Ng%rB6*ZGOabCFLqtY z^FytyT)O`w@}UJE8w(|oB|VKUf6f+)uW%RZ@6wSf;nQEsv{YX|oTq00Y9~hqYe9Vy z^x9NO(R{B6d$y?6s9UR@{W8chTR4f%c2n2Bw&UZ*X>kBfuDfpsL^YIE;v*zCs*@A9 zhzt|9_Mk3Y?}o%&?{4OE7TXtRZsF^!8@BSTFRuA3wITGoc^{PD?0G&c#=x~Pe&X%y zRreEsB(ryQiuB@Zf3q`M$N6ovb3_zxR~VuEv|h|ov(T4C4UhPKsiIR^%Q@6eye}~) zc&sPHQUY*iKJA-EtX+TC5SDYDT-)Ozw+ZqS2(URBhgJ7c4KjXrUY>}ZM}aQXs~t10 zay0R}>VFiaYi_y8k{#`-oD$BJ9DS5?uBj#*b6`8CAclA_h!q)6Cy3o8cs$a2oeLZ>`ULDWxtCrhDIA#z7f0D}$nZ@&!Oj~s zEClHV%EM-z=E72kqcW3<=octMyoFprSAcc(>=uUokJ!C#5ui?u+o=#{J~3E_!C!k`Y82zyP-z5d$- zq}fwNjCP=ojmZ?GbR5;0m1K$%d4WM1wEztCObw84$$;x6^2dBf4c=yA}Xdi*?0gzJGndN(=ZP z)TBBg=P56Db#maW6vPkDkRob@PYN21dVU+(uV#(9+%L&kH41VEhT}Ua(9FW8pOB(A z|M~`^x0~~>rReDAhxl|C|L%$J6~A}a|F)ahP0AOM zdb}zmUfS}*+&SsfFt{k%=C7yN66ljHTkk)#pT)cv46ggjEALftTIbB98bca^H$uvZm)|;7F)<4KOzII%?@kCQ-`yIJ$OdeNDgSl3Ha~%UW9N#v}81=*1$l zFi%1~f!c3!S9+2+xWfqL7Z`;2jbYRp#xGQ2-bDS=(|8p!h?0t??EGr{cu$|Uf8p?c zdBORaDtCXsuFmt8>+9| z7Jsa5Dzb7Hv9C-KmunrA^fU_wGN+K;3Z3@#o*OPhp7-^^PxbtK>@nseW*6$cX!ogN zQ`}_wQldgKd~7SbuCiaALaeT8l+xfw&fi$3sxE#w(^y#9d~X>}{ACcvbMGY(A?3}6&tyW+3pVKVd`=V*9|2rnMS#oltcRH|zUiBY$!`8%1s$ox1p z_ODXV75X4p(AXkdU>$-EgwzM_xA+6!V~A3MR3BZU@tHz&h~_JY&G@(2E@M?`&uh=N z&L#(9T)3A5w5RoU7%AJf=#F(8$o8nx4feD`0(u$yY=QJC7hvmJEma4;Le{jvP0kN~ zBsF2~u|ewZ7B*d`ts(t9vyO{jY6--Ljk7Pei)T?PsiSc4$)IV}7FIeDSa1pbzt0}q8PyIUv!hnuhej}|#KdMWMEZyR3Rab=NxHF;@|h6W;j zy#n2?eIj0ZLx8~=+tQuoaDp%j=kT*Dt*|*`(rL@y$Donk=}>9ZGt2X~%~z&cGs)2( zY0>n1s+3X(SK%IzuapKx(NKnaQV%lLJ9{u8DU6u42*7BF8V47K>Rv;>K3eaveoBw8 z=64CMyX$_52<|^1Q*x_8>uThqcL(v9_pEh)#2HHelF>RaqH)UIkZAJUHpt)UHmB&w;Kn3 zhDkiQ7Js9LD5}|yNR9ya(?O-fnT1gq$yI|v7{I3Fkd<%+!=R5vAJ6lS=n#F^6;lmqIzO%9+;=B$j>`8(gC{IW5`zms495*&q<@ zIG(nsa-|R(+B2* z3gBCmfElxq-ystJL4<{ibQU8cGyS^8FW*-8n`S7?TgYXNQj)P67LOAlkQL+R40T>{ ze%1Ciea7yTq3d}z5=4|VO<&OiKjj$FIMAGNecHRYUXT#a~v{Fhijx?RZN?~ zMz-#v!6!lBnW0%dP2g~VEi{J<9s_?(Cl|KAaDe1}Et_{P!D#nK{X-2O+c$^#l#KE`Tn_C%!31bl zr!!R&4cZ%DZ0k;{kZO#LQ5t3_;Lt$Qk9jQhB4xWz6te>2M+gijdN{=akzsmn8o;5E z#DhlD!MuQ0=g>{Cs!SboA*0u=4|sL3+06%hnd!!dot14$2Z%qMHw$Xa^-bf5FpNIE z=_CLn-!hrw?>|4JR>xh3Ipr0oHoF!n38?*1&w-zh5a3Mso!ZqwVAszGntgJpaL8@D|DeM)uM88`1n&16{U9id!I&Y?^dBb}I zo~+F|sNgY31Vla$CB(TQLZ3%2gVsK~B^(s4_8P_B4!W-VIBZ`H0DQ^u03>K;oPCg>OPi4TZO)2CcOa@(CDo#c{KOC;qMUOW6e@3hq31 z>R);xLA-)o|7MO0ln7sr2n*8{5Hn+SshHfrB23I}X<1yjj0B-I$ZCQ6dn7Tvx#`~x z_RWiVg`0pW9sJ*#&sJ<0fWIk__6Ii52!CZ)diN*Sqzqjt+AEIDZA9gKsCLuI8n1yu zUW@FXAOyf!)`>EWlXbf;!Ua(Amz3{5W}f+q!wuRDGxeH(rB>2}u?miM#Yw}c7p>XH z7{a7(_R}L|OX=&J2CKBIt1mi7{3$EMWy7j=x~0If2Uw6kYk;{|&YN)2 z`y_Xcmp{f-W}^_`i|MO4TltE0Thg%%x6Yf{2HII`6qu$0>$>@*;Z)(;UiC2QCGTTn z@G#;*zub)`ye(^b1tR2(1%ZCvsrX&i9MtM>zVu+8tr#Ta{UZ!(B6eO&#tLOLJnfQO zo;+xsAaIN&E{fw%0K)KzUdbczTlkuCx`S(9@uBtiy7Zxc^Ume!P-o!86Xx)P9-^gReqK>gck?>p#Mh$2mKFP4g{ng4lXJV z!i$9S?;0mDvzrhS?S4=BUnCB8lc8|XF|d+D|8K?IXE*zQ6?0rYM!=x|k)@ z*=q%dWJ32Pa%ZXR#ts7n1Wxszd)sYdCfZNKK+<5XD*ubbfN2zf{Z`vuCjgvYjDRwJ zb!SAj7UGkTGuK-%QP0`U2_HvzPAX|y4EcBb{XyX8%gilde1cmyAB%3E9xW$5eAq)l zWQsb8WTc!Mtt|3DMQCe+3+tqZTw;RcMoID7IwMM@%3NyLGy1_7N}uEm@B-}Zw`4=) z#z|*|j>5W9$7?&F=y&xICr_dZB5PZtavn!iwEFMbYMRojBJ$4`I?s&76@MM+bq#<0 zy|>3985*u}DZ|nMTo8Q1O}a$MM6+CD_q@t5!oBq(hNTqQ4d@C;m>o5SwvJSlQzWfI zJ%u8!YS<(RYqE8GmVLPDgKP_Pb8>2B!ZAzF2W-)N;SqE|ZTwiKej#zl!{Io}Q}sza zl29TD6b!4QpX@R{F{okSARAe5SZd`G2P({GY$XB8w^OHC&&3Jirb19jHv#DrD# zbA1X6%`{fPerd6RM04#P!|T2;B1*6hLHg||MF&UQmZos#vXgX$Jx@g#cDdQAWhd$S zD&G1Lj%IZ>C9h!YI2F`;{HFERz(Y$RXi@`P9E5-_-3|{mEL6gWi@O8j>+7o~@LzL# z)Hi;9wX_4)fhCJy)P9f^bgv#rD@@g{2}wX@4Znl|(t(ylWI3BjV>Og#NWbE9{FM=j zJ&10wACgL$V$8~eFp7l)Wz*;@5qEJQe55y(clH?o)icUMf*Z#7#{97FOE|IP_ZCIW z;^CAp{c~S%_pdbia?7@59UB;6*QGBIT=NzHrFprTe!BL6hhHZx_~}TRnqG%{sHRr% z4Pi)t9t{5;7s_|=IN_ET$&pU2nG0i~&+d^=OeBC%mmfSYjIjK2$#s$z3Q$7BA$h`;KPj$DjPRZS zyn9xH`ZxS>R(KF1UigfbKiCY?%h#upvd(4a2uXhZmfIJE^nb18Om&!AfKZPALk#RT z-m4vZ=KPtmJ@+aMstFYXC=6_2XUW~~_-w4P=zA}>)>hcz&S-qZvCe^Ob2hh3%~Fji z3V%mg!stZ{$#c>sVs==8Bs_Be44r2OaE6!qWP!rHTi_pY%%Vm{zMPy*D9)4Az!%{^ zC%R2=t@CFF+MtdT_jJp29u`&05yWignLxhcCZ7qnDC{<> z>XwAnsuhu0YMJ>NvbirMz{7-5TLGP2iBFhJ$Fk5Cou>X3D9@mGrpWio6|Bu+ustDkqSNH!XR5>{;2utMydGc>b93d$$4y=g5eSfIm^b&-deTUA^E zQ(-cX6Feha+%%XYUi!eV`qlhLW5kVeHdT@5kq>=BHyGtQewXI&uWt- zx!ux7Ksk{q!VV+Ez@4GSSWYlU;eAtm?hf{QLP&1ck3|-Gxuc&D20=X00&B(J4cDQ2 z(#k7eBdik0jDH)KCdk4L+3dT+?YQslqcdP(t1b-MJ7d>Az;n+ir}sVV%`v69DxRdZ z-%ZHmEfwz$R-4CRibs?J00R(QYR^$}*cdUq9o!@!Bds3PyO%{AjCfCdbq2zhB(m)dO4UCAG{UZ-xr6Jm8+%qjmxTh&4OB&kq|m_v+yI zcvFGgql((TUvsov?Yc)#(BBX1Uc7W5pc5X zAXF|U&h>I&uMZ8l&s$ zZV2Ck+YtZCM~_Z`xMLVBriFVxfHa!&cUdX{l&(^B8*8JP+gD?4jAZm_#B zUZ>z&8)Cjx^rki_2VHUPq*4c8??Z!D4z`wjY}SH{aZO7cP8}i#1P#mAXQU_)pPOQ8 zF>9b;SdJ+&|L>%78Y3~8O4#76k^8S(l^K%|u{_cTlsP>O;1Ah{IoP2?=5BtvMXTh} zB7YeqqO#n50FgSZJOM6*UW{9PE6!n-n}rWfGFyPEpa~rLCTpDfw}9oI$hpZY>wqR zTbN%p+njN1RMUuyMz4o7pGiu&l<^1C5jQ%D#rN|EfG}ju)xT``nf2>mc1p4rRY`E? zY{f@x`jDFAp8-+Cqg5``hKVxKD|~g%W~R#;wWhpzMXHH=ebM|d^V_6s4^DB!LvHl` z!sbk5{Z|ur?TIQggVR zo|BW;TVoGRKP~7 zhMYX-c`s2ucD%S=l4~wbF6pqf_~OdG=}tpiOa=S<68A6ZdC>pgHTs`5rvH}XV{6GE|5KwIY%>2hnX%dV>wl6OM{NI1 zCLh`S-;rRa|8FGUsp&8HaTjn=IMd@$7kD5bOS;7RJ8A&e+@A7(;{P+nu+>s@-fTni zo2^y2IZCi3TkMqcUUhpnkZw3?B&{rl|L*^MWqFC@isacOPDT~CJ%w>u7j&~LySMwBVDsAU zJHBeW!zMFV$-=7G;TD^C32>^Tl^V!iZG9!dktwTepm$}upN}9st5yET=RN1Rf28I{ zwAmip60+abUYOW}m-kn->G<`$C|yOyb%a|Nxt@OVM~aR~@2vA;&Ryum*%D87gj(_a zPkfm5PcB&T!ijoO(D3+%Yjjm>=UlSG6DmZIlCeSLDW*OGkfa3_8vyqI@b#8Kk!{P? zD22PbySux)yF=sd?uEO1<4)r=?oMM(1C6`8yEO8#_qpeseQ(5jKPsYP)~Xp5Q7gw9 zIY!RR)SVnWeelH%i)!9HeFt8d*TBT1-wlcZ-Yx{H&ztXp$g{m~xkiN&&x2oF^|59F z(i9v|8l>04v|~Vd@aF{a%j1pH*g@SMCmRULnFby>D!JtfF8sT>kX1r*YqvaLL1pV# z;r=X#^=uNZT-Mmot=2Rv+$25J&$m}wNWjW|5bpDHaVMK*vetak&*K4Vz{NrkRIJk;Kn1sdQ z3KTJNj2z(NHx(d?WJg*Gpk`Eq`5iN1b47&#zD5urGS#C~s3CjoS+SbT!{b({cR-Mo zCSD-}`q)5m=%nfji00&=Aoc6pz^MRA19=t08kY}?>CTV0c2iITL+LVJ5iiysfo1FH02?fu&DpuH12L_BjPZWo%? z5qLxkaf!0dAk4w~$k%Omhmv$biGjBury&)O2WcJH@+JG9;|IK1TErbQp^lct$ia}r z0*nnKuTbW^Kl-WJAE!Bmk zK=jMaR=Zw9XIes{6JI9#|fc1 z{-dd*AmAS46oa@q^_gY{JXE}90m~Flf^9oVicgIlK}uz;@wb$|O)FTU^wPlvL;|mU zVMW}oAEXDZ(*PxCJz78aM6WqEOiULVvn6$wg69ThP`<^=xMQ(Q6AiHK&srAgbzU*c zi0X~s87HxAUZR8wnSX!MctapdVHmx%TP3lMut%j)(SaK}mMS>faY{WlDyEY{C_Ub2 z5zD^e9VeO<6v=FbDTVajcX}goc0|=-v^^zAy5KP9L?%Y{Ze|X&o;`YRZSj<&2dAxV zGr&WZRLX2=IyM>BhA>c8#Kt7+qd6G!oIr$}&!oP+^Im2i{PoIO!B69C*4+ncw0`OJ zUJU+bP*x51@IY}km0ElBgKWp>eUQ4hMpp%89ju4Xid;i3k|mKbm`ZwfvBJ%F&m-@Y zPP5~COLX4G`ih>ohYkAz;x4SdD4}+h>QGlCl#uwW05i-vg z!Bc}9NiHi~cF(zy1zkFwGyyN(IH@E!Zn%Y9Wxveaj0QNXY8nL{1?v{PAFGIKGz+T4 zJ6-qaK^s^Z#aTf?O0J46*;-%h=sD3@lfd+rKXUBaCVFp+IM3<8HnBk|5=H0zEQ}E= z<+PKrK|GExPv*SLSUhI6RIXib_`r##eeMd~a>@i_!s?lfDXJ`13D_nz&F)M7CY1@D zK8eRiqX$F;$%y4$H@7Yy(b-78;cEL?a<0yp?If)=rZT&uHI#i&etIJYQwFqvx6cwjAPoj}da~ zW}~_2!4Qw3hu=|vV>r2FMIuR1qXcwv7N-+$`?fvfI=@O@AnHF1>+V00 z5;?!qUq|$WMmdyUdiDJeJNSEX$0v+W6mz52?bj3(OW7}Vhi_Wa51~^Z;>RTrQ=Woz z)5!1w1jmoCCN;-tvvL#(d9RAg4bfTy$TL}gzRx&ZT+cYXL?aN<`v$%~8{|}4#TfW6 z`v6mp(kc4s9Er{Mkif3FKZ1;0Q7C+NOzR_?pv*YApceQ1F}d&NqZ&4;+^}Cf08B}96g7TgOoFrfHa-q zYNA?1&xb0&$dQf_v5IGYb1y}i19~~8fF$GaRjxJ!BHR)%eA}qhr1O;7-u{`DXbU$v z!c$;5D@@*pzIup@IWz)~F-|#eF{3#L`$*kyo8j!vM7aM(Ctu2lF)flp*MfD z+LO1?kFr?3c2Kc{B^3gDWq|vdp(B?+-`o!9dsjarc8`im)@Kz3mJ5j)=GVK2plSU> zJNP=*hAs2XQd{{X*bLO#YAaV$@!)KrB!L%P$It`$qQH;Nl`x~oLe8jXJi zP0(_1yTx$~T@m%JLrus6G|;RCf?ChdPHMS2cZxTM9|P}c!ClsxXsn1z=ket$62&u zDt>BQ#*wP3)od;PKH!RX2sI7ONKj}X1y3$JmC4U2lsL7a!2WN)kY{IJ&K29@J>Ybu z5}~muFeW;!Ty(Pp5IEHJ7wK;xMMy|^xjjzs%o+g-!xVuvX$XIMh)0Qh{Dy53od&m6 zOA&||CseYV)6#5a4Qt8LVGUlgS7(&ErD2UluIP0xz>`a;Fo2g568jQ&eYp{kNbok?spqND?eDyzxBgs%&@4F9RtizQi(IEp3jivb&Dv_y|AC_XmF4j zQNR^-NtArh_Y*OeIW`O|!oG(F+_9bx_cX_^z+xuX`9?{s9ol*m?~qr96MO&-#k0X* zFpw04>I8w5q}4=g*MbrAVtQ+Io5_NWeiXRhIwMnXYJkN|gt!*G*n`&ipo1|oS?@8{ zKrP42BY&22rjxiHT9B7D)|)k#@q7X1-}(GbFRMS#Vq|2eHt-o93A<4U?8L{%EX3(k zg%)~ar>~&|1-g=W)Rk2mO;_@wTv_1qfp3882&2(f)mJmaAIhB(xEk~C!X|5vH5EiX z=X(o4EFc5{O^)eeBB@K4)1RfQPUEARKSC=QE*)_X=zc|-eV2dHYiir`LjV%GY|5~k#bA!w0j`1k(oRMG00lwXo1Lz?TKrM_hHG*57Qr0B?d!MHyG^~W^?~~}{Kasr zPB>u2s?WLWJDlMJZ)QZxTM5(yv<~P`2|J@XDnF0jhu8c!)0gx055RvD*3{w zeNYe(7s!mlKrlR@v5D!w=WYCtFZF*DT7Pvt$82V7|3fWp-=J!kc6M@wmRi|Ge(`a} zm5v^E9M&hWHGpIb&3f7EYyXvnPXS_jC*~N={bP0!ngMM6fkm+dm6a)`zd=%8L@cb+auc0O>OUOy1G+#x$Qx7 zx(w@6F-mf7QSxWc9@kwi;}!N z3jJAae6cq0_g5N=K;Svel%#O)d=02le@}Px`O1?p$-}GKjQ0Ud+p}WEe}tUf7(MpQ zDJy)ruYV#qlu-hC1!eR}zIS3&mt-044&G-u4!c8n`DMnQhe&17dYyqR^@l7|J{V3O za*!ksaWpn@YschdFqGSjnIIvaMty#QVlE?kN!;*jB&KaAP25!pjzw~u5<~JhcGG!> zBD4lfAukCzj_w%{P1Iaenkv)`9A<|-wj_Lxd|odrl4qP7P8j-!(mD#VVENY)dIm7k zUu%PhDIk2zS;4zglE0XV8)ss3@~4=$SPyPD}-4 zeJFnVPS1jR1eX$}VRzz`zy=5lse=A26=z|eLFAcWlf!BS_M>l^bAv-vG(pq-&NSXx zfRv;0K$0cc6;?kSV9@*KI1$7I;wq&2HT23%fDTIwA;B8fQ}+~7uIqcFzBt}Q!=|A- zXRfD(Cy@fy*V2*SV>0t0*bzIb8e0bw=O*13O<=0uj}q;2!|U@#tX)S<&O*!`yMsQhK= zK78=~TN!HR2H^dz3}tA70{){HWw1blqqUZS0?fe?KffTZe%C=z{W+Yi8#}|;`>)tC zbGLJI^|ZGCcZB^Jj?Si9aty}M?`X9)^cC(68zEC_L*J#^ zp*?$y{KnF;H0>{erzp%EFkasa|E> zY()V9CzRkU`GdyGoeKty@kpB~+%H>%c_>rL6h|v2Uq`YD=X7H+xF8U{i}W8b|ryJv=jv>g-^K3^Xr4Brl(Cgk^f7$96) zp4b=#jLLujzq?2*o9FqwjffT}|KuoZLpe!Hd6KVq+d)~YY!eCvS2?xpV$cCXD1->e z3=wVM(N|bv)tFsN4G@$BWN>AsqD_)O>XAU=!&EC#3GI4));tba6MAIHVa%(HLV^?) zRQ}RPDsaG+*Jyo-3AhzTqJCf}DR7W_KxUw|!EE|L=ZL9C0*|qOj}QF^JydPM*7Zv& z$14AJ=Jd|=VoG6Dt97FBLKtDAXtIv7D-HwuMSbMbc}W2e7Ch{pgKD`ArZ?PT_Ah%c zSS|9aU5K^p7w4~Ym$X6B=oND1eHY~2|?E;O5YEy^@{iHbz zAndMoyNK+>BJ3A5V=XP|OVMtALnx&J8lBzUO)-5q|C1h{HJAikh2!wsb+BFLO zt?ky|C``Gnpgq|~ufst#XcDgs%9Iba@F*h*+=rTJt$u}OwP0Ik&dYDZMaM8hMsVIO z(8rFzObCW7kL~NwNT6@yM8n}4Gpeh(2^Y5Z)cwN zrW&Ym85kVYUoVSV&g7sK0QJn*`g5XOX_mGirX2f-gV^UdrUGQJNGRKNv4_?Wq(iHQ zwvr#rn(J}jp)u*XJuPU-!Ax&33WB)EmK;q94L`~BFGso+Q-2EqX&+h0QGTqSBfm7x zbKv2V3dnEu`0h&u&j7<=1CyAQy$)htFFLPty={sI-4P@v9!&2{jZ+In(N%jVuGw1=opzG5 zzc`>nGOqmy#pT7N6NcA#A`1MN+`fO2Rg5arHrfHC^Zhl#2cxOYm;|HJB!7Lct}0&w z@wAzCk#j=;PBFu7q(w#O%6C}roMhe)!}|E}8dXrT9SfM`Vv1Dd6GG7hYOA)3Ax~wa zbo3!LG@k>T*_Ny&(`KF-0WRy zj+8xz{#sW+f=zM{^rHSA{Wa`1XQ0BV=$fJ8wc$emYZn!>2GRWDO1-WexL1{{UjDQD z&3Uo31qeLpEXgiJdm$|FoW@+Fk+~)qFJM8ScB@tH0Wc(1pvpNqXHnf19cLnn6~`q9 z*{JF)SP_w8&hIc#La#DgBcgzWoM7iW)ym^U(h?~uAHRYoy$jk2ASr@i&;slmzm(2Y z_dG&ZiM_fdPmGl@+>-682xQ+?Jtx*S2$y#G@d8C>tv~prE>LoF%X+;9MHlgtuqM5I zVk@~o-8Wtc{HZ)3GzNz^*sY#AxS4o`s2M};5mFE9`g!q37gvd`IW8AMP3>VH2$ zTNR-IM_@32Jtp%5g-_Engx~Y;X^lHR@^B%54?^bzVSO8xV^@|p_=oZ6)Pzz(vF?cz21)TxM7W)B0A-$>zoW@jo>4^Yr9$<)dn2VRrR~m>>#Jd93nmQw=sd z+tyUp6m&}3&+Qq6&}ooNX4FnfwqW%JYMVdhX;`pWs&9>n#Vur6XnZK}uJjaKmKid& zd&4ze|1_xNKh0T6hj~1C-JO?$c7G|&J2kGW`bk*K>k)}R;L*x*nwX9KGE#giH7K$d zx3iMAzK-+Dx&*Q!ND}10Ys)(`6pR-(e5@xr5Wid<86vt9IWE!$Xc~YT zHaME_m})~aT{iqo>qo01YA!#aSo(5!DQl;UWWegCd4Syl{Zr13a>*y87CXIKbg@^k z`Ey)bR2r(e%AbN6?jdJ%$nQ#Mtb6Z?L;cKw2s`9B%$&FaNG9#S4k0kz%jh^AlFxg- zw&!cc2;3Dv`=1p#T6_}}e>;>C2bPb+b@xvlIDs=46_cwZC=Zb0{!F2UhKAb-Rr?i* z<+?<4+mlUx{tPAklDG|u4KwYlue>lQp@JFek4F=0{7Xk3lovl#1^Ij5W3gEtJo9!) z`_#LVs@wPvgAPANi zhN)o(g_fDZdX#O{P7iURLjm}Zc7eN27c<7FiJ52zD!5(&v10P?Y$RNov)w$hbm464 z-R?jS@(C|2fP_N+0vXd`zFUTcLp+Ag0=DO3A3~ReSTCd;=;d=NQHd*j^E>}p&S9du`Btm=)h)Kbl^&^+Z)2H_B@CD{1f0!oaeTnH zzd7TfsXxN6I^tUvqF59icwVrm6T_O=KNu>xZEl)5<0u06&fiCP|=v8&nT z*bUJ;3~fgN{_y!y-%^>H@f5ax0=cOl=MO{RUkGaudG(#sEaWZa5b z__F$OF|kC+5NP+Fqgm`KK74n&N~SuChLjid>m06(@KJR=C&0_BY!We>dXMm%$<+#j zq22Vkvv)hp;!Z`yXqC_T0o~hga5cu3`K9rkvV%OkGMQGp6b9Vhm8tx!&6J+4t(lj< z3q;XBOG2SRJ|QcE3K{U9^3GOMWI+GFk^w3-0L#BItn~{Tz!2&$OF5(Ov;WP1mO=3V z3Xp%N2S^_Y;cyTjAR%xW*B$`83@;J@>VGavA^}i9{5^YN9gRVj3>pN)4gK#7J!6v+ z0QdhjfuULZ)MZv0^Zl}%+dMrjNBbrWIWlGoHZka|?*j$1gTDAv8!@UF-%(G{X*`?D2LQnq2xLYHABjx$f+(2G}QZ$_GOwGdw1QMbRrg- z?Y+0EMzu~9GfOk{?gT2wDMN3fjovU*3!)c4jal4wo@5q zTbCQyYt8!*Ic$Y;@1+%oXWioWkzW4J9Y7f&Ql8SwuNk+G)-lUBzUQ@0e5FUe=S#w| zFY)W$zm{zFuk~~CzT~LUr+k@g?4e&t=Kz%(kxbI)p8Z3uO zK;j3clOI)kqu+-QhHTGVjTL%^1+yj^?>JTDc$eX~?^qA0px0SYk5#gbgf(7Y(C zz|FT|hB;#u+(CSyVXe;XF+o*yH`zA$YMY7t*#_$AV`w%EjhE(0oN7MovUf^aXe(3C z!qrW2;OY+%=y9pOss_#%CbC$Tq^n>m7!CGl#@Er*EtszNcgL5neC6-SfpRE4Kh%E$ zw+T`La7$OTh@B9a^u5B+5j0pNK$&L6Y192Ao>SR;qVc~cZPIQ@TAFS*S<%WyNac9!o(7onk@Q*1c8PhrE#xJ`E?;Ice>og z?X>w@P+hGLRxGUUJ+;vxntj-`ZyMzU zIxH9Fa|)U?T8cn|n|Vfq&o?6>MzNRAQ8>(k5sf2V>M9JKO4RzXs1IHs&?7=v0|eKj z?I|gLq=(0m{G8}XR;C~m2_uE;%FA2v1!jO{VoTo`okh6J6>yD>>^xZ{PqK|O%v$85T#^~i z*d?ukObwI3gS_^E6FjRqQzLo>4s4M2q+92-i&9yF05zWxyt_A=o$qrJyaJJjBX5_b zU3i07&!hnw|7^=%NYS&?Xpq57fgxi`f>A}*L@4#xP=*Gy8&>=n)OVc&kz5WR&C_u| zB%RcJFe;8n8p`E$CUH!=tkx~)fJyo3|F-N9Dvd;5x2P|BMr$ItQqsY_0W=wSOD-Kh zs?%rKH7SZfU1cqfnLl=0Ko_Y6}A&0H9 zX$P^EEVPg?&7r#0EyVY*{l^8JUHAdNpw9b&jg{BG>yKX(! z$pdbiobT?Zyt02VC(&mbzOqw@5U(xOxhiXAAWe|Ezp7;!ft9+qsz3U4NA-RP*7CQ6 z|54DUT)rP(X%`BNk-(fn{Xs?$BQKLVGUN`Ev>e@*@@t?*CZC2uat$c)7V+dHX_{0< zDPz&eJb~VAIro5KD&q(JmE5GLM`2D%K@XteJBeM&e0zU{K(9(u=pAITE3Xlh#v^@b z4q3_3xnjY#j<+*2`I}5>l$uW z;t12*W!Xl8uL-zrvo?MkAm-o5i;zw4*|9q8TAYUyCT$m?E;xV8u#WNMQN?o1i}FNK zOauAu{C=xc&?|mHx-c8EY_Rfy71yelxs&Ieob_AbJ#OBYn!!t(BgSX-8{RB@@LonF zUqRx%dhMNjAq;SUEnG3wh%0;vr~Fuk=}3i-c(H(N20?|>&SBiWu{}zo(L#YL#QK@C z?&psGU_2pAlcYq-8H9SeA_`72 z!xAODtc&nBmEJGq`u^*BCE;H#V|3Q5r_-C>^dqrB;uC-*MLNz>X-O(O{9T-ADJ}8r zaD_&d))uU|JR!&Npo>~62)LFdnhQVBA6#$w?%!2w(zI$0qC3yc)yEF^o0_w5UG8_9 z2xX~8TGyYHaM^<@f~n{t3lIfFG(ofuM2 zd7#A7>*g>)Q(u`Tk*Cqvcg1kA%-B46y&cKY|D~HOXxJs%l$gXpQdqujcB*ALtg_lm zKY7``8Pi;@=OTfhRd?IDDmX49{)gt$mdL2)1LS|_Y^&rXdQYDxR1B#yNHRe2GKAEi zU|>IIZ~u={*_uNSK!yLC)O_duukhJ=!3~fE`+J#-{~yb4`~Yf*znAkx{;|9!0=W7Y zGn$h52akf21@!-2gO@R-_K&OK)dBC|h<|w%#y)Kso8TZIi|`pNKf&=b@-(2}{`ztM zV^p+C>j1uk0o|c>SS_eCpVP-FVzUP<`PdmXbj~%faiP@|WWAV~apVYIH%=Njpx?^1 z3$SyE^}b4e=`0jy)y7t>g4?-RmUV&e2%*hwYpgs=A&71vgq+{mV(x)Te-@i_=(#X- zqzF2G_X(L6X#|z#9Wai}eoyunzdl0Kf2u0WOOuRVEW3bjEcU2xR#pw45Vk zqxdBX35*H}H9Nakj}X`wgp7->4Sr~D*HsJG)c*2~e)*GC0)JQn|3rvhp}bc`{bfPG z3`}#_HviuJ$J--ws_~KXyQ4yHN8>C{ME3&S?0)J;UC?;Ia&yZ3tgkH{bPP9VWM#yI zorTBHibCCT3*zZmCG*YOpDYbDadHKnvr=+v8@(^X^!#*w-M!xQXd-icjt=Ho+XJsb!yNxbkT}87rDxle) z0P_(-OH?@FQu_oRpK?ycib{l4Qq{{;ktHHyRB1yhgVn}}$J+rCF6Z9%B0+}~wNxdl z&^mUw77{?xa@%5P4pr|wDc2&7j>%GVmTzvH_nX8%rbx>e41(*Ef>N8k>xFnFP8RYN zRJ;8~&AJSOUb9_pz6gfgU_4h;kBbl}S1kN_cj?9!;_=<#r^dX%dUoImRjX5}3%?|X zy;#ToTHzed7$`w1EIWEQHe*bmVU&8`ENLLeq%<%|w4lZVj0TF}wNjl^Z|}=t>)_er zZE$|B!FQFFZ^xd0dc}}%i2E5)CIbaeWedV(9VuM+(juL0s;6si%7${D2KCO*R85V~ zp`DU@&$QsVc-mIhR`gBcEANl7nYyQxOv0SJOT!& z<&J=fLu1dw`}4!|SE+Gq8RpR={c|=y1Hc(k#x_hzz zd*}Xz7A(SJc9@@e(-T(4HpM5DO=?0x{r}veHQK8#tK6vmi&_N@NF|)X;<82JHk>K4 zoQlJIW9qaX7A@l*--U~4Oon1$!5Ms2H<*@3{C@O2kF<#V#&rK)BU1#G4bp)$-5Nsq zAvur}V<$*f8vSiG$}A6cGeK5E_R631w>gjzgN7~0Ws6EQ$V_JDm>mw4w^>o>=Pdiw z1$ulVwNQs@au{t!oOrJ~Da{4>PsIMs?w?7i?PnUUq-p_-Z}d|IdD^Txfm3p0siTdC z<*UbT1EClY-fzcGqiai5d{yf439npIR3GF_k=I!UA?Om=A>{evu~OzO#6*E`WhOvv z?6kIz)vCu4$JeR+jpA^2lhX9ziDe_Bo}3!Zs@s4^bK ze6uSA{?RV5DsVYMtAKm7Sf?0|y9bMHjM7LXJ;cV_{PTEb>=*_%M?>uGkIP31P?84C zw53W&`tl509~SYsATTy#8NWdUo)lb@ZHNXVZKJ2@f3R`T zL*seZvoY#SnS&I|;HalyB<;s28aAGtJ~yEsf=Ga^DDdMO zfkaL`!|SehyjbqcG|bbI`L9TOfYyprsd1be&qixysH||^2cnK7H{EE3nLhC7C(V&H zJUm-wwRT&e`1$Oia;PeObC;y|qRaZ~4|nlS2gx4y5XuA;fA$Ui-gct(y8wO4RGhrX zbR7VyDsBvWnAs({`4}pzu4tefetx>PsZuE<+>dwyZ9-2fPNYDkXLfi2Ol`mtA*sKf zP3Xc`dM{JSW<9aBrj6EI*zzl{SP$*H@oq05A+q1 zrG>e5%B{g7L6{{sc6T8C_(;0g2qKZnBqF-V`ZP{_|4KXSiVCpOPpF)Zojy=Q2R+Mf zb3K3|1{_o~n4kD}zE($Ov!lfxlUU8J&1wn}))F+Bu5fHAzO=$1i!I7iuz9qk7wLFI zB;eOrzvxa}qi}k<`U(5w5rt@~PKnL6#d?D^Y&65}sVIG(bQo}(8hUx!mDG1f+i#~m zi7Q^z(#Ct1W`y>=Onobl5560j8SsOVK#9QYCTUl7%3NfN6?%m1ouJ~1Q|Un1PV{?m zC);fx`V)kKc+u(yNrL6fxz_m%4iC0%E?6zs3YjuvN{+GFouX7mte=r8vrAEZnsm$M zV0!S>clU3gLFd3Q^HsIosMn5fol=M>*A(?b5gl-xaMDGD{ra{Y#&2@BTS)6`qC|hb zGS`~Doc6S0_GTOuX;Yr9VBxzr*#H@DU93;O)t08i6FdaZDf53ZPs5>uz6*{D?8cnd zJ*QRh)9+fO4;*8bL_2UYcgUpAm+9k5g2(gsc-Cw{*K7ys=RB&YANdGyabd}a7zD_( z3%t0O#|wl=G4;e!avAL6|M_gdn0|PG<;EdaWf|T+^IMC+pAGkQ zr+?T>LdN6)Ty8sp8|`BNntc~V z!RNTrnLdF&iWjOP0(;F$?u@t-JIhPiJG)6YtW1LhQU2yH#3t z`Uk%NS-wWuIb6tDoXyDSQp(b!S+#sbZLyVMvv^?Gh!>ftB&I2|2m&gggRJsYc&u?_ zZ6&;aPwo35r`}?k79!}>X614wFn#S);Od>o{88sEM!G~G2Y{&fwI*uk)gj5>xS}=d zVZYF-W{@PUe#!?G=5BN$_@0?2ov_t8ftfD?1f>b@)~zF}Hs_rDHdXAcsi$XM&|1kt z4x!HGZqWjxMWj4?wb5d~xgFan43tc&A+^uS?6yfOR;<%}swLE&D~OsW@Ag{&&X&C;_ft;#a?Vwh0ru6c73 zLcdp98`nv)_Nr3IR?%1Fy%uV6154odS|F36ISgOFPKd`l(tjz&U&1b)+duLYZ8t#7 zzhvM84*>UnI5UMOfB^Y#y_c~|>HhSSGiyU;I3q&hW!Odl5dL!+FaiMauM8?8`X3^4 zZ#3ZOUz=9O0shlwp!FyYpbhr-rrRdHkEWlSo`7c*N`11N={NvHhC>nn_P;wP0sQ~9 z#Yf6Nwh%}K^n)YBV?K&UR0dmceEM`483lo0_&`$=*MHZi$U{x3{q_1kN17%z>>Y8X zklzD(O|octrMGJ#@nG$3h7s-U3(+y`T3N@emsdkLd^;EYx9ysrFLS#?KxF1=-{w+; z`_66~8mADyYVwfF98}NJ%LE>V{l?7MQ!k}QSz}cQg$e$wQfVX}<)m^bxp{r}r*b8>7|U3Bc1m(~8NK52<6F-k zDmUFwv2RVvKp1n|!%Bw4q@j+x>m^G<#L$*|)Xp>pfE7JnX}f zu`wklkrsVx@bikfJp|(ntQQ^1>rr=~#Qwgi{y6-67qDJ`Ow4TzMI>BS%L6C+~u32B{ zhu0{7D9a}EH&#x`B)t}L>c^0SkyNlIBV%NsST{A~d5jY05&QDR#h#l}OI?o;cWSUz za<-D<9#C$YlZjZP6g|3RWXNJN#!O4}NS^QE@hs}gNvAIfxt}_M5iHJ@pO1lK5cd>^`wn10y zOFI#~GVH$9m5E-nI?)fmKtjS`f9b0%m2lItXy7oO=76JY-C<#n3alDcJry;Np79Y2 z-jV4+C3MTyN)#3MvBooB+&c-Wf!)>zH>u-kdwK&r>SUy}wtzBTcvLk6cGkJky;3bE zQb2VBHC1|TCC5y_&ccLHbuFdAfSS0MQPbQw210(!TUIgyY=c=_$-#;}!!joB=+aAH z6L3UBlkNo95_`rij8D5^|K6e8kBaJlR44n@zvkGD=_D8Hxk#$B|v z@mAtH*=9hS4*?->ACOaLqF5%CQ*kLA?t5<-F{c_Yksucd|K?YFNZ>z;FF)}^JTyGs zkm%C^!a)E5A^LR4y&c`%GODCNQ8G@l0Z9Lj;Ee0vV0f)~IRL_cX({}L|FDw+3IX(x ze@iSi<^KSqlXAc-JoI1D4b4J7pK;Ojsk8h~G-uE@1BiiWA-SRYJad?pF|`qGH>4z6 z)p4Gj%O<|X>l`#|_r06d=j4i@_PTP^&K?I}Gb{};Yt3YfA`dCGkR`-R)GFY|*ihsk zRY>8fvyLQ-d6k(zIE!#Q`d`l*({+mb8M3e@*wdErZ8Dv`Uxul1@hWIxn7Bx1Twz*8 zuA({bRH)-hfW3Z~;~Hv{nV#I^DT zlgWy5qFB`Y`IlB*6QCNG&wkkwj&LOMF@ZHcQe#V}as$bhE?YetKUN+)C;6s$_fiWo z%CR!ApuPS$UONy`X+^OShd~TUIn~AMgN4JZzS;uIk%gM9lZF2TWm%4{uwiFN>dMWf zhGC{Xbi5Kn`%XV11$yv82|z!F1V-eF9eI5HqJ@$f9vQV%u=Bh3CQ_%~kw+PfmVGNG z%=x!zvH~mX*i%k;mSN1T|Mb33I(q@36o+WmC6pO=0JfbJxJdIK zqkLPc03MVqladoYn2})IQ2&)fmdoG7{Cm^D!dyWlFrlL>MDu{n%`1|8%4AY8%@2e3 z*H=Iw#+bhXGcDMLD5psixoz(*(Nh4`tBy;ZM2Cr~uZ?q$`MFB4J7t3wo>MPgsB`Ng z(Y+47)0XoZ062GEpR{So{{9{EEMogzr1kJa97A6*P~QmUHko!wiD!LeXdvJ31IHKpnb4Q_1 zlLxybcH*LLkV;!{OrNKW&sg&P>X)mCq6&*`&ABUm674X;Sr8w;j`&jJMCPDq->* zo8~8qAkj^*xGLaq@p{m7@ZJ=uM!Xx#KBx0zsE^US#iqq=7|%WAW@-JZ=2(M@uYLRc z{g-6&L0XKJM}jXW#L9Y;rd%JB8GP9s)q^w%m9~4y(j}(tBqSy3%;MQPFAXzLq^{ob z(pH4g2Ad3e@C|hC7 zp#E;3TNo6f_orS7mn6&!+9D79x`j9PO&E#}L%%{R)52CxxvITyRl7lpCL^Uef_*lcVCj&GZPHh- zs67d6+ltE=k`7DSGPK=k#m(ub2)vEz65^>!X;G1tDxu}GtS5YwY%aDlpI_#EYHs+V z)Q3qKbJW7sMq-)&9L-c8E$Tda;Ukycla>*R%dx;s0|5Ik z);Bfw51kcu91#4k<%G$9kin5jKqugD%GQI?pvn8Ggd1gCQ-R}WR80Zk{{!!W$>6xa zesehL)?_;>j~$%JhC;Y{5Cctm>&Jc>aM>dIvSjMS)ZBtm;AT>)`I!4}SP}8{_1mlX zF07AOle~Ht9;s&8x34L%h6T*>wiCa8n6)8WpLNcmTLWyYnw5z$^?MZeIYGPJ&Wa`C zmvxK|j7)2Uw?+=g+lNAe`tLXaFOOinVxX3?8aIA|_#KD0_dfo3@V|DGEA`HIorY1z zDZUBzn2tHd{MlY#?MK$j%8oh3GkUV=xeKvP+T~%5?SnE4vN%CCFOe^qk^@cx)eo@f zG4*fMWu6$(deYy268&*cLzakGT4lu=Q)f${+%4YSExtyQTU$>HEmETJPEhF_KV)@TYB%A$tmq2c_C@j2yGOxjxsZaSJpcrPzseb^#t6E zu2OBAqV0#FEq%_{eh>J3fV7%( zQ!^6eS|*#S?`#`Uu6il}uEgaNlH(C8xDNPJ^$Rf|xM}~kU*Ev3!KHiCHELw&v2CW8 zpwL>d+F12LQrzhrK9Z^rW**%Q_~Ux*t7`KHJsAy0aB#hwiL5!J1K99qz~6z3ouhLG zLatIjM7<9_L3$zr!Z`Ag0GRh}F^& z+TU+?fB4*_^CyR-0ZkQYsr%{~-;Ob!9Q3$af@GeIQ8}p&I3+F>&tYJD6UV!YJ=M}X zZ|lypjT+y)jHk0&TQAc~1hG1O+y^{*4D)2N_p8L}Ztus9>=)PjAB6sQe)~525A@-f z1MvULwR2nj2RJsb0?Z-)M!{F5ZpWri@9-yC8sM{>De?;x>OZW*j4#^&0$?8{$VN$9 zQd%{=rN;M^RQf}SbQLfo>0h{7#vrQE6~N7leuUukx^XvvUkFa{Rh{KhQz;&mBJL)D9VB=Os!Jw%WY0~+!u z>6@Fc*FnR27tAvd)+I2H;y^(41GK)dP*D^`a@&_)CDWh$51bKW#I76B zKm=1d=n#B(bzSEJQjrYGE9KLBpLnS-VywccwFo#&5R%IiRRPMHmeka0p#UGx`yVe} zZ}B-v+A8SxuZFASGUUH9$|~}hJUiE^#P~dOl&mP!NViKJ+9yQUuYq3V5A-{r^7Ie! z#WCdW-qa7zK1bd^WxTK>-)QgoyFunbenqorWd_iPR@||6Wltb+1>QE7)CGP`GnWBJXT_H?SyX54_1d6Z&mt`hswz+F ziC@q+qRvKZQD-A*s<-7&5o^(t&VMW(6Q0~ zoV)8h=RR-MsrSSBGWXoG)~=dkjJ5W>uHP^-nc0va2o3h3Pv?Un)|j)Dtsx)Q02^r; z;mw+{d>M3CaP#3bc`*Sg{VMqiI!NUB;$@-cRk;I|H$1n0RH=@kMR(B-ewM+j~dJ_K_J z8YxOh?q@O*69t|#7R*tP!>faQd^o|>g2ijNQ=m-tmhtX;9`}rtBR)%0#hD%4H^kNs z+G12em7FHQwZ6))eNKaT;SDu^Nof4l(cjibna-QgAuZUeHIsK*&mPIx8pBLgvq5o#UP8mns?!?+uPxtCylrDXkCNW_|N& zCaf@Q22azT8;4{K$d+qc^8%uHWK26kz0fTF>3Ze$VQ+Rd%dR!~y(vUOHhg^M*lXrw zw0g)3kq&+P(CGC@TLms562bqnb$TPg+o`#5H0WS&tn*|?Ei zU|vl6>tz-0hZ=)}1!q~>Mv}aatiwKir*EW)k(B*aeNjRl(%D5wtcL0cAwA|-7Wa+N z{k7ZYublYt8fCZF6|cbbQ-)^63IPjOKN&@=m%-+Og|(sr!5l<=OJ;)D&0lxV_nfi$ z@vaOpXd%L(JC1MSeQy-1IODZy-#lZ6l{}M>{rmK>VI}k9a^EnKnJL>LF^8qOY^kS( z>l|*17(|K+o4+fNzF{w&IV;DN%>2S+uDD=0|j-eiYWsI2hKq?e_4HW$^{-j z-d4P2_HODcNI7iMvxk0fi4{%)N21S}74oHDb>sgXCTWbAr?6HR@5ZD58z`&b#;pVY zVkU@d6+Ty4#-^2}fNR@6dg|M9l04>FOfX(OO&P$I%W=iJyZFm#fvRXol<%i70TX2% zd$#p^$G(5a64x#;ZYD|oWSojo7X=QtTsWVqn){jzUt8^&Y#!I)b_te=h>o7kccahd zyRW2hm;|y)xSRwXp;CNj?J{Z7KKNIAKnI)F@(-xTR_OGv&r#sUqHpG8dZyzfPg!Wm zm3luxjAiS`?x$Y2>xWcmy*VKUZN3MrGG2*g`An{ag&jix`Ie!zO#F9edz%VhckG^E zf7C!)F7pSa0ogL;ulhRsv|+W;QcM`PdWf=jmzgXFhU|Q!gqUWCbtcEmIB}&IjVG7+ znNwAgGWx#bngO~=f7Hhfu&bnQC=k0GLR%#YY#@|Z(`K}uCa2wtz4o|45yvRI388ky zPXP4{{=BvVkP#AO~AuUeHdGTg^s*Ci-!dcsGkO|!X59P27<38 zAa7}aW&??i63Nw%Ci{h{nnebIJbT?D+;TY&4ni;AW~<;0h-p`Q)%Fv|tVbnGavPGx z{YjY>f=03q3%`t4-%BBOCyIAF(>4&stYZApwNW?q-${BIl1rycg6pjqex|Y7ORCL4 zCr5uEoB7`TMH9}zPqYEy{u}s8;RnZ*F5Gyq&WWkT`hpH^11_zC-nu@1#jp(gK8+0? zQsF~jvu*;jU?vSa*|4N?oO`7S?OL^9S5<#6kf=ZHIcInQ>l;@7QTxKJTEr_`>%sf5CPim^+uqMijMR2Q!)x zKC6^yPrH!R5kNCze$!LF_0=UWVhnT~T}?s`w*uD6hYP*Q-sp56zVX> zy$?h25c1lqB*=T>MsQ~406z_Si@<@klfdW%;q6o*n}rC)V08EwqdQzF;k&jAW8MN_ zN6*pkRq592hoKEEo%;C*4l&MWw{JI|=cS;CsN5I%AqUl8hA5-=@^`$*UHERb=}sIL zlO0E9U=kdnfP8IdM1pfRfjPtYjYeoYn4&!{YZBP|VdUCifgK9vCkcU-;5D+1w|`%Z#@os59z;p50)5mtQI zo1t$uh^q5~V{BM56#KgB@biH|sLV5yt|^JV4sJ@x4$ zm|F(uVP28;S@`+EW*w9vFr&!~jf5A!NY7u!cFb*-Eaafg#7n0#Hc)WArS~>cQ_zbz zUn<@qkx1B~$oj0#?P8!hV8n3bZxAL;BVmUNU@``V z=c;H|?-qCVLVj{Uj2Rv$lC^XKzq6ON@8i}^EZ}#MD1d%%nr<+|)M_N&W|Lpgtr*e= zGtLpE5&8*|cQiX&9ysBSkmBySRcamWVRngsPW01wXgSoGc@SLp)#?e0k!4rx_Z#Us z@g~A6t95!oY4cm!XgWqLHd7GRsj7QYwDMU~QMcX&F29BrL;VzWflSppkiTz7^Y;rz zFt0HR-w0`Y%5uIkcw42}yh^#dlv}w<%Zgxz@H_dYn1uV!<+R^+MDSxLbW)WooDb%= zE6&B4vg*(u_aMUFyq{R9`EiEdcmflLJjo8<&!IWdu7Azvkcl_APIu%kis*|edKtLK zjEC*6;}SRV0P6M~8UpV(fx9pJLM9vw56_aeYr_#ZU&RmyhSNpET=1njw8C$FPN)uo z|Ip!C>_MMcMBlFK!OyO7>k?A^G}K{*&_LUvvl^|VptFGLN~aors(TTNkes%@chDvg z_&s#)NjPu!<$-Rxj_#T_z$F%h{?8()Dj$0-Z;`3dP`&>}4Ok03zs5v^k(;%W#;mz| zOlLXA7W%^P%({4vp2LyY>Q(}c8{{$5KZUJAo)w8+;KDbCU$*e@B}L|Dw*|z0k8J&0 zEBIdm8$5jXm@NVj5H#z5zoZeueH6Zlw!1rR(#I$ z3)NXKCS}(-`(~(A?LKkwVu^JjnWXALP2c_BE*(8U6F{WL9QYoO1g6LfrOr+2w>v=? zj-tD$SILv!R=3iWdMpyNOH60p(98711Ro+rGNB8;b zUbrBn)4}^GGhQ0G1NTcy>WMSj$Z9206!T*543K%;pG*zb?9@Zj7*$YYvR8lgVqwS8 zXi}yZLi$2cmp2it=}(|SNJrugbui75HJflTKMb7UVXJYwj@9V?dIKseeQ z%nQZBs}!pHOMYXQZ>pxY2||i8rOY)PQZ0xF=G6Ta?LKQ9=G*;q*8J>}6CJ+~9w9*w z@0+LhG@_Q^bL2>g(8k(Y)V!38dy@Vk2hI;~{tYU*;69K%%-eEwuO;LOXjUcL<}Xfc zq7CIc-?N=LQe@lW#!-M-QFyua5q`cvUe==fLOl9e@>&_d4-}Z0Z%Ax&srYmHAdn30 zd(5)mpw4|M&7i_Z_nKs^3=o5h)bPOaPyQBYp}xtm)wrj( zN|dFc{1rukD{iLhLt;a?0N#|6G-IrO%b&#w$4bo&_7EiLLMB39Y7h+qI7+2QfWlbg zm%pW$_Wb<+V$=_UI?2xhD2PIHWvBs*tp&~=<=M4OSi<9&!ZF)~PZ>!pI`@^sq)@GC z&`U$I*Ok$V1Vt6-n+R_K_+4~@ok0$kJX`z=^u8&a9wUId$3+u%06Sjzs||m&18Jfp zS}{G7Fs&Yq_^a5KIgE_~={^$qe4lVdy6N zk|u~$!g5FQxI%+q2>6M&C;B;bXfx-OVRhWp{3LOH1@ao;ie7+>6~(W;SvlpmEcIJz zykHuNQ6k6|3@j6oj*4F@13u0?L_lW4bDVEM-08&XoIW>pj(mn{F3j-1C9fNrvn^hf z$jN#$QW{aRoLO>GABCa5bMD|s$-s@7C<(=VnaUm|;TfR5)x<#~r4ro(r+qMb%zAY? z$R25w8?@pC(i>94;nu@EDM!fcK<>Er^_`H2Qd-&JrHk=f(I>to9Hw6OWS4!hLHH6* zWI)$U0KY6JPpT>;IA2nIPKG|@2AS)K(3Hgf?pe+F2iddFJXeFf!Ihbi`LG2W!>gRi zrjjFKT-w+lf9r}g(}fcS`7j_afV>hl5e?P6e`odsc+I8kFu}1>$jBMmzte>#l1;^5 zN@STpgk4Haeu|S{e!%+$bu0`dC~?*|(FC7)zUN5dc>?z&i}BfJ^O53DX`XNB0pS4` z<8Yv(gX7PGF9${x#hP*wqu(6z_yg@b!%mB;ge=Vn$f#{-&Z4enmgq#=_Dmm4xvDCck)2F)zGjY|eu?r0 zm4scLcKV8BrWi5inlH8rMK&(X#>zIp`*8*j4gC7-_8e+v5e?Qc^8U&Y>Im ziH{lW;|-fCE!N|fi8}8qqYuBfrFPg^VL_@re0vis+lx%#hN6&u0zJkmp*yg$RF#0&WDb%6VCUo?EZ?mz9$uYfcwuI7w*A(GrJ?*2I!Yey1ow6= zw38bC1%d!J6vL`eEGrYdw7er{H8yO)OAETlVQnF&0F0RLlxD%DnO{ase^+1!;1FEF zZNz_lWlhN3RIY!^lw55B5Ue;JJ?o!|sdG2w-q@|t$~ggG+|<(oy!H+6HfcU& zPpmPwwDZ4T+z7nwJ@SST z4_jg9HAV#|Zc&I9Md)g{3H+^cJ{L?)rimcw*%f5doO$I8pxk2eqF$zx0wMca0v*VM zPnudjD$GC$Gm8!z8t_adZvg)=8;yt>39R6WS4c!v_MU4(S}^(fMc&nAIf|}1%Q3ec zf8+E9#0yo6O{Kb0_j}LFL`-xa)VYi5!yA`Dz&@^CCCD2~(FV9V1aJ~cz9__!rdZlU z{bcDafWm(gTtjn>CyR48{F6-CPFVtJ2l*XDg3y)|!5ShKvW z4pT5Hb8Jv(-u90_BfzoMczRmn>I8A8XoMtHpG%A#P4l(l(OQvCg*bU14GtLRpRBYg zDAWVPL!-9!`MOF|sl16q@Q}J3SVHOWe^^h+h#^LfZAjv-_*^n(leW6!;Mk{*dMo;9(TYACB8-Sdsy##m2xZwpL@AZG<5Gqaltq`0O!^U-4ZbDTa7_ z*ApkrMGl-4FJ47gX?!A!u2kF=M5ji8U$89z-;H$?o0IPi=5)=9C41e{#sk#r*>*0wp~vp&QQE{8#<+NQi>A-Sp-iv;a5ikCgIwSF^35pJUthvFKLbHuzw|hy_Bnm91xt>(reK< z881BiiJxvXpEds$zKaz&5a@P>&9O*lqo?2x0wf0(6=<;EEvncO|JD#aka~Y zuMA{!h0$o-W>`t326drCd^r}OTW`RO_;A{Vx;$MXOL)v!p|}V9Fox6WHGJeWSrn?g zI%4s{TVn%Tt0~kjj!d5f|SA__|jO-6N|x1q2b^3kN)<{eui zD=MCiJdS_e7F;lfu+s!@8-zRNT=sc|i>1&0_FOdYU;ed{q_at%;jBi5BMg4ioo)l{ zeZq(IBs=m#V31U{Qk(!W%{42bc1yfwRQ*k?Hs@UM#hAl}ug zeKjCACFyE01(BQn3VPzDEHg>`7WsJia0>h3?AYeaSxZ|x+&R^IbuP~NX5>?D8k9k;uWlVBQkB|qR_+e8!UZ`9 zxD0Q}QeUZmhF%iYJzQfF_Pt&)9cLjB)?>@pIHn99YZTZcdL;N}pXMB1hCt9{>gxEx z1b6)>@_4ine(}5jp3hn-e75chom*5`>_Nb%p>;mTRq|Q@UMwY5u=|t$P>ZgWZ(elo z%?cK1b(4SYRRL^_ zR1jM@0be)-pB=Olj|`6z$i0aywch1zs_VwRK75h1sxEY}YHEi23chLp1H-?#;<`br zKwKG}q8AZeYF;GJ&P#FnhB-sIps~c5>({6!6A*@{a{9++p!;DN)SW5mT0$vN^E@%BnmAf-*oovGY9xlB#naBX>Y?I=H(VO$61rqx@DMUjy)mD zz2KVsY8_I)^Gbkyj9jn_gQ5*4pu@vb>eCun08cqkH64{5{SKYa#HX zb3H5=%q;Ree7=30ivRwLGlcwWX?N6*r~U4ztIfi=JArw+j@`7m7F=N&Ynl)onxIH&E4lBM8AvDx+N4HgJ8f|6Xm&5DK8X3Bi;mVDO5sa(;bN;ac* zhKn$J52`m#H_%5+Tuv>`_ecJ?1lW#t$`pCG8dxH3aWS7?rsB~1QAlF%@2UBmqxlNd z=x?Wecz)o3#@QpQ?O;p3nP1OH4I$ma#Q@Z!mOq*#K^Ji!yxQ<%oRJ83TP?EUL+Y z`VCgDgI9U7D~S5TJ!DPgHlc3Yp2@M3zA^HGcPT6%PLX_zB4P2`bS;rfj0+lS#&6G| zIx#`8l*fk9>RHR9Txx@wooxYgh*u-C{_MHJI;ihueD|BgNzV6%;fF#cN06E!(Rh9F zueM;vS@^)o3Zc|aoqP$*)$%Per70LyKAp>fHET}2vRO64^R|uJ+U;w=J9R|hk%^6o z>w|m_9~+uRQWwlXZA#T6+WnDVtfDH-{b@{209}yt0^Er1!k&GcL$0tknl!JGH-vHz zZJV)z8j)QY7L=1hDuej>?d~fZzi^1zLWZ{i?JzL8iJz=B#_}$Ktyiqvc4)DZ1j#T{ zI1I8|&&5N>amG;*6CVAff5;~2%rNS@Xz$$PP0by+({Y0(-v%6U` zk3F)LdS?mVQQlax@8I@`RQfU0WnKVC~J1bACVX`rC{7 z?q{G_Ma?lb16wE8tbSWynK37a{y5PB-<$11EmO`EG0ycp4#WXdq53Pz9MPPJ-1=$@ z=X`AGDN35iL+P}4TXc~nm-;Us&3eC1;W_D)=~dCz+SS8-{W04^b%F98bAvBDv`%CA z_L{~@@4O@wYc|79oxYz9*wo{a*+-*)Jrn~oACRq_OL!tB{Oi_ZUKM!5f&bI*t#xVZie__Jb%e|o|fF0G-Zp8qq)ecxoCd6SblWL_5|^}8hQ1D zQlPFw1!2ZHJUB_LS!jC-`Rt77e$|BcTNLt3j*j%@GP;d`r;*h+tfg5r*K_WvTU%FP zTF!@E81F+(KYWg<0G}Z6538^1)6MdJQ~+!dlq8JxTKz~z1PFE za?RF0h9C49s73PwjOJTLbL%Bna;QyS<-AF`N8Ne#p8-m$5!bwgL6e&V_W2@%CD$M{ zICR~5ZIjwIw(d1bHY@(_ANP?Z&0C1TnrO(G5->BCBB)XR=71DUeObEdi}>^7Utg1U z&@JDLjR=Y-;VLTiH7~uzD0X!w@(2Z$RoYxv`6l<^5q#zdmU^gSi7<#33a79Bc(eu9 zW>H)6xME4w%S%M^rQ0Y-=5#H7Q@bR8x6HY6^+@UK;S3(GDK^c?k#Zb)n%TzW0y6lb$CtDOj{n^6S_x#6>$$}5HE zkx2p#BTNbyDTo9*;-V`2a?uqT3)Sy=ZR{Nl$c#$VBf6a#PG=hLpe)>~7~Hd1lcfUq zfg<9Nc!e86{rvv9$=B1&FU zRUr%AKc&&zb!@Bs$hDc!Khz89)i|slsX{6*dSrqs_tv4kk5xnY3E}FG$t51{WP=A~ z#!Snd+(g&Dpwj49XQmO-vKyT3z?rP~;Mp0*iUYbyeC$A8v}dO}@12%mId6)lB8B?= zhU%KTS}VlM%F0xmXsB<2Ee(f?Yq(A4-dK2*+uk`SP!5~kP*nO%J6=04Ll+5M?v4SE zhWH6s;m{;M&j23&w&78ISeK~X0)CG@_1_g9e<4eNU2gz<1qkPuhzBE?)e74MdnQyY z*(UZ%yK}IYVe6d?288X-QVPhlnLhiL?_>-t;O^ptxO?!?k4uRGA7*X?{B}0fN+%9k zK|rW++h~;}(yrExSaiFXzh@p!u=Ygx`{%D2IFMMZ(S=eBGTpFPuM2nk@&;^gc4))p z{g{*semoA}uXTUOjq&JtK3etkaJ01SdR<&LjNkn*(jRGT=8aD7oLTSMtX~nQLJ^bL zBih$|p8pD;t1ZU{jJ!0m2l}_#yPJ))Rq!uex{hD}S#WRewqF;1@&Se>^yPOgIc9`c zOD2!DMXm znxERtf&#Or%MLn%w>-O}#LNcILd4z`aoR5J<0-g~x@RjH1j)^eBTLuHZa=h;;G54qOTMuZ6uEw|%8 z7Xs2v3RU$`Kfa#}QMo;_-zjeAW)GJ(ndejhiTXTw**?;3qG=dExp|@n;gGQ@(A1-( zY65G)hyWyQvvI0UrTWlCt%=i@rOMzxmwm^>1$C=gqUTBx9%Vat*s=H6ZDLid&rV3W z1SjH5(upld=3twZ_?y+4#$7RAccm~-!Db8i2_o6>hCAkt&f39YheLGacEZR+#SgcE z(>a}>$jYG^vJyKmr!7=O4qIfp9&66slP(SJDa&BZB^mLMWM?T+P|($-Gspr`TFgJO zBF&Ut$>m_&J)>h4%lKB!>oQO8Hz){nB2(>QI!nK5WSALxU8?iE%0{OT!-C!zOVrN}4igz+==;6@-BF2c->@7wsUs+~X!@CI6nL)0Fij-FlLrKJI zE$H+Gvo_tKRGH|o5WFV<)p67JH!MO?#f}(Z2AxRBhaTY)1-W>~r}?KF(ff^@$-VTD zB_{!&-0#oraP?`^3ME1keVcD~3q)Q|5Y;>f?q_!x{GdoJZavERn=fW<&Xy$`Yaq^@ zM4!__T-9zbJSepORBBT0JnCKn@A3;zg3%R|Bb{+xJ#vT_(nCsvSg``EF}8QC6&|&X zi`an0DCWuqasC1ybi8OnApG;Bh?|AHkY`bH1OtQ(;s-S^S?+9KRL;?ng?7&gr!E&#o4|wG0 z`Rrl%-oW$X1gC)sKu~&Uo6WdL1_~jL>`Nu$vOTTZ2&+whu!zOsoGNd$G6j3#X|ocK zt$ldXN6w664bNC&AwJtLYnr#!~Ad z<_@xx|JZ6zGj!r~mC+8+(;G&|8~j{8E@@C}^QbVnNVS)?nAg@lo8PmD;~T*>*AlJi zbNZQJ5svH6{7oWbhnEdBpFF6~KJfe_Q2FM*5^&uu+Yr?;%COPIU54M~7itVFb+kKS zrI1x8$bM>yY}Hhyc(u1iefN3LXKeN13(wF?nBipzE>oK{DAQ)uL?NClt*7ajH?cl5 zih1|!(8>vrCJ5?4b^pUBOw1idIPe&$M`aYv-cHQj((lB}-0Q~SOJ4u+LXxEC)${bf z1^D7h39G`WP#_?(Xnz4CS+D?<{|NFMVFC0||7cFTYb)I1KfQ~S(Er#Ufu=6Trncs0 z|9uGke*m^i)NTI@u>D?RD1r?}&Xi=*d5z{AL?T~rWUu^Pzn)|qTBq2~;Zr8BmhH9z z+@_#7TV%&(25phpaz&aUVX8%=VGVIsIaOheL79Oi;h=RTgd2An=SU_8s>i89k-KIO z9)#47vL@!C{=O045VV#yVK9q@mYq^{6ZJ$4DkD~5nM~DUpj6#fpkb)T%s5{27>?T? zq)~?51X;|B+1m6LIK3V|+L;mR>h_5RK0h<8k^UlVVqCaCdfVvS!jB)J#y1>M_c!~R zE95c`{!k;N=i-eq+sN_*7*7rJ102ax+4HCNsmAv_2O)nzf6v7zzXOe`NANj77-_>; zeq%SMhAJ822XvI$$qunfX;6f)Y%r-9_L zMR)Y3o%~Tuy=P1A(AQ~`2G3@lp^0Z-2@l&P`Q199j2kU6ld3LQpt6|7y&J1tgaA%g z76#Tp#1XH#2KWm|+|T%7lo$Dw6Atbuz1S^X#fW1IjY6(ws=H}#+#BUmlQFm{2?x#M z+o`He?*@yBXS@20If9gaGwCukNKQ+3ZN?=-+3}1ya=HK`ZAp);eMfBf#8I0@SYfg8E9vhd6l`}TO=SBffr z2RhJz5q+u_6T*-_pG&%8;(IkVwWo`C?kcF&9htVe3wE5B%Ugtmch`_UH?Er~pYy_*ek{q}b>voB`m@Oq!USY$2RKekO`yE4yg zLuah3`nD664TeuCH2^zp_FsftDv??${@8>;4L?HJk0?WLUhpkDGAUe!G=7Zf5Nh?d zO(}3KD|F;AuqrkWBI``K*TWwO^+*m}8614Sr^0!IQ#+pFyjJDIe&D}-Tv&OPBx~(q z;yj!_37uZ=LSnWL)Ga9M16ibF1bG++v+GXJ@-Bj$Jyqgdba3x@?fGBYb8&F&zy*y@ zPmLnP-vsc(2nz9Ea`IMURDjc8_YFTRpB(I`?p%f>9aQBL3)PMeK>JUsm`4YY!~Nrr zd?5m`{r7NsTmU#;t0FNVVK`w zK@C`e{byxlHo$+nOSVe00j~dgcLcZq{{sp2;sQhh5dO>bX=+h`90Ur*xEz^!VT6`tZGS}I7%Z@et!4?BI9uQc$mJPY@J39?T=pz z+MFm#W{ITqcBjXThb3GQop^|fyeX0ptN^#H|5WJX&r!;%TbRMw^sx@7?C2&5cg4C|3wAKM^HI)zRfYG6 zQr!mzOwE|JvJX)32oT$G-Bsgv&H^nKeL>oRW3UQEoE6dDxa?GXm_<2)yZa3e>n9)9 z`gWeAqO`et(2fq8_!>+=PlGDAYvUxS!RK6lO|VaeaG{cSJ=7*6BdO=q_lzXK_acLz zjYI$#*XhwA^GVlOca+?{EBZD7Crqub+)`U%$qz=)8U(qm1TfbAGX~tN)@X0{x4c># zp(EXO$G{p8MM(bK>nXqYKNYl@HU$~*0DH8%BpoA4Cad_8%{K&I13|5f4XcV4Jgl0~ zw1p0;mWNi`C>TP$xRHVPGlb38ga6$HLp<=$7YK^airWYIH!kUT|5cd9cmYCxxdb!H z)8-4HpAI#!ztgG&{xxkt0Pq|1pI}h#t-CP!T+KP1dGgc9rfBw;==R^Zxl18{@84i@ z5c^j!Rf++Afg#{TK8ZJ5|IWtv45q8}{4W4HU=Ycy>VIATA7Fu>>ZZdyGy0DiRV_Jn zRI5!+`xTvfb@MZcAx32Qgp;V$!H3ha$l!~g4c3kWSyv`2&g)+>cHoFsk6))f{Lj%6 zU?!tFS<2Zjvc1%z@QKCg^reH4jl5`zA=UffcmN zGZOXtGjOyPcnryMaP1PkGHf;O(7{}RN)$YnG_+_H(3Me_sXr-;)33#8oG2u|MNRo) z@<(IE2^e9%@OS4L7AO+c^zkHo$egLj4{tg!0&F??KADnmAj>0cL4{khDd+$ z%kdfd`QKYRy>b&jO$f{!iVRwE+nJ_h+q`wg9fb!%B|-y5C4gfZ*R78+QTl{AV_-E5HB@%+3EH z-PRqz31x3Lt@?Sjmb(LR;ri%1GALR3k~K072t+z>e0H*;1)0OPHA7+m#=xa^`Qcq%5) zy8X_HAV~2Hjg}(S5Ez~aTUsPjQV~%URDsHggZ`#3QsFn^if@_J&_IqQ3aV-H*$At1 zxEF5;v{2DfGyQm$Xj#)t96iTIKc#G-uUCLz`uNs)Cx>zZ+BErRK$1OcO@S?vgfQvn zSx*CYTlmv zdzn@gf~(Kp#oz)04y;6)*T-&Fw9LrP8UKqntV+GrpR1{KtrMf<*QW8k?8pvi*s#Y^ zWUcU>d+sMa{`tHj3g%#k%}h;mPE&r^a?NXx37y`86sn znvssyEw(-p$sn?RkYFf^s(ub2$947+42o45!Yo31v${&d;;;_rF)~&;6u2&?-t?^+ zDm7;rPhH&$;jcu z8qSL?XwjCM6Qb8;J&Pp{?&kU{;lmLc-9zI}k%2vjLUuM zq4XT3b;cPGPe=zAxgDJIshLit0)6bRjBPD>599K899q5H@uj`oJNI4b?O}S4@)8LI z<`RifF!Q2E!4gDJl0u0<+Ot;vrNNh|Y>d%Qjksps360FaFb64%S&T0Xq;M{e4NuiR zD#MswB~xExu^_Rz*wI+mDd9(6&`9~mpII#*`D1x@* zBa%~e@7-;LIV7jaA=YVej84_T%LK%9tTPJXjD~z$lf!mB`iq!n4|+0^#gs)XLm#-R za#nKh>F6%%lCE@Kk+i;ycy!o&VO$AXd7cX~2Vse06%&=N<=3pq-E<`L8gl7paGi{8 z&EoEwX>ZpmjeOl)CGE~0d)w1Covyq&VLeMXv9?~WWleOgA8%v+_S^6Bt0^b5U2YLP ze*pjM1t6U<3h+O`BfBU7@)*aQXXM&{+cbA8`MB2_XLO?D)!mWzv~S zfC=CqCMrH%XqV3C+d>i9Kbf1!0SYqRs2TtZ{6D1dQ`&!tlaHE4sZ&WZ;!#-ADSFOL zgd<~Sbl=A88Y*&Y$TC5r9Ye8 z{mA|e`I`ilH&J%r)-RvD$sSQeE}<=DOj_@knFRi7=U9s^ zCG~t4C}Av8%d3nmZY=%Ae^w3RAhy-@4$3xXM8&n$@fwsU%WszaR@9x(7-=TyTN^&uD8Fe!_(wVa3sgjW zRSOVLKg2&o|CROX&<6I8^eubrSP*Z>{g9|% z#n@hUv7XKY+ZZN{^1c^;NzICB zKS=ljnH)8$dz!4Ym}VMymI^m^YKIN1%^FZ#8>o(k`np2Wu<&OiT{uqgVxW-XP$kD8 zIi`eLdKE(cxFMxjgnm(N25681&TU?|Hdc#@W!)o!1Q!@^rF`=i`qfWk7Bw$1HhUTu z%rmee-cqnWUDd^vEeOrhf$AVzZ#;5A$ZMO==V$UF)V#yxeg*Cz*ow7mc9d?rkvtGC z6g%G~UGE_ZrbRYmphu+698_FU<^Us64O7f&Ohxgu1-)q_Q@`!BmTtelQzNytN&8v- z9ukx*7y0Lp%QepeNDI!ipYM7n4vqr1{m`OhbZj-6Kfv=j%MJJ{_f;^)pRy1x+KjD4eVIumQIIilUN?3)S;THkLLi)7m>)((ZFqqE{4!g>7D}x8#Zu2F{AU{9t$7^Xe#(C3?Mwmf{ zt00B97CZAGdC9D6bWtH7qu~s|q;j|h&477)S?g1@`sOGOUm2OD>Q(cA^K>Adl`9=Z z7!Jd^=I*YTxLEt(=E{s9uqFYEuvayc&!IvU6;a%@=DBq6oHoWpa`lsYuHNA_r0L^N z?Hfk=1*55ZI%J{>?XW}g#`8-{^P70X6fZG9WdNd0& z9Jn(nQjf}=XXsh|<4$JOm8EUoW{w`x3^XO^HL3h-`TfdzogS%3%AStF`6xavuhF#$ zgmB%lqD`AFx65?fx5uiOZAJ>rjoi*}ZK;orTy^}L;X1pr$WzoOyG=l4c4*rwq!;|R zkX*tlq%6$VZTuepTOG3@n{UmVcEryAo7ig>7bG#_ZtWA)2M!`9`qQ6X@Tcv?4)Y``+6K^!kOa8Zuaa&p$}bOCFhdm=pCh zBgoHFc_=+3XVnrj27rmB=ARr1jgFj@qryjaZ}}c(*}K}1o;m{eJh1p=g?@O(9)$P; zikJ_)MC7JBRS>#|wj1?{kqd7JxKQdcrwT?Gm6Maxa0E23YoOcBS{dXhcfg}ET!_Jb zWOps6jI9P&Z06)%m4$C6_jpX>GSg6!Ipu6ara4|hrl{~-9X#Em5RG~f7lls};@t)Gx+_!B_q6keaVR?<&xHS?L= zi1NBF6-C@IF0iJnGCALGNT$mC$u;R*JBiKk>ZCCyqS4|25@@g8Tx*bc zHkk2|LF^Ivm41d!XQxmEbKoPg>+44P#UB+I##Px~8M6ToB6eW~L$C$Fr}HKXDo-;F z@)1x2`8K#lojCDl>Ov8g@#SN_@qDF!`qES%$1!hT-|hg@21?|Dar+x0^}3mM>Y}}{ zS?8j@DW|>aVzTtYLJdy>;S359Q(nzWjdlc*JsM=5S6JHi~G*h36@LDS(HhF z7uw-R(BuvUiQ1p_=Lm;5s5Q^MDQFgc`yC!K%RSU7?0&v)+!uOH$?;dN;g=_5!TNq? zKkpKGq)D&h$r+1yzJ1A)wz<80YZQp?k6GyGaOwWs-PF``C+N@ZiSQeUWRWTpP_a+Bu<8T^J7+QVLw1^WKv4 zu+n&Ae{^GK&B=N@**7}0j40F}@ySRNTN=ISNtO$}`4VLf>9hi5Q?qJkW)> z+|ln5O2B*N@ho6-)>}$hBp=*0sk4?)0(= z+3vtq|IkKo=kaA%s$@+T;KY^4ID(5kWn#xNT1cVYOs;m!PMm(O54 ztoi&045YKSxBeep?;IW3)@~0csaTzkZJXWc*tTuk>2y%BZQHilvF(o4v8`Xu+xMPx z?mNEkk3DLPHFmAFckSBi!F=X?+@@hZJ=7Iq$U6|uThY@AzCbUT!lVc%wc(wyqiH`Q z-KIfp_mr$;&>t@1hAt9&wi*`OCYH&X4Jkb2fxzbj9dpN^UG`xo9^m$anrsUBJi8S| zN`L!JH_InlJ5zGj4$zE0qnp+a1{guV!20tGF#EIIn0Q^^?spO5*p^4_Ukn924}{QG zO=qhH&RB8HhKOc|ec0A$_(7Ig9IRB4AuH9*C9NcDH>7t_-)O7u-TVLbuHPH~?O_w@ z5HN8H#F>}-n0TwvhS`c_5F*y|Gq=b|JO&B&Q8`RxZ20Jyt1|5e=E$j&Peu3-_ zRkybrjCa1RqnUL<`vHXf%!{+d?xvR@OLX0pmo-i&lSoP$ao1ZG-giJU~U!326+-y zy%Dng`K<5NJKPR6+;{05{>iU-5eGlNTFY2IvP3?k_aRJvoioGjzJJ?#{JB7@v-!7a zsqv3o1kWzclc(OZO)<3CeA&Pb9n)lZQ9pi=zVpmy{we|r%unJB4<*#N#!pqs5Ak5= z-aKXZF5(caK>bIsWrF#Jwt@R_-)n{^)k~UN2|NZYBHgApG zckO7m-WRgy>}Y_DAZ1m3MKcOU39_=PCNEal*=;{0Loc%qHi50{f#m(b!rHIwXk@fp zk`4&dvY!hYoSIpp!LaQhdkVgv?~;q)i*Pu$20^YyknORfXp;Y*wdL7p&s;=rPC!;T#-L9qBInX3SKpi2S8P zuh>FDKxJa&K9#nDu^G8yeIy2DI*jT!ofrwEMU`2lkZlgri7~}Z3)C>F+c6acjD#nv zZx(1}(=z7tr$bB>5lG`rU!vejG*%n6MlXeOL`u~sKJiIFSOh7^l{UdYc-Xq4C=@L- zM7hkAnn#h$m*u!OQxa0#UHka82+eC*gpyy50KrxYvEP2J$+e|Dv7gz8$5PQANGR5) z8U@WRZ?&VpA=#rf6LDU+l~AcL5(&QA0#~8j>8dw+RFDHW^vGo>jv7oS*AM$o`X7y} z?p6dNz)Lt&mMdeuwtIv|P* zDN4^dd6NU$f(6Ebw^YuX+6{qM6)Fwt%MVchck3DM{%7k+;wb=NHxc!Knf+163-A3` z*gn(?hWaNE-x&H=e2zN|wgo^mVt5tuVyz>?{n(al{^Uxt?V!Mcj!yax{|l(W;Vvp# zVlVzT9FU>1YO^YW^wH{pR)H`dJ2c-TPFfQYcF8>aDW^DttDYKN@+^8KeiwPPV6XM} z#tq9;BEd1OEioAR*}3J);>|R4Htnud(Xn*AtuMQG2&}Dzq~S4cImX!Wu5vcmA8AyQvbwjwybM z1gKI8d~OBF=*+eg5*5XXsLpAoMksKbsFUAj&Db-f$mK^yVqb=sn`fogv{p%AXR{mg zvw+PVExB1vn>Rmn()%# z=rdLO)*IZg7zk zND~@~ocSbRu6f3RUMU&-)8w%2QX(H#0uYV!h4f*2np*_oxWTU^4rB?DrTKP=`70=f zrYXuK=5QQ~5zf_qRs%=a9|516nRY3?qRlmqs@{`P^41*mTH2CQoD%}Rg+k2}GAHtV zqYmC5Lg89Q6;DCc84^6-{C)EKVRMP|@>TR+GUmiURhSy9sPF>e$%mKs3InRhy~UCf z+Ic@r=jJ~Du@cDM=TEIi6;LRBf;_WCq}FfUmMlx&%TTD^Jq}EcTxf`FJIxd6Sgf>6 zhmAxZn39e!hh3dpbef^DCZuI_m^1Hg{L+=mPgxGp98orBGQqH+QzroW~Acf7uQT0 zYvv^R7Jp|c9f<(#?>gn8L#Q>MY%M!*I_rnpc={@m_=kB>cKKF;J^^}ZoK z@hYlyhJ2QTqUw9%N^HqY*oN_aZ2!&$bad-?N`UCIfxH5a;JwRi?CYzif8F4un-1I# z*Bl~Z>V?zv>aKvCkJkxLJt~RI;(RAf1{;)M&)Wgn335w;H~U;52y$8-)VJ z!5*ew+^>D+egv|=X>6g@!752Q?w#$`6@ANO(?n({nr+7ip?{7%*1POVJlT^)2<&#t zj7zX~mBdoI9vTqGb#vDyN86;4eLFEYS-A;#Ree8`Iee1t9;;Eco$Zz8!%TDRz+^sbZZ3hNg*U71t|j^Qdo21Q%Gk) zV|nIEOz0|3=wem0E10BKf#=^ev=@H{8kJ&A8Be}?;flu~ZA2wnP^FxsWEu%j*Gjn& z3hWPRF^TVZFj9UZ#epa8y9A3NB?eX?(a(ydZ_tPX$c$jN=+L6BVSnNyHG|OPjp&ZB z@3ZjcF`M>g0*2o-YPArcCiEDg4N?zww_n>BoUqD99ou@xzENMiGT8EJb>8#pdJ<9y zX}}fKzMPn`)=oyMl+DjMPVDR31%Ve*K2e4p0&w4cjP=f%Hy@);Qb{kBa09hpcR1Q2 z3l7)QbvLvC;~QbB?QfM?7qxsw$HAz$J_L-{)G`Qpmt~h*J;#^7JDT@wE$2mGr_+rsR}HuKpyBo3Tq*ok7fxrT5RMy)ZpWPoBWTl2*svuwj7q2* z)~rf&pFrK9M+EusiHWabekS=-<4+}f_=ksm4lUX}EzlDQPZo-S!e@tOUQ&VB z4N}$Lb#TMQ#29jX4mUsoj#eMigG0O|VrjKfcon)b3|U>MembMi(|glFto4rQqJj=t zeO^OXd{B`ufi zE>PL~nQjDVvja#wT2M#F8ZQ(jheWP<(9CgN>t7yb=P^jr7iF~-$iCeeiZ_>CwAv89 z-$0}J<2SP3>TqPoiO^Z6(*#HDqWA~xVRCFkxIutxuAI5l3zw>3?AVZl=Jgs5AB%wH4BWAztw8G5ATFyhve@LR7S>{RI#n|2e`}(!?1i9?NK*AW6d%RmV zfI3tW6rm8orUAqx;>A*2KiC~a?!IAJkTfjW$h`YWMv@2E8vG$Ui+-BedmTQlNuFgX z8gcus;UHa0*En~fiSTXROzgVeQfxeTBUV#^0^Kn)(Y(%}E_?#3l#}-J_azB@_Y{_p zos(!IM(!$qcsx5eV)wUnD(SI7L{c>rd46Aw0wVgAaNm(z zwdoQqz*{(-gJB`~)&vWwU9S}L={NFzJ8F?@zW@Rsl73sVH2aN2DAOkV*w3lpU!|~& zs(n1Oz*ReSTtg5@Q#}lKaT>P)zLC$( zZ!3_4)Lh(w@=E#FvzCbm(Wc<0GduE+m*2sW^ge^v=iqYm2W6fX8-jFDHE7L-E)U+- za{MO15wN`WxZYOzHEvzz)elpkMVo2FUyUC{>XN4gNx`|qPmNq;Mg{Le&Ycfd#d+b% z1)PB{eC22aVCSoud=ZkPv#@>lOL9?*KV58_=FaFE{$x+WeGiJE_%@u`vU2yI5pqH@x~-K8NJBka`4167vG;=-O11PfMon6> zNDSmNX?hUGe%z~{+kxm+#hqI_JSi$4HQ6W|ldV_F%+Ij$(x=dTU+vKTr9)s#9L4JX zhVAB9&Q!R9aGFDZN>_Jdqv?jA*x3ZN@o)JmiqKb~k{lSaCSnkfRIfikBE-T6koefT zsOYda-Gs9MMvMXk%OL?Ei8D&frX(`;*JQLhBa3DZ#h3`lVF&w*v6FUh^NYj0ZnQ-K z>_8AfjE6Jh2}pU)YN}RO*FKu!&>827b>h=8FcT?Sco&a?^Y4|V%`%L%mjk{Dw{9!t zEo#-UFf)dQ)3H&vwnNk=YQUxvufNC$D93Uv)v1*Hrt$>hZPH;6CU+uU-n|(??^feHtm_RUnMXAr?4a_x(kAUMo(r7*LTh!}8rKKi7F3F3#sUVfEOmF*!RJCY{a*m9>{Q8blpWS0}l0^wjh}$PyO?s?#hn`1catQoW2J?*# zjLchsspYMyLR1`h;~)lsA-d7ECkI>nbJJ2Xss)kTNTS>+F#c>qXZ&EdsiYEg!kgb) z^~(UPR{!lRyMQX#K<&RjerWiB%)^jE&Ky~iB(3=@ zxrNy!_zaP#Yu==xD5`$mJz-mO_TJNX^ zIA0JU5LhCx>zq(IlcGrn%ll3K7Z7Evq%**vN%(HBx0ubrK2xCrUht_QF+e#FN!JR( zbRwcv+5)+3L0u)&Z|#ek2Adya$uv@CF@KE4Wy-;dhCe@;B>Q_U5f`D<(g1?Oh5@{J zpiA{9$ZQ!YX;UJ&Wz;WF&`}dSC>o(7Kv3Q}eGRUl1Rmv8$-;W*<}ZPuK?QpvIXexG zLFR&y=>5ZxH$;@{)*3ecQvBQ|IN+Wq_z(hKo`~;)bkvoD2$ZLgYl-;j3D%bB_mG#JtnQlUX$Z{;NdTWi(n$)ydStjz79<6l{+~ownDBydlO7@XD)cfT|wy z(%AB%2s&HljAR-4OEt!WP)foP6lHTSa^)U31ALv4#rghKuMR&-wcE}-v}8@~+3JOqlR*D~4w!~Td^jaUDS zYDHD6X3Mxb0Y0z{E0k>DeD{ai3 z2DNHl$k_k&WRk&C(r7`L3&p^@PO7iku=fcQ3{Nv3d?zCyzCgTv#fes3c z!PzrRl=%qp!G$7n>?yvg9j)x~OTBKt)dlpT+5!VY6<4bj(Z?CuV7#AlD_Ul_Tkk`A z+wfLt*w&Q91v|CDZNMRexTpdoJhZyeH<><~xFOX#LPrD9uZu5-hKJG_jt;KjQo0}| zwl+3aqqvg0+E6_|)ggKY8uctl9ZhYi7dL5QKKg=UT;6DyVQJrti$VF@pih2s#;d=# zj(PCb7QUkS*;Mw0YPxL27dt((t5zS9lY{m}2h2yfjoDXY!4c>J9p;af` zkemWoE=LsmeTVOt?eD7}CQ61N(wL4X;-vQnab;9f9j{K=iabU%%Fs>Gn!KsQbcze- zMTeW(7k!0iyZtso+n93Y7S$GmmGzNZpTHkB28-a7t1oC4aSXa+gpN$W@=B_*;D$VC zIOM2>$a3HY@5YQ5(PCpnYUt_$-Br2NRxt|g1!1G$s3C3cF(Kk+MG={kIM|fCZLP+v zU+q!Lt8!hC-3M7Z%j`q{=CgEIqe;_g1C8tcrm!W$f=T2gkur6YWDt#-&GcgWymIZj zDU%MGVL)ku>%I+d4Gms~Dss^GG1AkQAEy z&opnydB#kaQ>N13UV97KF8KZIVAFl*OIOpui{sf`a)?eeRe!GW;gH)z)6{@Ul(t5u zn%fCfqnNk*ZsqK+22RJ5U7puH`L_93XR@93=q=7}0jekrmXwDRN6?SB=be3Q{g|(564&IbTfHD=xA3E(FsF6tJlZ1St^RJ zu#nvS9Gk2gd7(59q^nPNQkGvjEwk`U>iNVNY_(jy%p)yPeH{kH8~h0|!sEXc5`HEx zg=y&J_YC6U>q2ZKWl|>4{82#0k&HH~?bHTzjLSedPw%%uPmb^`*+JM8$ykHtC{J?- z5t~Lnu{#1;;FUR`O?@8gIJHIvV7Vn41-*jIsCVlvxanLNX!bXL8I73AZ&-h(m@7yT z>u@kRL-Tqb;tX+O8*Z%ZC#|jBjP=a&VmRC)BhKu!cFTBej>4$@v~5;wW9-BfNPi7{ zK{52WGsLM}Us#1&Rxm3^T;$pW-C0p%@k^oovOVd0eO$2^cms^JybwZHWBzTOZKsYe zxF3US5K`4nM;UDVg{lw|_yq@+()TxUrnFIwimNmj9~B>oKwN6o*%J#z`YeW6knwMw z>q)B5dR6|i5of;*DI1=9#thQIBFa&K1Q+K-@ZUyyfKNl+U-2GPJ}cIhHYOTL+qDyy zjIeln%!OiT+n#uMsLkxPc|Xyl-;utoTZU7%ZOffjVQ1x+Mvy`HMnND`$h;_Jznq{( z#VFlKwVjYjm>UujM{X3JRab6O$l15}hFwk`%$j=3;*12Wcp%7h59UZ8lW$Q0Dai+E z_OJCAEqd6 zx=^6CxhYvp130bV2JUBJ;>r7UBki=_fId zv&FEmTRjlI7~T^@cg&9*?)U}fKG=|14g7={)&OCWKwVQgWu9My{pjxA@~b>H;6U`q zd-&6VR33_iOS$>Yn@IYRP*9_f{4C^*09|t@Si5;hxTF@h3 zZv+W=Q=5P&VO>Y zSBGYsG10bRW*I`@n+gg0uMizvlfXNKlH}v*G_#80F)c-tSq}{;0Y&rl7&53&8^8Dd z>gz2Cq>*dz&T4zn`@~VQ1S0x|$B{!^B$ zecW)H59PI;U^^0`?gnS@qQUYjfX%=EtZ$vTKHZsWcu%33%{*5sMW^};EQQUShgbtC z?crR6A&1DRx@MsECa~%(89N(m_A>ehWr3|u*JF}MwpTrMEArbU0lhjlAJV1sQ zJ=s+qSU2(^NV61`CS_1v4$S+ZyS;HBmG zFr(O=rPs1vxBYRTzXJPE4i%j7mH8XU&cN({2{W0#wK1!|du~2DScnCDR~Ru?l%thK z8D;Lh+M1FDaRF|ZKl!#e6U^|(;t7l^fB9pcS8n6nT%-T7nENVH>y^@yRU_Dji4 zJABDLY3WS2(l^oGdyZ39|4Fv>7@|1nx?oQL@1F@)OF@7)KBOvW0|O` zG^C@fr=Ut$yXEq2)G@L)x8HD`{h2TXl+kAIDX`mTM(aE>UZ%y&XUQ~JRUs;-wEFXX zvv)9@?HUpa>8#{6_WUF!UdgULF-VrdT9BU@3*tUGJrBuyL69E}UVM-)M`_#QJMTZ( z<6oN9T6dWV!yhyZIH*5-VN+WpCualW{{;;He=2ngl(lWs7*RbBR3G%wstX`nO~mt@ z<>y5d3o26=T+$YthI+{DjSY>Y%)j1tO$LJa%oII>!r!MqZ@D-3DcB(e+E+S=|3s3@ zge~FAoD$PRW-bjDqOB{h0P-V`h9W?T_&UbS`CpTwhl!HO=llO6)~lo(weU9t?NA_P zLEhFP78Yh+aT8@>dfkK~8Ev4YF`yjnHub5xM*F7Aj(2}no*%FwOFuFBGtCxb6I0AR zPbqcWH1lB0R9K!ihf^1>oE2#9a0{EC8_|@`i_3XkML_lD)YfPA4xAi*t7>zt)OKsv z(bCp6w{6hHr{x^IBh!X2r}MzUGaDN6e}kBtl=A6@QWa6jUBcEfW43 zv`Gmn2HHTBO&H!o1pL0nJq|q}>i5PzjJjRIkNdC_()sWP!YG@+BukTN z%8CuE=_44flv3tmK4HzQHbs6=20mS@9y{jsb=%uE>4HbQ>#!zsb@23Vg4#B@k1!s* zCR*vrk@@HL=P7}ukttewm3t9?aECl^WPqlp$_3;rAJb=|eqgG8upOOnCP!gd<-9j> zOrKK)Q33;PXg=+G3`-FWqT;GII@z!gJ;}DcFO>w=58|2C(QFqzzYcPkAtC4c+v8t`y)Up$;2I#LbYTE#a+UmjW?0e10a5z(F> z1-#?G$KZ=58GvjGHLHeI#;euG7z~FE-Ou#c+6cQ+-!#6mHI6U_y%T8DK4u1{mDDDk zy4c)kB$Xz2oW*Z6%cnCns;g#s@mh-CoD&{?>T(!kWeS2cB=N~?_|R+auw8vrNqdF! z;*?AEJ9&=w#U}-qi!9+5enwt z{3OyxupfV*_?)+YVPV^EU>$#GOHBiz$p#-#{4dx)vn)IQsSx_#qWUdRfXAQec|AzL z-?Z4IDR&6$rbbA>A>@Auw*m_k+YKMDXED@&5Vau$z~AJjrVRwZ!wKDzd>?Z#^577LFm9e9-&ELCcp7}4uzmER`J|k2mZCBZmI-gaM=)s07NNCK{ zSJrPK`@bAQn)wLpCN-m(*&Ed*h|vkNInSowo1WAhth-BkEg{|}?m>Re_1_-*%94&j z@hO-A3!@B6+_{?f5JEzv?;7Z~ z!;ay@^_q)z+n@vy6lZ}?P8PIA@=(s_jwAps;655LxXid3St8NB6OxYG2K9&zP{OkZ z#rK$gL>G-#%8UlPiV&iamHc!c)WKi1crBPpy8B`Y4Fk>2+n{NJU;@M%a=*Xne`Gm7 zEyFO9iEmiokdZOTi}7Uc%^DpYwVl@6f|vPDWTGEwQJnP+@Q9F0R?VJ|BL}E+ztq2Z zn>MpE$a;C@GzDrkKhNGrL8??9-KMD)$?BrFGAkET7J>;Bp=OB}F%fL(dyAC7imIlM zSBk3oD1DxL=E#12fHP0xWu(U|z zy()jSjALW$^zo0%3@@79IgDW|-xIa6+9lx5#D$pchWNqdLNO?dPe4Zz2XJMEv>Tk` zwGv?G_+|KO5xSi216P7RE*%cWG!%^3Mih3$^Udk_0@d;uNdYAK`o8`Ky?pw~5%WrF z{Vhpk_i=D>vvlt&0ZvKaE=zRU`HU=Yj5GCu(qp{Q*}m9mx?zThB)=OvGeq4d;idE-xC6uX z6%*MVIR(g((KR5t;1I88|8JKy6#iUuRFcJ>7MqFM))+)UnB@rn)wmNV(WZ|6OuqodR9j7PQkQsmc@SJWkWW=Rm_+sHO8v+T6Ceh zDfKLHz)EKOqIuM4@~e1`sHJ-U2&>BeOdA{I=t1|q?PrX=YWu2xSf!s)xDXAlG;8M- z*aU&hh+qc9K5ChVmQN@(lPud>)gC3Dnp;oko0LLyr6Z)>u*GCD`<^pqHTSDo$mRFi z-siF`;m-JJQQNVL(>&3q-!WdJ>7{{<)>QqM*|jDMGm6XXsd0csXS}AxVvyz=j}%zz zZMC%@E(aV96=MsoL+?fURo0ftdX+YQ#o+6c2y|+|7<9Ne47fNJ2P(QsblOjCM8E*c5$KZC|Uy_EPJ)Lti%2sh6T?G~X z25>@T72*Rnn2ci#?Samph9o;RENj8R_PFa#EOiQ6? zD8BaWTj_lH=)u0w&S)Taf2J>*8I8Ta;5danxSc-f&&nwTWH?NsVEQUra{>!m;PB0K zDZuA5-FUt`uQ{E*--7CvcF+LReyivFv}U+Ba6l1}y1v39xE@lQCXA{qwMesGOO?sy zgv`EIV76|AOphLkMqjh8*O`O@b(0sx;NYQ&6MjBC>9xbr&eCIzNmu!pGpO|HI5MPE zm1Z%zHO^A{C?YwzM#g$*p1jI{3O=8!q(F>WFoViC z&fyvGAMf@rX^Fgyu|drbZrl`P64UI562{vPD3pJjAys*R^B+?&sq`;XfuIa<`eVn4 za+;vJJ|-ysA1hv}20;GXbo8nLmj8S^OY0vK-n6O($N(UYYd;Es^rQN`ebmDMG5%w{ zGd=#)!`M^&f7Zh!s98I%Hh+Gr)b)8fiVZiGa5CU@IsP%zcgh|o$z^)*#6N9Mh+KH$P@bQhICAmqJ-^ zO9q;&TUqY2N^bgyZLgzpVhg_Jfw4qCUDy?EWg&_!bBYj51@%>DCHUl-S68P)#cjLe za8pxLQ18$fKg)tt9^aMn)zfy&6fL>IsBpax!)8o-7cja__M9gpP8N%#jJe2Oh=yO` zNk}DJ2_iY{LTZ<^0;MO+KSmV4uKj9wEieY^EQF|ufXIeswlfx2R&dV}f}&D0n=60lBTnuw{;-IRqx2jYJJuC7PBSNfNi zRVW933E)zp`{Vd?ZwJ=~w0!!c$vRoPZPO}4r-vfsqoVroGgxAZIMYLSy_@RB*Z1Hr ztfOi_cYyS7$#kFEdEHSDE{aS{%CMNl*5DrFUf)*eFJ5#eVCnooM%HqChLz(hBiL}w;;_`&Mk$PXY87o5JBKb$qkrokg*?DDf z-2qLHh(Vj+4XKmk89(_xE>9n_W6=nVLGZ3`N?1TLIEb`!EX!Md?tcxem#pK-qKUFvZ(yP*%%vJZoL9#4c9)K-YhRpTo8BPl*J?9gn}w^2dZ?3!~NqWi>38L8X(%j2{X86 zsUu{IL0x%QyQY1qy9p+mmQvgqjk^`GWhlD;(<}u&+&Rmw}q1KpJ4@9{1*|(I^FTp zgDUEHu<4%|iT8fWlUQal;<_ZFf5ZG~x8$p#pN%p~O`ic!fY|MbU{HjSY7Si01RoW) z>-}l{Rec+)v#DwYnj|-_l=t@DPn2$L~Db0;D+a ziQbK_5TPOw^k)i!%UGx4H#lJ^t4Rkoq_rO-hz`{b>)att!d!??s!Cw;aiaP|=X+)zNQl!g z?+C)Q$J;2Czc-THw37w-WgGqKKWelrzkmT|I$WV^hxor`vuY3^nHGwh)`x$2iBYb5 z9T7zmuC~a>!6J0XuAz2+!afcG%Fkm*hVvwxuB(^w2W|2EnrUfy+&-qG z!n^y`|8fCOUDwg&*JYWaLqJ-GTl$-bFA~6|)FjrmFK2Vuz^FMZGTeFDc9g$@&p!!E zLSa;TwtPf2mwOrCSr8%>H9(x0%^nq42#)Sr{Y|aha#26MhkQ98;rxU98P2fQ#V*J* z2R4Ayiu$~hrI6UFAJi5mr=g3>Q=&!H*0dnR*<=ou86RY~!+8WB%e0sL~3vrd$#no>s9VDu!yl>lPmNBVeIzRB^!t0 z%PBD)dyyW!MMD*fb0Fs(&9X&r%b{$a;bQA2hl&hAab_MkVy-IJBaY}mrGv{z;pLsR9PXiJ5im>DT17g$ZryBe;V2r$ zjaUCR=lmc;jwfS&W7g7~%E(g|F}jFza|J;FJ*Uf4!)$Lb8gHb;`hZP@FB zt;00j{8^jD_fpow1}BAZE&bB<3ai-`B&>A1yzV84kc_8<9FOJieU<9Q^(smM-;#5c zrL>v6k9wc<)!0mb1K6i%U%d)lh0(W-Ap?1ym~{+qYzsJ~mp3~_&f%bMG&$c5ul|*$ z`*38E2F?Bzn}V4G@c+0cJ5H&OfgfQuE<_Sh5*SXBxD^2YZ}&vY3XuILJbt$U{6k{m zu?55f{v&C!;A5t0s5l+dT}JT5S4EsJNfkmf$ZeO4DpTm@nEln6aEm=EIV#E zKtIT;ft!>ON3tewnv~*E(K4z!3HQto6-oF<%B9y|3K68LNg05wvpJIQ{lJcAr(2%4 z>s1N|{`xEp&E#cPc-69b>v#OE!oZEz@A^6Ou6hgp8Ow`~JsayUcB79aoV~Q zRR>~D*Lgo&lXQ>9vSL5_<=9-|&maaC0eiQ;BOwIkM4PcaC{toBp@R8|R{;{hHxk7C z3JPZ?SV=KTMrve3K5 zsbnGSDpL*=_-3-Bmy9l~OzY6;sPI?>9!pb}titY8sg~l`_f{DqT|#yt=1A1DiG%d+ zU70&31m-UxGZofm6%X#pBBKtOg5bbThHNnlPn&E`vgJk6Tl92UviLibA)#WVYYe0N zo81*5JLOEzc|NO}K|)gBBR7b-7|?LXl#dr0a&15TEvit&mOO8E_>d45PK}lsnvl{A zltWE^bcRr#14%fP3~CANepce5x;s~z9lrxhD%WI}IPX{r^XqY%pUm6$^~I!lr~FcJ z)^B(srha+q?^>GAfv73DxK3Iq3kh#y%Whs3T*GYDN~KbCiwr(4)a!(ONx*N9<>g{R zo>x+E7sHmow$-8CiLx_XWMs>1b@*GCBg~;#{2nUX#`rdertIvjwi0E;*VnUBPuI!> zyK1!Hp=Zg8k=z}Q4p+6F+-ylccj>-)iPp?M96_kVADpR`O#l_`r5=Se(;CoH_0UI# ztr|zU>bpsr_ok-({8`=0Z0Mm22R}WbevzaZFnLkJZn(Ng*X? z$WK*T>nqIFOtVmo9`C6Va4&OGoYo5YD zilz?dVQLA=>-OLJA}VhG3W4I?07c-4E;0{7kJ*Mt5+56Y`+ri9KuZUGM;CKr*Z)Nb zKDA9L{&oCUjw?ZV)Mkzmb?tzLwnhw$h)%H-aZ8>EGbGd(3H1xSP)c8lz4-Q!{R&v= z+)re1gD|}wUv6rp_Gg3%0((OWELVw`YSxe)_lcVGURN2y^Z-`kjdNgX_H0AY620Uz9!`i~c9!;NpT!IY*#1rbsfluuo-OcC+Zk{zx}RzO{R7 zBlATS;+YmdMhw-u3g@|W*L*Lny1@^zBQt8nn0}THohn-nMGNVm7l87|(ad3sj(8#FtT3xuOTi#W)bEyR{B&a>Ei z_u(UF`P7pj_F>dS^*tZ4(RwS~&crN4UG1pfZr6XOC~DhIdqA8d;Cl?vGp|x9Z9?yw zL+RNOZBXQfD)77?(w6|Dvr-(=jX!;*nw3XKO2G;22-416ixYI^Ca^SEwP>wSz}>=p zgog@=Qr1_8kTHPb&rAa=6O|A>c7E0SitwF12GdnT19m;fnCyWROhnpgFg&qExoF}G z#}qmKUJoWfBt+PWMbZrEF`@@dyeMuanCVyOut+y-_5#LCg}N}%F&_+yHr-p$u-zCh z^fL?Rb~XE9&*YDzOpWzM{YLKk$ut>vQYh)1!iv*!M8JV>24|nA8yUV6p}GagR8?I; zjxrTbvWO&2t)clDrsF8>NQ}X1a4or&)32xUL$wTw==E%=hyJuFlas?t?GD^K|9rj~ z4|7RGxv5GghE@aM9BzoXFWeP4f$(A(heMo@N3Ndrr+SmMVXSecohUlRz_qw^LGjpQ ziP1TaG(G0bi+3f}{H~#|kR9-tfn8xIRS_k0iz&w?sV1sCgRB&fZ>CT)oo~}1t&f)o z`56<0EAU{sA0JBf+-SF0nkdv&At?*?;eWdW5YQlh`2##&|0JcGT)Y5ye++%1_rHcG zya5`2(i1fPfWOszip=~05P*iZn6{fDv#C1-PzHfmtMe$7q<124 z34Zu)!C*Z`VhWg0~xLNe!Wv zK$wIYC1yBqY1e96hu!GsH)bdexo+IgSu{Nnc3aI?f*Lm6Aa-0A9mo|jUB237RFK_! z5^pP0v((D;aUnDlgoI0?mvnH~5xM~{5A!7AIy#UJJKV4b%@vTcDD;20#EE~IR4{k> zek>(ay0mrj`8()*sB!0r(coKWqCBa|Tc~*dW!RhChCcVN5RN!zwsL_O@Hd1L?I&8A zhcMD>#X|~n14>0KyJ0`L%)Jdq-wN+0A?Lea9UUEReeuM$eSvHP<$GJD^FXL5>} zS&!#Bo!lfO0(omXrAaTq4iCq-k@uZf9JK_e6yq}ernHOG1XY_30Th>xtO0G)m*+{3 zUjBLi{uc-?hm123a4zK^(%=l0zMhMCu7kYTph>0}N!`yfz+Mapz%)^fk$P@@{;bom zTX*bcd_N17+C3nP%I?+@T{r+(pBMLb-5ZC08t<{QiTQ|6fG88WPa$i1vb+00nST3F zm+i{Te#nae<#*thB2C<_;YGNQg_MZBFA2(Q89E*I0!d}o&QV%rL>$ImnWGwv$dJd) ze>>d9D|<|OtQ=q4{YkA52CCyN`_uc;DzW|et6Qs#9IKF|wHwL9ozEW7swL7C24&?Y z_R~A_{=HZ06;CDlfaXK%#^}Z^5cE?Bj0;-Wko<@Gtk82e27l0|VEA_wbBTub`Jze8D-9@)eaU|>n2TG_umB$(|9*OUeEehufO`~+#^V$ zTQ+Xq*ReLA&QL!#%}@^kGaqAHIV~!@q9^!CxKg09nnLadq;ZviOMdewgJERQMK((uus?cgkh7fY;91UTbRO9Xh*5ppf#PBCLsvmU^ zuk(lCswD7jh)2$^ZZM~K-{SokL9VV^SYKkPZnj{?L+ob?i~BCNr3BVUx??s68>jX4 zGf0qv^d|%|6BG{FIQS8=3?9M<{$~|yt?AOdFeTF>el}Fv&lO+dq$qVPWtH>xXrXJX z;gdvpdHPVB`pnw+fgz4>IyM%agoBkNMgVKh8sP;i-neYP`EME022$sA-}mL5;S#>` zB*Uh#b^1;Q8aXnJ}S@c1wO=@GKulo6cFhM$Garn-02mjUo_S z<2kz7lzso596N|mSYU%vx|=Rzx#B(hn+v&2_d$SEDXWbT6Zj?BeEvQshgUvSH;QtZ z0{uBwn(a&~)!nLL8)?UN-0z?RtHm`n>|0Bgs|a3v6o8$oHOIK=Fh;*VhpvndP<9$m zGc4%MGmQJZ#ox7fto(H?DX?t5s@C+9tJ+hsJSSe|2L`LA$!&RVz94IS^CVT14C8E} zirw4O>T?qV1Mn4?`RX>CCM(*8m&bIO>BibcRJTdx7zr4F}HHK@+fyRkF8Ym zTKlX8g|$+%5K{SgTHkmun+lrWDf|L*Ime)S?#vvDXfJUGj@gV^z@vdL}R z{$+YYJz2|VFCqG*Y7n4$Y#rfHXDiH zai{eToB99I^_5X^ZA-UE;~IjyyL)gC?(QzZf@^5p-8wh~cXtaAT!OnpaCZstIEQ=B z$$evdKlYy?Q2XHv4a>N)UGfYwE9Q})zlq#*YKs2Gr(S@PGw2+b<+01?ZpfEh3cInD=p%Ih zxwb6%qxTnWCyxlZvLj1ic>+Qq>Yit6-e6w0(3Ja!2!){qsbY8wI-~IBRpyCL2Q};& zS7oGIMi^rVqZ*`p2+h-Hd2u#tigX$^%MAma(NMOP4M9X58v{_6(V~m+LK^g>c#IgT zpW=gOv4hJnd`%=E-hIMPh{F%z+~MfN;ap>D#KEl5f#FW%*}}sDZj|EgX19JASjfPm z;><4bX1OorU2(exzy!Pm3Eb{7M?u&%&*Gp|_9-Hc1x)N#SoiUJ0j`9M&g*0Q&c74n(42#lxafH01Pbem^04P9gduDLCW z*suH}s?=su$xyL%^&$nTqV5ofJ#+gDnlGa^13)H4 zM}3Zgt>g2_sNU%_G$U?z8qfOnw^yT0 zO2LC}wQBe(C;=TWIY($c6`^RvDI@*7O3a-gcCV$CE~6row<2c1i?9$6`RKz$@|0R= zS2@A>9U`eTP=U|^BOevU4`+WXuaYlL-zo?y{*yIPAn9hw;c=@#UUSNO*OHIjlmPEN zU{GAd2u+lVtX~_V{G4Y}4))eMn5F`WoiVo;|Bvw9Yq6PQN$ZTCpF>dh!w#U+o*lU4 zu?{WEk%_(e@lP=)LY5AhZ~T-E!LLi2wUun+tUY=efDX1H+X^LvH@2v?dCTv*oe(!K zLZCh-tKdli%}wFBPA5>tDuC$F?H6C4!M{J{1p1w5=$%-TC(UUiB^;Qua;fK9uC&03 z3G^RuTH&Z3xtp-pji4Sq+L@#}*prCM%7BGirtQCMkDZ^{LS9xhM8{b6Mm(I=>n#!{ z@j5m;00ZX~>sZT2!Ip$#;6w<-TwjF;4?rvlG_x(Tcmn_wF#0&+U$i;Cp|f;PCQFC4 zpi19&VB$$G&RyDPfif&qZ9<}^W3dppP+1n=k+_6^!^0Wm9B?Sk^rB&tC7k-Jm1KYG zEzq#QDy))1nY{eKgM1GM?TB~vNg)-2^0@Wtg%U$~O`VCB;hOG#dE`Ta{WWidi%zlb z-V5aa6x~2W$$yYB03b+}H&J-)9LRqq<>PW7t=_QdQ{EpWl~?f#;2V#-2h z|Ba*JTlPmLtFsJp`b|Q|20Nc0SFxBs!`O#6Q;f^uDdVCkSPNOIV}HHOOu|5#*y5V8OYDg8A~<|52r6#vQuX$2|q z0PumfHvfp&TfV~Ozpno;KpqACJ#r(s^HBq~7k`JibOXXaFvjsA4qsd#4MxiwX0$cjjSWyVW%nIK$bG zkyK;lP|cu5KC<_|P5Fcs|Ro_ehl2cH6enu8Lwv)dpbhdGSqW!Km(5YuSs-bFK` zDMx-vGi+}t*Xp%O=!Y_9z(}`w<_0SkY@S)uXg#IW&x-EtI!sAKfBmRt<)-(mk(&O-Z4Iktu4&q``=87tHjCx88OWtHN zu~4=_)-Z)xPB7!u$>R!Cfe;u(Sof$FX1M2R5DnZhVe`Ru>3oLmr ztUMyI6rGo*VQDGAIB5BrxenZrrnEl%^Vjtcv}hMN>6^aBOIo}qJjl9peo6+dK)^jF zbXD7U7V_Oa_aI*;u-~Hn`P7pi%k0=KymIhmZi-Biq)WRFS%nB=oo& z@)1lI(9k2D|1|y1u%ODAJDhrWn|Xla^Y>Ek5=8zVpLb#oI;_LC1croPr4CvM#B-X# zI#a|;bzEY=^P^Kz7U9AdDS#(=m4o;MNf&k?^&$o7>o)&<7`Bg2fk; zfuP>RDm~goR>Tu2gHk1Di6n2Qc!toKG--%xKDFf`KSUu|x*x1-3f5Zn+B6F2!|A-h zdOO<^mHrCH`iDq`LW_gxxiOC~xH3mdlS*puzS3pe`nomleV39EYZqLpc_F}dfS9{6 zZdqx_a_nT3{}YmX0PWxq1uZ0oekQGc6860zxwq38!)X8`-nK?wu`d* z4zDrjCnWt_iN(uFqk7|&1{wA@#SgSN`3DX1d=m2U%`ctKLH?^H&omE-@#b+pF8$$J zf|nrM0DrSO^Knou!Cu!KcpcKz{wfoH9Q?ndTmsi2ao^U>+5RIZyS5GK@W##5HV;7V zd>tn70rGERNo&aeis#4fLN0*+?X7I~|MkV7R|+V0W5@n~9USNJ9}dp$7;+iu??>bw z|9F+CM@X$Vzqbzw_=lz1NC5zhzWqE6AvgMey@~+*8=15!3v;-g| zg4eJ5kBbGdz(Sz|(nVhmO)M9)uin*&z(4fpa--(pC8{TuQ|^0jV7l5#M0Pu8!KF*a}GwcWi<0% zv}3}I2vOhmM1i;Sy72PyT=p>zyx0Uj{oe7C@Ch9w8gNjt-cCMYIz8zcm^+ess$++% zQ&D9pu`#Cvwtu)hi^LOJf$&U5)uw#P@L2D@0ZHV{*)P}%J>I1d{7lm0=JMqWn{QIRFBj1sZ%DE z$d_$$bQt7OYhf(*GX+%g(jvHPgyu(aHGr+3f_>&-9cOQR1ZYwVnm|HGl%~NPPQgS^ z?^MEE7`TG{lR9*}0oFhay#EIcvU8QYvi9Ph@R5UW{?CMQ@Hk}y#dLS4P*Vv|OY+S9 zf>MElWjI!zsA$6`*)liJzBbB07aBx^m zn6hIosz>wve!}xEgGWkvs2}#W zo90xRjXUz4^(j^^ei=S-E00qzV zcMo)scn{-kjs{~z%F9r^X)A&yeu@zIWoBCovPUe|=?a{xBdFK`#Lbo2?dz>*SD^AWR^j|0O4}y{7^q zLwwA4a#N-65fW5QimWq;;4~6>=L3tUwNy6}7pxB=yp;nXs-9RMH{@f|=nb2KKO|dr z{S1LGyK-)FrzPA$Pw*92wQeBK+ekZPIh|ZwETn^B9uSeno}Cuc=~aEYHZmL$+!ZFc zXw>_fmakHoee>BT6VK`d!6h@;E^qe_DV!`$q-)1`3R zy`8ljO>d2T1b;91LS`7--ZDy7#Yw-$*5NQDYF7yBgt8yp7rgsbP8xAa?T!o}tS!&J zER}eVY@@T`%n+>bzC61-?t9yo6=gkmad8I}T91rhBZi5t|u2mS^m39caV zUUUSW)y zYEZZ$$mq4`yHqh&zBX(;gTOXg?YsPyHRh_lhw+B0i>@qCIizMD1pC67|gG7yBy zZjIIx$QY)=Ww`1GF^la&xG$Yk9DUA%^NjSr;p#c*AAaU_piJwV``M)e{M&#)Obt+d z``C>h@Gq63fgZr|7OtK!0{*G6G}18v!rpoZ8rlC?`?bX4@-`{QLg4h){sAALS20MuMkQsy>>C21RsVO* zMssz5)7vA<+JAhEtpfnO-A$zb$HsK^0jF%Ii%Bq_Rm-$J6V;$@Xcb&3FQQcDc$&D+KZ$!E~L_svc0&*SC zb!S!v7#mfdfcs?d4 zPGQhHg4$pxGH<+%!piRqx4lmURxVi zr=NZ5+aI_3*RY>fIwE&97>;J>*C>HLwSX5@p#4dA{-%2a*{yUXdJMKXPd$B2VUJA-1f@ z-`#2>sK)I%^sE7f^k=BWyQEHytUe{~YWW zRZs6-_-WXhx(gMLqB=V@YACA6*uaYBH*l-0;TYU+Bq^}_x_?Z794CZ>ni6v(sBh2s z^jS0IvQ#jK$T!&(X+SbfpK)ahZ9Ke8N{>7dZR~x#0KtM*ao||qkO_lKQg>(qUk;!= zSe{&uvZEVH3Ae+hC;i^%%wajT-X|lB8ByRla_I(twB^QrhI)<<=N>@HXk-0b1DK6O zZnxDY5g8AebYw)!?E#KaW0-&LMgDH`JM5ZmhL+Z$=9!N0$<~yRYD?W{ov%gO^Quc# zz?ZXtQisC;x#qzNTNGLGwW>uADDt^#-t3n`-e@*ZV$hZd3s1{9NIYfWplyGGwdHsr zPLj!1>u3^Jf+?G+6kEdO<<3j*0LZPgtHwLNMSkV>(dX+vy8YUj_hL#eT_Dq_3^uPP_v>eVt-w4Gyw+o&wam6s=RvJcTh0k z-*I0rht@rA?#r6;~EaE!d7@_K!|sZordW2)>y$zqi6I41{QtnUYJTUakh?ed&^#4sm+Acj{<}% zD&$95(F>;cmD)#L2ge@@vv%8WOg%PTEcWV+wv;6a0}*YTy~XIYfh^KE;u2B>@CS`c z$KSR_4={IMoIzB2r}=BR9W*M%hFXOA@q#P{DQd=5@B?f5yS2UNleGlg5{+KT$Tl{^ z`@w^Z^OPceve>s*J0ljOn)yRh2B>!ZrW?->CxmEc%HW?FMfk)u^C8f{msBL`R0%-z7K3SNGcAq22@aRpWVAb`7jrJ62OLeg z^9c~d%(hF}%ZBuj;M`IM_yXQLa$;W}q9bE$s}M>OcW4fFr_-7}by?0IMm-cJ;K~gz z)RJyc^V>=r5|OCX$XsE$N7_a8?+JS>15}cs{0l#=X%i6012yunuDmRs20t@@1(@&{ zgXgxd9?)Y)LU)B86%Rns+yy8ktja%_3#`e?Q|pjrrEEdaj4Ve69b)>oxwqD$Qj`)M ztXIkB`B$)Htfa7hF7#ibfEDXKwGoRiWNZkUFV#%6D2Yexkx;|#u#-HxY%wcMw81`$ z3SnR9GZHB>0K)2?)vB?nUTX38!}7?}ixSpu{y3bnG$NJwz#@Q)heJl{eg(BuWijVp z@)2L@xo$u}exp~rP(5s;5vp>w&kF7{*42-mkLCOvK`#t}X@sk~8<^VfrMe>ovwI)_ ztkM^X`rb0eJ6fs4p81bcUleezPMRRD$%_c-- z*CyyPV%TCWNSVQ~p821yabD=L3oeT~B9AkkKXoM&lxdaz@|5ETu*jR1haM>|s_9;o zLoj058dv|md{~JP&&}2u;&Sz?geQ&R3Np^SgYh2>WKLX5;L9_&hFUOQJfEq*MJNQz zIyA|qT?Y<)ew~O!D11NLfGkyh;As&rY^1Q}l%2^;r{c9wE!Fx1OWXkdAg8SUW0$1n z%|O7@Icg`oTzm7PS>bNv2kBpc>C_UOqL=9}1&<_YB}MdXY1rE9|7O6$cEVwSMeCL$ql~|&59Td{|KV8i zPHy&*Y%OzB!k#uBsZP|=gQw3Wbk6ynB}ScPBVQ%BiwuMQm*jhcv^!q+`gt)85*YVu zy;cf5?icX?fuUj&nwvAMucvJX^jpX5Q{w-2%+^K&WZw>4CuVQ{%GWy|{&Ox<$NzCI z3&aBk->@8fGT`6lSIK0+*EiCyM5W;9D)Zpzw&3_eyZ) z86sjQM4LCijh_X%1zAl_d;qE17%+8LsIF*LPXuE_Ji?Y8BiuM1ufmh%HcvDPb3@dq^%}v9aRk`SXLLa=G(Z3g zUX?2}J^~&qp>>_jfnjoa^Vs*ycaPPPKyb2ohVTuOp~VwImHnYBo?YDiE?^$`i)O3E zwQ+2$BE+c3yvw9oEQOvw$C}%8nXZ_ioM6{*ar9L97DxH&M0sk*2BO#iPAayHJ%xC) zE5TU$7#xgvjv{{T*Z2K(C4G&k{YFln<{<*TXb+<{Ip(zF?L6w)}5O01bn6>dH&)nPscJ(B5$Ih|qNQ<`xLP;4ei?Z8j z0yGIWi&)%F3(dYrbc79MgC<~E^~+kwX*nin+O~9yH7{UC45IUpGWEGiv>R?T{9qKw zw+8_^1MRUvRn{W>ZP=>JR$>(E`ReKE@N8POo|w^>Yiooql?saKvAE?S=Yh4QOJyr{ zDt$S!NQYHU-DQ^|=1(gEX~6$I8bF5wfPdTj=?4L~Z!st32;kp-b)ykL*_%C~j{kw? zq{jgZ|G9e#!1s@>T1^2e-V(&PGk+|iHUr>!Gc(VKtT3x(EgWh#lxlE8eG=_;|8#uWz?Bbo;ywj0k+u zecX@dlaA99?_C9I^T3^9I9jvKsItIX#2_Q(p?Fbj(o~E{8Py%t1>vvCaQKDYHJm`O zkmI#l!)CSn$G=COWZ1usJZYDXHW_R(({cz85^}pWsI;$0cgyCjj`i%$GO)8}>kZGIg0$N^|tJYR9^qzjBur|{ICVkLU}kQY|yRWBPnHE94k zN2LW_2UWcMX}fd10ptZ%U;WQufxU6ho0AbZiOT{0@M@4uC!ca>1Rr`3pZhm(9hG=JARRx)C3?ev?3Vn~$tL1t{Id!le%yI#o; zl#NJB**)6~=Y$rbaWt54i^_GiG$3ejS;YTOABg>c= z%_O0EZEtSbD0q&WTUzp=qD{x!Yjv~NLFw9yRn~M)|GyWk4J^ zT>y=X>Kc#`GP?nF8CB2Mq~shYaT1({1KU$6dA^@E1t3?>S_WHVF{T1KfgXq&? z;Qz{z{2%528O_624G6TC%ufH^9`&0(Ps$524JzvKBNCwohIku$2PyUJ(YR4{CPmfF zh9&!3i{r+pe%B%pg^t`5I`=Z1ux#Ar=15Er&Qpd^T_{dW@<;N74uOSBaeTC&mux9; zXMEi~#=&%4s7<_%C$UWR8*kh!E0(vsSSge>7L2*)qc^Klr zn01w@boh4>Mgonnz7ng_!NTX!Ltl_bWbzGFMOX&O_ItY{Hesoty}Z04d<$rrn|NY2 zA8V(4hJCw~#-?7I*Xm%4w=F-l%YK%3h}Wom;Q*>a781s3SZH8XhHPJexC*iGQX4CQ zYLFsi5~O;o#aM}%*5|7o+=5>FPmT`q=3RP|;|ICdMa>mpK=FauSHiXtsg(HF9dvx_w@l|sa4vpMYqKLSQ~#TCWj*^09FC+ z?_Bx)WM==@48`V63+3~)@f2#{;=2iS^LM~%ig0xDaUDv%Uea&EV1^G4Re%+Bd2X6U zjx_C%n=36dE3<-fq$OJJOr@CfATjYQ*T`9J73l4n2JTBUO*(;5l#>>93J`eFHCBDG z7?mK6Nmx`ahZL(U>e3qnk_Yw$| zwuBtO$fAYzBhiC4g@z^CEXsi^S3W8wJD`^ul|5(@@I}sFdV< zz19+qdU_Bj4eM;F(JK?k-su*6##O+~W(9vG#!Ftqt6ktU=9xSh);%Vw2rSVBW5o2; z2QyR_gGfU?$uIg4nnv(NZ<*6G{Z2|&b+hd`opvF=1BiYp^5c| zPKJ3!&1XWTRYZtU(~+M1IBCGF$Sssw4z;KW&yDk@cEPdsto9R|ha_kn`xF>I23Z|o zx>UV<;}-s>xqkGi%YeFj(qU%EDW_&`$g@1i5YqvFt}~V1rwbW zxT-tvmVIk$#r^H(;-?_(6qEGS;KBk~^`POA!dKqZo&k#x0p_KP^PdDURAiiuJk`x< zfWp~@V9$5LeM-u`kd!Q@Mud3$U)Ma&hLcNlYB{Iy`!`>4Fkix}VH6EG^z{x4ho z3H}IMvvj1CEV{&={fkvK-nG^zyCpH&e&~sXRWmlXTwh!}t0}yIzK?z`5D0KK1rV$A zs+q!{n0jR@=hHwxZ{2LH$YYQT`VJVaGniZI)T}X<6#Zh%{nFdRa|_y|B7Gej1jrNT zRgjCwLx`<9N647eaEl4}$|ey8r-s)zBn376VL_;rr1IwNv@2JkJi(}gTBoB)pDvWY z!zB~0RXuf?#eB^Gl9V?o!Nr)eX=)F~+^G6dp&Aw?5piN-776!Qc|^LpF&e@h`rxti z+x8UIB(OFy9Nax{A?e7L&t0jc<#~*7(zR0AMlsts*+pZ(f6z7hr+W8j^P(EV3Xy*I8#mK&?7UL4%mFJRI<3fv_swnq{Ao0g$OpvrNN4BZmv`t zUd;aTz@s93&i`?M8GM9pKG)#IeDx$PKw)fG_?P8~x1)pv}d`V>73e0H*ycr_4@5)9u;D`5|bBEjLBVVA~jNDNyAXjqvuM@Tw(oBunjug`XlBf z+Xmdh{N3w%)Nrs$_!=9(ihWSMy704f7`VS&`2W%G>Z1N)m-|XK$SRyyafX=VoDbU~ zFS1IatT3f1FOfM>9dww0h*)S15^t3`s%r^3V7uz&8Mcq?Aqq9?yf@!jG74rBoAeD~ zUumY+n7CRD1t`SsiZ>5Io%4w$L?Q%TBtk^HM*?X{nG=GQY+;oJ?=|CpbyMRU`BK3t zSYNu}p3exw;Zrlx24>I=nMPG10zj&yD2bp#9OMqU$T%Zx@E+xF3O^0h-D2(t5rXFE zO8dDS5tgop9-mGcF*s$!BvO z^#y#GFp#AJ+hPHm3;{LoM&bj--zVm`me5{7aa7z&?FDHXamUoC+5(%wRH&_Gwt#p| z{_K3I!P{Wt9py;hLXz!EX0nF(YG60{o;a)K>ujciT5V;qrQB$t-7B{lE_)W!o$okL zjCmJFv|HJ(w9vLYY5aq}+e#u2Xo{}Sf=G^C4KW136F&AhOAcu-DOq3Ifuxy*T@dQ6l)Gi-(n{7nOUaR*P06_R6$NCrzkGhXPK2&aK+T z^ug_cN-a(9wdMnLhHv4!6%NQ@IyW0RGyiTE=BIaxodmWch^L{=D__S8(BM!q^ueR% zOAj8!uz{tj+;G7B5haJrJDOms@%Ov3_2&yhlTo=c0_cVc-UKmf9+{eT8)TO`5c~2a zxszz{+$iv2gb@Z3dU0;h$}HN^5gXHr{0us5AL>u#>K6%(hO)vbqfLUfOM-(ad*Pge zOV0mk-21y$BPMZoJ-7cFS4;gTu5La9{M)cUa`sw={X5SFeT>aY{#pWIM|}$>?k@pI z{{-(yR{(*x0*L(mzeVB3kb6McTb8bPY)Q2K_38L`e+TbCC!^2y|83X(KT>7o8pn2N zlITyTg+hzvRr!ERBb%xQoqVZ9%_X~1O4}LAcer1>GSRVt2 zgBn!);nhAPCgGVMg;~XIKDcO@9C&mlZAy(wuR~I&J04p3?kN*OBb-&9FWo{?G5HAn z=XWhhxSOT{W;D}6uDxqd;XrPUXr&?ZkSFLzLv77b!p%+IyDAgj4 zM=c!e`+xtwTDAP@!~i%F#u4=L!-^AQDQx0ZZB-<#7`)+@=8Euex2nsmYS@_* zi9QhOn1zwYf&_u7blrwCw6fE{=^ZX%G56uc=@fYQgQLT^;iXrg#-fsNyr`6njh%oF z_9@P~NnP@a#i6fnzH0o3*s+_g)zzK_dyBX?l&4J8iRjE_@%m8V0%G8U-vCx!K6ig^ zTtGjGYb01Q0UG*VgBfm)Sxi+-fV}w3535MR_ZC&~c63&_WM53>8)A2YUABZ%Ux>6> z>yv@$6>Gm;94__msMvSHJnrv*5q;!B83>z)mGc)0nU1PHeMk-xg^a>yb&NC0T_^d# zFq#!Rg?Wy#$MDNpY%0*<+fglmug5DG)Gj7ns1))|vM2^0@;(Pr2R_chQgp@*pS=(E zu}cytrerebEv9r)zZ`4Ys=a$)@+D0hiyafFqsoHDGBj+I5?5nxM%~q`f)nx^RLw`* zdU6hu%|qQ|xmW^{ArB6C zQo6{j`JF}RTaL3PN_H%k7;%=yy0R0boDe6isho=K@7ohkB2mL0UZ0Gr#I@Y_5qvlA z#d1Rixcw5os51MUXCCQXdrv|8 z!%(lk*>TVuCuCJU?yPyb)d|r6|5UU&P--wAtBUU(Yo-{Vk;`P_8d)L|H~F=oBWKyE z0|NW5f^-_YC6%oTrmr*vduBI`I52y>>Pm>TD5`Kb2`Y71A^PjkFYM?*TOwf_?ozPC z-7`7jn)IT4$o9F#wd_tRh6?w)@YOYa3W7qeTi2~E?|#GjO`Tuj?IrdXv1W?ZK+^+x z-k=rSK$`*W!6B$xZe{_4Qiw~T%X z#tk;{)2|h*+$=g%ZX8gFFo+@0(?Ff_=FW#oKUN5X6RB1tI^)vlZp@PNRf* zu5&w@M1Xh;emf^y+_=}i+MpsA(nBLEBLdj^wS zO@z96BF3yj;-`A;G%bO+k~Xu+dMf`$u}RFwLBT+ECWyv9vIiIU5B>r_`dHeT;w-no zCYLsP?*dn48SyK&g6i{eu3A4-<&YCsLwFa|hd5{GK zGoqd?lo~7fEQ`}OLV4QU?R9sfr})A-8EJxpK%#d99fjTg0*Yg>?t# z&+g8jz3=v2a6kS0pfa3@^N1NV>*f)Vlq1E##Go-*%YGB@XBEepevTZ9AxVka$+K4u7?ELPNNUal=HFCc1c6ve_(&1(|{r=9jtU-`n|KUHMlY zyzV7*%eZ3KT)$aI{63iip?X^;-Uo=Ug3l=(2H(mQ^%HgE#=)*B`-wJ;>Q5QWEAWZ_ z`t%F^P>Q_ZO7y|z{l_vcspTl0+s6=;^2dM>tYQhS*Muq0bj8qFun!_nW!)U*=1FT% z@%dmvv$|SJV1jyX@`S;^|HHrJ7o+)-l4f52hh{KfAl4B8E@(aTe@GtY1j7V2M}#aCK)$Q$5kMS}X5efNL__1eS58h$4hOw1!d|5_3K1Y&+o zy#k#qjU3HP|BHBH$ROXXofK6#GS75>w-gq?XpG)^Kzt1+^?_%Q=-^$&-~cU=_@SLij5bI_1_+ zN;w5fV$^Gu2dxjw_B7%~@>7-+ajrw@F3Rr9(uTn}paPn+`(oX!OZ-+=#RA+nwM-J) zfzJ;&JddZx)~r-Kx;i?e^767K7c3l03405j8tFj(r?a?;^PdWxWAdk)%x47=X>JI0 z4>L#0?~P?QA`zAF2ln@S_pgo|c`^bA^;=Ef7xH@`THJ5f3=s7=^W=Z-gLj8W*pC;W z&D@^)_~m^xjcMdACep1>d+3L%+)UgLHW^Bq>boIm!{uO9UR@g7;u*kRP@>>~hzg_7 z?er<|_r=)z@7ctfxU{TiWfIV0aj2$7{S{u)^}jcpg6i@(4Y+vrGhHiJt$@3Ts(m=x z+&#{(g7V^w&D?v5v@H;-XOgnEd5Vca*g?oy9o^foDu$t| z$={Rlyf7${++~{tzXZ5haT+3gVEO#nEcdJ(==72BD`ZiMbQv3H7 zMEHD}k>MGxZbbw}91IAP_RX3ShH63DuQ9XfEU{#yR$;AsJ-ZWyz|D8}^5QEeM18rO z37J`XSUDlND@h&K1`6wOj4}?8lX8KUsE+tVEs``Q3%Jyf+dKL3n0W+D%$||7d1@5y zKzRm@3sc@z8%`4#)|2lr`8P)^24}83S4GH`Zqm9Hza4t|vIh3*A@!G(O`m;;sp#fO zFC(=NM3&wYP_}1}Cw%Nr!#}aIQ?IPl?K0B-W=PPMWi;Q>^J+x5R>hw9Z z)FN5yL^65l!?%48esPZW%surXk_Vo4o07z?DEXy?-_zk=j?)$C&HYl|#BU18H+t0` zq%}LsI(M7pSM^8P}MuAfBCWd@1U07hyw$de^@9C7F6t8Q8E=5>K}eA=yx*&ZsR#F zl<8Y#Qj-Ac-#TUj0aX1v#!gPWN18~lbyZuKZDFAUmGg_y8b_- z&PZCbU*bgVU%S@O^fD=>(p_i0=ASKRo*w&MCWr8r>Snon9(&G-C9I zMl$^;D6}T8A`L&<|K6CgWNnMBW5zVImS&v_LpMvWqE2c;yRbKF)#*)C@9JhB&uh&n z;tZP6m8g1eBzvcMzoc|C-nge~p}BwvF%3ITEEI88K-4(M4h$kB03P7vvWq4?2aGVm z(-02sI$xY`n|gaMYY1Zu)L8}|{X{*bRh6{!Dp{wQ4JsuoJxxDTP%94KWN6Fm? zQdm2JuJ2pkJ&Jt_7wH@5sAkHSp3k73cfV4>AfB1q?%ec6g25LV1z+PU67m%?{4Lg` z5_~=}_>yeo2;>n+O}}~aRBMt!txGBY85@D$tjtkw-EzrjftA-s{k|WYF@t8Scusn=ZWs zAF|X%d!y#eip8m@SEPD#T0>+O8$aGzr?|YSSP_rH7+5e467C)W7Q&s3Obza27Dc<@ zwYDN}W`A!S?LZPaNqH%${jx?Ab2F*qK6jx_@J_c{C{b5qs?oMa%IMprO%Ewc-$x4z zCP^>#bcVagO+d`gj`-x%vEb3qUB$nGPP%g|xbQG7+E?bw`k`8l!Fmi^QSTRj?r1oZ ztY@bcngb8fe%W36VC*AZXj17-2l0G9`502D;(v`iX0UA=Gf`XDUMn`v3z{tbT8TUQ zWm+wKpSOSBpn{`AveW2rqBZsc2ICHAtUou`gxmLEMk_(ArSpE3vSC4;$u)dzFQvkK zm0xEid8vH0*3Rt}_#$T7do9rc`?su451;mL3UU6NlkgYFoXoY?!+!;sFd#z@NPKK3 zdlT!w9q)hr?tcL1Uvx`s;E9275dt|!L%jKL+6K8LmKy>pqG&2+&!%ejkAzoEK(+Yr z45Y_XUg-vXe5xM6e7wu;GG12eB_5hgU$3{UbV8&&bXfccxSl-reE(N%W2QXTJaqhP z;*lnBaW?)UjDT!*zA0-4d!e&b#;9-Aai2;OReKKf=r8?Kt5mi6fVoxK(mkAh{-+d{ zDiPS(mFWnuMq!n|yM`kC>)imm%4O{aVPc#eFag5pO67x8ID)U9s43Nx9|@@I0oU2q z+0lY1xTc%H_HB9ktB675?M++6xpDPZsOKPkov&IUUT{Cb@;eo{c{`VgGCGK!q&@;y zP9N-SPq${S+1t|ffeQA8ppDTh&^}Sp#!{lSadn{7xbY4ygiLfZTCt=wM;I7jCwcgz zVXa|J|J~O8(Dw1w6a(&k>w_5+*5R*cDGY|ba6f3dMB7-wC->h*o}Vu^wy!Sk&;?Jb zIAUu>t=AKeKMuBXhec}w5;LoMas#%h1^5M)1;bIuW`jPL0rdymZBXZfl_S1#+=O>Z z4}VVZQ;WRgiyXQG?+kQ@k3qSKPy`JmD_8jnT*wh;b_UtTeXScI6ZTL;g4(Jq4F}j; zbTt}3i++5`5`JpmR2PZ0Wv^YX@jhcW9gH>9(`c*GV9d3@IU^n@4x5suvV>D9G<4>Z8EvHsqugfx+lXsPSLfaXc&+M|G|`uV z2K_2}V$Sblc4}}L>n1d46&I+FWVXr*a+yIcBJP1snn2GX7rj&CeT61!X|}0W{+OL& zUpA^=k$#^!gJRg}lnz$DxSXs#{QTj+gBfv>A#kqSSiFE5^B$w6F#Yqu*OU6P_D`Z) z`r1zi+;s0~KM2YgHBtMmf4(aM8?Znc+COXdpwHvnvl)&>I)j1bZE5EzNUq?v&N5QJ zg!zS<}g;lFCKn)3L?P&68e3$eWwM~NOz_+N2GbNc39d{v8 z?CZuoYVQ1oRaX3Hlid6qfvrP=Xlkl3Z)~Mx%2$DZ!tl}3D$rp&w*b0b{`b%5gIc1F z#^az0MvcWLp2N8x#w|D2zgpG|NbS~wcyq|rV(XlNh_0m+t~=~q3pjo{nta@Nxm6S< z^`=Mu^Z0Tu^kXtIJtVE=#*pQ~H>K@dQfnDrT@`{85>hOJr!ErwmrIhVeoulW-IpJ3 z^3@$0nXz1~B`!e-6O18t*3vRkOKEO+GG)nu*Njs(PBYVVjWpx47&DKhlnPi9J0{*BL0_zj68@jQkC5oT(7T3STxQ}=Kxy}kE zEZsqlk;JeuIW;xMw!-Evrnw%-h*A+FmF&5aOTdH-`cczHKWc2Q708s!EH8!mIoss_ z(RJ2Aaco~6Cy>Dj?(XjH?(XjHfdrSqA-E6j?(XjH3GNUexD#}FFT20@cB^)(`k$_z z+uc(&_nv#s`F_61)2bM%g3HUJh65EXeVo=FpP5_t=I|gC!Kq&j1nI>$4(eBwgzGQCG`Ei>!#E9)t%R*YlPD5^3 zkAyCal+-h-zkbO$z<=xK0H4f$33;b602lVv6U6ME7NUZb&)_`$t)I-PpM2l{()S2= z&skYoIb0DBCx>g1xzQeJsEZa$luCNm4{VK;51nFyUJLCP4G(N-FIxP^6Iy=jm&cp^ z7uLZY}gjq>jk4=owknbw8-awW?= zH71{5MKOL8yJ$b}*)*lKuKzYT=wj}c)k?eJ;o{maolcB9buOES5#?)rwCCAOcP%1% z`u^3ydo%U5tKRxhk|+;38(aQ6laNDv)>b$O!wr}{vDP`op>QB5CeR6CKWjs{e>*&K zSn&mP?y0)_MBQ@#(ag?#^%X6HDl0ovr}~|F4CuB&2mT&wzD* zM@7g7Gs!{jqSF_e`BHokiWRX=rB};!L;?3hzV9qxc9qw@dun=DKr|#YaCCP2@UTZq z0tzUfR>&)YV!=9H(679im6G7JY38tr9}_cFb-a>w6rJAB1s1&TOc~ru_=B#F)^tJy zdWD~&9im?FF#YBA?3Jf<+)M^ykLc()mJd<$!zV?sNicDrI+NHy1uWT*7w$d6wxG3u zS7^1P07{{LqNz2XzR_@SykO#Qb><(<{N{mX!ukV%5lyi#b&6QQ@FB*^c#p66t)Bw@ zP}1pA&Q(#cbAL9C>J)r}^|aB$@f!uvMSs9EQSiBfeVOM_Fhls{N$o8;6?`rQ(u4LU z6U@C2^F?Oz{6bK#JEehtwE!sk;PGpX=#*8^R2kk~aiub4kd5=svRTuS!NLiB2?UZ5pv*IKeP+i@-Y7_o}$K`#ceDwft}|A?E~AV z^Af`@)7b;@^dbF32d*>3q0m5!5?EL*y;w8;*FoKF0`IqBl?x6Qa+SCTKotPf`f!a- zgs@6u!n~I*3vjSae=Qx;k+&$E+%pJ-JG+K{6)0|A6NmM4gt)=5Inc=`U!|ZI`D7Uc zi0J5L-jn3Ex(18$w#kL@_l3Jc&4%JM#7JDICV>ktF2!E{d zl)gWFw(r1j;HFTqX*=ufxx>m_Dq=O+m|=xVVc_B)=}A3>1GF92p| z=DByV4im=Vim6l?rwJtRgn@`}WY^{s^*Eu}eN)gC<5$^j=h_GCLLQP31{QNoZo)~ z{q7>)x!q%LD&Er{()PRp*RgAn#?m5c6#GK7K|6=p$j?<_lj^bu^bE#ktERc|W58BY zS4BQli`XVdzu#LMZZtxz8p+i2kd;hs-4CXVu(O6rd}4}9^cy;&iFBN~S<%bPCkbvt ziJ(<07bqU9?2sV#{>7w!{K(c7B1fjfiJ$t@>!DhGEFc!EFAP3BKVf2c7~vzDkSbQ5 zzp{*mY*gJxho4uBz_RK|T}ia%^(B)Le2B9k+{HXl)|N$!+l??_{B(5jKnHeWI7Ap}{+m3y+FlA>wA0z>%wZ7sc21H14@=0BL|sg14|oMd~`hL*N|z zs81&SYho_xe1XiHM0MusP>%A)Nzg{!-agMrQZ*eUCxdsAa({~9wclg%o}adV?xwY_ z&w!_)c6sm~#{C0c;s?n0&);CcDR*sy$~C)J|&y*>iJAUusF$IA~rh~u7eE>=#0JgzWWD9nwz&v7Ng z-}3a=m6E`8W`}miC*al-;D&70f?!Gwmsm#EA(-7u0C$Q#!K8aGLYqym_HwTOUhG!$gW-pJ9?i#1BcsF>Z0Wr(QmP}PrX!QD zk4;O>4V?|A7WsJ>7-K1mQ^Q&j~Z?vJr5ANt|4K46`zx1hXrU`?%0`Ac(D2#D< zh|9c5Fl|m*DVGv=Dp8?#+5+aPV3M0#!#!V{vw&rFL3DdkAG@F1Oj0<};x(*4^wj$* z^B;T%cA{#B-0AY|89_3A#b`?`<9k~I9q#$F!3wmlnQS{0|?!JAq6DRWiJLuCRuD1LqI(ParQr069=v zambDOu!}@86IFs^OP%t1(IN@jjg)hl}6T>8EdizJ%S%KC*^3P{o zM({WNkvBVd>tV#gu@{+uma;mb3^t)!gIM55r}klv z-7{MuG`o2Mio{P;9i>o8p@KsCcB62>0%72XL939OOqW6u>nVYl;^4a z=Bx)b@nK3Q6kf#wS3)1(eiWelZ0fK2(gzB2T#a!1xy(1thBdWAvPKf9c^PjB^46IC&(&b|t0Kamv8)rsEx=9%+=(}vL9IKMl+eMWzRhH+7j7B#%G&(#`K z&>C3V;Q)JB^Q%sD!DunHU|`*tV~?#d8Q|{9tjbZubi+BWeh@0WM*s*n_cJ6_R#k`g z*SI2FEg9yfbX`;D>dbYGkRKn#WxBFXspyTW0pdZyxvfdc95Fl+4fdAi=pLG$yKk6`CQ9#I_I*bMS^tt1E z#YP4IGWK}a&W?!#kpI(ovLg=o_9tcQAO-jb*;66~0Q|}F*2w;A&@2%< z2Oac>T`;W-xc`$c9@Y5QSD-Wj!+%Da)%n*A;B*0LP%wX)QLGZ=fUAS5OaS!%p9w|h zyNTAyyR>(zdS>Qm*?|fRn%GzbYb7?hy7VATPGw7pL^hnUxDgQyD;8PNu{(!q}Tx{ zDU1|c+Q;=Zf7Vi=c9JwrY5}x%txc1wiNu#W5jGe0V{e6pY+{JngSWMZjj&3m@vGVU_0uOd0_?L8CG0QoNR!lQQ^E{~UJ!2$^ zT&mk1q^RgI(FX$tNKdN$SZJJ(oW-)hU)L^jQw02>Vunt5xCl3PCnQ}&RFL9(%xJ-{ zIIYOyD$pCH-u+h55Go>Q5xdv*rC*HL#_q_1)_je_+(;CBIq>1(Z{YR8Y<7@--6wH3 zkc5eU*ftQtN<(GPmo;K}s5W=L5q50Ukv|?1x*`RKbvm#eMA9`f8o%}K!`Yb!661+- z;m-RX+ytANAU}6-8fNj~QJoQglKwh$kZ*fz@nB&lFQLf^>K}#PDS(-`R)ZCe!zdh& zI;hB{Mw;<`alLtrA@myoPc=r+l6sP-U0?D>-ZYqErtIzoed##k90Zk9?M1wvbLpA1 zVZgb441ASdl*>qqbf9eB8hHT$BWGyD3RXnFpL6TapWvlhBi%}b*aLcfJ0(aS$o-C&BhKy> zsi%8T)AA_uq12R=k6d>}bvub(=Rizf%5;fdUv^r}n&eqmxISoMiQ%Q}jxQ(NFTJhi zGj~M9Ri+<8gOXbn&<{}*DTb~x%Cg}Gywf2v7-gTl5q?|1Afp$!Eb*K)=~z$>Mr#)!XNiyBgBxLp^Mn5Ve$yyl$IySkFzBA~gd z7S%IT4)BR62`OXUX=k5RjUS@P61q`SL1b#iRLSYGZkFLdRhI|b3w+Fw7}r`{2ya5Z zToWtP8~;(CVbkC)>n@k!@d3)O!ZYn&H9J{h7+K^7B9>6yX#Iy;f??JtHy zNJ7@isqwmWNRl0l0exN2XBF*`2Tc_MzR~qs zdcO2<+55>wkLu{4h8M#b>FOh4mepXzx|CV#7=y_Z(uWc7o9rL7nHkJ^s@|DA0t94a z+!hHb2o0j*Zy->FN@$3P;2xYM{L1T}y34@o^5y*~)77XXv(Y6%a^onZg(c*9CFerw zjRZtpFD7aTuC&Pxh8aNpYu?2bLb4&=+ zPfCh-u8>HRW{KqR6`+`Z9Zu-pd;sVXh>a7*;5nDNM0w-FE*cj&$6VrCQ*d&dMn1% z&MRYcD_{-Odilc_!$pH#rNi(r3PFS5{($WRxxk+Za}C4V8ljt;OzFQiamG|5`ANTO zj3(Z{xwuXb4L$=IzqYpI6VOCOE*NAzU4a>0*!7v;OZ@$|k5kvTge!C@2un z8UPRcf2`A^)YlzWIncTmRgtJ+M@z{W{f~!2@JV&~iL~wmIrRMpVT8X)a;VBINYS{~ z-MT8)t@00Um?_qYjwYLPK5a))WuEiC9UNjyqhbCw5tB&|u{0=Cm!OiD)wRh<469ID ziD$tKgP;ip0wxPCJEDa8?<~Y24JKnylFVr~;~B5jCVyzu572Z9ixr~J*&+K&UJ#WV zB`531AkPO_L#$JN#PMb5U8-8V3XZ|ZyVlA`XU z<8uYfRS(<@M{t6wkDi(xk#b)O8-r7$Jv%X6qqhuzOfSZC55L*r2pRjbyP!kaIy`1e z1&X=Hx1JyGmT!Kxu*M{FBy?%gcBgf=i*$CYIi5XWg$t4-W%|%gh5gooKMxU|kBJ!G z2<%fCKysF*mykaPK#8wXKF9myxW$$aJH}JdJ~kemO=%4o@|XrtBcGp#PSj=;erxJkQ zPZr!p3J$??ibB^@#JV=B=6wK*s61p>SHUz3tfI7W53G_U;$p#L*0EB@@RyYvwiS|z z0O$+r)c}ZUevEvl0fk>y5(#y#OBhCE!p5#GFcgv;$c+g-brH%fX4Z~G%uP*3bgr$0 zf>TKLer-U@5PdDD-j!RLnkAlcq28%-jHz)FOdv757*!^B>6`kh=sj)LYEI}DeHU>I zd|K};af6{nOLo6n@Roc4Z`Gw2#&@QLQXi|xqnHKr*b?LDlUwrMRVflKojA1-1nOVh2* zuf-yLRu0kWRcrJ5l76a7uD;q9PSN#m-8T{N>@W5HnJktCvMLs-8QxJqZmaL&bP%t| z*OVaRgtual{w-hZ_or^@dEzg}ai)&vrw&iJ|GS&P(EgwPgysx;fWn{X^wjBJ(J8Gn zfaBw*=Wj1!_dhi0{&I+qLjpOv0vLf6ZHuaZ9sj2rVN!F|VO0XjXHnB`7BUfBb=%$p z`4{Y`9Wd+phOqfPVU2J5XBFb<&9UQD4qJ}YS4-#6SBClqXbE}v(!zvenDOnF7E@Ch z_zc~WzeLez6N5(w;gbT&9oSiRJa9-i4+^QiT=<|3X#>;X)F^TX0tkb_ol(&9m3ia( zOKMZ+*rMmnOfTrRkB+?JP-*5m-U;K#5`&O&aUEdUN!-ZBX^|47IB|JGmW~FmuykZ5 z0L^KIVSd4cW$4jypwHFwGU{6lXnK};EGY>|n>m}`lPzod$MNm&uPlr|JUX151TLo9)4(@oGeP<(Y~|lqfnNCz1eN+RZBDGp5(w3r z#g^4mWW|G_kDYCaEHR1LWzsU?`X=brAu@vn#5+1!yVi25*f4tPi@j>!Lgm%x;dw9c zCJ<_p@^#Od`;**2CJtZZ-Qc0pi%w0(a|ar~CIGpjPf=FbVaz3bFjR;U96dNxD_mW% zLRU~WG|v*b>YFUZs7OkFni(sPRYj1jhcHoD5m+R_+fc$!!^?B_EI^2)SRXfi$P(=h z?AhaS1qZ?BRg7^-NogJMgf3^hbQL2`7lW1u5d-}y56PBl*iCJlCh`)QvXPaqlhx=D zj)Cs0(hz~(^-aaGlzVWjqgy_C*2YhVMIIg8BAax$2w!(h^phi<@~KlXdlZ&G zwo%AN(w~jmK@_GeeHcny&iI9=`#`jeH)3qK+(Gn}oN7D!RhWk78;LLjY;rLskzv)G zI?m{J_YY%X^PjWWdN5(E3h{8uby$z&QPMzR83DR6{4|KDlpy8x597xE!UzemLN?K9 z9B^Qf`f0Yd-^0&n)B1}-?&sEs4Bsdx0UwyiWY51_}q3 zi_p9pzN#MjtcpHu4sW+dRkZwiy!H>f`31eGmc%v&R+p_R%j>|PukTL~d**1MD2*pU zOeQWN@De2zNiZ&&xK>*e8rA?d-ed zY;x`zM9{rlN~zCzJ~Lm(EyKJuGVL!Wz!uu=^Z{8=M8)`&xTbA~t)(K`k16U~PB{*1 zCqF*N1>>O`aiCfV2qS6xhD34PP7lV2RGK3%znAclMR86lV!Nw6Di$D+&|qZFX?KT5)vtE z4F*@&BP?S!_c#tIZk|MemEgWlJy7M$@N`o@uuWplgju!nG&a+9BV`6%8YS#ZTBJMw zo?e6^eX}QzK3=R@G4l@bjq!ia<{+mQES};I(zQ=0e(0`gtZA$)_ zTKzxzz9e;f$Be&I2{q1@ej()kCl26k?dpX^_61p0GV{LD&dI$NPJ_Dk^Y%LSz^COU z^U0!bIt?bh*L?3bl|%i6Mt63QR~YjanE?i9^{kCMXcd(og2Wj;C5S#Yoas;qZ7O{u z2iD{TFsV5WGeb(?O~PC^RjvMn+Rme1xn>N=)oYk=%IFZu2&8SG$T%SX#W>XoGoXl1 z#Q3oNJ3RvP;$vP z`I4~HZCQT2tL^M{xEWMfLc2K2Ts5_+59~~Mt?ouR|K;qZ(MpX4KK7YKqXq8fbH*W= zbl!uU7ozKiO^4D(9Uf}purdo{9hdfwc>LZT+c#9boZpvDCaNVBkOOR(@h#)B={3$4 zCfXUjQe9Lbx^CA#5jlAzV|O^xqf9MglW8Bf(5(}Lv^S0Vlg=6Cme@z+HU@R!yx)3V zzQ5v5mUwTw8uwF~FqQ3CckAn6SbgeWqpg5Ju33q(X-sj#Z_->X!8jYZF_z0n3RPGYqCH zH}7UG)pih{rJ$pHCiBixx!?rC^J7AIf?>{?%2I4a!h!V4jqm4n>oN>uD|lemnz|8p zZJj1<5dTzG)3PJMPVsYl^ao`|om(!{3d%>Nz~Wtp04NSRcAzmzeE-58oSH!sw5V29 z61`QRvby}d#hJe)3t`Rn_Lv~FU(2zSXU_cXM4EN&jS%Are!YHg#fA8|nPBO|V)Gpd z7Azw!OYAo%A>4#RwRIEct0AC>ZSm(6#c&^Jy~D9~XE(x1$%=5d&7$HZ{teeO@g+Ab z7?Y_WY}oBIXhjLcp61GPMHtU{;$J*-M%6XHa`iv|E)9U(PX)rUO_i70$xye03ZVNx zs>&>V@6Hl$=CzC*QM9?9Uv{{io0e>uYSI@~KpL0js_-g$^7$h2GF-%ZDrzY*$_{>y zml7b==HYo0QInl-?n5?TdHpZx++Y7*H~Y74xOeb(KJuTPR$(aM|Fxp+)b#qR5A|1eM(w#TQIvC@E=R9a zDb-@IfR~49(jZG4l4apoKxyNMtuXC>W@=-bp;mDhnef+IuE@krFl_!2G%{fs^piZWAh zcf`qPu^?l)uQfI1;?I@7+H$99@1!;#viaF=J}0-dzkG4Qm$f;jAxcKolqJ)Tr@ni? z**%fVIq5_EqrYp8j?Z|7L{Sn__VHKeykk$r(w|CM>&Qyc8v@oqRLMo%==IY>O8xdl zaFxz4a#H2B>C!lC{z z5D3$P23Uu`Hb-2PFG{BKb0~({Eh_ay0Lqnx_nw|#Vr*T?i+RV*$D6!{GhMp@Jsb`5u?S`8D9p;z z<1?p=ym$^#s8rE z(;ge!kd?%jBLlfz6^oVSob`)$kAjUA1Uh|qU-cUtKAUf2<(Pe4kp8&%&9R<+pSE#C z`?I>T`0p$P8-~mAy$GINB$-Ad4dOOMEX@i3yl;aZl_g(|b1O`>4YqAH8~2`Xz|5AV zWirWcf#7LvUX%tTy_f)kn0GBWl4$Z?l&BAGdle2fhghx!K!8#p<85so!sTwbcSnkM z1Yz#3XMtF-_udBP_><%p*F7bWo^e-Ny=L*nD%3-N*cb7fN%S7<9!FOuO$=~E1Ie`K zvScGxJ<2d6M`&A1azT)7u=|{IGPTNjp%niopxTiXJ-*KO$Y!Gy_bxbgXS3N|Eb7?$ z4DYz|EHd0ci278W+@kXUA7p>4-(Iqt76}3>TYFF6?%L9ikz0xHS+Eu$I0ez8t|X?F z8tFYs`HAT9`L%W741@bx&$BMR#T|;f1q;LDLBJ^xefC41%WCI^_6+jD-RBboW+UZ9 z0hwUMs(|DEjUg?#VS}9Y7V@F#{Uvt*zI7}IGkqM(-8c_>Ddq6IPs=`8Ds#NWP@<5( z=$*{QKBr`O?io>ifQrapL`dK09MvK!S$<#->Ffv(gCO4yt-$(JKpO8A^+U?7a{yxf zwf&U>uVHm#z^=Bpu+g!}-FRGfwh?6}3#gN1WCvbXy1T#rKyyTTeY`}3CipjB>Lt5_*BhC0r>w@ z+d_{9yk~O$YCz}Gf8mt} zK!o~lbpj|Z58wtIriQG2*9qL~-1DKk88#HuV${ta4PdK>Px!qh&7QtwZpPkI;0Gw) zY=b!On`hrMX(I@68#2ct@|5oh-b_1=^w1p6?>#Tz@9Qp<={a%EK9l=C_sz-KI=uhp z3FEbU;Y0^at(a7xQ6RfeV1G8m5W1|;r(Sm!HKC-fKxLpi#|ACpjb{ydA)ejgk7Lb= z=?=bDriIb{@5i4r^opy8rM;7eoOlRgMB4DOWBO(XU9|e$;hXWu>3%@-aUF?$BgWM? zFx=YweaHeoZ6j44z<`s)H<7ftRVHrD|Z6YS@(O~SD`adg2> zGxUvLu(Y(b38>IT$jy++lr-To#UWNpVh(#NAeh-FuqPGkM8eTnS1CYL2-K6v420m4 zpiP^>`0z1~b(metRF20xWPjzJ?DZ~3 z-*{aWjh)n?c-Wm)q4Q6>*Io0t-vTyMfv{C+r82;3u^t4O=x3c9F+egA&z#2*zwLdz zinWuCe=RKEludv#Seg~uP*h@n8l6{8V_!&ivN%%Y*-)@e;!G{6e{-*ZCHx@3`zecQ zw~ZZ$ui8$YxH@SYp1$ev&GXJ>n3eT`3c7rX}*vx=2l{3*@ecsCFX$h?efm*s8bKj=(L(Hns$OKVj95=rAi}{5cR|^4946%1-z(m}T)jHvEc=9DNu&5vwTvgN2 zv2Dl61iMXZp8E%j&%BQk=>5Qtpr+{P6hJUpu)==t%n> zHL04!6Q@GcT1Zu^+M+S`2w?=)rbIP|;v#vathItj%JvE!2j(@#JE!*zy}^=I3dj?< zvh5hdNBL?{3*^H5+Hwxa{-3lN&%2$2 z1;`8?p+%~v`x5M!I2)#`+Oa&#YfX9L5RsvU;&kwVmfEbs1H)C!A1padV z$EF5>5UQg+@~TXS5axr{aqNP2M!thU-uI+_KpQkm?T4d95z{PJtoM3 z=ba-F*DxCn)4X|W;(R&c{u>XQ3L|{Q$gKugr_o=|?CybPi1sot15m-@)j%89ew0p; z1a`Y{`HuoCx8iUnfS=*bLcVSR9FYcN6ky{unN1sM8_h(b&KS{Cx_;E-LbcVv8L`zQ z4&EnI(c2f>h-6%fi+b^Vt5A=R`D)kuQGiK7_OMBA24NQ z@RF>Eszphy>5bDzWvB$9wQ0o}Mb;;jG?Ub0)C6w6n&25HR^VLQtK?A5ryJ4wE1b^x zERLi2n4Fds%%AYkGm8a&e`*r|vf>3Qk~A*9Fs=?8(~{c{Ovn?p9}|YWu}TyzIW(Lr z-ENQS-mLUCraFa|$;)q;IIxgYoA#p`E7DMH?tHFlFdIjCBNxuDf%a8AnjuR&X%Fz> zDc4#20nZ_&>8#J~hSg)k4E*&B_rJE_VwCZXYrOA!ZD$a834r!L(=1yFK>bgJKeGH^ z^XWi2;OC#&x3UWGA1{OE(<%Tu1xOc04K_c%SkA8>`XWJpfqv^M1)A0N(#O4SJ{Y zVl`ik03QCVCC4-WdQQq&K-HheUz-0{(*w!^zzXK?1<7aqU;4O~b%4j8=WsO2!k~Qr zNxVM(L3DQ3K*9W*lWxBQ5dJf6?cTozIN5ubr6bsP{1)>JG8d(Of8WKwNx({hQ2^K=p<}%Kx!`~O~8c-S6EaK%(JxOV?Qa+Mv zee4CxF;k?BuzO^ELAdYs6b?Wmbe*{TMKjtzxJO3f)ZtLBxpsx(n<)+Yr^T(7gmBD*&jsLaL!RN)rW!pi!Ev+V`l z1^Fd6Q7zw@zF3B}uaS>CORl_d8UUEjIEuq`&%!KJv;FFG&0H7*!t@>1VxlDE3c+_-&rbeFizH7ezkJHpqGF_c#4UyDe$IBySj)B)YOsi}%wQZeSK&8K54n!Z2Zd-1)ZIMo0f4e=hoj}$+ zJYpQ2o+WPE2EIwN*KLqo+#MZzX7dH1Q)l5au$J#zj-68h^I9=ZHf(5apeto3Kf7yq z#pO1N;m%Ad%b_FO)6k>2;KUf5yXY`&$?k!rbfw`b`nt1v_;f&N?UfcVe=DUn&9F@C9=IX2A>C&hTNALYGD>o9KlRZ7^JAEd z`YB)QBFlCAM9Xtis{9uM*m`e2F+#_pU6oLR?ggw)yNYNX(&ryX!4|u8ugkSSrLM5F#cW~Ntffia8Nbs!INb5?UMl(bhEDn`1 zV8O&K7D&V4LL!5#UrQdG&3SPF;A{lMcd_*&H4h5}7UPEYV5B#1{d$Eb-6&e=XR2Da zqmrLXk5XRos#S0yG3b5<*W{y%g<-a{Nf!jz)x}Lfz3>I8|f(V+f0L%D&rjqO7t1%Ujld)EWSQL87$-i&SzFEV~ich$2FdS^zN5W+X`3TfZtWU&rx>%|{oNHM$1 zn!jL*ruNCZxZVGfU3TfWX*=|9wjhLi zBmv{dwHjYnc}BO)ZiRvr!N!KalrQ_#fYuQQ4VrkU+(%BkndHh#m&nn*FS|$lXCe5@ zjlsAP(QN5`no@@Rd-4Ukn7I7U9P{6X4F9)m7NutUj-)_)d3R^H?T;6d;?2Q7rh>LM z7u{hN7EV|(X|0`ikJz1ZvSJ?qZcg%26HTg^bKYlsF}%A?LW4FHoc(5kMarO|Vx1_q zmXNp|Yg;6Rg)3pKG{N+oxC``DfyPb>iWmXyMrjPptDr-3&hkadevDyDhLvOihv|ot z#>;;acV=$V(ett*(t6lFx!R%a>h2UHEtn8G{$8`%s1SPm&hcI;9wkXFB>w6{0Q>N| zn=+qp6dB*y?e5rRJG~|pF*DIfvD*$a!e{w5XHG%G7Fv=BsMVo0vIfTTS+oYICVV_C zE+CaS+V-m@6@iR+5#BVs!Nzy@tv<(x$JjWa2o|+TaaM$=b>Zo1OK_H} z0%A8Qe{{XP4LU5y-Jsq{kltP+r9W?=7?&Y7xt3{{H!-;vAmM;_vPRS z$C!5zIw`S*hiXMia2GHz$3pze9Qodk<_gYF*t|}n{uY--XZK*=okZygY9^Jub~P4l zZEFO(eDKO;6Y*qtrdF(^W2(fUojxP~0##}DFl})fofQr|*1Qg|Ijy>=?=*odF|5zu z+PyqKAxIL2Y552vmYyJK&kvin2n?^|nev#cDQG{0Y}Vy$wK)OXE8pOEZF?b$S=($$ zd-KKWTlVX0QUks7q`7!PhoK=4k)=iW+aQ6i`W9!J%m}(0Wm0YuRx{wP7hISfU4C&}<;b5&t@BGe}~?-wj?+j>VnV@v!B> zU~Gu9sKku5F`Ir}=uLMX8EXdw$|Mfci^Vyj8?B{~4GCiX^Y8d8<`_5&x9E7M27@sE z#2lq3|B5*}PXK1He}^VY(~*``?=c5I)St^L>Y!l%z1ADt14RDBIuV1<(0?%!y3$^1F?rf7~!Rdz_T?9e0!NunS7@rF^`_RJ0>cU7x?yjK~Bg zKA4W{`a8cUfDzmf?LdJL1!YN}4rBUEAV(B*iUx@f3^LlE7scb2gBi-W4jZIX*1T9d z4z`-Poaa(Vm|GD?DLO!uQ8Fydi~YW&%^*e-;@L1qHw4*f zFdb8pxRyUFdnuKH7_|bs5GpU1VaH| z@N%miSm78A7N!uPVI)F+fjrwOwPThxQ(A-2jt5Jg7r@|6)wFCUFJPMC)NN zYJJ|_x}H4ZN7VA1vlp7KBzYVOvX(eLc!M+oQgJ#VFGL+~rQkk2BNB9^`Mj(iO+62S z-K~%JJGuCJxWMG5@T=Ehh;8yvU_8bR_fjk7hV`+a%CxaWEt4P+NYdZ~GNQKh)_|Q^ zazhE7m+qciO(996zIe}bf)p>8y#cc?fy}pk=$7mz`o@EN0guZ(QWyVPSW{C_O27;vAP}g=AG7%;oO4 z6}sR0f@e73q#4lpLUiy4%YQKwLhQ#XUsC!(q=ZnjP&QPTQQU$fV}X< z5k&An?uJ+RuBM7Y@}`|}7KIPwV1`e-M|&l@kuZrKszH9-b0neXui81#O zLP9!*W@6ujtVX=xn7P@XzIyI$mfc~d`6(NpL3g_I4zKX$%#=38COZuYM`oruJ$EXk?0gOb{~ zOu{TU{)joym^dQm7XBssKpx`Dx|ffuhr!J(OQ-n+DP>#C9fzgvO{!n;0C2oK@TR8L zYtt-kDPDY=2`VCVSaasX^9OUK4SrOfEXuu6nylW|**!0ENDgUgK6_|A=HER2a#G_ixREMU%3Dp+V@{8cFnEG-H>{jtP@M9lK;(6h3nqhsoE$g z^Ol-9j+3LKFsVO4j^Uv6bYOyJV{w`KUpQlV8ETi;$5`oxs2l%0yQ5Bi(rwkxZ`Tg^mF??`9!hHxG6>$o*X$73>A z5pvgROuPjSXJ!|QD}h(-1P(Udgjk0Gv`Q*Nrn+&x0cvR2-Zx+&L#?iPGUI^KH`W|_ zdmg&pCy>244IaKuU{pGt$aUc)!W7=34-40<=d|=-CGR`MmjPq(Xz2wEk3MkYx>Js> z-t3A4LvnXlLCg%N>ode`6zyv8;q+?$^isQ%MY_>htQ+1KbH*oGo5rr^?Nf&^ ztrFZo4KNSc9pIhtqcu1mnQ3QLJS6)^WO(j9w#QdE6y9c%NsXpprW#0KsfvBFN0E}Y zr^~n=29dD~deSqMaB)1HL|c%xY>ESBNCIQ{_aQc(S?d;h+2+xoH}&!Tiw9-qRRlhkvA_+EjyGo z(S9r7;{sCr7Pvk%%<#&d639Y)FZ0t1rw2RN1&mDuB+wGQ-pajdYm_uoOeUK}bDekAIEk z&k|!Z_?Q?pT%xRx6bUg)fPvjYdoA{*y7=t2Jp%E7A@W3KJ0})WKQq1ocbFoALs22I zDzyfx5tSW$ev3O;&_GXEmWAe-e4$wP&ZxN_kUlBBndNgT8gr^EI)7)!mI~60Hr}v^ z{RY%J^~4E~`QfU5sXOAh40062d8$e#7?Agz;xKa-?T|~K8;?(kE5N(Z53|4n>SC%Az69P_Im&iNZ)C z=K~(yv|fEXpYJJmxGdIbiN4XIf2fOi;}k9xSafGD;^#O#h^3>ur*EjoUG0J~fOmkb zVy{RF472#wEryJ+_ndTCEg85nsK5*Ia>hop9r>20CN1prwdka@k9LK_~`dQ7wzx79v;xz%-;Ne zwxIdeYpQ=8|0e(~)OhdQ5$B zu%<%ji(d91vn)-YIZ90g?`SO}HY2hFg*6#XkSX!)jF@Mn7mTctk-$gf{!B#?XGNCx zzB!G}Iy%8Vk(}zpfzKY>c##W+*dh0~r^Dm-8{I&lnC-x+(wLf^M*b{4xh`i&T)lR0 zNw*URFjLvtw~^faVRLo6`MmncwfD^#csY$J{$j23Sj$SVOsgh^E~9gJUF>$3^I^~| zSGd<(W(ZD8;b$=x(*qokPxp*MRx1|!a#L;I@d zTq8o)$d?%}ei>1U)bx;}pRWAra>e5bm)=e+1l`&S1X7lGptgk3QZF8#Egnc>rwp4O zZ*P|LiK1%{sKi1V>;Y1(G#G_p*wzdNf(oIOciS-4dR;t?#oM3l)lFyeZH~yk=+)hH z*P=v11Wa=g=G?!jS!yMvrYnI84bN%HWKc+q8Bv zkEi962Ev#zXosIlj#xq~E2T9VKRO<7L51GrQu_ACg3?eNCD<21HPz+*%>L7Q6WX|~ z*R}&a{d=_uue%%^S3kS_z{IB}TGT?Flv7&m>vih?qU#-lGwIs3;qb}?6Wg|J+qP|6 zS1_^7iJgfjwrx#pJDFH-o_)XX-uJhwz8~E`R`pt4)m5wdSm$|QbW&F5#_PwzsoSa3 zA~0x=HqmCy-t_ds$9BKsYUkK32(?O0IlEePObbSLlZRTKTWVl_;=vd~bJy}+Xp!@n z>UKEjY`w6{!(Ry%}6pDO)c7RaC7z5yf#f9pblU zC=l32I8Pb+G0mBW!^8?7)-2mM<9nv3mkR{iq0jxkr^cSv$xplOQ0c)wTU};Zy8j7F z%?>=*f2MB?6|Xc~{cT{|rpmS3PVS`m$&e_)&`~kvHs0L|Jd5<$-(=}l(6_Bx5<}sT zc>frXQ|tC%9Bef}V=J83$XQeKI*r>(TC{UNoV2&d<(J%7+lSS?2$2*2C>BX8E3LC4G$7O} zI2qVlfW$*|qqfRDX6yZAF9`1i!F)Re2k$|EzPspgdOtu~8H!rk?*$UWEe+J8uX*Ay zj}u>dqx@i6d7+1?(-z5~}o|^d`e9wK2Vt@2O%=wBL zwh$Yvs4TkXbv}e2gS80( zAFhV><9wMe%2;ck=@h6_>3I>cC4;UrVPbPQy!19z;Dp}&0MZN@bWxphAEF;IRhOgcDY{n zIM%+XaUD|X6p4cvgRvyKm=uxrwsQ<+hoZ=S0LCTH1_N~G0@*fg24Ug;cs-c^C7Nr3 zD2nh0Jjmr};RtYHgk<*5bB3GK%gZmRKf~V}Ob&4k!gS2{SK+WMLvy=!?}bAdlW#{y z21kszmF6lrH$^2b*wZ*qMQ|d8XtkxgOzytx)vJ2S*WPsoaHrDFsQAm#*OsK`{p#fO zoPPW5Jz!~B1M(+8ly8Awe218yxH;3_-^X~}TARhHR*Dr!M5Avo{zUXQKo2YKr8HZT zwF&TSEpd{}em4kBA3*FytJt&98i;UEK%t$F`N!YUF7yDbHpF@MhJ-2L*SU)mbx~q} zI(5oc2kKTuo>L2(t?Vi3*e{!DZ~?&GOk3BNb#Ik82hMaO6@2A;UE|t?Hb|=*O-gYg z-VmGTm9sz4_a&Ar!59=`p+{4dp1iE36N`ZT8 z6xDZsOXf4D@GZdYazUOaM>$yTbbC}yaDU@%QXhIR~VUrMTLfo5}o(xr9WJl5I zKCEd~>3nA1=?JZZ4tcEMxP|UF39)+O*Wdj3J$gaM>%nasFsOGLzvl5%zVr+(ECmn4 z#FR)7nkSarWBo!F@ZQUBP3m_72F3yUjARRvZm2Cb&4v@vK=dubF*|Wd11qTEdpW8v zusMn0^Oxq;As-@a+gLGyZ92gqk;zS_eUlPTBq(f^;cTSFFUT70wKB-sxwarF^gCzpz?xiMs z2v#C;7+iz;b~C6⪥puhxXmIE3B1!2Oz&(2n+sf+I_zU6rj?lF}Rrzkrc7J6sb} zNMedE#nfY@n$y?6&|EnE=YGc z)Tlo3Uo$--}RYF5XF9CWkSEVUningudsfRrw_000e8xvh}60P zzMX@nqC6sPhAI}aNA4E<7Z2j{H5@;uwLCQYl<<8KA831MeLPmUu}abs30;l61o@%| zBGeNBN1}eE@ExYjL5q})c8c1RBC*8@OEG7JdCRJYsA1Sb?ojS0bYoB9x-1iTEl7u@ z#=iP66RJB@QTSdgQ`eTvKx~D>&fYSCpHn=0Q$;+P9zO5(xpIf#0H*;^7!c~cwM+ae z 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
  • 5(E^awDvu${_T z))KD>&g1XwZfzli4&K=~I2u<^3!YWqzO7R|oCY@X7sBywmBqIId_w(k;g$L?saD#F zJhUJaBtgSk^S%F)Tpn$$AH`~20k9372te+LjOpB=rM`y3SYHMbj2%t z$Jeqt!m&=m=`OhE-0rm&6cPR$FzX{{gV@JJPgiCu+Kox!EibP@fX1?pzXeJ5*(UNatq3;vq@BVmALqs zMS2nGFk9d#9_Uh~H@}5LI z{Vuyz&)RND{(OF;J4;)dYhe5fOWM35tD+zNYp2^{Ty1l!H{n(vdK8}7_{N3sPeS(v zAov7pVZh`=Cg58~_g~Jq3rDEvb9K-NS^*^#E{9YLE>$}t%e|!77a@Zou9utUl;{Lt zE9ka%?6jK`-Z<>^E{~JS>U_K}+r)W2`Oi6rMgMhg$?UG{-wklCwJvVvz86ctVQgmp z=Q9xlnX*}XcIqJvLo{sL(9QW{AuN^yu&spD>f{pEb9fl{{TT#&&<>}yh1HEq=qIIJ zpzl9>Yvl9!7aQ;btm~>)1j%A=~hJn5^9CSIr5#i_D~$T->)A z!b;K&)Gc%;$6o>v=HI>}!f2A$Xi4wQnm<|Tj57vIZSu0#;2c$>1FGt zNUMg-lKuonW>* z5X)TBYB4=TtjjS8Zk%tj9ahzI@S(=21j78PO6<7w^SJ|X5Xh~m>H;-r$}PsSPTZiq z+bhvcK^I-c;HzPsaOm}r=H^nI-29(ENB6Vll#uyTyl>FFO}oIO5nF5jP1cvZz)#J-klW(u48m&$j~$CHD?Zluf6(nzK()bRKc zU&6w6ZW_C(--+e&ZnoNXvd{|VDZ={Yh30U}#=?;5#%70cCLw=h-9&%S;F|tAMm&Ot zh#XVw@;V7Kt>=x3cKS-dI6YHjJG7mss(2s%T?|zBD;2@~N&|AU5qy_Z1o%g86})zT z2uP&MlD7(oNPbjqBN^q~hOf=f89C$7f
    l=1GAIYKLrX6Mb+0t?>8I9~O4$K#Q* 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 YiSUsgqdJ9u3g7iQ9$w@HP`-Ho1Arbmh5!Hn diff --git a/youtube-dl.1 b/youtube-dl.1 index 26833e8..59edc71 100644 --- a/youtube-dl.1 +++ b/youtube-dl.1 @@ -29,12 +29,6 @@ redistribute it or use it however you like. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ playlist\ or\ the\ command\ line)\ if\ an\ error \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ occurs \-\-dump\-user\-agent\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ display\ the\ current\ browser\ identification -\-\-user\-agent\ UA\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ specify\ a\ custom\ user\ agent -\-\-referer\ REF\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ specify\ a\ custom\ referer,\ use\ if\ the\ video -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ access\ is\ restricted\ to\ one\ domain -\-\-add\-header\ FIELD:VALUE\ \ \ \ \ \ \ \ \ specify\ a\ custom\ HTTP\ header\ and\ its\ value, -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ separated\ by\ a\ colon\ \[aq]:\[aq].\ You\ can\ use\ this -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ option\ multiple\ times \-\-list\-extractors\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ List\ all\ supported\ extractors\ and\ the\ URLs \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ they\ would\ handle \-\-extractor\-descriptions\ \ \ \ \ \ \ \ \ Output\ descriptions\ of\ all\ supported @@ -42,35 +36,22 @@ redistribute it or use it however you like. \-\-proxy\ URL\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Use\ the\ specified\ HTTP/HTTPS\ proxy.\ Pass\ in \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ an\ empty\ string\ (\-\-proxy\ "")\ for\ direct \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ connection -\-\-no\-check\-certificate\ \ \ \ \ \ \ \ \ \ \ Suppress\ HTTPS\ certificate\ validation. -\-\-prefer\-insecure\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Use\ an\ unencrypted\ connection\ to\ retrieve -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ information\ about\ the\ video.\ (Currently -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ supported\ only\ for\ YouTube) -\-\-cache\-dir\ DIR\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Location\ in\ the\ filesystem\ where\ youtube\-dl -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ can\ store\ some\ downloaded\ information -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ permanently.\ By\ default\ $XDG_CACHE_HOME -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ /youtube\-dl\ or\ ~/.cache/youtube\-dl\ .\ At\ the -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ moment,\ only\ YouTube\ player\ files\ (for -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ videos\ with\ obfuscated\ signatures)\ are -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cached,\ but\ that\ may\ change. -\-\-no\-cache\-dir\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Disable\ filesystem\ caching \-\-socket\-timeout\ None\ \ \ \ \ \ \ \ \ \ \ \ Time\ to\ wait\ before\ giving\ up,\ in\ seconds -\-\-bidi\-workaround\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Work\ around\ terminals\ that\ lack -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ bidirectional\ text\ support.\ Requires\ bidiv -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ or\ fribidi\ executable\ in\ PATH \-\-default\-search\ PREFIX\ \ \ \ \ \ \ \ \ \ Use\ this\ prefix\ for\ unqualified\ URLs.\ For \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ example\ "gvsearch2:"\ downloads\ two\ videos \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ from\ google\ videos\ for\ \ youtube\-dl\ "large \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ apple".\ Use\ the\ value\ "auto"\ to\ let -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ youtube\-dl\ guess.\ The\ default\ value\ "error" -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ just\ throws\ an\ error. +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ youtube\-dl\ guess\ ("auto_warning"\ to\ emit\ a +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ warning\ when\ guessing).\ "error"\ just\ throws +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ an\ error.\ The\ default\ value\ "fixup_error" +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ repairs\ broken\ URLs,\ but\ emits\ an\ error\ if +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ this\ is\ not\ possible\ instead\ of\ searching. \-\-ignore\-config\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Do\ not\ read\ configuration\ files.\ When\ given \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ in\ the\ global\ configuration\ file\ /etc \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ /youtube\-dl.conf:\ do\ not\ read\ the\ user \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ configuration\ in\ ~/.config/youtube\-dl.conf \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (%APPDATA%/youtube\-dl/config.txt\ on \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Windows) -\-\-encoding\ ENCODING\ \ \ \ \ \ \ \ \ \ \ \ \ \ Force\ the\ specified\ encoding\ (experimental) \f[] .fi .SS Video Selection: @@ -128,9 +109,9 @@ redistribute it or use it however you like. .IP .nf \f[C] -\-t,\ \-\-title\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ use\ title\ in\ file\ name\ (default) +\-a,\ \-\-batch\-file\ FILE\ \ \ \ \ \ \ \ \ \ \ \ file\ containing\ URLs\ to\ download\ (\[aq]\-\[aq]\ for +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ stdin) \-\-id\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ use\ only\ video\ ID\ in\ file\ name -\-l,\ \-\-literal\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [deprecated]\ alias\ of\ \-\-title \-A,\ \-\-auto\-number\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ number\ downloaded\ files\ starting\ from\ 00000 \-o,\ \-\-output\ TEMPLATE\ \ \ \ \ \ \ \ \ \ \ \ output\ filename\ template.\ Use\ %(title)s\ to \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ get\ the\ title,\ %(uploader)s\ for\ the @@ -163,18 +144,15 @@ redistribute it or use it however you like. \-\-restrict\-filenames\ \ \ \ \ \ \ \ \ \ \ \ \ Restrict\ filenames\ to\ only\ ASCII \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ characters,\ and\ avoid\ "&"\ and\ spaces\ in \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ filenames -\-a,\ \-\-batch\-file\ FILE\ \ \ \ \ \ \ \ \ \ \ \ file\ containing\ URLs\ to\ download\ (\[aq]\-\[aq]\ for -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ stdin) -\-\-load\-info\ FILE\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ json\ file\ containing\ the\ video\ information -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (created\ with\ the\ "\-\-write\-json"\ option) +\-t,\ \-\-title\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [deprecated]\ use\ title\ in\ file\ name +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (default) +\-l,\ \-\-literal\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [deprecated]\ alias\ of\ \-\-title \-w,\ \-\-no\-overwrites\ \ \ \ \ \ \ \ \ \ \ \ \ \ do\ not\ overwrite\ files \-c,\ \-\-continue\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ force\ resume\ of\ partially\ downloaded\ files. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ By\ default,\ youtube\-dl\ will\ resume \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ downloads\ if\ possible. \-\-no\-continue\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ do\ not\ resume\ partially\ downloaded\ files \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (restart\ from\ beginning) -\-\-cookies\ FILE\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ file\ to\ read\ cookies\ from\ and\ dump\ cookie -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ jar\ in \-\-no\-part\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ do\ not\ use\ .part\ files \-\-no\-mtime\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ do\ not\ use\ the\ Last\-modified\ header\ to\ set \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ the\ file\ modification\ time @@ -184,6 +162,19 @@ redistribute it or use it however you like. \-\-write\-annotations\ \ \ \ \ \ \ \ \ \ \ \ \ \ write\ video\ annotations\ to\ a\ .annotation \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ file \-\-write\-thumbnail\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ write\ thumbnail\ image\ to\ disk +\-\-load\-info\ FILE\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ json\ file\ containing\ the\ video\ information +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (created\ with\ the\ "\-\-write\-json"\ option) +\-\-cookies\ FILE\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ file\ to\ read\ cookies\ from\ and\ dump\ cookie +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ jar\ in +\-\-cache\-dir\ DIR\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Location\ in\ the\ filesystem\ where\ youtube\-dl +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ can\ store\ some\ downloaded\ information +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ permanently.\ By\ default\ $XDG_CACHE_HOME +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ /youtube\-dl\ or\ ~/.cache/youtube\-dl\ .\ At\ the +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ moment,\ only\ YouTube\ player\ files\ (for +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ videos\ with\ obfuscated\ signatures)\ are +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ cached,\ but\ that\ may\ change. +\-\-no\-cache\-dir\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Disable\ filesystem\ caching +\-\-rm\-cache\-dir\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Delete\ all\ filesystem\ cache\ files \f[] .fi .SS Verbosity / Simulation Options: @@ -218,6 +209,26 @@ redistribute it or use it however you like. \-\-print\-traffic\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Display\ sent\ and\ read\ HTTP\ traffic \f[] .fi +.SS Workarounds: +.IP +.nf +\f[C] +\-\-encoding\ ENCODING\ \ \ \ \ \ \ \ \ \ \ \ \ \ Force\ the\ specified\ encoding\ (experimental) +\-\-no\-check\-certificate\ \ \ \ \ \ \ \ \ \ \ Suppress\ HTTPS\ certificate\ validation. +\-\-prefer\-insecure\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Use\ an\ unencrypted\ connection\ to\ retrieve +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ information\ about\ the\ video.\ (Currently +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ supported\ only\ for\ YouTube) +\-\-user\-agent\ UA\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ specify\ a\ custom\ user\ agent +\-\-referer\ REF\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ specify\ a\ custom\ referer,\ use\ if\ the\ video +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ access\ is\ restricted\ to\ one\ domain +\-\-add\-header\ FIELD:VALUE\ \ \ \ \ \ \ \ \ specify\ a\ custom\ HTTP\ header\ and\ its\ value, +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ separated\ by\ a\ colon\ \[aq]:\[aq].\ You\ can\ use\ this +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ option\ multiple\ times +\-\-bidi\-workaround\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Work\ around\ terminals\ that\ lack +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ bidirectional\ text\ support.\ Requires\ bidiv +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ or\ fribidi\ executable\ in\ PATH +\f[] +.fi .SS Video Format Options: .IP .nf diff --git a/youtube-dl.bash-completion b/youtube-dl.bash-completion index 498e841..4077a16 100644 --- a/youtube-dl.bash-completion +++ b/youtube-dl.bash-completion @@ -4,7 +4,7 @@ __youtube_dl() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="--help --version --update --ignore-errors --abort-on-error --dump-user-agent --user-agent --referer --add-header --list-extractors --extractor-descriptions --proxy --no-check-certificate --prefer-insecure --cache-dir --no-cache-dir --socket-timeout --bidi-workaround --default-search --ignore-config --encoding --playlist-start --playlist-end --match-title --reject-title --max-downloads --min-filesize --max-filesize --date --datebefore --dateafter --min-views --max-views --no-playlist --age-limit --download-archive --include-ads --youtube-include-dash-manifest --rate-limit --retries --buffer-size --no-resize-buffer --test --title --id --literal --auto-number --output --autonumber-size --restrict-filenames --batch-file --load-info --no-overwrites --continue --no-continue --cookies --no-part --no-mtime --write-description --write-info-json --write-annotations --write-thumbnail --quiet --no-warnings --simulate --skip-download --get-url --get-title --get-id --get-thumbnail --get-description --get-duration --get-filename --get-format --dump-json --newline --no-progress --console-title --verbose --dump-intermediate-pages --write-pages --youtube-print-sig-code --print-traffic --format --all-formats --prefer-free-formats --max-quality --list-formats --write-sub --write-auto-sub --all-subs --list-subs --sub-format --sub-lang --username --password --netrc --video-password --extract-audio --audio-format --audio-quality --recode-video --keep-video --no-post-overwrites --embed-subs --embed-thumbnail --add-metadata --xattrs --prefer-avconv --prefer-ffmpeg" + opts="--help --version --update --ignore-errors --abort-on-error --dump-user-agent --list-extractors --extractor-descriptions --proxy --socket-timeout --default-search --ignore-config --playlist-start --playlist-end --match-title --reject-title --max-downloads --min-filesize --max-filesize --date --datebefore --dateafter --min-views --max-views --no-playlist --age-limit --download-archive --include-ads --youtube-include-dash-manifest --rate-limit --retries --buffer-size --no-resize-buffer --test --batch-file --id --auto-number --output --autonumber-size --restrict-filenames --title --literal --no-overwrites --continue --no-continue --no-part --no-mtime --write-description --write-info-json --write-annotations --write-thumbnail --load-info --cookies --cache-dir --no-cache-dir --rm-cache-dir --quiet --no-warnings --simulate --skip-download --get-url --get-title --get-id --get-thumbnail --get-description --get-duration --get-filename --get-format --dump-json --newline --no-progress --console-title --verbose --dump-intermediate-pages --write-pages --youtube-print-sig-code --print-traffic --encoding --no-check-certificate --prefer-insecure --user-agent --referer --add-header --bidi-workaround --format --all-formats --prefer-free-formats --max-quality --list-formats --write-sub --write-auto-sub --all-subs --list-subs --sub-format --sub-lang --username --password --netrc --video-password --extract-audio --audio-format --audio-quality --recode-video --keep-video --no-post-overwrites --embed-subs --embed-thumbnail --add-metadata --xattrs --prefer-avconv --prefer-ffmpeg" keywords=":ytfavorites :ytrecommended :ytsubscriptions :ytwatchlater :ythistory" fileopts="-a|--batch-file|--download-archive|--cookies|--load-info" diropts="--cache-dir" diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py deleted file mode 100644 index 5c8e676..0000000 --- a/youtube_dl/FileDownloader.py +++ /dev/null @@ -1,12 +0,0 @@ -# Legacy file for backwards compatibility, use youtube_dl.downloader instead! -from .downloader import FileDownloader as RealFileDownloader -from .downloader import get_suitable_downloader - - -# This class reproduces the old behaviour of FileDownloader -class FileDownloader(RealFileDownloader): - def _do_download(self, filename, info_dict): - real_fd = get_suitable_downloader(info_dict)(self.ydl, self.params) - for ph in self._progress_hooks: - real_fd.add_progress_hook(ph) - return real_fd.download(filename, info_dict) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 3dff723..14a1d06 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -275,7 +275,7 @@ class YoutubeDL(object): return message assert hasattr(self, '_output_process') - assert type(message) == type('') + assert isinstance(message, compat_str) line_count = message.count('\n') + 1 self._output_process.stdin.write((message + '\n').encode('utf-8')) self._output_process.stdin.flush() @@ -303,7 +303,7 @@ class YoutubeDL(object): def to_stderr(self, message): """Print message to stderr.""" - assert type(message) == type('') + assert isinstance(message, compat_str) if self.params.get('logger'): self.params['logger'].error(message) else: @@ -849,7 +849,7 @@ class YoutubeDL(object): # Keep for backwards compatibility info_dict['stitle'] = info_dict['title'] - if not 'format' in info_dict: + if 'format' not in info_dict: info_dict['format'] = info_dict['ext'] reason = self._match_entry(info_dict) @@ -999,7 +999,7 @@ class YoutubeDL(object): if info_dict.get('requested_formats') is not None: downloaded = [] success = True - merger = FFmpegMergerPP(self) + merger = FFmpegMergerPP(self, not self.params.get('keepvideo')) if not merger._get_executable(): postprocessors = [] self.report_warning('You have requested multiple ' @@ -1197,6 +1197,10 @@ class YoutubeDL(object): if res: res += ', ' res += format_bytes(fdict['filesize']) + elif fdict.get('filesize_approx') is not None: + if res: + res += ', ' + res += '~' + format_bytes(fdict['filesize_approx']) return res def list_formats(self, info_dict): @@ -1230,14 +1234,18 @@ class YoutubeDL(object): if not self.params.get('verbose'): return - write_string( + if type('') is not compat_str: + # Python 2.6 on SLES11 SP1 (https://github.com/rg3/youtube-dl/issues/3326) + self.report_warning( + 'Your Python is broken! Update to a newer and supported version') + + encoding_str = ( '[debug] Encodings: locale %s, fs %s, out %s, pref %s\n' % ( locale.getpreferredencoding(), sys.getfilesystemencoding(), sys.stdout.encoding, - self.get_encoding()), - encoding=None - ) + self.get_encoding())) + write_string(encoding_str, encoding=None) self._write_string('[debug] youtube-dl version ' + __version__ + '\n') try: diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index 5e16a54..f9c16e4 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -64,18 +64,20 @@ __authors__ = ( 'Adam Malcontenti-Wilson', 'Tobias Bell', 'Naglis Jonaitis', + 'Charles Chen', + 'Hassaan Ali', + 'Dobrosław Żybort', ) __license__ = 'Public Domain' import codecs import io -import locale import optparse import os import random -import re import shlex +import shutil import sys @@ -97,7 +99,7 @@ from .utils import ( write_string, ) from .update import update_self -from .FileDownloader import ( +from .downloader import ( FileDownloader, ) from .extractor import gen_extractors @@ -222,6 +224,7 @@ def parseOpts(overrideArguments=None): downloader = optparse.OptionGroup(parser, 'Download Options') postproc = optparse.OptionGroup(parser, 'Post-processing Options') filesystem = optparse.OptionGroup(parser, 'Filesystem Options') + workarounds = optparse.OptionGroup(parser, 'Workarounds') verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options') general.add_option('-h', '--help', @@ -238,14 +241,6 @@ def parseOpts(overrideArguments=None): general.add_option('--dump-user-agent', action='store_true', dest='dump_user_agent', help='display the current browser identification', default=False) - general.add_option('--user-agent', - dest='user_agent', help='specify a custom user agent', metavar='UA') - general.add_option('--referer', - dest='referer', help='specify a custom referer, use if the video access is restricted to one domain', - metavar='REF', default=None) - general.add_option('--add-header', - dest='headers', help='specify a custom HTTP header and its value, separated by a colon \':\'. You can use this option multiple times', action="append", - metavar='FIELD:VALUE') general.add_option('--list-extractors', action='store_true', dest='list_extractors', help='List all supported extractors and the URLs they would handle', default=False) @@ -255,33 +250,17 @@ def parseOpts(overrideArguments=None): general.add_option( '--proxy', dest='proxy', default=None, metavar='URL', help='Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy "") for direct connection') - general.add_option('--no-check-certificate', action='store_true', dest='no_check_certificate', default=False, help='Suppress HTTPS certificate validation.') - general.add_option( - '--prefer-insecure', '--prefer-unsecure', action='store_true', dest='prefer_insecure', - help='Use an unencrypted connection to retrieve information about the video. (Currently supported only for YouTube)') - general.add_option( - '--cache-dir', dest='cachedir', default=get_cachedir(), metavar='DIR', - help='Location in the filesystem where youtube-dl can store some downloaded information permanently. By default $XDG_CACHE_HOME/youtube-dl or ~/.cache/youtube-dl . At the moment, only YouTube player files (for videos with obfuscated signatures) are cached, but that may change.') - general.add_option( - '--no-cache-dir', action='store_const', const=None, dest='cachedir', - help='Disable filesystem caching') general.add_option( '--socket-timeout', dest='socket_timeout', type=float, default=None, help=u'Time to wait before giving up, in seconds') - general.add_option( - '--bidi-workaround', dest='bidi_workaround', action='store_true', - help=u'Work around terminals that lack bidirectional text support. Requires bidiv or fribidi executable in PATH') general.add_option( '--default-search', dest='default_search', metavar='PREFIX', - help='Use this prefix for unqualified URLs. For example "gvsearch2:" downloads two videos from google videos for youtube-dl "large apple". Use the value "auto" to let youtube-dl guess. The default value "error" just throws an error.') + help='Use this prefix for unqualified URLs. For example "gvsearch2:" downloads two videos from google videos for youtube-dl "large apple". Use the value "auto" to let youtube-dl guess ("auto_warning" to emit a warning when guessing). "error" just throws an error. The default value "fixup_error" repairs broken URLs, but emits an error if this is not possible instead of searching.') general.add_option( '--ignore-config', action='store_true', help='Do not read configuration files. When given in the global configuration file /etc/youtube-dl.conf: do not read the user configuration in ~/.config/youtube-dl.conf (%APPDATA%/youtube-dl/config.txt on Windows)') - general.add_option( - '--encoding', dest='encoding', metavar='ENCODING', - help='Force the specified encoding (experimental)') selection.add_option( '--playlist-start', @@ -382,6 +361,33 @@ def parseOpts(overrideArguments=None): help='do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE.', default=False) downloader.add_option('--test', action='store_true', dest='test', default=False, help=optparse.SUPPRESS_HELP) + workarounds.add_option( + '--encoding', dest='encoding', metavar='ENCODING', + help='Force the specified encoding (experimental)') + workarounds.add_option( + '--no-check-certificate', action='store_true', + dest='no_check_certificate', default=False, + help='Suppress HTTPS certificate validation.') + workarounds.add_option( + '--prefer-insecure', '--prefer-unsecure', action='store_true', dest='prefer_insecure', + help='Use an unencrypted connection to retrieve information about the video. (Currently supported only for YouTube)') + workarounds.add_option( + '--user-agent', metavar='UA', + dest='user_agent', help='specify a custom user agent') + workarounds.add_option( + '--referer', metavar='REF', + dest='referer', default=None, + help='specify a custom referer, use if the video access is restricted to one domain', + ) + workarounds.add_option( + '--add-header', metavar='FIELD:VALUE', + dest='headers', action='append', + help='specify a custom HTTP header and its value, separated by a colon \':\'. You can use this option multiple times', + ) + workarounds.add_option( + '--bidi-workaround', dest='bidi_workaround', action='store_true', + help=u'Work around terminals that lack bidirectional text support. Requires bidiv or fribidi executable in PATH') + verbosity.add_option('-q', '--quiet', action='store_true', dest='quiet', help='activates quiet mode', default=False) verbosity.add_option( @@ -439,12 +445,10 @@ def parseOpts(overrideArguments=None): help='Display sent and read HTTP traffic') - filesystem.add_option('-t', '--title', - action='store_true', dest='usetitle', help='use title in file name (default)', default=False) + filesystem.add_option('-a', '--batch-file', + dest='batchfile', metavar='FILE', help='file containing URLs to download (\'-\' for stdin)') filesystem.add_option('--id', action='store_true', dest='useid', help='use only video ID in file name', default=False) - filesystem.add_option('-l', '--literal', - action='store_true', dest='usetitle', help='[deprecated] alias of --title', default=False) filesystem.add_option('-A', '--auto-number', action='store_true', dest='autonumber', help='number downloaded files starting from 00000', default=False) @@ -470,11 +474,10 @@ def parseOpts(overrideArguments=None): filesystem.add_option('--restrict-filenames', action='store_true', dest='restrictfilenames', help='Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames', default=False) - filesystem.add_option('-a', '--batch-file', - dest='batchfile', metavar='FILE', help='file containing URLs to download (\'-\' for stdin)') - filesystem.add_option('--load-info', - dest='load_info_filename', metavar='FILE', - help='json file containing the video information (created with the "--write-json" option)') + filesystem.add_option('-t', '--title', + action='store_true', dest='usetitle', help='[deprecated] use title in file name (default)', default=False) + filesystem.add_option('-l', '--literal', + action='store_true', dest='usetitle', help='[deprecated] alias of --title', default=False) filesystem.add_option('-w', '--no-overwrites', action='store_true', dest='nooverwrites', help='do not overwrite files', default=False) filesystem.add_option('-c', '--continue', @@ -482,8 +485,6 @@ def parseOpts(overrideArguments=None): filesystem.add_option('--no-continue', action='store_false', dest='continue_dl', help='do not resume partially downloaded files (restart from beginning)') - filesystem.add_option('--cookies', - dest='cookiefile', metavar='FILE', help='file to read cookies from and dump cookie jar in') filesystem.add_option('--no-part', action='store_true', dest='nopart', help='do not use .part files', default=False) filesystem.add_option('--no-mtime', @@ -501,6 +502,20 @@ def parseOpts(overrideArguments=None): filesystem.add_option('--write-thumbnail', action='store_true', dest='writethumbnail', help='write thumbnail image to disk', default=False) + filesystem.add_option('--load-info', + dest='load_info_filename', metavar='FILE', + help='json file containing the video information (created with the "--write-json" option)') + filesystem.add_option('--cookies', + dest='cookiefile', metavar='FILE', help='file to read cookies from and dump cookie jar in') + filesystem.add_option( + '--cache-dir', dest='cachedir', default=get_cachedir(), metavar='DIR', + help='Location in the filesystem where youtube-dl can store some downloaded information permanently. By default $XDG_CACHE_HOME/youtube-dl or ~/.cache/youtube-dl . At the moment, only YouTube player files (for videos with obfuscated signatures) are cached, but that may change.') + filesystem.add_option( + '--no-cache-dir', action='store_const', const=None, dest='cachedir', + help='Disable filesystem caching') + filesystem.add_option( + '--rm-cache-dir', action='store_true', dest='rm_cachedir', + help='Delete all filesystem cache files') postproc.add_option('-x', '--extract-audio', action='store_true', dest='extractaudio', default=False, @@ -534,6 +549,7 @@ def parseOpts(overrideArguments=None): parser.add_option_group(downloader) parser.add_option_group(filesystem) parser.add_option_group(verbosity) + parser.add_option_group(workarounds) parser.add_option_group(video_format) parser.add_option_group(subtitles) parser.add_option_group(authentication) @@ -633,7 +649,7 @@ def _real_main(argv=None): if desc is False: continue if hasattr(ie, 'SEARCH_KEY'): - _SEARCHES = (u'cute kittens', u'slithering pythons', u'falling cat', u'angry poodle', u'purple fish', u'running tortoise') + _SEARCHES = (u'cute kittens', u'slithering pythons', u'falling cat', u'angry poodle', u'purple fish', u'running tortoise', u'sleeping bunny') _COUNTS = (u'', u'5', u'10', u'all') desc += u' (Example: "%s%s:%s" )' % (ie.SEARCH_KEY, random.choice(_COUNTS), random.choice(_SEARCHES)) compat_print(desc) @@ -694,7 +710,7 @@ def _real_main(argv=None): date = DateRange.day(opts.date) else: date = DateRange(opts.dateafter, opts.datebefore) - if opts.default_search not in ('auto', 'auto_warning', None) and ':' not in opts.default_search: + if opts.default_search not in ('auto', 'auto_warning', 'error', 'fixup_error', None) and ':' not in opts.default_search: parser.error(u'--default-search invalid; did you forget a colon (:) at the end?') # Do not download videos when there are audio-only formats @@ -833,9 +849,26 @@ def _real_main(argv=None): if opts.update_self: update_self(ydl.to_screen, opts.verbose) + # Remove cache dir + if opts.rm_cachedir: + if opts.cachedir is None: + ydl.to_screen(u'No cache dir specified (Did you combine --no-cache-dir and --rm-cache-dir?)') + else: + if ('.cache' not in opts.cachedir) or ('youtube-dl' not in opts.cachedir): + ydl.to_screen(u'Not removing directory %s - this does not look like a cache dir') + retcode = 141 + else: + ydl.to_screen( + u'Removing cache dir %s .' % opts.cachedir, + skip_eol=True) + if os.path.exists(opts.cachedir): + ydl.to_screen(u'.', skip_eol=True) + shutil.rmtree(opts.cachedir) + ydl.to_screen(u'.') + # Maybe do nothing if (len(all_urls) < 1) and (opts.load_info_filename is None): - if not opts.update_self: + if not (opts.update_self or opts.rm_cachedir): parser.error(u'you must provide at least one URL') else: sys.exit() diff --git a/youtube_dl/downloader/f4m.py b/youtube_dl/downloader/f4m.py index e6be6ae..71353f6 100644 --- a/youtube_dl/downloader/f4m.py +++ b/youtube_dl/downloader/f4m.py @@ -220,6 +220,7 @@ class F4mFD(FileDownloader): def real_download(self, filename, info_dict): man_url = info_dict['url'] + requested_bitrate = info_dict.get('tbr') self.to_screen('[download] Downloading f4m manifest') manifest = self.ydl.urlopen(man_url).read() self.report_destination(filename) @@ -233,8 +234,14 @@ class F4mFD(FileDownloader): doc = etree.fromstring(manifest) formats = [(int(f.attrib.get('bitrate', -1)), f) for f in doc.findall(_add_ns('media'))] - formats = sorted(formats, key=lambda f: f[0]) - rate, media = formats[-1] + if requested_bitrate is None: + # get the best format + formats = sorted(formats, key=lambda f: f[0]) + rate, media = formats[-1] + else: + rate, media = list(filter( + lambda f: int(f[0]) == requested_bitrate, formats))[0] + base_url = compat_urlparse.urljoin(man_url, media.attrib['url']) bootstrap = base64.b64decode(doc.find(_add_ns('bootstrapInfo')).text) metadata = base64.b64decode(media.find(_add_ns('metadata')).text) diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index e49ac3e..66c8737 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -1,5 +1,7 @@ +from .abc import ABCIE from .academicearth import AcademicEarthCourseIE from .addanime import AddAnimeIE +from .adultswim import AdultSwimIE from .aftonbladet import AftonbladetIE from .anitube import AnitubeIE from .aol import AolIE @@ -52,6 +54,7 @@ from .cnn import ( from .collegehumor import CollegeHumorIE from .comedycentral import ComedyCentralIE, ComedyCentralShowsIE from .condenast import CondeNastIE +from .cracked import CrackedIE from .criterion import CriterionIE from .crunchyroll import CrunchyrollIE from .cspan import CSpanIE @@ -62,6 +65,7 @@ from .dailymotion import ( DailymotionUserIE, ) from .daum import DaumIE +from .dfb import DFBIE from .dotsub import DotsubIE from .dreisat import DreiSatIE from .drtv import DRTVIE @@ -108,9 +112,11 @@ from .funnyordie import FunnyOrDieIE from .gamekings import GamekingsIE from .gameone import GameOneIE from .gamespot import GameSpotIE +from .gamestar import GameStarIE from .gametrailers import GametrailersIE from .gdcvault import GDCVaultIE from .generic import GenericIE +from .godtube import GodTubeIE from .googleplus import GooglePlusIE from .googlesearch import GoogleSearchIE from .gorillavid import GorillaVidIE @@ -137,6 +143,7 @@ from .ivi import ( IviIE, IviCompilationIE ) +from .izlesene import IzleseneIE from .jadorecettepub import JadoreCettePubIE from .jeuxvideo import JeuxVideoIE from .jukebox import JukeboxIE @@ -148,6 +155,7 @@ from .khanacademy import KhanAcademyIE from .kickstarter import KickStarterIE from .keek import KeekIE from .kontrtube import KontrTubeIE +from .krasview import KrasViewIE from .ku6 import Ku6IE from .la7 import LA7IE from .lifenews import LifeNewsIE @@ -170,6 +178,7 @@ from .metacafe import MetacafeIE from .metacritic import MetacriticIE from .mit import TechTVMITIE, MITIE, OCWMITIE from .mixcloud import MixcloudIE +from .mlb import MLBIE from .mpora import MporaIE from .mofosex import MofosexIE from .mooshare import MooshareIE @@ -249,10 +258,12 @@ from .rutube import ( RutubePersonIE, ) from .rutv import RUTVIE +from .sapo import SapoIE from .savefrom import SaveFromIE from .scivee import SciVeeIE from .screencast import ScreencastIE from .servingsys import ServingSysIE +from .shared import SharedIE from .sina import SinaIE from .slideshare import SlideshareIE from .slutload import SlutloadIE @@ -262,6 +273,8 @@ from .smotri import ( SmotriUserIE, SmotriBroadcastIE, ) +from .snotr import SnotrIE +from .sockshare import SockshareIE from .sohu import SohuIE from .soundcloud import ( SoundcloudIE, @@ -313,6 +326,8 @@ from .tumblr import TumblrIE from .tutv import TutvIE from .tvigle import TvigleIE from .tvp import TvpIE +from .tvplay import TVPlayIE +from .ubu import UbuIE from .udemy import ( UdemyIE, UdemyCourseIE @@ -334,6 +349,7 @@ from .videofyme import VideofyMeIE from .videopremium import VideoPremiumIE from .videott import VideoTtIE from .videoweed import VideoWeedIE +from .vidme import VidmeIE from .vimeo import ( VimeoIE, VimeoChannelIE, @@ -396,6 +412,7 @@ from .youtube import ( YoutubeUserIE, YoutubeWatchLaterIE, ) + from .zdf import ZDFIE diff --git a/youtube_dl/extractor/abc.py b/youtube_dl/extractor/abc.py new file mode 100644 index 0000000..7d89f44 --- /dev/null +++ b/youtube_dl/extractor/abc.py @@ -0,0 +1,48 @@ +from __future__ import unicode_literals + +import re +import json + +from .common import InfoExtractor + + +class ABCIE(InfoExtractor): + IE_NAME = 'abc.net.au' + _VALID_URL = r'http://www\.abc\.net\.au/news/[^/]+/[^/]+/(?P\d+)' + + _TEST = { + 'url': 'http://www.abc.net.au/news/2014-07-25/bringing-asylum-seekers-to-australia-would-give/5624716', + 'md5': 'dad6f8ad011a70d9ddf887ce6d5d0742', + 'info_dict': { + 'id': '5624716', + 'ext': 'mp4', + 'title': 'Bringing asylum seekers to Australia would give them right to asylum claims: professor', + 'description': 'md5:ba36fa5e27e5c9251fd929d339aea4af', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + webpage = self._download_webpage(url, video_id) + + urls_info_json = self._search_regex( + r'inlineVideoData\.push\((.*?)\);', webpage, 'video urls', + flags=re.DOTALL) + urls_info = json.loads(urls_info_json.replace('\'', '"')) + formats = [{ + 'url': url_info['url'], + 'width': int(url_info['width']), + 'height': int(url_info['height']), + 'tbr': int(url_info['bitrate']), + 'filesize': int(url_info['filesize']), + } for url_info in urls_info] + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': self._og_search_title(webpage), + 'formats': formats, + 'description': self._og_search_description(webpage), + 'thumbnail': self._og_search_thumbnail(webpage), + } diff --git a/youtube_dl/extractor/adultswim.py b/youtube_dl/extractor/adultswim.py new file mode 100644 index 0000000..a00bfcb --- /dev/null +++ b/youtube_dl/extractor/adultswim.py @@ -0,0 +1,139 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor + +class AdultSwimIE(InfoExtractor): + _VALID_URL = r'https?://video\.adultswim\.com/(?P.+?)(?:\.html)?(?:\?.*)?(?:#.*)?$' + _TEST = { + 'url': 'http://video.adultswim.com/rick-and-morty/close-rick-counters-of-the-rick-kind.html?x=y#title', + 'playlist': [ + { + 'md5': '4da359ec73b58df4575cd01a610ba5dc', + 'info_dict': { + 'id': '8a250ba1450996e901453d7f02ca02f5', + 'ext': 'flv', + 'title': 'Rick and Morty Close Rick-Counters of the Rick Kind part 1', + 'description': 'Rick has a run in with some old associates, resulting in a fallout with Morty. You got any chips, broh?', + 'uploader': 'Rick and Morty', + 'thumbnail': 'http://i.cdn.turner.com/asfix/repository/8a250ba13f865824013fc9db8b6b0400/thumbnail_267549017116827057.jpg' + } + }, + { + 'md5': 'ffbdf55af9331c509d95350bd0cc1819', + 'info_dict': { + 'id': '8a250ba1450996e901453d7f4bd102f6', + 'ext': 'flv', + 'title': 'Rick and Morty Close Rick-Counters of the Rick Kind part 2', + 'description': 'Rick has a run in with some old associates, resulting in a fallout with Morty. You got any chips, broh?', + 'uploader': 'Rick and Morty', + 'thumbnail': 'http://i.cdn.turner.com/asfix/repository/8a250ba13f865824013fc9db8b6b0400/thumbnail_267549017116827057.jpg' + } + }, + { + 'md5': 'b92409635540304280b4b6c36bd14a0a', + 'info_dict': { + 'id': '8a250ba1450996e901453d7fa73c02f7', + 'ext': 'flv', + 'title': 'Rick and Morty Close Rick-Counters of the Rick Kind part 3', + 'description': 'Rick has a run in with some old associates, resulting in a fallout with Morty. You got any chips, broh?', + 'uploader': 'Rick and Morty', + 'thumbnail': 'http://i.cdn.turner.com/asfix/repository/8a250ba13f865824013fc9db8b6b0400/thumbnail_267549017116827057.jpg' + } + }, + { + 'md5': 'e8818891d60e47b29cd89d7b0278156d', + 'info_dict': { + 'id': '8a250ba1450996e901453d7fc8ba02f8', + 'ext': 'flv', + 'title': 'Rick and Morty Close Rick-Counters of the Rick Kind part 4', + 'description': 'Rick has a run in with some old associates, resulting in a fallout with Morty. You got any chips, broh?', + 'uploader': 'Rick and Morty', + 'thumbnail': 'http://i.cdn.turner.com/asfix/repository/8a250ba13f865824013fc9db8b6b0400/thumbnail_267549017116827057.jpg' + } + } + ] + } + + _video_extensions = { + '3500': 'flv', + '640': 'mp4', + '150': 'mp4', + 'ipad': 'm3u8', + 'iphone': 'm3u8' + } + _video_dimensions = { + '3500': (1280, 720), + '640': (480, 270), + '150': (320, 180) + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_path = mobj.group('path') + + webpage = self._download_webpage(url, video_path) + episode_id = self._html_search_regex(r'', webpage, 'episode_id') + title = self._og_search_title(webpage) + + index_url = 'http://asfix.adultswim.com/asfix-svc/episodeSearch/getEpisodesByIDs?networkName=AS&ids=%s' % episode_id + idoc = self._download_xml(index_url, title, 'Downloading episode index', 'Unable to download episode index') + + episode_el = idoc.find('.//episode') + show_title = episode_el.attrib.get('collectionTitle') + episode_title = episode_el.attrib.get('title') + thumbnail = episode_el.attrib.get('thumbnailUrl') + description = episode_el.find('./description').text.strip() + + entries = [] + segment_els = episode_el.findall('./segments/segment') + + for part_num, segment_el in enumerate(segment_els): + segment_id = segment_el.attrib.get('id') + segment_title = '%s %s part %d' % (show_title, episode_title, part_num + 1) + thumbnail = segment_el.attrib.get('thumbnailUrl') + duration = segment_el.attrib.get('duration') + + segment_url = 'http://asfix.adultswim.com/asfix-svc/episodeservices/getCvpPlaylist?networkName=AS&id=%s' % segment_id + idoc = self._download_xml(segment_url, segment_title, 'Downloading segment information', 'Unable to download segment information') + + formats = [] + file_els = idoc.findall('.//files/file') + + for file_el in file_els: + bitrate = file_el.attrib.get('bitrate') + type = file_el.attrib.get('type') + width, height = self._video_dimensions.get(bitrate, (None, None)) + formats.append({ + 'format_id': '%s-%s' % (bitrate, type), + 'url': file_el.text, + 'ext': self._video_extensions.get(bitrate, 'mp4'), + # The bitrate may not be a number (for example: 'iphone') + 'tbr': int(bitrate) if bitrate.isdigit() else None, + 'height': height, + 'width': width + }) + + self._sort_formats(formats) + + entries.append({ + 'id': segment_id, + 'title': segment_title, + 'formats': formats, + 'uploader': show_title, + 'thumbnail': thumbnail, + 'duration': duration, + 'description': description + }) + + return { + '_type': 'playlist', + 'id': episode_id, + 'display_id': video_path, + 'entries': entries, + 'title': '%s %s' % (show_title, episode_title), + 'description': description, + 'thumbnail': thumbnail + } diff --git a/youtube_dl/extractor/allocine.py b/youtube_dl/extractor/allocine.py index 34f0cd4..7bd7978 100644 --- a/youtube_dl/extractor/allocine.py +++ b/youtube_dl/extractor/allocine.py @@ -32,7 +32,7 @@ class AllocineIE(InfoExtractor): 'id': '19540403', 'ext': 'mp4', 'title': 'Planes 2 Bande-annonce VF', - 'description': 'md5:c4b1f7bd682a91de6491ada267ec0f4d', + 'description': 'md5:eeaffe7c2d634525e21159b93acf3b1e', 'thumbnail': 're:http://.*\.jpg', }, }, { @@ -42,7 +42,7 @@ class AllocineIE(InfoExtractor): 'id': '19544709', 'ext': 'mp4', 'title': 'Dragons 2 - Bande annonce finale VF', - 'description': 'md5:e74a4dc750894bac300ece46c7036490', + 'description': 'md5:71742e3a74b0d692c7fce0dd2017a4ac', 'thumbnail': 're:http://.*\.jpg', }, }] diff --git a/youtube_dl/extractor/ard.py b/youtube_dl/extractor/ard.py index b36a4d4..957bdef 100644 --- a/youtube_dl/extractor/ard.py +++ b/youtube_dl/extractor/ard.py @@ -7,23 +7,34 @@ from .common import InfoExtractor from ..utils import ( determine_ext, ExtractorError, + qualities, + compat_urllib_parse_urlparse, + compat_urllib_parse, ) class ARDIE(InfoExtractor): - _VALID_URL = r'^https?://(?:(?:www\.)?ardmediathek\.de|mediathek\.daserste\.de)/(?:.*/)(?P[^/\?]+)(?:\?.*)?' + _VALID_URL = r'^https?://(?:(?:www\.)?ardmediathek\.de|mediathek\.daserste\.de)/(?:.*/)(?P[0-9]+|[^0-9][^/\?]+)[^/\?]*(?:\?.*)?' - _TEST = { - 'url': 'http://www.ardmediathek.de/das-erste/guenther-jauch/edward-snowden-im-interview-held-oder-verraeter?documentId=19288786', - 'file': '19288786.mp4', - 'md5': '515bf47ce209fb3f5a61b7aad364634c', + _TESTS = [{ + 'url': 'http://mediathek.daserste.de/sendungen_a-z/328454_anne-will/22429276_vertrauen-ist-gut-spionieren-ist-besser-geht', + 'file': '22429276.mp4', + 'md5': '469751912f1de0816a9fc9df8336476c', 'info_dict': { - 'title': 'Edward Snowden im Interview - Held oder Verräter?', - 'description': 'Edward Snowden hat alles aufs Spiel gesetzt, um die weltweite \xdcberwachung durch die Geheimdienste zu enttarnen. Nun stellt sich der ehemalige NSA-Mitarbeiter erstmals weltweit in einem TV-Interview den Fragen eines NDR-Journalisten. Die Sendung vom Sonntagabend.', - 'thumbnail': 'http://www.ardmediathek.de/ard/servlet/contentblob/19/28/87/90/19288790/bild/2250037', + 'title': 'Vertrauen ist gut, Spionieren ist besser - Geht so deutsch-amerikanische Freundschaft?', + 'description': 'Das Erste Mediathek [ARD]: Vertrauen ist gut, Spionieren ist besser - Geht so deutsch-amerikanische Freundschaft?, Anne Will, Über die Spionage-Affäre diskutieren Clemens Binninger, Katrin Göring-Eckardt, Georg Mascolo, Andrew B. Denison und Constanze Kurz.. Das Video zur Sendung Anne Will am Mittwoch, 16.07.2014', }, 'skip': 'Blocked outside of Germany', - } + }, { + 'url': 'http://www.ardmediathek.de/tv/Tatort/Das-Wunder-von-Wolbeck-Video-tgl-ab-20/Das-Erste/Video?documentId=22490580&bcastId=602916', + 'info_dict': { + 'id': '22490580', + 'ext': 'mp4', + 'title': 'Das Wunder von Wolbeck (Video tgl. ab 20 Uhr)', + 'description': 'Auf einem restaurierten Hof bei Wolbeck wird der Heilpraktiker Raffael Lembeck eines morgens von seiner Frau Stella tot aufgefunden. Das Opfer war offensichtlich in seiner Praxis zu Fall gekommen und ist dann verblutet, erklärt Prof. Boerne am Tatort.', + }, + 'skip': 'Blocked outside of Germany', + }] def _real_extract(self, url): # determine video id from url @@ -35,6 +46,9 @@ class ARDIE(InfoExtractor): else: video_id = m.group('video_id') + urlp = compat_urllib_parse_urlparse(url) + url = urlp._replace(path=compat_urllib_parse.quote(urlp.path.encode('utf-8'))).geturl() + webpage = self._download_webpage(url, video_id) title = self._html_search_regex( @@ -43,40 +57,64 @@ class ARDIE(InfoExtractor): r'

    (.*?)

    '], webpage, 'title') description = self._html_search_meta( - 'dcterms.abstract', webpage, 'description') - thumbnail = self._og_search_thumbnail(webpage) - - - media_info = self._download_json( - 'http://www.ardmediathek.de/play/media/%s' % video_id, video_id) - # The second element of the _mediaArray contains the standard http urls - streams = media_info['_mediaArray'][1]['_mediaStreamArray'] - if not streams: - if '"fsk"' in webpage: - raise ExtractorError('This video is only available after 20:00') - - formats = [] - - for s in streams: - if type(s['_stream']) == list: - for index, url in enumerate(s['_stream'][::-1]): - quality = s['_quality'] + index - formats.append({ - 'quality': quality, - 'url': url, - 'format_id': '%s-%s' % (determine_ext(url), quality) + 'dcterms.abstract', webpage, 'description', default=None) + if description is None: + description = self._html_search_meta( + 'description', webpage, 'meta description') + + # Thumbnail is sometimes not present. + # It is in the mobile version, but that seems to use a different URL + # structure altogether. + thumbnail = self._og_search_thumbnail(webpage, default=None) + + media_streams = re.findall(r'''(?x) + mediaCollection\.addMediaStream\([0-9]+,\s*[0-9]+,\s*"[^"]*",\s* + "([^"]+)"''', webpage) + + if media_streams: + QUALITIES = qualities(['lo', 'hi', 'hq']) + formats = [] + for furl in set(media_streams): + if furl.endswith('.f4m'): + fid = 'f4m' + else: + fid_m = re.match(r'.*\.([^.]+)\.[^.]+$', furl) + fid = fid_m.group(1) if fid_m else None + formats.append({ + 'quality': QUALITIES(fid), + 'format_id': fid, + 'url': furl, + }) + else: # request JSON file + media_info = self._download_json( + 'http://www.ardmediathek.de/play/media/%s' % video_id, video_id) + # The second element of the _mediaArray contains the standard http urls + streams = media_info['_mediaArray'][1]['_mediaStreamArray'] + if not streams: + if '"fsk"' in webpage: + raise ExtractorError('This video is only available after 20:00') + + formats = [] + for s in streams: + if type(s['_stream']) == list: + for index, url in enumerate(s['_stream'][::-1]): + quality = s['_quality'] + index + formats.append({ + 'quality': quality, + 'url': url, + 'format_id': '%s-%s' % (determine_ext(url), quality) }) - continue + continue - format = { - 'quality': s['_quality'], - 'url': s['_stream'], - } + format = { + 'quality': s['_quality'], + 'url': s['_stream'], + } - format['format_id'] = '%s-%s' % ( - determine_ext(format['url']), format['quality']) + format['format_id'] = '%s-%s' % ( + determine_ext(format['url']), format['quality']) - formats.append(format) + formats.append(format) self._sort_formats(formats) diff --git a/youtube_dl/extractor/blinkx.py b/youtube_dl/extractor/blinkx.py index 7d558e2..3e461e7 100644 --- a/youtube_dl/extractor/blinkx.py +++ b/youtube_dl/extractor/blinkx.py @@ -52,7 +52,7 @@ class BlinkxIE(InfoExtractor): 'height': int(m['h']), }) elif m['type'] == 'original': - duration = m['d'] + duration = float(m['d']) elif m['type'] == 'youtube': yt_id = m['link'] self.to_screen('Youtube video detected: %s' % yt_id) diff --git a/youtube_dl/extractor/bloomberg.py b/youtube_dl/extractor/bloomberg.py index 25fb79e..c51a97c 100644 --- a/youtube_dl/extractor/bloomberg.py +++ b/youtube_dl/extractor/bloomberg.py @@ -10,7 +10,7 @@ class BloombergIE(InfoExtractor): _TEST = { 'url': 'http://www.bloomberg.com/video/shah-s-presentation-on-foreign-exchange-strategies-qurhIVlJSB6hzkVi229d8g.html', - 'md5': '7bf08858ff7c203c870e8a6190e221e5', + # The md5 checksum changes 'info_dict': { 'id': 'qurhIVlJSB6hzkVi229d8g', 'ext': 'flv', @@ -31,8 +31,7 @@ class BloombergIE(InfoExtractor): return { 'id': name.split('-')[-1], 'title': title, - 'url': f4m_url, - 'ext': 'flv', + 'formats': self._extract_f4m_formats(f4m_url, name), 'description': self._og_search_description(webpage), 'thumbnail': self._og_search_thumbnail(webpage), } diff --git a/youtube_dl/extractor/br.py b/youtube_dl/extractor/br.py index 9933607..86f0c28 100644 --- a/youtube_dl/extractor/br.py +++ b/youtube_dl/extractor/br.py @@ -7,12 +7,13 @@ from .common import InfoExtractor from ..utils import ( ExtractorError, int_or_none, + parse_duration, ) class BRIE(InfoExtractor): IE_DESC = 'Bayerischer Rundfunk Mediathek' - _VALID_URL = r'https?://(?:www\.)?br\.de/(?:[a-z0-9\-]+/)+(?P[a-z0-9\-]+)\.html' + _VALID_URL = r'https?://(?:www\.)?br\.de/(?:[a-z0-9\-_]+/)+(?P[a-z0-9\-_]+)\.html' _BASE_URL = 'http://www.br.de' _TESTS = [ @@ -22,8 +23,9 @@ class BRIE(InfoExtractor): 'info_dict': { 'id': '25e279aa-1ffd-40fd-9955-5325bd48a53a', 'ext': 'mp4', - 'title': 'Am 1. und 2. August in Oberammergau', - 'description': 'md5:dfd224e5aa6819bc1fcbb7826a932021', + 'title': 'Wenn das Traditions-Theater wackelt', + 'description': 'Heimatsound-Festival 2014: Wenn das Traditions-Theater wackelt', + 'duration': 34, } }, { @@ -34,6 +36,7 @@ class BRIE(InfoExtractor): 'ext': 'mp4', 'title': 'Über den Pass', 'description': 'Die Eroberung der Alpen: Über den Pass', + 'duration': 2588, } }, { @@ -44,6 +47,7 @@ class BRIE(InfoExtractor): 'ext': 'aac', 'title': '"Keine neuen Schulden im nächsten Jahr"', 'description': 'Haushaltsentwurf: "Keine neuen Schulden im nächsten Jahr"', + 'duration': 64, } }, { @@ -54,6 +58,7 @@ class BRIE(InfoExtractor): 'ext': 'mp4', 'title': 'Umweltbewusster Häuslebauer', 'description': 'Uwe Erdelt: Umweltbewusster Häuslebauer', + 'duration': 116, } }, { @@ -64,6 +69,7 @@ class BRIE(InfoExtractor): 'ext': 'mp4', 'title': 'Folge 1 - Metaphysik', 'description': 'Kant für Anfänger: Folge 1 - Metaphysik', + 'duration': 893, 'uploader': 'Eva Maria Steimle', 'upload_date': '20140117', } @@ -84,6 +90,7 @@ class BRIE(InfoExtractor): media = { 'id': xml_media.get('externalId'), 'title': xml_media.find('title').text, + 'duration': parse_duration(xml_media.find('duration').text), 'formats': self._extract_formats(xml_media.find('assets')), 'thumbnails': self._extract_thumbnails(xml_media.find('teaserImage/variants')), 'description': ' '.join(xml_media.find('shareTitle').text.splitlines()), diff --git a/youtube_dl/extractor/cbs.py b/youtube_dl/extractor/cbs.py index ac03158..822f9a7 100644 --- a/youtube_dl/extractor/cbs.py +++ b/youtube_dl/extractor/cbs.py @@ -1,24 +1,42 @@ +from __future__ import unicode_literals + import re from .common import InfoExtractor class CBSIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?cbs\.com/shows/[^/]+/video/(?P[^/]+)/.*' + _VALID_URL = r'https?://(?:www\.)?cbs\.com/shows/[^/]+/(?:video|artist)/(?P[^/]+)/.*' - _TEST = { - u'url': u'http://www.cbs.com/shows/garth-brooks/video/_u7W953k6la293J7EPTd9oHkSPs6Xn6_/connect-chat-feat-garth-brooks/', - u'file': u'4JUVEwq3wUT7.flv', - u'info_dict': { - u'title': u'Connect Chat feat. Garth Brooks', - u'description': u'Connect with country music singer Garth Brooks, as he chats with fans on Wednesday November 27, 2013. Be sure to tune in to Garth Brooks: Live from Las Vegas, Friday November 29, at 9/8c on CBS!', - u'duration': 1495, + _TESTS = [{ + 'url': 'http://www.cbs.com/shows/garth-brooks/video/_u7W953k6la293J7EPTd9oHkSPs6Xn6_/connect-chat-feat-garth-brooks/', + 'info_dict': { + 'id': '4JUVEwq3wUT7', + 'ext': 'flv', + 'title': 'Connect Chat feat. Garth Brooks', + 'description': 'Connect with country music singer Garth Brooks, as he chats with fans on Wednesday November 27, 2013. Be sure to tune in to Garth Brooks: Live from Las Vegas, Friday November 29, at 9/8c on CBS!', + 'duration': 1495, + }, + 'params': { + # rtmp download + 'skip_download': True, + }, + '_skip': 'Blocked outside the US', + }, { + 'url': 'http://www.cbs.com/shows/liveonletterman/artist/221752/st-vincent/', + 'info_dict': { + 'id': 'P9gjWjelt6iP', + 'ext': 'flv', + 'title': 'Live on Letterman - St. Vincent', + 'description': 'Live On Letterman: St. Vincent in concert from New York\'s Ed Sullivan Theater on Tuesday, July 16, 2014.', + 'duration': 3221, }, - u'params': { + 'params': { # rtmp download - u'skip_download': True, + 'skip_download': True, }, - } + '_skip': 'Blocked outside the US', + }] def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) @@ -26,5 +44,5 @@ class CBSIE(InfoExtractor): webpage = self._download_webpage(url, video_id) real_id = self._search_regex( r"video\.settings\.pid\s*=\s*'([^']+)';", - webpage, u'real video ID') + webpage, 'real video ID') return self.url_result(u'theplatform:%s' % real_id) diff --git a/youtube_dl/extractor/chilloutzone.py b/youtube_dl/extractor/chilloutzone.py index 02d5ba5..a62395d 100644 --- a/youtube_dl/extractor/chilloutzone.py +++ b/youtube_dl/extractor/chilloutzone.py @@ -42,7 +42,7 @@ class ChilloutzoneIE(InfoExtractor): 'id': '85523671', 'ext': 'mp4', 'title': 'The Sunday Times - Icons', - 'description': 'md5:3e1c0dc6047498d6728dcdaad0891762', + 'description': 'md5:a5f7ff82e2f7a9ed77473fe666954e84', 'uploader': 'Us', 'uploader_id': 'usfilms', 'upload_date': '20140131' diff --git a/youtube_dl/extractor/cnet.py b/youtube_dl/extractor/cnet.py index a94f425..710d500 100644 --- a/youtube_dl/extractor/cnet.py +++ b/youtube_dl/extractor/cnet.py @@ -43,7 +43,11 @@ class CNETIE(InfoExtractor): raise ExtractorError('Cannot find video data') video_id = vdata['id'] - title = vdata['headline'] + title = vdata.get('headline') + if title is None: + title = vdata.get('title') + if title is None: + raise ExtractorError('Cannot find title!') description = vdata.get('dek') thumbnail = vdata.get('image', {}).get('path') author = vdata.get('author') diff --git a/youtube_dl/extractor/comedycentral.py b/youtube_dl/extractor/comedycentral.py index 8af0aba..c81ce5a 100644 --- a/youtube_dl/extractor/comedycentral.py +++ b/youtube_dl/extractor/comedycentral.py @@ -14,13 +14,13 @@ from ..utils import ( class ComedyCentralIE(MTVServicesInfoExtractor): - _VALID_URL = r'''(?x)https?://(?:www\.)?(comedycentral|cc)\.com/ - (video-clips|episodes|cc-studios|video-collections) + _VALID_URL = r'''(?x)https?://(?:www\.)?cc\.com/ + (video-clips|episodes|cc-studios|video-collections|full-episodes) /(?P.*)''' _FEED_URL = 'http://comedycentral.com/feeds/mrss/' _TEST = { - 'url': 'http://www.comedycentral.com/video-clips/kllhuv/stand-up-greg-fitzsimmons--uncensored---too-good-of-a-mother', + 'url': 'http://www.cc.com/video-clips/kllhuv/stand-up-greg-fitzsimmons--uncensored---too-good-of-a-mother', 'md5': 'c4f48e9eda1b16dd10add0744344b6d8', 'info_dict': { 'id': 'cef0cbb3-e776-4bc9-b62e-8016deccb354', diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index e686573..342bfb8 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -18,6 +18,7 @@ from ..utils import ( clean_html, compiled_regex_type, ExtractorError, + int_or_none, RegexNotFoundError, sanitize_filename, unescapeHTML, @@ -69,6 +70,7 @@ class InfoExtractor(object): * vcodec Name of the video codec in use * container Name of the container format * filesize The number of bytes, if known in advance + * filesize_approx An estimate for the number of bytes * player_url SWF Player URL (used for rtmpdump). * protocol The protocol that will be used for the actual download, lower-case. @@ -300,8 +302,12 @@ class InfoExtractor(object): def _download_json(self, url_or_request, video_id, note=u'Downloading JSON metadata', errnote=u'Unable to download JSON metadata', - transform_source=None): - json_string = self._download_webpage(url_or_request, video_id, note, errnote) + transform_source=None, + fatal=True): + json_string = self._download_webpage( + url_or_request, video_id, note, errnote, fatal=fatal) + if (not fatal) and json_string is False: + return None if transform_source: json_string = transform_source(json_string) try: @@ -368,7 +374,8 @@ class InfoExtractor(object): else: for p in pattern: mobj = re.search(p, string, flags) - if mobj: break + if mobj: + break if os.name != 'nt' and sys.stderr.isatty(): _name = u'\033[0;34m%s\033[0m' % name @@ -468,7 +475,7 @@ class InfoExtractor(object): display_name = name return self._html_search_regex( r'''(?ix)<meta - (?=[^>]+(?:itemprop|name|property)=["\']%s["\']) + (?=[^>]+(?:itemprop|name|property)=["\']?%s["\']?) [^>]+content=["\']([^"\']+)["\']''' % re.escape(name), html, display_name, fatal=fatal, **kwargs) @@ -555,6 +562,7 @@ class InfoExtractor(object): f.get('abr') if f.get('abr') is not None else -1, audio_ext_preference, f.get('filesize') if f.get('filesize') is not None else -1, + f.get('filesize_approx') if f.get('filesize_approx') is not None else -1, f.get('format_id'), ) formats.sort(key=_formats_key) @@ -583,6 +591,24 @@ class InfoExtractor(object): self.to_screen(msg) time.sleep(timeout) + def _extract_f4m_formats(self, manifest_url, video_id): + manifest = self._download_xml( + manifest_url, video_id, 'Downloading f4m manifest', + 'Unable to download f4m manifest') + + formats = [] + for media_el in manifest.findall('{http://ns.adobe.com/f4m/1.0}media'): + formats.append({ + 'url': manifest_url, + 'ext': 'flv', + 'tbr': int_or_none(media_el.attrib.get('bitrate')), + 'width': int_or_none(media_el.attrib.get('width')), + 'height': int_or_none(media_el.attrib.get('height')), + }) + self._sort_formats(formats) + + return formats + class SearchInfoExtractor(InfoExtractor): """ diff --git a/youtube_dl/extractor/cracked.py b/youtube_dl/extractor/cracked.py new file mode 100644 index 0000000..74b880f --- /dev/null +++ b/youtube_dl/extractor/cracked.py @@ -0,0 +1,65 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + parse_iso8601, + str_to_int, +) + + +class CrackedIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?cracked\.com/video_(?P<id>\d+)_[\da-z-]+\.html' + _TEST = { + 'url': 'http://www.cracked.com/video_19006_4-plot-holes-you-didnt-notice-in-your-favorite-movies.html', + 'md5': '4b29a5eeec292cd5eca6388c7558db9e', + 'info_dict': { + 'id': '19006', + 'ext': 'mp4', + 'title': '4 Plot Holes You Didn\'t Notice in Your Favorite Movies', + 'description': 'md5:3b909e752661db86007d10e5ec2df769', + 'timestamp': 1405659600, + 'upload_date': '20140718', + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + + video_url = self._html_search_regex( + [r'var\s+CK_vidSrc\s*=\s*"([^"]+)"', r'<video\s+src="([^"]+)"'], webpage, 'video URL') + + title = self._og_search_title(webpage) + description = self._og_search_description(webpage) + + timestamp = self._html_search_regex(r'<time datetime="([^"]+)"', webpage, 'upload date', fatal=False) + if timestamp: + timestamp = parse_iso8601(timestamp[:-6]) + + view_count = str_to_int(self._html_search_regex( + r'<span class="views" id="viewCounts">([\d,\.]+) Views</span>', webpage, 'view count', fatal=False)) + comment_count = str_to_int(self._html_search_regex( + r'<span id="commentCounts">([\d,\.]+)</span>', webpage, 'comment count', fatal=False)) + + m = re.search(r'_(?P<width>\d+)X(?P<height>\d+)\.mp4$', video_url) + if m: + width = int(m.group('width')) + height = int(m.group('height')) + else: + width = height = None + + return { + 'id': video_id, + 'url':video_url, + 'title': title, + 'description': description, + 'timestamp': timestamp, + 'view_count': view_count, + 'comment_count': comment_count, + 'height': height, + 'width': width, + } \ No newline at end of file diff --git a/youtube_dl/extractor/dfb.py b/youtube_dl/extractor/dfb.py new file mode 100644 index 0000000..cb8e068 --- /dev/null +++ b/youtube_dl/extractor/dfb.py @@ -0,0 +1,44 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor + + +class DFBIE(InfoExtractor): + IE_NAME = 'tv.dfb.de' + _VALID_URL = r'https?://tv\.dfb\.de/video/[^/]+/(?P<id>\d+)' + + _TEST = { + 'url': 'http://tv.dfb.de/video/highlights-des-empfangs-in-berlin/9070/', + # The md5 is different each time + 'info_dict': { + 'id': '9070', + 'ext': 'flv', + 'title': 'Highlights des Empfangs in Berlin', + 'upload_date': '20140716', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + player_info = self._download_xml( + 'http://tv.dfb.de/server/hd_video.php?play=%s' % video_id, + video_id) + video_info = player_info.find('video') + + f4m_info = self._download_xml(video_info.find('url').text, video_id) + token_el = f4m_info.find('token') + manifest_url = token_el.attrib['url'] + '?' + 'hdnea=' + token_el.attrib['auth'] + '&hdcore=3.2.0' + + return { + 'id': video_id, + 'title': video_info.find('title').text, + 'url': manifest_url, + 'ext': 'flv', + 'thumbnail': self._og_search_thumbnail(webpage), + 'upload_date': ''.join(video_info.find('time_date').text.split('.')[::-1]), + } diff --git a/youtube_dl/extractor/dropbox.py b/youtube_dl/extractor/dropbox.py index 41208c9..9f569aa 100644 --- a/youtube_dl/extractor/dropbox.py +++ b/youtube_dl/extractor/dropbox.py @@ -5,24 +5,26 @@ import os.path import re from .common import InfoExtractor +from ..utils import compat_urllib_parse_unquote class DropboxIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?dropbox[.]com/s/(?P<id>[a-zA-Z0-9]{15})/(?P<title>[^?#]*)' _TEST = { - 'url': 'https://www.dropbox.com/s/0qr9sai2veej4f8/THE_DOCTOR_GAMES.mp4', - 'md5': '8ae17c51172fb7f93bdd6a214cc8c896', + 'url': 'https://www.dropbox.com/s/nelirfsxnmcfbfh/youtube-dl%20test%20video%20%27%C3%A4%22BaW_jenozKc.mp4', + 'md5': '8a3d905427a6951ccb9eb292f154530b', 'info_dict': { - 'id': '0qr9sai2veej4f8', + 'id': 'nelirfsxnmcfbfh', 'ext': 'mp4', - 'title': 'THE_DOCTOR_GAMES' + 'title': 'youtube-dl test video \'ä"BaW_jenozKc' } } def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('id') - title = os.path.splitext(mobj.group('title'))[0] + fn = compat_urllib_parse_unquote(mobj.group('title')) + title = os.path.splitext(fn)[0] video_url = url + '?dl=1' return { diff --git a/youtube_dl/extractor/firedrive.py b/youtube_dl/extractor/firedrive.py index d26145d..6d73c8a 100644 --- a/youtube_dl/extractor/firedrive.py +++ b/youtube_dl/extractor/firedrive.py @@ -8,7 +8,6 @@ from ..utils import ( ExtractorError, compat_urllib_parse, compat_urllib_request, - determine_ext, ) diff --git a/youtube_dl/extractor/francetv.py b/youtube_dl/extractor/francetv.py index f3e0f38..1b0e8e5 100644 --- a/youtube_dl/extractor/francetv.py +++ b/youtube_dl/extractor/francetv.py @@ -19,17 +19,35 @@ class FranceTVBaseInfoExtractor(InfoExtractor): + video_id, video_id, 'Downloading XML config') manifest_url = info.find('videos/video/url').text - video_url = manifest_url.replace('manifest.f4m', 'index_2_av.m3u8') - video_url = video_url.replace('/z/', '/i/') + manifest_url = manifest_url.replace('/z/', '/i/') + + if manifest_url.startswith('rtmp'): + formats = [{'url': manifest_url, 'ext': 'flv'}] + else: + formats = [] + available_formats = self._search_regex(r'/[^,]*,(.*?),k\.mp4', manifest_url, 'available formats') + for index, format_descr in enumerate(available_formats.split(',')): + format_info = { + 'url': manifest_url.replace('manifest.f4m', 'index_%d_av.m3u8' % index), + 'ext': 'mp4', + } + m_resolution = re.search(r'(?P<width>\d+)x(?P<height>\d+)', format_descr) + if m_resolution is not None: + format_info.update({ + 'width': int(m_resolution.group('width')), + 'height': int(m_resolution.group('height')), + }) + formats.append(format_info) + thumbnail_path = info.find('image').text - return {'id': video_id, - 'ext': 'flv' if video_url.startswith('rtmp') else 'mp4', - 'url': video_url, - 'title': info.find('titre').text, - 'thumbnail': compat_urlparse.urljoin('http://pluzz.francetv.fr', thumbnail_path), - 'description': info.find('synopsis').text, - } + return { + 'id': video_id, + 'title': info.find('titre').text, + 'formats': formats, + 'thumbnail': compat_urlparse.urljoin('http://pluzz.francetv.fr', thumbnail_path), + 'description': info.find('synopsis').text, + } class PluzzIE(FranceTVBaseInfoExtractor): @@ -48,7 +66,7 @@ class PluzzIE(FranceTVBaseInfoExtractor): class FranceTvInfoIE(FranceTVBaseInfoExtractor): IE_NAME = 'francetvinfo.fr' - _VALID_URL = r'https?://www\.francetvinfo\.fr/.*/(?P<title>.+)\.html' + _VALID_URL = r'https?://(?:www|mobile)\.francetvinfo\.fr/.*/(?P<title>.+)\.html' _TESTS = [{ 'url': 'http://www.francetvinfo.fr/replay-jt/france-3/soir-3/jt-grand-soir-3-lundi-26-aout-2013_393427.html', @@ -211,7 +229,7 @@ class GenerationQuoiIE(InfoExtractor): class CultureboxIE(FranceTVBaseInfoExtractor): IE_NAME = 'culturebox.francetvinfo.fr' - _VALID_URL = r'https?://culturebox\.francetvinfo\.fr/(?P<name>.*?)(\?|$)' + _VALID_URL = r'https?://(?:m\.)?culturebox\.francetvinfo\.fr/(?P<name>.*?)(\?|$)' _TEST = { 'url': 'http://culturebox.francetvinfo.fr/einstein-on-the-beach-au-theatre-du-chatelet-146813', diff --git a/youtube_dl/extractor/funnyordie.py b/youtube_dl/extractor/funnyordie.py index 6e6b666..721e5fc 100644 --- a/youtube_dl/extractor/funnyordie.py +++ b/youtube_dl/extractor/funnyordie.py @@ -26,7 +26,7 @@ class FunnyOrDieIE(InfoExtractor): 'id': 'e402820827', 'ext': 'mp4', 'title': 'Please Use This Song (Jon Lajoie)', - 'description': 'md5:2ed27d364f5a805a6dba199faaf6681d', + 'description': 'Please use this to sell something. www.jonlajoie.com', 'thumbnail': 're:^http:.*\.jpg$', }, }] diff --git a/youtube_dl/extractor/gamestar.py b/youtube_dl/extractor/gamestar.py new file mode 100644 index 0000000..50f8fc7 --- /dev/null +++ b/youtube_dl/extractor/gamestar.py @@ -0,0 +1,74 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + parse_duration, + str_to_int, + unified_strdate, +) + + +class GameStarIE(InfoExtractor): + _VALID_URL = r'http://www\.gamestar\.de/videos/.*,(?P<id>[0-9]+)\.html' + _TEST = { + 'url': 'http://www.gamestar.de/videos/trailer,3/hobbit-3-die-schlacht-der-fuenf-heere,76110.html', + 'md5': '96974ecbb7fd8d0d20fca5a00810cea7', + 'info_dict': { + 'id': '76110', + 'ext': 'mp4', + 'title': 'Hobbit 3: Die Schlacht der Fünf Heere - Teaser-Trailer zum dritten Teil', + 'description': 'Der Teaser-Trailer zu Hobbit 3: Die Schlacht der Fünf Heere zeigt einige Szenen aus dem dritten Teil der Saga und kündigt den vollständigen Trailer an.', + 'thumbnail': 'http://images.gamestar.de/images/idgwpgsgp/bdb/2494525/600x.jpg', + 'upload_date': '20140728', + 'duration': 17 + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + + og_title = self._og_search_title(webpage) + title = og_title.replace(' - Video bei GameStar.de', '').strip() + + url = 'http://gamestar.de/_misc/videos/portal/getVideoUrl.cfm?premium=0&videoId=' + video_id + + description = self._og_search_description(webpage).strip() + + thumbnail = self._proto_relative_url( + self._og_search_thumbnail(webpage), scheme='http:') + + upload_date = unified_strdate(self._html_search_regex( + r'<span style="float:left;font-size:11px;">Datum: ([0-9]+\.[0-9]+\.[0-9]+)  ', + webpage, 'upload_date', fatal=False)) + + duration = parse_duration(self._html_search_regex( + r'  Länge: ([0-9]+:[0-9]+)</span>', webpage, 'duration', + fatal=False)) + + view_count = str_to_int(self._html_search_regex( + r'  Zuschauer: ([0-9\.]+)  ', webpage, + 'view_count', fatal=False)) + + comment_count = int_or_none(self._html_search_regex( + r'>Kommentieren \(([0-9]+)\)</a>', webpage, 'comment_count', + fatal=False)) + + return { + 'id': video_id, + 'title': title, + 'url': url, + 'ext': 'mp4', + 'thumbnail': thumbnail, + 'description': description, + 'upload_date': upload_date, + 'duration': duration, + 'view_count': view_count, + 'comment_count': comment_count + } diff --git a/youtube_dl/extractor/gdcvault.py b/youtube_dl/extractor/gdcvault.py index 89d5994..de14ae1 100644 --- a/youtube_dl/extractor/gdcvault.py +++ b/youtube_dl/extractor/gdcvault.py @@ -8,6 +8,7 @@ from ..utils import ( compat_urllib_request, ) + class GDCVaultIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?gdcvault\.com/play/(?P<id>\d+)/(?P<name>(\w|-)+)' _TESTS = [ @@ -31,6 +32,15 @@ class GDCVaultIE(InfoExtractor): 'skip_download': True, # Requires rtmpdump } }, + { + 'url': 'http://www.gdcvault.com/play/1015301/Thexder-Meets-Windows-95-or', + 'md5': 'a5eb77996ef82118afbbe8e48731b98e', + 'info_dict': { + 'id': '1015301', + 'ext': 'flv', + 'title': 'Thexder Meets Windows 95, or Writing Great Games in the Windows 95 Environment', + } + } ] def _parse_mp4(self, xml_description): @@ -103,18 +113,40 @@ class GDCVaultIE(InfoExtractor): webpage_url = 'http://www.gdcvault.com/play/' + video_id start_page = self._download_webpage(webpage_url, video_id) - xml_root = self._html_search_regex(r'<iframe src="(?P<xml_root>.*?)player.html.*?".*?</iframe>', start_page, 'xml root', None, False) + direct_url = self._search_regex( + r's1\.addVariable\("file",\s*encodeURIComponent\("(/[^"]+)"\)\);', + start_page, 'url', default=None) + if direct_url: + video_url = 'http://www.gdcvault.com/' + direct_url + title = self._html_search_regex( + r'<td><strong>Session Name</strong></td>\s*<td>(.*?)</td>', + start_page, 'title') + + return { + 'id': video_id, + 'url': video_url, + 'ext': 'flv', + 'title': title, + } + xml_root = self._html_search_regex( + r'<iframe src="(?P<xml_root>.*?)player.html.*?".*?</iframe>', + start_page, 'xml root', default=None) if xml_root is None: # Probably need to authenticate - start_page = self._login(webpage_url, video_id) - if start_page is None: + login_res = self._login(webpage_url, video_id) + if login_res is None: self.report_warning('Could not login.') else: + start_page = login_res # Grab the url from the authenticated page - xml_root = self._html_search_regex(r'<iframe src="(?P<xml_root>.*?)player.html.*?".*?</iframe>', start_page, 'xml root') + xml_root = self._html_search_regex( + r'<iframe src="(.*?)player.html.*?".*?</iframe>', + start_page, 'xml root') - xml_name = self._html_search_regex(r'<iframe src=".*?\?xml=(?P<xml_file>.+?\.xml).*?".*?</iframe>', start_page, 'xml filename', None, False) + xml_name = self._html_search_regex( + r'<iframe src=".*?\?xml=(.+?\.xml).*?".*?</iframe>', + start_page, 'xml filename', default=None) if xml_name is None: # Fallback to the older format xml_name = self._html_search_regex(r'<iframe src=".*?\?xmlURL=xml/(?P<xml_file>.+?\.xml).*?".*?</iframe>', start_page, 'xml filename') diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index f97b598..bcb0765 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -383,13 +383,13 @@ class GenericIE(InfoExtractor): if not parsed_url.scheme: default_search = self._downloader.params.get('default_search') if default_search is None: - default_search = 'error' + default_search = 'fixup_error' - if default_search in ('auto', 'auto_warning'): + if default_search in ('auto', 'auto_warning', 'fixup_error'): if '/' in url: self._downloader.report_warning('The url doesn\'t specify the protocol, trying with http') return self.url_result('http://' + url) - else: + elif default_search != 'fixup_error': if default_search == 'auto_warning': if re.match(r'^(?:url|URL)$', url): raise ExtractorError( @@ -399,10 +399,11 @@ class GenericIE(InfoExtractor): self._downloader.report_warning( 'Falling back to youtube search for %s . Set --default-search "auto" to suppress this warning.' % url) return self.url_result('ytsearch:' + url) - elif default_search == 'error': + + if default_search in ('error', 'fixup_error'): raise ExtractorError( ('%r is not a valid URL. ' - 'Set --default-search "ytseach" (or run youtube-dl "ytsearch:%s" ) to search YouTube' + 'Set --default-search "ytsearch" (or run youtube-dl "ytsearch:%s" ) to search YouTube' ) % (url, url), expected=True) else: assert ':' in default_search diff --git a/youtube_dl/extractor/godtube.py b/youtube_dl/extractor/godtube.py new file mode 100644 index 0000000..73bd6d8 --- /dev/null +++ b/youtube_dl/extractor/godtube.py @@ -0,0 +1,58 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + parse_duration, + parse_iso8601, +) + + +class GodTubeIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?godtube\.com/watch/\?v=(?P<id>[\da-zA-Z]+)' + _TESTS = [ + { + 'url': 'https://www.godtube.com/watch/?v=0C0CNNNU', + 'md5': '77108c1e4ab58f48031101a1a2119789', + 'info_dict': { + 'id': '0C0CNNNU', + 'ext': 'mp4', + 'title': 'Woman at the well.', + 'duration': 159, + 'timestamp': 1205712000, + 'uploader': 'beverlybmusic', + 'upload_date': '20080317', + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, + ] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + config = self._download_xml( + 'http://www.godtube.com/resource/mediaplayer/%s.xml' % video_id.lower(), + video_id, 'Downloading player config XML') + + video_url = config.find('.//file').text + uploader = config.find('.//author').text + timestamp = parse_iso8601(config.find('.//date').text) + duration = parse_duration(config.find('.//duration').text) + thumbnail = config.find('.//image').text + + media = self._download_xml( + 'http://www.godtube.com/media/xml/?v=%s' % video_id, video_id, 'Downloading media XML') + + title = media.find('.//title').text + + return { + 'id': video_id, + 'url': video_url, + 'title': title, + 'thumbnail': thumbnail, + 'timestamp': timestamp, + 'uploader': uploader, + 'duration': duration, + } diff --git a/youtube_dl/extractor/izlesene.py b/youtube_dl/extractor/izlesene.py new file mode 100644 index 0000000..79e8430 --- /dev/null +++ b/youtube_dl/extractor/izlesene.py @@ -0,0 +1,97 @@ +# coding: utf-8 +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + get_element_by_id, + parse_iso8601, + determine_ext, + int_or_none, + str_to_int, +) + + +class IzleseneIE(InfoExtractor): + _VALID_URL = r'https?://(?:(?:www|m)\.)?izlesene\.com/(?:video|embedplayer)/(?:[^/]+/)?(?P<id>[0-9]+)' + _STREAM_URL = 'http://panel.izlesene.com/api/streamurl/{id:}/{format:}' + _TEST = { + 'url': 'http://www.izlesene.com/video/sevincten-cildirtan-dogum-gunu-hediyesi/7599694', + 'md5': '4384f9f0ea65086734b881085ee05ac2', + 'info_dict': { + 'id': '7599694', + 'ext': 'mp4', + 'title': 'Sevinçten Çıldırtan Doğum Günü Hediyesi', + 'description': 'Annesi oğluna doğum günü hediyesi olarak minecraft cd si alıyor, ve çocuk hunharca seviniyor', + 'thumbnail': 're:^http://.*\.jpg', + 'uploader_id': 'pelikzzle', + 'timestamp': 1404298698, + 'upload_date': '20140702', + 'duration': 95.395, + 'age_limit': 0, + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + url = 'http://www.izlesene.com/video/%s' % video_id + + webpage = self._download_webpage(url, video_id) + + title = self._og_search_title(webpage) + description = self._og_search_description(webpage) + thumbnail = self._og_search_thumbnail(webpage) + + uploader = self._html_search_regex( + r"adduserUsername\s*=\s*'([^']+)';", webpage, 'uploader', fatal=False, default='') + timestamp = parse_iso8601(self._html_search_meta( + 'uploadDate', webpage, 'upload date', fatal=False)) + + duration = int_or_none(self._html_search_regex( + r'"videoduration"\s*:\s*"([^"]+)"', webpage, 'duration', fatal=False)) + if duration: + duration /= 1000.0 + + view_count = str_to_int(get_element_by_id('videoViewCount', webpage)) + comment_count = self._html_search_regex( + r'comment_count\s*=\s*\'([^\']+)\';', webpage, 'uploader', fatal=False) + + family_friendly = self._html_search_meta( + 'isFamilyFriendly', webpage, 'age limit', fatal=False) + + content_url = self._html_search_meta( + 'contentURL', webpage, 'content URL', fatal=False) + ext = determine_ext(content_url, 'mp4') + + # Might be empty for some videos. + qualities = self._html_search_regex( + r'"quality"\s*:\s*"([^"]+)"', webpage, 'qualities', fatal=False, default='') + + formats = [] + for quality in qualities.split('|'): + json = self._download_json( + self._STREAM_URL.format(id=video_id, format=quality), video_id, + note='Getting video URL for "%s" quality' % quality, + errnote='Failed to get video URL for "%s" quality' % quality + ) + formats.append({ + 'url': json.get('streamurl'), + 'ext': ext, + 'format_id': '%sp' % quality if quality else 'sd', + }) + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'uploader_id': uploader, + 'timestamp': timestamp, + 'duration': duration, + 'view_count': int_or_none(view_count), + 'comment_count': int_or_none(comment_count), + 'age_limit': 18 if family_friendly == 'False' else 0, + 'formats': formats, + } diff --git a/youtube_dl/extractor/justintv.py b/youtube_dl/extractor/justintv.py index 7083db1..27017e8 100644 --- a/youtube_dl/extractor/justintv.py +++ b/youtube_dl/extractor/justintv.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import itertools import json import os import re @@ -43,10 +44,11 @@ class JustinTVIE(InfoExtractor): } # Return count of items, list of *valid* items - def _parse_page(self, url, video_id): - info_json = self._download_webpage(url, video_id, - 'Downloading video info JSON', - 'unable to download video info JSON') + def _parse_page(self, url, video_id, counter): + info_json = self._download_webpage( + url, video_id, + 'Downloading video info JSON on page %d' % counter, + 'Unable to download video info JSON %d' % counter) response = json.loads(info_json) if type(response) != list: @@ -138,11 +140,10 @@ class JustinTVIE(InfoExtractor): entries = [] offset = 0 limit = self._JUSTIN_PAGE_LIMIT - while True: - if paged: - self.report_download_page(video_id, offset) + for counter in itertools.count(1): page_url = api + ('?offset=%d&limit=%d' % (offset, limit)) - page_count, page_info = self._parse_page(page_url, video_id) + page_count, page_info = self._parse_page( + page_url, video_id, counter) entries.extend(page_info) if not paged or page_count != limit: break diff --git a/youtube_dl/extractor/kickstarter.py b/youtube_dl/extractor/kickstarter.py index 961dd1a..56a7638 100644 --- a/youtube_dl/extractor/kickstarter.py +++ b/youtube_dl/extractor/kickstarter.py @@ -8,7 +8,7 @@ from .common import InfoExtractor class KickStarterIE(InfoExtractor): _VALID_URL = r'https?://www\.kickstarter\.com/projects/(?P<id>[^/]*)/.*' - _TEST = { + _TESTS = [{ 'url': 'https://www.kickstarter.com/projects/1404461844/intersection-the-story-of-josh-grant?ref=home_location', 'md5': 'c81addca81327ffa66c642b5d8b08cab', 'info_dict': { @@ -18,22 +18,45 @@ class KickStarterIE(InfoExtractor): 'description': 'A unique motocross documentary that examines the ' 'life and mind of one of sports most elite athletes: Josh Grant.', }, - } + }, { + 'note': 'Embedded video (not using the native kickstarter video service)', + 'url': 'https://www.kickstarter.com/projects/597507018/pebble-e-paper-watch-for-iphone-and-android/posts/659178', + 'playlist': [ + { + 'info_dict': { + 'id': '78704821', + 'ext': 'mp4', + 'uploader_id': 'pebble', + 'uploader': 'Pebble Technology', + 'title': 'Pebble iOS Notifications', + } + } + ], + }] def _real_extract(self, url): m = re.match(self._VALID_URL, url) video_id = m.group('id') webpage = self._download_webpage(url, video_id) - video_url = self._search_regex(r'data-video-url="(.*?)"', - webpage, 'video URL') - video_title = self._html_search_regex(r'<title>(.*?)', - webpage, 'title').rpartition('— Kickstarter')[0].strip() + title = self._html_search_regex( + r'\s*(.*?)(?:\s*— Kickstarter)?\s*', + webpage, 'title') + video_url = self._search_regex( + r'data-video-url="(.*?)"', + webpage, 'video URL', default=None) + if video_url is None: # No native kickstarter, look for embedded videos + return { + '_type': 'url_transparent', + 'ie_key': 'Generic', + 'url': url, + 'title': title, + } return { 'id': video_id, 'url': video_url, - 'title': video_title, + 'title': title, 'description': self._og_search_description(webpage), 'thumbnail': self._og_search_thumbnail(webpage), } diff --git a/youtube_dl/extractor/krasview.py b/youtube_dl/extractor/krasview.py new file mode 100644 index 0000000..6f3d234 --- /dev/null +++ b/youtube_dl/extractor/krasview.py @@ -0,0 +1,59 @@ +# encoding: utf-8 +from __future__ import unicode_literals + +import json +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + unescapeHTML, +) + + +class KrasViewIE(InfoExtractor): + IE_DESC = 'Красвью' + _VALID_URL = r'https?://krasview\.ru/video/(?P\d+)' + + _TEST = { + 'url': 'http://krasview.ru/video/512228', + 'md5': '3b91003cf85fc5db277870c8ebd98eae', + 'info_dict': { + 'id': '512228', + 'ext': 'mp4', + 'title': 'Снег, лёд, заносы', + 'description': 'Снято в городе Нягань, в Ханты-Мансийском автономном округе.', + 'duration': 27, + 'thumbnail': 're:^https?://.*\.jpg', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + + flashvars = json.loads(self._search_regex( + r'flashvars\s*:\s*({.+?})\s*}\);', webpage, 'flashvars')) + + video_url = flashvars['url'] + title = unescapeHTML(flashvars['title']) + description = unescapeHTML(flashvars.get('subtitle') or self._og_search_description(webpage, default=None)) + thumbnail = flashvars['image'] + duration = int(flashvars['duration']) + filesize = int(flashvars['size']) + width = int_or_none(self._og_search_property('video:width', webpage, 'video width')) + height = int_or_none(self._og_search_property('video:height', webpage, 'video height')) + + return { + 'id': video_id, + 'url': video_url, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'duration': duration, + 'filesize': filesize, + 'width': width, + 'height': height, + } diff --git a/youtube_dl/extractor/livestream.py b/youtube_dl/extractor/livestream.py index 2c100d4..c0c2d9b 100644 --- a/youtube_dl/extractor/livestream.py +++ b/youtube_dl/extractor/livestream.py @@ -5,11 +5,14 @@ import json from .common import InfoExtractor from ..utils import ( + compat_str, compat_urllib_parse_urlparse, compat_urlparse, - xpath_with_ns, - compat_str, + ExtractorError, + find_xpath_attr, + int_or_none, orderedSet, + xpath_with_ns, ) @@ -24,18 +27,82 @@ class LivestreamIE(InfoExtractor): 'ext': 'mp4', 'title': 'Live from Webster Hall NYC', 'upload_date': '20121012', + 'like_count': int, + 'view_count': int, + 'thumbnail': 're:^http://.*\.jpg$' } } + def _parse_smil(self, video_id, smil_url): + formats = [] + _SWITCH_XPATH = ( + './/{http://www.w3.org/2001/SMIL20/Language}body/' + '{http://www.w3.org/2001/SMIL20/Language}switch') + smil_doc = self._download_xml( + smil_url, video_id, + note='Downloading SMIL information', + errnote='Unable to download SMIL information', + fatal=False) + if smil_doc is False: # Download failed + return formats + title_node = find_xpath_attr( + smil_doc, './/{http://www.w3.org/2001/SMIL20/Language}meta', + 'name', 'title') + if title_node is None: + self.report_warning('Cannot find SMIL id') + switch_node = smil_doc.find(_SWITCH_XPATH) + else: + title_id = title_node.attrib['content'] + switch_node = find_xpath_attr( + smil_doc, _SWITCH_XPATH, 'id', title_id) + if switch_node is None: + raise ExtractorError('Cannot find switch node') + video_nodes = switch_node.findall( + '{http://www.w3.org/2001/SMIL20/Language}video') + + for vn in video_nodes: + tbr = int_or_none(vn.attrib.get('system-bitrate')) + furl = ( + 'http://livestream-f.akamaihd.net/%s?v=3.0.3&fp=WIN%%2014,0,0,145' % + (vn.attrib['src'])) + if 'clipBegin' in vn.attrib: + furl += '&ssek=' + vn.attrib['clipBegin'] + formats.append({ + 'url': furl, + 'format_id': 'smil_%d' % tbr, + 'ext': 'flv', + 'tbr': tbr, + 'preference': -1000, + }) + return formats + def _extract_video_info(self, video_data): - video_url = video_data.get('progressive_url_hd') or video_data.get('progressive_url') + video_id = compat_str(video_data['id']) + + FORMAT_KEYS = ( + ('sd', 'progressive_url'), + ('hd', 'progressive_url_hd'), + ) + formats = [{ + 'format_id': format_id, + 'url': video_data[key], + 'quality': i + 1, + } for i, (format_id, key) in enumerate(FORMAT_KEYS) + if video_data.get(key)] + + smil_url = video_data.get('smil_url') + if smil_url: + formats.extend(self._parse_smil(video_id, smil_url)) + self._sort_formats(formats) + return { - 'id': compat_str(video_data['id']), - 'url': video_url, - 'ext': 'mp4', + 'id': video_id, + 'formats': formats, 'title': video_data['caption'], - 'thumbnail': video_data['thumbnail_url'], + 'thumbnail': video_data.get('thumbnail_url'), 'upload_date': video_data['updated_at'].replace('-', '')[:8], + 'like_count': video_data.get('likes', {}).get('total'), + 'view_count': video_data.get('views'), } def _real_extract(self, url): @@ -50,7 +117,8 @@ class LivestreamIE(InfoExtractor): r'window.config = ({.*?});', webpage, 'window config') info = json.loads(config_json)['event'] videos = [self._extract_video_info(video_data['data']) - for video_data in info['feed']['data'] if video_data['type'] == 'video'] + for video_data in info['feed']['data'] + if video_data['type'] == 'video'] return self.playlist_result(videos, info['id'], info['full_name']) else: og_video = self._og_search_video_url(webpage, 'player url') diff --git a/youtube_dl/extractor/mlb.py b/youtube_dl/extractor/mlb.py new file mode 100644 index 0000000..37c72bc --- /dev/null +++ b/youtube_dl/extractor/mlb.py @@ -0,0 +1,116 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + parse_duration, + parse_iso8601, + find_xpath_attr, +) + + +class MLBIE(InfoExtractor): + _VALID_URL = r'https?://m\.mlb\.com/(?:.*?/)?video/(?:topic/[\da-z_-]+/)?v(?Pn?\d+)' + _TESTS = [ + { + 'url': 'http://m.mlb.com/sea/video/topic/51231442/v34698933/nymsea-ackley-robs-a-home-run-with-an-amazing-catch/?c_id=sea', + 'md5': 'ff56a598c2cf411a9a38a69709e97079', + 'info_dict': { + 'id': '34698933', + 'ext': 'mp4', + 'title': "Ackley's spectacular catch", + 'description': 'md5:7f5a981eb4f3cbc8daf2aeffa2215bf0', + 'duration': 66, + 'timestamp': 1405980600, + 'upload_date': '20140721', + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, + { + 'url': 'http://m.mlb.com/video/topic/81536970/v34496663/mianym-stanton-practices-for-the-home-run-derby', + 'md5': 'd9c022c10d21f849f49c05ae12a8a7e9', + 'info_dict': { + 'id': '34496663', + 'ext': 'mp4', + 'title': 'Stanton prepares for Derby', + 'description': 'md5:d00ce1e5fd9c9069e9c13ab4faedfa57', + 'duration': 46, + 'timestamp': 1405105800, + 'upload_date': '20140711', + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, + { + 'url': 'http://m.mlb.com/video/topic/vtp_hrd_sponsor/v34578115/hrd-cespedes-wins-2014-gillette-home-run-derby', + 'md5': '0e6e73d509321e142409b695eadd541f', + 'info_dict': { + 'id': '34578115', + 'ext': 'mp4', + 'title': 'Cespedes repeats as Derby champ', + 'description': 'md5:08df253ce265d4cf6fb09f581fafad07', + 'duration': 488, + 'timestamp': 1405399936, + 'upload_date': '20140715', + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, + { + 'url': 'http://m.mlb.com/video/v34577915/bautista-on-derby-captaining-duties-his-performance', + 'md5': 'b8fd237347b844365d74ea61d4245967', + 'info_dict': { + 'id': '34577915', + 'ext': 'mp4', + 'title': 'Bautista on Home Run Derby', + 'description': 'md5:b80b34031143d0986dddc64a8839f0fb', + 'duration': 52, + 'timestamp': 1405390722, + 'upload_date': '20140715', + 'thumbnail': 're:^https?://.*\.jpg$', + }, + }, + ] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + detail = self._download_xml( + 'http://m.mlb.com/gen/multimedia/detail/%s/%s/%s/%s.xml' + % (video_id[-3], video_id[-2], video_id[-1], video_id), video_id) + + title = detail.find('./headline').text + description = detail.find('./big-blurb').text + duration = parse_duration(detail.find('./duration').text) + timestamp = parse_iso8601(detail.attrib['date'][:-5]) + + thumbnail = find_xpath_attr( + detail, './thumbnailScenarios/thumbnailScenario', 'type', '45').text + + formats = [] + for media_url in detail.findall('./url'): + playback_scenario = media_url.attrib['playback_scenario'] + fmt = { + 'url': media_url.text, + 'format_id': playback_scenario, + } + m = re.search(r'(?P\d+)K_(?P\d+)X(?P\d+)', playback_scenario) + if m: + fmt.update({ + 'vbr': int(m.group('vbr')) * 1000, + 'width': int(m.group('width')), + 'height': int(m.group('height')), + }) + formats.append(fmt) + + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'duration': duration, + 'timestamp': timestamp, + 'formats': formats, + 'thumbnail': thumbnail, + } diff --git a/youtube_dl/extractor/nbc.py b/youtube_dl/extractor/nbc.py index aa34665..d2e4acb 100644 --- a/youtube_dl/extractor/nbc.py +++ b/youtube_dl/extractor/nbc.py @@ -4,7 +4,11 @@ import re import json from .common import InfoExtractor -from ..utils import find_xpath_attr, compat_str +from ..utils import ( + compat_str, + ExtractorError, + find_xpath_attr, +) class NBCIE(InfoExtractor): @@ -85,11 +89,25 @@ class NBCNewsIE(InfoExtractor): flags=re.MULTILINE) bootstrap = json.loads(bootstrap_json) info = bootstrap['results'][0]['video'] - playlist_url = info['fallbackPlaylistUrl'] + '?form=MPXNBCNewsAPI' mpxid = info['mpxId'] - all_videos = self._download_json(playlist_url, title)['videos'] - # The response contains additional videos - info = next(v for v in all_videos if v['mpxId'] == mpxid) + + base_urls = [ + info['fallbackPlaylistUrl'], + info['associatedPlaylistUrl'], + ] + + for base_url in base_urls: + playlist_url = base_url + '?form=MPXNBCNewsAPI' + all_videos = self._download_json(playlist_url, title)['videos'] + + try: + info = next(v for v in all_videos if v['mpxId'] == mpxid) + break + except StopIteration: + continue + + if info is None: + raise ExtractorError('Could not find video in playlists') return { '_type': 'url', diff --git a/youtube_dl/extractor/npo.py b/youtube_dl/extractor/npo.py index fbcbe1f..12e85a7 100644 --- a/youtube_dl/extractor/npo.py +++ b/youtube_dl/extractor/npo.py @@ -32,7 +32,7 @@ class NPOIE(InfoExtractor): 'http://e.omroep.nl/metadata/aflevering/%s' % video_id, video_id, # We have to remove the javascript callback - transform_source=lambda j: re.sub(r'parseMetadata\((.*?)\);\n//epc', r'\1', j) + transform_source=lambda j: re.sub(r'parseMetadata\((.*?)\);\n//.*$', r'\1', j) ) token_page = self._download_webpage( 'http://ida.omroep.nl/npoplayer/i.js', diff --git a/youtube_dl/extractor/pbs.py b/youtube_dl/extractor/pbs.py index 64cded7..ec95d07 100644 --- a/youtube_dl/extractor/pbs.py +++ b/youtube_dl/extractor/pbs.py @@ -32,13 +32,21 @@ class PBSIE(InfoExtractor): }, } - def _real_extract(self, url): + def _extract_ids(self, url): mobj = re.match(self._VALID_URL, url) presumptive_id = mobj.group('presumptive_id') display_id = presumptive_id if presumptive_id: webpage = self._download_webpage(url, display_id) + + # frontline video embed + media_id = self._search_regex( + r"div\s*:\s*'videoembed'\s*,\s*mediaid\s*:\s*'(\d+)'", + webpage, 'frontline video ID', fatal=False, default=None) + if media_id: + return media_id, presumptive_id + url = self._search_regex( r'', webpage, 'player URL') @@ -57,6 +65,11 @@ class PBSIE(InfoExtractor): video_id = mobj.group('id') display_id = video_id + return video_id, display_id + + def _real_extract(self, url): + video_id, display_id = self._extract_ids(url) + info_url = 'http://video.pbs.org/videoInfo/%s?format=json' % video_id info = self._download_json(info_url, display_id) diff --git a/youtube_dl/extractor/redtube.py b/youtube_dl/extractor/redtube.py index 4295cf9..d1e12dd 100644 --- a/youtube_dl/extractor/redtube.py +++ b/youtube_dl/extractor/redtube.py @@ -35,9 +35,7 @@ class RedTubeIE(InfoExtractor): r'

    (.+?)

    ', webpage, u'title') - video_thumbnail = self._html_search_regex( - r'playerInnerHTML.+?[\da-zA-Z]{20})' + + _TESTS = [ + { + 'url': 'http://videos.sapo.pt/UBz95kOtiWYUMTA5Ghfi', + 'md5': '79ee523f6ecb9233ac25075dee0eda83', + 'note': 'SD video', + 'info_dict': { + 'id': 'UBz95kOtiWYUMTA5Ghfi', + 'ext': 'mp4', + 'title': 'Benfica - Marcas na Hitória', + 'description': 'md5:c9082000a128c3fd57bf0299e1367f22', + 'duration': 264, + 'uploader': 'tiago_1988', + 'upload_date': '20080229', + 'categories': ['benfica', 'cabral', 'desporto', 'futebol', 'geovanni', 'hooijdonk', 'joao', 'karel', 'lisboa', 'miccoli'], + }, + }, + { + 'url': 'http://videos.sapo.pt/IyusNAZ791ZdoCY5H5IF', + 'md5': '90a2f283cfb49193fe06e861613a72aa', + 'note': 'HD video', + 'info_dict': { + 'id': 'IyusNAZ791ZdoCY5H5IF', + 'ext': 'mp4', + 'title': 'Codebits VII - Report', + 'description': 'md5:6448d6fd81ce86feac05321f354dbdc8', + 'duration': 144, + 'uploader': 'codebits', + 'upload_date': '20140427', + 'categories': ['codebits', 'codebits2014'], + }, + }, + { + 'url': 'http://v2.videos.sapo.pt/yLqjzPtbTimsn2wWBKHz', + 'md5': 'e5aa7cc0bdc6db9b33df1a48e49a15ac', + 'note': 'v2 video', + 'info_dict': { + 'id': 'yLqjzPtbTimsn2wWBKHz', + 'ext': 'mp4', + 'title': 'Hipnose Condicionativa 4', + 'description': 'md5:ef0481abf8fb4ae6f525088a6dadbc40', + 'duration': 692, + 'uploader': 'sapozen', + 'upload_date': '20090609', + 'categories': ['condicionativa', 'heloisa', 'hipnose', 'miranda', 'sapo', 'zen'], + }, + }, + ] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + item = self._download_xml( + 'http://rd3.videos.sapo.pt/%s/rss2' % video_id, video_id).find('./channel/item') + + title = item.find('./title').text + description = item.find('./{http://videos.sapo.pt/mrss/}synopse').text + thumbnail = item.find('./{http://search.yahoo.com/mrss/}content').get('url') + duration = parse_duration(item.find('./{http://videos.sapo.pt/mrss/}time').text) + uploader = item.find('./{http://videos.sapo.pt/mrss/}author').text + upload_date = unified_strdate(item.find('./pubDate').text) + view_count = int(item.find('./{http://videos.sapo.pt/mrss/}views').text) + comment_count = int(item.find('./{http://videos.sapo.pt/mrss/}comment_count').text) + tags = item.find('./{http://videos.sapo.pt/mrss/}tags').text + categories = tags.split() if tags else [] + age_limit = 18 if item.find('./{http://videos.sapo.pt/mrss/}m18').text == 'true' else 0 + + video_url = item.find('./{http://videos.sapo.pt/mrss/}videoFile').text + video_size = item.find('./{http://videos.sapo.pt/mrss/}videoSize').text.split('x') + + formats = [{ + 'url': video_url, + 'ext': 'mp4', + 'format_id': 'sd', + 'width': int(video_size[0]), + 'height': int(video_size[1]), + }] + + if item.find('./{http://videos.sapo.pt/mrss/}HD').text == 'true': + formats.append({ + 'url': re.sub(r'/mov/1$', '/mov/39', video_url), + 'ext': 'mp4', + 'format_id': 'hd', + 'width': 1280, + 'height': 720, + }) + + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'duration': duration, + 'uploader': uploader, + 'upload_date': upload_date, + 'view_count': view_count, + 'comment_count': comment_count, + 'categories': categories, + 'age_limit': age_limit, + 'formats': formats, + } diff --git a/youtube_dl/extractor/savefrom.py b/youtube_dl/extractor/savefrom.py index 198a08c..5b7367b 100644 --- a/youtube_dl/extractor/savefrom.py +++ b/youtube_dl/extractor/savefrom.py @@ -20,7 +20,7 @@ class SaveFromIE(InfoExtractor): 'upload_date': '20120816', 'uploader': 'Howcast', 'uploader_id': 'Howcast', - 'description': 'md5:4f0aac94361a12e1ce57d74f85265175', + 'description': 're:(?s).* Hi, my name is Rene Dreifuss\. And I\'m here to show you some MMA.*', }, 'params': { 'skip_download': True diff --git a/youtube_dl/extractor/shared.py b/youtube_dl/extractor/shared.py new file mode 100644 index 0000000..8607482 --- /dev/null +++ b/youtube_dl/extractor/shared.py @@ -0,0 +1,57 @@ +from __future__ import unicode_literals + +import re +import base64 + +from .common import InfoExtractor +from ..utils import ( + ExtractorError, + compat_urllib_request, + compat_urllib_parse, + int_or_none, +) + + +class SharedIE(InfoExtractor): + _VALID_URL = r'http://shared\.sx/(?P[\da-z]{10})' + + _TEST = { + 'url': 'http://shared.sx/0060718775', + 'md5': '53e1c58fc3e777ae1dfe9e57ba2f9c72', + 'info_dict': { + 'id': '0060718775', + 'ext': 'mp4', + 'title': 'Big Buck Bunny Trailer', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + page = self._download_webpage(url, video_id) + + if re.search(r'>File does not exist<', page) is not None: + raise ExtractorError('Video %s does not exist' % video_id, expected=True) + + download_form = dict(re.findall(r'\d+)/([\w]+)' + _TESTS = [{ + 'url': 'http://www.snotr.com/video/13708/Drone_flying_through_fireworks', + 'info_dict': { + 'id': '13708', + 'ext': 'flv', + 'title': 'Drone flying through fireworks!', + 'duration': 247, + 'filesize_approx': 98566144, + 'description': 'A drone flying through Fourth of July Fireworks', + } + }, { + 'url': 'http://www.snotr.com/video/530/David_Letteman_-_George_W_Bush_Top_10', + 'info_dict': { + 'id': '530', + 'ext': 'flv', + 'title': 'David Letteman - George W. Bush Top 10', + 'duration': 126, + 'filesize_approx': 8912896, + 'description': 'The top 10 George W. Bush moments, brought to you by David Letterman!', + } + }] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + title = self._og_search_title(webpage) + + description = self._og_search_description(webpage) + video_url = "http://cdn.videos.snotr.com/%s.flv" % video_id + + view_count = str_to_int(self._html_search_regex( + r'

    \nViews:\n([\d,\.]+)

    ', + webpage, 'view count', fatal=False)) + + duration = parse_duration(self._html_search_regex( + r'

    \nLength:\n\s*([0-9:]+).*?

    ', + webpage, 'duration', fatal=False)) + + filesize_approx = float_or_none(self._html_search_regex( + r'

    \nFilesize:\n\s*([0-9.]+)\s*megabyte

    ', + webpage, 'filesize', fatal=False), invscale=1024 * 1024) + + return { + 'id': video_id, + 'description': description, + 'title': title, + 'url': video_url, + 'view_count': view_count, + 'duration': duration, + 'filesize_approx': filesize_approx, + } diff --git a/youtube_dl/extractor/sockshare.py b/youtube_dl/extractor/sockshare.py new file mode 100644 index 0000000..dc9f805 --- /dev/null +++ b/youtube_dl/extractor/sockshare.py @@ -0,0 +1,80 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from ..utils import ( + ExtractorError, + compat_urllib_parse, + compat_urllib_request, + determine_ext, +) +import re + +from .common import InfoExtractor + + +class SockshareIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?sockshare\.com/file/(?P[0-9A-Za-z]+)' + _FILE_DELETED_REGEX = r'This file doesn\'t exist, or has been removed\.' + _TEST = { + 'url': 'http://www.sockshare.com/file/437BE28B89D799D7', + 'md5': '9d0bf1cfb6dbeaa8d562f6c97506c5bd', + 'info_dict': { + 'id': '437BE28B89D799D7', + 'title': 'big_buck_bunny_720p_surround.avi', + 'ext': 'avi', + 'thumbnail': 're:^http://.*\.jpg$', + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + url = 'http://sockshare.com/file/%s' % video_id + webpage = self._download_webpage(url, video_id) + + if re.search(self._FILE_DELETED_REGEX, webpage) is not None: + raise ExtractorError('Video %s does not exist' % video_id, + expected=True) + + confirm_hash = self._html_search_regex(r'''(?x)(.+)', webpage, 'title') + thumbnail = self._html_search_regex( + r'[a-zA-Z0-9_-]+)/(?P[^#?]*)\.html' _TEST = { - u'url': u'http://streamcloud.eu/skp9j99s4bpz/youtube-dl_test_video_____________-BaW_jenozKc.mp4.html', - u'file': u'skp9j99s4bpz.mp4', - u'md5': u'6bea4c7fa5daaacc2a946b7146286686', - u'info_dict': { - u'title': u'youtube-dl test video \'/\\ ä ↭', - u'duration': 9, + 'url': 'http://streamcloud.eu/skp9j99s4bpz/youtube-dl_test_video_____________-BaW_jenozKc.mp4.html', + 'md5': '6bea4c7fa5daaacc2a946b7146286686', + 'info_dict': { + 'id': 'skp9j99s4bpz', + 'ext': 'mp4', + 'title': 'youtube-dl test video \'/\\ ä ↭', }, - u'skip': u'Only available from the EU' + 'skip': 'Only available from the EU' } def _real_extract(self, url): @@ -46,21 +48,17 @@ class StreamcloudIE(InfoExtractor): req = compat_urllib_request.Request(url, post, headers) webpage = self._download_webpage( - req, video_id, note=u'Downloading video page ...') + req, video_id, note='Downloading video page ...') title = self._html_search_regex( - r']*>([^<]+)<', webpage, u'title') + r']*>([^<]+)<', webpage, 'title') video_url = self._search_regex( - r'file:\s*"([^"]+)"', webpage, u'video URL') - duration_str = self._search_regex( - r'duration:\s*"?([0-9]+)"?', webpage, u'duration', fatal=False) - duration = None if duration_str is None else int(duration_str) + r'file:\s*"([^"]+)"', webpage, 'video URL') thumbnail = self._search_regex( - r'image:\s*"([^"]+)"', webpage, u'thumbnail URL', fatal=False) + r'image:\s*"([^"]+)"', webpage, 'thumbnail URL', fatal=False) return { 'id': video_id, 'title': title, 'url': video_url, - 'duration': duration, 'thumbnail': thumbnail, } diff --git a/youtube_dl/extractor/swrmediathek.py b/youtube_dl/extractor/swrmediathek.py index 6c688c5..5d9d703 100644 --- a/youtube_dl/extractor/swrmediathek.py +++ b/youtube_dl/extractor/swrmediathek.py @@ -8,7 +8,7 @@ from ..utils import parse_duration class SWRMediathekIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?swrmediathek\.de/player\.htm\?show=(?P[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})' + _VALID_URL = r'https?://(?:www\.)?swrmediathek\.de/(?:content/)?player\.htm\?show=(?P[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})' _TESTS = [{ 'url': 'http://swrmediathek.de/player.htm?show=849790d0-dab8-11e3-a953-0026b975f2e6', @@ -52,6 +52,20 @@ class SWRMediathekIE(InfoExtractor): 'uploader': 'SWR 2', 'uploader_id': '284670', } + }, { + 'url': 'http://swrmediathek.de/content/player.htm?show=52dc7e00-15c5-11e4-84bc-0026b975f2e6', + 'md5': '881531487d0633080a8cc88d31ef896f', + 'info_dict': { + 'id': '52dc7e00-15c5-11e4-84bc-0026b975f2e6', + 'ext': 'mp4', + 'title': 'Familienspaß am Bodensee', + 'description': 'md5:0b591225a32cfde7be1629ed49fe4315', + 'thumbnail': 're:http://.*\.jpg', + 'duration': 1784, + 'upload_date': '20140727', + 'uploader': 'SWR Fernsehen BW', + 'uploader_id': '281130', + } }] def _real_extract(self, url): diff --git a/youtube_dl/extractor/tagesschau.py b/youtube_dl/extractor/tagesschau.py index 25b9864..b870474 100644 --- a/youtube_dl/extractor/tagesschau.py +++ b/youtube_dl/extractor/tagesschau.py @@ -19,16 +19,6 @@ class TagesschauIE(InfoExtractor): 'description': 'md5:69da3c61275b426426d711bde96463ab', 'thumbnail': 're:^http:.*\.jpg$', }, - }, { - 'url': 'http://www.tagesschau.de/multimedia/video/video-5964.html', - 'md5': '66652566900963a3f962333579eeffcf', - 'info_dict': { - 'id': '5964', - 'ext': 'mp4', - 'title': 'Nahost-Konflikt: Israel bombadiert Ziele im Gazastreifen und Westjordanland', - 'description': 'md5:07bfc78c48eec3145ed4805299a1900a', - 'thumbnail': 're:http://.*\.jpg', - }, }] _FORMATS = { diff --git a/youtube_dl/extractor/teachertube.py b/youtube_dl/extractor/teachertube.py index 2c2113b..46d727d 100644 --- a/youtube_dl/extractor/teachertube.py +++ b/youtube_dl/extractor/teachertube.py @@ -62,7 +62,7 @@ class TeacherTubeIE(InfoExtractor): webpage = self._download_webpage(url, video_id) - title = self._html_search_meta('title', webpage, 'title') + title = self._html_search_meta('title', webpage, 'title', fatal=True) TITLE_SUFFIX = ' - TeacherTube' if title.endswith(TITLE_SUFFIX): title = title[:-len(TITLE_SUFFIX)].strip() @@ -101,7 +101,11 @@ class TeacherTubeUserIE(InfoExtractor): _VALID_URL = r'https?://(?:www\.)?teachertube\.com/(user/profile|collection)/(?P[0-9a-zA-Z]+)/?' - _MEDIA_RE = r'(?s)"sidebar_thumb_time">[0-9:]+.+?
    ' + _MEDIA_RE = r'''(?sx) + class="?sidebar_thumb_time"?>[0-9:]+ + \s* + \d+)' + _TESTS = [ + { + 'url': 'http://www.tvplay.lv/parraides/vinas-melo-labak/418113?autostart=true', + 'info_dict': { + 'id': '418113', + 'ext': 'flv', + 'title': 'Kādi ir īri? - Viņas melo labāk', + 'description': 'Baiba apsmej īrus, kādi tie ir un ko viņi dara.', + 'duration': 25, + 'timestamp': 1406097056, + 'upload_date': '20140723', + }, + 'params': { + # rtmp download + 'skip_download': True, + }, + }, + ] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + video = self._download_json( + 'http://playapi.mtgx.tv/v1/videos/%s' % video_id, video_id, 'Downloading video JSON') + + if video['is_geo_blocked']: + raise ExtractorError( + 'This content is not available in your country due to copyright reasons', expected=True) + + streams = self._download_json( + 'http://playapi.mtgx.tv/v1/videos/stream/%s' % video_id, video_id, 'Downloading streams JSON') + + quality = qualities(['hls', 'medium', 'high']) + formats = [] + for format_id, video_url in streams['streams'].items(): + if not video_url: + continue + fmt = { + 'format_id': format_id, + 'preference': quality(format_id), + } + if video_url.startswith('rtmp'): + m = re.search(r'^(?Prtmp://[^/]+/(?P[^/]+))/(?P.+)$', video_url) + if not m: + continue + fmt.update({ + 'ext': 'flv', + 'url': m.group('url'), + 'app': m.group('app'), + 'play_path': m.group('playpath'), + }) + else: + fmt.update({ + 'url': video_url, + }) + formats.append(fmt) + + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': video['title'], + 'description': video['description'], + 'duration': video['duration'], + 'timestamp': parse_iso8601(video['created_at']), + 'view_count': video['views']['total'], + 'age_limit': video.get('age_limit', 0), + 'formats': formats, + } diff --git a/youtube_dl/extractor/ubu.py b/youtube_dl/extractor/ubu.py new file mode 100644 index 0000000..0182d67 --- /dev/null +++ b/youtube_dl/extractor/ubu.py @@ -0,0 +1,56 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import int_or_none + + +class UbuIE(InfoExtractor): + _VALID_URL = r'http://(?:www\.)?ubu\.com/film/(?P[\da-z_-]+)\.html' + _TEST = { + 'url': 'http://ubu.com/film/her_noise.html', + 'md5': '8edd46ee8aa6b265fb5ed6cf05c36bc9', + 'info_dict': { + 'id': 'her_noise', + 'ext': 'mp4', + 'title': 'Her Noise - The Making Of (2007)', + 'duration': 3600, + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + + title = self._html_search_regex( + r'.+?Film & Video: ([^<]+)', webpage, 'title') + + duration = int_or_none(self._html_search_regex( + r'Duration: (\d+) minutes', webpage, 'duration', fatal=False, default=None)) + if duration: + duration *= 60 + + formats = [] + + FORMAT_REGEXES = [ + ['sq', r"'flashvars'\s*,\s*'file=([^']+)'"], + ['hq', r'href="(http://ubumexico\.centro\.org\.mx/video/[^"]+)"'] + ] + + for format_id, format_regex in FORMAT_REGEXES: + m = re.search(format_regex, webpage) + if m: + formats.append({ + 'url': m.group(1), + 'format_id': format_id, + }) + + return { + 'id': video_id, + 'title': title, + 'duration': duration, + 'formats': formats, + } diff --git a/youtube_dl/extractor/vevo.py b/youtube_dl/extractor/vevo.py index eada13c..d2ffd1b 100644 --- a/youtube_dl/extractor/vevo.py +++ b/youtube_dl/extractor/vevo.py @@ -177,6 +177,7 @@ class VevoIE(InfoExtractor): self._downloader.report_warning( 'Cannot download SMIL information, falling back to JSON ..') + self._sort_formats(formats) timestamp_ms = int(self._search_regex( r'/Date\((\d+)\)/', video_info['launchDate'], 'launch date')) diff --git a/youtube_dl/extractor/vidme.py b/youtube_dl/extractor/vidme.py new file mode 100644 index 0000000..5c89824 --- /dev/null +++ b/youtube_dl/extractor/vidme.py @@ -0,0 +1,68 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor +from ..utils import ( + int_or_none, + float_or_none, + str_to_int, +) + + +class VidmeIE(InfoExtractor): + _VALID_URL = r'https?://vid\.me/(?:e/)?(?P[\da-zA-Z]+)' + _TEST = { + 'url': 'https://vid.me/QNB', + 'md5': 'f42d05e7149aeaec5c037b17e5d3dc82', + 'info_dict': { + 'id': 'QNB', + 'ext': 'mp4', + 'title': 'Fishing for piranha - the easy way', + 'description': 'source: https://www.facebook.com/photo.php?v=312276045600871', + 'duration': 119.92, + 'timestamp': 1406313244, + 'upload_date': '20140725', + 'thumbnail': 're:^https?://.*\.jpg', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + + video_url = self._html_search_regex(r'\s*([\d,\.]+)\s*plays?', webpage, 'view count', fatal=False)) + like_count = str_to_int(self._html_search_regex( + r'class="score js-video-vote-score"[^>]+data-score="([\d,\.\s]+)">', + webpage, 'like count', fatal=False)) + comment_count = str_to_int(self._html_search_regex( + r'class="js-comment-count"[^>]+data-count="([\d,\.\s]+)">', + webpage, 'comment count', fatal=False)) + + return { + 'id': video_id, + 'url': video_url, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'timestamp': timestamp, + 'width': width, + 'height': height, + 'duration': duration, + 'view_count': view_count, + 'like_count': like_count, + 'comment_count': comment_count, + } diff --git a/youtube_dl/extractor/vimeo.py b/youtube_dl/extractor/vimeo.py index 2558555..11c7d7e 100644 --- a/youtube_dl/extractor/vimeo.py +++ b/youtube_dl/extractor/vimeo.py @@ -98,7 +98,7 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): 'info_dict': { 'id': '54469442', 'ext': 'mp4', - 'title': 'Kathy Sierra: Building the minimum Badass User, Business of Software', + 'title': 'Kathy Sierra: Building the minimum Badass User, Business of Software 2012', 'uploader': 'The BLN & Business of Software', 'uploader_id': 'theblnbusinessofsoftware', 'duration': 3610, @@ -121,6 +121,21 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): 'videopassword': 'youtube-dl', }, }, + { + 'url': 'http://vimeo.com/channels/keypeele/75629013', + 'md5': '2f86a05afe9d7abc0b9126d229bbe15d', + 'note': 'Video is freely available via original URL ' + 'and protected with password when accessed via http://vimeo.com/75629013', + 'info_dict': { + 'id': '75629013', + 'ext': 'mp4', + 'title': 'Key & Peele: Terrorist Interrogation', + 'description': 'md5:8678b246399b070816b12313e8b4eb5c', + 'uploader_id': 'atencio', + 'uploader': 'Peter Atencio', + 'duration': 187, + }, + }, { 'url': 'http://vimeo.com/76979871', 'md5': '3363dd6ffebe3784d56f4132317fd446', @@ -196,8 +211,6 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): video_id = mobj.group('id') if mobj.group('pro') or mobj.group('player'): url = 'http://player.vimeo.com/video/' + video_id - else: - url = 'https://vimeo.com/' + video_id # Retrieve video webpage to extract further information request = compat_urllib_request.Request(url, None, headers) @@ -263,7 +276,7 @@ class VimeoIE(VimeoBaseInfoExtractor, SubtitlesInfoExtractor): if video_thumbnail is None: video_thumbs = config["video"].get("thumbs") if video_thumbs and isinstance(video_thumbs, dict): - _, video_thumbnail = sorted((int(width), t_url) for (width, t_url) in video_thumbs.items())[-1] + _, video_thumbnail = sorted((int(width if width.isdigit() else 0), t_url) for (width, t_url) in video_thumbs.items())[-1] # Extract video description video_description = None diff --git a/youtube_dl/extractor/vodlocker.py b/youtube_dl/extractor/vodlocker.py index 68c5936..6d3b787 100644 --- a/youtube_dl/extractor/vodlocker.py +++ b/youtube_dl/extractor/vodlocker.py @@ -10,7 +10,7 @@ from ..utils import ( class VodlockerIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?vodlocker.com/(?P[0-9a-zA-Z]+)(?:\..*?)?' + _VALID_URL = r'https?://(?:www\.)?vodlocker\.com/(?P[0-9a-zA-Z]+)(?:\..*?)?' _TESTS = [{ 'url': 'http://vodlocker.com/e8wvyzz4sl42', diff --git a/youtube_dl/extractor/vube.py b/youtube_dl/extractor/vube.py index 7b77865..f1b9e9a 100644 --- a/youtube_dl/extractor/vube.py +++ b/youtube_dl/extractor/vube.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import json import re from .common import InfoExtractor @@ -20,12 +21,14 @@ class VubeIE(InfoExtractor): 'ext': 'mp4', 'title': 'Chiara Grispo - Price Tag by Jessie J', 'description': 'md5:8ea652a1f36818352428cb5134933313', - 'thumbnail': 'http://frame.thestaticvube.com/snap/228x128/102e7e63057-5ebc-4f5c-4065-6ce4ebde131f.jpg', + 'thumbnail': 're:^http://frame\.thestaticvube\.com/snap/[0-9x]+/102e7e63057-5ebc-4f5c-4065-6ce4ebde131f\.jpg$', 'uploader': 'Chiara.Grispo', - 'uploader_id': '1u3hX0znhP', 'timestamp': 1388743358, 'upload_date': '20140103', - 'duration': 170.56 + 'duration': 170.56, + 'like_count': int, + 'dislike_count': int, + 'comment_count': int, } }, { @@ -36,12 +39,30 @@ class VubeIE(InfoExtractor): 'ext': 'mp4', 'title': 'My 7 year old Sister and I singing "Alive" by Krewella', 'description': 'md5:40bcacb97796339f1690642c21d56f4a', - 'thumbnail': 'http://frame.thestaticvube.com/snap/228x128/102265d5a9f-0f17-4f6b-5753-adf08484ee1e.jpg', + 'thumbnail': 're:^http://frame\.thestaticvube\.com/snap/[0-9x]+/102265d5a9f-0f17-4f6b-5753-adf08484ee1e\.jpg$', 'uploader': 'Seraina', - 'uploader_id': 'XU9VE2BQ2q', 'timestamp': 1396492438, 'upload_date': '20140403', - 'duration': 240.107 + 'duration': 240.107, + 'like_count': int, + 'dislike_count': int, + 'comment_count': int, + } + }, { + 'url': 'http://vube.com/vote/Siren+Gene/0nmsMY5vEq?n=2&t=s', + 'md5': '0584fc13b50f887127d9d1007589d27f', + 'info_dict': { + 'id': '0nmsMY5vEq', + 'ext': 'mp4', + 'title': 'Frozen - Let It Go Cover by Siren Gene', + 'description': 'My rendition of "Let It Go" originally sung by Idina Menzel.', + 'uploader': 'Siren Gene', + 'uploader_id': 'Siren', + 'thumbnail': 're:^http://frame\.thestaticvube\.com/snap/[0-9x]+/10283ab622a-86c9-4681-51f2-30d1f65774af\.jpg$', + 'duration': 221.788, + 'like_count': int, + 'dislike_count': int, + 'comment_count': int, } } ] @@ -50,8 +71,16 @@ class VubeIE(InfoExtractor): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('id') - video = self._download_json( - 'http://vube.com/api/v2/video/%s' % video_id, video_id, 'Downloading video JSON') + webpage = self._download_webpage(url, video_id) + data_json = self._search_regex( + r'(?s)window\["(?:tapiVideoData|vubeOriginalVideoData)"\]\s*=\s*(\{.*?\n});\n', + webpage, 'video data' + ) + data = json.loads(data_json) + video = ( + data.get('video') or + data) + assert isinstance(video, dict) public_id = video['public_id'] @@ -69,21 +98,31 @@ class VubeIE(InfoExtractor): title = video['title'] description = video.get('description') - thumbnail = video['thumbnail_src'] - if thumbnail.startswith('//'): - thumbnail = 'http:' + thumbnail - uploader = video['user_alias'] - uploader_id = video['user_url_id'] - timestamp = int(video['upload_time']) + thumbnail = self._proto_relative_url( + video.get('thumbnail') or video.get('thumbnail_src'), + scheme='http:') + uploader = data.get('user', {}).get('channel', {}).get('name') or video.get('user_alias') + uploader_id = data.get('user', {}).get('name') + timestamp = int_or_none(video.get('upload_time')) duration = video['duration'] view_count = video.get('raw_view_count') - like_count = video.get('total_likes') - dislike_count= video.get('total_hates') - - comment = self._download_json( - 'http://vube.com/api/video/%s/comment' % video_id, video_id, 'Downloading video comment JSON') + like_count = video.get('rlikes') + if like_count is None: + like_count = video.get('total_likes') + dislike_count = video.get('rhates') + if dislike_count is None: + dislike_count = video.get('total_hates') - comment_count = int_or_none(comment.get('total')) + comments = video.get('comments') + comment_count = None + if comments is None: + comment_data = self._download_json( + 'http://vube.com/api/video/%s/comment' % video_id, + video_id, 'Downloading video comment JSON', fatal=False) + if comment_data is not None: + comment_count = int_or_none(comment_data.get('total')) + else: + comment_count = len(comments) return { 'id': video_id, diff --git a/youtube_dl/extractor/wdr.py b/youtube_dl/extractor/wdr.py index f741ba5..54d37da 100644 --- a/youtube_dl/extractor/wdr.py +++ b/youtube_dl/extractor/wdr.py @@ -55,14 +55,14 @@ class WDRIE(InfoExtractor): }, }, { - 'url': 'http://www.funkhauseuropa.de/av/audiosuepersongsoulbossanova100-audioplayer.html', - 'md5': '24e83813e832badb0a8d7d1ef9ef0691', + 'url': 'http://www.funkhauseuropa.de/av/audioflaviacoelhoamaramar100-audioplayer.html', + 'md5': '99a1443ff29af19f6c52cf6f4dc1f4aa', 'info_dict': { - 'id': 'mdb-463528', + 'id': 'mdb-478135', 'ext': 'mp3', - 'title': 'Süpersong: Soul Bossa Nova', + 'title': 'Flavia Coelho: Amar é Amar', 'description': 'md5:7b29e97e10dfb6e265238b32fa35b23a', - 'upload_date': '20140630', + 'upload_date': '20140717', }, }, ] @@ -81,7 +81,7 @@ class WDRIE(InfoExtractor): ] return self.playlist_result(entries, page_id) - flashvars = compat_urlparse.parse_qs( + flashvars = compat_parse_qs( self._html_search_regex(r'[a-zA-Z0-9_-]+)\.(?P[a-z]+)$', - player_url) + def _signature_cache_id(self, example_sig): + """ Return a string representation of a signature """ + return u'.'.join(compat_str(len(part)) for part in example_sig.split('.')) + + def _extract_signature_function(self, video_id, player_url, example_sig): + id_m = re.match( + r'.*-(?P[a-zA-Z0-9_-]+)(?:/watch_as3|/html5player)?\.(?P[a-z]+)$', + player_url) + if not id_m: + raise ExtractorError('Cannot identify player %r' % player_url) player_type = id_m.group('ext') player_id = id_m.group('id') # Read from filesystem cache - func_id = '%s_%s_%d' % (player_type, player_id, slen) + func_id = '%s_%s_%s' % ( + player_type, player_id, self._signature_cache_id(example_sig)) assert os.path.basename(func_id) == func_id cache_dir = get_cachedir(self._downloader.params) @@ -387,7 +393,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): if cache_enabled: try: - test_string = u''.join(map(compat_chr, range(slen))) + test_string = u''.join(map(compat_chr, range(len(example_sig)))) cache_res = res(test_string) cache_spec = [ord(c) for c in cache_res] try: @@ -403,7 +409,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): return res - def _print_sig_code(self, func, slen): + def _print_sig_code(self, func, example_sig): def gen_sig_code(idxs): def _genslice(start, end, step): starts = u'' if start == 0 else str(start) @@ -432,11 +438,14 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): else: yield _genslice(start, i, step) - test_string = u''.join(map(compat_chr, range(slen))) + test_string = u''.join(map(compat_chr, range(len(example_sig)))) cache_res = func(test_string) cache_spec = [ord(c) for c in cache_res] expr_code = u' + '.join(gen_sig_code(cache_spec)) - code = u'if len(s) == %d:\n return %s\n' % (slen, expr_code) + signature_id_tuple = '(%s)' % ( + ', '.join(compat_str(len(p)) for p in example_sig.split('.'))) + code = (u'if tuple(len(p) for p in s.split(\'.\')) == %s:\n' + u' return %s\n') % (signature_id_tuple, expr_code) self.to_screen(u'Extracted signature function:\n' + code) def _parse_sig_js(self, jscode): @@ -449,417 +458,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): return lambda s: initial_function([s]) def _parse_sig_swf(self, file_contents): - if file_contents[1:3] != b'WS': - raise ExtractorError( - u'Not an SWF file; header is %r' % file_contents[:3]) - if file_contents[:1] == b'C': - content = zlib.decompress(file_contents[8:]) - else: - raise NotImplementedError(u'Unsupported compression format %r' % - file_contents[:1]) - - def extract_tags(content): - pos = 0 - while pos < len(content): - header16 = struct.unpack('> 6 - tag_len = header16 & 0x3f - if tag_len == 0x3f: - tag_len = struct.unpack('> 4 - methods = {} - if kind in [0x00, 0x06]: # Slot or Const - u30() # Slot id - u30() # type_name_idx - vindex = u30() - if vindex != 0: - read_byte() # vkind - elif kind in [0x01, 0x02, 0x03]: # Method / Getter / Setter - u30() # disp_id - method_idx = u30() - methods[multinames[trait_name_idx]] = method_idx - elif kind == 0x04: # Class - u30() # slot_id - u30() # classi - elif kind == 0x05: # Function - u30() # slot_id - function_idx = u30() - methods[function_idx] = multinames[trait_name_idx] - else: - raise ExtractorError(u'Unsupported trait kind %d' % kind) - - if attrs & 0x4 != 0: # Metadata present - metadata_count = u30() - for _c3 in range(metadata_count): - u30() # metadata index - - return methods - - # Classes + swfi = SWFInterpreter(file_contents) TARGET_CLASSNAME = u'SignatureDecipher' - searched_idx = multinames.index(TARGET_CLASSNAME) - searched_class_id = None - class_count = u30() - for class_id in range(class_count): - name_idx = u30() - if name_idx == searched_idx: - # We found the class we're looking for! - searched_class_id = class_id - u30() # super_name idx - flags = read_byte() - if flags & 0x08 != 0: # Protected namespace is present - u30() # protected_ns_idx - intrf_count = u30() - for _c2 in range(intrf_count): - u30() - u30() # iinit - trait_count = u30() - for _c2 in range(trait_count): - parse_traits_info() - - if searched_class_id is None: - raise ExtractorError(u'Target class %r not found' % - TARGET_CLASSNAME) - - method_names = {} - method_idxs = {} - for class_id in range(class_count): - u30() # cinit - trait_count = u30() - for _c2 in range(trait_count): - trait_methods = parse_traits_info() - if class_id == searched_class_id: - method_names.update(trait_methods.items()) - method_idxs.update(dict( - (idx, name) - for name, idx in trait_methods.items())) - - # Scripts - script_count = u30() - for _c in range(script_count): - u30() # init - trait_count = u30() - for _c2 in range(trait_count): - parse_traits_info() - - # Method bodies - method_body_count = u30() - Method = collections.namedtuple('Method', ['code', 'local_count']) - methods = {} - for _c in range(method_body_count): - method_idx = u30() - u30() # max_stack - local_count = u30() - u30() # init_scope_depth - u30() # max_scope_depth - code_length = u30() - code = read_bytes(code_length) - if method_idx in method_idxs: - m = Method(code, local_count) - methods[method_idxs[method_idx]] = m - exception_count = u30() - for _c2 in range(exception_count): - u30() # from - u30() # to - u30() # target - u30() # exc_type - u30() # var_name - trait_count = u30() - for _c2 in range(trait_count): - parse_traits_info() - - assert p + code_reader.tell() == len(code_tag) - assert len(methods) == len(method_idxs) - - method_pyfunctions = {} - - def extract_function(func_name): - if func_name in method_pyfunctions: - return method_pyfunctions[func_name] - if func_name not in methods: - raise ExtractorError(u'Cannot find function %r' % func_name) - m = methods[func_name] - - def resfunc(args): - registers = ['(this)'] + list(args) + [None] * m.local_count - stack = [] - coder = io.BytesIO(m.code) - while True: - opcode = struct.unpack('!B', coder.read(1))[0] - if opcode == 36: # pushbyte - v = struct.unpack('!B', coder.read(1))[0] - stack.append(v) - elif opcode == 44: # pushstring - idx = u30(coder) - stack.append(constant_strings[idx]) - elif opcode == 48: # pushscope - # We don't implement the scope register, so we'll just - # ignore the popped value - stack.pop() - elif opcode == 70: # callproperty - index = u30(coder) - mname = multinames[index] - arg_count = u30(coder) - args = list(reversed( - [stack.pop() for _ in range(arg_count)])) - obj = stack.pop() - if mname == u'split': - assert len(args) == 1 - assert isinstance(args[0], compat_str) - assert isinstance(obj, compat_str) - if args[0] == u'': - res = list(obj) - else: - res = obj.split(args[0]) - stack.append(res) - elif mname == u'slice': - assert len(args) == 1 - assert isinstance(args[0], int) - assert isinstance(obj, list) - res = obj[args[0]:] - stack.append(res) - elif mname == u'join': - assert len(args) == 1 - assert isinstance(args[0], compat_str) - assert isinstance(obj, list) - res = args[0].join(obj) - stack.append(res) - elif mname in method_pyfunctions: - stack.append(method_pyfunctions[mname](args)) - else: - raise NotImplementedError( - u'Unsupported property %r on %r' - % (mname, obj)) - elif opcode == 72: # returnvalue - res = stack.pop() - return res - elif opcode == 79: # callpropvoid - index = u30(coder) - mname = multinames[index] - arg_count = u30(coder) - args = list(reversed( - [stack.pop() for _ in range(arg_count)])) - obj = stack.pop() - if mname == u'reverse': - assert isinstance(obj, list) - obj.reverse() - else: - raise NotImplementedError( - u'Unsupported (void) property %r on %r' - % (mname, obj)) - elif opcode == 93: # findpropstrict - index = u30(coder) - mname = multinames[index] - res = extract_function(mname) - stack.append(res) - elif opcode == 97: # setproperty - index = u30(coder) - value = stack.pop() - idx = stack.pop() - obj = stack.pop() - assert isinstance(obj, list) - assert isinstance(idx, int) - obj[idx] = value - elif opcode == 98: # getlocal - index = u30(coder) - stack.append(registers[index]) - elif opcode == 99: # setlocal - index = u30(coder) - value = stack.pop() - registers[index] = value - elif opcode == 102: # getproperty - index = u30(coder) - pname = multinames[index] - if pname == u'length': - obj = stack.pop() - assert isinstance(obj, list) - stack.append(len(obj)) - else: # Assume attribute access - idx = stack.pop() - assert isinstance(idx, int) - obj = stack.pop() - assert isinstance(obj, list) - stack.append(obj[idx]) - elif opcode == 128: # coerce - u30(coder) - elif opcode == 133: # coerce_s - assert isinstance(stack[-1], (type(None), compat_str)) - elif opcode == 164: # modulo - value2 = stack.pop() - value1 = stack.pop() - res = value1 % value2 - stack.append(res) - elif opcode == 208: # getlocal_0 - stack.append(registers[0]) - elif opcode == 209: # getlocal_1 - stack.append(registers[1]) - elif opcode == 210: # getlocal_2 - stack.append(registers[2]) - elif opcode == 211: # getlocal_3 - stack.append(registers[3]) - elif opcode == 214: # setlocal_2 - registers[2] = stack.pop() - elif opcode == 215: # setlocal_3 - registers[3] = stack.pop() - else: - raise NotImplementedError( - u'Unsupported opcode %d' % opcode) - - method_pyfunctions[func_name] = resfunc - return resfunc - - initial_function = extract_function(u'decipher') + searched_class = swfi.extract_class(TARGET_CLASSNAME) + initial_function = swfi.extract_function(searched_class, u'decipher') return lambda s: initial_function([s]) def _decrypt_signature(self, s, video_id, player_url, age_gate=False): @@ -871,20 +473,20 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): if player_url.startswith(u'//'): player_url = u'https:' + player_url try: - player_id = (player_url, len(s)) + player_id = (player_url, self._signature_cache_id(s)) if player_id not in self._player_cache: func = self._extract_signature_function( - video_id, player_url, len(s) + video_id, player_url, s ) self._player_cache[player_id] = func func = self._player_cache[player_id] if self._downloader.params.get('youtube_print_sig_code'): - self._print_sig_code(func, len(s)) + self._print_sig_code(func, s) return func(s) except Exception as e: tb = traceback.format_exc() raise ExtractorError( - u'Automatic signature extraction failed: ' + tb, cause=e) + u'Signature extraction failed: ' + tb, cause=e) def _get_available_subtitles(self, video_id, webpage): try: @@ -1014,14 +616,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): age_gate = True # We simulate the access to the video from www.youtube.com/v/{video_id} # this can be viewed without login into Youtube - data = compat_urllib_parse.urlencode({'video_id': video_id, - 'el': 'player_embedded', - 'gl': 'US', - 'hl': 'en', - 'eurl': 'https://youtube.googleapis.com/v/' + video_id, - 'asv': 3, - 'sts':'1588', - }) + data = compat_urllib_parse.urlencode({ + 'video_id': video_id, + 'eurl': 'https://youtube.googleapis.com/v/' + video_id, + 'sts': self._search_regex( + r'"sts"\s*:\s*(\d+)', video_webpage, 'sts'), + }) video_info_url = proto + '://www.youtube.com/get_video_info?' + data video_info_webpage = self._download_webpage(video_info_url, video_id, note=False, @@ -1214,43 +814,54 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor): url_map = {} for url_data_str in encoded_url_map.split(','): url_data = compat_parse_qs(url_data_str) - if 'itag' in url_data and 'url' in url_data: - url = url_data['url'][0] - if 'sig' in url_data: - url += '&signature=' + url_data['sig'][0] - elif 's' in url_data: - encrypted_sig = url_data['s'][0] - if self._downloader.params.get('verbose'): - if age_gate: - if player_url is None: - player_version = 'unknown' - else: - player_version = self._search_regex( - r'-(.+)\.swf$', player_url, - u'flash player', fatal=False) + if 'itag' not in url_data or 'url' not in url_data: + continue + format_id = url_data['itag'][0] + url = url_data['url'][0] + + if 'sig' in url_data: + url += '&signature=' + url_data['sig'][0] + elif 's' in url_data: + encrypted_sig = url_data['s'][0] + + if not age_gate: + jsplayer_url_json = self._search_regex( + r'"assets":.+?"js":\s*("[^"]+")', + video_webpage, u'JS player URL') + player_url = json.loads(jsplayer_url_json) + if player_url is None: + player_url_json = self._search_regex( + r'ytplayer\.config.*?"url"\s*:\s*("[^"]+")', + video_webpage, u'age gate player URL') + player_url = json.loads(player_url_json) + + if self._downloader.params.get('verbose'): + if player_url is None: + player_version = 'unknown' + player_desc = 'unknown' + else: + if player_url.endswith('swf'): + player_version = self._search_regex( + r'-(.+?)(?:/watch_as3)?\.swf$', player_url, + u'flash player', fatal=False) player_desc = 'flash player %s' % player_version else: player_version = self._search_regex( - r'html5player-(.+?)\.js', video_webpage, + r'html5player-([^/]+?)(?:/html5player)?\.js', + player_url, 'html5 player', fatal=False) player_desc = u'html5 player %s' % player_version - parts_sizes = u'.'.join(compat_str(len(part)) for part in encrypted_sig.split('.')) - self.to_screen(u'encrypted signature length %d (%s), itag %s, %s' % - (len(encrypted_sig), parts_sizes, url_data['itag'][0], player_desc)) - - if not age_gate: - jsplayer_url_json = self._search_regex( - r'"assets":.+?"js":\s*("[^"]+")', - video_webpage, u'JS player URL') - player_url = json.loads(jsplayer_url_json) - - signature = self._decrypt_signature( - encrypted_sig, video_id, player_url, age_gate) - url += '&signature=' + signature - if 'ratebypass' not in url: - url += '&ratebypass=yes' - url_map[url_data['itag'][0]] = url + parts_sizes = self._signature_cache_id(encrypted_sig) + self.to_screen(u'{%s} signature length %s, %s' % + (format_id, parts_sizes, player_desc)) + + signature = self._decrypt_signature( + encrypted_sig, video_id, player_url, age_gate) + url += '&signature=' + signature + if 'ratebypass' not in url: + url += '&ratebypass=yes' + url_map[format_id] = url formats = _map_to_format_list(url_map) elif video_info.get('hlsvp'): manifest_url = video_info['hlsvp'][0] diff --git a/youtube_dl/jsinterp.py b/youtube_dl/jsinterp.py index ae5bca2..c40cd37 100644 --- a/youtube_dl/jsinterp.py +++ b/youtube_dl/jsinterp.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import json import re from .utils import ( @@ -40,8 +41,9 @@ class JSInterpreter(object): assign = lambda v: v expr = stmt[len('return '):] else: - raise ExtractorError( - 'Cannot determine left side of statement in %r' % stmt) + # Try interpreting it as an expression + expr = stmt + assign = lambda v: v v = self.interpret_expression(expr, local_vars, allow_recursion) return assign(v) @@ -53,35 +55,63 @@ class JSInterpreter(object): if expr.isalpha(): return local_vars[expr] - m = re.match(r'^(?P[a-z]+)\.(?P.*)$', expr) + try: + return json.loads(expr) + except ValueError: + pass + + m = re.match( + r'^(?P[a-zA-Z0-9_]+)\.(?P[^(]+)(?:\(+(?P[^()]*)\))?$', + expr) if m: + variable = m.group('var') member = m.group('member') - variable = m.group('in') + arg_str = m.group('args') - if variable not in local_vars: + if variable in local_vars: + obj = local_vars[variable] + else: if variable not in self._objects: self._objects[variable] = self.extract_object(variable) obj = self._objects[variable] - key, args = member.split('(', 1) - args = args.strip(')') - argvals = [int(v) if v.isdigit() else local_vars[v] - for v in args.split(',')] - return obj[key](argvals) - - val = local_vars[variable] - if member == 'split("")': - return list(val) - if member == 'join("")': - return ''.join(val) - if member == 'length': - return len(val) - if member == 'reverse()': - return val[::-1] - slice_m = re.match(r'slice\((?P.*)\)', member) - if slice_m: - idx = self.interpret_expression( - slice_m.group('idx'), local_vars, allow_recursion - 1) - return val[idx:] + + if arg_str is None: + # Member access + if member == 'length': + return len(obj) + return obj[member] + + assert expr.endswith(')') + # Function call + if arg_str == '': + argvals = tuple() + else: + argvals = tuple([ + self.interpret_expression(v, local_vars, allow_recursion) + for v in arg_str.split(',')]) + + if member == 'split': + assert argvals == ('',) + return list(obj) + if member == 'join': + assert len(argvals) == 1 + return argvals[0].join(obj) + if member == 'reverse': + assert len(argvals) == 0 + obj.reverse() + return obj + if member == 'slice': + assert len(argvals) == 1 + return obj[argvals[0]:] + if member == 'splice': + assert isinstance(obj, list) + index, howMany = argvals + res = [] + for i in range(index, min(index + howMany, len(obj))): + res.append(obj.pop(index)) + return res + + return obj[member](argvals) m = re.match( r'^(?P[a-z]+)\[(?P.+)\]$', expr) @@ -103,10 +133,11 @@ class JSInterpreter(object): r'^(?P[a-zA-Z$]+)\((?P[a-z0-9,]+)\)$', expr) if m: fname = m.group('func') + argvals = tuple([ + int(v) if v.isdigit() else local_vars[v] + for v in m.group('args').split(',')]) if fname not in self._functions: self._functions[fname] = self.extract_function(fname) - argvals = [int(v) if v.isdigit() else local_vars[v] - for v in m.group('args').split(',')] return self._functions[fname](argvals) raise ExtractorError('Unsupported JS expression %r' % expr) @@ -114,13 +145,13 @@ class JSInterpreter(object): obj = {} obj_m = re.search( (r'(?:var\s+)?%s\s*=\s*\{' % re.escape(objname)) + - r'\s*(?P([a-zA-Z$]+\s*:\s*function\(.*?\)\s*\{.*?\})*)' + + r'\s*(?P([a-zA-Z$0-9]+\s*:\s*function\(.*?\)\s*\{.*?\})*)' + r'\}\s*;', self.code) fields = obj_m.group('fields') # Currently, it only supports function definitions fields_m = re.finditer( - r'(?P[a-zA-Z$]+)\s*:\s*function' + r'(?P[a-zA-Z$0-9]+)\s*:\s*function' r'\((?P[a-z,]+)\){(?P[^}]+)}', fields) for f in fields_m: diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 45328ed..8c5f7c4 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -18,14 +18,15 @@ from ..utils import ( ) - class FFmpegPostProcessorError(PostProcessingError): pass + class FFmpegPostProcessor(PostProcessor): - def __init__(self,downloader=None): + def __init__(self, downloader=None, deletetempfiles=False): PostProcessor.__init__(self, downloader) self._exes = self.detect_executables() + self._deletetempfiles = deletetempfiles @staticmethod def detect_executables(): @@ -60,6 +61,9 @@ class FFmpegPostProcessor(PostProcessor): stderr = stderr.decode('utf-8', 'replace') msg = stderr.strip().split('\n')[-1] raise FFmpegPostProcessorError(msg) + if self._deletetempfiles: + for ipath in input_paths: + os.remove(ipath) def run_ffmpeg(self, path, out_path, opts): self.run_ffmpeg_multiple_files([path], out_path, opts) diff --git a/youtube_dl/swfinterp.py b/youtube_dl/swfinterp.py new file mode 100644 index 0000000..b63c65b --- /dev/null +++ b/youtube_dl/swfinterp.py @@ -0,0 +1,609 @@ +from __future__ import unicode_literals + +import collections +import io +import zlib + +from .utils import ( + compat_str, + ExtractorError, + struct_unpack, +) + + +def _extract_tags(file_contents): + if file_contents[1:3] != b'WS': + raise ExtractorError( + 'Not an SWF file; header is %r' % file_contents[:3]) + if file_contents[:1] == b'C': + content = zlib.decompress(file_contents[8:]) + else: + raise NotImplementedError( + 'Unsupported compression format %r' % + file_contents[:1]) + + # Determine number of bits in framesize rectangle + framesize_nbits = struct_unpack('!B', content[:1])[0] >> 3 + framesize_len = (5 + 4 * framesize_nbits + 7) // 8 + + pos = framesize_len + 2 + 2 + while pos < len(content): + header16 = struct_unpack('> 6 + tag_len = header16 & 0x3f + if tag_len == 0x3f: + tag_len = struct_unpack('= 0x80) else b'\x00' + return struct_unpack('= 0 + resb = reader.read(count) + assert len(resb) == count + return resb + + +def _read_byte(reader): + resb = _read_bytes(1, reader=reader) + res = struct_unpack('> 4 + methods = {} + if kind in [0x00, 0x06]: # Slot or Const + u30() # Slot id + u30() # type_name_idx + vindex = u30() + if vindex != 0: + read_byte() # vkind + elif kind in [0x01, 0x02, 0x03]: # Method / Getter / Setter + u30() # disp_id + method_idx = u30() + methods[self.multinames[trait_name_idx]] = method_idx + elif kind == 0x04: # Class + u30() # slot_id + u30() # classi + elif kind == 0x05: # Function + u30() # slot_id + function_idx = u30() + methods[function_idx] = self.multinames[trait_name_idx] + else: + raise ExtractorError('Unsupported trait kind %d' % kind) + + if attrs & 0x4 != 0: # Metadata present + metadata_count = u30() + for _c3 in range(metadata_count): + u30() # metadata index + + return methods + + # Classes + class_count = u30() + classes = [] + for class_id in range(class_count): + name_idx = u30() + + cname = self.multinames[name_idx] + avm_class = _AVMClass(name_idx, cname) + classes.append(avm_class) + + u30() # super_name idx + flags = read_byte() + if flags & 0x08 != 0: # Protected namespace is present + u30() # protected_ns_idx + intrf_count = u30() + for _c2 in range(intrf_count): + u30() + u30() # iinit + trait_count = u30() + for _c2 in range(trait_count): + trait_methods = parse_traits_info() + avm_class.register_methods(trait_methods) + + assert len(classes) == class_count + self._classes_by_name = dict((c.name, c) for c in classes) + + for avm_class in classes: + u30() # cinit + trait_count = u30() + for _c2 in range(trait_count): + trait_methods = parse_traits_info() + avm_class.register_methods(trait_methods) + + # Scripts + script_count = u30() + for _c in range(script_count): + u30() # init + trait_count = u30() + for _c2 in range(trait_count): + parse_traits_info() + + # Method bodies + method_body_count = u30() + Method = collections.namedtuple('Method', ['code', 'local_count']) + for _c in range(method_body_count): + method_idx = u30() + u30() # max_stack + local_count = u30() + u30() # init_scope_depth + u30() # max_scope_depth + code_length = u30() + code = read_bytes(code_length) + for avm_class in classes: + if method_idx in avm_class.method_idxs: + m = Method(code, local_count) + avm_class.methods[avm_class.method_idxs[method_idx]] = m + exception_count = u30() + for _c2 in range(exception_count): + u30() # from + u30() # to + u30() # target + u30() # exc_type + u30() # var_name + trait_count = u30() + for _c2 in range(trait_count): + parse_traits_info() + + assert p + code_reader.tell() == len(code_tag) + + def extract_class(self, class_name): + try: + return self._classes_by_name[class_name] + except KeyError: + raise ExtractorError('Class %r not found' % class_name) + + def extract_function(self, avm_class, func_name): + if func_name in avm_class.method_pyfunctions: + return avm_class.method_pyfunctions[func_name] + if func_name in self._classes_by_name: + return self._classes_by_name[func_name].make_object() + if func_name not in avm_class.methods: + raise ExtractorError('Cannot find function %s.%s' % ( + avm_class.name, func_name)) + m = avm_class.methods[func_name] + + def resfunc(args): + # Helper functions + coder = io.BytesIO(m.code) + s24 = lambda: _s24(coder) + u30 = lambda: _u30(coder) + + registers = [avm_class.variables] + list(args) + [None] * m.local_count + stack = [] + scopes = collections.deque([ + self._classes_by_name, avm_class.variables]) + while True: + opcode = _read_byte(coder) + if opcode == 17: # iftrue + offset = s24() + value = stack.pop() + if value: + coder.seek(coder.tell() + offset) + elif opcode == 18: # iffalse + offset = s24() + value = stack.pop() + if not value: + coder.seek(coder.tell() + offset) + elif opcode == 36: # pushbyte + v = _read_byte(coder) + stack.append(v) + elif opcode == 42: # dup + value = stack[-1] + stack.append(value) + elif opcode == 44: # pushstring + idx = u30() + stack.append(self.constant_strings[idx]) + elif opcode == 48: # pushscope + new_scope = stack.pop() + scopes.append(new_scope) + elif opcode == 66: # construct + arg_count = u30() + args = list(reversed( + [stack.pop() for _ in range(arg_count)])) + obj = stack.pop() + res = obj.avm_class.make_object() + stack.append(res) + elif opcode == 70: # callproperty + index = u30() + mname = self.multinames[index] + arg_count = u30() + args = list(reversed( + [stack.pop() for _ in range(arg_count)])) + obj = stack.pop() + + if isinstance(obj, _AVMClass_Object): + func = self.extract_function(obj.avm_class, mname) + res = func(args) + stack.append(res) + continue + elif isinstance(obj, _ScopeDict): + if mname in obj.avm_class.method_names: + func = self.extract_function(obj.avm_class, mname) + res = func(args) + else: + res = obj[mname] + stack.append(res) + continue + elif isinstance(obj, compat_str): + if mname == 'split': + assert len(args) == 1 + assert isinstance(args[0], compat_str) + if args[0] == '': + res = list(obj) + else: + res = obj.split(args[0]) + stack.append(res) + continue + elif isinstance(obj, list): + if mname == 'slice': + assert len(args) == 1 + assert isinstance(args[0], int) + res = obj[args[0]:] + stack.append(res) + continue + elif mname == 'join': + assert len(args) == 1 + assert isinstance(args[0], compat_str) + res = args[0].join(obj) + stack.append(res) + continue + raise NotImplementedError( + 'Unsupported property %r on %r' + % (mname, obj)) + elif opcode == 72: # returnvalue + res = stack.pop() + return res + elif opcode == 74: # constructproperty + index = u30() + arg_count = u30() + args = list(reversed( + [stack.pop() for _ in range(arg_count)])) + obj = stack.pop() + + mname = self.multinames[index] + assert isinstance(obj, _AVMClass) + + # We do not actually call the constructor for now; + # we just pretend it does nothing + stack.append(obj.make_object()) + elif opcode == 79: # callpropvoid + index = u30() + mname = self.multinames[index] + arg_count = u30() + args = list(reversed( + [stack.pop() for _ in range(arg_count)])) + obj = stack.pop() + if mname == 'reverse': + assert isinstance(obj, list) + obj.reverse() + else: + raise NotImplementedError( + 'Unsupported (void) property %r on %r' + % (mname, obj)) + elif opcode == 86: # newarray + arg_count = u30() + arr = [] + for i in range(arg_count): + arr.append(stack.pop()) + arr = arr[::-1] + stack.append(arr) + elif opcode == 93: # findpropstrict + index = u30() + mname = self.multinames[index] + for s in reversed(scopes): + if mname in s: + res = s + break + else: + res = scopes[0] + stack.append(res[mname]) + elif opcode == 94: # findproperty + index = u30() + mname = self.multinames[index] + for s in reversed(scopes): + if mname in s: + res = s + break + else: + res = avm_class.variables + stack.append(res) + elif opcode == 96: # getlex + index = u30() + mname = self.multinames[index] + for s in reversed(scopes): + if mname in s: + scope = s + break + else: + scope = avm_class.variables + # I cannot find where static variables are initialized + # so let's just return None + res = scope.get(mname) + stack.append(res) + elif opcode == 97: # setproperty + index = u30() + value = stack.pop() + idx = self.multinames[index] + if isinstance(idx, _Multiname): + idx = stack.pop() + obj = stack.pop() + obj[idx] = value + elif opcode == 98: # getlocal + index = u30() + stack.append(registers[index]) + elif opcode == 99: # setlocal + index = u30() + value = stack.pop() + registers[index] = value + elif opcode == 102: # getproperty + index = u30() + pname = self.multinames[index] + if pname == 'length': + obj = stack.pop() + assert isinstance(obj, list) + stack.append(len(obj)) + else: # Assume attribute access + idx = stack.pop() + assert isinstance(idx, int) + obj = stack.pop() + assert isinstance(obj, list) + stack.append(obj[idx]) + elif opcode == 115: # convert_ + value = stack.pop() + intvalue = int(value) + stack.append(intvalue) + elif opcode == 128: # coerce + u30() + elif opcode == 133: # coerce_s + assert isinstance(stack[-1], (type(None), compat_str)) + elif opcode == 160: # add + value2 = stack.pop() + value1 = stack.pop() + res = value1 + value2 + stack.append(res) + elif opcode == 161: # subtract + value2 = stack.pop() + value1 = stack.pop() + res = value1 - value2 + stack.append(res) + elif opcode == 164: # modulo + value2 = stack.pop() + value1 = stack.pop() + res = value1 % value2 + stack.append(res) + elif opcode == 175: # greaterequals + value2 = stack.pop() + value1 = stack.pop() + result = value1 >= value2 + stack.append(result) + elif opcode == 208: # getlocal_0 + stack.append(registers[0]) + elif opcode == 209: # getlocal_1 + stack.append(registers[1]) + elif opcode == 210: # getlocal_2 + stack.append(registers[2]) + elif opcode == 211: # getlocal_3 + stack.append(registers[3]) + elif opcode == 212: # setlocal_0 + registers[0] = stack.pop() + elif opcode == 213: # setlocal_1 + registers[1] = stack.pop() + elif opcode == 214: # setlocal_2 + registers[2] = stack.pop() + elif opcode == 215: # setlocal_3 + registers[3] = stack.pop() + else: + raise NotImplementedError( + 'Unsupported opcode %d' % opcode) + + avm_class.method_pyfunctions[func_name] = resfunc + return resfunc + diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 64a9618..e40b367 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -91,11 +91,9 @@ except ImportError: compat_subprocess_get_DEVNULL = lambda: open(os.path.devnull, 'w') try: - from urllib.parse import parse_qs as compat_parse_qs -except ImportError: # Python 2 - # HACK: The following is the correct parse_qs implementation from cpython 3's stdlib. - # Python 2's version is apparently totally broken - def _unquote(string, encoding='utf-8', errors='replace'): + from urllib.parse import unquote as compat_urllib_parse_unquote +except ImportError: + def compat_urllib_parse_unquote(string, encoding='utf-8', errors='replace'): if string == '': return string res = string.split('%') @@ -130,6 +128,13 @@ except ImportError: # Python 2 string += pct_sequence.decode(encoding, errors) return string + +try: + from urllib.parse import parse_qs as compat_parse_qs +except ImportError: # Python 2 + # HACK: The following is the correct parse_qs implementation from cpython 3's stdlib. + # Python 2's version is apparently totally broken + def _parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace'): qs, _coerce_result = qs, unicode @@ -149,10 +154,12 @@ except ImportError: # Python 2 continue if len(nv[1]) or keep_blank_values: name = nv[0].replace('+', ' ') - name = _unquote(name, encoding=encoding, errors=errors) + name = compat_urllib_parse_unquote( + name, encoding=encoding, errors=errors) name = _coerce_result(name) value = nv[1].replace('+', ' ') - value = _unquote(value, encoding=encoding, errors=errors) + value = compat_urllib_parse_unquote( + value, encoding=encoding, errors=errors) value = _coerce_result(value) r.append((name, value)) return r @@ -235,8 +242,8 @@ else: if sys.version_info >= (2,7): def find_xpath_attr(node, xpath, key, val): """ Find the xpath xpath[@key=val] """ - assert re.match(r'^[a-zA-Z]+$', key) - assert re.match(r'^[a-zA-Z0-9@\s:._]*$', val) + assert re.match(r'^[a-zA-Z-]+$', key) + assert re.match(r'^[a-zA-Z0-9@\s:._-]*$', val) expr = xpath + u"[@%s='%s']" % (key, val) return node.find(expr) else: @@ -845,6 +852,8 @@ def unified_strdate(date_str): return upload_date def determine_ext(url, default_ext=u'unknown_video'): + if url is None: + return default_ext guess = url.partition(u'?')[0].rpartition(u'.')[2] if re.match(r'^[A-Za-z0-9]+$', guess): return guess @@ -1193,11 +1202,6 @@ def format_bytes(bytes): return u'%.2f%s' % (converted, suffix) -def str_to_int(int_str): - int_str = re.sub(r'[,\.]', u'', int_str) - return int(int_str) - - def get_term_width(): columns = os.environ.get('COLUMNS', None) if columns: @@ -1265,15 +1269,22 @@ class HEADRequest(compat_urllib_request.Request): return "HEAD" -def int_or_none(v, scale=1, default=None, get_attr=None): +def int_or_none(v, scale=1, default=None, get_attr=None, invscale=1): if get_attr: if v is not None: v = getattr(v, get_attr, None) - return default if v is None else (int(v) // scale) + return default if v is None else (int(v) * invscale // scale) + + +def str_to_int(int_str): + if int_str is None: + return None + int_str = re.sub(r'[,\.]', u'', int_str) + return int(int_str) -def float_or_none(v, scale=1, default=None): - return default if v is None else (float(v) / scale) +def float_or_none(v, scale=1, invscale=1, default=None): + return default if v is None else (float(v) * invscale / scale) def parse_duration(s): diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 4d606c3..08b5339 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2014.07.15' +__version__ = '2014.08.05' -- 2.41.1