[Pkg-mozext-commits] [flashgot] 02/04: Imported Upstream version 1.5.5.95+dfsg

Michael Meskes meskes at moszumanska.debian.org
Sat Jan 25 11:04:20 UTC 2014


This is an automated email from the git hooks/post-receive script.

meskes pushed a commit to branch master
in repository flashgot.

commit 81b819e2dfda11be4602fb75ca3e2f27d10dd19e
Author: Michael Meskes <meskes at debian.org>
Date:   Sat Jan 25 11:50:44 2014 +0100

    Imported Upstream version 1.5.5.95+dfsg
---
 META-INF/manifest.mf                               |   43 -
 META-INF/zigbert.rsa                               |  Bin 1933 -> 0 bytes
 META-INF/zigbert.sf                                |   46 -
 chrome/flashgot.jar!/content/flashgot/DMS.js       |  164 +-
 .../content/flashgot/HttpInterceptor.js            |   68 +-
 .../content/flashgot/JSDownloadsAPI.jsm            |   66 +
 .../content/flashgot/JSDownloadsExtras.jsm         |  363 ++++
 .../flashgot.jar!/content/flashgot/LinkChooser.jsm |    6 +-
 .../flashgot.jar!/content/flashgot/MediaSniffer.js |  473 +++--
 chrome/flashgot.jar!/content/flashgot/Youtube.js   |  860 +++++++-
 .../flashgot.jar!/content/flashgot/YoutubeSwf.js   | 2115 ++++++++++++++++++++
 chrome/flashgot.jar!/content/flashgot/about.xul    |    2 +-
 chrome/flashgot.jar!/content/flashgot/chooser.js   |    5 +-
 chrome/flashgot.jar!/content/flashgot/contents.rdf |    2 +-
 .../content/flashgot/flashgotOverlay.js            |  227 ++-
 .../content/flashgot/flashgotOverlayFx.xul         |   37 +-
 .../content/flashgot/flashgotOverlayMoz.xul        |   27 +-
 .../locale/af-ZA/flashgot/flashgot.dtd             |    6 +-
 .../locale/af-ZA/flashgot/flashgot.properties      |    1 +
 .../locale/ar-SA/flashgot/flashgot.dtd             |    4 +
 .../locale/ar-SA/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/ar/flashgot/flashgot.dtd  |    4 +
 .../locale/ar/flashgot/flashgot.properties         |    1 +
 .../locale/be-BY/flashgot/flashgot.dtd             |    6 +-
 .../locale/be-BY/flashgot/flashgot.properties      |    1 +
 .../locale/bg-BG/flashgot/flashgot.dtd             |    6 +-
 .../locale/bg-BG/flashgot/flashgot.properties      |    1 +
 .../locale/bn-BD/flashgot/flashgot.dtd             |    4 +
 .../locale/bn-BD/flashgot/flashgot.properties      |    1 +
 .../locale/bn-IN/flashgot/flashgot.dtd             |    6 +-
 .../locale/bn-IN/flashgot/flashgot.properties      |    1 +
 .../locale/ca-AD/flashgot/flashgot.dtd             |    6 +-
 .../locale/ca-AD/flashgot/flashgot.properties      |    1 +
 .../locale/cs-CZ/flashgot/flashgot.dtd             |    6 +-
 .../locale/cs-CZ/flashgot/flashgot.properties      |    1 +
 .../locale/da-DK/flashgot/flashgot.dtd             |    6 +-
 .../locale/da-DK/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/da/flashgot/flashgot.dtd  |    6 +-
 .../locale/da/flashgot/flashgot.properties         |    1 +
 .../flashgot.jar!/locale/de/flashgot/flashgot.dtd  |    6 +-
 .../locale/de/flashgot/flashgot.properties         |    1 +
 .../locale/el-GR/flashgot/flashgot.dtd             |    6 +-
 .../locale/el-GR/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/el/flashgot/flashgot.dtd  |    6 +-
 .../locale/el/flashgot/flashgot.properties         |    1 +
 .../locale/en-US/flashgot/flashgot.dtd             |    6 +-
 .../locale/en-US/flashgot/flashgot.properties      |    3 +-
 .../locale/es-AR/flashgot/flashgot.dtd             |    6 +-
 .../locale/es-AR/flashgot/flashgot.properties      |    1 +
 .../locale/es-CL/flashgot/flashgot.dtd             |    6 +-
 .../locale/es-CL/flashgot/flashgot.properties      |    1 +
 .../locale/es-ES/flashgot/flashgot.dtd             |    6 +-
 .../locale/es-ES/flashgot/flashgot.properties      |    1 +
 .../locale/et-EE/flashgot/flashgot.dtd             |    6 +-
 .../locale/et-EE/flashgot/flashgot.properties      |    1 +
 .../locale/eu-ES/flashgot/flashgot.dtd             |    6 +-
 .../locale/eu-ES/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/eu/flashgot/flashgot.dtd  |    6 +-
 .../locale/eu/flashgot/flashgot.properties         |    1 +
 .../locale/fa-IR/flashgot/flashgot.dtd             |    6 +-
 .../locale/fa-IR/flashgot/flashgot.properties      |    1 +
 .../locale/fi-FI/flashgot/flashgot.dtd             |    6 +-
 .../locale/fi-FI/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/fi/flashgot/flashgot.dtd  |    6 +-
 .../locale/fi/flashgot/flashgot.properties         |    1 +
 .../flashgot.jar!/locale/fr/flashgot/flashgot.dtd  |   14 +-
 .../locale/fr/flashgot/flashgot.properties         |    2 +-
 .../locale/gl-ES/flashgot/flashgot.dtd             |    6 +-
 .../locale/gl-ES/flashgot/flashgot.properties      |    1 +
 .../locale/he-IL/flashgot/flashgot.dtd             |    6 +-
 .../locale/he-IL/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/he/flashgot/flashgot.dtd  |    6 +-
 .../locale/he/flashgot/flashgot.properties         |    1 +
 .../locale/hi-IN/flashgot/flashgot.dtd             |    6 +-
 .../locale/hi-IN/flashgot/flashgot.properties      |    1 +
 .../locale/hr-HR/flashgot/flashgot.dtd             |    6 +-
 .../locale/hr-HR/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/hu/flashgot/flashgot.dtd  |    6 +-
 .../locale/hu/flashgot/flashgot.properties         |    1 +
 .../locale/hy-AM/flashgot/flashgot.dtd             |    6 +-
 .../locale/hy-AM/flashgot/flashgot.properties      |    1 +
 .../locale/id-ID/flashgot/flashgot.dtd             |    6 +-
 .../locale/id-ID/flashgot/flashgot.properties      |    1 +
 .../locale/it-IT/flashgot/flashgot.dtd             |    6 +-
 .../locale/it-IT/flashgot/flashgot.properties      |    4 +-
 .../flashgot.jar!/locale/it/flashgot/flashgot.dtd  |    6 +-
 .../locale/it/flashgot/flashgot.properties         |    1 +
 .../locale/ja-JP/flashgot/flashgot.dtd             |    6 +-
 .../locale/ja-JP/flashgot/flashgot.properties      |    1 +
 .../locale/ka-GE/flashgot/flashgot.dtd             |    6 +-
 .../locale/ka-GE/flashgot/flashgot.properties      |    1 +
 .../locale/kk-KZ/flashgot/flashgot.dtd             |    6 +-
 .../locale/kk-KZ/flashgot/flashgot.properties      |    1 +
 .../locale/km-KH/flashgot/flashgot.dtd             |    6 +-
 .../locale/km-KH/flashgot/flashgot.properties      |    1 +
 .../locale/ko-KR/flashgot/flashgot.dtd             |    4 +
 .../locale/ko-KR/flashgot/flashgot.properties      |    1 +
 .../locale/lt-LT/flashgot/flashgot.dtd             |    6 +-
 .../locale/lt-LT/flashgot/flashgot.properties      |    1 +
 .../locale/mk-MK/flashgot/flashgot.dtd             |    6 +-
 .../locale/mk-MK/flashgot/flashgot.properties      |    1 +
 .../locale/ml-IN/flashgot/flashgot.dtd             |    6 +-
 .../locale/ml-IN/flashgot/flashgot.properties      |    1 +
 .../locale/mn-MN/flashgot/flashgot.dtd             |    6 +-
 .../locale/mn-MN/flashgot/flashgot.properties      |    1 +
 .../locale/ms-MY/flashgot/flashgot.dtd             |    6 +-
 .../locale/ms-MY/flashgot/flashgot.properties      |    1 +
 .../locale/nb-NO/flashgot/flashgot.dtd             |    6 +-
 .../locale/nb-NO/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/nl/flashgot/flashgot.dtd  |    6 +-
 .../locale/nl/flashgot/flashgot.properties         |    1 +
 .../locale/pl/flashgot/about.properties            |    2 +-
 .../flashgot.jar!/locale/pl/flashgot/contents.rdf  |    8 +-
 .../flashgot.jar!/locale/pl/flashgot/flashgot.dtd  |   22 +-
 .../locale/pl/flashgot/flashgot.properties         |    1 +
 .../locale/pt-BR/flashgot/flashgot.dtd             |    6 +-
 .../locale/pt-BR/flashgot/flashgot.properties      |    1 +
 .../locale/pt-PT/flashgot/flashgot.dtd             |    6 +-
 .../locale/pt-PT/flashgot/flashgot.properties      |    1 +
 .../locale/ro-RO/flashgot/flashgot.dtd             |    6 +-
 .../locale/ro-RO/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/ru/flashgot/flashgot.dtd  |    6 +-
 .../locale/ru/flashgot/flashgot.properties         |    1 +
 .../locale/sk-SK/flashgot/flashgot.dtd             |    6 +-
 .../locale/sk-SK/flashgot/flashgot.properties      |    1 +
 .../locale/sl-SI/flashgot/flashgot.dtd             |    6 +-
 .../locale/sl-SI/flashgot/flashgot.properties      |    1 +
 .../locale/sq-AL/flashgot/flashgot.dtd             |    6 +-
 .../locale/sq-AL/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/sr/flashgot/flashgot.dtd  |    6 +-
 .../locale/sr/flashgot/flashgot.properties         |    1 +
 .../locale/sv-SE/flashgot/flashgot.dtd             |    6 +-
 .../locale/sv-SE/flashgot/flashgot.properties      |    1 +
 .../locale/th-TH/flashgot/flashgot.dtd             |    6 +-
 .../locale/th-TH/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/th/flashgot/flashgot.dtd  |    6 +-
 .../locale/th/flashgot/flashgot.properties         |    1 +
 .../locale/tr-TR/flashgot/flashgot.dtd             |    6 +-
 .../locale/tr-TR/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/tr/flashgot/flashgot.dtd  |    6 +-
 .../locale/tr/flashgot/flashgot.properties         |    1 +
 .../locale/uk-UA/flashgot/flashgot.dtd             |    6 +-
 .../locale/uk-UA/flashgot/flashgot.properties      |    1 +
 .../flashgot.jar!/locale/uk/flashgot/flashgot.dtd  |    6 +-
 .../locale/uk/flashgot/flashgot.properties         |    1 +
 .../flashgot.jar!/locale/vi/flashgot/flashgot.dtd  |    6 +-
 .../locale/vi/flashgot/flashgot.properties         |    1 +
 .../locale/zh-CN/flashgot/flashgot.dtd             |    6 +-
 .../locale/zh-CN/flashgot/flashgot.properties      |    1 +
 .../locale/zh-TW/flashgot/flashgot.dtd             |    6 +-
 .../locale/zh-TW/flashgot/flashgot.properties      |    1 +
 components/flashgotService.js                      |   71 +-
 defaults/preferences/flashgot.js                   |   13 +
 install.js                                         |    2 +-
 install.rdf                                        |   10 +-
 155 files changed, 4576 insertions(+), 518 deletions(-)

diff --git a/META-INF/manifest.mf b/META-INF/manifest.mf
deleted file mode 100644
index 8ee70f5..0000000
--- a/META-INF/manifest.mf
+++ /dev/null
@@ -1,43 +0,0 @@
-Manifest-Version: 1.0
-Created-By: Signtool (signtool 3.11)
-Comments: PLEASE DO NOT EDIT THIS FILE. YOU WILL BREAK IT.
-
-Name: chrome/flashgot.jar
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: m4VsLu3XAUHWN+lPtGwWCQ==
-SHA1-Digest: 5qrp7Vv5cq1u/K/KFHzIUrP1/0A=
-
-Name: chrome.manifest
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: rljIjqaf3b/KnLFp5VlbOQ==
-SHA1-Digest: NQvIvN+FxzuRO54TUv6/ksMxcgI=
-
-Name: components/flashgotService.js
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: rYWsBDw+hkMI556yCgO9bg==
-SHA1-Digest: mhk1B9u+jhwfIq3BXmO7EKJ0HZo=
-
-Name: defaults/preferences/flashgot.js
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: icZ4sKRfFRSrUWtaLHabQw==
-SHA1-Digest: YeK79VJFSQyromdkuBqdpznNRhY=
-
-Name: FlashGot_License.txt
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: B41iWwCoRIp1qiKtG4CiSw==
-SHA1-Digest: hVuTFtcfnK60d7JsKf4ell2qbXo=
-
-Name: GPL.txt
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: /a/Gkapft/jiqelSH+93Gw==
-SHA1-Digest: HkktDXw+pcQm0470ZxX7bjD5mI4=
-
-Name: install.js
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: Nxgd0NEaL+D0vYiTyBf4VA==
-SHA1-Digest: S2fI72fe2ANeCLMyETG0BFZQXE4=
-
-Name: install.rdf
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: 36qhoooVKu0+B8HEgKVFxw==
-SHA1-Digest: hULG45b2RCCBsxqwmgF0bpx7/VQ=
diff --git a/META-INF/zigbert.rsa b/META-INF/zigbert.rsa
deleted file mode 100644
index f667fdb..0000000
Binary files a/META-INF/zigbert.rsa and /dev/null differ
diff --git a/META-INF/zigbert.sf b/META-INF/zigbert.sf
deleted file mode 100644
index e737335..0000000
--- a/META-INF/zigbert.sf
+++ /dev/null
@@ -1,46 +0,0 @@
-Signature-Version: 1.0
-Created-By: Signtool (signtool 3.11)
-Comments: PLEASE DO NOT EDIT THIS FILE. YOU WILL BREAK IT.
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: nl53hJxnMljy9bE5h1HK+g==
-SHA1-Digest: g/j7zfXSIT300ZToLcV2CUljpNQ=
-
-Name: chrome/flashgot.jar
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: R6kTxYRN8tYwoBs8KQWk8g==
-SHA1-Digest: jJe2IrvPUPkPt2UhL59OUY/goU8=
-
-Name: chrome.manifest
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: ziLam0HtUkG1KNdexsoF+A==
-SHA1-Digest: eFrFx2rPhU46elEJvEMUcttFzZk=
-
-Name: components/flashgotService.js
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: c2Vxob2ptEImeZT1yNN6DQ==
-SHA1-Digest: izeAI1IHMKKQxGu3XSoryMAFkN8=
-
-Name: defaults/preferences/flashgot.js
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: 6NeaSfx+RdCWoie4ynNmOA==
-SHA1-Digest: 5RQq6LJvXR5FxKkqzcqX+4o5qk0=
-
-Name: FlashGot_License.txt
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: Xq6uuCcGSVn6pewEClnYPA==
-SHA1-Digest: U9B0fsIHawNLBxpJYicu0lr3Hes=
-
-Name: GPL.txt
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: 9xDAnODig/1bioCK9wbJOw==
-SHA1-Digest: ZNhkpEDj8LDH6HX6B/gIU3oFi7A=
-
-Name: install.js
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: D7aLWhVARp85iR6yQeMepA==
-SHA1-Digest: 9XR7k02gZCVXkC19qQOnYS6JB88=
-
-Name: install.rdf
-Digest-Algorithms: MD5 SHA1
-MD5-Digest: 43/8FO9wtMWltb5ZjO9CxA==
-SHA1-Digest: oJA6nJG2bzfCgWUwbEJUC7wbYYU=
diff --git a/chrome/flashgot.jar!/content/flashgot/DMS.js b/chrome/flashgot.jar!/content/flashgot/DMS.js
index 92e2461..8a8cdb8 100644
--- a/chrome/flashgot.jar!/content/flashgot/DMS.js
+++ b/chrome/flashgot.jar!/content/flashgot/DMS.js
@@ -279,13 +279,12 @@ FlashGotDM.prototype = {
 ,
   createJobBody: function(links) {
     var jobLines = [];
-    var postData = links.postData || "";
  
     for (var j = 0, len = links.length, l; j < len; j++) {
       jobLines.push((l = links[j]).href,
            l.description,
            this.getCookie(l, links),
-           postData);
+           l.postData || links.postData ||  '');
       this.updateProgress(links, j, len);
     }
     return jobLines.join("\n");
@@ -376,7 +375,7 @@ FlashGotDM.prototype = {
     var l, parts;
     for (j = links.length; j-- > 0;) {
       l = links[j];
-      parts = l.href.match(/http[s]{0,1}:\/\/([^\/]+\.[^\/]+)/i); // host?
+      parts = l.href.match(/^https?:\/\/([^\/:]+)/i); // host?
       if (parts) {
         host = parts[1];
         var hpos = host.indexOf("@");
@@ -607,7 +606,7 @@ FlashGotDM.prototype = {
       ? links.length + " @ " +
       (function() {
         var ll = links.map(function(l) {
-          return l.href.match(/^[\w-]+:\/*([^\/]+)/)[1];
+          return l.href.match(/^[\w-]+:\/*([^\/]*)/)[1];
         }).sort(); // extract and sort domains
         for (var j = ll.length; j-- > 1;) // remove dupes
           if (ll[j - 1] == ll[j]) ll.splice(j, 1);
@@ -781,7 +780,7 @@ FlashGotDMX.prototype.createJob = function(links, opType) {
       COOKIE: shellEsc(this.getCookie(l, links)),
       CFILE: cookieFile,
       FOLDER: folder, 
-      POST: postData,
+      POST: l.postData && shellEsc(l.postData) || postData,
       UFILE: ufile,
       ULIST: ulist,
       USERPASS: l.userPass && shellEsc(l.userPass) || null,
@@ -1188,8 +1187,9 @@ FlashGotDMCust.prototype.shellEsc = function(s) {
 
 FlashGotDMCust.prototype.winEscHack = function(s) {
   // hack for bug at http://mxr.mozilla.org/seamonkey/source/xpcom/threads/nsProcessCommon.cpp#149 
+  var rstr = /^\w+:\/+/.test(s) ? "# " : " ";
   return (/[;&=]/.test(s) && !/\s/.test(s)) // "=" and ";" are command line separators on win!!!
-    ? s + " " : s; // we add a space to force escaping
+    ? s + rstr : s; // we add a space to force escaping
 }
 
 FlashGotDMCust.prototype.performJob = function(job) {
@@ -1228,7 +1228,7 @@ FlashGotDMCust.prototype.performJob = function(job) {
         REFERER: referrer, 
         COOKIE: esc(this.getCookie(l, links)), 
         FOLDER: folder, 
-        POST: postData,
+        POST: l.postData && esc(l.postData) || postData,
         CFILE: cookieFile,
         UFILE: urls.file,
         ULIST: urls.list,
@@ -1355,17 +1355,19 @@ FlashGotDM.initDMS = function() {
   new FlashGotDM("Download Master");
   
   for each (dm in [new FlashGotDM("DTA"), new FlashGotDM("DTA (Turbo)")]) {
-    dm.__defineGetter__("supported", 
-      function() {
-        try {
-          IOS.newChannel("chrome://dta-modules/content/support/filtermanager.js", null, null);
-          return true;
-        } catch(e) {}
-        try {
-          IOS.newChannel("resource://dta/support/filtermanager.jsm", null, null);
-          return true;
-        } catch(e) {}
-        return  "dtaIFilterManager" in CI || "@downthemall.net/privacycontrol;1" in CC 
+    dm.__defineGetter__("_supported", function() {
+      delete this._supported;
+      return this._supported = (function() {
+            try {
+              IOS.newChannel("chrome://dta-modules/content/support/filtermanager.js", null, null);
+              return true;
+            } catch(e) {}
+            try {
+              IOS.newChannel("resource://dta/support/filtermanager.jsm", null, null);
+              return true;
+            } catch(e) {}
+            return  "dtaIFilterManager" in CI || "@downthemall.net/privacycontrol;1" in CC;
+          })();
     });
     dm.turboDTA = /Turbo/.test(dm.name);
     dm.nativeUI = dm.turboDTA
@@ -1444,9 +1446,11 @@ FlashGotDM.initDMS = function() {
               description: l.description,
               ultDescription: '',
               referrer: referrer,
-              isPrivate: fg.inPrivate
+              isPrivate: fg.inPrivate,
           });
           
+          if ("postData" in l) lastItem.postData = l.postData;
+          
           if (("fname" in l) && l.fname) {
             lastItem.fileName = lastItem.destinationName = l.fname;
             // if (single && !turbo) single = false;
@@ -1478,7 +1482,7 @@ FlashGotDM.initDMS = function() {
             DTA.saveSingleItem(w, turbo, lastItem);
           } else if (single && (DTA.saveSingleLink || w.DTA_AddingFunctions.saveSingleLink)) {
             this.log("DTA.saveSingleLink " + lastItem.url);
-            DTA.saveSingleLink(w, turbo, lastItem.url, lastItem.referrer, lastItem.description, links.postData);
+            DTA.saveSingleLink(w, turbo, lastItem.url, lastItem.referrer, lastItem.description, lastItem.postData || links.postData);
           } else {
             this.log("DTA.saveLinkArray " + anchors.toSource());
             DTA[turbo ? "turboSaveLinkArray" : "saveLinkArray"](w, anchors, images);
@@ -1778,7 +1782,7 @@ FlashGotDM.initDMS = function() {
             rg.setInfo(l.description);
             rg.setCookie(this.getCookie(l, links));
             rg.setReferer(ref);
-            rg.setPostData(links.postData);
+            rg.setPostData(l.postData || links.postData);
             rg.setConfirmation(true);
             rg.addDownload();
             return;
@@ -2328,9 +2332,9 @@ FlashGotDM.initDMS = function() {
       '" to AddURL {"' + urlList.join('","') + '"}';
     
     if (this.postSupport) {
-
-      if (links.postData) { 
-        job +=' with form data "' + links.postData + '"';
+      var postData = links[0].postData || links.postData;
+      if (postData) { 
+        job +=' with form data "' + postData + '"';
       }
 
       const referer = this.getReferrer(links);
@@ -2371,8 +2375,9 @@ FlashGotDM.initDMS = function() {
     
     var job = 'tell app "' + this.macAppName + '" to download URLs {"'
       + urlList.join('", "') + '"}';
-    if (links.postData) {
-      job += ' by posting data "' + links.postData + '"';
+    var postData = links.links[0].postData || links.postData;
+    if (postData) {
+      job += ' by posting data "' + postData + '"';
     }
     job += ' to POSIX path "' + links.folder + '"';
     if (cookieList.length) {
@@ -2427,9 +2432,11 @@ FlashGotDM.initDMS = function() {
       "\" with cookies {\"" + cookies.join('", "') +
       "\"} with titles {\"" + titles.join('", "') +
       "\"} ";
-    if (links.postData)
-      job += 'with post data "' + links.postData + '"';
-    return job + " from applecation \"FlashGot\"\nend tell\n";
+    var postData = links[0].postData || links.postData;
+    if (postData) {
+      job += 'with post data "' + postData + '"';
+    }
+    return job + " from application \"FlashGot\"\nend tell\n";
   }
   
   if ("nsIDownloadManager" in CI) {
@@ -2457,7 +2464,7 @@ FlashGotDM.initDMS = function() {
         l = links[j];
         l.uri = IOS.newURI(l.href, cs, null);
         
-        if (noRedir || l.fname || !(l.uri instanceof CI.nsIURL) ||
+        if (noRedir || l.postData || l.fname || !(l.uri instanceof CI.nsIURL) ||
             rx && rx.test(l.uri.fileName)) {
           count--;
           continue;
@@ -2465,12 +2472,19 @@ FlashGotDM.initDMS = function() {
         
         allDone = false;
         
-        ch = IOS.newChannelFromURI(l.uri);
+        try {
+          ch = IOS.newChannelFromURI(l.uri);
+        }
+        catch (x) {
+          this.log("newChannelFromURI() failed: " + l.href + " (" + l.uri.spec + "): " + x + "\n" + x.stack);
+          --count;
+          continue;
+        }
         ch.asyncOpen({
           dm: this,
           link: l,
           onStartRequest: function(ch, ctx) {
-            if (!(ch instanceof CI.nsIHttpChannel) || Math.round(ch.responseStatus / 100) != 3)
+            if (!(ch instanceof CI.nsIHttpChannel) || !Components.isSuccessCode(ch.status) || Math.floor(ch.responseStatus / 100) != 3)
               this._done(ch);
           },
           onDataAvailable: function(req, ctx , stream , offset , count ) {
@@ -2480,12 +2494,13 @@ FlashGotDM.initDMS = function() {
           },
 
           _done: function(ch) {
+            var status = ch.status;
             ch.cancel(NS_BINDING_ABORTED);
-            if (ch instanceof CI.nsIHttpChannel && ch.responseStatus == 200 && !/\b(?:x|ht)ml\b/.test(ch.contentType)) {
+            if (ch instanceof CI.nsIHttpChannel && Components.isSuccessCode(status) && ch.responseStatus == 200 && !/\b(?:x|ht)ml\b/.test(ch.contentType)) {
               // this.link.uri = ch.URI; // removed, it breaks filesonic.com...
               this.link.fname = fg.extractFileName(ch) || this.link.fname;
             }
-            
+           
             if (--count === 0) {
               callback();
               progressHolder.progress.update(100);
@@ -2508,6 +2523,18 @@ FlashGotDM.initDMS = function() {
       this._checkLinks(links, cs, function() { self.performDownload(links, opType); });
     };
     
+    dm._streamify = function(s, contentType) {
+      if (!s) return null;
+      var stream = CC["@mozilla.org/io/string-input-stream;1"].createInstance(CI.nsIStringInputStream);
+      stream.setData(s, s.length);
+      if (stream instanceof CI.nsISeekableStream) stream.seek(0, 0);
+      var mis = CC["@mozilla.org/network/mime-input-stream;1"].createInstance(CI.nsIMIMEInputStream);
+      if (contentType) { mis.addHeader("Content-Type", contentType); }
+      mis.addContentLength = true;
+      mis.setData(stream);
+      return mis;
+    }
+    
     dm.performDownload = function(links, opType) {
       if (!links._prepared) {
         links._prepared = true;
@@ -2520,26 +2547,37 @@ FlashGotDM.initDMS = function() {
         CI.nsIWebBrowserPersist.PERSIST_FLAGS_FROM_CACHE;
       
       const dType = CI.nsIDownloadManager.DOWNLOAD_TYPE_DOWNLOAD;
-      var postData = links.postStream || null;
-
+      var postData = links.postData, postStream;
       var uri, folder, file;
-      var persist, args;
+      var args;
       var now = Date.now() * 1000;
       var dm = CC["@mozilla.org/download-manager;1"].getService(CI.nsIDownloadManager);
       folder = CC["@mozilla.org/file/local;1"].createInstance(CI.nsILocalFile);
       folder.initWithPath(links.folder);
       var mozAddDownload;
-      if(dm.startBatchUpdate) {
-        mozAddDownload = typeof(dType) == "undefined" 
-          ? function(src, dest, des, persist) { return dm.addDownload(src, dest, des, null, now, null, persist); }
-          : function(src, dest, des, persist) { return dm.addDownload(dType, src, dest, des, null, null, now, null, persist); }
-          ;
-        dm.startBatchUpdate();
-      } else {
-        mozAddDownload = function(src, dest, des, persist) { return dm.addDownload(dType, src, dest, des, null, now, null, persist, fg.inPrivate); };
+      try { // Fx 26 and above
+        Components.utils.import("chrome://flashgot/content/JSDownloadsAPI.jsm");
+      } catch (e) {
+        fg.log(e);
+        JSDownloadsAPI = null;
+      }
+      if (!JSDownloadsAPI) {
+        // older browsers
+        if(dm.startBatchUpdate) {
+          mozAddDownload = typeof(dType) == "undefined" 
+            ? function(src, dest, des, persist) { return dm.addDownload(src, dest, des, null, now, null, persist); }
+            : function(src, dest, des, persist) { return dm.addDownload(dType, src, dest, des, null, null, now, null, persist); }
+            ;
+          dm.startBatchUpdate();
+        } else {
+          mozAddDownload = function(src, dest, des, persist) { return dm.addDownload(dType, src, dest, des, null, now, null, persist, fg.inPrivate); };
+        }
       }
+      
       var dl;
       const overwrite = this.getPref("overwrite", false);
+      var persist = {}; // dummy for JSDownloadsAPI
+      var isPrivate = fg.inPrivate;
       for(var j = 0, len = links.length, l; j < len; j++) {
         l = links[j];
         try {
@@ -2548,27 +2586,47 @@ FlashGotDM.initDMS = function() {
           file = fg.createDownloadFile(folder, l.fname || uri, overwrite);
           
           if (!file) continue;
+          fg.log("Saving " + l.href + " to " + file.path);
           
+          if (JSDownloadsAPI) {
+            JSDownloadsAPI.add(l, links, file.path, isPrivate, function(err) {
+              if (isPrivate) {
+                Cu.reportError(err);
+              } else {
+                fg.log("Skipping link " + l.href + ": " + err);
+              }
+            });
+            continue;
+          }
+
           persist = CC["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(CI.nsIWebBrowserPersist);
           persist.persistFlags = persistFlags;
+          dl =  mozAddDownload(uri, IOS.newFileURI(file), file.leafName, persist);
+          if (dl instanceof CI.nsIWebProgressListener) persist.progressListener = dl;
+          else continue;
           
-          fg.log("Saving " + l.href + " to " + file.path);
-          
-          persist.progressListener = dl = 
-            mozAddDownload(uri, IOS.newFileURI(file), file.leafName, persist)
-              .QueryInterface(CI.nsIWebProgressListener);
-          
+          postStream = this._streamify(l.postData || postData, l.postContentType);
+          var extraHeaders = "";
+          if (l.extraHeaders) {
+            for (var p in l.extraHeaders) {
+              extraHeaders += p + ": " + l.extraHeaders[p] + "\r\n";
+            }
+          }
+          if (!extraHeaders) { extraHeaders = null; }
           if ("savePrivacyAwareURI" in persist) { // Gecko >= 19
               persist.savePrivacyAwareURI(uri, l.cacheKey || null,
-                  links.refURI, l.postStream || postData || null, null, file, fg.inPrivate);
+                  links.refURI, postStream, extraHeaders, file, fg.inPrivate);
           } else {
             persist.saveURI(uri, l.cacheKey || null,
-                  links.refURI, l.postStream || postData || null, null, file);
+                  links.refURI, postStream, extraHeaders, file);
           }
         } catch (e) {
           fg.log("Skipping link " + l.href + ": " + e);
         }
       }
+      
+      if (JSDownloadsAPI) return;
+      
       if(dm.endBatchUpdate) dm.endBatchUpdate();
       if(dm.flush) dm.flush();
       
diff --git a/chrome/flashgot.jar!/content/flashgot/HttpInterceptor.js b/chrome/flashgot.jar!/content/flashgot/HttpInterceptor.js
index c4d5995..6e11b49 100644
--- a/chrome/flashgot.jar!/content/flashgot/HttpInterceptor.js
+++ b/chrome/flashgot.jar!/content/flashgot/HttpInterceptor.js
@@ -84,33 +84,65 @@ HttpInterceptor.prototype = {
     return true;
   }
 ,
+  _slurp: function(stream, len) {
+    var sis = CC['@mozilla.org/binaryinputstream;1'].createInstance(CI.nsIBinaryInputStream);
+    sis.setInputStream(stream);
+    return sis.readBytes(len);
+  },
   extractPostData: function(channel, res) {
     res = res || {};
-    res.postData = res.postStream = null;
+    res.postData = null;
     if (channel instanceof CI.nsIUploadChannel &&
        channel.uploadStream instanceof CI.nsISeekableStream) {
       this.log("Extracting post data...");
-      var sis;
       try {
-        res.postStream = channel.uploadStream;
-        res.postStream.seek(0, 0);
-        sis = CC['@mozilla.org/scriptableinputstream;1'].createInstance(CI.nsIScriptableInputStream);
-        sis.init(res.postStream);
-        var postData  = sis.read(sis.available());
-        res.postStream.seek(0, 0);
+        var stream = channel.uploadStream;
+        var originalOffset = stream.tell(); 
+        stream.seek(2 /* EOF */, 0);
+        var size = stream.tell();
+        // Extra paranoia mode.
+        if (size !== originalOffset) {
+          this.log("WARNING: original offset != size: " + originalOffset + ", " + size);
+        }
+        stream.seek(0, 0);
+        var s = this._slurp(stream, size);
+        stream.seek(0, originalOffset);
         
-        // buffered persistent copy 
-        res.postStream = CC["@mozilla.org/io/string-input-stream;1"].createInstance(CI.nsIStringInputStream);
-        res.postStream.setData(postData, postData.length);
-        if (res.postStream instanceof CI.nsISeekableStream) res.postStream.seek(0, 0);
+        // extract upload content type
+        const headerVisitor = {visitHeader: function(name, value) {
+          if ("content-type" === name.toLowerCase()) res.postContentType = value;
+        }};
+        channel.visitRequestHeaders(headerVisitor);
+
+        // For some reason, grooveshark.com
+        // puts the "Referer", "Content-Type" and "Content-Length" headers
+        // into channel.uploadStream instead of the headers (visitRequestHeaders()).
+        // The download manager still has to send the "Range: bytes=0-"
+        // header in order to get the file.
+        if (/\.grooveshark\.com$/.test(channel.URI.asciiHost)) {
+          // Remove the headers.
+          const hdrEndPos = s.indexOf("\r\n\r\n");
+          if (hdrEndPos !== -1) {
+            var headers = s.substr(0, hdrEndPos).split(/\r\n/);
+            var m;
+            for each (var hdr in headers) {
+              m = hdr.match(/^(.+?)\s*:\s*(.+)$/);
+              if (!m) continue;
+              headerVisitor.visitHeader(m[1], m[2]);
+              if (res.postContentType) break;
+            }
+            if (!res.extraHeaders) res.extraHeaders = {};
+            res.extraHeaders["Range"] = "bytes=0-";
+            s = s.substr(hdrEndPos + 4);
+          }
+        }
         
-        // remove headers
-        postData = postData.replace(/\s+$/,'').split(/[\r\n]+/)
-        res.postData = postData[postData.length - 1];
+        res.postData = s;
       } catch(ex) {
-        this.log(ex.message);
-      } finally {
-        if (sis) sis.close();
+        this.log(ex
+          ? (ex.message || ex) + "\n" + (ex.stack || new Error().stack)
+          : "Error extracting POST data\n" + new Error().stack
+        );
       }
     }
     return res;
diff --git a/chrome/flashgot.jar!/content/flashgot/JSDownloadsAPI.jsm b/chrome/flashgot.jar!/content/flashgot/JSDownloadsAPI.jsm
new file mode 100644
index 0000000..545a85a
--- /dev/null
+++ b/chrome/flashgot.jar!/content/flashgot/JSDownloadsAPI.jsm
@@ -0,0 +1,66 @@
+var EXPORTED_SYMBOLS = ["JSDownloadsAPI"];
+
+const Cu = Components.utils;
+
+function isRequired() {
+  Cu.import("resource://gre/modules/Services.jsm");
+  try {
+    Cu.import("resource://gre/modules/Downloads.jsm");
+  } catch (e) { return false; }
+  try {
+    if (!Services.prefs.getBoolPref("browser.download.useJSTransfer")) return false;
+  } catch (e) {}
+  try {
+    return Services.vc.compare(Services.appinfo.version, "26.0a1") >= 0;
+  } catch (e) {}
+  return false;
+}
+
+function getList(isPrivate) {
+  delete this.getList;
+  return (this.getList =
+    ("getList" in Downloads)
+      ? function(p) Downloads.getList(p ? Downloads.PRIVATE : Downloads.PUBLIC)
+      : function(p) Downloads[p ? "getPrivateDownloadList" : "getPublicDownloadList"]()
+    )(isPrivate);
+}
+
+var JSDownloadsAPI = isRequired() && {
+  add: function(l, links, targetPath, isPrivate, onError) {
+    let src =  {
+      url: l.href,
+      isPrivate: isPrivate,
+      referrer: links.referrer
+    };
+    let saver = null;
+    let postData = l.postData || links.postData;
+    if (postData || l.extraHeaders) {
+      Cu.import("chrome://flashgot/content/JSDownloadsExtras.jsm");
+      src = new FlashgotDownloadSource(src);
+      src.post = { data: postData, contentType: l.postContentType };
+      src.headers = l.extraHeaders;
+      saver = new FlashgotDownloadCopySaver();
+    }
+    try {
+    Downloads.createDownload({source: src, target: targetPath }
+      ).then(
+        function(dl) {
+          try {
+            if (saver) {
+              dl.saver = saver;
+              saver.download = dl;
+            }
+            getList(isPrivate).then(
+              function(dlist) {
+                dlist.add(dl);
+              },
+              onError);
+            dl.start();
+          } catch (e) { onError(e) }
+        },
+        onError
+      );
+    } catch (e) { onError(e) }
+  }
+}
+|| null;
\ No newline at end of file
diff --git a/chrome/flashgot.jar!/content/flashgot/JSDownloadsExtras.jsm b/chrome/flashgot.jar!/content/flashgot/JSDownloadsExtras.jsm
new file mode 100644
index 0000000..a45fa08
--- /dev/null
+++ b/chrome/flashgot.jar!/content/flashgot/JSDownloadsExtras.jsm
@@ -0,0 +1,363 @@
+var EXPORTED_SYMBOLS = [
+  "FlashgotDownloadSource",
+  "FlashgotDownloadCopySaver"
+];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/DownloadCore.jsm");
+Cu.import("resource://gre/modules/Downloads.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "DownloadIntegration",
+                                  "resource://gre/modules/DownloadIntegration.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+                                  "resource://gre/modules/FileUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
+                                  "resource://gre/modules/NetUtil.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "OS",
+                                  "resource://gre/modules/osfile.jsm")
+XPCOMUtils.defineLazyModuleGetter(this, "Promise",
+                                  "resource://gre/modules/commonjs/sdk/core/promise.js");
+XPCOMUtils.defineLazyModuleGetter(this, "Task",
+                                  "resource://gre/modules/Task.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gDownloadHistory",
+           "@mozilla.org/browser/download-history;1",
+           Ci.nsIDownloadHistory);
+XPCOMUtils.defineLazyServiceGetter(this, "gExternalHelperAppService",
+           "@mozilla.org/uriloader/external-helper-app-service;1",
+           Ci.nsIExternalHelperAppService);
+
+const BackgroundFileSaverStreamListener = Components.Constructor(
+      "@mozilla.org/network/background-file-saver;1?mode=streamlistener",
+      "nsIBackgroundFileSaver");
+
+
+
+/**
+ * Returns true if the given value is a primitive string or a String object.
+ */
+function isString(aValue) {
+  // We cannot use the "instanceof" operator reliably across module boundaries.
+  return (typeof aValue == "string") ||
+         (typeof aValue == "object" && "charAt" in aValue);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Supports POST data and custom headers support.
+// class FlashgotDownloadSource extends DownloadSource {
+//   Post post;
+//   Map<string, string> headers;
+//
+//   struct Post {
+//     string data;
+//     string contentType;
+//   }
+// }
+// FlashgotDownloadSource(Object serializable = null);
+function FlashgotDownloadSource(o /*= null*/) {
+  if (!o) { return; }
+  this.url = o.url;
+  this.isPrivate = o.isPrivate;
+  this.referrer = o.referrer;
+  this.post = o.post;
+  this.headers = o.headers;
+}
+
+FlashgotDownloadSource.prototype = {
+  __proto__: DownloadSource.prototype,
+
+  post: null,
+  headers: null,
+
+  // @override
+  toSerializable: function() {
+    return {
+      url: this.url,
+      isPrivate: this.isPrivate,
+      referrer: this.referrer,
+      post: this.post,
+      headers: this.headers
+    };
+  }
+};
+
+FlashgotDownloadSource.fromSerializable = function(o) {
+  return new FlashgotDownloadSource(o);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// class FlashgotDownloadCopySaver extends DownloadCopySaver
+// Supports POST data and custom headers support.
+function FlashgotDownloadCopySaver() {}
+
+FlashgotDownloadCopySaver.prototype = {
+  __proto__: DownloadCopySaver.prototype,
+
+  // @override
+  execute: function DCS_execute(aSetProgressBytesFn, aSetPropertiesFn) {
+    try {
+      let copySaver = this;
+      this._canceled = false;
+  
+      let download = this.download;
+      let targetPath = download.target.path;
+      let partFilePath = download.target.partFilePath;
+      let keepPartialData = download.tryToKeepPartialData;
+  
+      return Task.spawn(function task_DCS_execute() {
+        // Add the download to history the first time it is started in this
+        // session.  If the download is restarted in a different session, a new
+        // history visit will be added.  We do this just to avoid the complexity
+        // of serializing this state between sessions, since adding a new visit
+        // does not have any noticeable side effect.
+        if (!this.alreadyAddedToHistory) {
+          this.addToHistory();
+          this.alreadyAddedToHistory = true;
+        }
+  
+        // To reduce the chance that other downloads reuse the same final target
+        // file name, we should create a placeholder as soon as possible, before
+        // starting the network request.  The placeholder is also required in case
+        // we are using a ".part" file instead of the final target while the
+        // download is in progress.
+        try {
+          // If the file already exists, don't delete its contents yet.
+          let file = yield OS.File.open(targetPath, { write: true });
+          yield file.close();
+        } catch (ex if ex instanceof OS.File.Error) {
+          // Throw a DownloadError indicating that the operation failed because of
+          // the target file.  We cannot translate this into a specific result
+          // code, but we preserve the original message using the toString method.
+          let error = new DownloadError(Cr.NS_ERROR_FAILURE, ex.toString());
+          error.becauseTargetFailed = true;
+          throw error;
+        }
+  
+        try {
+          let deferSaveComplete = Promise.defer();
+  
+          if (this._canceled) {
+            // Don't create the BackgroundFileSaver object if we have been
+            // canceled meanwhile.
+            throw new DownloadError(Cr.NS_ERROR_FAILURE, "Saver canceled.");
+          }
+  
+          // Create the object that will save the file in a background thread.
+          let backgroundFileSaver = new BackgroundFileSaverStreamListener();
+          try {
+            // When the operation completes, reflect the status in the promise
+            // returned by this download execution function.
+            backgroundFileSaver.observer = {
+              onTargetChange: function () { },
+              onSaveComplete: function DCSE_onSaveComplete(aSaver, aStatus)
+              {
+                // Free the reference cycle, to release resources earlier.
+                backgroundFileSaver.observer = null;
+                this._backgroundFileSaver = null;
+  
+                // Send notifications now that we can restart if needed.
+                if (Components.isSuccessCode(aStatus)) {
+                  deferSaveComplete.resolve();
+                } else {
+                  // Infer the origin of the error from the failure code, because
+                  // BackgroundFileSaver does not provide more specific data.
+                  deferSaveComplete.reject(new DownloadError(aStatus, null,
+                                                             true));
+                }
+              },
+            };
+  
+            // Create a channel from the source, and listen to progress
+            // notifications.
+            let channel = NetUtil.newChannel(NetUtil.newURI(download.source.url));
+            if (channel instanceof Ci.nsIPrivateBrowsingChannel) {
+              channel.setPrivate(download.source.isPrivate);
+            }
+            if (channel instanceof Ci.nsIHttpChannel) {
+              if (download.source.referrer) {
+                channel.referrer = NetUtil.newURI(download.source.referrer);
+              }
+              if (download.source.post) {
+                let post = download.source.post;
+                let sis = Components.classes["@mozilla.org/io/string-input-stream;1"]
+                  .createInstance(Components.interfaces.nsIStringInputStream);
+                sis.setData(post.data, post.data.length);
+                channel.QueryInterface(Components.interfaces.nsIUploadChannel)
+                  .setUploadStream(sis, post.contentType || null, -1);
+                // The order is important - setUploadStream resets to PUT.
+                channel.requestMethod = "POST";
+              }
+              if (download.source.headers) {
+                let headers = download.source.headers;
+                for (let p in headers) {
+                  channel.setRequestHeader(p, headers[p], false /*don't merge, overwrite*/);
+                }
+              }
+            }
+  
+            // If we have data that we can use to resume the download from where
+            // it stopped, try to use it.
+            let resumeAttempted = false;
+            let resumeFromBytes = 0;
+            if (channel instanceof Ci.nsIResumableChannel && this.entityID &&
+                partFilePath && keepPartialData) {
+              try {
+                let stat = yield OS.File.stat(partFilePath);
+                channel.resumeAt(stat.size, this.entityID);
+                resumeAttempted = true;
+                resumeFromBytes = stat.size;
+              } catch (ex if ex instanceof OS.File.Error &&
+                             ex.becauseNoSuchFile) { }
+            }
+  
+            channel.notificationCallbacks = {
+              QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor]),
+              getInterface: XPCOMUtils.generateQI([Ci.nsIProgressEventSink]),
+              onProgress: function DCSE_onProgress(aRequest, aContext, aProgress,
+                                                   aProgressMax)
+              {
+                let currentBytes = resumeFromBytes + aProgress;
+                let totalBytes = aProgressMax == -1 ? -1 : (resumeFromBytes +
+                                                            aProgressMax);
+                aSetProgressBytesFn(currentBytes, totalBytes, aProgress > 0 &&
+                                    partFilePath && keepPartialData);
+              },
+              onStatus: function () { },
+            };
+  
+            // Open the channel, directing output to the background file saver.
+            backgroundFileSaver.QueryInterface(Ci.nsIStreamListener);
+            channel.asyncOpen({
+              onStartRequest: function (aRequest, aContext) {
+                backgroundFileSaver.onStartRequest(aRequest, aContext);
+  
+                aSetPropertiesFn({ contentType: channel.contentType });
+  
+                // Ensure we report the value of "Content-Length", if available,
+                // even if the download doesn't generate any progress events
+                // later.
+                if (channel.contentLength >= 0) {
+                  aSetProgressBytesFn(0, channel.contentLength);
+                }
+  
+                // If the URL we are downloading from includes a file extension
+                // that matches the "Content-Encoding" header, for example ".gz"
+                // with a "gzip" encoding, we should save the file in its encoded
+                // form.  In all other cases, we decode the body while saving.
+                if (channel instanceof Ci.nsIEncodedChannel &&
+                    channel.contentEncodings) {
+                  let uri = channel.URI;
+                  if (uri instanceof Ci.nsIURL && uri.fileExtension) {
+                    // Only the first, outermost encoding is considered.
+                    let encoding = channel.contentEncodings.getNext();
+                    if (encoding) {
+                      channel.applyConversion =
+                        gExternalHelperAppService.applyDecodingForExtension(
+                                                  uri.fileExtension, encoding);
+                    }
+                  }
+                }
+  
+                if (keepPartialData) {
+                  // If the source is not resumable, don't keep partial data even
+                  // if we were asked to try and do it.
+                  if (aRequest instanceof Ci.nsIResumableChannel) {
+                    try {
+                      // If reading the ID succeeds, the source is resumable.
+                      this.entityID = aRequest.entityID;
+                    } catch (ex if ex instanceof Components.Exception &&
+                                   ex.result == Cr.NS_ERROR_NOT_RESUMABLE) {
+                      keepPartialData = false;
+                    }
+                  } else {
+                    keepPartialData = false;
+                  }
+                }
+  
+                if (partFilePath) {
+                  // If we actually resumed a request, append to the partial data.
+                  if (resumeAttempted) {
+                    // TODO: Handle Cr.NS_ERROR_ENTITY_CHANGED
+                    backgroundFileSaver.enableAppend();
+                  }
+  
+                  // Use a part file, determining if we should keep it on failure.
+                  backgroundFileSaver.setTarget(new FileUtils.File(partFilePath),
+                                                keepPartialData);
+                } else {
+                  // Set the final target file, and delete it on failure.
+                  backgroundFileSaver.setTarget(new FileUtils.File(targetPath),
+                                                false);
+                }
+              }.bind(copySaver),
+  
+              onStopRequest: function (aRequest, aContext, aStatusCode) {
+                try {
+                  backgroundFileSaver.onStopRequest(aRequest, aContext,
+                                                    aStatusCode);
+                } finally {
+                  // If the data transfer completed successfully, indicate to the
+                  // background file saver that the operation can finish.  If the
+                  // data transfer failed, the saver has been already stopped.
+                  if (Components.isSuccessCode(aStatusCode)) {
+                    if (partFilePath) {
+                      // Move to the final target if we were using a part file.
+                      backgroundFileSaver.setTarget(
+                                          new FileUtils.File(targetPath), false);
+                    }
+                    backgroundFileSaver.finish(Cr.NS_OK);
+                  }
+                }
+              }.bind(copySaver),
+  
+              onDataAvailable: function (aRequest, aContext, aInputStream,
+                                         aOffset, aCount) {
+                backgroundFileSaver.onDataAvailable(aRequest, aContext,
+                                                    aInputStream, aOffset,
+                                                    aCount);
+              }.bind(copySaver),
+            }, null);
+  
+            // If the operation succeeded, store the object to allow cancellation.
+            this._backgroundFileSaver = backgroundFileSaver;
+          } catch (ex) {
+            // In case an error occurs while setting up the chain of objects for
+            // the download, ensure that we release the resources of the saver.
+            backgroundFileSaver.finish(Cr.NS_ERROR_FAILURE);
+            throw ex;
+          }
+  
+          // We will wait on this promise in case no error occurred while setting
+          // up the chain of objects for the download.
+          yield deferSaveComplete.promise;
+        } catch (ex) {
+          // Ensure we always remove the placeholder for the final target file on
+          // failure, independently of which code path failed.  In some cases, the
+          // background file saver may have already removed the file.
+          try {
+            yield OS.File.remove(targetPath);
+          } catch (e2 if e2 instanceof OS.File.Error && e2.becauseNoSuchFile) { }
+          throw ex;
+        }
+      }.bind(this));
+    } catch(x){
+      Components.utils.reportError("FlashgotDownloadCopySaver::execute: exception: "
+        + (x ? (x.message || x) + "\n" + (x.stack || new Error().stack): x));
+    }
+    return null;
+  },
+
+
+  // @override
+  toSerializable: function() this.entityID ? { type: "flashgot", entityID: this.entityID } : "flashgot"
+  
+};
+
diff --git a/chrome/flashgot.jar!/content/flashgot/LinkChooser.jsm b/chrome/flashgot.jar!/content/flashgot/LinkChooser.jsm
index f2cbba5..2cf2724 100644
--- a/chrome/flashgot.jar!/content/flashgot/LinkChooser.jsm
+++ b/chrome/flashgot.jar!/content/flashgot/LinkChooser.jsm
@@ -34,7 +34,11 @@ function LinkChooser(tree, links, filter, allChoosen) {
         }
       }
       if (l._type) {
-        ext = ms.getPrimaryExtension(l._type, ext);
+        try {
+            ext = ms.getPrimaryExtension(l._type, ext);
+        } catch (e) {
+            ext = "";
+        }
       } else {
         l._type = ext ? "(" + ext + ")" : fname ? "???" : "/";
       }
diff --git a/chrome/flashgot.jar!/content/flashgot/MediaSniffer.js b/chrome/flashgot.jar!/content/flashgot/MediaSniffer.js
index fefcf6f..ddce090 100644
--- a/chrome/flashgot.jar!/content/flashgot/MediaSniffer.js
+++ b/chrome/flashgot.jar!/content/flashgot/MediaSniffer.js
@@ -18,24 +18,26 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                              
 ***** END LICENSE BLOCK *****/
+
 LAZY_INCLUDE("Youtube");
+var gFlashGotService = Components.classes["@maone.net/flashgot-service;1"].getService().wrappedJSObject;
 
 var MediaSniffer = {
- 
+
   QueryInterface: xpcom_generateQI([
-    CI.nsIObserver, 
+    CI.nsIObserver,
     CI.nsISupportsWeakReference,
     CI.nsISupports,
     CI.nsIWebProgressListener
   ]),
-  
-  
+
+
   debug: false,
   // http-on-examine-response Observer
-  
+
   mimeService: CC['@mozilla.org/uriloader/external-helper-app-service;1']
-                     .getService(CI.nsIMIMEService),
-  mediaTypesRx: /\b(?:audio|video|smil|flv)\b/i,
+    .getService(CI.nsIMIMEService),
+  mediaTypesRx: /\b(?:audio|video|smil|flv)\b|media\b/i,
   badTypesRx: /\b(?:mp2ts?|mpeg-tts)$/i,
   mediaMap: {
     "asx": "video/x-ms-asx", // fake, see "media" processor
@@ -47,19 +49,20 @@ var MediaSniffer = {
     "f4p": "video/mp4",
     "m4v": "video/mp4",
     "mp3": "audio/mp3", // MimeService chokes on this
-    "mp4": "video/mp4" // just to be sure :)
+    "mp4": "video/mp4", // just to be sure :)
+    "rm": "application/vnd.rn-realmedia"
   },
   get inverseMediaMap() {
     var m = {};
     for (var p in this.mediaMap) m[this.mediaMap[p]] = p;
     m["flv-application/octet-stream"] =
-    m["application/octet-stream"] =
-    m["video/x-flv"] = "flv";
+      m["application/octet-stream"] =
+      m["video/x-flv"] = "flv";
     delete this.inverseMediaMap;
     return this.inverseMediaMap = m;
   },
-  
-  sniffType: function(channel, forcedContentType) {
+
+  sniffType: function (channel, forcedContentType) {
     var path = fg.extractFileName(channel) || channel.URI.path;
     path = path.replace(/#[\s\S]*/, '');
     if (path.length > 1024) path = path.substring(0, 1024);
@@ -73,90 +76,145 @@ var MediaSniffer = {
       try {
         contentType = this.mimeService.getTypeFromExtension(ext);
         if (this.mediaTypesRx.test(contentType)) break;
-      } catch(e) {}
+      } catch (e) {}
       contentType = '';
     }
-    
+
     var fname = m && m[1];
     if (forcedContentType && !(forcedContentType == "video/x-ms-asf" && contentType == "video/x-ms-asx")) {
       if (!fname) {
         fname = (channel.URI instanceof CI.nsIURL) && channel.URI.fileName || path.replace(/.*\//g, '');
         try {
-          fname += "." + (this.inverseMediaMap[forcedContentType] || this.mimeService.getPrimaryExtension(forcedContentType, '')); 
-        } catch(ex) {}
+          fname += "." + (this.inverseMediaMap[forcedContentType] || this.mimeService.getPrimaryExtension(forcedContentType, ''));
+        } catch (ex) {}
       }
       contentType = forcedContentType;
     }
-    
+
     if (!(contentType && fname)) return null;
     try {
       fname = decodeURIComponent(fname);
     } catch (e) {
       fname = unescape(fname);
     }
-    return { fname: fname, contentType: contentType };
+    return {
+      fname: fname,
+      contentType: contentType
+    };
   },
-  
+
   typesWhitelistRx: /\b(?:x(?:ht)?ml|image|css|j(?:ava(?:script)?|son)|shockwave)\b/i,
-  
+
   get downloadInterface() {
     delete this.downloadInterface;
     return this.downloadInterface = "nsIHttpActivityObserver" in CI ? CI.nsICancelable : CI.nsIWebBrowserPersist;
   },
 
-  observe: function(channel, topic, data) {
-    if (channel instanceof CI.nsIChannel) {
+  _set_current_url: function (w, url) {
+    w._flashgotMediaCurrentUrl = url;
+  },
+
+  observe: function (channel, topic, data) {
+    if (channel instanceof CI.nsIChannel && Components.isSuccessCode(channel.status)) {
       try {
-        var contentType = channel.contentType;
+        var extras = {}, win, yt_win, media, map, location;
+        try {
+          if (channel instanceof CI.nsIPropertyBag && channel instanceof CI.nsIWritablePropertyBag) {
+            extras = channel.getProperty("flashgot.media.extras").wrappedJSObject || extras;
+            win = extras.window;
+            if (win) {
+              channel.deleteProperty("flashgot.media.extras");
+              win = win.top;
+            }
+          }
+        } catch (ignore) {}
+        if (!win) {
+          yt_win = DOM.findChannelWindow(channel) || DOM.mostRecentBrowserWindow && DOM.mostRecentBrowserWindow.content;
+          if (!yt_win) return;
+          win = extras.window = yt_win.top;
+        }
+        media = win._flashgotMedia || (win._flashgotMedia = []);
+        location = win.location.href.replace(/#.*/, '');
+        if (("_location" in media) && media._location !== location) win._flashgotMedia = media = [];
+        media._location = location;
+        map = media._map || (media._map = {});
+
+        // YouTube - 403 Forbidden. Probably the signature algorithm has changed.
+        if ((channel instanceof CI.nsIHttpChannel)
+          && channel.responseStatus === 403
+          && Youtube.is_stream_url(channel.name))
+        {
+          fg.log("YouTube 403: video " + extras["flashgot::video_id"] + ": outdated signature function? URL: " + channel.name);
+          if (extras["flashgot::parsed"] && !win.flashgotRefreshedYoutubeSignature) {
+            if (fg.getPref("media.YouTube.decode_signature_func.auto", true)
+                && (win.flashgotRefreshedYoutubeSignature = 
+                      Youtube.refresh_signature_func(win, function() {
+                        MediaSniffer.checkYoutube(win, null, true);
+                      })
+                   )
+               ) {
+              return;
+            }
+            
+            // Add the "Refresh signature" menu item
+            const YOUTUBE_REFRESH_SIGNATURE_FUNC_URL = "flashgot::Youtube::refresh_signature_func";
+            if (!(YOUTUBE_REFRESH_SIGNATURE_FUNC_URL in map)) {
+              media.push(map[YOUTUBE_REFRESH_SIGNATURE_FUNC_URL] = {
+                parsed: true,
+                originalURL: YOUTUBE_REFRESH_SIGNATURE_FUNC_URL,
+                Youtube: Youtube,
+                MediaSniffer: MediaSniffer,
+              });
+              this.updateUI(win);
+            }
+            return;
+            
+          }
+        }
+
+        // YouTube - for DASH'ed streams (audio/video-only), Content-Type is "application/octet-stream".
+        var contentType;
+        if (Youtube.is_stream_url(channel.name) && Math.floor(channel.responseStatus / 100) === 2) {
+          if (Object.keys(map).some(function(url){return Youtube.stream_url_equals(url, channel.name)})) {
+            this._set_current_url(win, channel.name);
+            return;
+          }
+          // Our parsed stream, or a stream requested by the player.
+          // Don't use extras.type because it can be remapped (e.g. "mp4" instead of "video/mp4").
+          contentType = Youtube.get_stream_content_type(channel.name);
+        }
+        if (!contentType) {
+          contentType = channel.contentType;
+        }
         if (!contentType ||
-            (channel instanceof CI.nsIHttpChannel) && channel.responseStatus >= 400 ||
-            this.typesWhitelistRx.test(contentType))
+          (channel instanceof CI.nsIHttpChannel) && channel.responseStatus >= 400 ||
+          this.typesWhitelistRx.test(contentType))
           return;
-        
-         if (channel.responseStatus === 204 && contentType.indexOf("video/") === 0 || 
-             contentType === "application/x-www-form-urlencoded" && /youtube\.com\/get_video_info\?.*el=embedded/.test(channel.name)
-          ) {
+
+        if (channel.responseStatus === 204 && contentType.indexOf("video/") === 0 ||
+          contentType === "application/x-www-form-urlencoded" && /youtube\.com\/get_video_info\?.*el=embedded/.test(channel.name)
+        ) {
           this.checkYoutube(DOM.findChannelWindow(channel) || DOM.mostRecentBrowserWindow.content, channel.name);
           return;
         }
-        
+
         if (channel.notificationCallbacks instanceof this.downloadInterface) {
           if (this.debug) dump("Skipping " + channel.name + ": from the built-in download manager or DTA\n" + channel.notificationCallbacks + "\n\n");
           return;
         }
-          
+
+        if (yt_win && (this.checkYoutube(yt_win, url) || this.checkYoutube(yt_win))) {
+          //return;
+        }
         if (this.debug) dump("Examining " + channel.name + " (" + contentType + ")\n");
-        
+
         var typeInfo = null;
         if (this.mediaTypesRx.test(contentType) || (typeInfo = this.sniffType(channel))) {
-          
+
           var url = channel.URI.spec;
-          
-          var win, extras = {};
-          try {
-            if (channel instanceof CI.nsIPropertyBag && channel instanceof CI.nsIWritablePropertyBag) {
-              extras = channel.getProperty("flashgot.media.extras").wrappedJSObject || extras;
-              win = extras.window;
-              if (win) {
-                channel.deleteProperty("flashgot.media.extras");
-                win = win.top;
-              }
-            }
-          } catch (e) {}
-          
-          if (!win) {
-            win = (DOM.findChannelWindow(channel) || DOM.mostRecentBrowserWindow.content);
-            if (win && (this.checkYoutube(win, url) || this.checkYoutube(win))) {
-              return;
-            }
-            win = extras.window = win.top;
-          }
+
           if (this.debug) dump("Media Window: " + win + " - " + win.location.href + " -- " + contentType + "\n");
-          var media = win._flashgotMedia || (win._flashgotMedia = []);
-          
-          
-          var map = media._map || (media._map = {});
-          
+
           var cacheable = true;
 
           if (/\/frag\(\d+\)\/|&range=\d+-\d+/.test(url)) {
@@ -164,132 +222,135 @@ var MediaSniffer = {
             url = this.normalizeQuery(url.replace(/&range=[^&]*|\/frag\(\d+\)/g, '').replace(/\b(?:cm2|mt)=\d+\b/, ''));
             const goodDMHost = "vid2.ec.dmcdn.net"; // Dailymotion unfragmented-enabled host
             if (url in map || url.replace(/(:\/\/)[^\/]+\.(?:dmcdn\.net|dailymotion\.com)(?=\/)/, "$1" + goodDMHost) in map) return;
-            if (this.peek(url, extras, function(xhr) {
-              switch(xhr.status) {
-                case 403:
-                  var host = xhr.channel.URI.host;
-                  if (/\.(?:dmcdn\.net|dailymotion\.com)$/.test(host) && host !== goodDMHost) {
-                    var uri = xhr.channel.URI.clone();
-                    uri.host = goodDMHost;
-                    MediaSniffer.peek(uri.spec, extras);
-                  }
+            if (this.peek(url, extras, function (xhr) {
+              switch (xhr.status) {
+              case 403:
+                var host = xhr.channel.URI.host;
+                if (/\.(?:dmcdn\.net|dailymotion\.com)$/.test(host) && host !== goodDMHost) {
+                  var uri = xhr.channel.URI.clone();
+                  uri.host = goodDMHost;
+                  MediaSniffer.peek(uri.spec, extras);
+                }
               }
             })) return;
           } else if ((url in map) && !("cacheKey" in map[url])) {
             media.splice(media.indexOf(map[url], 1));
             delete map[url];
           }
-          
+
           if (!(url in map)) {
-            
-            contentType = contentType.replace(/;.*/); // ignore trailing extras, e.g. charset
-            
+
+            contentType = contentType.replace(/\s*;.*/, ""); // ignore trailing extras, e.g. charset
+
             if (/\bx-ms-asf\b/.test(contentType)) {
               try {
-                if (channel.contentLength && channel.contentLength < 2048) contentType = "video/x-ms-asx";
-              } catch(e) {}
-              try {
-                if (channel.contentCharset && channel.contentLength < 16384) contentType = "video/x-ms-asx";
-              } catch(e) {}
+                if (channel.contentCharset || channel.contentLength < 16384) contentType = "video/x-ms-asx";
+              } catch (e) {}
             }
-            
+
             // asf content type can also refer to an asx, we need to check the file name to decide
             if (!typeInfo) {
               typeInfo = this.sniffType(channel, contentType)
             }
-            
+
             contentType = typeInfo.contentType;
-            
-            if (contentType === "video/x-ms-asx" && /(?:\.(?:youtube|ytimg)\.com|doubleclick\.net)$/.test(channel.URI.host)
-                && gFlashGotService.getPref("media.skipAds", true))
+
+            if (/-ms-/.test(contentType) && /(?:\.(?:youtube|ytimg)\.com|doubleclick\.net)$/.test(channel.URI.host)
+              && gFlashGotService.getPref("media.skipAds", true))
               return;
-            
+
             if (this.badTypesRx.test(contentType)) return;
 
             var contentLength = -1;
             if (cacheable) try {
-                contentLength = channel.contentLength;
-                if (/\b(?:flv|mp4)\b/.test(contentType) &&
-                    (channel instanceof CI.nsIHttpChannel) &&
-                    channel.responseStatus < 300 && // redirects can have 0 length
-                    contentLength > -1 && contentLength < fg.getPref("media.minSize.flv"))
-                  return;
+              contentLength = channel.contentLength;
+              if (/\b(?:flv|mp4)\b/.test(contentType) &&
+                (channel instanceof CI.nsIHttpChannel) &&
+                channel.responseStatus < 300 && // redirects can have 0 length
+                contentLength > -1 && contentLength < fg.getPref("media.minSize.flv"))
+                return;
             } catch (e) {}
-            
+
             var humanType = extras.type || contentType;
             if (extras.quality) humanType = extras.quality + " " + humanType;
-            
+
+            // YouTube seek timestamps.
+            extras["flashgot::seek_pos"] = 0;
+            if (/\.youtube\.com$/.test(channel.URI.host) && /[?&]begin=(\d+)/.test(url)) {
+              extras["flashgot::seek_pos"] = parseInt(RegExp.$1, 10);
+            }
+
             var tip = url.match(/[^\/]*$/)[0] || '';
             if (tip) {
-                tip = humanType + ": " + tip;
-                if (tip.length > 60) {
-                    tip = tip.substring(0, 29) + "..." + tip.slice(-28); 
-                }
+              tip = humanType + ": " + tip;
+              if (tip.length > 60) {
+                tip = tip.substring(0, 29) + "..." + tip.slice(-28);
+              }
             } else tip = humanType;
-            
-            
+
+
             var redirect;
             var host = (channel.originalURI || channel.URI).host;
             if (host) {
               host = host.replace(/\./g, '_');
-              while(host && (redirect = fg.getPref("media.redirect." + host, -1)) === -1) {
+              while (host && (redirect = fg.getPref("media.redirect." + host, -1)) === -1) {
                 host = host.replace(/.*?(?:_|$)/, '');
               }
             }
             if (redirect === -1) redirect = fg.getPref("media.redirect", 0); // 0 - no redirect, 1 redirect, 2 include both initial and final url
             if (redirect === 0) url = channel.originalURI && channel.originalURI.spec || url;
-            
+
             var size = contentLength < 0 ? "???KB"
-             : contentLength < 1024 ? (contentLength + "B")
-                 : contentLength < 1048576 ? (Math.round(contentLength  / 1024) + "KB")
-                   : (Math.round(contentLength / 1048576)) + "MB";
-            
+              : contentLength < 1024 ? (contentLength + "B")
+              : contentLength < 1048576 ? (Math.round(contentLength / 1024) + "KB")
+              : (Math.round(contentLength / 1048576)) + "MB";
+
             // Youtube channel hack
             var doc = win.document;
             var node = doc.getElementById("playnav-curvideo-title");
-            
-            var createStrings = function(title, o) {
+
+            var createStrings = function (title, o) {
               if (!title) {
-                title = doc._flashGotMediaTitle === doc.title ? '' : doc._flashGotMediaTitle = doc.title;
-                win.setTimeout(function() {
-                   if (doc._flashGotMediaTitle !== doc.title) {
+                title = doc._flashGotMediaTitle = doc.title;
+                win.setTimeout(function () {
+                  if (doc._flashGotMediaTitle !== doc.title) {
                     createStrings(doc._flashGotMediaTitle = doc.title, o);
                     MediaSniffer.updateUI(win);
                   }
                 }, 3000);
-              } 
-              
+              }
+
               var fname = typeInfo.fname || '';
-            
+
               title = title.replace(/^\s+|\s+$/, '');
               const unicode = fg.getPref("media.unicode") && /^UTF.?8$/i.test(win.document.characterSet);
               if (title) {
                 const nonWordRx = unicode ? /[\u0000-\u0020\u2000-\u206F\u2E00-\u2E7F]+|[^\w\u0080-\uffff]+/g : /\W+/g;
                 // remove site name from title
                 title = title.replace(new RegExp("\\b(?:" +
-                    (win.location.host || '').split(".").filter(function(s) { return s }).join("|")  + ")\\b", 'ig'), '')
-                    .replace(/https?:\/{2}/gi, '')
-                    .replace(nonWordRx, '_')
-                    .replace(/^_+([^_])/g, '$1')
-                    .replace(/([^_])_+$/g, '$1')
-                    .replace(/_+/g, '_');
-                
+                  (win.location.host || '').split(".").filter(function (s) {return s}).join("|") + ")\\b", 'ig'), '')
+                  .replace(/https?:\/{2}/gi, '')
+                  .replace(nonWordRx, '_')
+                  .replace(/^_+([^_])/g, '$1')
+                  .replace(/([^_])_+$/g, '$1')
+                  .replace(/_+/g, '_');
+
                 if (title.toLowerCase().indexOf(fname.replace(/\.\w+$/, '').replace(nonWordRx, '_').toLowerCase()) !== -1) {
                   fname = fname.replace(/.*(?=\.\w+$)/, '');
                 }
               }
-              
+
               if (title && fg.getPref("media.guessName", true)) {
-                  fname = (title + "_" + fname)
-                            .replace(unicode ? /[^\w\.\u0080-\uffff]+/g : /[^\w\.]+/g, '_')
-                            .replace(/_(?:get_video|videoplayback)\b/, '')
-                            .replace(/([^_]+)_+(?=\.\w+$)/, '$1');
+                fname = (title + "_" + fname)
+                  .replace(unicode ? /[^\w\.\u0080-\uffff]+/g : /[^\w\.]+/g, '_')
+                  .replace(/_(?:get_video|videoplayback)\b/, '')
+                  .replace(/([^_]+)_+(?=\.\w+$)/, '$1');
               }
               if (extras.quality && fname.indexOf(extras.quality) < 0) {
                 var dotPos = fname.lastIndexOf(".");
                 fname = fname.substring(0, dotPos) + "_" + extras.quality + fname.substring(dotPos);
               }
-              if (fname.length > 32) fname = this.limitFName(fname);
+              if (fname.length > 32) fname = MediaSniffer.limitFName(fname);
               url = o.originalURL || url;
               o.href = (fname && fg.getPref("media.forceNameHack", true) && url.indexOf("#") == -1) ? url + "#/" + encodeURIComponent(fname) : url;
               o.fname = fname;
@@ -297,63 +358,76 @@ var MediaSniffer = {
               o.description = title + " (" + size + " " + humanType + ")";
               o.tip = tip + " (" + size + ")";
               return o;
-            }.bind(this);
-            
+            };
+
             var title = extras.title || node && node.textContent;
-            
+
             var entry;
-            while(url) {
-              media.push (entry = map[url] = createStrings(title, {
+            while (url) {
+              media.push(entry = map[url] = createStrings(title, {
                 referrer: (channel instanceof CI.nsIHttpChannel) && channel.referrer && channel.referrer.spec,
                 contentType: contentType,
                 contentLength: contentLength,
-                postStream: channel instanceof CI.nsIUploadChannel &&
-                            channel.uploadStream instanceof CI.nsISeekableStream &&
-                            channel.uploadStream,
-                originalURL: url
+                originalURL: url,
+                parsed: extras["flashgot::parsed"],
+                seek_pos: extras["flashgot::seek_pos"],
+                sort_key: extras["flashgot::sort_key"],
+                Youtube: extras["flashgot::parsed"] ? Youtube : null,
+                yt_dash: extras["flashgot::yt_dash"]
               }));
-              
+              fg.interceptor.extractPostData(channel, entry); // adds entry.postData if needed
+              // YouTube fallback host.
+              if (extras["flashgot::parsed"] && extras.fallback_host && /(^|\.)youtube\.com$/.test(channel.URI.host)) {
+                var fb_url = url.replace(/^(.+?)\/\/(?:.+?)\//, "$1//" + extras.fallback_host + "/");
+                if (fb_url !== url) {
+                  entry.fallback_href = fb_url;
+                }
+              } // YouTube fallback host.
+              if (!extras["flashgot::parsed"]) { this._set_current_url(win, url); }
+
               if (cacheable && (channel instanceof CI.nsICachingChannel))
                 entry.cacheKey = channel.cacheKey;
 
               url = redirect === 2 && (!channel.originalURI || channel.originalURI.spec == url ? null : channel.originalURI.spec);
             }
             this.updateUI(win);
+          } else if (!extras["flashgot::parsed"]) {
+            this._set_current_url(win, url);
           }
 
-          if (this.debug) dump(win._flashgotMedia && win._flashgotMedia.toSource() + "\n");
         }
-      } catch(e) {
+      } catch (e) {
+        fg.log("MediaSniffer::observe: exception: [" + typeof(e) + "]: " + (e.message || e) + "\n" + (e.stack || new Error().stack));
         if (!this.debug) return;
-        
+
         var msg = topic + " " + e.toString() + "\n" + e.stack;
         if (channel) {
           msg += "\__> " + channel.name;
           try {
             msg += ", " + channel.contentType;
-          } catch(e1) {}
+          } catch (e1) {}
         }
         dump("*** ERROR ***\n" + msg + "\n\n");
       }
     }
   },
-  updateUI: function(win) {
+  updateUI: function (win) {
     var bw = DOM.mostRecentBrowserWindow;
     if (bw && bw.gFlashGot && bw.content == win.top) bw.gFlashGot.updateMediaUI();
   },
-  
+
   get _channelFlags() {
     delete this._channelFlags;
     const constRx = /^[A-Z_]+$/;
     const ff = {};
-    [CI.nsIHttpChannel, CI.nsICachingChannel].forEach(function(c) {
+    [CI.nsIHttpChannel, CI.nsICachingChannel].forEach(function (c) {
       for (var p in c) {
         if (constRx.test(p)) ff[p] = c[p];
       }
     });
     return this._channelFlags = ff;
   },
-  humanFlags: function(loadFlags) {
+  humanFlags: function (loadFlags) {
     var hf = [];
     var c = this._channelFlags;
     for (var p in c) {
@@ -361,8 +435,8 @@ var MediaSniffer = {
     }
     return hf.join("\n");
   },
-  
-  limitFName: function(fname) {
+
+  limitFName: function (fname) {
     const MAX_FILE_LEN = 128, MAX_EXT_LEN = 5;
     var dotPos = fname.lastIndexOf(".");
     if (dotPos >= MAX_FILE_LEN - MAX_EXT_LEN - 1) {
@@ -374,53 +448,74 @@ var MediaSniffer = {
     }
     return fname;
   },
-  normalizeQuery: function(url) {
+  normalizeQuery: function (url) {
     var parts = url.split("?");
     if (parts.length < 2) return url;
     var qs = parts[1].split("&");
     qs.sort();
     return parts[0] + "?" + qs.join("&");
   },
-  onStateChange: function(wp, channel, stateFlag, status) {
+  onStateChange: function (wp, channel, stateFlag, status) {
     // here we wait STATE_STOP of cached channels
-    if ((stateFlag & 16) && (channel instanceof CI.nsICachingChannel))
+    if (Components.isSuccessCode(status) && (stateFlag & 16) && (channel instanceof CI.nsICachingChannel))
       this.observe(channel, "http-cached-stop", null);
-  }
-  ,
-  onLocationChange: function(wp, req, location) {
-    this.checkYoutube(wp.DOMWindow);
-  }
-  ,
-  onLinkIconAvailable: function() {},
-  onStatusChange: function() {},
-  onSecurityChange: function() {}, 
-  onProgressChange: function() {},
-  
-  checkYoutube: function(w, url) {
+  },
+  onLocationChange: function (wp, req, location) {
+    wp.DOMWindow.setTimeout(function() { MediaSniffer.checkYoutube(this) }, 1000);
+  },
+  onLinkIconAvailable: function () {},
+  onStatusChange: function () {},
+  onSecurityChange: function () {},
+  onProgressChange: function () {},
+
+  checkYoutube: function(w, url, force) {
+    if (!gFlashGotService.getPref("media.YouTube.autodetect", true)) { return false; }
     var id = this.parseYoutubeId(url || w.location.href);
     if (!id) return false;
     
-    var yids = w._flashGotYoutubeIds || (w._flashGotYoutubeIds = []);
+    var yids = !force && w._flashGotYoutubeIds || (w._flashGotYoutubeIds = []);
     if (yids.indexOf(id) !== -1) return true;
     yids.push(id);
-    
-    Youtube.process(id, function(data) {
+
+    Youtube.process(w, id, function (data) {
       if (!data) return;
       var title = data.title;
-      data.streams.forEach(function(s) {
+      data.streams.forEach(function (s) {
         s.title = title;
-        s.type = s.type.split(";")[0];
+        s.type = s.type.split(";")[0] || "Media";
         s.window = w;
-        MediaSniffer.peek(s.url + "&signature=" + encodeURIComponent(s.sig), s);
+        s["flashgot::parsed"] = true;
+        MediaSniffer.peek(s.url, s);
       });
     }, fg.isPrivate(w));
     return true;
   },
-  parseYoutubeId: function(url) {
-    var m = url.match(/\b(?:youtube\.com\b|videoplayback).*(?:[?&](?:video_)?id=|[?&/]v[=\/])([^&]+)/);
-    return m && m[1] || null;
+  parseYoutubeId: function (url) {
+    var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+      .getService(Components.interfaces.nsIIOService);
+    var uri = ioService.newURI(url, null, null);
+    // Accessing uri.host throws for urls like "about:blank".
+    // Accessing uri.asciiHost doesn't throw.
+    if (!/^https?$/i.test(uri.scheme)) { return null; }
+    if (/(?:^|\.)youtube\.com$/.test(uri.asciiHost)) {
+      var s = uri.path.replace(/#.*$/, "").replace(/^\//, "");
+      // /watch?v=VIDEO_ID
+      if (/^watch\?/.test(s)) { return /[?&]v=([^&]+)/.test(s) ? RegExp.$1 : null; }
+      // /v/VIDEO_ID, /embed/VIDEO_ID
+      if (/^(?:v|embed)\/([^?]+)/.test(s)) { return RegExp.$1; }
+      // /get_video_info?video_id=VIDEO_ID, /get_video?video_id=VIDEO_ID
+      if (/^get_video(?:_info)?\?/.test(s)) { return /[?&]video_id=([^&]+)/.test(s) ? RegExp.$1 : null; }
+      // /api_video_info?video_id=VIDEO_ID
+      if (/^api_video_info\?/.test(s)) { return /[?&]video_id=([^&]+)/.test(s) ? RegExp.$1 : null; }
+      return null;
+    }
+    // https://youtube.googleapis.com/v/VIDEO_ID - youtube.com/v/VIDEO_ID redirects here.
+    if ("youtube.googleapis.com" === uri.asciiHost && /^\/v\/([^?#]+)/.test(uri.path)) {
+      return RegExp.$1;
+    }
+    return null;
   },
-  peek: function(url, extras, callback) {
+  peek: function (url, extras, callback) {
     try {
       var xhr = CC["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(CI.nsIXMLHttpRequest);
       xhr.open("HEAD", url);
@@ -431,9 +526,43 @@ var MediaSniffer = {
       if (extras.window && fg.isPrivate(extras.window)) {
         fg.privatize(ch);
       }
-      if (callback) xhr.addEventListener("readystatechange", function(ev) {
-        if (xhr.readyState !== 4) return;
-        callback(xhr);
+      // The channel |ch| will be lost (changed) in case of a redirect (3xx),
+      // so we must listen for redirects in order to preserve our |extras|.
+      ch.notificationCallbacks = {
+        // nsIInterfaceRequestor methods.
+        getInterface: function (uuid) {
+          if (uuid.equals(CI.nsIInterfaceRequestor) || uuid.equals(CI.nsIChannelEventSink)) {
+            return this;
+          }
+          throw Components.results.NS_ERROR_NO_INTERFACE;
+        },
+
+        // nsIChannelEventSink methods.
+        asyncOnChannelRedirect: function (oldChannel, newChannel, flags, callback) {
+          newChannel.notificationCallbacks = this;
+          try {
+            newChannel.QueryInterface(Components.interfaces.nsIWritablePropertyBag)
+              .setProperty("flashgot.media.extras", extras);
+          } catch (x) {
+            fg.log("MediaSniffer::peek: " + (extras["flashgot::video_id"] ? "video " + extras["flashgot::video_id"] + ": " : "") + "failed to preserve extras: " + (x.message || x) + "\n" + x.stack);
+          }
+          if (callback != null && "onRedirectVerifyCallback" in callback) {
+            callback.onRedirectVerifyCallback(Components.results.NS_OK);
+          }
+        },
+
+        // Deprecated.
+        onChannelRedirect: function (oldChannel, newChannel, flags) {
+          this.asyncOnChannelRedirect(oldChannel, newChannel, flags, null);
+        }
+      }; // ch.notificationCallbacks
+      xhr.addEventListener("readystatechange", function (ev) {
+        if (xhr.readyState < 2) return;
+        try {
+          if (callback) callback(xhr);
+        } finally {
+          xhr.abort();
+        }
       }, false);
       xhr.send(null);
       return true;
@@ -442,4 +571,4 @@ var MediaSniffer = {
     }
     return false;
   }
-};
\ No newline at end of file
+};
diff --git a/chrome/flashgot.jar!/content/flashgot/Youtube.js b/chrome/flashgot.jar!/content/flashgot/Youtube.js
index 0e49b5b..6b77782 100644
--- a/chrome/flashgot.jar!/content/flashgot/Youtube.js
+++ b/chrome/flashgot.jar!/content/flashgot/Youtube.js
@@ -19,37 +19,867 @@
                              
 ***** END LICENSE BLOCK *****/
 
+var Youtube = function(){
+
+///////////////////////////////////////////////////////////////////////////////
+// Public part.
 var Youtube = {
 
-  process: function(id, callback, isPrivate) {
-    var xhr =  CC["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(CI.nsIXMLHttpRequest);
-    xhr.open("GET", "http://www.youtube.com/get_video_info?hl=en_US&el=detailpage&video_id=" + id);
+  process: function (w, id, callback, isPrivate) {
+    // First try to extract the stream data from the document:
+    // either from ytplayer.config.args.url_encoded_fmt_stream_map
+    // or from the player's flashvars.
+    // If that fails, retry with /get_video_info.
+    // XXX: The problem with using /get_video_info is that it allows
+    // you to bypass the "This video is age-restricted" warning. But
+    // I guess it's their problem that their script doesn't check what
+    // it should check. Or did they leave that backdoor on purpose?
+    // Or it's not a backdoor and the response contains some kind of
+    // an "age-restricted" flag that the client must check?
+    // You also can bypass it with /v/VIDEO_ID and /embed/VIDEO_ID.
+    w["flashgot::Youtube::process::call_cnt"] = (w["flashgot::Youtube::process::call_cnt"] || 0) + 1;
+    if (w["flashgot::Youtube::process::tid"]) {
+      w.clearTimeout(w["flashgot::Youtube::process::tid"]);
+      delete w["flashgot::Youtube::process::tid"];
+    }
+
+    function wait_for_player() {
+      delete w["flashgot::Youtube::process::tid"];
+
+      var now = Date.now();
+      if (!arguments.callee["flashgot::start_time"]) {
+        arguments.callee["flashgot::start_time"] = now;
+      }
+      if (now - arguments.callee["flashgot::start_time"] > 5000) {
+        Youtube.do_xhr(w, id, callback, isPrivate);
+        return;
+      }
+      var data;
+      var o;
+      // ytplayer.config.args
+      if (!data && (o = w.wrappedJSObject) && (o = o.ytplayer) && (o = o.config) && (o = o.args) && o.url_encoded_fmt_stream_map) {
+        data = o;
+      }
+      // <embed/> flashvars
+      if (!data && (o = w.document)) {
+        var ids = gFlashGotService.getPref("media.YouTube.flashvars_element_id", "movie_player").split(/\s+/).map(unescape);
+        var attrs = gFlashGotService.getPref("media.YouTube.flashvars_element_attr", "flashvars").split(/\s+/).map(unescape);
+        for (var i = 0, len = ids.length; !data && i !== len; ++i) {
+          let id = ids[i];
+          if (id.length === 0) { continue; }
+          var elm = o.getElementById(id);
+          if (elm === null) { continue; }
+          for (var j = 0, jlen = attrs.length; j !== jlen; ++j) {
+            var attr = attrs[j];
+            if (attr.length !== 0 && (attr = elm.getAttribute(attr))) {
+              data = Youtube.parse(attr);
+              break;
+            }
+          }
+        }
+      }
+      if (!data) {
+        // The document is loaded, but still no data - no point in waiting further
+        // (e.g. /embed/VIDEO_ID documents don't have the data we're looking for).
+        if (w.document && w.document.readyState && (w.document.readyState === "interactive" || w.document.readyState === "complete")) {
+          Youtube.do_xhr(w, id, callback, isPrivate);
+        }
+        else {
+          w["flashgot::Youtube::process::tid"] = w.setTimeout(arguments.callee, 200);
+        }
+        return;
+      }
+      if (Youtube.process_video_info(data, callback)) {
+        delete w["flashgot::Youtube::process::call_cnt"];
+        return;
+      }
+      Youtube.do_xhr(w, id, callback, isPrivate);
+    } // wait_for_player()
+    w["flashgot::Youtube::process::tid"] = w.setTimeout(wait_for_player, 0);
+  },
+
+  do_xhr: function (w, id, callback, isPrivate) {
+    var call_cnt = w["flashgot::Youtube::process::call_cnt"];
+
+    var xhr = CC["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(CI.nsIXMLHttpRequest);
+    xhr.open("GET", w.location.protocol + "//www.youtube.com/get_video_info?hl=en_US&el=detailpage&video_id="
+      + id + "&sts=" + fg.getPref("media.YouTube.decode_signature_func.timestamp", -1));
     if (isPrivate) {
       fg.privatize(xhr.channel);
     }
-    xhr.addEventListener("readystatechange", function(ev) {
+    xhr.addEventListener("readystatechange", function (ev) {
+      if (w["flashgot::Youtube::process::call_cnt"] !== call_cnt) {
+        this.abort();
+        return;
+      };
       if (xhr.readyState !== 4) return;
-      var data = Youtube.parse(xhr.responseText || "");
-      callback (
-        ("url_encoded_fmt_stream_map" in data)
-        ? { title: data.title, 
-            streams: data.url_encoded_fmt_stream_map.split(",").map(Youtube.parse, this) 
-          }
-        : null
-      );
+      delete w["flashgot::Youtube::process::call_cnt"];
+      Youtube.process_video_info(Youtube.parse(xhr.responseText || ""), callback);
     }, false);
     xhr.send(null);
   },
-  parse: function(s) {
+
+  parse: function (s) {
     var pairs = s.split("&");
     var res = {};
     var nv;
-    for each (var p in pairs) {
+    for each(var p in pairs) {
       try {
         nv = p.split("=").map(function(v) { return decodeURIComponent(v.replace(/\+/g, ' ')) });
         if (!(nv[0] in res)) res[nv[0]] = nv[1];
       } catch (e) {}
     }
     return res;
+  },
+
+  process_video_info: function (data, callback) {
+    if (!data || !data.url_encoded_fmt_stream_map) { return false; }
+    var streams = data.url_encoded_fmt_stream_map.split(",").map(Youtube.parse);
+    // 2013-10: 1080p is not in the map anymore (and some other formats as well).
+    this.get_missing_streams(data, streams);
+    if (!streams.length) { return false; }
+
+    // Preprocess the streams:
+    // 1) Mark 3D videos. MediaSniffer uses .quality ("small" (240p), "medium" (360p),
+    // "hd720", etc.) and .type ("video/flv", "video/mp4", etc.) for formatting menu
+    // item labels and tooltips.
+    // 2) Decode the stream signatures.
+    // 3) Build the sort keys. Don't sort right here,
+    // because the responses can arrive in any order.
+    var data_title = String(data.title);
+    var signature_decoder;
+    try {
+      signature_decoder = this.create_signature_decoder();
+    } catch (x) {
+      fg.log("Error compiling YouTube.decode_signature_func: " + (x.message || x) + "\n" + x.stack);
+      return false;
+    }
+    var remap_quality = fg.getPref("media.YouTube.remap_stream_quality", false);
+    var remap_type = fg.getPref("media.YouTube.remap_stream_type", false);
+    var quality_sort_order = remap_quality ? Youtube.REMAP_QUALITY_SORT_ORDER : Youtube.QUALITY_SORT_ORDER;
+    var type_sort_order = remap_type ? Youtube.REMAP_TYPE_SORT_ORDER : Youtube.TYPE_SORT_ORDER;
+    streams = streams.filter(function(s) {
+      // We're only interested in HTTP streams, no RTMP or something.
+      if (!/^https?:\/\//.test(s.url)) { return false; }
+
+      // Save the video ID, for debugging purposes.
+      s["flashgot::video_id"] = data.video_id;
+
+      // Tidy the type: "video/3gpp;+codecs="mp4v.20.3,+mp4a.40.2" -> "video/3gpp".
+      s.type = s.type.split(";")[0];
+      if (remap_type) { s.type = Youtube.remap_stream_type(s); }
+
+      if (remap_quality) { s.quality = Youtube.remap_stream_quality(s); }
+      // Mark 3D videos.
+      // http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs
+      if ((s.itag >= 82 && s.itag <= 85) || (s.itag >= 100 && s.itag <= 102)) {
+        s.quality += " (3D)";
+      }
+
+      // Build the sort key: order by quality, type.
+      s["flashgot::sort_key"] = (Youtube.get_sort_idx(quality_sort_order, s.quality) << 8)
+        | Youtube.get_sort_idx(type_sort_order, s.type);
+      // For DASH streams: audio goes after video.
+      // So it's actually order by media type (audio or video), quality, container type.
+      if (s["flashgot::yt_dash"] === "audio") {
+        s["flashgot::sort_key"] |= 0x10000;
+      }
+
+      // Decode the signature.
+      try {
+        var sig = signature_decoder.decode( {stream: s, video_info: data, swap: Youtube.decode_signature_swap} );
+        if (sig) { s.url += "&signature=" + encodeURIComponent(sig); }
+      } catch (x) {
+        fg.log("Error calling YouTube.decode_signature_func: " + (x.message || x) + "\n" + x.stack);
+        return false;
+      }
+
+      // Tidy the URL.
+      if (fg.getPref("media.YouTube.stream_url.tidy", false)) {
+        var extra_keep_params = fg.getPref("media.YouTube.stream_url.extra_keep_params", "")
+          .split(/\s+/)
+          // URL-decode.
+          .map(unescape)
+          // Ignore empty items.
+          .filter(function(o){return o.length !== 0;});
+        Youtube.tidy_stream_url(s, extra_keep_params);
+      }
+
+      // Add "ratebypass" (speed limit) and "cmbypass" (no idea)
+      // if they're not part of the signature.
+      var idx = s.url.indexOf("?");
+      if (idx !== -1 && idx + 1 !== s.url.length) {
+        var qs = Youtube.parse(s.url.substr(idx + 1));
+        var sparams = (qs.sparams || "").split(",");
+        if (sparams.indexOf("ratebypass") === -1) { qs.ratebypass = "yes"; }
+        if (sparams.indexOf("cmbypass") === -1) { qs.cmbypass = "yes"; }
+        s.url = s.url.substr(0, idx + 1)
+          + Object.keys(qs)
+            .map(function(p){return encodeURIComponent(p) + "=" + encodeURIComponent(qs[p] || "")})
+            .join("&");
+      }
+
+      return true;
+    });
+    signature_decoder.dispose();
+    if (!streams.length) { return false; }
+    callback( {title: data_title, streams: streams} );
+    return true;
+  }, // process_video_info()
+
+  get_missing_streams: function(data, streams)
+  {
+    if (data.adaptive_fmts) {
+      data.adaptive_fmts.split(",").map(Youtube.parse).forEach(function(o){
+        var b = o.itag && o.type && o.url
+          && (o.quality = Youtube._map_itag(Youtube.STREAM_QUALITY_MAP, o.itag, o.size || /*audio*/(Math.round(o.bitrate / 1024) + "k")));
+        if (b) {
+          o["flashgot::yt_dash"] = o.size ? "video" : "audio";
+          streams.push(o);
+        }
+      });
+    }
+
+    // 2013-11: Doesn't work anymore - they added "itag" to the signature.
+    if ( ! /(^|\.)youtube\.com\/api\/manifest\/dash\/(.+)/.test(data.dashmpd)) { return; }
+    var a = RegExp.$2.split("/");
+    if (a.length % 2) { a.push(""); }
+    var dmp = {key: "yt1"};
+    for (var i = 0, len = a.length; i !== len; i += 2) {
+      dmp[decodeURIComponent(a[i])] = decodeURIComponent(a[i + 1]);
+    }
+    if ( ! dmp.signature || ! dmp.sparams) { return; }
+    var dmp_keep_params = dmp.sparams.split(",").concat("sparams", "key");
+    if (dmp_keep_params.indexOf("itag") !== -1) { return; }
+    var stream_base = null;
+    streams.some(function(s){
+      if ( ! /^(https?:\/\/[^\/]+)\//.test(s.url)) { return false; }
+      var host = RegExp.$1;
+      if ( ! /[?&]id=([^&]+)/.test(s.url) || RegExp.$1 !== dmp.id) { return false; }
+      stream_base = {
+        fallback_host: s.fallback_host,
+        sig: dmp.signature,
+        url: host + "/videoplayback?"
+          + dmp_keep_params.map(function(p) { return encodeURIComponent(p) + "=" + encodeURIComponent(dmp[p]) }).join("&")
+      };
+      return true;
+    });
+    if ( ! stream_base) { return; }
+    // http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs
+    // Map<int itag, Object info> itag_map;
+    var itag_map = {
+      83 /* 240p mp4 */: {quality: "small", type: "video/mp4"},
+      34 /* 360p flv */: {quality: "medium", type: "video/x-flv"},
+      100 /* 360p 3D webm */: {quality: "medium", type: "video/webm"},
+      101 /* 360p 3D webm */: {quality: "medium", type: "video/webm"},
+      35 /* 480p flv */: {quality: "large", type: "video/x-flv"},
+      44 /* 480p webm */: {quality: "large", type: "video/webm"},
+      85 /* 520p mp4 */: {quality: "520p", type: "video/mp4"},
+      45 /* 720p webm */: {quality: "hd720", type: "video/webm"},
+      102 /* 720p 3D webm */: {quality: "hd720", type: "video/webm"},
+      37 /* 1080p mp4 */: {quality: "hd1080", type: "video/mp4"},
+      46 /* 1080p webm */: {quality: "hd1080", type: "video/webm"},
+      38 /* 3072p mp4 aka "highres" aka "original" */: {quality: "highres", type: "video/mp4"}
+    };
+    // itags = select itag from itag_map where itag not in (select itag from streams);
+    var itags = Object.keys(itag_map).filter(function(k) { return streams.every(function(s) { return k != s.itag }) });
+    itags.forEach(function(k){
+      var itag = itag_map[k];
+      var stream = {
+        itag: k,
+        quality: itag.quality,
+        type: itag.type,
+        sig: stream_base.sig,
+        fallback_host: stream_base.fallback_host,
+        url: stream_base.url + "&itag=" + k
+      };
+      streams.push(stream);
+    });
+  },
+
+  QUALITY_SORT_ORDER: ["highres" /*"original"*/, "hd1080", "hd1080 (3D)", "hd720", "hd720 (3D)", "large", "large (3D)", "medium", "medium (3D)", "small", "light", "tiny"],
+  REMAP_QUALITY_SORT_ORDER: [
+    "Original" /*highres*/, "1080p", "1080p (3D)", "720p", "720p (3D)", "520p", "480p", "480p (3D)", "360p", "360p (3D)", "270p", "240p", "144p",
+    /*audio*/ "256k", "128k", "48k"
+  ],
+  TYPE_SORT_ORDER: ["video/mp4", "video/x-flv", "video/webm", "video/3gpp", "audio/mp4"],
+  REMAP_TYPE_SORT_ORDER: ["mp4", "flv", "webm", "3gp", "audio/mp4"],
+  get_sort_idx: function (arr, value) {
+    // Unknown values go to the very end of the list.
+    return arr.indexOf(value) & 0xff;
+  },
+
+  // http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs
+  // Map<String name, Array<int> itags> STREAM_REMAP_QUALITY_MAP;
+  STREAM_REMAP_QUALITY_MAP: {"144p": [17, 160], "240p": [5, 36, 83, 133], "270p": [6], "360p": [18, 34, 43, 82, 100, 101, 134],
+    "480p": [35, 44, 135], "520p": [85], "720p": [22, 45, 84, 102, 120, 136], "1080p": [37, 46, 137], "Original": [38, 138],
+    /*audio*/ "48k": [139], "128k": [140, 171], "256k": [141, 172]
+  },
+  // Map<String name, Array<int> itags> STREAM_REMAP_TYPE_MAP;
+  STREAM_REMAP_TYPE_MAP: {"mp4": [18, 22, 37, 38, 82, 83, 84, 85, 133, 134, 135, 136, 137, 138, 160],
+    "flv": [5, 6, 34, 35, 120], "webm": [43, 44, 45, 46, 100, 101, 102], "3gp": [13, 17, 36],
+    "audio/mp4": [139, 140, 141], "audio/webm": [171, 172]
+  },
+  // Map<String name, Array<int> itags> STREAM_QUALITY_MAP;
+  STREAM_QUALITY_MAP: {"small": [5, 6, 17, 36, 83, 133, 139, 160], "medium": [18, 34, 43, 82, 100, 101, 134, 140, 171],
+    "large": [35, 44, 85, 135, 141, 172], "hd720": [22, 45, 84, 102, 120, 136], "hd1080": [37, 46, 137], "highres": [38, 138]
+  },
+  // Map<String name, Array<int> itags> STREAM_TYPE_MAP;
+  STREAM_TYPE_MAP: {"video/mp4": [18, 22, 37, 38, 82, 83, 84, 85, 133, 134, 135, 136, 137, 138, 160],
+    "video/x-flv": [5, 6, 34, 35, 120], "video/webm": [43, 44, 45, 46, 100, 101, 102], "video/3gpp": [13, 17, 36],
+    "audio/mp4": [139 /*48k*/, 140 /*125k*/, 141 /*250k*/], "audio/webm": [171 /*138k*/, 172 /*209k*/]
+  },
+  remap_stream_quality: function(stream) {
+    return this._map_itag(this.STREAM_REMAP_QUALITY_MAP, stream.itag, stream.quality);
+  },
+  remap_stream_type: function(stream) {
+    return this._map_itag(this.STREAM_REMAP_TYPE_MAP, stream.itag, stream.type);
+  },
+  _map_itag: function(map, itag, defaultValue) {
+    itag = Number(itag);
+    for (var p in map) {
+      if (map[p].indexOf(itag) !== -1) {
+        return p;
+      }
+    }
+    return defaultValue;
+  },
+  get_stream_content_type: function(url) {
+    if ( ! this.is_stream_url(url) || ! /[?&]itag=([^&]+)/.test(url)) { return null; }
+    return this._map_itag(this.STREAM_TYPE_MAP, RegExp.$1, null);
+  },
+
+  // Removes junk parameters (like "fexp") from the stream URL.
+  // We keep the following parameters:
+  // 1) those listed in the "sparams" parameter
+  // 2) "sparams"
+  // 3) "signature"
+  // 4) "key"
+  // 5) "id" (internal? (as in private/non-public) video ID)
+  // 6) "itag" (stream "ID" - container type and video quality)
+  // 7) those passed in the |extra_keep_params| argument.
+  // 8) anything that ends with "bypass" and has the value of "yes".
+  tidy_stream_url: function (stream, extra_keep_params /*= null*/ ) {
+    if (!extra_keep_params) { extra_keep_params = []; }
+    var url = stream.url;
+    if (!url) { return; }
+    var qs_idx = url.indexOf("?");
+    if (qs_idx === -1 || qs_idx + 1 === url.length) { return; }
+    var qs = Youtube.parse(url.substr(qs_idx + 1));
+    var sparams = qs["sparams"];
+    if (!sparams) { return; }
+    sparams = sparams.split(",");
+    extra_keep_params.push("sparams", "signature", "key", "id", "itag");
+    extra_keep_params.forEach(function(p){if (sparams.indexOf(p) === -1) sparams.push(p);});
+    var new_qs = [];
+    for (var p in qs) {
+      if (sparams.indexOf(p) !== -1 || (/.+bypass$/.test(p) && qs[p] === "yes")) {
+        new_qs.push(encodeURIComponent(p) + "=" + encodeURIComponent(qs[p] || ""));
+      }
+    }
+    stream.url = url.substr(0, qs_idx + 1) + new_qs.join("&");
+  }, // tidy_stream_url()
+
+  // For YouTube, we can't rely on simple URL comparison because
+  // the query strings of our parsed streams and the ones built by
+  // the player can (and most likely, will) differ.
+  stream_url_equals: function (url1, url2) {
+    if (!this.is_stream_url(url1) || !this.is_stream_url(url2)) { return false; }
+
+    // The |id| parameter is something like the internal video ID:
+    // it's different for two different videos (those with different
+    // "public" video IDs - /watch?v=VIDEO_ID), and it's the same for
+    // all the streams of the same video.
+    var id1 = /[?&]id=([^&]+)/.test(url1) ? RegExp.$1 : "flashgot-id-1";
+    var id2 = /[?&]id=([^&]+)/.test(url2) ? RegExp.$1 : "flashgot-id-2";
+    if (id1 !== id2) { return false; }
+
+    // The only thing that allows us to identify a stream is the |itag|
+    // parameter, which is a combination of the container type (MP4,
+    // FLV, etc.) and the quality (1080p, 1080p 3D, 720p, etc.).
+    var itag1 = /[?&]itag=([^&]+)/.test(url1) ? RegExp.$1 : "flashgot-itag-1";
+    var itag2 = /[?&]itag=([^&]+)/.test(url2) ? RegExp.$1 : "flashgot-itag-2";
+    if (itag1 !== itag2) { return false; }
+
+    // Different seek positions are considered different streams (in case
+    // the user wants to save the stream from a particular position).
+    var begin1 = /[?&]begin=([^&]+)/.test(url1) ? RegExp.$1 : "0";
+    var begin2 = /[?&]begin=([^&]+)/.test(url2) ? RegExp.$1 : "0";
+    return begin1 === begin2;
+  },
+
+  is_stream_url: function (url) {
+    return /^[a-z]+:\/\/([^\/]+)\/videoplayback\?/.test(url) && /\.(?:youtube|googlevideo)\.com$/.test(RegExp.$1);
+  },
+
+  decode_signature: function (params) {
+    /* Not encoded. */
+    return params.stream.sig || "";
+  },
+  decode_signature_swap: function (a, idx) {
+    var tmp = a[0];
+    a[0] = a[idx % a.length];
+    a[idx] = tmp;
+    return a;
+  },
+
+  create_signature_decoder: function () {
+    var s = fg.getPref("media.YouTube.decode_signature_func", "");
+    if (!s) {
+      return new SignatureDecoder(Youtube.decode_signature);
+    }
+    // Fail fast: try to compile right now to check the code for
+    // syntax errors, so that we don't do all that heavy stuff for
+    // sandbox initialization only to fail later in evalInSandbox()
+    // and have an incorrect error message saying "error _calling_
+    // the function" while actually we failed to compile it.
+    var func = new Function("params", s);
+    if (fg.getPref("media.YouTube.decode_signature_func.sandbox", true)) {
+      // Wrap the code into a function invocation because we promised
+      // to call it as a function with one parameter.
+      s = "(function(params){\n" + s + "\n})(params);";
+      return new SandboxedSignatureDecoder(s);
+    }
+    return new SignatureDecoder(func);
+  },
+
+
+  refresh_signature_func: function (w, callback /*= null*/, force /*= false*/) {
+    return SDASniffer.sniff(w, callback, force);
+  }
+}; // Youtube
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Private part.
+
+// interface ISignatureDecoder {
+//   string decode(Params params);
+//   void dispose();
+// }
+// class Params {
+//   Map<string, string> stream;
+//   Map<string, string> video_info;
+//   Function swap; //Array swap(Array, int);
+// }
+//
+// class SignatureDecoder implements ISignatureDecoder {
+//   SignatureDecoder(Function func);
+// }
+function SignatureDecoder(func) {
+  this.func = func;
+}
+
+SignatureDecoder.prototype = {
+  decode: function(params) { return this.func(params); },
+  dispose: function() { this.func = null; }
+};
+
+
+
+// class SandboxedSignatureDecoder implements ISignatureDecoder {
+//   SandboxedSignatureDecoder(String code_str);
+// }
+function SandboxedSignatureDecoder(code_str) {
+  this.code_str = code_str;
+
+  this.sandbox = new Components.utils.Sandbox(this.SANDBOX_PRINCIPAL, this.SANDBOX_OPTIONS);
+
+  // If you simply assign objects to the sandbox properties, they will
+  // be visible, but their properties won't.
+  // Primitive values and functions can be assigned as-is. (Although
+  // converting a function to string will return the "standard" string
+  // "function() { [native code] }" because none of its properties,
+  // including the toString method, will be visible.)
+  //   var obj = {stream: s, video_info: data, swap: ... };
+  //   sandbox.obj = obj;
+  //   sandbox.str = "hi";
+  //   sandbox.num = 42;
+  //   sandbox.fun = function(){};
+  //   // Somewhere in decode_signature_func's global scope,
+  //   // i.e. |this| points to |sandbox|:
+  //   this.obj; // defined.
+  //   this.obj.stream; // undefined.
+  //   this.str; // defined.
+  //   this.num; // defined.
+  //   this.fun; // defined.
+  this.sb_params = this.export_to_sandbox({
+    stream: null,
+    video_info: null,
+    swap: Youtube.decode_signature_swap
+  });
+  this.sandbox.params = this.sb_params;
+
+} // SandboxedSignatureDecoder()
+
+
+SandboxedSignatureDecoder.prototype = {
+  // https://developer.mozilla.org/en-US/docs/Security_check_basics:
+  // The null principal (whose contract ID is @mozilla.org/nullprincipal;1)
+  // fails almost all security checks. It has no privileges and can't be
+  // accessed by anything but itself and chrome. They aren't same-origin
+  // with anything but themselves.
+  SANDBOX_PRINCIPAL: Components.classes["@mozilla.org/nullprincipal;1"]
+    .createInstance(Components.interfaces.nsIPrincipal),
+
+  SANDBOX_OPTIONS: {wantComponents: false, wantXHRConstructor: false},
+
+
+  // Makes all the own properties of an object available for reading
+  // in a sandbox.
+  // Not recursive, i.e. doesn't go in depth, i.e. if a property
+  // is an object as well, then its properties won't be processed.
+  // Exposing actual objects and not their copies is safe because
+  // the sandboxed code can't define getters/setters for their
+  // properties because we expose them as read-only, nor can it
+  // assign a watcher for a property because calling watch()
+  // on the exposed objects throws "can't watch non-native
+  // objects of class Proxy".
+  //
+  // [quote src="https://developer.mozilla.org/en/docs/XPConnect_wrappers#XPCChromeObjectWrapper"]
+  // XPCChromeObjectWrapper. A chrome object wrapper, or COW, is automatically
+  // created when a chrome object is exposed to content. If the chrome object
+  // has an __exposedProps__ property, then content may only access the whitelisted
+  // properties. This allows chrome to expose limited parts of objects to content
+  // without having to use IDL.
+  // The __exposedProps__ property is an object with a property corresponding
+  // to each of the chrome object's properties which should be exposed. The value
+  // of the properties within __exposedProps__ is either "w", "wr", or "r". These
+  // will allow content to read and/or write the property (executing a function
+  // is considered reading). Remember that functions defined in chrome context
+  // execute with chrome privileges.
+  // Gecko 15.0 note (Firefox 15.0 / Thunderbird 15.0 / SeaMonkey 2.12):
+  //   Starting in Gecko 15.0 (Firefox 15.0 / Thunderbird 15.0 / SeaMonkey 2.12),
+  //   exposing functions or objects without using __exposedProps__ is deprecated.
+  //   Using __exposedProps__ will be mandatory starting with Gecko 17.0 (Firefox 17.0
+  //   / Thunderbird 17.0 / SeaMonkey 2.14 / Firefox OS 1.0).
+  // [/quote]
+  export_to_sandbox: function (obj) {
+    var props = {"toString": "r", "valueOf": "r"};
+    for (var p in obj) {
+      if (p !== "__exposedProps__" && obj.hasOwnProperty(p)) {
+        props[p] = "r";
+      }
+    }
+    obj.__exposedProps__ = props;
+    return obj;
+  }, // export_to_sandbox()
+
+
+  decode: function (params) {
+    this.sb_params.stream = this.export_to_sandbox(params.stream);
+
+    // First call - export the video_info.
+    if (!this.sb_params.video_info) {
+      this.sb_params.video_info = this.export_to_sandbox(params.video_info);
+    }
+
+    var rc = Components.utils.evalInSandbox(this.code_str, this.sandbox);
+    delete params.stream.__exposedProps__;
+    // No fancy return values - we expect a primitive string value.
+    // We don't silently return something that could pass for a signature.
+    // Instead, we throw - to inform the user that their decode_signature_func
+    // function is broken (anyone can make a typo) or malicious.
+    //
+    // It's OK to pass uncaught exceptions as-is because even if they have
+    // getters for properties like "message", those will be executed in the
+    // context of the sandbox (i.e. the global |this| will point to the sandbox),
+    // which is useless for malicious code anyway.
+    // Here's what am I talking about - somewhere in the sandboxed code:
+    //   var x = new Error();
+    //   x.__defineGetter__("message", function(){alert("pwned");});
+    //   throw x;
+    //   or:
+    //   var x = { message: { valueOf: function(){alert("pwned");}, toString: function(){alert("pwned");} } };
+    //   throw x;
+    // We could catch the exceptions here, manually sanitize them and rethrow
+    // if they're safe to use in our chrome code, but I just don't see the point
+    // in doing so because if there's a bug in the security manager, then our
+    // manual sanitization will just conceal it.
+    if (typeof (rc) === "string") { return rc; }
+    // Nulls are kinda OK.
+    if (rc === null) { return ""; }
+    // A forgotten return or outdated code that returns nonexistent stream
+    // properties? Worth a warning in either case.
+    if (rc === undefined) {
+      fg.log("WARNING: YouTube.decode_signature_func returned undefined.");
+      return "";
+    }
+    throw new Error("Invalid return value type: expected string, got " + typeof (rc));
+  }, // decode()
+
+  dispose: function () {
+    if (!this.sandbox) { return; }
+    this.sandbox.params = this.sb_params = null;
+    Components.utils.nukeSandbox(this.sandbox);
+    this.sandbox = null;
   }
-};
\ No newline at end of file
+}; // SandboxedSignatureDecoder.prototype
+
+
+
+// Signature decoding algorithm (SDA) sniffer.
+var SDASniffer = {
+  // We don't want "over 9000" workers doing the same thing when one
+  // is enough (can happen if we're restoring a session with several
+  // YouTube tabs/windows).
+  // static boolean working = false;
+  // static Array<Function> callbacks = [];
+  working: false,
+  callbacks: [],
+
+  sniff: function (w, callback /*= null*/, force /*= false*/) {
+    if (typeof(callback) !== "function") { callback = null; }
+
+    if (this.working) {
+      if (callback) { this.callbacks.push(callback); }
+      return true;
+    }
+
+    // Get the SWF player URL.
+    w = w.wrappedJSObject;
+    var swf_url;
+    var o;
+    // ytplayer.config.url
+    if (w && (o = w.ytplayer) && (o = o.config)) {
+      swf_url = o.url;
+    }
+    // yt.config_["PLAYER_CONFIG"].url
+    else if (w && (o = w.yt) && (o = o.config_) && (o = o.PLAYER_CONFIG)) {
+      swf_url = o.url;
+    }
+    if (!swf_url) { return false; }
+    fg.log("SWF URL: " + swf_url);
+
+    // Automatic update frequency is limited so that we waste less traffic
+    // and CPU cycles in case YoutubeSwf code is outdated.
+    if ( ! force) {
+      var now = Math.floor(Date.now() / 1000);
+      var min_int = fg.getPref("media.YouTube.decode_signature_func.auto.min_interval", 60);
+      var last_update = fg.getPref("media.YouTube.decode_signature_func.auto.last_update_time", 0);
+      if (min_int !== 0 && now - last_update < min_int) {
+        if ( ! fg.getPref("media.YouTube.decode_signature_func.auto.last_update_ok")) {
+          return false;
+        }
+        // We promised to be async, so we can't call back _before_ we return,
+        // hence setTimeout.
+        w.setTimeout(function(){
+          try {
+            callback();
+          } catch (x) {
+            fg.log("Callback error: " + (x.message || x) + "\n" + x.stack);
+          }
+        }, 1);
+        return true;
+      }
+      fg.setPref("media.YouTube.decode_signature_func.auto.last_update_time", now);
+    }
+
+    var st, ft;
+    var stream_ctx = {
+      file: swf_url, //.split("/").pop().replace(/\?.*$/, "").replace(/#.*$/, ""),
+      bytes: "",
+      contentLength: -1,
+      bstream: null
+    };
+    var stream_listener = {
+      onDataAvailable: function (req, ctx, stream, offset, count) {
+        stream_ctx.bstream.setInputStream(stream);
+        stream_ctx.bytes += stream_ctx.bstream.readBytes(count);
+      },
+      onStartRequest: function (req /*, ctx*/) {
+        var channel = req.QueryInterface(Components.interfaces.nsIChannel);
+        if (!((channel instanceof Components.interfaces.nsIHttpChannel)
+          && Components.isSuccessCode(channel.status)
+          && channel.responseStatus === 200))
+        {
+          throw new Error("cancel"); //req.cancel(NS_BINDING_ABORTED);
+        }
+        stream_ctx.contentLength = channel.contentLength || -1;
+        fg.log("SWF content length: " + stream_ctx.contentLength);
+        stream_ctx.bstream = Components.classes["@mozilla.org/binaryinputstream;1"]
+          .createInstance(Components.interfaces.nsIBinaryInputStream);
+        st = Date.now();
+      },
+      onStopRequest: function (req, ctx, status) {
+        ft = Date.now();
+        stream_ctx.bstream = null;
+        // SDASniffer::sniff0 is async, so we can't simply do if (SDASniffer.working) {clean up}.
+        var cleanup = true;
+        if (Components.isSuccessCode(status)) {
+          fg.log("SWF downloaded in " + (ft - st) + " ms, size: " + stream_ctx.bytes.length);
+          if (stream_ctx.contentLength === -1 || stream_ctx.bytes.length === stream_ctx.contentLength) {
+            SDASniffer.sniff0(stream_ctx, callback);
+            cleanup = false;
+          }
+          else {
+            fg.log("SWF content length mismatch: expected " + stream_ctx.contentLength + ", got " + stream_ctx.bytes.length);
+          }
+        }
+        else {
+          fg.log("Failed to download the SWF: status=" + status);
+        }
+        stream_ctx = null;
+        if (cleanup) {
+          SDASniffer.working = false;
+          SDASniffer.callbacks = [];
+        }
+      }
+    }; // stream_listener
+    Components.classes["@mozilla.org/network/io-service;1"]
+      .getService(Components.interfaces.nsIIOService)
+      .newChannel(swf_url, null, null)
+      .asyncOpen(stream_listener, null);
+
+    this.working = true;
+    if (callback) { this.callbacks.push(callback); }
+    fg.setPref("media.YouTube.decode_signature_func.auto.last_update_ok", false);
+    return true;
+  },
+
+
+  sniff0: function (ctx, callback) {
+    // Using a worker instead of a direct call resolves the problem
+    // with GUI freezing due to severe performance degradation: 100 ms
+    // vs 2400 ms for zip_inflate(), 100 ms vs 800 ms for swf_parse().
+    // See bug 911570 (https://bugzilla.mozilla.org/show_bug.cgi?id=911570),
+    // or 776798, or 907201, or whatever is causing it.
+    var worker = new SDAWorker( {bytes: ctx.bytes, file: ctx.file} );
+    ctx.bytes = null;
+
+    worker.onfinish = function(rc) {
+      SDASniffer.working = false;
+      var callbacks = SDASniffer.callbacks;
+      SDASniffer.callbacks = [];
+
+      if (typeof(rc) === "string") {
+        fg.log("Error refreshing signature function: " + rc);
+        return;
+      }
+
+      if ( ! rc) { return; }
+      fg.setPref("media.YouTube.decode_signature_func.auto.last_update_ok", true);
+
+      if (rc.timestamp !== fg.getPref("media.YouTube.decode_signature_func.timestamp")) {
+        fg.log("New timestamp: " + rc.timestamp);
+        fg.setPref("media.YouTube.decode_signature_func.timestamp", rc.timestamp);
+      }
+
+      if (rc.func_text !== fg.getPref("media.YouTube.decode_signature_func")) {
+        fg.log("New signature function:\n" + rc.func_text);
+        fg.setPref("media.YouTube.decode_signature_func", rc.func_text);
+        callbacks.forEach(function(f){
+          try {
+            f();
+          } catch (x) {
+            fg.log("Callback error: " + (x.message || x) + "\n" + x.stack);
+          }
+        });
+      }
+    };
+
+    try {
+      worker.start();
+    } catch (x) {
+      worker.onfinish("Error starting the worker: " + (x.message || x) + "\n" + x.stack);
+    }
+  }
+}; // SDASniffer
+
+
+
+// class SDAWorker;
+function SDAWorker(ctx) {
+  this.ctx = ctx;
+  this.worker = null;
+  this.fired_onfinish = false;
+}
+
+SDAWorker.prototype = {
+  // public
+  start: function() {
+    var worker = this.worker = new Worker("YoutubeSwf.js");
+    worker["SDAWorker::this"] = this;
+    worker.onmessage = this.worker_onmessage;
+    worker.onerror = this.worker_onerror;
+    worker.postMessage(this.ctx);
+    this.ctx = null;
+  },
+
+  // Completion event handler, implemented by the caller.
+  // void onfinish(Object data);
+  // @param data - the result of the decoding, one of:
+  //   1) a primitive string value (typeof data === "string") - there was
+  //      an uncaught exception in the worker, and |data| is the error message.
+  //   2) Object - struct { string func_text; int timestamp; } - the result
+  //      of the decoding. Can be null/undefined (data == null covers both)
+  //      if the signature function could not be decoded.
+  onfinish: function(){},
+
+
+  // private
+  fire_onfinish: function(data) {
+    this.fired_onfinish = true;
+    try {
+      this.onfinish(data);
+    } catch (x) {
+      fg.log("Error in onfinish: " + (x.message || x) + "\n" + x.stack);
+    }
+  },
+
+  worker_onmessage: function(evt) {
+    var This = this["SDAWorker::this"];
+    // struct msg { string type; Object data; };
+    var msg = evt.data;
+    if (msg == null) {
+      fg.log("SDAWorker: Invalid message: null or undefined: " + msg);
+      This.finish();
+      return;
+    }
+    if (typeof(msg) !== "object") {
+      fg.log("SDAWorker: Invalid message: expected [object], got [" + typeof(msg) + "]: " + msg);
+      This.finish();
+      return;
+    }
+    switch (msg.type) {
+      case "done":
+        This.finish();
+        return;
+      case "log":
+        fg.log(msg.data);
+        return;
+      case "result":
+        This.fire_onfinish(msg.data);
+        return;
+    }
+    fg.log("SDAWorker: Invalid message type: '" + msg.type + "'");
+    This.finish();
+  },
+
+  worker_onerror: function(evt) {
+    var This = this["SDAWorker::this"];
+    This.fire_onfinish("Uncaught exception in worker: " + evt.message);
+    This.finish();
+  },
+
+  finish: function() {
+    if ( ! this.fired_onfinish) {
+      this.fire_onfinish(null);
+    }
+    try {
+      this.worker.terminate();
+      this.worker["SDAWorker::this"]
+        = this.worker.onmessage
+        = this.worker.onerror
+        = null;
+      this.worker = null;
+    } catch (x) {
+      fg.log("Error terminating the worker: " + (x.message || x) + "\n" + x.stack);
+    }
+  }
+}; // SDAWorker.prototype
+
+
+return Youtube;
+}(); // Youtube
diff --git a/chrome/flashgot.jar!/content/flashgot/YoutubeSwf.js b/chrome/flashgot.jar!/content/flashgot/YoutubeSwf.js
new file mode 100644
index 0000000..9c97a57
--- /dev/null
+++ b/chrome/flashgot.jar!/content/flashgot/YoutubeSwf.js
@@ -0,0 +1,2115 @@
+onmessage = function(evt)
+{
+  try
+  {
+    var rc = refresh_signature_func(evt.data);
+    postMessage( {type: "result", data: rc} );
+  }
+  // Log errors here because the stacktrace is lost
+  // when they're marshalled to the onerror handler.
+  catch (x)
+  {
+    log("YoutubeSwf: exception: " + (x.message || x) + "\n" + (x.stack || new Error().stack));
+  }
+  finally
+  {
+    // Notify the caller we're done. They will terminate us.
+    postMessage( {type: "done"} );
+  }
+}
+
+function log(msg)
+{
+  postMessage( {type: "log", data: String(msg)} );
+}
+
+
+
+var zip_inflate = function(){
+// http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
+/* Copyright (C) 1999,2012 Masanao Izumo <iz at onicos.co.jp>
+ * Version: 1.0.1
+ * LastModified: Jun 29 2012
+ */
+
+/* Interface:
+ * data = zip_inflate(src);
+ */
+
+/* constant parameters */
+var zip_WSIZE = 32768;		// Sliding Window size
+var zip_STORED_BLOCK = 0;
+var zip_STATIC_TREES = 1;
+var zip_DYN_TREES    = 2;
+
+/* for inflate */
+var zip_lbits = 9; 		// bits in base literal/length lookup table
+var zip_dbits = 6; 		// bits in base distance lookup table
+var zip_INBUFSIZ = 32768;	// Input buffer size
+var zip_INBUF_EXTRA = 64;	// Extra buffer
+
+/* variables (inflate) */
+var zip_slide;
+var zip_wp;			// current position in slide
+var zip_fixed_tl = null;	// inflate static
+var zip_fixed_td;		// inflate static
+var zip_fixed_bl, fixed_bd;	// inflate static
+var zip_bit_buf;		// bit buffer
+var zip_bit_len;		// bits in bit buffer
+var zip_method;
+var zip_eof;
+var zip_copy_leng;
+var zip_copy_dist;
+var zip_tl, zip_td;	// literal/length and distance decoder tables
+var zip_bl, zip_bd;	// number of bits decoded by tl and td
+
+var zip_inflate_data;
+var zip_inflate_pos;
+
+
+/* constant tables (inflate) */
+var zip_MASK_BITS = new Array(
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff);
+// Tables for deflate from PKZIP's appnote.txt.
+var zip_cplens = new Array( // Copy lengths for literal codes 257..285
+    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+    35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
+/* note: see note #13 above about the 258 in this list. */
+var zip_cplext = new Array( // Extra bits for literal codes 257..285
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+    3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid
+var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
+    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+    257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+    8193, 12289, 16385, 24577);
+var zip_cpdext = new Array( // Extra bits for distance codes
+    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+    7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+    12, 12, 13, 13);
+var zip_border = new Array(  // Order of the bit length code lengths
+    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
+/* objects (inflate) */
+
+function zip_HuftList() {
+    this.next = null;
+    this.list = null;
+}
+
+function zip_HuftNode() {
+    this.e = 0; // number of extra bits or operation
+    this.b = 0; // number of bits in this code or subcode
+
+    // union
+    this.n = 0; // literal, length base, or distance base
+    this.t = null; // (zip_HuftNode) pointer to next level of table
+}
+
+function zip_HuftBuild(b,	// code lengths in bits (all assumed <= BMAX)
+		       n,	// number of codes (assumed <= N_MAX)
+		       s,	// number of simple-valued codes (0..s-1)
+		       d,	// list of base values for non-simple codes
+		       e,	// list of extra bits for non-simple codes
+		       mm	// maximum lookup bits
+		   ) {
+    this.BMAX = 16;   // maximum bit length of any code
+    this.N_MAX = 288; // maximum number of codes in any set
+    this.status = 0;	// 0: success, 1: incomplete table, 2: bad input
+    this.root = null;	// (zip_HuftList) starting table
+    this.m = 0;		// maximum lookup bits, returns actual
+
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.	Return zero on success, one if
+   the given code set is incomplete (the tables are still built in this
+   case), two if the input is invalid (all zero length codes or an
+   oversubscribed set of lengths), and three if not enough memory.
+   The code with value 256 is special, and the tables are constructed
+   so that no bits beyond that code are fetched when that code is
+   decoded. */
+    {
+	var a;			// counter for codes of length k
+	var c = new Array(this.BMAX+1);	// bit length count table
+	var el;			// length of EOB code (value 256)
+	var f;			// i repeats in table every f entries
+	var g;			// maximum code length
+	var h;			// table level
+	var i;			// counter, current code
+	var j;			// counter
+	var k;			// number of bits in current code
+	var lx = new Array(this.BMAX+1);	// stack of bits per table
+	var p;			// pointer into c[], b[], or v[]
+	var pidx;		// index of p
+	var q;			// (zip_HuftNode) points to current table
+	var r = new zip_HuftNode(); // table entry for structure assignment
+	var u = new Array(this.BMAX); // zip_HuftNode[BMAX][]  table stack
+	var v = new Array(this.N_MAX); // values in order of bit length
+	var w;
+	var x = new Array(this.BMAX+1);// bit offsets, then code stack
+	var xp;			// pointer into x or c
+	var y;			// number of dummy codes added
+	var z;			// number of entries in current table
+	var o;
+	var tail;		// (zip_HuftList)
+
+	tail = this.root = null;
+	for(i = 0; i < c.length; i++)
+	    c[i] = 0;
+	for(i = 0; i < lx.length; i++)
+	    lx[i] = 0;
+	for(i = 0; i < u.length; i++)
+	    u[i] = null;
+	for(i = 0; i < v.length; i++)
+	    v[i] = 0;
+	for(i = 0; i < x.length; i++)
+	    x[i] = 0;
+
+	// Generate counts for each bit length
+	el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any
+	p = b; pidx = 0;
+	i = n;
+	do {
+	    c[p[pidx]]++;	// assume all entries <= BMAX
+	    pidx++;
+	} while(--i > 0);
+	if(c[0] == n) {	// null input--all zero length codes
+	    this.root = null;
+	    this.m = 0;
+	    this.status = 0;
+	    return;
+	}
+
+	// Find minimum and maximum length, bound *m by those
+	for(j = 1; j <= this.BMAX; j++)
+	    if(c[j] != 0)
+		break;
+	k = j;			// minimum code length
+	if(mm < j)
+	    mm = j;
+	for(i = this.BMAX; i != 0; i--)
+	    if(c[i] != 0)
+		break;
+	g = i;			// maximum code length
+	if(mm > i)
+	    mm = i;
+
+	// Adjust last length count to fill out codes, if needed
+	for(y = 1 << j; j < i; j++, y <<= 1)
+	    if((y -= c[j]) < 0) {
+		this.status = 2;	// bad input: more codes than bits
+		this.m = mm;
+		return;
+	    }
+	if((y -= c[i]) < 0) {
+	    this.status = 2;
+	    this.m = mm;
+	    return;
+	}
+	c[i] += y;
+
+	// Generate starting offsets into the value table for each length
+	x[1] = j = 0;
+	p = c;
+	pidx = 1;
+	xp = 2;
+	while(--i > 0)		// note that i == g from above
+	    x[xp++] = (j += p[pidx++]);
+
+	// Make a table of values in order of bit lengths
+	p = b; pidx = 0;
+	i = 0;
+	do {
+	    if((j = p[pidx++]) != 0)
+		v[x[j]++] = i;
+	} while(++i < n);
+	n = x[g];			// set n to length of v
+
+	// Generate the Huffman codes and for each, make the table entries
+	x[0] = i = 0;		// first Huffman code is zero
+	p = v; pidx = 0;		// grab values in bit order
+	h = -1;			// no tables yet--level -1
+	w = lx[0] = 0;		// no bits decoded yet
+	q = null;			// ditto
+	z = 0;			// ditto
+
+	// go through the bit lengths (k already is bits in shortest code)
+	for(; k <= g; k++) {
+	    a = c[k];
+	    while(a-- > 0) {
+		// here i is the Huffman code of length k bits for value p[pidx]
+		// make tables up to required level
+		while(k > w + lx[1 + h]) {
+		    w += lx[1 + h]; // add bits already decoded
+		    h++;
+
+		    // compute minimum size table less than or equal to *m bits
+		    z = (z = g - w) > mm ? mm : z; // upper limit
+		    if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
+			// too few codes for k-w bit table
+			f -= a + 1;	// deduct codes from patterns left
+			xp = k;
+			while(++j < z) { // try smaller tables up to z bits
+			    if((f <<= 1) <= c[++xp])
+				break;	// enough codes to use up j bits
+			    f -= c[xp];	// else deduct codes from patterns
+			}
+		    }
+		    if(w + j > el && w < el)
+			j = el - w;	// make EOB code end at table
+		    z = 1 << j;	// table entries for j-bit table
+		    lx[1 + h] = j; // set table size in stack
+
+		    // allocate and link in new table
+		    q = new Array(z);
+		    for(o = 0; o < z; o++) {
+			q[o] = new zip_HuftNode();
+		    }
+
+		    if(tail == null)
+			tail = this.root = new zip_HuftList();
+		    else
+			tail = tail.next = new zip_HuftList();
+		    tail.next = null;
+		    tail.list = q;
+		    u[h] = q;	// table starts after link
+
+		    /* connect to last table, if there is one */
+		    if(h > 0) {
+			x[h] = i;		// save pattern for backing up
+			r.b = lx[h];	// bits to dump before this table
+			r.e = 16 + j;	// bits in this table
+			r.t = q;		// pointer to this table
+			j = (i & ((1 << w) - 1)) >> (w - lx[h]);
+			u[h-1][j].e = r.e;
+			u[h-1][j].b = r.b;
+			u[h-1][j].n = r.n;
+			u[h-1][j].t = r.t;
+		    }
+		}
+
+		// set up table entry in r
+		r.b = k - w;
+		if(pidx >= n)
+		    r.e = 99;		// out of values--invalid code
+		else if(p[pidx] < s) {
+		    r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code
+		    r.n = p[pidx++];	// simple code is just the value
+		} else {
+		    r.e = e[p[pidx] - s];	// non-simple--look up in lists
+		    r.n = d[p[pidx++] - s];
+		}
+
+		// fill code-like entries with r //
+		f = 1 << (k - w);
+		for(j = i >> w; j < z; j += f) {
+		    q[j].e = r.e;
+		    q[j].b = r.b;
+		    q[j].n = r.n;
+		    q[j].t = r.t;
+		}
+
+		// backwards increment the k-bit code i
+		for(j = 1 << (k - 1); (i & j) != 0; j >>= 1)
+		    i ^= j;
+		i ^= j;
+
+		// backup over finished tables
+		while((i & ((1 << w) - 1)) != x[h]) {
+		    w -= lx[h];		// don't need to update q
+		    h--;
+		}
+	    }
+	}
+
+	/* return actual size of base table */
+	this.m = lx[1];
+
+	/* Return true (1) if we were given an incomplete table */
+	this.status = ((y != 0 && g != 1) ? 1 : 0);
+    } /* end of constructor */
+}
+
+
+/* routines (inflate) */
+
+function zip_GET_BYTE() {
+	if(zip_inflate_data.length == zip_inflate_pos) {
+		throw new Error("EOF");
+		return -1;
+	}
+	return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
+}
+
+function zip_NEEDBITS(n) {
+	while(zip_bit_len < n) {
+		zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
+		zip_bit_len += 8;
+	}
+}
+
+function zip_GETBITS(n) {
+	return zip_bit_buf & zip_MASK_BITS[n];
+}
+
+function zip_DUMPBITS(n) {
+	zip_bit_buf >>= n;
+	zip_bit_len -= n;
+}
+
+function zip_inflate_codes(buff, off, size) {
+    /* inflate (decompress) the codes in a deflated (compressed) block.
+       Return an error code or zero if it all goes ok. */
+    var e;		// table entry flag/number of extra bits
+    var t;		// (zip_HuftNode) pointer to table entry
+    var n;
+
+    if(size == 0)
+      return 0;
+
+    // inflate the coded data
+    n = 0;
+    for(;;) {			// do until end of block
+	zip_NEEDBITS(zip_bl);
+	t = zip_tl.list[zip_GETBITS(zip_bl)];
+	e = t.e;
+	while(e > 16) {
+	    if(e == 99)
+		return -1;
+	    zip_DUMPBITS(t.b);
+	    e -= 16;
+	    zip_NEEDBITS(e);
+	    t = t.t[zip_GETBITS(e)];
+	    e = t.e;
+	}
+	zip_DUMPBITS(t.b);
+
+	if(e == 16) {		// then it's a literal
+	    zip_wp &= zip_WSIZE - 1;
+	    buff[off + n++] = zip_slide[zip_wp++] = t.n;
+	    if(n == size)
+		return size;
+	    continue;
+	}
+
+	// exit if end of block
+	if(e == 15)
+	    break;
+
+	// it's an EOB or a length
+
+	// get length of block to copy
+	zip_NEEDBITS(e);
+	zip_copy_leng = t.n + zip_GETBITS(e);
+	zip_DUMPBITS(e);
+
+	// decode distance of block to copy
+	zip_NEEDBITS(zip_bd);
+	t = zip_td.list[zip_GETBITS(zip_bd)];
+	e = t.e;
+
+	while(e > 16) {
+	    if(e == 99)
+		return -1;
+	    zip_DUMPBITS(t.b);
+	    e -= 16;
+	    zip_NEEDBITS(e);
+	    t = t.t[zip_GETBITS(e)];
+	    e = t.e;
+	}
+	zip_DUMPBITS(t.b);
+	zip_NEEDBITS(e);
+	zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
+	zip_DUMPBITS(e);
+
+	// do the copy
+	while(zip_copy_leng > 0 && n < size) {
+	    zip_copy_leng--;
+	    zip_copy_dist &= zip_WSIZE - 1;
+	    zip_wp &= zip_WSIZE - 1;
+	    buff[off + n++] = zip_slide[zip_wp++]
+		= zip_slide[zip_copy_dist++];
+	}
+
+	if(n == size)
+	    return size;
+    }
+
+    zip_method = -1; // done
+    return n;
+}
+
+function zip_inflate_stored(buff, off, size) {
+	/* "decompress" an inflated type 0 (stored) block. */
+	var n;
+
+	// go to byte boundary
+	n = zip_bit_len & 7;
+	zip_DUMPBITS(n);
+
+	// get the length and its complement
+	zip_NEEDBITS(16);
+	n = zip_GETBITS(16);
+	zip_DUMPBITS(16);
+	zip_NEEDBITS(16);
+	if(n != ((~zip_bit_buf) & 0xffff)) {
+		throw new Error("n != (~zip_bit_buf) & 0xffff");
+		return -1; // error in compressed data
+	}
+	zip_DUMPBITS(16);
+
+	// read and output the compressed data
+	zip_copy_leng = n;
+
+	n = 0;
+	while(zip_copy_leng > 0 && n < size) {
+		zip_copy_leng--;
+		zip_wp &= zip_WSIZE - 1;
+		zip_NEEDBITS(8);
+		buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
+		zip_DUMPBITS(8);
+	}
+
+	if(zip_copy_leng == 0)
+		zip_method = -1; // done
+	return n;
+}
+
+function zip_inflate_fixed(buff, off, size) {
+    /* decompress an inflated type 1 (fixed Huffman codes) block.  We should
+       either replace this with a custom decoder, or at least precompute the
+       Huffman tables. */
+
+    // if first time, set up tables for fixed blocks
+    if(zip_fixed_tl == null) {
+	var i;			// temporary variable
+	var l = new Array(288);	// length list for huft_build
+	var h;	// zip_HuftBuild
+
+	// literal table
+	for(i = 0; i < 144; i++)
+	    l[i] = 8;
+	for(; i < 256; i++)
+	    l[i] = 9;
+	for(; i < 280; i++)
+	    l[i] = 7;
+	for(; i < 288; i++)	// make a complete, but wrong code set
+	    l[i] = 8;
+	zip_fixed_bl = 7;
+
+	h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext,
+			      zip_fixed_bl);
+	if(h.status != 0) {
+	    throw new Error("HufBuild error: "+h.status);
+	    return -1;
+	}
+	zip_fixed_tl = h.root;
+	zip_fixed_bl = h.m;
+
+	// distance table
+	for(i = 0; i < 30; i++)	// make an incomplete code set
+	    l[i] = 5;
+	zip_fixed_bd = 5;
+
+	h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
+	if(h.status > 1) {
+	    zip_fixed_tl = null;
+	    throw new Error("HufBuild error: "+h.status);
+	    return -1;
+	}
+	zip_fixed_td = h.root;
+	zip_fixed_bd = h.m;
+    }
+
+    zip_tl = zip_fixed_tl;
+    zip_td = zip_fixed_td;
+    zip_bl = zip_fixed_bl;
+    zip_bd = zip_fixed_bd;
+    return zip_inflate_codes(buff, off, size);
+}
+
+function zip_inflate_dynamic(buff, off, size) {
+    // decompress an inflated type 2 (dynamic Huffman codes) block.
+    var i;		// temporary variables
+    var j;
+    var l;		// last length
+    var n;		// number of lengths to get
+    var t;		// (zip_HuftNode) literal/length code table
+    var nb;		// number of bit length codes
+    var nl;		// number of literal/length codes
+    var nd;		// number of distance codes
+    var ll = new Array(286+30); // literal/length and distance code lengths
+    var h;		// (zip_HuftBuild)
+
+    for(i = 0; i < ll.length; i++)
+	ll[i] = 0;
+
+    // read in table lengths
+    zip_NEEDBITS(5);
+    nl = 257 + zip_GETBITS(5);	// number of literal/length codes
+    zip_DUMPBITS(5);
+    zip_NEEDBITS(5);
+    nd = 1 + zip_GETBITS(5);	// number of distance codes
+    zip_DUMPBITS(5);
+    zip_NEEDBITS(4);
+    nb = 4 + zip_GETBITS(4);	// number of bit length codes
+    zip_DUMPBITS(4);
+    if(nl > 286 || nd > 30)
+      return -1;		// bad lengths
+
+    // read in bit-length-code lengths
+    for(j = 0; j < nb; j++)
+    {
+	zip_NEEDBITS(3);
+	ll[zip_border[j]] = zip_GETBITS(3);
+	zip_DUMPBITS(3);
+    }
+    for(; j < 19; j++)
+	ll[zip_border[j]] = 0;
+
+    // build decoding table for trees--single level, 7 bit lookup
+    zip_bl = 7;
+    h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
+    if(h.status != 0)
+	return -1;	// incomplete code set
+
+    zip_tl = h.root;
+    zip_bl = h.m;
+
+    // read in literal and distance code lengths
+    n = nl + nd;
+    i = l = 0;
+    while(i < n) {
+	zip_NEEDBITS(zip_bl);
+	t = zip_tl.list[zip_GETBITS(zip_bl)];
+	j = t.b;
+	zip_DUMPBITS(j);
+	j = t.n;
+	if(j < 16)		// length of code in bits (0..15)
+	    ll[i++] = l = j;	// save last length in l
+	else if(j == 16) {	// repeat last length 3 to 6 times
+	    zip_NEEDBITS(2);
+	    j = 3 + zip_GETBITS(2);
+	    zip_DUMPBITS(2);
+	    if(i + j > n)
+		return -1;
+	    while(j-- > 0)
+		ll[i++] = l;
+	} else if(j == 17) {	// 3 to 10 zero length codes
+	    zip_NEEDBITS(3);
+	    j = 3 + zip_GETBITS(3);
+	    zip_DUMPBITS(3);
+	    if(i + j > n)
+		return -1;
+	    while(j-- > 0)
+		ll[i++] = 0;
+	    l = 0;
+	} else {		// j == 18: 11 to 138 zero length codes
+	    zip_NEEDBITS(7);
+	    j = 11 + zip_GETBITS(7);
+	    zip_DUMPBITS(7);
+	    if(i + j > n)
+		return -1;
+	    while(j-- > 0)
+		ll[i++] = 0;
+	    l = 0;
+	}
+    }
+
+    // build the decoding tables for literal/length and distance codes
+    zip_bl = zip_lbits;
+    h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
+    if(zip_bl == 0)	// no literals or lengths
+	h.status = 1;
+    if(h.status != 0) {
+	if(h.status == 1)
+	    ;// **incomplete literal tree**
+	return -1;		// incomplete code set
+    }
+    zip_tl = h.root;
+    zip_bl = h.m;
+
+    for(i = 0; i < nd; i++)
+	ll[i] = ll[i + nl];
+    zip_bd = zip_dbits;
+    h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
+    zip_td = h.root;
+    zip_bd = h.m;
+
+    if(zip_bd == 0 && nl > 257) {   // lengths but no distances
+	// **incomplete distance tree**
+	return -1;
+    }
+
+    if(h.status == 1) {
+	;// **incomplete distance tree**
+    }
+    if(h.status != 0)
+	return -1;
+
+    // decompress until an end-of-block code
+    return zip_inflate_codes(buff, off, size);
+}
+
+function zip_inflate_start() {
+    var i;
+
+    if(zip_slide == null)
+        zip_slide = new Array(2 * zip_WSIZE);
+    zip_wp = 0;
+    zip_bit_buf = 0;
+    zip_bit_len = 0;
+    zip_method = -1;
+    zip_eof = false;
+    zip_copy_leng = zip_copy_dist = 0;
+    zip_tl = null;
+}
+
+function zip_inflate_internal(buff, off, size) {
+	// decompress an inflated entry
+	var n, i;
+
+	n = 0;
+	while(n < size) {
+		if(zip_eof && zip_method == -1) {
+			return n;
+		}
+
+		if(zip_copy_leng > 0) {
+			if(zip_method != zip_STORED_BLOCK) {
+				// STATIC_TREES or DYN_TREES
+				while(zip_copy_leng > 0 && n < size) {
+					zip_copy_leng--;
+					zip_copy_dist &= zip_WSIZE - 1;
+					zip_wp &= zip_WSIZE - 1;
+					buff[off + n++] = zip_slide[zip_wp++] =
+					zip_slide[zip_copy_dist++];
+				}
+			} else {
+				while(zip_copy_leng > 0 && n < size) {
+					zip_copy_leng--;
+					zip_wp &= zip_WSIZE - 1;
+					zip_NEEDBITS(8);
+					buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
+					zip_DUMPBITS(8);
+				}
+				if(zip_copy_leng == 0)
+					zip_method = -1; // done
+			}
+			if(n == size) {
+				return n;
+			}
+		}
+
+		if(zip_method == -1) {
+			if(zip_eof) {
+				break;
+			}
+
+			// read in last block bit
+			zip_NEEDBITS(1);
+			if(zip_GETBITS(1) != 0)
+				zip_eof = true;
+			zip_DUMPBITS(1);
+
+			// read in block type
+			zip_NEEDBITS(2);
+			zip_method = zip_GETBITS(2);
+			zip_DUMPBITS(2);
+			zip_tl = null;
+			zip_copy_leng = 0;
+		}
+
+		switch(zip_method) {
+			case 0: // zip_STORED_BLOCK
+				i = zip_inflate_stored(buff, off + n, size - n);
+				break;
+
+			case 1: // zip_STATIC_TREES
+				if(zip_tl != null)
+					i = zip_inflate_codes(buff, off + n, size - n);
+				else
+					i = zip_inflate_fixed(buff, off + n, size - n);
+				break;
+
+			case 2: // zip_DYN_TREES
+				if(zip_tl != null)
+					i = zip_inflate_codes(buff, off + n, size - n);
+				else
+					i = zip_inflate_dynamic(buff, off + n, size - n);
+				break;
+
+			default: // error
+				i = -1;
+				break;
+		}
+
+		if(i == -1) {
+			if(zip_eof)
+				return 0;
+			return -1;
+		}
+		n += i;
+    }
+    return n;
+}
+
+function zip_inflate(data, offset /*= 0*/) {
+    var out, buff;
+    var i, j;
+
+    zip_inflate_start();
+    zip_inflate_data = data;
+    zip_inflate_pos = offset || 0;
+    var last_zip_inflate_pos = -1;
+
+if(!0){
+	zip_NEEDBITS(8);
+	var CMF = zip_GETBITS(8);
+	zip_DUMPBITS(8);
+	zip_NEEDBITS(8);
+	var FLG = zip_GETBITS(8);
+	zip_DUMPBITS(8);
+	if ((CMF & 0x0f) !== 8)
+	{
+		throw new Error("Unsupported compression.");
+	}
+	if (FLG & 0x20)
+	{
+		throw new Error("DICT");
+	}
+	if ((CMF * 256 + FLG) % 31 !== 0)
+	{
+		throw new Error("FCHECK");
+	}
+}
+
+    buff = new Array(1024);
+    out = "";
+    while((i = zip_inflate_internal(buff, 0, buff.length)) > 0
+        && last_zip_inflate_pos != zip_inflate_pos)
+    {
+      last_zip_inflate_pos = zip_inflate_pos;
+      for(j = 0; j < i; j++) out += String.fromCharCode(buff[j]);
+    }
+    zip_inflate_data = null; // G.C.
+    return out;
+}
+
+return zip_inflate;}();
+
+
+
+function swf_inflate(data)
+{
+	var sig = data.substr(0, 3);
+	if (sig === "FWS") { return data; }
+	if (sig !== "CWS") { throw new Error("Invalid signature: " + sig); }
+	var ss = new SwfStream(data);
+	ss.skip_bytes(3); // Signature.
+	ss.read_uint8(); // Version.
+	var inflated_size = ss.read_uint32();
+	var inflated = zip_inflate(data, 8);
+	if (inflated.length + 8 !== inflated_size) { throw new Error("Inflated size mismatch: expected " + inflated_size + ", got " + inflated.length); }
+	return "FWS" + data.substring(3, 8) + inflated;
+}
+
+
+
+function SwfStream(data)
+{
+	var m_bytes = data;
+	var m_byte_idx = 0;
+	var m_buf = 0;
+	var m_buf_bits = 0;
+
+	var byte_align = this.byte_align = function $SwfStream_$byte_align()
+	{
+		m_buf_bits = 0;
+	};
+
+	var read_bits = this.read_bits = function $SwfStream_$read_bits(count)
+	{
+		var rc = 0;
+		while (count !== 0)
+		{
+			if (m_buf_bits === 0)
+			{
+				if (m_byte_idx >= m_bytes.length)
+				{
+					throw new Error("EOF");
+				}
+				m_buf = m_bytes.charCodeAt(m_byte_idx++) & 0xff;
+				m_buf_bits = 8;
+			}
+			var cpy_bits = Math.min(count, m_buf_bits);
+			rc = (rc << cpy_bits) | n_hbits8(m_buf, cpy_bits);
+			m_buf = (m_buf << cpy_bits) & 0xff;
+			m_buf_bits -= cpy_bits;
+			count -= cpy_bits;
+		}
+		return rc;
+	};
+
+
+	var read_uint8 = this.read_uint8 = function $SwfStream_$read_uint8()
+	{
+		byte_align();
+		return read_bits(8);
+	};
+
+
+	var read_uint16 = this.read_uint16 = function $SwfStream_$read_uint16()
+	{
+		var b1 = read_uint8();
+		var b2 = read_uint8() << 8;
+		return b1 | b2;
+	};
+
+
+	var read_uint32 = this.read_uint32 = function $SwfStream_$read_uint32()
+	{
+		var b1 = read_uint8();
+		var b2 = read_uint8() << 8;
+		var b3 = read_uint8() << 16;
+		var b4 = read_uint8() << 24;
+		return (b1 | b2 | b3 | b4) >>> 0;
+	};
+
+
+	var read_sint32 = this.read_sint32 = function $SwfStream_$read_sint32()
+	{
+		return read_uint32() | 0;
+	};
+
+
+	var read_fixed8 = this.read_fixed8 = function $SwfStream_$read_fixed8()
+	{
+		var a = read_uint8();
+		var b = read_uint8();
+		return b + (a / 0x100);
+	};
+
+	var read_fixed = this.read_fixed = function $SwfStream_$read_fixed()
+	{
+		var a = read_uint16();
+		var b = read_uint16();
+		return b + (a / 0x10000);
+	};
+
+	var read_bytes = this.read_bytes = function $SwfStream_$read_bytes(count)
+	{
+		byte_align();
+		if (m_byte_idx + count > m_bytes.length)
+		{
+			m_byte_idx = m_bytes.length;
+			throw new Error("EOF");
+		}
+		return m_bytes.slice(m_byte_idx, m_byte_idx += count);
+	};
+
+
+	var skip_bytes = this.skip_bytes = function $SwfStream_$skip_bytes(count)
+	{
+		byte_align();
+		m_byte_idx += count;
+	};
+
+	var n_hbits8 = this.n_hbits8 = function $SwfStream_$n_hbits8(n, count)
+	{
+		return (n & 0xff) >> (8 - count);
+	};
+
+
+	var n_hbits16 = this.n_hbits16 = function $SwfStream_$n_hbits16(n, count)
+	{
+		return (n & 0xffff) >> (16 - count);
+	};
+
+
+	var n_lbits16 = this.n_lbits16 = function $SwfStream_$n_lbits16(n, count)
+	{
+		return n & ((1 << count) - 1);
+	};
+};
+
+
+
+// namespace_info kinds.
+var doabc_CONSTANT_Namespace = 0x08;
+var doabc_CONSTANT_PackageNamespace = 0x16;
+var doabc_CONSTANT_PackageInternalNs = 0x17;
+var doabc_CONSTANT_ProtectedNamespace = 0x18;
+var doabc_CONSTANT_ExplicitNamespace = 0x19;
+var doabc_CONSTANT_StaticProtectedNs = 0x1A;
+var doabc_CONSTANT_PrivateNs = 0x05;
+
+// multiname_info kinds.
+var doabc_CONSTANT_QName = 0x07;
+var doabc_CONSTANT_QNameA = 0x0D;
+var doabc_CONSTANT_RTQName = 0x0F;
+var doabc_CONSTANT_RTQNameA = 0x10;
+var doabc_CONSTANT_RTQNameL = 0x11;
+var doabc_CONSTANT_RTQNameLA = 0x12;
+var doabc_CONSTANT_Multiname = 0x09;
+var doabc_CONSTANT_MultinameA = 0x0E;
+var doabc_CONSTANT_MultinameL = 0x1B;
+var doabc_CONSTANT_MultinameLA = 0x1C;
+
+// option_detail kinds: these plus namespace_info kinds.
+var doabc_CONSTANT_Int = 0x03;
+var doabc_CONSTANT_UInt = 0x04;
+var doabc_CONSTANT_Double = 0x06;
+var doabc_CONSTANT_Utf8 = 0x01;
+var doabc_CONSTANT_True = 0x0B;
+var doabc_CONSTANT_False = 0x0A;
+var doabc_CONSTANT_Null = 0x0C;
+var doabc_CONSTANT_Undefined = 0x00;
+
+// method_info flags.
+var doabc_MF_NEED_ARGUMENTS = 0x01;
+var doabc_MF_NEED_ACTIVATION = 0x02;
+var doabc_MF_NEED_REST = 0x04;
+var doabc_MF_HAS_OPTIONAL = 0x08;
+var doabc_MF_SET_DXNS = 0x40;
+var doabc_MF_HAS_PARAM_NAMES = 0x80;
+
+// traits_info kinds.
+var doabc_Trait_Slot = 0;
+var doabc_Trait_Method = 1;
+var doabc_Trait_Getter = 2;
+var doabc_Trait_Setter = 3;
+var doabc_Trait_Class = 4;
+var doabc_Trait_Function = 5;
+var doabc_Trait_Const = 6;
+
+// traits_info attributes.
+var doabc_ATTR_Final = 0x01;
+var doabc_ATTR_Override = 0x02;
+var doabc_ATTR_Metadata = 0x04;
+
+// instance_info flags.
+var doabc_CONSTANT_ClassSealed = 0x01;
+var doabc_CONSTANT_ClassFinal = 0x02;
+var doabc_CONSTANT_ClassInterface = 0x04;
+var doabc_CONSTANT_ClassProtectedNs = 0x08;
+
+
+
+function doABCReader(bytes)
+{
+	var m_bytes = bytes;
+	var m_byte_idx = 0;
+
+	var eof = this.eof = function $doABCReader_$eof()
+	{
+		return m_byte_idx >= m_bytes.length;
+	};
+
+
+	var read_bytes = this.read_bytes = function $doABCReader_$read_bytes(count)
+	{
+		var end = m_byte_idx + count;
+		if (end > m_bytes.length)
+		{
+			m_byte_idx = m_bytes.length;
+			throw new Error("EOF");
+		}
+		var rc = m_bytes.slice(m_byte_idx, end);
+		m_byte_idx = end;
+		return rc;
+	};
+
+	var read_u8 = this.read_u8 = function $doABCReader_$read_u8()
+	{
+		if (eof())
+		{
+			throw new Error("EOF");
+		}
+		return m_bytes.charCodeAt(m_byte_idx++) & 0xff;
+	};
+
+
+	var read_u16 = this.read_u16 = function $doABCReader_$read_u16()
+	{
+		var b1 = read_u8();
+		var b2 = read_u8();
+		return (b2 << 8) | b1;
+	};
+
+
+	var read_s24 = this.read_s24 = function $doABCReader_$read_s24()
+	{
+		var b1 = read_u8();
+		var b2 = read_u8() << 8;
+		var b3 = read_u8() << 16;
+		var n = b1 | b2 | b3;
+		// 0x800000 is 2^23, 0x1000000 is 2^24.
+		if (n >= 0x800000)
+		{
+			n -= 0x1000000;
+		}
+		return n;
+	};
+
+
+	var read_u32 = this.read_u32 = function $doABCReader_$read_u32()
+	{
+		var n = 0;
+		for (var i = 0; i !== 5; ++i)
+		{
+			var b = read_u8();
+			const has_next = b & 0x80;
+			b &= 0x7f;
+			// Sanity check.
+			if (i === 4)
+			{
+				// The last byte must not have the high bit set.
+				if (has_next)
+				{
+					throw new Error("Invalid stream: high bit is set, but no more bytes needed.");
+				}
+				// The last byte can't have non-zero bits 4-7,
+				// i.e. it can't be greater than 0x0f (bin: 00001111),
+				// otherwise it would overflow the result value: 4*7 bits
+				// in the previous bytes = 28, so there's only 4 bits left,
+				// namely, 0-3.
+				if (b > 0x0f)
+				{
+					throw new Error("Invalid stream: too many bits set in the last byte.");
+				}
+			} // Sanity check.
+			n |= b << (i * 7);
+			if (!has_next) { break; }
+		}
+		return n >>> 0;
+	};
+
+
+	var read_u30 = this.read_u30 = function $doABCReader_$read_u30()
+	{
+		// 0x3fffffff is 2^30 - 1.
+		return read_u32() & 0x3fffffff;
+	};
+
+
+	var read_s32 = this.read_s32 = function $doABCReader_$read_s32()
+	{
+		return read_u32() | 0;
+	};
+
+	var read_d64 = this.read_d64 = function $doABCReader_$read_d64()
+	{
+		// static const boolean little_endian = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
+		if (arguments.callee["doABCReader::little_endian"] === undefined)
+		{
+			arguments.callee["doABCReader::little_endian"] = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
+		}
+		var b = new Array(8);
+		for (var i = 0; i !== 8; ++i) { b[i] = read_u8(); }
+		if (!arguments.callee["doABCReader::little_endian"])
+		{
+			b.reverse();
+		}
+		return new Float64Array(new Uint8Array(b).buffer)[0];
+	};
+
+
+	var read_cpool_info = this.read_cpool_info = function $doABCReader_$read_cpool_info()
+	{
+		var cp = new doabc_cpool_info();
+		
+		var cnt;
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.integers = new Array(cnt);
+			cp.integers[0] = 0;
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.integers[i] = read_s32();
+			}
+		}
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.uintegers = new Array(cnt);
+			cp.uintegers[0] = 0;
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.uintegers[i] = read_u32();
+			}
+		}
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.doubles = new Array(cnt);
+			cp.doubles[0] = 0;
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.doubles[i] = read_d64();
+			}
+		}
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.strings = new Array(cnt);
+			cp.strings[0] = "";
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.strings[i] = read_string_info();
+			}
+		}
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.namespaces = new Array(cnt);
+			cp.namespaces[0] = new doabc_namespace_info();
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.namespaces[i] = read_namespace_info();
+			}
+		}
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.ns_sets = new Array(cnt);
+			cp.ns_sets[0] = new doabc_ns_set_info();
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.ns_sets[i] = read_ns_set_info();
+			}
+		}
+
+		cnt = read_u30();
+		if (cnt !== 0)
+		{
+			cp.multinames = new Array(cnt);
+			cp.multinames[0] = new doabc_multiname_info();
+			for (var i = 1; i !== cnt; ++i)
+			{
+				cp.multinames[i] = read_multiname_info();
+			}
+		}
+
+		return cp;
+	};
+
+
+	var read_string_info = this.read_string_info = function $doABCReader_$read_string_info()
+	{
+		var size = read_u30();
+		if (size === 0) { return ""; }
+		var arr_utf8 = new Array(size);
+		for (var i = 0; i !== size; ++i)
+		{
+			arr_utf8[i] = String.fromCharCode(read_u8());
+		}
+		return UTF8.decode(arr_utf8.join(""));
+	};
+
+
+	var read_namespace_info = this.read_namespace_info = function $doABCReader_$read_namespace_info()
+	{
+		var o = {}; //new doabc_namespace_info();
+		o.kind = read_u8();
+		o.name = read_u30();
+		return o;
+	};
+
+
+	var read_ns_set_info = this.read_ns_set_info = function $doABCReader_$read_ns_set_info()
+	{
+		var o = {}; //new doabc_ns_set_info();
+		var cnt = read_u8();
+		o.ns = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.ns[i] = read_u30();
+		}
+		return o;
+	};
+
+
+	var read_multiname_info = this.read_multiname_info = function $doABCReader_$read_multiname_info()
+	{
+		var o;
+		var kind = read_u8();
+		switch (kind)
+		{
+			case doabc_CONSTANT_QName:
+			case doabc_CONSTANT_QNameA:
+				o = read_multiname_info_QName();
+				break;
+			case doabc_CONSTANT_RTQName:
+			case doabc_CONSTANT_RTQNameA:
+				o = read_multiname_info_RTQName();
+				break;
+			case doabc_CONSTANT_RTQNameL:
+			case doabc_CONSTANT_RTQNameLA:
+				o = read_multiname_info_RTQNameL();
+				break;
+			case doabc_CONSTANT_Multiname:
+			case doabc_CONSTANT_MultinameA:
+				o = read_multiname_info_Multiname();
+				break;
+			case doabc_CONSTANT_MultinameL:
+			case doabc_CONSTANT_MultinameLA:
+				o = read_multiname_info_MultinameL();
+				break;
+			default:
+				throw new Error("Unexpected multiname kind: " + kind);
+		}
+		o.kind = kind;
+		return o;
+	};
+
+
+	var read_method_info = this.read_method_info = function $doABCReader_$read_method_info()
+	{
+		var o = {}; //new doabc_method_info();
+
+		var cnt = read_u30();
+		o.return_type = read_u30();
+		
+		o.param_types = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.param_types[i] = read_u30();
+		}
+		
+		o.name = read_u30();
+		o.flags = read_u8();
+
+		if (o.flags & doabc_MF_HAS_OPTIONAL)
+		{
+			var cnt = read_u30();
+			o.options = new Array(cnt);
+			for (var i = 0; i !== cnt; ++i)
+			{
+				o.options[i] = read_option_detail();
+			}
+		}
+
+		if (o.flags & doabc_MF_HAS_PARAM_NAMES)
+		{
+			var cnt = read_u30();
+			o.param_names = new Array(cnt);
+			for (var i = 0; i !== cnt; ++i)
+			{
+				o.param_names[i] = read_u30();
+			}
+		}
+
+		return o;
+	};
+
+
+	var read_metadata_info = this.read_metadata_info = function $doABCReader_$read_metadata_info()
+	{
+		var o = {}; //new doabc_metadata_info();
+		o.name = read_u30();
+		var cnt = read_u30();
+		o.items = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.items[i] = read_item_info();
+		}
+		return o;
+	};
+
+
+	var read_instance_info = this.read_instance_info = function $doABCReader_$read_instance_info()
+	{
+		var o = {}; //new doabc_instance_info();
+		var cnt;
+
+		o.name = read_u30();
+		o.super_name = read_u30();
+		o.flags = read_u8();
+
+		if (o.flags & doabc_CONSTANT_ClassProtectedNs)
+		{
+			o.protectedNs = read_u30();
+		}
+
+		cnt = read_u30();
+		o.interfaces = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.interfaces[i] = read_u30();
+		}
+
+		o.iinit = read_u30();
+
+		cnt = read_u30();
+		o.traits = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.traits[i] = read_traits_info();
+		}
+
+		return o;
+	};
+
+
+	var read_class_info = this.read_class_info = function $doABCReader_$read_class_info()
+	{
+		var o = {}; //new doabc_class_info();
+		o.cinit = read_u30();
+		var cnt = read_u30();
+		o.traits = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.traits[i] = read_traits_info();
+		}
+		return o;
+	};
+
+
+	var read_script_info = this.read_script_info = function $doABCReader_$read_script_info()
+	{
+		var o = {}; //new doabc_script_info();
+		o.init = read_u30();
+		var cnt = read_u30();
+		o.traits = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.traits[i] = read_traits_info();
+		}
+		return o;
+	};
+
+
+	var read_method_body_info = this.read_method_body_info = function $doABCReader_$read_method_body_info()
+	{
+		var o = {}; //new doabc_method_body_info();
+		var cnt;
+
+		o.method = read_u30();
+		o.max_stack = read_u30();
+		o.local_count = read_u30();
+		o.init_scope_depth = read_u30();
+		o.max_scope_depth = read_u30();
+
+		cnt = read_u30();
+		o.code = read_bytes(cnt);
+
+		cnt = read_u30();
+		o.exceptions = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.exceptions[i] = read_exception_info();
+		}
+
+		cnt = read_u30();
+		o.traits = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			o.traits[i] = read_traits_info();
+		}
+
+		return o;
+	};
+
+
+	var read_option_detail = this.read_option_detail = function $doABCReader_$read_option_detail()
+	{
+		var o = {}; //new doabc_option_detail();
+		o.val = read_u30();
+		o.kind = read_u8();
+		return o;
+	};
+
+
+	var read_item_info = this.read_item_info = function $doABCReader_$read_item_info()
+	{
+		var o = {}; //new doabc_item_info();
+		o.key = read_u30();
+		o.val = read_u30();
+		return o;
+	};
+
+
+	var read_exception_info = this.read_exception_info = function $doABCReader_$read_exception_info()
+	{
+		var o = {}; //new doabc_exception_info();
+		o.from = read_u30();
+		o.to = read_u30();
+		o.target = read_u30();
+		o.exc_type = read_u30();
+		o.var_name = read_u30();
+		return o;
+	};
+
+
+	var read_traits_info = this.read_traits_info = function $doABCReader_$read_traits_info()
+	{
+		var o = {}; //new doabc_traits_info();
+		o.name = read_u30();
+
+		var kind = read_u8();
+		o.kind = kind & 0x0f;
+		o.attrs = (kind >> 4) & 0x0f;
+
+		switch (o.kind)
+		{
+			case doabc_Trait_Slot:
+			case doabc_Trait_Const:
+				o.trait = read_trait_slot();
+				break;
+			case doabc_Trait_Class:
+				o.trait = read_trait_class();
+				break;
+			case doabc_Trait_Function:
+				o.trait = read_trait_function();
+				break;
+			case doabc_Trait_Method:
+			case doabc_Trait_Getter:
+			case doabc_Trait_Setter:
+				o.trait = read_trait_method();
+				break;
+			default:
+				throw new Error("Unexpected trait kind: " + o.kind);
+		}
+
+		if (o.attrs & doabc_ATTR_Metadata)
+		{
+			var cnt = read_u8();
+			o.metadata = new Array(cnt);
+			for (var i = 0; i !== cnt; ++i)
+			{
+				o.metadata[i] = read_u30();
+			}
+		}
+
+		return o;
+	};
+
+
+	var read_trait_slot = this.read_trait_slot = function $doABCReader_$read_trait_slot()
+	{
+		var o = {}; //new doabc_trait_slot();
+		o.slot_id = read_u30();
+		o.type_name = read_u30();
+		o.vindex = read_u30();
+		if (o.vindex !== 0)
+		{
+			o.vkind = read_u8();
+		}
+		return o;
+	};
+
+
+	var read_trait_class = this.read_trait_class = function $doABCReader_$read_trait_class()
+	{
+		var o = {}; //new doabc_trait_class();
+		o.slot_id = read_u30();
+		o.classi = read_u30();
+		return o;
+	};
+
+
+	var read_trait_function = this.read_trait_function = function $doABCReader_$read_trait_function()
+	{
+		var o = {}; //new doabc_trait_function();
+		o.slot_id = read_u30();
+		o.func = read_u30();
+		return o;
+	};
+
+
+	var read_trait_method = this.read_trait_method = function $doABCReader_$read_trait_method()
+	{
+		var o = {}; //new doabc_trait_method();
+		o.disp_id = read_u30();
+		o.method = read_u30();
+		return o;
+	};
+
+
+	var read_multiname_info_QName = this.read_multiname_info_QName = function $doABCReader_$read_multiname_info_QName()
+	{
+		var o = {}; //new doabc_multiname_info_QName();
+		o.ns = read_u30();
+		o.name = read_u30();
+		return o;
+	};
+
+
+	var read_multiname_info_RTQName = this.read_multiname_info_RTQName = function $doABCReader_$read_multiname_info_RTQName()
+	{
+		var o = {}; //new doabc_multiname_info_RTQName();
+		o.name = read_u30();
+		return o;
+	};
+
+
+	var read_multiname_info_RTQNameL = this.read_multiname_info_RTQNameL = function $doABCReader_$read_multiname_info_RTQNameL()
+	{
+		// This kind has no associated data.
+		return {}; //new doabc_multiname_info_RTQNameL();
+	};
+
+
+	var read_multiname_info_Multiname = this.read_multiname_info_Multiname = function $doABCReader_$read_multiname_info_Multiname()
+	{
+		var o = {}; //new doabc_multiname_info_Multiname();
+		o.name = read_u30();
+		o.ns_set = read_u30();
+		return o;
+	};
+
+
+	var read_multiname_info_MultinameL = this.read_multiname_info_MultinameL = function $doABCReader_$read_multiname_info_MultinameL()
+	{
+		var o = {}; //new doabc_multiname_info_MultinameL();
+		o.ns_set = read_u30();
+		return o;
+	};
+}
+
+
+function doabc_namespace_info()
+{
+	this.kind = 0;
+	this.name = 0;
+}
+
+
+function doabc_ns_set_info()
+{
+	this.ns = [];
+}
+
+
+function doabc_multiname_info()
+{
+	this.kind = 0;
+}
+
+
+function doabc_cpool_info()
+{
+	this.integers = [];
+	this.uintegers = [];
+	this.doubles = [];
+	this.strings = [];
+	this.namespaces = [];
+	this.ns_sets = [];
+	this.multinames = [];
+}
+
+doabc_cpool_info.prototype = {
+	resolve_string: function $doabc_cpool_info_$resolve_string(idx)
+	{
+		if (idx < 0 || idx >= this.strings.length)
+		{
+			throw new Error("Index out of range: " + idx);
+		}
+		return this.strings[idx];
+	},
+
+	resolve_ns: function $doabc_cpool_info_$resolve_ns(idx)
+	{
+		if (idx < 0 || idx >= this.namespaces.length)
+		{
+			throw new Error("Index out of range: " + idx);
+		}
+		return this.resolve_string(this.namespaces[idx].name);
+	},
+
+	resolve_multiname: function $doabc_cpool_info_$resolve_multiname(idx)
+	{
+		if (idx < 0 || idx >= this.multinames.length)
+		{
+			throw new Error("Index out of range: " + idx);
+		}
+
+		var s = "";
+
+		var mi = this.multinames[idx];
+		switch (mi.kind)
+		{
+			case doabc_CONSTANT_QName:
+			case doabc_CONSTANT_QNameA:
+				if (mi.ns !== 0) { s = this.resolve_ns(mi.ns); }
+				if (s.length !== 0) { s += "."; }
+				s += this.resolve_string(mi.name);
+				break;
+			case doabc_CONSTANT_RTQName:
+			case doabc_CONSTANT_RTQNameA:
+				s = this.resolve_string(mi.name);
+				break;
+			case doabc_CONSTANT_RTQNameL:
+			case doabc_CONSTANT_RTQNameLA:
+				// This kind has no associated data.
+				break;
+			case doabc_CONSTANT_Multiname:
+			case doabc_CONSTANT_MultinameA:
+				// TODO: Implement.
+				break;
+			case doabc_CONSTANT_MultinameL:
+			case doabc_CONSTANT_MultinameLA:
+				// TODO: Implement.
+				break;
+			default:
+				throw new Error("Unexpected multiname kind: " + mi.kind);
+		}
+		return s;
+	}
+};
+
+
+
+function doABCFile()
+{
+	this.major_version = 0;
+	this.minor_version = 0;
+	this.constant_pool = null;
+	this.methods = [];
+	this.metadata = [];
+	this.instances = [];
+	this.classes = [];
+	this.scripts = [];
+	this.method_bodies = [];
+}
+
+
+// ActionScript 3 opcodes.
+var AS3_OP_PUSHSCOPE = 0x30;
+var AS3_OP_PUSHSTRING = 0x2c;
+var AS3_OP_PUSHBYTE = 0x24;
+var AS3_OP_GETLOCAL_0 = 0xd0;
+var AS3_OP_GETLOCAL_1 = 0xd1;
+var AS3_OP_GETLOCAL_2 = 0xd2;
+var AS3_OP_SETLOCAL_2 = 0xd6;
+var AS3_OP_CALLPROPERTY = 0x46;
+var AS3_OP_COERCE = 0x80;
+var AS3_OP_FINDPROPSTRICT = 0x5d;
+var AS3_OP_RETURNVALUE = 0x48;
+
+
+var UTF8 = {
+	decode: function(str)
+	{
+		var a = [];
+		for (var i = 0, len = str.length; i < len; ++i)
+		{
+			var cc = str.charCodeAt(i);
+			if (cc > 255) { throw new Error("Illegal character: must be in range [0; 255]: " + cc); }
+			if (cc < 0x80)
+			{
+				a.push(str.charAt(i));
+				continue;
+			}
+			var n = 0;
+			var num_bytes = 0;
+			// 110xxxxx 10xxxxxx
+			if ((cc & 0xe0) === 0xc0)
+			{
+				num_bytes = 1;
+				n = cc & 0x1f;
+			}
+			// 1110xxxx 10xxxxxx 10xxxxxx
+			else if ((cc & 0xf0) === 0xe0)
+			{
+				num_bytes = 2;
+				n = cc & 0x0f;
+			}
+			// Other is not supported, because we have only 16 bits for code points.
+			// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+			// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+			// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+			else
+			{
+				throw new Error("Code point too big.");
+			}
+			var j = i + 1, j_end = j + num_bytes;
+			if (j_end > len)
+			{
+				throw new Error("Premature end of input string.");
+			}
+			for (; j !== j_end; ++j)
+			{
+				cc = str.charCodeAt(j);
+				if (cc > 255)
+				{
+					throw new Error("Illegal character: must be in range [0; 255]: " + cc);
+				}
+				if ((cc & 0xc0) !== 0x80)
+				{
+					throw new Error("Illegal character: high bits must be 10: " + cc
+						+ " (0x" + hex_pad(cc, cc < 0x100 ? 2 : 4) + ", " + bin_pad(cc, cc < 0x100 ? 8 : 16) + ")");
+				}
+				n <<= 6;
+				n |= cc & 0x3f;
+			}
+			a.push(String.fromCharCode(n));
+			i = j_end - 1;
+		}
+		return a.join("");
+	},
+
+
+	encode: function(str)
+	{
+		var a = [];
+		for (var i = 0, len = str.length; i !== len; ++i)
+		{
+			var cc = str.charCodeAt(i);
+			// 0xxxxxxx
+			if (cc < 0x80)
+			{
+				a.push(str.charAt(i));
+				continue;
+			}
+			var n, num_bytes;
+			// 110xxxxx 10xxxxxx
+			if (cc < 0x0800)
+			{
+				num_bytes = 1;
+				n = 0xc0 | ((cc >> 6) & 0x1f);
+				cc <<= 8;
+			}
+			// 1110xxxx 10xxxxxx 10xxxxxx
+			else if (cc < 0x10000)
+			{
+				num_bytes = 2;
+				n = 0xe0 | ((cc >> 12) & 0x0f);
+				cc <<= 2;
+			}
+			// Other is not supported, because we have only 16 bits for code points.
+			// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+			// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+			// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+			else
+			{
+				throw new Error("Code point too big.");
+			}
+			a.push(String.fromCharCode(n));
+			for (var j = 0; j !== num_bytes; ++j)
+			{
+				n = 0x80 | ((cc >> 8) & 0x3f);
+				a.push(String.fromCharCode(n));
+				cc <<= 6;
+			}
+		}
+		return a.join("");
+	}
+};
+
+
+
+function get_simple_date_str()
+{
+	var now = new Date();
+	var y = now.getFullYear();
+	var m = now.getMonth() + 1;
+	var d = now.getDate();
+	return "" + y + "-" + (m < 10 ? "0" : "") + m + "-" + (d < 10 ? "0" : "") + d;
+}
+
+
+function Stopwatch()
+{
+	this.start_times = {};
+	this.end_times = {};
+}
+Stopwatch.prototype = {
+	start: function(name /*= null*/)
+	{
+		this.start_times[name] = Date.now();
+		this.end_times[name] = 0;
+	},
+
+	stop: function(name /*= null*/)
+	{
+		this.end_times[name] = Date.now();
+	},
+
+	time: function(name /*= null*/)
+	{
+		return (this.end_times[name] || Date.now()) - this.start_times[name];
+	}
+};
+
+
+function refresh_signature_func(ctx)
+{
+	var df = parse_swf(ctx);
+	if (!df) { return; }
+
+	var rc = {timestamp: -1, func_text: ""};
+
+	var stopwatch = new Stopwatch();
+	stopwatch.start();
+	var cp = df.constant_pool;
+	var inst_idx = -1;
+	for (var i = 0, len = df.instances.length; i !== len; ++i) 
+	{
+		var ii = df.instances[i];
+		if (cp.multinames[ii.name].kind !== doabc_CONSTANT_QName) { continue; }
+		if (cp.resolve_multiname(ii.name) === "com.google.youtube.util.SignatureDecipher")
+		{
+			inst_idx = i;
+			break;
+		}
+	}
+	if (inst_idx === -1) { return; }
+	var index_by_name = {"decipher": null, "clone": null, "swap": null, "reverse": null};
+	var name_by_index = {};
+	var cls = df.classes[inst_idx];
+	for (var i = 0, len = cls.traits.length; i !== len; ++i)
+	{
+		var ti = cls.traits[i];
+		if (ti.kind !== doabc_Trait_Method || cp.multinames[ti.name].kind !== doabc_CONSTANT_QName) { continue; }
+		var s_name = cp.resolve_multiname(ti.name);
+		var map_name, map_idx;
+		if (/^(clone|swap|reverse)_(\d+)$/.test(s_name))
+		{
+			map_name = RegExp.$1;
+			map_idx = ti.name;
+			rc.timestamp = parseInt(RegExp.$2);
+		}
+		else if ("decipher" === s_name)
+		{
+			map_name = s_name;
+			map_idx = ti.trait.method;
+		}
+		if (!map_name) { continue; }
+		if (index_by_name[map_name] != null) { return; }
+		index_by_name[map_name] = map_idx;
+		name_by_index[map_idx] = map_name;
+	}
+	for (var p in index_by_name)
+	{
+		if (index_by_name[p] == null) { return; }
+	}
+	var m_idx = index_by_name["decipher"], mb = null;
+	if (!df.method_bodies.some(function(o){return o.method === m_idx && (mb = o);})) { return; }
+	var calls = [];
+	var dar = new doABCReader(mb.code);
+	var state = {states: null, idx: -1};
+	function advance_if(cond) { return cond ? ++state.idx : false; }
+	function switch_if(cond, states, idx /*= 0*/) {
+		if (!cond) { return false; }
+		state.states = states;
+		state.idx = idx || 0;
+		return true;
+	}
+	function done_if(cond) { return cond ? null : false; }
+	var PS_START = [
+		AS3_OP_GETLOCAL_0,
+		AS3_OP_PUSHSCOPE,
+		AS3_OP_GETLOCAL_1,
+		function(op) { return advance_if(op === AS3_OP_PUSHSTRING && cp.resolve_string(dar.read_u30()).length === 0); },
+		function(op) {
+			return switch_if(op === AS3_OP_CALLPROPERTY
+				&& cp.resolve_multiname(dar.read_u30()) === "http://adobe.com/AS3/2006/builtin.split"
+				&& dar.read_u30() === 1, PS_STORE_AND_BRANCH);
+		}
+	];
+	var PS_STORE_AND_BRANCH = [
+		function(op) { return advance_if(op === AS3_OP_COERCE && cp.resolve_multiname(dar.read_u30()) === "Array"); },
+		AS3_OP_SETLOCAL_2,
+		function(op) {
+			if (op === AS3_OP_FINDPROPSTRICT) {
+				var name = name_by_index[dar.read_u30()];
+				return switch_if(name === "swap", PS_SWAP)
+					|| switch_if(name === "clone", PS_CLONE)
+					|| switch_if(name === "reverse", PS_REVERSE);
+			}
+			return advance_if(op === AS3_OP_GETLOCAL_2);
+		},
+		function(op) { return advance_if(op === AS3_OP_PUSHSTRING && cp.resolve_string(dar.read_u30()).length === 0); },
+		function(op) {
+			return advance_if(op === AS3_OP_CALLPROPERTY
+				&& cp.resolve_multiname(dar.read_u30()) === "http://adobe.com/AS3/2006/builtin.join"
+				&& dar.read_u30() === 1);
+		},
+		function(op) { return done_if(op === AS3_OP_RETURNVALUE); }
+	];
+	var PS_SWAP = [
+		AS3_OP_GETLOCAL_2,
+		function(op) { return advance_if(op === AS3_OP_PUSHBYTE && calls.push( {name: "swap", arg: dar.read_u8()} )); },
+		function(op) {
+			return switch_if(op === AS3_OP_CALLPROPERTY
+				&& dar.read_u30() === index_by_name["swap"]
+				&& dar.read_u30() === 2, PS_STORE_AND_BRANCH);
+		}
+	];
+	var PS_CLONE = [
+		AS3_OP_GETLOCAL_2,
+		function(op) { return advance_if(op === AS3_OP_PUSHBYTE && calls.push( {name: "clone", arg: dar.read_u8()} )); },
+		function(op) {
+			return switch_if(op === AS3_OP_CALLPROPERTY
+				&& dar.read_u30() === index_by_name["clone"]
+				&& dar.read_u30() === 2, PS_STORE_AND_BRANCH);
+		}
+	];
+	var PS_REVERSE = [
+		function(op) { return advance_if(op === AS3_OP_GETLOCAL_2 && calls.push( {name: "reverse"} )); },
+		function(op) {
+			return switch_if(op === AS3_OP_CALLPROPERTY
+				&& dar.read_u30() === index_by_name["reverse"]
+				&& dar.read_u30() === 1, PS_STORE_AND_BRANCH);
+		}
+	];
+	state.states = PS_START;
+	state.idx = 0;
+	var done = false;
+	while (!done && !dar.eof())
+	{
+		var opcode = dar.read_u8();
+		var sv = state.states[state.idx];
+		var res;
+		switch (typeof(sv))
+		{
+			case "number":
+				res = advance_if(opcode === sv);
+				break;
+			case "function":
+				res = sv(opcode);
+				break;
+			default:
+				throw new Error("Invalid state type: " + typeof(sv));
+		}
+		if (!res)
+		{
+			done = res === null;
+			break;
+		}
+	}
+	if (!done) { return; }
+	var code = [
+		"/* Not encoded. */",
+		"if (params.stream.sig) { return params.stream.sig; }",
+		"/* " + get_simple_date_str() + ": " + String(ctx.file).replace(/[\\*]/g, "_") + " */",
+		"var s = params.stream.s;",
+		"if (!s) { return ''; }",
+		"var swap = params.swap;",
+		"var a = s.split('');"
+		];
+	for (var i = 0, len = calls.length; i !== len; ++i) {
+		var o = calls[i];
+		switch (o.name) {
+			case "swap":
+				code.push("swap(a, " + o.arg + ");");
+				break;
+			case "clone":
+				code.push("a = a.slice(" + o.arg + ");");
+				break;
+			case "reverse":
+				code.push("a.reverse();");
+				break;
+			default:
+				return;
+		}
+	}
+	code.push("return a.join('');");
+	stopwatch.stop();
+	log("Got signature function in " + stopwatch.time() + " ms.");
+	rc.func_text = code.join(" ");
+	return rc;
+}
+
+function parse_swf(ctx)
+{
+var stopwatch = new Stopwatch();
+
+stopwatch.start();
+	var swf_inflated = swf_inflate(ctx.bytes);
+stopwatch.stop();
+log("SWF inflated in " + stopwatch.time() + " ms.");
+	ctx.bytes = null;
+
+stopwatch.start();
+	var bs = new SwfStream(swf_inflated);
+	bs.skip_bytes(8); // Signature, version, size.
+	var num_bits = bs.read_bits(5);
+	bs.read_bits(num_bits);
+	bs.read_bits(num_bits);
+	bs.read_bits(num_bits);
+	bs.read_bits(num_bits);
+	bs.skip_bytes(4); // Frame rate, frame count.
+
+	var df = null;
+	for (;;)
+	{
+		var t = bs.read_uint16();
+		var tag_type = bs.n_hbits16(t, 10);
+		var tag_len = bs.n_lbits16(t, 6);
+		if (tag_len === 0x3f)
+		{
+			tag_len = bs.read_sint32();
+		}
+		if (0 === tag_type) { break; }
+		if (tag_type !== 82)
+		{
+			bs.skip_bytes(tag_len);
+			continue;
+		}
+
+		var bytes = bs.read_bytes(tag_len);
+		var dar = new doABCReader(bytes);
+		for (var i = 0; i !== 4; ++i) { dar.read_u8(); }
+		while (dar.read_u8() !== 0) {}
+		df = new doABCFile();
+		df.minor_version = dar.read_u16();
+		df.major_verison = dar.read_u16();
+		df.constant_pool = dar.read_cpool_info();
+
+		var cnt;
+		cnt = dar.read_u30();
+		df.methods = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			df.methods[i] = dar.read_method_info();
+		}
+
+		cnt = dar.read_u30();
+		df.metadata = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			df.metadata[i] = dar.read_metadata_info();
+		}
+
+		cnt = dar.read_u30();
+		df.instances = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			df.instances[i] = dar.read_instance_info();
+		}
+		df.classes = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			df.classes[i] = dar.read_class_info();
+		}
+
+		cnt = dar.read_u30();
+		df.scripts = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			df.scripts[i] = dar.read_script_info();
+		}
+
+		cnt = dar.read_u30();
+		df.method_bodies = new Array(cnt);
+		for (var i = 0; i !== cnt; ++i)
+		{
+			df.method_bodies[i] = dar.read_method_body_info();
+		}
+
+		break;
+	}
+stopwatch.stop();
+log("SWF parsed in " + stopwatch.time() + " ms.");
+
+	return df;
+}
diff --git a/chrome/flashgot.jar!/content/flashgot/about.xul b/chrome/flashgot.jar!/content/flashgot/about.xul
index 2bd94b4..3e91a47 100644
--- a/chrome/flashgot.jar!/content/flashgot/about.xul
+++ b/chrome/flashgot.jar!/content/flashgot/about.xul
@@ -64,4 +64,4 @@ function browse(url, features) {
 }
 
 
-</script><stringbundleset id="stringbundleset"><stringbundle id="about-strings" src="chrome://flashgot/locale/about.properties"/><stringbundle id="about-stringsFB" src="chrome://flashgot/content/en-US/about.properties"/></stringbundleset><vbox id="clientBox"><vbox id="clientBoxInternal" flex="1"><hbox align="start"><vbox id="logoBox"><image id="logo" src="chrome://flashgot/skin/icon80.png" class="link" tooltiptext="Visit Extension Home Page" onclick="browse('http://flashgot.net')"/></vbo [...]
\ No newline at end of file
+</script><stringbundleset id="stringbundleset"><stringbundle id="about-strings" src="chrome://flashgot/locale/about.properties"/><stringbundle id="about-stringsFB" src="chrome://flashgot/content/en-US/about.properties"/></stringbundleset><vbox id="clientBox"><vbox id="clientBoxInternal" flex="1"><hbox align="start"><vbox id="logoBox"><image id="logo" src="chrome://flashgot/skin/icon80.png" class="link" tooltiptext="Visit Extension Home Page" onclick="browse('http://flashgot.net')"/></vbo [...]
\ No newline at end of file
diff --git a/chrome/flashgot.jar!/content/flashgot/chooser.js b/chrome/flashgot.jar!/content/flashgot/chooser.js
index f13895a..210c9bd 100644
--- a/chrome/flashgot.jar!/content/flashgot/chooser.js
+++ b/chrome/flashgot.jar!/content/flashgot/chooser.js
@@ -161,11 +161,12 @@ var Chooser = {
     var d = this.params.choosenDir;
     if (d) {
       if (!d.exists()) {
-        var permissions = d.parent.exists() ? d.parent.permissions : parseInt("0600", 8);
+        var permissions = d.parent && d.parent.exists() ? d.parent.permissions : parseInt("0600", 8);
         try {
           d.create(CI.nsIFile.DIRECTORY_TYPE, permissions);
         } catch (e) {
-          return;
+          gFlashGotService.showFileWriteError(d, e);
+          throw e;
         }
       }
       try {
diff --git a/chrome/flashgot.jar!/content/flashgot/contents.rdf b/chrome/flashgot.jar!/content/flashgot/contents.rdf
index 6230821..d649449 100644
--- a/chrome/flashgot.jar!/content/flashgot/contents.rdf
+++ b/chrome/flashgot.jar!/content/flashgot/contents.rdf
@@ -8,7 +8,7 @@
     </RDF:Seq>
 
     <RDF:Description about="urn:mozilla:package:flashgot"
-            chrome:displayName="FlashGot 1.5.5.3"
+            chrome:displayName="FlashGot 1.5.5.95"
             chrome:author="Giorgio Maone (InformAction)"
             chrome:authorURL="http://www.informaction.com/g_maone"
             chrome:name="flashgot"
diff --git a/chrome/flashgot.jar!/content/flashgot/flashgotOverlay.js b/chrome/flashgot.jar!/content/flashgot/flashgotOverlay.js
index 6584ffa..2c09373 100644
--- a/chrome/flashgot.jar!/content/flashgot/flashgotOverlay.js
+++ b/chrome/flashgot.jar!/content/flashgot/flashgotOverlay.js
@@ -20,7 +20,8 @@
 ***** END LICENSE BLOCK *****/
 
 var gFlashGot = {
-    
+  _current_url: null,
+
   onload: function(ev) {
     ev.currentTarget.removeEventListener(ev.type, arguments.callee, false);
     try {
@@ -288,7 +289,8 @@ var gFlashGot = {
       toggleMenu("all", dis);
       toggleMenu("sel", dis || this.isSelInvalid);
       toggleMenu("buildGallery", false);
-      toggleMenu("media", dis || !this.media);
+      const media = this.media;
+      toggleMenu("media", dis || !(media && media.length));
       toggleMenu("opts", false);      
     }
   }
@@ -305,8 +307,8 @@ var gFlashGot = {
       var menuItem = document.getElementById("flashgot-menuitem-" + name);
       
       if(menuItem && 
-        ! ( menuItem.hidden = 
-            ( hidden || gFlashGotService.getPref("hide-" + name) ) )
+        !(menuItem.hidden = 
+            (hidden || gFlashGotService.getPref("hide-" + name)))
       ) {
        menuItem.setAttribute("disabled", disabled ? "true" : "false");
        if(! (menuItem.hidden=disabled && hideDisabled) ) {
@@ -342,7 +344,9 @@ var gFlashGot = {
     menuSwitch("tabs", (! (typeof(gBrowser)=="object" 
       && gBrowser.browsers && gBrowser.browsers.length > 1) ) 
                            || hidden || dm.disabledAll);
-    menuSwitch("media", hidden || !this.media);
+    
+    const media = this.media;
+    menuSwitch("media", hidden || !(media && media.length));
 
     hidden = false;
     menuSwitch("buildGallery", false);
@@ -514,15 +518,20 @@ var gFlashGot = {
 ,
 
   get _mediaIDs() {
-    var addonBar = document.getElementById("addon-bar");
     var widgetId = "flashgot-media-status";
-    var el = document.getElementById(widgetId);
-    if (addonBar) {
+    var addonBar = document.getElementById("addon-bar");
+    var statusBar = document.getElementById("status-bar");
+    if (addonBar || !document.getElementById("status-bar")) {
+      
+      var el = document.getElementById(widgetId);
+      
       if (el) el.parentNode.removeChild(el);
       widgetId = "flashgot-media-tbb";
       el = document.getElementById(widgetId);
+      
+      var addonBarVisible = addonBar && addonBar.boxObject.height;
       if (el && (el.nextSibling && el.nextSibling.id === "search-container" ||
-                 addonBar.collapsed && el.parentNode === addonBar &&
+                 addonBarVisible && el.parentNode === addonBar &&
                  !gFlashGotService.getPref("media.iconInstalled", false))) {
         el = null;
       }
@@ -530,24 +539,33 @@ var gFlashGot = {
       if (!el) {
         const fakeID = "flashgot-fake-tbb";
         const splitRx = /\s*,\s*/;
-        var set = addonBar.currentSet.split(splitRx);
-        
-        if (set.indexOf(fakeID) === -1) {
-          set.push(fakeID);
+        var bar, set, refId;
+        if (addonBar) {
+          set = addonBar.currentSet.split(splitRx);
           
-          var bar, refId;
-          var navBar = document.getElementById("nav-bar");
-          
-          if(addonBar.collapsed && navBar && !navBar.collapsed) {
-            addonBar.setAttribute("currentset", addonBar.currentSet = set.join(","));
-            document.persist(addonBar.id, "currentset");
-            bar = navBar;
-            set = bar.currentSet.split(splitRx)
-          } else {
-            bar = addonBar;
-            refId = "status";
+          if (set.indexOf(fakeID) === -1) {
+            set.push(fakeID);
+            
+            var navBar = document.getElementById("nav-bar");
+            
+            if(!addonBarVisible && navBar && !navBar.collapsed) {
+              addonBar.setAttribute("currentset", addonBar.currentSet = set.join(","));
+              document.persist(addonBar.id, "currentset");
+              bar = navBar;
+              set = bar.currentSet.split(splitRx);
+            } else {
+              bar = addonBar;
+              refId = "status";
+            }
           }
-
+        }
+        
+        if (!bar) {
+          bar = document.getElementById("nav-bar");
+          set = bar && bar.currentSet.split(splitRx);
+        }
+        
+        if (bar) {
           for (var p; (p = set.indexOf(widgetId)) > -1;)
             set.splice(p, 1);
           
@@ -659,33 +677,170 @@ var gFlashGot = {
   },
   
   prepareMediaMenu: function(menu) {
-    var pivot = Array.slice(menu.getElementsByTagName("menuseparator")).pop();
-    while (pivot.nextSibling) menu.removeChild(pivot.nextSibling);
+    var menu_parsed = document.getElementById("flashgot-media-parsed-popup");
+    var menu_parsed_dash = document.getElementById("flashgot-media-parsed-dash-popup");
+    var mi_refresh_decode_signature_func = document.getElementById("flashgot-media-parsed-refresh_signature_func");
+    this._clearMenu(document.getElementById("flashgot-media-parsed-menu").nextSibling);
+    this._clearMenu(mi_refresh_decode_signature_func.nextSibling);
+    this._clearMenu(menu_parsed_dash.firstChild);
+    menu_parsed.parentNode.setAttribute("hidden", "true");
+    menu_parsed_dash.parentNode.setAttribute("hidden", "true");
+    mi_refresh_decode_signature_func.setAttribute("hidden", "true");
     var m = this.media;
     if (!(m && m.length)) return false;
   
-    var mi;
+    // YouTube parsed streams. We'll sort them before building the menu.
+    var parsed_items = [], parsed_dash_items = [];
     for (var j = 0; j < m.length; j++) {
-      menu.appendChild(this._createMediaMenuItem(m[j]));
+      var mo = m[j];
+      // Special menu item, used for refreshing YouTube's signature decoding function.
+      // See |YOUTUBE_REFRESH_SIGNATURE_FUNC_URL| in MediaSniffer::observe().
+      if (mo.originalURL === "flashgot::Youtube::refresh_signature_func") {
+        var mi = mi_refresh_decode_signature_func;
+        mi.setAttribute("hidden", "false");
+        menu_parsed.parentNode.setAttribute("hidden", "false");
+        mi["flashgot::Youtube"] = mo.Youtube;
+        mi["flashgot::MediaSniffer"] = mo.MediaSniffer;
+        continue;
+      }
+      var mi = this._createMediaMenuItem(mo);
+      if (!mo.parsed) {
+        menu.appendChild(mi);
+        continue;
+      }
+      mi["flashgot::sort_key"] = mo.sort_key;
+      (mo.yt_dash ? parsed_dash_items : parsed_items).push(mi);
+    }
+    if (parsed_items.length || parsed_dash_items.length) {
+      function mo_cmp(lhs, rhs) { return lhs["flashgot::sort_key"] - rhs["flashgot::sort_key"]; }
+      if (parsed_items.length) {
+        parsed_items.sort(mo_cmp);
+        parsed_items.forEach(function(mi){delete mi["flashgot::sort_key"]; menu_parsed.appendChild(mi);});
+        menu_parsed.parentNode.setAttribute("hidden", "false");
+      }
+      if (parsed_dash_items.length) {
+        parsed_dash_items.sort(mo_cmp);
+        parsed_dash_items.forEach(function(mi){delete mi["flashgot::sort_key"]; menu_parsed_dash.appendChild(mi);});
+        menu_parsed_dash.parentNode.setAttribute("hidden", "false");
+      }
+      this._cb_mediaMenuItem_key_down = false;
+      // https://developer.mozilla.org/en-US/docs/XUL/PopupGuide/PopupKeys:
+      // A key listener added to a <menupopup> will not receive any key events.
+      // Instead, you must add a capturing key listener to the document or window
+      // if you want to listen for keys pressed within a menu.
+      window.addEventListener("keydown", this._cb_mediaMenuItem_keydown, true);
+      window.addEventListener("keyup", this._cb_mediaMenuItem_keyup, true);
     }
     return true;
   },
+  unprepareMediaMenu: function() {
+    this._cb_mediaMenuItem_key_down = false;
+    window.removeEventListener("keydown", this._cb_mediaMenuItem_keydown, true);
+    window.removeEventListener("keyup", this._cb_mediaMenuItem_keyup, true);
+  },
+  _clearMenu: function(from) {
+    if (!from) { return; }
+    var pn = from.parentNode;
+    while (from.nextSibling !== null) { pn.removeChild(from.nextSibling); }
+    pn.removeChild(from);
+  },
   _createMediaMenuItem: function(l) {
-    mi = document.createElement("menuitem");
-    mi.setAttribute("label", l.label);
+    var mi = document.createElement("menuitem");
+
+    // Hilight the currently playing stream.
+    var is_current = false;
+    if (content._flashgotMediaCurrentUrl) {
+      is_current = l.Youtube
+        ? l.Youtube.stream_url_equals(content._flashgotMediaCurrentUrl, l.originalURL)
+        : content._flashgotMediaCurrentUrl === l.originalURL;
+    }
+    if (is_current) { mi.setAttribute("default", "true"); }
+
+    if (l.fallback_href) { mi.setAttribute("flashgotMediaFallbackHref", l.fallback_href); }
+    var label = l.label;
+    if (l.seek_pos && gFlashGotService.getPref("media.YouTube.seek_pos.show", true)) {
+      label = "@" + this._formatMediaSeekPos(l.seek_pos) + " " + label;
+    }
+    mi.setAttribute("label", label);
     mi.setAttribute("tooltiptext", l.tip);
-    mi.addEventListener("command", function() { gFlashGot.downloadMedia([l]); }, false);
+    // YouTube: hold Shift to download/copy fallback URL if it exists,
+    // otherwise the "main" URL will be used.
+    mi.addEventListener("command", function(ev) {
+      var o = l;
+      if (ev.shiftKey && l.fallback_href) {
+        o = Object.create(l);
+        o.href = l.fallback_href;
+      }
+      gFlashGot.downloadMedia([o]);
+    }, false);
     mi.addEventListener("click", function(ev) {
       if (ev.button === 2) {
         Components.classes["@mozilla.org/widget/clipboardhelper;1"]
           .getService(Components.interfaces.nsIClipboardHelper)
-          .copyString(l.href);
+          .copyString(ev.shiftKey && l.fallback_href || l.href);
         ev.preventDefault();
       }
     }, true);
     return mi;
   },
-  
+  _cb_mediaMenuItem_key_down: false,
+  _cb_mediaMenuItem_keydown: function(ev) {
+    if (ev.keyCode !== 16 /*VK_SHIFT*/) { return; }
+    var This = gFlashGot;
+    if (This._cb_mediaMenuItem_key_down) { return; }
+    This._cb_mediaMenuItem_key_down = true;
+    var menu = document.getElementById("flashgot-media-parsed-popup");
+    var nl = menu.getElementsByTagName("menuitem");
+    for (var i = 0, len = nl.length; i !== len; ++i) {
+      var mi = nl[i];
+      mi.setAttribute("disabled", "" + !mi.hasAttribute("flashgotMediaFallbackHref"));
+    }
+  },
+  _cb_mediaMenuItem_keyup: function(ev) {
+    if (ev.keyCode !== 16 /*VK_SHIFT*/) { return; }
+    var This = gFlashGot;
+    if (!This._cb_mediaMenuItem_key_down) { return; }
+    This._cb_mediaMenuItem_key_down = false;
+    var menu = document.getElementById("flashgot-media-parsed-popup");
+    var nl = menu.getElementsByTagName("menuitem");
+    for (var i = 0, len = nl.length; i !== len; ++i) {
+      nl[i].setAttribute("disabled", "false");
+    }
+  },
+  _formatMediaSeekPos: function(ms) {
+    var h = Math.floor(ms / 1000 / 60 / 60);
+    var m = Math.floor((ms -= h * 60 * 60 * 1000) / 1000 / 60);
+    var s = Math.floor((ms -= m * 60 * 1000) / 1000);
+    ms -= s * 1000;
+    function strpad(str, pad_char, length) {
+      str = String(str);
+      var addon_len = length - str.length;
+      if (addon_len < 1) { return str; }
+      return new Array(addon_len + 1).join(pad_char) + str;
+    }
+    var rc;
+    // [h:m]m
+    if (gFlashGotService.getPref("media.YouTube.seek_pos.compact", true)) {
+      rc = "" + (h !== 0 ? h + ":" + strpad(m, "0", 2) : m);
+    }
+    // h:mm
+    else {
+      rc = "" + h + ":" + strpad(m, "0", 2);
+    }
+    // Seconds: ":ss".
+    rc += ":" + strpad(s, "0", 2);
+    // Milliseconds: ".SSS".
+    if (ms !== 0 && gFlashGotService.getPref("media.YouTube.seek_pos.show_ms", false)) {
+      rc += "." + strpad(ms, "0", 3);
+    }
+    return rc;
+  },
+  Youtube_refresh_signature: function(evt, elm) {
+    var win = document.commandDispatcher.focusedWindow;
+    elm['flashgot::Youtube'].refresh_signature_func(win, function(){elm['flashgot::MediaSniffer'].checkYoutube(win, null, true);}, true);
+    evt.preventDefault();
+    evt.stopPropagation();
+  },
 
   get srcWindow() {
     return document.commandDispatcher.focusedWindow;
@@ -1068,6 +1223,10 @@ var gFlashGot = {
   }
 ,
   downloadMedia: function(mediaLinks, dmName) {
+    if (gFlashGotService.getPref("media.autoCloseDocument", false)) {
+      var w = content;
+      w.setTimeout(function() { w.close() }, 500);
+    }
     var links = [];
     return this.addMediaLinks(links, mediaLinks) &&
       this.download(links, gFlashGotService.OP_SEL, dmName || gFlashGotService.getUPref("media.dm", ""));
diff --git a/chrome/flashgot.jar!/content/flashgot/flashgotOverlayFx.xul b/chrome/flashgot.jar!/content/flashgot/flashgotOverlayFx.xul
index a34b9c5..971f0ea 100644
--- a/chrome/flashgot.jar!/content/flashgot/flashgotOverlayFx.xul
+++ b/chrome/flashgot.jar!/content/flashgot/flashgotOverlayFx.xul
@@ -172,19 +172,30 @@
 
   <popupset id="mainPopupSet">
 
-		<menupopup id="flashgot-media-popup" onpopupshowing="return gFlashGot.prepareMediaMenu(this)">
-		 <menuitem id="flashgot-media-menuitem-opts"
-              label="&flashgotOptions;"
-              oncommand="gFlashGot.openOptionsDialog(3)"
-            />
-     <menuitem id="flashgot-media-clear"
-              label="&flashgotClear.label;"
-              accesskey="&flashgotClear.accesskey;"
-              oncommand="gFlashGot.clearMedia()"
-              />
-     <menuseparator id="flashgot-media-sep" />
-		</menupopup>
-	</popupset>
+    <menupopup id="flashgot-media-popup" onpopupshowing="return gFlashGot.prepareMediaMenu(this)" onpopuphiding="gFlashGot.unprepareMediaMenu();">
+      <menuitem id="flashgot-media-menuitem-opts"
+                label="&flashgotOptions;"
+                oncommand="gFlashGot.openOptionsDialog(3)"
+                />
+      <menuitem id="flashgot-media-clear"
+                label="&flashgotClear.label;"
+                accesskey="&flashgotClear.accesskey;"
+                oncommand="gFlashGot.clearMedia()"
+                />
+      <menuseparator id="flashgot-media-sep" />
+      <menu id="flashgot-media-parsed-menu" label="&flashgot.media.formats;">
+        <menupopup id="flashgot-media-parsed-popup">
+          <menu id="flashgot-media-parsed-dash-menu" label="&flashgot.media.formats.dash;">
+            <menupopup id="flashgot-media-parsed-dash-popup" />
+          </menu>
+          <menuitem id="flashgot-media-parsed-refresh_signature_func"
+                    label="&flashgot.media.refresh_signature_func.label;"
+                    tooltiptext="&flashgot.media.refresh_signature_func.tooltiptext;"
+                    oncommand="gFlashGot.Youtube_refresh_signature(event, this);" />
+        </menupopup>
+      </menu>
+    </menupopup>
+  </popupset>
 
   <popup id="contentAreaContextMenu">
     <menu id="flashgot-submenu" hidden="true" persist="hidden"
diff --git a/chrome/flashgot.jar!/content/flashgot/flashgotOverlayMoz.xul b/chrome/flashgot.jar!/content/flashgot/flashgotOverlayMoz.xul
index 0208e04..b46db14 100644
--- a/chrome/flashgot.jar!/content/flashgot/flashgotOverlayMoz.xul
+++ b/chrome/flashgot.jar!/content/flashgot/flashgotOverlayMoz.xul
@@ -265,14 +265,25 @@
         mousethrough="never"
     />
    
-   <menupopup id="flashgot-media-popup" onpopupshowing="return gFlashGot.prepareMediaMenu(this)">
-     <menuitem id="flashgot-media-clear"
-              label="&flashgotClear.label;"
-              accesskey="&flashgotClear.accesskey;"
-              oncommand="gFlashGot.clearMedia()"
-              />
-     <menuseparator id="flashgot-media-sep" />
-   </menupopup>
+    <menupopup id="flashgot-media-popup" onpopupshowing="return gFlashGot.prepareMediaMenu(this)" onpopuphiding="gFlashGot.unprepareMediaMenu();">
+      <menuitem id="flashgot-media-clear"
+                label="&flashgotClear.label;"
+                accesskey="&flashgotClear.accesskey;"
+                oncommand="gFlashGot.clearMedia()"
+                />
+      <menuseparator id="flashgot-media-sep" />
+      <menu id="flashgot-media-parsed-menu" label="&flashgot.media.formats;">
+        <menupopup id="flashgot-media-parsed-popup">
+          <menu id="flashgot-media-parsed-dash-menu" label="&flashgot.media.formats.dash;">
+            <menupopup id="flashgot-media-parsed-dash-popup" />
+          </menu>
+          <menuitem id="flashgot-media-parsed-refresh_signature_func"
+                    label="&flashgot.media.refresh_signature_func.label;"
+                    tooltiptext="&flashgot.media.refresh_signature_func.tooltiptext;"
+                    oncommand="gFlashGot.Youtube_refresh_signature(event, this);" />
+        </menupopup>
+      </menu>
+    </menupopup>
      
   </statusbar>
   
diff --git a/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.dtd
index 3336e15..967ec4e 100644
--- a/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Prosesseer skakels in die agtergrond">
 <!ENTITY flashgotShowLog "Vertoon log…">
 <!ENTITY flashgotClearLog "Vee Log uit">
-<!ENTITY flashgotAbout "Rakende FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Rakende FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Gaan Bevestigings Verby">
 <!ENTITY flashgotGetRightQuick "Gebruik togetright.exe wanneer moontlik">
 <!ENTITY flashgotAutostart "Outo-begin aflaai">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.properties
index ebe5e60..bc0d02b 100644
--- a/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/af-ZA/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.dtd
index 0b053e8..7365307 100644
--- a/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.dtd
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.properties
index 05ecf8c..27cad60 100644
--- a/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ar-SA/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.dtd
index 37d4057..4b75cf7 100644
--- a/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.dtd
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.properties
index f7e1888..f11d4ca 100644
--- a/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ar/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=رابد شير يطلب الانتظار %S ثوان ل
 alwaysAsk=دائماً طلب التأكيد
 media.defaultDM=الافتراضي (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.dtd
index e300120..796c3fc 100644
--- a/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Апрацоўваць спасылкі ў фоне">
 <!ENTITY flashgotShowLog "Паказаць лог">
 <!ENTITY flashgotClearLog "Ачысціць лог">
-<!ENTITY flashgotAbout "Аб FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Аб FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Прапускаць пацверджанні">
 <!ENTITY flashgotGetRightQuick "Выкарыстаць togetright.exe калі магчыма">
 <!ENTITY flashgotAutostart "Аўтаматычна стартаваць загрузкі">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.properties
index 76d0632..79077de 100644
--- a/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/be-BY/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.dtd
index 0f1d74b..4ded40b 100644
--- a/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Обработи линковете в заден план">
 <!ENTITY flashgotShowLog "Покажи Лог-а">
 <!ENTITY flashgotClearLog "Изчисти Лог-а">
-<!ENTITY flashgotAbout "За FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "За FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Пропусни потвърдителните прозорци">
 <!ENTITY flashgotGetRightQuick "Използвай togetright.exe когато е възможно">
 <!ENTITY flashgotAutostart "Автостарт на Даунлоадите">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.properties
index c07b5cf..6ddcbfc 100644
--- a/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/bg-BG/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.dtd
index 15b4d5a..a327618 100644
--- a/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.dtd
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.properties
index 1c118c0..a66d29d 100644
--- a/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/bn-BD/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.dtd
index 3a2d5b8..ce2e34d 100644
--- a/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log...">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.properties
index a8fd031..c84c9c5 100644
--- a/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/bn-IN/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.dtd
index ea1163b..2bd7eae 100644
--- a/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Processar enllaços en segon pla">
 <!ENTITY flashgotShowLog "Mostrar…">
 <!ENTITY flashgotClearLog "Netejar">
-<!ENTITY flashgotAbout "Sobre FlashGot 1.5.5.3…">
+<!ENTITY flashgotAbout "Sobre FlashGot 1.5.5.95…">
 <!ENTITY flashgotDMQuiet "Saltar avisos de confirmació">
 <!ENTITY flashgotGetRightQuick "Usar togetright.exe sempre que sigui possible">
 <!ENTITY flashgotAutostart "Iniciar descàrregues automàticament">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.properties
index e2de855..fafdd23 100644
--- a/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ca-AD/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare et demana esperar %S segons perquè no has ac
 alwaysAsk=Pregunta per confirmació
 media.defaultDM=Defecte (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.dtd
index 06b7192..5694f36 100644
--- a/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Zpracovávat odkazy na pozadí">
 <!ENTITY flashgotShowLog "Zobrazit záznam">
 <!ENTITY flashgotClearLog "Smazat záznam">
-<!ENTITY flashgotAbout "O rozšíření FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "O rozšíření FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Přeskočit dotazy s potvrzením">
 <!ENTITY flashgotGetRightQuick "Používat togetright.exe vždy, když je to možné">
 <!ENTITY flashgotAutostart "Automatické stahování">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.properties
index 7b8a600..009677a 100644
--- a/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/cs-CZ/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare vyžaduje čekání v délce %S sekund, jelik
 alwaysAsk=Vždy vyžadovat potvrzení
 media.defaultDM=Výchozí (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.dtd
index 5162c70..b2e63a1 100644
--- a/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Udfør links i baggrunden">
 <!ENTITY flashgotShowLog "Vis log…">
 <!ENTITY flashgotClearLog "Ryd log">
-<!ENTITY flashgotAbout "Om FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Om FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Spring (Confirmation Prompts) over">
 <!ENTITY flashgotGetRightQuick "Brug togetright.exe når det er muligt">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.properties
index 5478dd0..9b4cdf3 100644
--- a/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/da-DK/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/da/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/da/flashgot/flashgot.dtd
index bae94d8..8e76b12 100644
--- a/chrome/flashgot.jar!/locale/da/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/da/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Udfør links i baggrunden">
 <!ENTITY flashgotShowLog "Vis log">
 <!ENTITY flashgotClearLog "Ryd log">
-<!ENTITY flashgotAbout "Om FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Om FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Spring bekræftelser over">
 <!ENTITY flashgotGetRightQuick "Brug togetright.exe når det er muligt">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/da/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/da/flashgot/flashgot.properties
index 2c721ab..fd4107a 100644
--- a/chrome/flashgot.jar!/locale/da/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/da/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare beder dig vente %S sekunder, fordi du ikke er
 alwaysAsk=Spørg altid om bekræftelse
 media.defaultDM=Standard (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/de/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/de/flashgot/flashgot.dtd
index e5ae1dd..42da049 100644
--- a/chrome/flashgot.jar!/locale/de/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/de/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Links im Hintergrund verarbeiten">
 <!ENTITY flashgotShowLog "Protokoll anzeigen…">
 <!ENTITY flashgotClearLog "Protokoll löschen">
-<!ENTITY flashgotAbout "Über FlashGot 1.5.5.3…">
+<!ENTITY flashgotAbout "Über FlashGot 1.5.5.95…">
 <!ENTITY flashgotDMQuiet "Bestätigungsabfragen überspringen bei">
 <!ENTITY flashgotGetRightQuick "Wann immer möglich togetright.exe verwenden">
 <!ENTITY flashgotAutostart "Downloads automatisch starten">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/de/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/de/flashgot/flashgot.properties
index 013d1d1..70bc671 100644
--- a/chrome/flashgot.jar!/locale/de/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/de/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ alwaysAsk=Immer nach einer Bestätigung fragen
 ph.USERPASS=Benutzername:Passwort
 media.defaultDM=Standard (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.dtd
index 5473880..7fa5b8f 100644
--- a/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Διεργασία δεσμών στο παρασκήνιο">
 <!ENTITY flashgotShowLog "Εμφάνιση αρχείου καταγραφής">
 <!ENTITY flashgotClearLog "Εκκαθάριση αρχείου καταγραφής">
-<!ENTITY flashgotAbout "Περί FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Περί FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Παράκαμψη ειδοποιήσεων επιβεβαίωσης">
 <!ENTITY flashgotGetRightQuick "Χρήση togetright.exe όταν είναι δυνατόν">
 <!ENTITY flashgotAutostart "Αυτόματη εκκίνηση μεταφορτώσεων">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.properties
index a7525c2..63c4ed5 100644
--- a/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/el-GR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Το Rapidshare ζητά να περιμένετε %S δ
 alwaysAsk=Πάντα ερώτηση για επιβεβαίωση
 media.defaultDM=Προκαθορισμένο (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/el/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/el/flashgot/flashgot.dtd
index 23ccaa3..38507aa 100644
--- a/chrome/flashgot.jar!/locale/el/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/el/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Διεργασία δεσμών στο παρασκήνιο">
 <!ENTITY flashgotShowLog "Εμφάνιση αρχείου καταγραφής">
 <!ENTITY flashgotClearLog "Εκκαθάριση αρχείου καταγραφής">
-<!ENTITY flashgotAbout "Περί FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Περί FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Παράκαμψη ειδοποιήσεων επιβεβαίωσης">
 <!ENTITY flashgotGetRightQuick "Χρήση togetright.exe όταν είναι δυνατόν">
 <!ENTITY flashgotAutostart "Αυτόματη εκκίνηση μεταφορτώσεων">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/el/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/el/flashgot/flashgot.properties
index 14f9866..96ffb3f 100644
--- a/chrome/flashgot.jar!/locale/el/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/el/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Το Rapidshare ζητά να περιμένετε %S δ
 alwaysAsk=Πάντα ερώτηση για επιβεβαίωση
 media.defaultDM=Προκαθορισμένο (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.dtd
index 94ce37d..7f69030 100644
--- a/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log…">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.properties
index d55c85d..e7d1715 100644
--- a/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/en-US/flashgot/flashgot.properties
@@ -20,4 +20,5 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 \n\nAnswer "No" if you prefer your download manager to handle the raw links on its own.
 alwaysAsk=Always ask for confirmation
-media.defaultDM=Default (%S)
\ No newline at end of file
+media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
\ No newline at end of file
diff --git a/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.dtd
index faf1c12..5ec7498 100644
--- a/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Procesar enlaces en segundo plano">
 <!ENTITY flashgotShowLog "Mostrar historial de cambio…">
 <!ENTITY flashgotClearLog "Limpiar historial de cambios">
-<!ENTITY flashgotAbout "Acerca de FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Acerca de FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Omitir mensajes de confirmación">
 <!ENTITY flashgotGetRightQuick "Usar togetright.exe siempre que sea posible">
 <!ENTITY flashgotAutostart "Iniciar descargas automáticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.properties
index 48ab0ad..45fecfa 100644
--- a/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/es-AR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=RapidShare está pidiéndote que esperés %S porque no i
 alwaysAsk=Siempre pedir confirmación
 media.defaultDM=Predeterminado (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.dtd
index d46e58c..dd3bdd6 100644
--- a/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Procesar enlaces en segundo plano">
 <!ENTITY flashgotShowLog "Mostrar registro…">
 <!ENTITY flashgotClearLog "Limpiar registro">
-<!ENTITY flashgotAbout "Acerca de FlashGot 1.5.5.3…">
+<!ENTITY flashgotAbout "Acerca de FlashGot 1.5.5.95…">
 <!ENTITY flashgotDMQuiet "No mostrar mensajes de confirmación">
 <!ENTITY flashgotGetRightQuick "Usar togetright.exe siempre que sea posible">
 <!ENTITY flashgotAutostart "Iniciar descargas automáticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.properties
index d97b2d7..00cbc83 100644
--- a/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/es-CL/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare esta pidiendo que espere %S segundos porque n
 alwaysAsk=Siempre preguntar por confirmación
 media.defaultDM=Default(%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.dtd
index cfa73c7..15a1c1b 100644
--- a/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Procesar enlaces en segundo plano">
 <!ENTITY flashgotShowLog "Mostrar registro…">
 <!ENTITY flashgotClearLog "Limpiar registro">
-<!ENTITY flashgotAbout "Acerca de FlashGot 1.5.5.3…">
+<!ENTITY flashgotAbout "Acerca de FlashGot 1.5.5.95…">
 <!ENTITY flashgotDMQuiet "No mostrar mensajes de confirmación">
 <!ENTITY flashgotGetRightQuick "Usar togetright.exe siempre que sea posible">
 <!ENTITY flashgotAutostart "Iniciar descargas automáticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.properties
index 11cf9a1..082f47c 100644
--- a/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/es-ES/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare le está pidiendo que espere %S segundos porq
 alwaysAsk=Pedir siempre confirmación
 media.defaultDM=Predeterminado (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.dtd
index 1a570b7..2f8ee36 100644
--- a/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log...">
 <!ENTITY flashgotClearLog "Puhasta logi">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.properties
index 9333c84..cbea4db 100644
--- a/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/et-EE/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.ULIST=Viidete nimekiri
 rapidshareRetry.confirm=Rapidshare palub sul oodata %S sekundit, sest sa ei ole sisse logitud Rapid Pro kasutajana.\\nKas sa soovid, et FlashGot ootaks ja prooviks automaatselt seda faili alla laadida?
 alwaysAsk=Alati küsi kinnitust
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.dtd
index 9aa1816..5da2e91 100644
--- a/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log…">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.properties
index 91a29c2..f6e08a5 100644
--- a/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/eu-ES/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.dtd
index 9aa1816..5da2e91 100644
--- a/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log…">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.properties
index 91a29c2..f6e08a5 100644
--- a/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/eu/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.dtd
index 34dc90d..42ebe69 100644
--- a/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "انجام عملیات در پس زمینه">
 <!ENTITY flashgotShowLog "نمایش وقایع">
 <!ENTITY flashgotClearLog "پاک کردن وقایع">
-<!ENTITY flashgotAbout "درباره FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "درباره FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "عدم نمایش پیغامهای تایید">
 <!ENTITY flashgotGetRightQuick "استفاده شود togetright.exe در هر زمان ممکن از">
 <!ENTITY flashgotAutostart "شروع خودکار دریافتی‌ها">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.properties
index e358ca7..6fa1b9c 100644
--- a/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/fa-IR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.dtd
index be0d05b..e7434cf 100644
--- a/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Käsittele linkit tausta-ajona">
 <!ENTITY flashgotShowLog "Näytä loki…">
 <!ENTITY flashgotClearLog "Tyhjennä loki">
-<!ENTITY flashgotAbout "Tietoja FlashGot 1.5.5.3:sta">
+<!ENTITY flashgotAbout "Tietoja FlashGot 1.5.5.95:sta">
 <!ENTITY flashgotDMQuiet "Ohita varmennuskyselyt">
 <!ENTITY flashgotGetRightQuick "Käytä togetright.exe:ä aina kun mahdollista">
 <!ENTITY flashgotAutostart "Aloita tiedostojen siirto automaattisesti">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.properties
index 6030497..5fae792 100644
--- a/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/fi-FI/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.dtd
index be0d05b..e7434cf 100644
--- a/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Käsittele linkit tausta-ajona">
 <!ENTITY flashgotShowLog "Näytä loki…">
 <!ENTITY flashgotClearLog "Tyhjennä loki">
-<!ENTITY flashgotAbout "Tietoja FlashGot 1.5.5.3:sta">
+<!ENTITY flashgotAbout "Tietoja FlashGot 1.5.5.95:sta">
 <!ENTITY flashgotDMQuiet "Ohita varmennuskyselyt">
 <!ENTITY flashgotGetRightQuick "Käytä togetright.exe:ä aina kun mahdollista">
 <!ENTITY flashgotAutostart "Aloita tiedostojen siirto automaattisesti">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.properties
index 6030497..5fae792 100644
--- a/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/fi/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.dtd
index e4def9d..06e9117 100644
--- a/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.dtd
@@ -12,12 +12,12 @@
 <!ENTITY flashgotBuildGallery "Créer une galerie…">
 <!ENTITY flashgotBuildGallery.title "FlashGot - Créer une galerie">
 <!ENTITY flashgotGBVariableURLs "URL variables">
-<!ENTITY flashgotGBSample "Les chaînes de variables sont exprimées sous la forme [début-fin;pas] ou [nom_de_la_fonction(…)], par exemple :">
+<!ENTITY flashgotGBSample "Les chaines de variables sont exprimées sous la forme [début-fin;pas] ou [nom_de_la_fonction(…)], par exemple :">
 <!ENTITY flashgotGBPreview "Aperçu :">
 <!ENTITY flashgotGBContent "Contenu :">
 <!ENTITY flashgotGBReferrer "URL de référence :">
-<!ENTITY flashgotGBSync "Synchroniser les chaînes">
-<!ENTITY flashgotGBRanges "Chaînes">
+<!ENTITY flashgotGBSync "Synchroniser les chaines">
+<!ENTITY flashgotGBRanges "Chaines">
 <!ENTITY flashgotGBExpressions "Fonctions JavaScript">
 <!ENTITY flashgotGeneral "Général">
 <!ENTITY flashgotMenu "Menu">
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Traiter les liens en arrière-plan">
 <!ENTITY flashgotShowLog "Montrer le journal…">
 <!ENTITY flashgotClearLog "Effacer le journal">
-<!ENTITY flashgotAbout "À propos de FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "À propos de FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Ignorer la fenêtre de confirmation">
 <!ENTITY flashgotGetRightQuick "Utiliser togetright.exe quand c'est possible">
 <!ENTITY flashgotAutostart "Démarrer les téléchargements automatiquement">
@@ -54,7 +54,7 @@
 <!ENTITY flashgotDownloads "Téléchargements">
 <!ENTITY flashgotInterceptAll "Intercepter tous les téléchargements">
 <!ENTITY flashgotLog "Journal">
-<!ENTITY flashgotShowFilter "Montrer la boîte de dialogue des filtres">
+<!ENTITY flashgotShowFilter "Montrer la boite de dialogue des filtres">
 <!ENTITY flashgotFilter "Filtre">
 <!ENTITY flashgotHost "Hôte">
 <!ENTITY flashgotRegExp "Expression régulière (RegExp)">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choisir tous les articles par défaut">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Afficher le bouton de la barre d'outils">
+<!ENTITY flashgot.media.formats "Formats disponibles">
+<!ENTITY flashgot.media.refresh_signature_func.label "Actualiser la signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Tente d'actualiser la fonction de décodage de signature">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.properties
index afa7fbb..3c58308 100644
--- a/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/fr/flashgot/flashgot.properties
@@ -17,7 +17,7 @@ ph.FNAME=Nom de fichier proposé
 ph.ULIST=Liste d'URL
 ph.USERPASS=nomdutilisateur:motdepasse
 rapidshareRetry.confirm=Rapidshare vous demande de patienter %S secondes car vous n'êtes pas identifié comme un utilisateur Rapid Pro.\n Voulez-vous que Flashgot attende et réessaie à votre place ?\
-\n\nRépondre "Non" si vous préférez laisser votre gestionnaire de téléchargements gérer les liens bruts.
 alwaysAsk=Toujours demander la confirmation
 media.defaultDM=Défaut (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.dtd
index 9e7e22f..51cc9ca 100644
--- a/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Procesar as ligazóns en segundo plano">
 <!ENTITY flashgotShowLog "Amosar o rexistro…">
 <!ENTITY flashgotClearLog "Limpar o rexistro">
-<!ENTITY flashgotAbout "Sobre FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Sobre FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Non amosar avisos de confirmación">
 <!ENTITY flashgotGetRightQuick "Empregar togetright.exe sempre que sexa posible">
 <!ENTITY flashgotAutostart "Comezar automaticamente as descargas">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.properties
index 07aee73..a862747 100644
--- a/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/gl-ES/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare pide que espere %S segundos porque vostede no
 alwaysAsk=Sempre pedir a confirmación
 media.defaultDM=Predefinido (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.dtd
index df85732..205c1f4 100644
--- a/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "עבד קישורים ברקע">
 <!ENTITY flashgotShowLog "הראה תיעוד…">
 <!ENTITY flashgotClearLog "נקה תיעוד">
-<!ENTITY flashgotAbout "אודות FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "אודות FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "דלג על אימות Prompts">
 <!ENTITY flashgotGetRightQuick "השתמש בtogetright.exe כל עוד זה אפשרי">
 <!ENTITY flashgotAutostart "התחל הורדות באופן אוטומטי">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.properties
index 65e98fe..42842cb 100644
--- a/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/he-IL/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/he/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/he/flashgot/flashgot.dtd
index c730515..e17e81e 100644
--- a/chrome/flashgot.jar!/locale/he/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/he/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "תהליך עיבוד קישורים ברקע">
 <!ENTITY flashgotShowLog "הצג יומן רישום...">
 <!ENTITY flashgotClearLog "נקה את יומן הרישום">
-<!ENTITY flashgotAbout "אודות FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "אודות FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "דלג על בקשות אישור">
 <!ENTITY flashgotGetRightQuick "השתמש ב־ togetright.exe במידת האפשר">
 <!ENTITY flashgotAutostart "הפעלה עצמית של הורדות">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/he/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/he/flashgot/flashgot.properties
index 5bafe5d..858304b 100644
--- a/chrome/flashgot.jar!/locale/he/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/he/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare מבקש ממך להמתין %S שניות, 
 alwaysAsk=תמיד בקש אישור
 media.defaultDM=ברירת מחדל (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.dtd
index 0f53d91..bd9f4e9 100644
--- a/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log...">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.properties
index a8fd031..c84c9c5 100644
--- a/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/hi-IN/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.dtd
index 36015af..727795f 100644
--- a/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Obradi veze u pozadini">
 <!ENTITY flashgotShowLog "Prikaži zapis…">
 <!ENTITY flashgotClearLog "Očisti zapis">
-<!ENTITY flashgotAbout "O FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "O FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Preskoči obavijesti koje treba potvrđivati">
 <!ENTITY flashgotGetRightQuick "Koristi togetright.exe kad god je to moguće">
 <!ENTITY flashgotAutostart "Automatski pokreni preuzimanje">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.properties
index bb77454..4acbfd3 100644
--- a/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/hr-HR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.dtd
index 2e78bd2..a95fc92 100644
--- a/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Linkek feldolgozása a háttérben">
 <!ENTITY flashgotShowLog "Naplófájl olvasása">
 <!ENTITY flashgotClearLog "Naplófájl törlése">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3 névjegye">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95 névjegye">
 <!ENTITY flashgotDMQuiet "Párbeszédablakok átugrása">
 <!ENTITY flashgotGetRightQuick "A togetright.exe használata, ha lehetséges">
 <!ENTITY flashgotAutostart "Letöltések automatikus indítása">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.properties
index b13f769..a81a5a0 100644
--- a/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/hu/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=A Rapidshare kéri hogy várakozzon %S másodpercet, mer
 alwaysAsk=Mind kérjen megerősítést
 media.defaultDM=Alapértelmezett (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.dtd
index 3b0d254..e797335 100644
--- a/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log…">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.properties
index 1f7e8c4..cd50760 100644
--- a/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/hy-AM/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.dtd
index 9a4cfd3..89e2aef 100644
--- a/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Proses links di background">
 <!ENTITY flashgotShowLog "Tampilkan Log">
 <!ENTITY flashgotClearLog "Hapus Log">
-<!ENTITY flashgotAbout "Tentang FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Tentang FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Abaikan Dialog Konfirmasi">
 <!ENTITY flashgotGetRightQuick "Gunakan togetright.exe apabila dimungkinkan">
 <!ENTITY flashgotAutostart "Memulai download secara otomatis">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.properties
index 491429e..208feaa 100644
--- a/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/id-ID/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.dtd
index eae5264..aa2291f 100644
--- a/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Elabora i link in background">
 <!ENTITY flashgotShowLog "Mostra log">
 <!ENTITY flashgotClearLog "Cancella log">
-<!ENTITY flashgotAbout "Informazioni su FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Informazioni su FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Evita le finestre di conferma">
 <!ENTITY flashgotGetRightQuick "Usa togetright.exe quando è possibile">
 <!ENTITY flashgotAutostart "Inizia i download automaticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.properties
index 3e108a3..b737d37 100644
--- a/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/it-IT/flashgot/flashgot.properties
@@ -18,6 +18,6 @@ ph.UA=User agent
 wellget.mustBeSameDrive=Il percorso portabile di WellGet deve puntare un eseguibile posto\nnella stessa partizione del profilo portabile di Firefox (%S).
 dm.builtIn=(Incorporato nel browser)
 rapidshareRetry.confirm=Rapidshare chiede di attendere %S secondi perché non sei loggato come utente "Rapid Pro".\nVuoi che FlashGot attenda e riprovi automaticamente al posto tuo?\
-\n\nRispondi "No" se preferisci mandare i link al download manager così come sono.
 alwaysAsk=Chiedi sempre conferma
-media.defaultDM=Default (%S)
\ No newline at end of file
+media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/it/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/it/flashgot/flashgot.dtd
index eae5264..aa2291f 100644
--- a/chrome/flashgot.jar!/locale/it/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/it/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Elabora i link in background">
 <!ENTITY flashgotShowLog "Mostra log">
 <!ENTITY flashgotClearLog "Cancella log">
-<!ENTITY flashgotAbout "Informazioni su FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Informazioni su FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Evita le finestre di conferma">
 <!ENTITY flashgotGetRightQuick "Usa togetright.exe quando è possibile">
 <!ENTITY flashgotAutostart "Inizia i download automaticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/it/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/it/flashgot/flashgot.properties
index 1d8816a..d98ca73 100644
--- a/chrome/flashgot.jar!/locale/it/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/it/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.ULIST=URL list
 ph.USERPASS=username:password
 ph.UA=User agent
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.dtd
index f342efc..dbd6b47 100644
--- a/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "バックグラウンドで処理">
 <!ENTITY flashgotShowLog "ログを表示">
 <!ENTITY flashgotClearLog "ログをクリア">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3 について">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95 について">
 <!ENTITY flashgotDMQuiet "確認画面をスキップ">
 <!ENTITY flashgotGetRightQuick "可能であれば togetright.exe を使用">
 <!ENTITY flashgotAutostart "ダウンロードを自動で開始する">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.properties
index a89e0c9..fe54acc 100644
--- a/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ja-JP/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapid Pro でログインしていないので Rapidshar
 alwaysAsk=常に確認する
 media.defaultDM=デフォルト(%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.dtd
index 00e0890..6a6c912 100644
--- a/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "ლინკების შესრულება უკანა ფონზე">
 <!ENTITY flashgotShowLog "ლოგის ნახვა…">
 <!ENTITY flashgotClearLog "ლოგის გასუფთავება">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3_ის შესახებ">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95_ის შესახებ">
 <!ENTITY flashgotDMQuiet "დამოწმების გამოტოვება">
 <!ENTITY flashgotGetRightQuick "გამოიყენე togetright.exe როცა შესაძლებელია">
 <!ENTITY flashgotAutostart "გადმოწერის ავტომატურად დაწყება">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.properties
index a8fd031..c84c9c5 100644
--- a/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ka-GE/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.dtd
index 018692e..3f2d52f 100644
--- a/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Сілтемелерді білдіртпей-ақ өңдеу">
 <!ENTITY flashgotShowLog "Лог көрсету…">
 <!ENTITY flashgotClearLog "Логты тазалау">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3 туралы">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95 туралы">
 <!ENTITY flashgotDMQuiet "Растаулар сұранымдарын өткізіп жіберу">
 <!ENTITY flashgotGetRightQuick "Мүмкін болса togetright.exe қолдану">
 <!ENTITY flashgotAutostart "Жүктемелерді автоматты түрде бастау">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.properties
index 0b545f2..1adc46b 100644
--- a/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/kk-KZ/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare сізді %S секунд күтуді сұ
 alwaysAsk=Әрқашан растауды сұрау
 media.defaultDM=Бастапқы (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.dtd
index 0f53d91..bd9f4e9 100644
--- a/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log...">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.properties
index a8fd031..c84c9c5 100644
--- a/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/km-KH/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.dtd
index 50710c1..29b93c8 100644
--- a/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.dtd
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.properties
index d80cf7e..64be71e 100644
--- a/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ko-KR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapid Pro 사용자로 로그인 하지 않았기 때문
 alwaysAsk=항상 확인 요구
 media.defaultDM=기본값 (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.dtd
index 39caaff..fb4c674 100644
--- a/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log...">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.properties
index a8fd031..c84c9c5 100644
--- a/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/lt-LT/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.dtd
index c1e3e65..772ebec 100644
--- a/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Обработи ги врските во позадина">
 <!ENTITY flashgotShowLog "Покажи го Дневникот…">
 <!ENTITY flashgotClearLog "Исчисти го Дневникот">
-<!ENTITY flashgotAbout "За FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "За FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Прескокни ги Потврдните Прашалници">
 <!ENTITY flashgotGetRightQuick "Користи togetright.exe секогаш кога е возможно">
 <!ENTITY flashgotAutostart "Автоматски стартувај ги симнувањата">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.properties
index a019267..c05a619 100644
--- a/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/mk-MK/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ media.defaultDM=Стандардно(%S)
 ph.FNAME=Препорачано име на датотеката
 rapidshareRetry.confirm=Rapidshare бара од вас да чекате %S секунди бидејќи вие не сте најавени како Rapid Pro корисник.\nДали сакате FlashGot да чека и да се обиде повторно автоматски за вас?\
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.dtd
index f062192..8fec284 100644
--- a/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Process links in background">
 <!ENTITY flashgotShowLog "Show Log...">
 <!ENTITY flashgotClearLog "Clear Log">
-<!ENTITY flashgotAbout "About FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "About FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Skip Confirmation Prompts">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.properties
index 83ef9cf..f43e2f2 100644
--- a/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ml-IN/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.dtd
index 05fff71..a375159 100644
--- a/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Холбоосуудыг ар талд ажиллуулах">
 <!ENTITY flashgotShowLog "Бүртгэл харах…">
 <!ENTITY flashgotClearLog "Бүртгэл цэвэрлэх">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3-ын тухай">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95-ын тухай">
 <!ENTITY flashgotDMQuiet "Баталгаажуулах асуултыг алгасах">
 <!ENTITY flashgotGetRightQuick "Энэ нь боломжтой бол хэдийд ч togetright.exe хэрэглэх">
 <!ENTITY flashgotAutostart "Татцыг шууд эхлэх">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.properties
index 7321887..6227cde 100644
--- a/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/mn-MN/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.dtd
index 9b2a8ae..874e2d5 100644
--- a/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Proses rangkaian di latarbelakang">
 <!ENTITY flashgotShowLog "Papar Log…">
 <!ENTITY flashgotClearLog "Padam Log">
-<!ENTITY flashgotAbout "Tentang FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Tentang FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Jangkau Prom Pengesahan">
 <!ENTITY flashgotGetRightQuick "Guna togetright.exe seboleh mungkin">
 <!ENTITY flashgotAutostart "Auto-mula Muat Turun">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.properties
index 63785e7..f579dcc 100644
--- a/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ms-MY/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.dtd
index 98383d1..fe727f5 100644
--- a/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Åpne lenker i bakgrunnen">
 <!ENTITY flashgotShowLog "Vis logg">
 <!ENTITY flashgotClearLog "Tøm logg">
-<!ENTITY flashgotAbout "Om FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Om FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Hopp over bekreftelser">
 <!ENTITY flashgotGetRightQuick "Use togetright.exe whenever it is possible">
 <!ENTITY flashgotAutostart "Autostart downloads">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.properties
index a8fd031..c84c9c5 100644
--- a/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/nb-NO/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.dtd
index 8c048a2..79fe76c 100644
--- a/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Koppelingen op de achtergrond verwerken">
 <!ENTITY flashgotShowLog "Log weergeven…">
 <!ENTITY flashgotClearLog "Log wissen">
-<!ENTITY flashgotAbout "Over FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Over FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Vragen om een bevestiging overslaan">
 <!ENTITY flashgotGetRightQuick "Gebruik togetright.exe wanneer mogelijk">
 <!ENTITY flashgotAutostart "Downloads automatisch starten">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.properties
index 1b5a5dd..cddd7f7 100644
--- a/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/nl/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare wil je %S seconden laten wachten, aangezien j
 alwaysAsk=Altijd om een bevestiging vragen
 media.defaultDM=Standaard (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/pl/flashgot/about.properties b/chrome/flashgot.jar!/locale/pl/flashgot/about.properties
index e6d2bdc..1ecf02e 100644
--- a/chrome/flashgot.jar!/locale/pl/flashgot/about.properties
+++ b/chrome/flashgot.jar!/locale/pl/flashgot/about.properties
@@ -1,7 +1,7 @@
 extensions.{19503e42-ca3c-4c27-b1e2-9cdb2170ee34}.description=Umożliwia ściąganie pojedynczych i wielu plików za pomocą najbardziej popularnych menedżerów pobierających dla systemów Windows, Mac OS X, Linux oraz FreeBSD. Oferuje również możliwość zbudowania galerii z wielu rozrzuconych w serwisie pojedynczych stron.
 aboutTitle=O %S
 extensionContributors=Współtwórcy
-extensionContributors.tip=Ludzie, którym należą się podziękowania za stworzenie tego rozszerzenia
+extensionContributors.tip=Osoby, którym należą się podziękowania za stworzenie tego rozszerzenia
 extensionCreatorLabel=Autor
 changelog=Lista zmian
 changelog.tip=Zobacz listę zmian
diff --git a/chrome/flashgot.jar!/locale/pl/flashgot/contents.rdf b/chrome/flashgot.jar!/locale/pl/flashgot/contents.rdf
index b6a8f18..693aa14 100644
--- a/chrome/flashgot.jar!/locale/pl/flashgot/contents.rdf
+++ b/chrome/flashgot.jar!/locale/pl/flashgot/contents.rdf
@@ -2,12 +2,12 @@
 <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
          xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
     <RDF:Seq about="urn:mozilla:locale:root">
-        <RDF:li resource="urn:mozilla:locale:pl-PL"/>
+        <RDF:li resource="urn:mozilla:locale:pl"/>
     </RDF:Seq>
-    <RDF:Description about="urn:mozilla:locale:pl-PL" chrome:name="pl-PL" >
+    <RDF:Description about="urn:mozilla:locale:pl" chrome:name="pl" >
         <chrome:packages>
-            <RDF:Seq about="urn:mozilla:locale:pl-PL:packages">
-                <RDF:li resource="urn:mozilla:locale:pl-PL:flashgot"/>
+            <RDF:Seq about="urn:mozilla:locale:pl:packages">
+                <RDF:li resource="urn:mozilla:locale:pl:flashgot"/>
             </RDF:Seq>
         </chrome:packages>
     </RDF:Description>
diff --git a/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.dtd
index d693dac..572d2ae 100644
--- a/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Przetwarzaj odnośniki w tle">
 <!ENTITY flashgotShowLog "Pokaż rejestr…">
 <!ENTITY flashgotClearLog "Wyczyść rejestr">
-<!ENTITY flashgotAbout "O FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "O FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Nie wymagaj potwierdzeń">
 <!ENTITY flashgotGetRightQuick "Użyj togetright.exe, jeśli to możliwe">
 <!ENTITY flashgotAutostart "Automatycznie rozpocznij pobieranie">
@@ -72,7 +72,7 @@
 <!ENTITY flashgotPlaceHolders "Zmienne predefiniowane">
 <!ENTITY flashgotQuoteWarn1 "Nie możesz używać cudzysłowów w szablonie argumentów.">
 <!ENTITY flashgotQuoteWarn2 "Jeżeli ich potrzebujesz, możesz napisać skrypt wsadowy.">
-<!ENTITY flashgotBadInstall "Jeden z kluczowych komponentów FlashGot jest niezainstalowany lub uszkodzony. Ponowna instalacja rozszerzenia powinna rozwiązać ten problem.">
+<!ENTITY flashgotBadInstall "Jeden z kluczowych komponentów FlashGot nie jest zainstalowany lub uszkodzony. Ponowna instalacja rozszerzenia powinna rozwiązać ten problem.">
 <!ENTITY flashgotWellGetPath "Ścieżka do WellGeta:">
 <!ENTITY flashgotExtFilter "Zastosuj filtr rozszerzeń plików również do pobrań wsadowych">
 <!ENTITY flashgotHTTPAuth "Autentykacja HTTP">
@@ -91,12 +91,16 @@
 <!ENTITY flashgotBrowse.accesskey "b">
 <!ENTITY flashgotSelAll.accesskey "a">
 <!ENTITY flashgotSelInv.accesskey "I">
-<!ENTITY flashgotURL "Address">
-<!ENTITY flashgotFileName "Name">
-<!ENTITY flashgotFileType "Type">
-<!ENTITY flashgotDestinationFolder "Destination folder">
+<!ENTITY flashgotURL "Adres">
+<!ENTITY flashgotFileName "Nazwa">
+<!ENTITY flashgotFileType "Typ">
+<!ENTITY flashgotDestinationFolder "Folder docelowy">
 <!ENTITY flashgotDestinationFolder.accesskey "d">
 <!ENTITY flashgotFilter.accesskey "f">
-<!ENTITY flashgotAllChoosen "Choose all the items by default">
-<!ENTITY flashgotAllChoosen.accesskey "c">
-<!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgotAllChoosen "Domyślnie wybierz wszystkie elementy">
+<!ENTITY flashgotAllChoosen.accesskey "s">
+<!ENTITY flashgotShowToolbarButton "Pokaż przycisk narzędziowy">
+<!ENTITY flashgot.media.formats "Dostępne formaty">
+<!ENTITY flashgot.media.refresh_signature_func.label "Odśwież ssygnsturę">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Próba odświeżenia funkcji dekodowania sygnatury">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.properties
index d27baaa..8726389 100644
--- a/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/pl/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare wymaga odczekania %S sekund, ponieważ nie je
 alwaysAsk=Zawsze pytaj o potwierdzenie
 media.defaultDM=Domyślny (%S)
 ph.UA=User agent
+cannotWriteFile=Nieodwracalny błąd! Pliku:\n%S\nnie można zapisać!
diff --git a/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.dtd
index 9001b3a..42dc2fd 100644
--- a/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Processar links em segundo plano">
 <!ENTITY flashgotShowLog "Exibir log…">
 <!ENTITY flashgotClearLog "Limpar log">
-<!ENTITY flashgotAbout "Sobre o FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Sobre o FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Executar sem confirmações">
 <!ENTITY flashgotGetRightQuick "Usar togetright.exe sempre que possível">
 <!ENTITY flashgotAutostart "Iniciar downloads automaticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.properties
index 380430b..afd866a 100644
--- a/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/pt-BR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=O Rapidshare está pedindo que você aguarde %S segundos
 alwaysAsk=Sempre pedir confirmação
 media.defaultDM=Padrão (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.dtd
index 1b2b26d..f6cd382 100644
--- a/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Processar links em segundo plano">
 <!ENTITY flashgotShowLog "Exibir Log…">
 <!ENTITY flashgotClearLog "Limpar Log">
-<!ENTITY flashgotAbout "Sobre o FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Sobre o FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Executar Sem Confimações">
 <!ENTITY flashgotGetRightQuick "Usar togetright.exe sempre que possível">
 <!ENTITY flashgotAutostart "Iniciar downloads automaticamente">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.properties
index 4641971..24699c1 100644
--- a/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/pt-PT/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=O Rapidshare está a pedir para aguardar %S segundos por
 alwaysAsk=Pedir sempre confirmação
 media.defaultDM=Pré-definido (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.dtd
index e9dc9ad..c8d85b2 100644
--- a/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Proceseaza link-urile in fundal">
 <!ENTITY flashgotShowLog "Arata log-ul">
 <!ENTITY flashgotClearLog "Sterge log-ul">
-<!ENTITY flashgotAbout "Despre FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Despre FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Sari peste ferestrele de confimare">
 <!ENTITY flashgotGetRightQuick "Foloseste togetright.exe cand e posibil">
 <!ENTITY flashgotAutostart "Autostart descarcari">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.properties
index 099bd79..f353b5e 100644
--- a/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ro-RO/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.dtd
index 3dd399b..4e12fe5 100644
--- a/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Обрабатывать ссылки в фоне">
 <!ENTITY flashgotShowLog "Показать журнал">
 <!ENTITY flashgotClearLog "Очистить журнал">
-<!ENTITY flashgotAbout "О FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "О FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Пропускать подтверждения">
 <!ENTITY flashgotGetRightQuick "Использовать togetright.exe, если возможно">
 <!ENTITY flashgotAutostart "Автоматически стартовать закачки">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.properties
index bff11ab..442d17e 100644
--- a/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/ru/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare просит подождать %S секун
 alwaysAsk=Всегда спрашивать подтверждение
 media.defaultDM=По умолчанию (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.dtd
index da3424c..738632c 100644
--- a/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Spracovávať odkazy na pozadí">
 <!ENTITY flashgotShowLog "Zobraziť záznam">
 <!ENTITY flashgotClearLog "Odstrániť záznam">
-<!ENTITY flashgotAbout "Čo je rozšírenie FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Čo je rozšírenie FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Preskočiť okná s potvrdením">
 <!ENTITY flashgotGetRightQuick "Použiť togetright.exe vždy keď je to možné">
 <!ENTITY flashgotAutostart "Automaticky spustiť sťahovanie">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.properties
index 14e828a..9216a3d 100644
--- a/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/sk-SK/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Pretože nie ste prihlásený ako používateľ Rapid Pr
 alwaysAsk=Vždy vyžiadať potvrdenie
 media.defaultDM=Predvolené (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.dtd
index 2804a22..58b6b4d 100644
--- a/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Predeluj povezave v ozadju">
 <!ENTITY flashgotShowLog "Pokaži dnevnik …">
 <!ENTITY flashgotClearLog "Počisti dnevnik">
-<!ENTITY flashgotAbout "O razširitvi FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "O razširitvi FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Preskoči potrditvena vprašanja">
 <!ENTITY flashgotGetRightQuick "Uporabi togetright.exe, ko je to mogoče">
 <!ENTITY flashgotAutostart "Samozaženi prenose">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.properties
index 5931db0..d71ae1c 100644
--- a/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/sl-SI/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare zahteva, da počakate %S sekund, ker niste pr
 alwaysAsk=Vedno zahtevaj potrditev
 media.defaultDM=Privzeto (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.dtd
index 4fc032c..1b63fe1 100644
--- a/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Proceso linket në sfond">
 <!ENTITY flashgotShowLog "Trego">
 <!ENTITY flashgotClearLog "Pastro">
-<!ENTITY flashgotAbout "Informacion mbi FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Informacion mbi FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Kapërceji Nxitjet për Konfirmim">
 <!ENTITY flashgotGetRightQuick "Përdore togetright.exe sa herë të jetë e mundur">
 <!ENTITY flashgotAutostart "Vetënisi shkarkimet">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.properties
index ecee8ad..f9e3d46 100644
--- a/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/sq-AL/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.dtd
index 1e7d594..2016b9c 100644
--- a/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Обради везе у позадини">
 <!ENTITY flashgotShowLog "Прикажи журнал…">
 <!ENTITY flashgotClearLog "Очисти журнал">
-<!ENTITY flashgotAbout "О FlashGot 1.5.5.3-у">
+<!ENTITY flashgotAbout "О FlashGot 1.5.5.95-у">
 <!ENTITY flashgotDMQuiet "Прескочи упите потврда">
 <!ENTITY flashgotGetRightQuick "Користи togetright.exe увек кад је то могуће">
 <!ENTITY flashgotAutostart "Самопокрени преузимања">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.properties
index 2f9f457..1fdfe12 100644
--- a/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/sr/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare тражи да сачекате %S секу
 alwaysAsk=Увек питај за потврду
 media.defaultDM=Подразумевано (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.dtd
index 5546161..daba9ee 100644
--- a/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Bearbeta länkar i bakgrunden">
 <!ENTITY flashgotShowLog "Visa logg…">
 <!ENTITY flashgotClearLog "Rensa logg">
-<!ENTITY flashgotAbout "Om FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Om FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Hoppa över bekräftelseförfrågningar">
 <!ENTITY flashgotGetRightQuick "Använd togetright.exe när det är möjligt">
 <!ENTITY flashgotAutostart "Starta nedladdningar automatiskt">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.properties
index 338bc72..eb4ab9a 100644
--- a/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/sv-SE/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.dtd
index 853055c..be4bd28 100644
--- a/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.dtd
@@ -33,7 +33,7 @@
 <!ENTITY flashgotBGProcessing "ประมวลผลลิงค์แบบ Background">
 <!ENTITY flashgotShowLog "แสดงล็อก">
 <!ENTITY flashgotClearLog "ล้างล็อก">
-<!ENTITY flashgotAbout "เกี่ยวกับ FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "เกี่ยวกับ FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "ข้ามขั้นตอนการยืนยัน">
 <!ENTITY flashgotGetRightQuick "ใช้ togetright.exe เมื่อเป็นไปได้">
 <!ENTITY flashgotAutostart "เริ่มดาวน์โหลดอัตโนมัติ">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.properties
index 2d43cdf..ea7ea4d 100644
--- a/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/th-TH/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/th/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/th/flashgot/flashgot.dtd
index 853055c..be4bd28 100644
--- a/chrome/flashgot.jar!/locale/th/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/th/flashgot/flashgot.dtd
@@ -33,7 +33,7 @@
 <!ENTITY flashgotBGProcessing "ประมวลผลลิงค์แบบ Background">
 <!ENTITY flashgotShowLog "แสดงล็อก">
 <!ENTITY flashgotClearLog "ล้างล็อก">
-<!ENTITY flashgotAbout "เกี่ยวกับ FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "เกี่ยวกับ FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "ข้ามขั้นตอนการยืนยัน">
 <!ENTITY flashgotGetRightQuick "ใช้ togetright.exe เมื่อเป็นไปได้">
 <!ENTITY flashgotAutostart "เริ่มดาวน์โหลดอัตโนมัติ">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/th/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/th/flashgot/flashgot.properties
index 2d43cdf..ea7ea4d 100644
--- a/chrome/flashgot.jar!/locale/th/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/th/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ dm.builtIn=(Browser Built In)
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.dtd
index 2c76a55..92bce68 100644
--- a/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Bağlantıyı arkaplanda işle">
 <!ENTITY flashgotShowLog "Kayıtları Göster…">
 <!ENTITY flashgotClearLog "Kayıtları Temizle">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3 Hakkında">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95 Hakkında">
 <!ENTITY flashgotDMQuiet "Onaylama sorgularını atla">
 <!ENTITY flashgotGetRightQuick "Münkün olduğunda togetright.exe dosyasını kullan">
 <!ENTITY flashgotAutostart "İndirmeleri Otomatik Başlat">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.properties
index 4db37d5..2c28552 100644
--- a/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/tr-TR/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.dtd
index 9f55b85..2394d2b 100644
--- a/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Bağlantıyı arkaplanda işle">
 <!ENTITY flashgotShowLog "Kayıtları Göster">
 <!ENTITY flashgotClearLog "Kayıtları Temizle">
-<!ENTITY flashgotAbout "FlashGot 1.5.5.3 Hakkında">
+<!ENTITY flashgotAbout "FlashGot 1.5.5.95 Hakkında">
 <!ENTITY flashgotDMQuiet "Onaylama sorgularını atla">
 <!ENTITY flashgotGetRightQuick "Münkün olduğunda togetright.exe dosyasını kullan">
 <!ENTITY flashgotAutostart "İndirmeleri Otomatik Başlat">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.properties
index 1cc9968..07a350d 100644
--- a/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/tr/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=Rapidshare Pro kullanıcı olarak giriş yapmadığını
 alwaysAsk=Her zaman sor
 media.defaultDM=Varsayılan (%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.dtd
index d9cf804..eda78a7 100644
--- a/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Обробляти посилання у фоновому режимі">
 <!ENTITY flashgotShowLog "Показати журнал…">
 <!ENTITY flashgotClearLog "Очистити журнал">
-<!ENTITY flashgotAbout "Про FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Про FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Пропускати підтвердження">
 <!ENTITY flashgotGetRightQuick "Використовувати togetright.exe коли це можливо">
 <!ENTITY flashgotAutostart "Автоматично починати завантаження">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.properties
index 9c1b877..dd8a807 100644
--- a/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/uk-UA/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.dtd
index 9c8b5af..e42776f 100644
--- a/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Обробляти посилання у фоновому режимі">
 <!ENTITY flashgotShowLog "Показати журнал…">
 <!ENTITY flashgotClearLog "Очистити журнал">
-<!ENTITY flashgotAbout "Про FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Про FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Пропускати підтвердження">
 <!ENTITY flashgotGetRightQuick "Використовувати togetright.exe коли це можливо">
 <!ENTITY flashgotAutostart "Автоматично починати завантаження">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.properties
index 9c1b877..dd8a807 100644
--- a/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/uk/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.dtd
index 74daf2c..af8bdf6 100644
--- a/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "Xử lí các liên kết thuộc hậu cảnh">
 <!ENTITY flashgotShowLog "Hiện lưu kí…">
 <!ENTITY flashgotClearLog "Xóa lưu kí">
-<!ENTITY flashgotAbout "Thông tin về FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "Thông tin về FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "Bỏ qua Hộp thoại Xác nhận">
 <!ENTITY flashgotGetRightQuick "Sử dụng togetright.exe bất cứ khi nào có thể">
 <!ENTITY flashgotAutostart "Tự động khởi chạy các tập tin tải xuống">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.properties
index db201b6..37107b4 100644
--- a/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/vi/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.dtd
index a617c33..73b450a 100644
--- a/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "在后台处理链接">
 <!ENTITY flashgotShowLog "显示日志">
 <!ENTITY flashgotClearLog "清空日志">
-<!ENTITY flashgotAbout "关于 FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "关于 FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "忽略确认提示">
 <!ENTITY flashgotGetRightQuick "尽可能使用“togetrght.exe”">
 <!ENTITY flashgotAutostart "自动下载已监视的文件">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.properties
index aa0f683..f2e6c09 100644
--- a/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/zh-CN/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ rapidshareRetry.confirm=因为你尚未登录Rapidshare,请你等待%S秒。\n
 alwaysAsk=始终要求确认
 media.defaultDM=默认(%S)
 ph.UA=User agent
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.dtd b/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.dtd
index 00005ed..d4ad9fb 100644
--- a/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.dtd
+++ b/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.dtd
@@ -35,7 +35,7 @@
 <!ENTITY flashgotBGProcessing "在背景處理鏈結">
 <!ENTITY flashgotShowLog "顯示日誌">
 <!ENTITY flashgotClearLog "清除日誌">
-<!ENTITY flashgotAbout "關於 FlashGot 1.5.5.3">
+<!ENTITY flashgotAbout "關於 FlashGot 1.5.5.95">
 <!ENTITY flashgotDMQuiet "略過確認提示">
 <!ENTITY flashgotGetRightQuick "儘可能使用 togetright.exe">
 <!ENTITY flashgotAutostart "自動下載受監視的檔案類型">
@@ -100,3 +100,7 @@
 <!ENTITY flashgotAllChoosen "Choose all the items by default">
 <!ENTITY flashgotAllChoosen.accesskey "c">
 <!ENTITY flashgotShowToolbarButton "Show toolbar button">
+<!ENTITY flashgot.media.formats "Available formats">
+<!ENTITY flashgot.media.refresh_signature_func.label "Refresh signature">
+<!ENTITY flashgot.media.refresh_signature_func.tooltiptext "Try to refresh the signature decoding function">
+<!ENTITY flashgot.media.formats.dash "DASH (separate audio and video tracks)">
diff --git a/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.properties b/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.properties
index 095259d..72ddbab 100644
--- a/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.properties
+++ b/chrome/flashgot.jar!/locale/zh-TW/flashgot/flashgot.properties
@@ -20,3 +20,4 @@ ph.UA=User agent
 rapidshareRetry.confirm=Rapidshare is asking you to wait %S seconds because you're not logged in as a Rapid Pro user.\nDo you want FlashGot to wait and retry automatically for you?\
 alwaysAsk=Always ask for confirmation
 media.defaultDM=Default (%S)
+cannotWriteFile=Unrecoverable error: file\n%S\ncannot be written!
diff --git a/components/flashgotService.js b/components/flashgotService.js
index 5eaae02..312ec28 100644
--- a/components/flashgotService.js
+++ b/components/flashgotService.js
@@ -28,7 +28,7 @@ const NS_BINDING_ABORTED = 0x804b0002;
 const EXTENSION_ID = "{19503e42-ca3c-4c27-b1e2-9cdb2170ee34}";
 const EXTENSION_NAME = "FlashGot";
 const CHROME_NAME = "flashgot";
-const VERSION = "1.5.5.3";
+const VERSION = "1.5.5.95";
 const SERVICE_NAME = EXTENSION_NAME + " Service";
 const SERVICE_CTRID = "@maone.net/flashgot-service;1";
 const SERVICE_ID = "{2a55fc5c-7b31-4ee1-ab15-5ee2eb428cbe}";
@@ -434,7 +434,12 @@ fg = {
     if (!overwrite || file.exists() && file.isDirectory()) {
       for (;;) {
         if(!file.exists()) {
-          file.create(0, B8('644'));
+          try {
+            file.create(0, B8('644'));
+          } catch (e) {
+            this.showFileWriteError(file, e);
+            throw e;
+          }
           break;
         } else { // rename
           var m = file.leafName.match(/(.*?)(?:\((\d+)\))?(\.[^\.]+$|$)/);
@@ -445,6 +450,12 @@ fg = {
     return file;
   }
 ,
+  showFileWriteError: function(file, e) {
+    CC["@mozilla.org/embedcomp/prompt-service;1"].getService(CI.nsIPromptService)
+              .alert(null, "FlashGot", this.getString("cannotWriteFile", [file.path]));
+    this.log("ERROR: " + file.path + " cannot be written - " + (e || " unspecificed error"));
+  }
+,
   download: function(links, opType, dmName) {
     
     switch (links.length) {
@@ -490,13 +501,6 @@ fg = {
   },
   
   _downloadDelayed: function(links, opType, dm) {
-    
-     if (!links.postData) { 
-      links.postData = null;
-    } else if(!dm.postSupport) {
-      // surrogate POST parameters as query string
-      links[0].href += (links[0].href.indexOf("?") > -1 ?  "&" : "?") + links.postData;
-    }
 
     const encodedURLs = this.getPref(dm.getPref("encode"), this.getPref("encode", true));
 
@@ -544,9 +548,15 @@ fg = {
     var cs = links.document && links.document.characterSet || null;
     
     var j, l, href, ol, pos1, pos2;
+    var postData;
     for (j = 0; j < len; j++) {
       l = links[j];
-      
+      postData =  l.postData || links.postData;
+      if (postData && !dm.postSupport) {
+        // surrogate POST parameters as query string
+        l.href += (l.href.indexOf("?") > -1 ?  "&" : "?") + postData;
+      }
+
       href = l.href;
       
       if (/^javascript:/i.test(href)) {
@@ -561,7 +571,7 @@ fg = {
       if (filters && !filters.doFilter(href)) continue;
       
       if (l.description) l.description = l.description.replace(/\s+/g, ' ');
-      if (l.fname) l.fname = l.fname.replace(/[\/\\]/g, '_');
+      if (l.fname) l.fname = l.fname.replace(/[\/\\":<>|?*]/g, '_');
       l._pos = j;
       
       ol = map[href];
@@ -842,18 +852,35 @@ fg = {
 ,
   setPref: function(name, value) {
     const prefs = this.prefs;
-    switch (typeof(value)) {
-      case "string":
-          prefs.setCharPref(name,value);
+    try {
+      switch (typeof(value)) {
+        case "string":
+            prefs.setCharPref(name,value);
+            break;
+        case "boolean":
+          prefs.setBoolPref(name,value);
           break;
-      case "boolean":
-        prefs.setBoolPref(name,value);
-        break;
-      case "number":
-        prefs.setIntPref(name,value);
-        break;
-      default:
-        throw new Error("Unsupported type "+typeof(value)+" for preference "+name);
+        case "number":
+          prefs.setIntPref(name,value);
+          break;
+        default:
+          throw new Error("Unsupported type " + typeof(value) + " for preference " + name);
+      }
+    } catch(e) {
+      const IPC = Ci.nsIPrefBranch;
+      try {
+        switch (prefs.getPrefType(name)) {
+          case IPC.PREF_STRING:
+            prefs.setCharPref(name, value);
+            break;
+          case IPC.PREF_INT:
+            prefs.setIntPref(name, parseInt(value));
+            break;
+          case IPC.PREF_BOOL:
+            prefs.setBoolPref(name, !!value && value != "false");
+            break;
+        }
+      } catch(e2) {}
     }
   }
 ,
diff --git a/defaults/preferences/flashgot.js b/defaults/preferences/flashgot.js
index 3a681c3..2e0ba66 100644
--- a/defaults/preferences/flashgot.js
+++ b/defaults/preferences/flashgot.js
@@ -58,6 +58,19 @@ pref("flashgot.media.redirect.joost_com", 0);
 pref("flashgot.media.minSize.flv", 500000);
 pref("flashgot.media.iconInstalled", false);
 pref("flashgot.media.skipAds", true);
+pref("flashgot.media.YouTube.autodetect", true);
+pref("flashgot.media.YouTube.seek_pos.show", true);
+pref("flashgot.media.YouTube.seek_pos.show_ms", false);
+pref("flashgot.media.YouTube.seek_pos.compact", true);
+pref("flashgot.media.YouTube.flashvars_element_id", "movie_player");
+pref("flashgot.media.YouTube.flashvars_element_attr", "flashvars");
+pref("flashgot.media.YouTube.decode_signature_func", "/* Not encoded. */ if (params.stream.sig) { return params.stream.sig; } /* 2013-09-20: watch_as3-vflJM6GCe.swf */ var s = params.stream.s; if (!s) { return ''; } var swap = params.swap; var a = s.split(''); a = a.slice(3); a.reverse(); a = a.slice(1); a.reverse(); a = a.slice(3); a.reverse(); a = a.slice(3); swap(a, 59); a = a.slice(2); return a.join('');");
+pref("flashgot.media.YouTube.decode_signature_func.sandbox", true);
+pref("flashgot.media.YouTube.decode_signature_func.timestamp", 15953);
+pref("flashgot.media.YouTube.decode_signature_func.auto", true);
+pref("flashgot.media.YouTube.stream_url.tidy", false);
+pref("flashgot.media.YouTube.stream_url.extra_keep_params", "");
+pref("flashgot.media.autoCloseDocument", false);
 
 pref("flashgot.dmsopts._Built_In_.redir.filesonic_com.enabled", false);
 pref("flashgot.dmsopts._Built_In_.invertAltShiftClick", false);
diff --git a/install.js b/install.js
index d7a27f2..ef97fcf 100644
--- a/install.js
+++ b/install.js
@@ -1,7 +1,7 @@
 const APP_DISPLAY_NAME = "FlashGot";
 const APP_NAME = "flashgot";
 const APP_PACKAGE = "/informaction/flashgot";
-const APP_VERSION = "1.5.5.3";
+const APP_VERSION = "1.5.5.95";
 
 const APP_PREFS_FILE="defaults/preferences/flashgot.js";
 const APP_XPCOM_SERVICE="components/flashgotService.js";
diff --git a/install.rdf b/install.rdf
index 1695f05..704cddb 100644
--- a/install.rdf
+++ b/install.rdf
@@ -5,7 +5,7 @@
  
    <em:id>{19503e42-ca3c-4c27-b1e2-9cdb2170ee34}</em:id>
    <em:name>FlashGot</em:name>
-   <em:version>1.5.5.3</em:version>
+   <em:version>1.5.5.95</em:version>
    <em:description>Enables Firefox, Mozilla Suite, Netscape and Thunderbird to handle single and massive ("all" and "selection") downloads using the most popular external download managers for Windows, Mac OS X, Linux and FreeBSD (dozens currently supported, see Extension's Home Page for details). FlashGot offers also a Build Gallery functionality which helps to synthetize full media galleries in one page, from serial contents originally scattered on several pages, fo [...]
    <em:creator>Giorgio Maone</em:creator>
    <em:type>2</em:type>
@@ -86,7 +86,7 @@
      <Description>
      <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
      <em:minVersion>2.0</em:minVersion>
-     <em:maxVersion>23.0</em:maxVersion>
+     <em:maxVersion>28.0</em:maxVersion>
      </Description>
    </em:targetApplication>
    
@@ -104,7 +104,7 @@
       <Description>
         <em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
         <em:minVersion>2.0</em:minVersion>
-        <em:maxVersion>2.20</em:maxVersion>
+        <em:maxVersion>2.25</em:maxVersion>
       </Description>
    </em:targetApplication>
    
@@ -113,7 +113,7 @@
       <Description>
         <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
         <em:minVersion>2.0</em:minVersion>
-        <em:maxVersion>23.0</em:maxVersion>
+        <em:maxVersion>28.0</em:maxVersion>
       </Description>
     </em:targetApplication>
    
@@ -131,7 +131,7 @@
     <Description>
       <em:id>toolkit at mozilla.org</em:id>
       <em:minVersion>1.9a3</em:minVersion>
-      <em:maxVersion>23.0</em:maxVersion>
+      <em:maxVersion>28.0</em:maxVersion>
     </Description>
     </em:targetApplication>
     

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/flashgot.git



More information about the Pkg-mozext-commits mailing list