Merge mozilla-central to autoland
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 21 Nov 2016 15:47:42 +0100
changeset 323616 097b3595fb739cff8af432f63916dfb02a6400e2
parent 323615 851a50989291df2d276d3094683c30feea32cf3f (current diff)
parent 323609 0534254e9a40b4bade2577c631fe4cfa0b5db41d (diff)
child 323617 0f44d49bb142709fc75dcba2a742f605182d7644
push id21
push usermaklebus@msu.edu
push dateThu, 01 Dec 2016 06:22:08 +0000
milestone53.0a1
Merge mozilla-central to autoland
browser/themes/shared/downloads/menubutton-dropmarker.svg
browser/themes/shared/filters.svg
js/src/wasm/WasmBinaryFormat.cpp
js/src/wasm/WasmBinaryFormat.h
js/xpconnect/tests/chrome/test_wrappers-2.xul
testing/web-platform/harness/requirements_b2g.txt
testing/web-platform/harness/wptrunner/browsers/b2g.py
testing/web-platform/meta/XMLHttpRequest/XMLHttpRequest-withCredentials.any.js.ini
testing/web-platform/meta/battery-status/battery-charging-manual.html.ini
testing/web-platform/meta/battery-status/battery-discharging-manual.html.ini
testing/web-platform/meta/battery-status/battery-full-manual.html.ini
testing/web-platform/meta/battery-status/battery-plugging-in-manual.html.ini
testing/web-platform/meta/battery-status/battery-unplugging-manual.html.ini
testing/web-platform/meta/battery-status/support-iframe-initial.html.ini
testing/web-platform/meta/battery-status/support-iframe.html.ini
testing/web-platform/meta/battery-status/support-window-open.html.ini
testing/web-platform/meta/html/browsers/the-window-object/security-window/window-security.sub.html.ini
testing/web-platform/meta/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html.ini
testing/web-platform/meta/html/dom/documents/dom-tree-accessors/Document.currentScript.sub.html.ini
testing/web-platform/meta/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html.ini
testing/web-platform/meta/html/semantics/forms/the-input-element/radio.html.ini
testing/web-platform/meta/html/semantics/grouping-content/the-ol-element/ol.start-reflection-2.html.ini
testing/web-platform/meta/html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID.worker.js.ini
testing/web-platform/meta/mediacapture-streams/MediaStream-id-manual.https.html.ini
testing/web-platform/meta/url/url-domainToUnicode.html.ini
testing/web-platform/meta/workers/interfaces/WorkerUtils/navigator/window-only.worker.js.ini
testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm
testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm
testing/web-platform/tests/conformance-checkers/html/elements/dl/model-isvalid.html
testing/web-platform/tests/conformance-checkers/html/elements/dl/model-novalid.html
testing/web-platform/tests/dom/ranges/Range-mutations.html
testing/web-platform/tests/encrypted-media/scripts/playback-temporary-multikey-multisession.js
testing/web-platform/tests/fetch/api/request/request-cache.html
testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm
testing/web-platform/tests/html/browsers/the-window-object/security-window/window-security.sub.html
testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html
testing/web-platform/tests/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.sub.html
testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.sub.html
testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html
testing/web-platform/tests/svg/import/shapes-rect-01-t-manual.svg
testing/web-platform/tests/url/url-domainToUnicode.html
testing/web-platform/tests/workers/interfaces/WorkerUtils/navigator/window-only.worker.js
toolkit/components/places/tests/cpp/mock_Link.h
toolkit/components/places/tests/cpp/moz.build
toolkit/components/places/tests/cpp/places_test_harness.h
toolkit/components/places/tests/cpp/places_test_harness_tail.h
toolkit/components/places/tests/cpp/test_IHistory.cpp
toolkit/themes/osx/global/filters.svg
--- a/addon-sdk/source/test/test-api-utils.js
+++ b/addon-sdk/source/test/test-api-utils.js
@@ -276,16 +276,25 @@ exports.testValidateMapWithMissingKeyAnd
     },
     baz: {
       map: v => "foo"
     }
   });
   assert.deepEqual(val, { baz: "foo" });
 };
 
+function forEachEnabled() {
+  try {
+    eval(`for each (var x in {}) {}`);
+  } catch (e) {
+    return false;
+  }
+  return true;
+}
+
 exports.testAddIterator = function testAddIterator (assert) {
   let obj = {};
   let keys = ["foo", "bar", "baz"];
   let vals = [1, 2, 3];
   let keysVals = [["foo", 1], ["bar", 2], ["baz", 3]];
   apiUtils.addIterator(
     obj,
     function keysValsGen() {
@@ -298,19 +307,22 @@ exports.testAddIterator = function testA
   for (let key in obj)
     keysItr.push(key);
 
   assert.equal(keysItr.length, keys.length,
                    "the keys iterator returns the correct number of items");
   for (let i = 0; i < keys.length; i++)
     assert.equal(keysItr[i], keys[i], "the key is correct");
 
-  let valsItr = [];
-  for each (let val in obj)
-    valsItr.push(val);
-  assert.equal(valsItr.length, vals.length,
-                   "the vals iterator returns the correct number of items");
-  for (let i = 0; i < vals.length; i++)
-    assert.equal(valsItr[i], vals[i], "the val is correct");
-
+  if (forEachEnabled()) {
+    eval(`
+    let valsItr = [];
+    for each (let val in obj)
+      valsItr.push(val);
+    assert.equal(valsItr.length, vals.length,
+                     "the vals iterator returns the correct number of items");
+    for (let i = 0; i < vals.length; i++)
+      assert.equal(valsItr[i], vals[i], "the val is correct");
+  `);
+  }
 };
 
 require("sdk/test").run(exports);
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -418,19 +418,19 @@ exports["test Auto Unwrap Custom Attribu
   );
 
 });
 
 exports["test Object Tag"] = createProxyTest("", function (helper) {
 
   helper.createWorker(
     'new ' + function ContentScriptScope() {
-      // <object>, <embed> and other tags return typeof 'function'
+      // <object>, <embed> and other tags return typeof 'object'
       let flash = document.createElement("object");
-      assert(typeof flash == "function", "<object> is typeof 'function'");
+      assert(typeof flash == "object", "<object> is typeof 'function'");
       assert(flash.toString().match(/\[object HTMLObjectElement.*\]/), "<object> is HTMLObjectElement");
       assert("setAttribute" in flash, "<object> has a setAttribute method");
       done();
     }
   );
 
 });
 
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,31 +1,31 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<blocklist lastupdate="1479474493182" xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist lastupdate="1479734891197" xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
     <emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i698" id="{6b2a75c8-6e2e-4267-b955-43e25b54e575}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i1231" id="youtube@downloader.yt">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1263" id="axtara__web@axtara.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.1.1" severity="3"/>
     </emItem>
-    <emItem blockID="i1231" id="youtube@downloader.yt">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i922" id="{34712C68-7391-4c47-94F3-8F88D49AD632}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
@@ -43,29 +43,29 @@
     <emItem blockID="i1078" id="/^(jid1-W4CLFIRExukJIFW@jetpack|jid1-W4CLFIRExukJIFW@jetpack_1|jid1-W3CLwrP[a-z]+@jetpack)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i682" id="f6682b47-e12f-400b-9bc0-43b3ccae69d1@39d6f481-b198-4349-9ebe-9a93a86f9267.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i522" id="/^({976cd962-e0ca-4337-aea7-d93fae63a79c}|{525ba996-1ce4-4677-91c5-9fc4ead2d245}|{91659dab-9117-42d1-a09f-13ec28037717}|{c1211069-1163-4ba8-b8b3-32fc724766be})$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i1024" id="{458fb825-2370-4973-bf66-9d7142141847}">
       <prefs>
         <pref>app.update.auto</pref>
         <pref>app.update.enabled</pref>
         <pref>app.update.interval</pref>
         <pref>app.update.url</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i522" id="/^({976cd962-e0ca-4337-aea7-d93fae63a79c}|{525ba996-1ce4-4677-91c5-9fc4ead2d245}|{91659dab-9117-42d1-a09f-13ec28037717}|{c1211069-1163-4ba8-b8b3-32fc724766be})$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
       <prefs/>
       <versionRange minVersion=" " maxVersion="8.5"/>
     </emItem>
     <emItem blockID="i692" id="/^(j003-lqgrmgpcekslhg|SupraSavings|j003-dkqonnnthqjnkq|j003-kaggrpmirxjpzh)@jetpack$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
@@ -83,41 +83,41 @@
     </emItem>
     <emItem blockID="i884" id="detgdp@gmail.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i487" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
       <prefs/>
       <versionRange minVersion="2.0.3" maxVersion="2.0.3"/>
       <versionRange minVersion="4.2" maxVersion="4.2" severity="3"/>
     </emItem>
     <emItem blockID="i543" id="{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i487" id="{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1040" id="frhegnejkgner@grhjgewfewf.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i523" id="/^({7e8a1050-cf67-4575-92df-dcc60e7d952d}|{b3420a9c-a397-4409-b90d-bcf22da1a08a}|{eca6641f-2176-42ba-bdbe-f3e327f8e0af}|{707dca12-3f99-4d94-afea-06dcc0ae0108}|{aea20431-87fc-40be-bc5b-18066fe2819c}|{30ee6676-1ba6-455a-a7e8-298fa863a546})$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i1030" id="support@todoist.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="3.9" severity="1"/>
     </emItem>
-    <emItem blockID="i523" id="/^({7e8a1050-cf67-4575-92df-dcc60e7d952d}|{b3420a9c-a397-4409-b90d-bcf22da1a08a}|{eca6641f-2176-42ba-bdbe-f3e327f8e0af}|{707dca12-3f99-4d94-afea-06dcc0ae0108}|{aea20431-87fc-40be-bc5b-18066fe2819c}|{30ee6676-1ba6-455a-a7e8-298fa863a546})$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i732" id="{e935dd68-f90d-46a6-b89e-c4657534b353}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i436" id="/(\{7aeae561-714b-45f6-ace3-4a8aed6e227b\})|(\{01e86e69-a2f8-48a0-b068-83869bdba3d0\})|(\{77f5fe49-12e3-4cf5-abb4-d993a0164d9e\})/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
@@ -132,40 +132,40 @@
     <emItem blockID="i320" id="torntv@torntv.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i524" id="/^({4e988b08-8c51-45c1-8d74-73e0c8724579}|{93ec97bf-fe43-4bca-a735-5c5d6a0a40c4}|{aed63b38-7428-4003-a052-ca6834d8bad3}|{0b5130a9-cc50-4ced-99d5-cda8cc12ae48}|{C4CFC0DE-134F-4466-B2A2-FF7C59A8BFAD})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i1266" id="@stopad">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="0.0.4" severity="1"/>
+    </emItem>
     <emItem blockID="i537" id="rally_toolbar_ff@bulletmedia.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i1266" id="@stopad">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="0.0.4" severity="1"/>
-    </emItem>
-    <emItem blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i496" id="{ACAA314B-EEBA-48e4-AD47-84E31C44796C}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i914" id="{0153E448-190B-4987-BDE1-F256CADA672F}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i690" id="{55dce8ba-9dec-4013-937e-adbf9317d990">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i218" id="ffxtlbr@claro.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
@@ -202,47 +202,47 @@
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i684" id="{9edd0ea8-2819-47c2-8320-b007d5996f8a}">
       <prefs>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i444" id="fplayer@adobe.flash">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i550" id="colmer@yopmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i362" id="addon@defaulttab.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.4.4" severity="1"/>
     </emItem>
     <emItem blockID="i140" id="mozillahmpg@mozilla.org">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i503" id="{9CE11043-9A15-4207-A565-0C94C42D590D}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    <emItem blockID="i549" id="/^firefox@(albrechto|swiftbrowse|springsmart|storimbo|squirrelweb|betterbrowse|lizardlink|rolimno|browsebeyond|clingclang|weblayers|kasimos|higher-aurum|xaven|bomlabio)\.(com?|net|org|info|biz)$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
       <prefs/>
       <versionRange minVersion="1.0" maxVersion="1.0"/>
     </emItem>
-    <emItem blockID="i549" id="/^firefox@(albrechto|swiftbrowse|springsmart|storimbo|squirrelweb|betterbrowse|lizardlink|rolimno|browsebeyond|clingclang|weblayers|kasimos|higher-aurum|xaven|bomlabio)\.(com?|net|org|info|biz)$/">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    <emItem blockID="i503" id="{9CE11043-9A15-4207-A565-0C94C42D590D}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1079" id="/^(@9338379C-DD5C-4A45-9A36-9733DC806FAE|9338379C-DD5C-4A45-9A36-9733DC806FAE|@EBC7B466-8A28-4061-81B5-10ACC05FFE53|@bd6a97c0-4b18-40ed-bce7-3b7d3309e3c4222|@bd6a97c0-4b18-40ed-bce7-3b7d3309e3c4|@b2d6a97c0-4b18-40ed-bce7-3b7d3309e3c4222)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i622" id="/^({ebd898f8-fcf6-4694-bc3b-eabc7271eeb1}|{46008e0d-47ac-4daa-a02a-5eb69044431a}|{213c8ed6-1d78-4d8f-8729-25006aa86a76}|{fa23121f-ee7c-4bd8-8c06-123d087282c5}|{19803860-b306-423c-bbb5-f60a7d82cde5})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
@@ -278,24 +278,24 @@
     <emItem blockID="i91" id="crossriderapp4926@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="0.81.43" severity="1"/>
     </emItem>
     <emItem blockID="i376" id="{9e09ac65-43c0-4b9d-970f-11e2e9616c55}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i870" id="M1uwW0@47z8gRpK8sULXXLivB.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i76" id="crossriderapp3924@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i870" id="M1uwW0@47z8gRpK8sULXXLivB.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
       <prefs/>
       <versionRange minVersion="2.0" maxVersion="2.0"/>
     </emItem>
     <emItem blockID="i778" id="{f2456568-e603-43db-8838-ffa7c4a685c7}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -318,32 +318,32 @@
     <emItem blockID="i12" id="masterfiler@gmail.com">
       <prefs/>
       <versionRange severity="3"/>
     </emItem>
     <emItem blockID="i71" id="youtube@2youtube.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i447" id="{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i1261" id="support@lastpass.com">
       <prefs/>
       <versionRange minVersion="4.0.0a" maxVersion="4.1.20a" severity="1"/>
     </emItem>
-    <emItem blockID="i447" id="{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}">
+    <emItem blockID="i509" id="contato@facefollow.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i394" id="{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i509" id="contato@facefollow.net">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i810" id="{41339ee8-61ed-489d-b049-01e41fd5d7e0}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i618" id="toolbar@ask.com">
       <prefs/>
       <versionRange minVersion="3.15.24" maxVersion="3.15.24.*" severity="1"/>
       <versionRange minVersion="3.15.13" maxVersion="3.15.13.*" severity="1"/>
@@ -359,28 +359,28 @@
     <emItem blockID="i15" id="personas@christopher.beard">
       <prefs/>
       <versionRange minVersion="1.6" maxVersion="1.6">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="3.6.*" minVersion="3.6"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i486" id="xz123@ya456.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i784" id="{41e5ef7a-171d-4ab5-8351-951c65a29908}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i529" id="/^(torntv@torntv\.com|trtv3@trtv\.com|torntv2@torntv\.com|e2fd07a6-e282-4f2e-8965-85565fcb6384@b69158e6-3c3b-476c-9d98-ae5838c5b707\.com)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i486" id="xz123@ya456.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i57" id="youtube@youtube3.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i424" id="{C7AE725D-FA5C-4027-BB4C-787EF9F8248A}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.0.0.2" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@@ -395,21 +395,21 @@
     <emItem blockID="i498" id="hoverst@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i54" id="applebeegifts@mozilla.doslash.org">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i1136" id="/^({1f43c8af-e9e4-4e5a-b77a-f51c7a916324}|{3a3bd700-322e-440a-8a6a-37243d5c7f92}|{6a5b9fc2-733a-4964-a96a-958dd3f3878e}|{7b5d6334-8bc7-4bca-a13e-ff218d5a3f17}|{b87bca5b-2b5d-4ae8-ad53-997aa2e238d4}|{bf8e032b-150f-4656-8f2d-6b5c4a646e0d})$/">
+    <emItem blockID="i482" id="brasilescapeeight@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i482" id="brasilescapeeight@facebook.com">
+    <emItem blockID="i1136" id="/^({1f43c8af-e9e4-4e5a-b77a-f51c7a916324}|{3a3bd700-322e-440a-8a6a-37243d5c7f92}|{6a5b9fc2-733a-4964-a96a-958dd3f3878e}|{7b5d6334-8bc7-4bca-a13e-ff218d5a3f17}|{b87bca5b-2b5d-4ae8-ad53-997aa2e238d4}|{bf8e032b-150f-4656-8f2d-6b5c4a646e0d})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i312" id="extension21804@extension21804.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i552" id="jid0-O6MIff3eO5dIGf5Tcv8RsJDKxrs@jetpack">
@@ -520,37 +520,37 @@
     <emItem blockID="i772" id="{72b98dbc-939a-4e0e-b5a9-9fdbf75963ef}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i996" id="9598582LLKmjasieijkaslesae@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i88" id="anttoolbar@ant.com">
-      <prefs/>
-      <versionRange minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1"/>
+    <emItem blockID="i438" id="{02edb56b-9b33-435b-b7df-b2843273a694}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i358" id="lfind@nijadsoft.net">
+    <emItem blockID="i546" id="firefox@browsefox.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i438" id="{02edb56b-9b33-435b-b7df-b2843273a694}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    <emItem blockID="i88" id="anttoolbar@ant.com">
+      <prefs/>
+      <versionRange minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1"/>
     </emItem>
     <emItem blockID="i67" id="youtube2@youtube2.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i546" id="firefox@browsefox.com">
+    <emItem blockID="i358" id="lfind@nijadsoft.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i786" id="{63eb5ed4-e1b3-47ec-a253-f8462f205350}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i115" id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@@ -625,24 +625,24 @@
     <emItem blockID="i584" id="{52b0f3db-f988-4788-b9dc-861d016f4487}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="0.1.9999999" severity="1"/>
     </emItem>
     <emItem blockID="i466" id="afext@anchorfree.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
+      <prefs/>
+      <versionRange minVersion="1.1b1" maxVersion="1.1b1"/>
+    </emItem>
     <emItem blockID="i982" id="odtffplugin@ibm.com">
       <prefs/>
       <versionRange minVersion="9.0.1.1" maxVersion="9.0.1.100" severity="1"/>
     </emItem>
-    <emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
-      <prefs/>
-      <versionRange minVersion="1.1b1" maxVersion="1.1b1"/>
-    </emItem>
     <emItem blockID="i1036" id="HxLVJK1ioigz9WEWo8QgCs3evE7uW6LEExAniBGG@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i580" id="{51c77233-c0ad-4220-8388-47c11c18b355}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="0.1.9999999" severity="1"/>
     </emItem>
@@ -657,21 +657,21 @@
     <emItem blockID="i1038" id="344141-fasf9jas08hasoiesj9ia8ws@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i471" id="firefox@luckyleap.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/">
+    <emItem blockID="i560" id="adsremoval@adsremoval.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i560" id="adsremoval@adsremoval.net">
+    <emItem blockID="i396" id="/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\.com$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i968" id="{184AA5E6-741D-464a-820E-94B3ABC2F3B4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i538" id="{354dbb0a-71d5-4e9f-9c02-6c88b9d387ba}">
@@ -697,84 +697,84 @@
     <emItem blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i814" id="liiros@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i172" id="info@bflix.info">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i167" id="{b64982b1-d112-42b5-b1e4-d3867c4533f8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i352" id="vpyekkifgv@vpyekkifgv.org">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/">
+    <emItem blockID="i172" id="info@bflix.info">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1278" id="/^(ff\-)?dodate(kKKK|XkKKK|k|kk|kkx|kR)@(firefox|flash(1)?)\.pl|dode(ee)?k@firefoxnet\.pl|(addon|1)@upsolutions\.pl$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i256" id="/^[0-9a-f]+@[0-9a-f]+\.info/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i980" id="wHO@W9.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i127" id="plugin@youtubeplayer.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i740" id="ascsurfingprotection@iobit.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i340" id="chiang@programmer.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i554" id="lightningnewtab@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i740" id="ascsurfingprotection@iobit.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i380" id="{cc8f597b-0765-404e-a575-82aefbd81daf}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i432" id="lugcla21@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i429" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}">
+    <emItem blockID="i724" id="{1cdbda58-45f8-4d91-b566-8edce18f8d0a}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i724" id="{1cdbda58-45f8-4d91-b566-8edce18f8d0a}">
+    <emItem blockID="i429" id="{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i392" id="{EEE6C361-6118-11DC-9C72-001320C79847}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i533" id="extension@Fast_Free_Converter.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i638" id="{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}">
       <prefs/>
       <versionRange minVersion="27.8" maxVersion="27.9" severity="3"/>
     </emItem>
-    <emItem blockID="i533" id="extension@Fast_Free_Converter.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
       <prefs/>
       <versionRange minVersion="3.3.1" maxVersion="*">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="5.0a1"/>
         </targetApplication>
       </versionRange>
       <versionRange minVersion="0.1" maxVersion="3.3.0.*">
@@ -813,24 +813,24 @@
     <emItem blockID="i872" id="search-snacks@search-snacks.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i90" id="videoplugin@player.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i966" id="{5C655500-E712-41e7-9349-CE462F844B19}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="1.0.1-signed" severity="1"/>
+    </emItem>
     <emItem blockID="i306" id="{ADFA33FD-16F5-4355-8504-DF4D664CFE10}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i966" id="{5C655500-E712-41e7-9349-CE462F844B19}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="1.0.1-signed" severity="1"/>
-    </emItem>
     <emItem blockID="i1012" id="wxtui502n2xce9j@no14">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i83" id="flash@adobee.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
@@ -839,80 +839,80 @@
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i508" id="advance@windowsclient.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i774" id="x77IjS@xU.net">
-      <prefs>
-        <pref>browser.startup.homepage</pref>
-        <pref>browser.search.defaultenginename</pref>
-      </prefs>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i165" id="{EEF73632-A085-4fd3-A778-ECD82C8CB297}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1022" id="g99hiaoekjoasiijdkoleabsy278djasi@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i774" id="x77IjS@xU.net">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+        <pref>browser.search.defaultenginename</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i499" id="{babb9931-ad56-444c-b935-38bffe18ad26}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i21" id="support@update-firefox.com">
+      <prefs/>
+    </emItem>
+    <emItem blockID="i718" id="G4Ce4@w.net">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i75" id="firebug@software.joehewitt.com" os="Darwin,Linux">
       <prefs/>
       <versionRange minVersion="1.9.0" maxVersion="1.9.0" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="9.*" minVersion="9.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i718" id="G4Ce4@w.net">
-      <prefs>
-        <pref>browser.startup.homepage</pref>
-      </prefs>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i499" id="{babb9931-ad56-444c-b935-38bffe18ad26}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i21" id="support@update-firefox.com">
-      <prefs/>
+    <emItem blockID="i1264" id="suchpony@suchpony.de">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="1.6.7" severity="3"/>
     </emItem>
     <emItem blockID="i491" id="{515b2424-5911-40bd-8a2c-bdb20286d8f5}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i532" id="249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i65" id="activity@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i476" id="mbroctone@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i1264" id="suchpony@suchpony.de">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="1.6.7" severity="3"/>
+    <emItem blockID="i532" id="249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i656" id="hdv@vovcacik.addons.mozilla.org">
+      <prefs/>
+      <versionRange minVersion="102.0" maxVersion="102.0" severity="3"/>
     </emItem>
     <emItem blockID="i722" id="{9802047e-5a84-4da3-b103-c55995d147d1}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i656" id="hdv@vovcacik.addons.mozilla.org">
-      <prefs/>
-      <versionRange minVersion="102.0" maxVersion="102.0" severity="3"/>
-    </emItem>
     <emItem blockID="i228" id="crossriderapp5060@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i470" id="extension@FastFreeConverter.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -924,66 +924,66 @@
     <emItem blockID="i478" id="{7e8a1050-cf67-4575-92df-dcc60e7d952d}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i370" id="happylyrics@hpyproductions.net">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i440" id="{2d069a16-fca1-4e81-81ea-5d5086dcbd0c}">
+    <emItem blockID="i1077" id="helper@vidscrab.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i1077" id="helper@vidscrab.com">
+    <emItem blockID="i440" id="{2d069a16-fca1-4e81-81ea-5d5086dcbd0c}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i55" id="youtube@youtube7.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i664" id="123456789@offeringmedia.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i630" id="webbooster@iminent.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i664" id="123456789@offeringmedia.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i924" id="{DAC3F861-B30D-40dd-9166-F4E75327FAC7}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+          <versionRange maxVersion="*" minVersion="39.0a1"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
     <emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
       <prefs/>
     </emItem>
+    <emItem blockID="i842" id="{746505DC-0E21-4667-97F8-72EA6BCF5EEF}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i624" id="/^({b95faac1-a3d7-4d69-8943-ddd5a487d966}|{ecce0073-a837-45a2-95b9-600420505f7e}|{2713b394-286f-4d7c-89ea-4174eeab9f5a}|{da7a20cf-bef4-4342-ad78-0240fdf87055})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i868" id="{6e7f6f9f-8ce6-4611-add2-05f0f7049ee6}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i842" id="{746505DC-0E21-4667-97F8-72EA6BCF5EEF}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i924" id="{DAC3F861-B30D-40dd-9166-F4E75327FAC7}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3">
-        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-          <versionRange maxVersion="*" minVersion="39.0a1"/>
-        </targetApplication>
-      </versionRange>
-    </emItem>
     <emItem blockID="i101" id="{3a12052a-66ef-49db-8c39-e5b0bd5c83fa}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i107" id="{ABDE892B-13A8-4d1b-88E6-365A6E755758}" os="WINNT">
       <prefs/>
       <versionRange minVersion="0" maxVersion="15.0.5" severity="1"/>
     </emItem>
@@ -1001,59 +1001,59 @@
     <emItem blockID="i1414" id="/^new@kuot\.pro|{13ec6687-0b15-4f01-a5a0-7a891c18e4ee}|rebeccahoppkins(ty(tr)?)?@gmail\.com|{501815af-725e-45be-b0f2-8f36f5617afc}|{9bdb5f1f-b1e1-4a75-be31-bdcaace20a99}|{e9d93e1d-792f-4f95-b738-7adb0e853b7b}|dojadewaskurwa@gmail\.com$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i528" id="008abed2-b43a-46c9-9a5b-a771c87b82da@1ad61d53-2bdc-4484-a26b-b888ecae1906.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i652" id="garg_sms@yahoo.in">
+      <prefs/>
+      <versionRange minVersion="67.9" maxVersion="67.9" severity="3"/>
+    </emItem>
     <emItem blockID="i712" id="{a2bfe612-4cf5-48ea-907c-f3fb25bc9d6b}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i652" id="garg_sms@yahoo.in">
-      <prefs/>
-      <versionRange minVersion="67.9" maxVersion="67.9" severity="3"/>
-    </emItem>
-    <emItem blockID="i47" id="youtube@youtube2.com">
-      <prefs/>
-    </emItem>
     <emItem blockID="i453" id="/^brasilescape.*\@facebook\.com$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i485" id="/^brasilescape.*\@facebook\.com$//">
+    <emItem blockID="i47" id="youtube@youtube2.com">
+      <prefs/>
+    </emItem>
+    <emItem blockID="i816" id="noOpus@outlook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i816" id="noOpus@outlook.com">
+    <emItem blockID="i485" id="/^brasilescape.*\@facebook\.com$//">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1262" id="my7thfakeid@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i451" id="{e44a1809-4d10-4ab8-b343-3326b64c7cdd}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i402" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i598" id="{29b136c9-938d-4d3d-8df8-d649d9b74d02}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i451" id="{e44a1809-4d10-4ab8-b343-3326b64c7cdd}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i108" id="{28bfb930-7620-11e1-b0c4-0800200c9a66}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i1056" id="{82AF8DCA-6DE9-405D-BD5E-43525BDAD38A}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="7.5.0.9082" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@@ -1064,50 +1064,50 @@
     <emItem blockID="i350" id="sqlmoz@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="1.0.8" severity="1"/>
-    </emItem>
     <emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
       <prefs/>
     </emItem>
     <emItem blockID="i226" id="{462be121-2b54-4218-bf00-b9bf8135b23f}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="1.0.8" severity="1"/>
+    </emItem>
     <emItem blockID="i258" id="helperbar@helperbar.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.0" severity="1"/>
     </emItem>
+    <emItem blockID="i44" id="sigma@labs.mozilla">
+      <prefs/>
+    </emItem>
     <emItem blockID="i96" id="youtubeee@youtuber3.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i44" id="sigma@labs.mozilla">
-      <prefs/>
-    </emItem>
     <emItem blockID="i564" id="/^(firefox@vebergreat\.net|EFGLQA@78ETGYN-0W7FN789T87\.COM)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i97" id="support3_en@adobe122.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i500" id="{2aab351c-ad56-444c-b935-38bffe18ad26}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i97" id="support3_en@adobe122.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
     <emItem blockID="i439" id="{d2cf9842-af95-48cd-b873-bfbb48cd7f5e}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i576" id="newmoz@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -1125,78 +1125,78 @@
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i494" id="/^({e9df9360-97f8-4690-afe6-996c80790da4}|{687578b9-7132-4a7a-80e4-30ee31099e03}|{46a3135d-3683-48cf-b94c-82655cbc0e8a}|{49c795c2-604a-4d18-aeb1-b3eba27e5ea2}|{7473b6bd-4691-4744-a82b-7854eb3d70b6}|{96f454ea-9d38-474f-b504-56193e00c1a5})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i174" id="info@thebflix.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i668" id="/^(matchersite(pro(srcs?)?)?\@matchersite(pro(srcs?)?)?\.com)|((pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\@(pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\.com)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i174" id="info@thebflix.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i822" id="{6af08a71-380e-42dd-9312-0111d2bc0630}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i846" id="PDVDZDW52397720@XDDWJXW57740856.com">
+    <emItem blockID="i888" id="istart_ffnt@gmail.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i888" id="istart_ffnt@gmail.com">
+    <emItem blockID="i846" id="PDVDZDW52397720@XDDWJXW57740856.com">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i972" id="831778-poidjao88DASfsAnindsd@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i515" id="/^({bf9194c2-b86d-4ebc-9b53-1c08b6ff779e}|{61a83e16-7198-49c6-8874-3e4e8faeb4f3}|{f0af464e-5167-45cf-9cf0-66b396d1918c}|{5d9968c3-101c-4944-ba71-72d77393322d}|{01e86e69-a2f8-48a0-b068-83869bdba3d0})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i844" id="e9d197d59f2f45f382b1aa5c14d82@8706aaed9b904554b5cb7984e9.com">
+      <prefs>
+        <pref>browser.startup.homepage</pref>
+        <pref>browser.search.defaultenginename</pref>
+      </prefs>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i216" id="fdm_ffext@freedownloadmanager.org">
       <prefs/>
       <versionRange minVersion="1.0" maxVersion="1.3.1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.0a1"/>
         </targetApplication>
       </versionRange>
       <versionRange minVersion="1.5.7.5" maxVersion="1.5.7.5" severity="1"/>
     </emItem>
-    <emItem blockID="i844" id="e9d197d59f2f45f382b1aa5c14d82@8706aaed9b904554b5cb7984e9.com">
-      <prefs>
-        <pref>browser.startup.homepage</pref>
-        <pref>browser.search.defaultenginename</pref>
-      </prefs>
+    <emItem blockID="i818" id="contentarget@maildrop.cc">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i596" id="{b99c8534-7800-48fa-bd71-519a46cdc7e1}">
+      <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i461" id="{8E9E3331-D360-4f87-8803-52DE43566502}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i596" id="{b99c8534-7800-48fa-bd71-519a46cdc7e1}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
-    <emItem blockID="i818" id="contentarget@maildrop.cc">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i23" id="firefox@bandoo.com">
       <prefs/>
       <versionRange minVersion="5.0" maxVersion="5.0" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.7a1pre"/>
         </targetApplication>
       </versionRange>
     </emItem>
@@ -1211,28 +1211,28 @@
     <emItem blockID="i59" id="ghostviewer@youtube2.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i78" id="socialnetworktools@mozilla.doslash.org">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i526" id="/^({83a8ce1b-683c-4784-b86d-9eb601b59f38}|{ef1feedd-d8da-4930-96f1-0a1a598375c6}|{79ff1aae-701f-4ca5-aea3-74b3eac6f01b}|{8a184644-a171-4b05-bc9a-28d75ffc9505}|{bc09c55d-0375-4dcc-836e-0e3c8addfbda}|{cef81415-2059-4dd5-9829-1aef3cf27f4f})$/">
+    <emItem blockID="i448" id="{0134af61-7a0c-4649-aeca-90d776060cb3}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i708" id="{849ded12-59e9-4dae-8f86-918b70d213dc}">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i448" id="{0134af61-7a0c-4649-aeca-90d776060cb3}">
+    <emItem blockID="i526" id="/^({83a8ce1b-683c-4784-b86d-9eb601b59f38}|{ef1feedd-d8da-4930-96f1-0a1a598375c6}|{79ff1aae-701f-4ca5-aea3-74b3eac6f01b}|{8a184644-a171-4b05-bc9a-28d75ffc9505}|{bc09c55d-0375-4dcc-836e-0e3c8addfbda}|{cef81415-2059-4dd5-9829-1aef3cf27f4f})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
       <prefs/>
       <versionRange minVersion="0.1" maxVersion="7.9.20.6" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="8.0a1"/>
@@ -1272,48 +1272,48 @@
     </emItem>
     <emItem blockID="i696" id="/^({fa95f577-07cb-4470-ac90-e843f5f83c52}|ffxtlbr@speedial\.com)$/">
       <prefs>
         <pref>browser.startup.homepage</pref>
         <pref>browser.search.defaultenginename</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i354" id="{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i1212" id="unblocker20@unblocker.yt">
       <prefs/>
       <versionRange minVersion="0" maxVersion="2.0.0" severity="3"/>
     </emItem>
-    <emItem blockID="i354" id="{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i84" id="pink@rosaplugin.info">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i547" id="{87934c42-161d-45bc-8cef-ef18abe2a30c}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="3.7.9999999999" severity="1"/>
     </emItem>
     <emItem blockID="i364" id="{FE1DEEEA-DB6D-44b8-83F0-34FC0F9D1052}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i356" id="{341f4dac-1966-47ff-aacf-0ce175f1498a}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i536" id="{25D77636-38B1-1260-887C-2D4AFA92D6A4}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i336" id="CortonExt@ext.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i536" id="{25D77636-38B1-1260-887C-2D4AFA92D6A4}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i374" id="update@firefox.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i452" id="{77beece6-3997-403a-92fa-0055bfcf88e5}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
@@ -1359,56 +1359,56 @@
     <emItem blockID="i1034" id="a88a77ahjjfjakckmmabsy278djasi@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i562" id="iobitapps@mybrowserbar.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i916" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i338" id="{1FD91A9C-410C-4090-BBCC-55D3450EF433}">
+    <emItem blockID="i430" id="1chtw@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i430" id="1chtw@facebook.com">
+    <emItem blockID="i970" id="hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
+    <emItem blockID="i338" id="{1FD91A9C-410C-4090-BBCC-55D3450EF433}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i344" id="lrcsTube@hansanddeta.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i79" id="GifBlock@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
+    <emItem blockID="i483" id="brasilescapefive@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i469" id="OKitSpace@OKitSpace.es">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i780" id="{b6ef1336-69bb-45b6-8cba-e578fc0e4433}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i483" id="brasilescapefive@facebook.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i1058" id="amo-validator-bypass@example.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i48" id="admin@youtubespeedup.com">
       <prefs/>
     </emItem>
     <emItem blockID="i766" id="/^[a-z0-9]+@foxysecure[a-z0-9]*\.com$/">
@@ -1485,26 +1485,26 @@
     <emItem blockID="i752" id="savingsslider@mybrowserbar.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i77" id="{fa277cfc-1d75-4949-a1f9-4ac8e41b2dfd}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i64" id="royal@facebook.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
     <emItem blockID="i728" id="l@AdLJ7uz.net">
       <prefs>
         <pref>browser.startup.homepage</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
+    <emItem blockID="i64" id="royal@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i468" id="05dd836e-2cbd-4204-9ff3-2f8a8665967d@a8876730-fb0c-4057-a2fc-f9c09d438e81.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i60" id="youtb3@youtb3.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
@@ -1543,21 +1543,21 @@
     <emItem blockID="i314" id="crossriderapp8812@crossrider.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i838" id="{87b5a11e-3b54-42d2-9102-0a7cb1f79ebf}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i678" id="{C4A4F5A0-4B89-4392-AFAC-D58010E349AF}">
+    <emItem blockID="i570" id="jid1-vW9nopuIAJiRHw@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i570" id="jid1-vW9nopuIAJiRHw@jetpack">
+    <emItem blockID="i678" id="{C4A4F5A0-4B89-4392-AFAC-D58010E349AF}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i14" id="mozilla_cc@internetdownloadmanager.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="6.9.8">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.7a1pre"/>
@@ -1611,21 +1611,21 @@
     <emItem blockID="i516" id="/^({3f3cddf8-f74d-430c-bd19-d2c9147aed3d}|{515b2424-5911-40bd-8a2c-bdb20286d8f5}|{17464f93-137e-4646-a0c6-0dc13faf0113}|{d1b5aad5-d1ae-4b20-88b1-feeaeb4c1ebc}|{aad50c91-b136-49d9-8b30-0e8d3ead63d0})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i51" id="admin@youtubeplayer.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i372" id="5nc3QHFgcb@r06Ws9gvNNVRfH.com">
+    <emItem blockID="i246" id="support@vide1flash2.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i246" id="support@vide1flash2.com">
+    <emItem blockID="i372" id="5nc3QHFgcb@r06Ws9gvNNVRfH.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i680" id="jid1-bKSXgRwy1UQeRA@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i802" id="{18d5a8fe-5428-485b-968f-b97b05a92b54}">
@@ -1658,53 +1658,53 @@
       <prefs/>
       <versionRange minVersion="99.7" maxVersion="99.7" severity="3"/>
       <versionRange minVersion="100.7" maxVersion="100.7" severity="3"/>
     </emItem>
     <emItem blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
+    <emItem blockID="i103" id="kdrgun@gmail.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i103" id="kdrgun@gmail.com">
+    <emItem blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i1119" id="/^(test3@test.org|test2@test.org|test@test.org|support@mozilla.org)$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i484" id="plugin@getwebcake.com">
+    <emItem blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
-    <emItem blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com">
+    <emItem blockID="i484" id="plugin@getwebcake.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i477" id="mbrnovone@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i495" id="kallow@facebook.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i836" id="hansin@topvest.id">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i542" id="/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/">
+    <emItem blockID="i286" id="{58bd07eb-0ee0-4df0-8121-dc9b693373df}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i286" id="{58bd07eb-0ee0-4df0-8121-dc9b693373df}">
+    <emItem blockID="i542" id="/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i52" id="ff-ext@youtube">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
     <emItem blockID="i676" id="SpecialSavings@SpecialSavings.com">
@@ -1716,64 +1716,64 @@
         <pref>browser.startup.homepage</pref>
       </prefs>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i540" id="/^(ffxtlbr@mixidj\.com|{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}|{67097627-fd8e-4f6b-af4b-ecb65e50112e}|{f6f0f973-a4a3-48cf-9a7a-b7a69c30d71a}|{a3d0e35f-f1da-4ccb-ae77-e9d27777e68d}|{1122b43d-30ee-403f-9bfa-3cc99b0caddd})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i493" id="12x3q@3244516.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i1265" id="@video_downloader_pro">
       <prefs/>
       <versionRange minVersion="1.2.1" maxVersion="1.2.5" severity="1"/>
     </emItem>
-    <emItem blockID="i493" id="12x3q@3244516.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i348" id="{13c9f1f9-2322-4d5c-81df-6d4bf8476ba4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i442" id="pennerdu@faceobooks.ws">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i450" id="{dff137ae-1ffd-11e3-8277-b8ac6f996f26}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i450" id="{dff137ae-1ffd-11e3-8277-b8ac6f996f26}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i238" id="/^pink@.*\.info$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="18.0"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i750" id="{46eddf51-a4f6-4476-8d6c-31c5187b2a2f}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i282" id="{33e0daa6-3af3-d8b5-6752-10e949c61516}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.1.999" severity="1"/>
     </emItem>
-    <emItem blockID="i750" id="{46eddf51-a4f6-4476-8d6c-31c5187b2a2f}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    <emItem blockID="i489" id="astrovia@facebook.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1245" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="3.9.9" severity="1"/>
     </emItem>
-    <emItem blockID="i489" id="astrovia@facebook.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i18" id="msntoolbar@msn.com">
       <prefs/>
       <versionRange minVersion=" " maxVersion="6.*"/>
     </emItem>
     <emItem blockID="i455" id="7d51fb17-b199-4d8f-894e-decaff4fc36a@a298838b-7f50-4c7c-9277-df6abbd42a0c.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
@@ -1796,32 +1796,32 @@
     <emItem blockID="i926" id="{B1FC07E1-E05B-4567-8891-E63FBE545BA8}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
+    <emItem blockID="i782" id="safebrowse@safebrowse.co">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i806" id="{d9284e50-81fc-11da-a72b-0800200c9a66}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="7.7.34" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="34.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i782" id="safebrowse@safebrowse.co">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
-    <emItem blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i812" id="{1e4ea5fc-09e5-4f45-a43b-c048304899fc}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i56" id="flash@adobe.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
@@ -1836,21 +1836,21 @@
     <emItem blockID="i472" id="linksicle@linksicle.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i98" id="youtubeeing@youtuberie.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*"/>
     </emItem>
-    <emItem blockID="i1213" id="unblocker20__web@unblocker.yt">
+    <emItem blockID="i578" id="jid1-XLjasWL55iEE1Q@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i578" id="jid1-XLjasWL55iEE1Q@jetpack">
+    <emItem blockID="i1213" id="unblocker20__web@unblocker.yt">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1233" id="cloudmask@cloudmask.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="2.0.788"/>
     </emItem>
     <emItem blockID="i582" id="discoverypro@discoverypro.com">
@@ -1876,48 +1876,48 @@
     <emItem blockID="i521" id="/^({66b103a7-d772-4fcd-ace4-16f79a9056e0}|{6926c7f7-6006-42d1-b046-eba1b3010315}|{72cabc40-64b2-46ed-8648-26d831761150}|{73ee2cf2-7b76-4c49-b659-c3d8cf30825d}|{ca6446a5-73d5-4c35-8aa1-c71dc1024a18}|{5373a31d-9410-45e2-b299-4f61428f0be4})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i322" id="jid0-Y6TVIzs0r7r4xkOogmJPNAGFGBw@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i1129" id="youtubeunblocker__web@unblocker.yt">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
       <prefs/>
       <versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.7a1pre"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i1129" id="youtubeunblocker__web@unblocker.yt">
+    <emItem blockID="i808" id="{c96d1ae6-c4cf-4984-b110-f5f561b33b5a}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i1214" id="firefoxdav@icloud.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="1.4.22" severity="1"/>
     </emItem>
-    <emItem blockID="i66" id="youtubeer@youtuber.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*"/>
-    </emItem>
-    <emItem blockID="i808" id="{c96d1ae6-c4cf-4984-b110-f5f561b33b5a}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="3"/>
-    </emItem>
     <emItem blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
       <prefs/>
       <versionRange minVersion="1.2" maxVersion="1.2">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="3.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
+    <emItem blockID="i66" id="youtubeer@youtuber.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*"/>
+    </emItem>
     <emItem blockID="i517" id="/^({16e193c8-1706-40bf-b6f3-91403a9a22be}|{284fed43-2e13-4afe-8aeb-50827d510e20}|{5e3cc5d8-ed11-4bed-bc47-35b4c4bc1033}|{7429e64a-1fd4-4112-a186-2b5630816b91}|{8c9980d7-0f09-4459-9197-99b3e559660c}|{8f1d9545-0bb9-4583-bb3c-5e1ac1e2920c})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i460" id="{845cab51-d8d2-472f-8bd9-2b44642d97c2}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
@@ -1943,44 +1943,44 @@
     <emItem blockID="i920" id="{FCE04E1F-9378-4f39-96F6-5689A9159E45}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3">
         <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
           <versionRange maxVersion="*" minVersion="39.0a1"/>
         </targetApplication>
       </versionRange>
     </emItem>
-    <emItem blockID="i507" id="4zffxtbr-bs@VideoDownloadConverter_4z.com">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="5.75.3.25126" severity="1"/>
+    <emItem blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i1050" id="87aukfkausiopoawjsuifhasefgased278djasi@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    <emItem blockID="i507" id="4zffxtbr-bs@VideoDownloadConverter_4z.com">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="5.75.3.25126" severity="1"/>
     </emItem>
     <emItem blockID="i22" id="ShopperReports@ShopperReports.com">
       <prefs/>
       <versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
     </emItem>
     <emItem blockID="i1137" id="/^({d50bfa5f-291d-48a8-909c-5f1a77b31948}|{d54bc985-6e7b-46cd-ad72-a4a266ad879e}|{d89e5de3-5543-4363-b320-a98cf150f86a}|{f3465017-6f51-4980-84a5-7bee2f961eba}|{fae25f38-ff55-46ea-888f-03b49aaf8812})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="i342" id="lbmsrvfvxcblvpane@lpaezhjez.org">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="1"/>
+    </emItem>
     <emItem blockID="i1230" id="addon@gemaoff">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
-    <emItem blockID="i342" id="lbmsrvfvxcblvpane@lpaezhjez.org">
-      <prefs/>
-      <versionRange minVersion="0" maxVersion="*" severity="1"/>
-    </emItem>
     <emItem blockID="i840" id="{4889ddce-7a83-45e6-afc9-1e4f1149fff4}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
       <prefs/>
     </emItem>
     <emItem blockID="i788" id="{729c9605-0626-4792-9584-4cbe65b243e6}">
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -83,35 +83,43 @@ const gXPInstallObserver = {
     // the next confirmation
     if (installInfo.installs.every(i => i.state != AddonManager.STATE_DOWNLOADED)) {
       showNextConfirmation();
       return;
     }
 
     const anchorID = "addons-notification-icon";
 
-    // Make notifications persist a minimum of 30 seconds
+    // Make notifications persistent
     var options = {
       displayURI: installInfo.originatingURI,
-      timeout: Date.now() + 30000,
+      persistent: true,
+    };
+
+    let acceptInstallation = () => {
+      for (let install of installInfo.installs)
+        install.install();
+      installInfo = null;
+
+      Services.telemetry
+              .getHistogramById("SECURITY_UI")
+              .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH);
     };
 
     let cancelInstallation = () => {
       if (installInfo) {
         for (let install of installInfo.installs) {
           // The notification may have been closed because the add-ons got
           // cancelled elsewhere, only try to cancel those that are still
           // pending install.
           if (install.state != AddonManager.STATE_CANCELLED)
             install.cancel();
         }
       }
 
-      this.acceptInstallation = null;
-
       showNextConfirmation();
     };
 
     let unsigned = installInfo.installs.filter(i => i.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING);
     let someUnsigned = unsigned.length > 0 && unsigned.length < installInfo.installs.length;
 
     options.eventCallback = (aEvent) => {
       switch (aEvent) {
@@ -137,26 +145,16 @@ const gXPInstallObserver = {
                 gNavigatorBundle.getString("addonInstall.unsigned"));
               unsignedLabel.setAttribute("class",
                 "addon-install-confirmation-unsigned");
               container.appendChild(unsignedLabel);
             }
 
             addonList.appendChild(container);
           }
-
-          this.acceptInstallation = () => {
-            for (let install of installInfo.installs)
-              install.install();
-            installInfo = null;
-
-            Services.telemetry
-                    .getHistogramById("SECURITY_UI")
-                    .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH);
-          };
           break;
       }
     };
 
     options.learnMoreURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
 
     let messageString;
     let notification = document.getElementById("addon-install-confirmation-notification");
@@ -182,36 +180,40 @@ const gXPInstallObserver = {
 
     let brandBundle = document.getElementById("bundle_brand");
     let brandShortName = brandBundle.getString("brandShortName");
 
     messageString = PluralForm.get(installInfo.installs.length, messageString);
     messageString = messageString.replace("#1", brandShortName);
     messageString = messageString.replace("#2", installInfo.installs.length);
 
-    let cancelButton = document.getElementById("addon-install-confirmation-cancel");
-    cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
-    cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
+    let action = {
+      label: gNavigatorBundle.getString("addonInstall.acceptButton.label"),
+      accessKey: gNavigatorBundle.getString("addonInstall.acceptButton.accesskey"),
+      callback: acceptInstallation,
+    };
 
-    let acceptButton = document.getElementById("addon-install-confirmation-accept");
-    acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
-    acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
+    let secondaryAction = {
+      label: gNavigatorBundle.getString("addonInstall.cancelButton.label"),
+      accessKey: gNavigatorBundle.getString("addonInstall.cancelButton.accesskey"),
+      callback: () => {},
+    };
 
     if (height) {
       notification.style.minHeight = height + "px";
     }
 
     let tab = gBrowser.getTabForBrowser(browser);
     if (tab) {
       gBrowser.selectedTab = tab;
     }
 
     let popup = PopupNotifications.show(browser, "addon-install-confirmation",
-                                        messageString, anchorID, null, null,
-                                        options);
+                                        messageString, anchorID, action,
+                                        [secondaryAction], options);
 
     removeNotificationOnEnd(popup, installInfo.installs);
 
     Services.telemetry
             .getHistogramById("SECURITY_UI")
             .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL);
   },
 
@@ -225,19 +227,20 @@ const gXPInstallObserver = {
     if (!browser || gBrowser.browsers.indexOf(browser) == -1)
       return;
 
     const anchorID = "addons-notification-icon";
     var messageString, action;
     var brandShortName = brandBundle.getString("brandShortName");
 
     var notificationID = aTopic;
-    // Make notifications persist a minimum of 30 seconds
+    // Make notifications persistent
     var options = {
       displayURI: installInfo.originatingURI,
+      persistent: true,
       timeout: Date.now() + 30000,
     };
 
     switch (aTopic) {
     case "addon-install-disabled": {
       notificationID = "xpinstall-disabled";
 
       if (gPrefService.prefIsLocked("xpinstall.enabled")) {
@@ -300,39 +303,56 @@ const gXPInstallObserver = {
         return;
       notificationID = "addon-progress";
       messageString = gNavigatorBundle.getString("addonDownloadingAndVerifying");
       messageString = PluralForm.get(installInfo.installs.length, messageString);
       messageString = messageString.replace("#1", installInfo.installs.length);
       options.installs = installInfo.installs;
       options.contentWindow = browser.contentWindow;
       options.sourceURI = browser.currentURI;
-      options.eventCallback = (aEvent) => {
+      options.eventCallback = function(aEvent) {
         switch (aEvent) {
+          case "shown":
+            let notificationElement = [...this.owner.panel.childNodes]
+                                      .find(n => n.notification == this);
+            if (notificationElement) {
+              if (Preferences.get("xpinstall.customConfirmationUI", false)) {
+                notificationElement.setAttribute("mainactiondisabled", "true");
+              } else {
+                notificationElement.button.hidden = true;
+              }
+            }
+            break;
           case "removed":
             options.contentWindow = null;
             options.sourceURI = null;
             break;
         }
       };
+      action = {
+        label: gNavigatorBundle.getString("addonInstall.acceptButton.label"),
+        accessKey: gNavigatorBundle.getString("addonInstall.acceptButton.accesskey"),
+        callback: () => {},
+      };
+      let secondaryAction = {
+        label: gNavigatorBundle.getString("addonInstall.cancelButton.label"),
+        accessKey: gNavigatorBundle.getString("addonInstall.cancelButton.accesskey"),
+        callback: () => {
+          for (let install of installInfo.installs) {
+            if (install.state != AddonManager.STATE_CANCELLED) {
+              install.cancel();
+            }
+          }
+        },
+      };
       let notification = PopupNotifications.show(browser, notificationID, messageString,
-                                                 anchorID, null, null, options);
+                                                 anchorID, action,
+                                                 [secondaryAction], options);
       notification._startTime = Date.now();
 
-      let cancelButton = document.getElementById("addon-progress-cancel");
-      cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
-      cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
-
-      let acceptButton = document.getElementById("addon-progress-accept");
-      if (Preferences.get("xpinstall.customConfirmationUI", false)) {
-        acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
-        acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
-      } else {
-        acceptButton.hidden = true;
-      }
       break; }
     case "addon-install-failed": {
       // TODO This isn't terribly ideal for the multiple failure case
       for (let install of installInfo.installs) {
         let host;
         try {
           host  = options.displayURI.host;
         } catch (e) {
@@ -562,17 +582,17 @@ var LightWeightThemeWebInstaller = {
           label: gNavigatorBundle.getString("lwthemeNeedsRestart.button"),
           accessKey: gNavigatorBundle.getString("lwthemeNeedsRestart.accesskey"),
           callback: function() {
             BrowserUtils.restartApplication();
           }
         };
 
         let options = {
-          timeout: Date.now() + 30000
+          persistent: true
         };
 
         PopupNotifications.show(gBrowser.selectedBrowser, "addon-theme-change",
                                 messageString, "addons-notification-icon",
                                 action, null, options);
       },
 
       onEnabled: function(aAddon) {
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -273,16 +273,17 @@ var gPluginHandler = {
         notification.reshow();
         browser.messageManager.sendAsyncMessage("BrowserPlugins:NotificationShown");
       }
       return;
     }
 
     let options = {
       dismissed: !showNow,
+      persistent: showNow,
       eventCallback: this._clickToPlayNotificationEventCallback,
       primaryPlugin: primaryPluginPermission,
       pluginData: pluginData,
       principal: principal,
     };
     PopupNotifications.show(browser, "click-to-play-plugins",
                             "", "plugins-notification-icon",
                             null, null, options);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -5965,18 +5965,22 @@ var OfflineApps = {
 
     let warnQuotaKB = Services.prefs.getIntPref("offline-apps.quota.warn");
     // This message shows the quota in MB, and so we divide the quota (in kb) by 1024.
     let message = gNavigatorBundle.getFormattedString("offlineApps.usage",
                                                       [ uri.host,
                                                         warnQuotaKB / 1024 ]);
 
     let anchorID = "indexedDB-notification-icon";
+    let options = {
+      persistent: true,
+      hideClose: true,
+    };
     PopupNotifications.show(browser, "offline-app-usage", message,
-                            anchorID, mainAction);
+                            anchorID, mainAction, null, options);
 
     // Now that we've warned once, prevent the warning from showing up
     // again.
     Services.perms.add(uri, "offline-app",
                        Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
   },
 
   // XXX: duplicated in preferences/advanced.js
@@ -6025,37 +6029,39 @@ var OfflineApps = {
     let notification = PopupNotifications.getNotification(notificationID, browser);
 
     if (notification) {
       notification.options.controlledItems.push([
         Cu.getWeakReference(browser), docId, uri
       ]);
     } else {
       let mainAction = {
-        label: gNavigatorBundle.getString("offlineApps.allow"),
-        accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
+        label: gNavigatorBundle.getString("offlineApps.allowStoring.label"),
+        accessKey: gNavigatorBundle.getString("offlineApps.allowStoring.accesskey"),
         callback: function() {
           for (let [ciBrowser, ciDocId, ciUri] of notification.options.controlledItems) {
             OfflineApps.allowSite(ciBrowser, ciDocId, ciUri);
           }
         }
       };
       let secondaryActions = [{
-        label: gNavigatorBundle.getString("offlineApps.never"),
-        accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
+        label: gNavigatorBundle.getString("offlineApps.dontAllow.label"),
+        accessKey: gNavigatorBundle.getString("offlineApps.dontAllow.accesskey"),
         callback: function() {
           for (let [, , ciUri] of notification.options.controlledItems) {
             OfflineApps.disallowSite(ciUri);
           }
         }
       }];
-      let message = gNavigatorBundle.getFormattedString("offlineApps.available",
+      let message = gNavigatorBundle.getFormattedString("offlineApps.available2",
                                                         [host]);
       let anchorID = "indexedDB-notification-icon";
       let options = {
+        persistent: true,
+        hideClose: true,
         controlledItems : [[Cu.getWeakReference(browser), docId, uri]]
       };
       notification = PopupNotifications.show(browser, notificationID, message,
                                              anchorID, mainAction,
                                              secondaryActions, options);
     }
   },
 
@@ -6127,103 +6133,55 @@ var IndexedDBPromptHelper = {
     var requestor = subject.QueryInterface(Ci.nsIInterfaceRequestor);
 
     var browser = requestor.getInterface(Ci.nsIDOMNode);
     if (browser.ownerGlobal != window) {
       // Only listen for notifications for browsers in our chrome window.
       return;
     }
 
-    var host = browser.currentURI.asciiHost;
+    // Get the host name if available or the file path otherwise.
+    var host = browser.currentURI.asciiHost || browser.currentURI.path;
 
     var message;
     var responseTopic;
     if (topic == this._permissionsPrompt) {
-      message = gNavigatorBundle.getFormattedString("offlineApps.available",
+      message = gNavigatorBundle.getFormattedString("offlineApps.available2",
                                                     [ host ]);
       responseTopic = this._permissionsResponse;
     }
 
-    const hiddenTimeoutDuration = 30000; // 30 seconds
-    const firstTimeoutDuration = 300000; // 5 minutes
-
-    var timeoutId;
-
     var observer = requestor.getInterface(Ci.nsIObserver);
 
     var mainAction = {
-      label: gNavigatorBundle.getString("offlineApps.allow"),
-      accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
+      label: gNavigatorBundle.getString("offlineApps.allowStoring.label"),
+      accessKey: gNavigatorBundle.getString("offlineApps.allowStoring.accesskey"),
       callback: function() {
-        clearTimeout(timeoutId);
         observer.observe(null, responseTopic,
                          Ci.nsIPermissionManager.ALLOW_ACTION);
       }
     };
 
     var secondaryActions = [
       {
-        label: gNavigatorBundle.getString("offlineApps.never"),
-        accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
+        label: gNavigatorBundle.getString("offlineApps.dontAllow.label"),
+        accessKey: gNavigatorBundle.getString("offlineApps.dontAllow.accesskey"),
         callback: function() {
-          clearTimeout(timeoutId);
           observer.observe(null, responseTopic,
                            Ci.nsIPermissionManager.DENY_ACTION);
         }
       }
     ];
 
-    // This will be set to the result of PopupNotifications.show().
-    var notification;
-
-    function timeoutNotification() {
-      // Remove the notification.
-      if (notification) {
-        notification.remove();
-      }
-
-      // Clear all of our timeout stuff. We may be called directly, not just
-      // when the timeout actually elapses.
-      clearTimeout(timeoutId);
-
-      // And tell the page that the popup timed out.
-      observer.observe(null, responseTopic,
-                       Ci.nsIPermissionManager.UNKNOWN_ACTION);
-    }
-
-    var options = {
-      eventCallback: function(state) {
-        // Don't do anything if the timeout has not been set yet.
-        if (!timeoutId) {
-          return;
-        }
-
-        // If the popup is being dismissed start the short timeout.
-        if (state == "dismissed") {
-          clearTimeout(timeoutId);
-          timeoutId = setTimeout(timeoutNotification, hiddenTimeoutDuration);
-          return;
-        }
-
-        // If the popup is being re-shown then clear the timeout allowing
-        // unlimited waiting.
-        if (state == "shown") {
-          clearTimeout(timeoutId);
-        }
-      }
-    };
-
-    notification = PopupNotifications.show(browser, topic, message,
-                                           this._notificationIcon, mainAction,
-                                           secondaryActions, options);
-
-    // Set the timeoutId after the popup has been created, and use the long
-    // timeout value. If the user doesn't notice the popup after this amount of
-    // time then it is most likely not visible and we want to alert the page.
-    timeoutId = setTimeout(timeoutNotification, firstTimeoutDuration);
+    PopupNotifications.show(browser, topic, message,
+                            this._notificationIcon, mainAction,
+                            secondaryActions, {
+                              persistent: true,
+                              hideClose: true,
+                            });
   }
 };
 
 function CanCloseWindow()
 {
   // Avoid redundant calls to canClose from showing multiple
   // PermitUnload dialogs.
   if (Services.startup.shuttingDown || window.skipNextCanClose) {
--- a/browser/base/content/popup-notifications.inc
+++ b/browser/base/content/popup-notifications.inc
@@ -17,17 +17,17 @@
           <menupopup id="webRTC-selectCamera-menupopup"/>
         </menulist>
       </popupnotificationcontent>
 
       <popupnotificationcontent id="webRTC-selectWindowOrScreen" orient="vertical">
         <label id="webRTC-selectWindow-label"
                control="webRTC-selectWindow-menulist"/>
         <menulist id="webRTC-selectWindow-menulist"
-                  oncommand="webrtcUI.updateMainActionLabel(this);">
+                  oncommand="webrtcUI.updateWarningLabel(this);">
           <menupopup id="webRTC-selectWindow-menupopup"/>
         </menulist>
         <description id="webRTC-all-windows-shared" hidden="true">&getUserMedia.allWindowsShared.message;</description>
       </popupnotificationcontent>
 
       <popupnotificationcontent id="webRTC-preview" hidden="true">
         <html:video id="webRTC-previewVideo"/>
         <vbox id="webRTC-previewWarningBox">
@@ -61,21 +61,13 @@
     </popupnotification>
 
 
     <popupnotification id="addon-progress-notification" hidden="true">
       <popupnotificationcontent orient="vertical">
         <progressmeter id="addon-progress-notification-progressmeter"/>
         <label id="addon-progress-notification-progresstext" crop="end"/>
       </popupnotificationcontent>
-      <button id="addon-progress-cancel"
-              oncommand="this.parentNode.cancel();"/>
-      <button id="addon-progress-accept" disabled="true"/>
     </popupnotification>
 
     <popupnotification id="addon-install-confirmation-notification" hidden="true">
       <popupnotificationcontent id="addon-install-confirmation-content" orient="vertical"/>
-      <button id="addon-install-confirmation-cancel"
-              oncommand="PopupNotifications.getNotification('addon-install-confirmation').remove();"/>
-      <button id="addon-install-confirmation-accept"
-              oncommand="gXPInstallObserver.acceptInstallation();
-                         PopupNotifications.getNotification('addon-install-confirmation').remove();"/>
     </popupnotification>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2855,17 +2855,24 @@
               var isBusy = aOtherTab.hasAttribute("busy");
               if (isBusy) {
                 aOurTab.setAttribute("busy", "true");
                 modifiedAttrs.push("busy");
                 if (aOurTab.selected)
                   this.mIsBusy = true;
               }
 
-              this._swapBrowserDocShells(aOurTab, otherBrowser);
+              this._swapBrowserDocShells(aOurTab, otherBrowser, Ci.nsIBrowser.SWAP_DEFAULT);
+            }
+
+            // Unregister the previously opened URI
+            if (otherBrowser.registeredOpenURI) {
+              this._unifiedComplete.unregisterOpenPage(otherBrowser.registeredOpenURI,
+                                                       otherBrowser.getAttribute("usercontextid") || 0);
+              delete otherBrowser.registeredOpenURI;
             }
 
             // Handle findbar data (if any)
             let otherFindBar = aOtherTab._findBar;
             if (otherFindBar &&
                 otherFindBar.findMode == otherFindBar.FIND_NORMAL) {
               let ourFindBar = this.getFindBar(aOurTab);
               ourFindBar._findField.value = otherFindBar._findField.value;
@@ -2888,19 +2895,31 @@
 
             if (modifiedAttrs.length) {
               this._tabAttrModified(aOurTab, modifiedAttrs);
             }
           ]]>
         </body>
       </method>
 
+      <method name="swapBrowsers">
+        <parameter name="aOurTab"/>
+        <parameter name="aOtherBrowser"/>
+        <parameter name="aFlags"/>
+        <body>
+          <![CDATA[
+            this._swapBrowserDocShells(aOurTab, aOtherBrowser, aFlags);
+          ]]>
+        </body>
+      </method>
+
       <method name="_swapBrowserDocShells">
         <parameter name="aOurTab"/>
         <parameter name="aOtherBrowser"/>
+        <parameter name="aFlags"/>
         <body>
           <![CDATA[
             // Unhook our progress listener
             const filter = this._tabFilters.get(aOurTab);
             let tabListener = this._tabListeners.get(aOurTab);
             let ourBrowser = this.getBrowserForTab(aOurTab);
             ourBrowser.webProgress.removeProgressListener(filter);
             filter.removeProgressListener(tabListener);
@@ -2932,25 +2951,27 @@
             }
 
             // Register new outerWindowIDs.
             this._outerWindowIDBrowserMap.set(ourBrowser.outerWindowID, ourBrowser);
             if (remoteBrowser) {
               remoteBrowser._outerWindowIDBrowserMap.set(aOtherBrowser.outerWindowID, aOtherBrowser);
             }
 
-            // Swap permanentKey properties.
-            let ourPermanentKey = ourBrowser.permanentKey;
-            ourBrowser.permanentKey = aOtherBrowser.permanentKey;
-            aOtherBrowser.permanentKey = ourPermanentKey;
-            aOurTab.permanentKey = ourBrowser.permanentKey;
-            if (remoteBrowser) {
-              let otherTab = remoteBrowser.getTabForBrowser(aOtherBrowser);
-              if (otherTab) {
-                otherTab.permanentKey = aOtherBrowser.permanentKey;
+            if (!(aFlags & Ci.nsIBrowser.SWAP_KEEP_PERMANENT_KEY)) {
+              // Swap permanentKey properties.
+              let ourPermanentKey = ourBrowser.permanentKey;
+              ourBrowser.permanentKey = aOtherBrowser.permanentKey;
+              aOtherBrowser.permanentKey = ourPermanentKey;
+              aOurTab.permanentKey = ourBrowser.permanentKey;
+              if (remoteBrowser) {
+                let otherTab = remoteBrowser.getTabForBrowser(aOtherBrowser);
+                if (otherTab) {
+                  otherTab.permanentKey = aOtherBrowser.permanentKey;
+                }
               }
             }
 
             // Restore the progress listener
             tabListener = this.mTabProgressListener(aOurTab, ourBrowser, false, false);
             this._tabListeners.set(aOurTab, tabListener);
 
             const notifyAll = Ci.nsIWebProgress.NOTIFY_ALL;
@@ -2960,28 +2981,26 @@
         </body>
       </method>
 
       <method name="_swapRegisteredOpenURIs">
         <parameter name="aOurBrowser"/>
         <parameter name="aOtherBrowser"/>
         <body>
           <![CDATA[
-            // If the current URI is registered as open remove it from the list.
-            if (aOurBrowser.registeredOpenURI) {
-              this._unifiedComplete.unregisterOpenPage(aOurBrowser.registeredOpenURI,
-                                                       aOurBrowser.getAttribute("usercontextid") || 0);
-              delete aOurBrowser.registeredOpenURI;
-            }
-
-            // If the other/new URI is registered as open then copy it over.
+            // Swap the registeredOpenURI properties of the two browsers
+            let tmp = aOurBrowser.registeredOpenURI;
+            delete aOurBrowser.registeredOpenURI;
             if (aOtherBrowser.registeredOpenURI) {
               aOurBrowser.registeredOpenURI = aOtherBrowser.registeredOpenURI;
               delete aOtherBrowser.registeredOpenURI;
             }
+            if (tmp) {
+              aOtherBrowser.registeredOpenURI = tmp;
+            }
           ]]>
         </body>
       </method>
 
       <method name="reloadAllTabs">
         <body>
           <![CDATA[
             let tabs = this.visibleTabs;
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -73,16 +73,18 @@ function waitForProgressNotification(aPa
 
     info("Saw a notification");
     ok(PopupNotifications.isPanelOpen, "Panel should be open");
     is(PopupNotifications.panel.childNodes.length, aExpectedCount, "Should be the right number of notifications");
     if (PopupNotifications.panel.childNodes.length) {
       let nodes = Array.from(PopupNotifications.panel.childNodes);
       let notification = nodes.find(n => n.id == notificationId + "-notification");
       ok(notification, `Should have seen the right notification`);
+      ok(notification.button.hasAttribute("disabled"),
+         "The install button should be disabled");
     }
 
     return PopupNotifications.panel;
   });
 }
 
 function waitForNotification(aId, aExpectedCount = 1) {
   return Task.spawn(function* () {
@@ -111,23 +113,23 @@ function waitForNotification(aId, aExpec
         PopupNotifications.panel.removeEventListener("PanelUpdated", eventListener);
         resolve();
       });
     });
 
     yield observerPromise;
     yield panelEventPromise;
 
-    info("Saw a notification");
+    info("Saw a " + aId + " notification");
     ok(PopupNotifications.isPanelOpen, "Panel should be open");
     is(PopupNotifications.panel.childNodes.length, aExpectedCount, "Should be the right number of notifications");
     if (PopupNotifications.panel.childNodes.length) {
       let nodes = Array.from(PopupNotifications.panel.childNodes);
       let notification = nodes.find(n => n.id == aId + "-notification");
-      ok(notification, `Should have seen the right notification`);
+      ok(notification, "Should have seen the " + aId + " notification");
     }
 
     return PopupNotifications.panel;
   });
 }
 
 function waitForNotificationClose() {
   return new Promise(resolve => {
@@ -137,18 +139,18 @@ function waitForNotificationClose() {
       resolve();
     }, false);
   });
 }
 
 function waitForInstallDialog() {
   return Task.spawn(function* () {
     if (Preferences.get("xpinstall.customConfirmationUI", false)) {
-      yield waitForNotification("addon-install-confirmation");
-      return;
+      let panel = yield waitForNotification("addon-install-confirmation");
+      return panel.childNodes[0];
     }
 
     info("Waiting for install dialog");
 
     let window = yield new Promise(resolve => {
       Services.wm.addListener({
         onOpenWindow: function(aXULWindow) {
           Services.wm.removeListener(this);
@@ -171,39 +173,39 @@ function waitForInstallDialog() {
     });
     info("Saw install dialog");
     is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
 
     // Override the countdown timer on the accept button
     let button = domwindow.document.documentElement.getButton("accept");
     button.disabled = false;
 
-    return;
+    return null;
   });
 }
 
 function removeTab() {
   return Promise.all([
     waitForNotificationClose(),
     BrowserTestUtils.removeTab(gBrowser.selectedTab)
   ]);
 }
 
-function acceptInstallDialog() {
+function acceptInstallDialog(installDialog) {
   if (Preferences.get("xpinstall.customConfirmationUI", false)) {
-    document.getElementById("addon-install-confirmation-accept").click();
+    installDialog.button.click();
   } else {
     let win = Services.wm.getMostRecentWindow("Addons:Install");
     win.document.documentElement.acceptDialog();
   }
 }
 
-function cancelInstallDialog() {
+function cancelInstallDialog(installDialog) {
   if (Preferences.get("xpinstall.customConfirmationUI", false)) {
-    document.getElementById("addon-install-confirmation-cancel").click();
+    installDialog.secondaryButton.click();
   } else {
     let win = Services.wm.getMostRecentWindow("Addons:Install");
     win.document.documentElement.cancelDialog();
   }
 }
 
 function waitForSingleNotification(aCallback) {
   return Task.spawn(function* () {
@@ -288,20 +290,20 @@ function test_blockedInstall() {
 
     let dialogPromise = waitForInstallDialog();
     // Click on Allow
     EventUtils.synthesizeMouse(notification.button, 20, 10, {});
     // Notification should have changed to progress notification
     ok(PopupNotifications.isPanelOpen, "Notification should still be open");
     notification = panel.childNodes[0];
     is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     panel = yield notificationPromise;
 
     notification = panel.childNodes[0];
     is(notification.button.label, "Restart Now", "Should have seen the right button");
     is(notification.getAttribute("label"),
        "XPI Test will be installed after you restart " + gApp + ".",
        "Should have seen the right message");
 
@@ -323,24 +325,24 @@ function test_whitelistedInstall() {
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "XPI": "amosigned.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?"
       + triggers).then(newTab => tab = newTab);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
     yield BrowserTestUtils.waitForCondition(() => !!tab, "tab should be present");
 
     is(gBrowser.selectedTab, tab,
        "tab selected in response to the addon-install-confirmation notification");
 
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     let panel = yield notificationPromise;
 
     let notification = panel.childNodes[0];
     is(notification.button.label, "Restart Now", "Should have seen the right button");
     is(notification.getAttribute("label"),
              "XPI Test will be installed after you restart " + gApp + ".",
              "Should have seen the right message");
 
@@ -435,20 +437,20 @@ function test_restartless() {
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "XPI": "restartless.xpi"
     }));
     gBrowser.selectedTab = gBrowser.addTab();
     gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notificationPromise = waitForNotification("addon-install-complete");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     let panel = yield notificationPromise;
 
     let notification = panel.childNodes[0];
     is(notification.getAttribute("label"),
        "XPI Test has been installed successfully.",
        "Should have seen the right message");
 
     let installs = yield getInstalls();
@@ -477,20 +479,20 @@ function test_multiple() {
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "Unsigned XPI": "amosigned.xpi",
       "Restartless XPI": "restartless.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     let panel = yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     yield notificationPromise;
 
     let notification = panel.childNodes[0];
     is(notification.button.label, "Restart Now", "Should have seen the right button");
     is(notification.getAttribute("label"),
        "2 add-ons will be installed after you restart " + gApp + ".",
        "Should have seen the right message");
 
@@ -507,30 +509,32 @@ function test_multiple() {
     Services.perms.remove(makeURI("http://example.com/"), "install");
     yield removeTab();
   });
 },
 
 function test_sequential() {
   return Task.spawn(function* () {
     // This test is only relevant if using the new doorhanger UI
-    if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
+    // TODO: this subtest is disabled until multiple notification prompts are
+    // reworked in bug 1188152
+    if (true || !Preferences.get("xpinstall.customConfirmationUI", false)) {
       return;
     }
     let pm = Services.perms;
     pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "Restartless XPI": "restartless.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     // Should see the right add-on
     let container = document.getElementById("addon-install-confirmation-content");
     is(container.childNodes.length, 1, "Should be one item listed");
     is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
 
     progressPromise = waitForProgressNotification(true, 2);
     triggers = encodeURIComponent(JSON.stringify({
@@ -559,30 +563,30 @@ function test_sequential() {
     is(PopupNotifications.panel.childNodes.length, 1, "Should be the right number of notifications");
     is(PopupNotifications.panel.childNodes[0].id, "addon-install-confirmation-notification",
        "Should only be showing one install confirmation");
 
     // Should still have the right add-on in the confirmation notification
     is(container.childNodes.length, 1, "Should be one item listed");
     is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
 
-    cancelInstallDialog();
+    cancelInstallDialog(installDialog);
 
     ok(PopupNotifications.isPanelOpen, "Panel should still be open");
     is(PopupNotifications.panel.childNodes.length, 1, "Should be the right number of notifications");
     is(PopupNotifications.panel.childNodes[0].id, "addon-install-confirmation-notification",
        "Should still have an install confirmation open");
 
     // Should have the next add-on's confirmation dialog
     is(container.childNodes.length, 1, "Should be one item listed");
     is(container.childNodes[0].firstChild.getAttribute("value"), "Theme Test", "Should have the right add-on");
 
     Services.perms.remove(makeURI("http://example.com"), "install");
     let closePromise = waitForNotificationClose();
-    cancelInstallDialog();
+    cancelInstallDialog(installDialog);
     yield closePromise;
     yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
   });
 },
 
 function test_someUnverified() {
   return Task.spawn(function* () {
     // This test is only relevant if using the new doorhanger UI and allowing
@@ -598,34 +602,34 @@ function test_someUnverified() {
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "Extension XPI": "restartless-unsigned.xpi",
       "Theme XPI": "theme.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notification = document.getElementById("addon-install-confirmation-notification");
     let message = notification.getAttribute("label");
     is(message, "Caution: This site would like to install 2 add-ons in " + gApp +
        ", some of which are unverified. Proceed at your own risk.",
        "Should see the right message");
 
     let container = document.getElementById("addon-install-confirmation-content");
     is(container.childNodes.length, 2, "Should be two items listed");
     is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
     is(container.childNodes[0].lastChild.getAttribute("class"),
        "addon-install-confirmation-unsigned", "Should have the unverified marker");
     is(container.childNodes[1].firstChild.getAttribute("value"), "Theme Test", "Should have the right add-on");
     is(container.childNodes[1].childNodes.length, 1, "Shouldn't have the unverified marker");
 
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     yield notificationPromise;
 
     let [addon, theme] = yield new Promise(resolve => {
       AddonManager.getAddonsByIDs(["restartless-xpi@tests.mozilla.org",
                                   "theme-xpi@tests.mozilla.org"],
                                   function(addons) {
         resolve(addons);
       });
@@ -655,29 +659,29 @@ function test_allUnverified() {
 
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "Extension XPI": "restartless-unsigned.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notification = document.getElementById("addon-install-confirmation-notification");
     let message = notification.getAttribute("label");
     is(message, "Caution: This site would like to install an unverified add-on in " + gApp + ". Proceed at your own risk.");
 
     let container = document.getElementById("addon-install-confirmation-content");
     is(container.childNodes.length, 1, "Should be one item listed");
     is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
     is(container.childNodes[0].childNodes.length, 1, "Shouldn't have the unverified marker");
 
     let notificationPromise = waitForNotification("addon-install-complete");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     yield notificationPromise;
 
     let addon = yield new Promise(resolve => {
       AddonManager.getAddonByID("restartless-xpi@tests.mozilla.org", function(result) {
         resolve(result);
       });
     });
     addon.uninstall();
@@ -690,20 +694,20 @@ function test_allUnverified() {
 function test_url() {
   return Task.spawn(function* () {
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     gBrowser.selectedTab = gBrowser.addTab("about:blank");
     yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
     gBrowser.loadURI(TESTROOT + "amosigned.xpi");
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     let panel = yield notificationPromise;
 
     let notification = panel.childNodes[0];
     is(notification.button.label, "Restart Now", "Should have seen the right button");
     is(notification.getAttribute("label"),
        "XPI Test will be installed after you restart " + gApp + ".",
        "Should have seen the right message");
 
@@ -858,20 +862,20 @@ function test_reload() {
 
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "Unsigned XPI": "amosigned.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     let panel = yield notificationPromise;
 
     let notification = panel.childNodes[0];
     is(notification.button.label, "Restart Now", "Should have seen the right button");
     is(notification.getAttribute("label"),
        "XPI Test will be installed after you restart " + gApp + ".",
        "Should have seen the right message");
 
@@ -901,20 +905,20 @@ function test_theme() {
 
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "Theme XPI": "theme.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     let panel = yield notificationPromise;
 
     let notification = panel.childNodes[0];
     is(notification.button.label, "Restart Now", "Should have seen the right button");
     is(notification.getAttribute("label"),
        "Theme Test will be installed after you restart " + gApp + ".",
        "Should have seen the right message");
 
@@ -981,42 +985,42 @@ function test_renotifyInstalled() {
 
     let progressPromise = waitForProgressNotification();
     let dialogPromise = waitForInstallDialog();
     let triggers = encodeURIComponent(JSON.stringify({
       "XPI": "amosigned.xpi"
     }));
     BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    let installDialog = yield dialogPromise;
 
     // Wait for the complete notification
     let notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     let panel = yield notificationPromise;
 
     let closePromise = waitForNotificationClose();
     // hide the panel (this simulates the user dismissing it)
     panel.hidePopup();
     yield closePromise;
 
     // Install another
     yield new Promise(resolve => executeSoon(resolve));
 
     progressPromise = waitForProgressNotification();
     dialogPromise = waitForInstallDialog();
     gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
     yield progressPromise;
-    yield dialogPromise;
+    installDialog = yield dialogPromise;
 
     info("Timeouts after this probably mean bug 589954 regressed");
 
     // Wait for the complete notification
     notificationPromise = waitForNotification("addon-install-restart");
-    acceptInstallDialog();
+    acceptInstallDialog(installDialog);
     yield notificationPromise;
 
     let installs = yield getInstalls();
     is(installs.length, 1, "Should be one pending installs");
     installs[0].cancel();
 
     Services.perms.remove(makeURI("http://example.com/"), "install");
     yield removeTab();
@@ -1041,29 +1045,28 @@ function test_cancel() {
     anchor.click();
     // Reopen the notification
     anchor.click();
 
     ok(PopupNotifications.isPanelOpen, "Notification should still be open");
     is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
     notification = panel.childNodes[0];
     is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
-    let button = document.getElementById("addon-progress-cancel");
 
     // Cancel the download
     let install = notification.notification.options.installs[0];
     let cancelledPromise = new Promise(resolve => {
       install.addListener({
         onDownloadCancelled: function() {
           install.removeListener(this);
           resolve();
         }
       });
     });
-    EventUtils.synthesizeMouseAtCenter(button, {});
+    EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
     yield cancelledPromise;
 
     yield new Promise(resolve => executeSoon(resolve));
 
     ok(!PopupNotifications.isPanelOpen, "Notification should be closed");
 
     let installs = yield getInstalls();
     is(installs.length, 0, "Should be no pending install");
--- a/browser/base/content/test/popupNotifications/browser.ini
+++ b/browser/base/content/test/popupNotifications/browser.ini
@@ -7,12 +7,14 @@ skip-if = (os == "linux" && (debug || as
 [browser_popupNotification.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_2.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_3.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_4.js]
 skip-if = (os == "linux" && (debug || asan))
+[browser_popupNotification_5.js]
+skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_checkbox.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_reshow_in_background.js]
 skip-if = (os == "linux" && (debug || asan))
--- a/browser/base/content/test/popupNotifications/browser_popupNotification.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification.js
@@ -42,16 +42,60 @@ var tests = [
       triggerSecondaryCommand(popup, 0);
     },
     onHidden: function(popup) {
       ok(this.notifyObj.secondaryActionClicked, "secondaryAction was clicked");
       ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     }
   },
+  { id: "Test#2b",
+    run: function() {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.secondaryActions.push({
+        label: "Extra Secondary Action",
+        accessKey: "E",
+        callback: () => this.extraSecondaryActionClicked = true,
+      });
+      showNotification(this.notifyObj);
+    },
+    onShown: function(popup) {
+      checkPopup(popup, this.notifyObj);
+      triggerSecondaryCommand(popup, 1);
+    },
+    onHidden: function(popup) {
+      ok(this.extraSecondaryActionClicked, "extra secondary action was clicked");
+      ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
+      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
+    }
+  },
+  { id: "Test#2c",
+    run: function() {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.secondaryActions.push({
+        label: "Extra Secondary Action",
+        accessKey: "E",
+        callback: () => ok(false, "unexpected callback invocation"),
+      }, {
+        label: "Other Extra Secondary Action",
+        accessKey: "O",
+        callback: () => this.extraSecondaryActionClicked = true,
+      });
+      showNotification(this.notifyObj);
+    },
+    onShown: function(popup) {
+      checkPopup(popup, this.notifyObj);
+      triggerSecondaryCommand(popup, 2);
+    },
+    onHidden: function(popup) {
+      ok(this.extraSecondaryActionClicked, "extra secondary action was clicked");
+      ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
+      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
+    }
+  },
   { id: "Test#3",
     run: function() {
       this.notifyObj = new BasicNotification(this.id);
       this.notification = showNotification(this.notifyObj);
     },
     onShown: function(popup) {
       checkPopup(popup, this.notifyObj);
       dismissNotification(popup);
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_2.js
@@ -182,32 +182,16 @@ var tests = [
       let promiseTopic = promiseTopicObserved("PopupNotifications-updateNotShowing");
       showNotification(notifyObj);
       yield promiseTopic;
       isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
             "geo anchor should be visible");
       goNext();
     }
   },
-  // Test notification "Not Now" menu item
-  { id: "Test#8",
-    run: function() {
-      this.notifyObj = new BasicNotification(this.id);
-      this.notification = showNotification(this.notifyObj);
-    },
-    onShown: function(popup) {
-      checkPopup(popup, this.notifyObj);
-      triggerSecondaryCommand(popup, 1);
-    },
-    onHidden: function(popup) {
-      ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
-      this.notification.remove();
-      ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
-    }
-  },
   // Test notification close button
   { id: "Test#9",
     run: function() {
       this.notifyObj = new BasicNotification(this.id);
       this.notification = showNotification(this.notifyObj);
     },
     onShown: function(popup) {
       checkPopup(popup, this.notifyObj);
--- a/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_4.js
@@ -155,33 +155,16 @@ var tests = [
                                               "The browser should be active");
       let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
       yield BrowserTestUtils.waitForCondition(() => fm.activeWindow == originalWindow,
                                               "The window should be active")
 
       goNext();
     }
   },
-  // the hideNotNow option
-  { id: "Test#7",
-    run: function() {
-      this.notifyObj = new BasicNotification(this.id);
-      this.notifyObj.options.hideNotNow = true;
-      this.notifyObj.mainAction.dismiss = true;
-      this.notification = showNotification(this.notifyObj);
-    },
-    onShown: function(popup) {
-      // checkPopup verifies that the Not Now item is hidden, and that no separator is added.
-      checkPopup(popup, this.notifyObj);
-      triggerMainCommand(popup);
-    },
-    onHidden: function(popup) {
-      this.notification.remove();
-    }
-  },
   // the main action callback can keep the notification.
   { id: "Test#8",
     run: function() {
       this.notifyObj = new BasicNotification(this.id);
       this.notifyObj.mainAction.dismiss = true;
       this.notification = showNotification(this.notifyObj);
     },
     onShown: function(popup) {
@@ -222,73 +205,10 @@ var tests = [
       };
 
       let notification = showNotification(notifyObj);
       ok(notifyObj.showingCallbackTriggered, "the showing callback was triggered");
       ok(!notifyObj.shownCallbackTriggered, "the shown callback wasn't triggered");
       notification.remove();
       goNext();
     }
-  },
-  // panel updates should fire the showing and shown callbacks again.
-  { id: "Test#11",
-    run: function() {
-      this.notifyObj = new BasicNotification(this.id);
-      this.notification = showNotification(this.notifyObj);
-    },
-    onShown: function(popup) {
-      checkPopup(popup, this.notifyObj);
-
-      this.notifyObj.showingCallbackTriggered = false;
-      this.notifyObj.shownCallbackTriggered = false;
-
-      // Force an update of the panel. This is typically called
-      // automatically when receiving 'activate' or 'TabSelect' events,
-      // but from a setTimeout, which is inconvenient for the test.
-      PopupNotifications._update();
-
-      checkPopup(popup, this.notifyObj);
-
-      this.notification.remove();
-    },
-    onHidden: function() { }
-  },
-  // A first dismissed notification shouldn't stop _update from showing a second notification
-  { id: "Test#12",
-    run: function() {
-      this.notifyObj1 = new BasicNotification(this.id);
-      this.notifyObj1.id += "_1";
-      this.notifyObj1.anchorID = "default-notification-icon";
-      this.notifyObj1.options.dismissed = true;
-      this.notification1 = showNotification(this.notifyObj1);
-
-      this.notifyObj2 = new BasicNotification(this.id);
-      this.notifyObj2.id += "_2";
-      this.notifyObj2.anchorID = "geo-notification-icon";
-      this.notifyObj2.options.dismissed = true;
-      this.notification2 = showNotification(this.notifyObj2);
-
-      this.notification2.dismissed = false;
-      PopupNotifications._update();
-    },
-    onShown: function(popup) {
-      checkPopup(popup, this.notifyObj2);
-      this.notification1.remove();
-      this.notification2.remove();
-    },
-    onHidden: function(popup) { }
-  },
-  // The anchor icon should be shown for notifications in background windows.
-  { id: "Test#13",
-    run: function() {
-      let notifyObj = new BasicNotification(this.id);
-      notifyObj.options.dismissed = true;
-      let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
-      whenDelayedStartupFinished(win, function() {
-        showNotification(notifyObj);
-        let anchor = document.getElementById("default-notification-icon");
-        is(anchor.getAttribute("showing"), "true", "the anchor is shown");
-        win.close();
-        goNext();
-      });
-    }
   }
 ];
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_5.js
@@ -0,0 +1,265 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function test() {
+  waitForExplicitFinish();
+
+  ok(PopupNotifications, "PopupNotifications object exists");
+  ok(PopupNotifications.panel, "PopupNotifications panel exists");
+
+  setup();
+  goNext();
+}
+
+var gNotification;
+
+var tests = [
+  // panel updates should fire the showing and shown callbacks again.
+  { id: "Test#1",
+    run: function() {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notification = showNotification(this.notifyObj);
+    },
+    onShown: function(popup) {
+      checkPopup(popup, this.notifyObj);
+
+      this.notifyObj.showingCallbackTriggered = false;
+      this.notifyObj.shownCallbackTriggered = false;
+
+      // Force an update of the panel. This is typically called
+      // automatically when receiving 'activate' or 'TabSelect' events,
+      // but from a setTimeout, which is inconvenient for the test.
+      PopupNotifications._update();
+
+      checkPopup(popup, this.notifyObj);
+
+      this.notification.remove();
+    },
+    onHidden: function() { }
+  },
+  // A first dismissed notification shouldn't stop _update from showing a second notification
+  { id: "Test#2",
+    run: function() {
+      this.notifyObj1 = new BasicNotification(this.id);
+      this.notifyObj1.id += "_1";
+      this.notifyObj1.anchorID = "default-notification-icon";
+      this.notifyObj1.options.dismissed = true;
+      this.notification1 = showNotification(this.notifyObj1);
+
+      this.notifyObj2 = new BasicNotification(this.id);
+      this.notifyObj2.id += "_2";
+      this.notifyObj2.anchorID = "geo-notification-icon";
+      this.notifyObj2.options.dismissed = true;
+      this.notification2 = showNotification(this.notifyObj2);
+
+      this.notification2.dismissed = false;
+      PopupNotifications._update();
+    },
+    onShown: function(popup) {
+      checkPopup(popup, this.notifyObj2);
+      this.notification1.remove();
+      this.notification2.remove();
+    },
+    onHidden: function(popup) { }
+  },
+  // The anchor icon should be shown for notifications in background windows.
+  { id: "Test#3",
+    run: function() {
+      let notifyObj = new BasicNotification(this.id);
+      notifyObj.options.dismissed = true;
+      let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
+      whenDelayedStartupFinished(win, function() {
+        showNotification(notifyObj);
+        let anchor = document.getElementById("default-notification-icon");
+        is(anchor.getAttribute("showing"), "true", "the anchor is shown");
+        win.close();
+        goNext();
+      });
+    }
+  },
+  // Test that persistent doesn't allow the notification to persist after
+  // navigation.
+  { id: "Test#4",
+    run: function* () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+      yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.addOptions({
+        persistent: true
+      });
+      this.notification = showNotification(this.notifyObj);
+    },
+    onShown: function* (popup) {
+      this.complete = false;
+
+      yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
+      yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
+
+      // This code should not be executed.
+      ok(false, "Should have removed the notification after navigation");
+      // Properly dismiss and cleanup in case the unthinkable happens.
+      this.complete = true;
+      triggerSecondaryCommand(popup, 0);
+    },
+    onHidden: function(popup) {
+      ok(!this.complete, "Should have hidden the notification after navigation");
+      this.notification.remove();
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
+  // Test that persistent allows the notification to persist until explicitly
+  // dismissed.
+  { id: "Test#5",
+    run: function* () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+      yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.addOptions({
+        persistent: true
+      });
+      this.notification = showNotification(this.notifyObj);
+    },
+    onShown: function* (popup) {
+      this.complete = false;
+
+      // Notification should persist after attempt to dismiss by clicking on the
+      // content area.
+      let browser = gBrowser.selectedBrowser;
+      yield BrowserTestUtils.synthesizeMouseAtCenter("body", {}, browser)
+
+      // Notification should be hidden after dismissal via Don't Allow.
+      this.complete = true;
+      triggerSecondaryCommand(popup, 0);
+    },
+    onHidden: function(popup) {
+      ok(this.complete, "Should have hidden the notification after clicking Not Now");
+      this.notification.remove();
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
+  // Test that persistent panels are still open after switching to another tab
+  // and back.
+  { id: "Test#6a",
+    run: function* () {
+      this.notifyObj = new BasicNotification(this.id);
+      this.notifyObj.options.persistent = true;
+      gNotification = showNotification(this.notifyObj);
+    },
+    onShown: function* (popup) {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+      info("Waiting for the new tab to load.");
+      yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
+    },
+    onHidden: function(popup) {
+      ok(true, "Should have hidden the notification after tab switch");
+      gBrowser.removeTab(gBrowser.selectedTab);
+      gBrowser.selectedTab = this.oldSelectedTab;
+    }
+  },
+  // Second part of the previous test that compensates for the limitation in
+  // runNextTest that expects a single onShown/onHidden invocation per test.
+  { id: "Test#6b",
+    run: function* () {
+      let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
+      ok(id.endsWith("Test#6a"), "Should have found the notification from Test6a");
+      ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the tab");
+      gNotification.remove();
+      gNotification = null;
+      goNext();
+    }
+  },
+  // Test that persistent panels are still open after switching to another
+  // window and back.
+  { id: "Test#7",
+    run: function* () {
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+      let notifyObj = new BasicNotification(this.id);
+      notifyObj.options.persistent = true;
+      this.notification = showNotification(notifyObj);
+      let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
+      whenDelayedStartupFinished(win, () => {
+        ok(notifyObj.shownCallbackTriggered, "Should have triggered the shown callback");
+        let anchor = win.document.getElementById("default-notification-icon");
+        win.PopupNotifications._reshowNotifications(anchor);
+        ok(win.PopupNotifications.panel.childNodes.length == 0,
+           "no notification displayed in new window");
+        ok(PopupNotifications.isPanelOpen, "Should be still showing the popup in the first window");
+        win.close();
+        let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
+        ok(id.endsWith("Test#7"), "Should have found the notification from Test7");
+        ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the window");
+        this.notification.remove();
+        gBrowser.removeTab(gBrowser.selectedTab);
+        gBrowser.selectedTab = this.oldSelectedTab;
+        goNext();
+      });
+    }
+  },
+  // Test that only the first persistent notification is shown on update
+  { id: "Test#8",
+    run: function() {
+      this.notifyObj1 = new BasicNotification(this.id);
+      this.notifyObj1.id += "_1";
+      this.notifyObj1.anchorID = "default-notification-icon";
+      this.notifyObj1.options.persistent = true;
+      this.notification1 = showNotification(this.notifyObj1);
+
+      this.notifyObj2 = new BasicNotification(this.id);
+      this.notifyObj2.id += "_2";
+      this.notifyObj2.anchorID = "geo-notification-icon";
+      this.notifyObj2.options.persistent = true;
+      this.notification2 = showNotification(this.notifyObj2);
+
+      PopupNotifications._update();
+    },
+    onShown: function(popup) {
+      checkPopup(popup, this.notifyObj1);
+      this.notification1.remove();
+      this.notification2.remove();
+    },
+    onHidden: function(popup) { }
+  },
+  // Test that persistent notifications are shown stacked by anchor on update
+  { id: "Test#9",
+    run: function() {
+      this.notifyObj1 = new BasicNotification(this.id);
+      this.notifyObj1.id += "_1";
+      this.notifyObj1.anchorID = "default-notification-icon";
+      this.notifyObj1.options.persistent = true;
+      this.notification1 = showNotification(this.notifyObj1);
+
+      this.notifyObj2 = new BasicNotification(this.id);
+      this.notifyObj2.id += "_2";
+      this.notifyObj2.anchorID = "geo-notification-icon";
+      this.notifyObj2.options.persistent = true;
+      this.notification2 = showNotification(this.notifyObj2);
+
+      this.notifyObj3 = new BasicNotification(this.id);
+      this.notifyObj3.id += "_3";
+      this.notifyObj3.anchorID = "default-notification-icon";
+      this.notifyObj3.options.persistent = true;
+      this.notification3 = showNotification(this.notifyObj3);
+
+      PopupNotifications._update();
+    },
+    onShown: function(popup) {
+      let notifications = popup.childNodes;
+      is(notifications.length, 2, "two notifications displayed");
+      let [notification1, notification2] = notifications;
+      is(notification1.id, this.notifyObj1.id + "-notification", "id 1 matches");
+      is(notification2.id, this.notifyObj3.id + "-notification", "id 2 matches");
+
+      this.notification1.remove();
+      this.notification2.remove();
+      this.notification3.remove();
+    },
+    onHidden: function(popup) { }
+  },
+];
--- a/browser/base/content/test/popupNotifications/head.js
+++ b/browser/base/content/test/popupNotifications/head.js
@@ -208,35 +208,34 @@ function checkPopup(popup, notifyObj) {
   is(notification.getAttribute("label"), notifyObj.message, "message matches");
   is(notification.id, notifyObj.id + "-notification", "id matches");
   if (notifyObj.mainAction) {
     is(notification.getAttribute("buttonlabel"), notifyObj.mainAction.label,
        "main action label matches");
     is(notification.getAttribute("buttonaccesskey"),
        notifyObj.mainAction.accessKey, "main action accesskey matches");
   }
-  let actualSecondaryActions =
-    Array.filter(notification.childNodes, child => child.nodeName == "menuitem");
-  let secondaryActions = notifyObj.secondaryActions || [];
-  let actualSecondaryActionsCount = actualSecondaryActions.length;
-  if (notifyObj.options.hideNotNow) {
-    is(notification.getAttribute("hidenotnow"), "true", "'Not Now' item hidden");
-    if (secondaryActions.length)
-      is(notification.lastChild.tagName, "menuitem", "no menuseparator");
+  if (notifyObj.secondaryActions && notifyObj.secondaryActions.length > 0) {
+    let secondaryAction = notifyObj.secondaryActions[0];
+    is(notification.getAttribute("secondarybuttonlabel"), secondaryAction.label,
+       "secondary action label matches");
+    is(notification.getAttribute("secondarybuttonaccesskey"),
+       secondaryAction.accessKey, "secondary action accesskey matches");
   }
-  else if (secondaryActions.length) {
-    is(notification.lastChild.tagName, "menuseparator", "menuseparator exists");
-  }
-  is(actualSecondaryActionsCount, secondaryActions.length,
-    actualSecondaryActions.length + " secondary actions");
-  secondaryActions.forEach(function(a, i) {
-    is(actualSecondaryActions[i].getAttribute("label"), a.label,
-       "label for secondary action " + i + " matches");
-    is(actualSecondaryActions[i].getAttribute("accesskey"), a.accessKey,
-       "accessKey for secondary action " + i + " matches");
+  // Additional secondary actions appear as menu items.
+  let actualExtraSecondaryActions =
+    Array.filter(notification.childNodes, child => child.nodeName == "menuitem");
+  let extraSecondaryActions = notifyObj.secondaryActions ? notifyObj.secondaryActions.slice(1) : [];
+  is(actualExtraSecondaryActions.length, extraSecondaryActions.length,
+     "number of extra secondary actions matches");
+  extraSecondaryActions.forEach(function(a, i) {
+    is(actualExtraSecondaryActions[i].getAttribute("label"), a.label,
+       "label for extra secondary action " + i + " matches");
+    is(actualExtraSecondaryActions[i].getAttribute("accesskey"), a.accessKey,
+       "accessKey for extra secondary action " + i + " matches");
   });
 }
 
 XPCOMUtils.defineLazyGetter(this, "gActiveListeners", () => {
   let listeners = new Map();
   registerCleanupFunction(() => {
     for (let [listener, eventName] of listeners) {
       PopupNotifications.panel.removeEventListener(eventName, listener, false);
@@ -258,36 +257,39 @@ function onPopupEvent(eventName, callbac
   PopupNotifications.panel.addEventListener(eventName, listener, false);
 }
 
 function triggerMainCommand(popup) {
   let notifications = popup.childNodes;
   ok(notifications.length > 0, "at least one notification displayed");
   let notification = notifications[0];
   info("Triggering main command for notification " + notification.id);
-  // 20, 10 so that the inner button is hit
-  EventUtils.synthesizeMouse(notification.button, 20, 10, {});
+  EventUtils.synthesizeMouseAtCenter(notification.button, {});
 }
 
 function triggerSecondaryCommand(popup, index) {
   let notifications = popup.childNodes;
   ok(notifications.length > 0, "at least one notification displayed");
   let notification = notifications[0];
   info("Triggering secondary command for notification " + notification.id);
-  // Cancel the arrow panel slide-in transition (bug 767133) such that
-  // it won't interfere with us interacting with the dropdown.
-  document.getAnonymousNodes(popup)[0].style.transition = "none";
 
-  notification.button.focus();
+  if (index == 0) {
+    EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
+    return;
+  }
+
+  // Extra secondary actions appear in a menu.
+  notification.secondaryButton.nextSibling.nextSibling.focus();
 
   popup.addEventListener("popupshown", function handle() {
     popup.removeEventListener("popupshown", handle, false);
     info("Command popup open for notification " + notification.id);
-    // Press down until the desired command is selected
-    for (let i = 0; i <= index; i++) {
+    // Press down until the desired command is selected. Decrease index by one
+    // since the secondary action was handled above.
+    for (let i = 0; i <= index - 1; i++) {
       EventUtils.synthesizeKey("VK_DOWN", {});
     }
     // Activate
     EventUtils.synthesizeKey("VK_RETURN", {});
   }, false);
 
   // One down event to open the popup
   info("Open the popup to trigger secondary command for notification " + notification.id);
--- a/browser/base/content/test/social/browser_social_activation.js
+++ b/browser/base/content/test/social/browser_social_activation.js
@@ -106,42 +106,54 @@ function clickAddonRemoveButton(tab, aCa
       executeSoon(function() { aCallback(addon); });
     });
 
     BrowserTestUtils.synthesizeMouseAtCenter(button, {}, tab.linkedBrowser);
   });
 }
 
 function activateOneProvider(manifest, finishActivation, aCallback) {
-  info("activating provider " + manifest.name);
-  let panel = document.getElementById("servicesInstall-notification");
-  BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
-    ok(!panel.hidden, "servicesInstall-notification panel opened");
-    if (finishActivation)
-      panel.button.click();
-    else
-      panel.closebutton.click();
-  });
-  BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden").then(() => {
-    ok(panel.hidden, "servicesInstall-notification panel hidden");
-    if (!finishActivation) {
-      ok(panel.hidden, "activation panel is not showing");
-      executeSoon(aCallback);
+  Task.spawn(function* () {
+    info("activating provider " + manifest.name);
+
+    // Wait for the helper callback and the popup shown event in any order.
+    let popupShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
+                                                   "popupshown");
+    yield new Promise(resolve => activateProvider(manifest.origin, resolve));
+    yield popupShown;
+
+    info("servicesInstall-notification panel opened");
+
+    // Start waiting for the activation event before the click on the button.
+    let providerLoaded = finishActivation ?
+                         waitForProviderLoad(manifest.origin) : null;
+    let popupHidden = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
+                                                    "popuphidden");
+
+    // We need to wait for PopupNotifications.jsm to place the element.
+    let notification;
+    yield BrowserTestUtils.waitForCondition(
+          () => (notification = PopupNotifications.panel.childNodes[0]));
+    is(notification.id, "servicesInstall-notification");
+
+    if (finishActivation) {
+      notification.button.click();
     } else {
-      waitForProviderLoad(manifest.origin).then(() => {
-        checkSocialUI();
-        executeSoon(aCallback);
-      });
+      notification.closebutton.click();
     }
-  });
+
+    yield providerLoaded;
+    yield popupHidden;
 
-  // the test will continue as the popup events fire...
-  activateProvider(manifest.origin, function() {
-    info("waiting on activation panel to open/close...");
-  });
+    info("servicesInstall-notification panel hidden");
+
+    if (finishActivation) {
+      checkSocialUI();
+    }
+  }).then(() => executeSoon(aCallback)).catch(ex => ok(false, ex));
 }
 
 var gTestDomains = ["https://example.com", "https://test1.example.com", "https://test2.example.com"];
 var gProviders = [
   {
     name: "provider 1",
     origin: "https://example.com",
     shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html?provider1",
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media.js
@@ -469,17 +469,17 @@ var gTests = [
     gIdentityHandler._identityPopup.hidden = true;
     yield expectNoObserverCalled();
 
     yield closeStream();
   }
 },
 
 {
-  desc: "'Always Allow' ignored and not shown on http pages",
+  desc: "'Always Allow' disabled on http pages",
   run: function* checkNoAlwaysOnHttp() {
     // Load an http page instead of the https version.
     let browser = gBrowser.selectedBrowser;
     browser.loadURI(browser.documentURI.spec.replace("https://", "http://"));
     yield BrowserTestUtils.browserLoaded(browser);
 
     // Initially set both permissions to 'allow'.
     let Perms = Services.perms;
@@ -489,26 +489,26 @@ var gTests = [
 
     // Request devices and expect a prompt despite the saved 'Allow' permission,
     // because the connection isn't secure.
     let promise = promisePopupNotificationShown("webRTC-shareDevices");
     yield promiseRequestDevice(true, true);
     yield promise;
     yield expectObserverCalled("getUserMedia:request");
 
-    // Ensure that the 'Always Allow' action isn't shown.
-    let alwaysLabel = gNavigatorBundle.getString("getUserMedia.always.label");
-    ok(!!alwaysLabel, "found the 'Always Allow' localized label");
-    let labels = [];
+    // Ensure that checking the 'Remember this decision' checkbox disables
+    // 'Allow'.
     let notification = PopupNotifications.panel.firstChild;
-    for (let node of notification.childNodes) {
-      if (node.localName == "menuitem")
-        labels.push(node.getAttribute("label"));
-    }
-    is(labels.indexOf(alwaysLabel), -1, "The 'Always Allow' item isn't shown");
+    let checkbox = notification.checkbox;
+    ok(!!checkbox, "checkbox is present");
+    ok(!checkbox.checked, "checkbox is not checked");
+    checkbox.click();
+    ok(checkbox.checked, "checkbox now checked");
+    ok(notification.button.disabled, "Allow button is disabled");
+    ok(!notification.hasAttribute("warninghidden"), "warning message is shown");
 
     // Cleanup.
     yield closeStream(true);
     Perms.remove(uri, "camera");
     Perms.remove(uri, "microphone");
   }
 }
 
--- a/browser/base/content/test/webrtc/head.js
+++ b/browser/base/content/test/webrtc/head.js
@@ -300,32 +300,27 @@ function promiseNoPopupNotification(aNam
 }
 
 const kActionAlways = 1;
 const kActionDeny = 2;
 const kActionNever = 3;
 
 function activateSecondaryAction(aAction) {
   let notification = PopupNotifications.panel.firstChild;
-  notification.button.focus();
-  let popup = notification.menupopup;
-  popup.addEventListener("popupshown", function() {
-    popup.removeEventListener("popupshown", arguments.callee, false);
-
-    // Press 'down' as many time as needed to select the requested action.
-    while (aAction--)
-      EventUtils.synthesizeKey("VK_DOWN", {});
-
-    // Activate
-    EventUtils.synthesizeKey("VK_RETURN", {});
-  }, false);
-
-  // One down event to open the popup
-  EventUtils.synthesizeKey("VK_DOWN",
-                           { altKey: !navigator.platform.includes("Mac") });
+  switch (aAction) {
+    case kActionNever:
+      notification.checkbox.setAttribute("checked", true); // fallthrough
+    case kActionDeny:
+      notification.secondaryButton.click();
+      break;
+    case kActionAlways:
+      notification.checkbox.setAttribute("checked", true);
+      notification.button.click();
+      break;
+  }
 }
 
 function getMediaCaptureState() {
   return new Promise(resolve => {
     let mm = _mm();
     mm.addMessageListener("Test:MediaCaptureState", ({data}) => {
       resolve(data);
     });
--- a/browser/components/contextualidentity/content/usercontext.css
+++ b/browser/components/contextualidentity/content/usercontext.css
@@ -78,14 +78,14 @@
   background-repeat: no-repeat;
 }
 
 .userContext-icon,
 .menuitem-iconic[data-usercontextid] > .menu-iconic-left > .menu-iconic-icon,
 .subviewbutton[usercontextid] > .toolbarbutton-icon,
 #userContext-indicator {
   background-image: var(--identity-icon);
-  filter: url(chrome://browser/skin/filters.svg#fill);
+  filter: url(chrome://global/skin/filters.svg#fill);
   fill: var(--identity-icon-color);
   background-size: contain;
   background-repeat: no-repeat;
   background-position: center center;
 }
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload.js
@@ -82,37 +82,43 @@ add_task(function* testBrowserActionDisa
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
       "browser_action": {
         "default_popup": "popup.html",
         "browser_style": true,
       },
     },
 
-    background() {
-      browser.browserAction.disable();
+    background: async function() {
+      await browser.browserAction.disable();
+      browser.test.sendMessage("browserAction-disabled");
     },
 
     files: {
       "popup.html": `<!DOCTYPE html><html><head><meta charset="utf-8"><script src="popup.js"></script></head></html>`,
       "popup.js"() {
         browser.test.fail("Should not get here");
       },
     },
   });
 
   yield extension.startup();
 
+  yield extension.awaitMessage("browserAction-disabled");
+
   const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
 
   let ext = GlobalManager.extensionMap.get(extension.id);
   let browserAction = browserActionFor(ext);
 
   let widget = getBrowserActionWidget(extension).forWindow(window);
 
+  is(widget.node.getAttribute("disabled"), "true", "Button is disabled");
+  is(browserAction.pendingPopup, null, "Have no pending popup prior to click");
+
   // Test canceled click.
   EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);
 
   is(browserAction.pendingPopup, null, "Have no pending popup");
   is(browserAction.pendingPopupTimeout, null, "Have no pending popup timeout");
 
   EventUtils.synthesizeMouseAtCenter(document.documentElement, {type: "mouseup", button: 0}, window);
 
--- a/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
+++ b/browser/components/extensions/test/browser/browser_ext_windows_create_tabId.js
@@ -99,18 +99,16 @@ add_task(function* testWindowCreate() {
       let readyPromise = Promise.all([
         // tabs.onUpdated can be invoked between the call of windows.create and
         // the invocation of its callback/promise, so set up the listeners
         // before creating the window.
         promiseTabUpdated("http://example.com/"),
         promiseTabUpdated("http://example.org/"),
       ]);
 
-      await new Promise(resolve => setTimeout(resolve, 0));
-
       window = await browser.windows.create({url: ["http://example.com/", "http://example.org/"]});
       await readyPromise;
 
       browser.test.assertEq(2, window.tabs.length, "2 tabs were opened in new window");
       browser.test.assertEq("about:blank", window.tabs[0].url, "about:blank, page not loaded yet");
       browser.test.assertEq("about:blank", window.tabs[1].url, "about:blank, page not loaded yet");
 
       window = await browser.windows.get(window.id, {populate: true});
--- a/browser/components/extensions/test/browser/browser_ext_windows_events.js
+++ b/browser/components/extensions/test/browser/browser_ext_windows_events.js
@@ -79,16 +79,18 @@ add_task(function* testWindowsEvents() {
   let winId = yield extension.awaitMessage(`window-focus-changed`);
   is(winId, win1Id, "Got focus change event for the correct window ID.");
 
   info(`Create browser window 2`);
   let win2 = yield BrowserTestUtils.openNewBrowserWindow();
   let win2Id = yield extension.awaitMessage("window-created");
   info(`Window 2 ID: ${win2Id}`);
 
+  win2.focus();
+
   winId = yield extension.awaitMessage(`window-focus-changed`);
   is(winId, win2Id, "Got focus change event for the correct window ID.");
 
   info(`Focus browser window 1`);
   yield focusWindow(win1);
 
   winId = yield extension.awaitMessage(`window-focus-changed`);
   is(winId, win1Id, "Got focus change event for the correct window ID.");
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2849,18 +2849,18 @@ var E10SAccessibilityCheck = {
     let secondaryActions = [{
       label: win.gNavigatorBundle.getString("e10s.accessibilityNotice.enableAndRestart.label"),
       accessKey: win.gNavigatorBundle.getString("e10s.accessibilityNotice.enableAndRestart.accesskey"),
       callback: restartCallback,
     }];
     let options = {
       popupIconURL: "chrome://browser/skin/e10s-64@2x.png",
       learnMoreURL: Services.urlFormatter.formatURLPref("app.support.e10sAccessibilityUrl"),
+      persistent: true,
       persistWhileVisible: true,
-      hideNotNow: true,
     };
 
     notification =
       win.PopupNotifications.show(browser, "a11y_enabled_with_e10s",
                                   promptMessage, null, mainAction,
                                   secondaryActions, options);
   },
 };
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
@@ -19,19 +19,19 @@ add_task(function* test() {
       // Wait until the notification is available.
       while (!notification){
         yield new Promise(resolve => { executeSoon(resolve); });
         let notification = aWindow.PopupNotifications.getNotification("geolocation");
       }
 
       if (aPrivateMode) {
         // Make sure the notification is correctly displayed without a remember control
-        is(notification.secondaryActions.length, 0, "Secondary actions shouldn't exist (always/never remember)");
+        ok(!notification.options.checkbox.show, "Secondary actions should exist (always/never remember)");
       } else {
-        ok(notification.secondaryActions.length > 1, "Secondary actions should exist (always/never remember)");
+        ok(notification.options.checkbox.show, "Secondary actions should exist (always/never remember)");
       }
       notification.remove();
 
       aWindow.gBrowser.removeCurrentTab();
     });
   };
 
   let win = yield BrowserTestUtils.openNewBrowserWindow();
--- a/browser/components/sessionstore/SessionHistory.jsm
+++ b/browser/components/sessionstore/SessionHistory.jsm
@@ -25,18 +25,18 @@ function debug(msg) {
 /**
  * The external API exported by this module.
  */
 this.SessionHistory = Object.freeze({
   isEmpty: function (docShell) {
     return SessionHistoryInternal.isEmpty(docShell);
   },
 
-  collect: function (docShell) {
-    return SessionHistoryInternal.collect(docShell);
+  collect: function (docShell, aFromIdx = -1) {
+    return SessionHistoryInternal.collect(docShell, aFromIdx);
   },
 
   restore: function (docShell, tabData) {
     SessionHistoryInternal.restore(docShell, tabData);
   }
 });
 
 /**
@@ -64,21 +64,25 @@ var SessionHistoryInternal = {
     return uri == "about:blank" && history.count == 0;
   },
 
   /**
    * Collects session history data for a given docShell.
    *
    * @param docShell
    *        The docShell that owns the session history.
+   * @param aFromIdx
+   *        The starting local index to collect the history from.
+   * @return An object reprereseting a partial global history update.
    */
-  collect: function (docShell) {
+  collect: function (docShell, aFromIdx = -1) {
     let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
     let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
     let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal);
+    let ihistory = history.QueryInterface(Ci.nsISHistory);
 
     let data = {entries: [], userContextId: loadContext.originAttributes.userContextId };
 
     if (history && history.count > 0) {
       // Loop over the transaction linked list directly so we can get the
       // persist property for each transaction.
       for (let txn = history.rootTransaction; txn; txn = txn.next) {
         let entry = this.serializeEntry(txn.sHEntry);
@@ -102,16 +106,33 @@ var SessionHistoryInternal = {
       // record it. For about:blank we explicitly want an empty array without
       // an 'index' property to denote that there are no history entries.
       if (uri != "about:blank" || (body && body.hasChildNodes())) {
         data.entries.push({ url: uri });
         data.index = 1;
       }
     }
 
+    // Check if we should discard some of the entries which didn't change
+    if (aFromIdx > -1) {
+      data.entries.splice(0, aFromIdx + 1);
+    }
+
+    // Transform the entries from local to global index space.
+    data.index += ihistory.globalIndexOffset;
+    data.fromIdx = aFromIdx + ihistory.globalIndexOffset;
+
+    // If we are not the most recent partialSHistory in our groupedSHistory, we
+    // need to make certain that we don't replace the entries from the following
+    // SHistories - so we replace only the number of entries which our SHistory
+    // takes up.
+    if (ihistory.globalIndexOffset + ihistory.count < ihistory.globalCount) {
+      data.toIdx = data.fromIdx + ihistory.count;
+    }
+
     return data;
   },
 
   /**
    * Get an object that is a serialized representation of a History entry.
    *
    * @param shEntry
    *        nsISHEntry instance
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -966,16 +966,28 @@ var SessionStoreInternal = {
         if (target.namespaceURI == NS_XUL &&
             target.localName == "browser" &&
             target.frameLoader &&
             target.permanentKey) {
           this._lastKnownFrameLoader.set(target.permanentKey, target.frameLoader);
           this.resetEpoch(target);
         }
         break;
+      case "BrowserWillChangeProcess":
+        let promise = TabStateFlusher.flush(target);
+        target.frameLoader.addProcessChangeBlockingPromise(promise);
+        break;
+      case "BrowserChangedProcess":
+        let newEpoch = 1 + Math.max(this.getCurrentEpoch(target),
+                                    this.getCurrentEpoch(aEvent.otherBrowser));
+        this.setCurrentEpoch(target, newEpoch);
+        target.messageManager.sendAsyncMessage("SessionStore:becomeActiveProcess", {
+          epoch: newEpoch
+        });
+        break;
       default:
         throw new Error(`unhandled event ${aEvent.type}?`);
     }
     this._clearRestoringWindows();
   },
 
   /**
    * Generate a unique window identifier
@@ -1032,16 +1044,18 @@ var SessionStoreInternal = {
     }
     // notification of tab add/remove/selection/show/hide
     TAB_EVENTS.forEach(function(aEvent) {
       tabbrowser.tabContainer.addEventListener(aEvent, this, true);
     }, this);
 
     // Keep track of a browser's latest frameLoader.
     aWindow.gBrowser.addEventListener("XULFrameLoaderCreated", this);
+    aWindow.gBrowser.addEventListener("BrowserChangedProcess", this);
+    aWindow.gBrowser.addEventListener("BrowserWillChangeProcess", this);
   },
 
   /**
    * Initializes a given window.
    *
    * Windows are registered as soon as they are created but we need to wait for
    * the session file to load, and the initial window's delayed startup to
    * finish before initializing a window, i.e. restoring data into it.
@@ -1286,16 +1300,18 @@ var SessionStoreInternal = {
 
     let browsers = Array.from(tabbrowser.browsers);
 
     TAB_EVENTS.forEach(function(aEvent) {
       tabbrowser.tabContainer.removeEventListener(aEvent, this, true);
     }, this);
 
     aWindow.gBrowser.removeEventListener("XULFrameLoaderCreated", this);
+    aWindow.gBrowser.removeEventListener("BrowserChangedProcess", this);
+    aWindow.gBrowser.removeEventListener("BrowserWillChangeProcess", this);
 
     let winData = this._windows[aWindow.__SSi];
 
     // Collect window data only when *not* closed during shutdown.
     if (RunState.isRunning) {
       // Grab the most recent window data. The tab data will be updated
       // once we finish flushing all of the messages from the tabs.
       let tabMap = this._collectWindowData(aWindow);
@@ -4408,16 +4424,24 @@ var SessionStoreInternal = {
    */
   startNextEpoch(browser) {
     let next = this.getCurrentEpoch(browser) + 1;
     this._browserEpochs.set(browser.permanentKey, next);
     return next;
   },
 
   /**
+   * Manually set the epoch to a given value.
+   */
+  setCurrentEpoch(aBrowser, aEpoch) {
+    this._browserEpochs.set(aBrowser.permanentKey, aEpoch);
+    return aEpoch;
+  },
+
+  /**
    * Returns the current epoch for the given <browser>. If we haven't assigned
    * a new epoch this will default to zero for new tabs.
    */
   getCurrentEpoch(browser) {
     return this._browserEpochs.get(browser.permanentKey) || 0;
   },
 
   /**
--- a/browser/components/sessionstore/TabStateCache.jsm
+++ b/browser/components/sessionstore/TabStateCache.jsm
@@ -108,25 +108,29 @@ var TabStateCacheInternal = {
   updatePartialHistoryChange: function (data, change) {
     const kLastIndex = Number.MAX_SAFE_INTEGER - 1;
 
     if (!data.history) {
       data.history = { entries: [] };
     }
 
     let history = data.history;
+    let toIdx = history.entries.length;
+    if ("toIdx" in change) {
+      toIdx = Math.min(toIdx, change.toIdx + 1);
+    }
+
     for (let key of Object.keys(change)) {
       if (key == "entries") {
         if (change.fromIdx != kLastIndex) {
-          history.entries.splice(change.fromIdx + 1);
-          while (change.entries.length) {
-            history.entries.push(change.entries.shift());
-          }
+          let start = change.fromIdx + 1;
+          history.entries.splice.apply(
+            history.entries, [start, toIdx - start].concat(change.entries));
         }
-      } else if (key != "fromIndex") {
+      } else if (key != "fromIdx" && key != "toIdx") {
         history[key] = change[key];
       }
     }
   },
 
   /**
    * Updates cached data for a given |tab| or associated |browser|.
    *
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -109,16 +109,17 @@ var EventListener = {
  */
 var MessageListener = {
 
   MESSAGES: [
     "SessionStore:restoreHistory",
     "SessionStore:restoreTabContent",
     "SessionStore:resetRestore",
     "SessionStore:flush",
+    "SessionStore:becomeActiveProcess",
   ],
 
   init: function () {
     this.MESSAGES.forEach(m => addMessageListener(m, this));
   },
 
   receiveMessage: function ({name, data}) {
     // The docShell might be gone. Don't process messages,
@@ -143,16 +144,28 @@ var MessageListener = {
         this.restoreTabContent(data);
         break;
       case "SessionStore:resetRestore":
         gContentRestore.resetRestore();
         break;
       case "SessionStore:flush":
         this.flush(data);
         break;
+      case "SessionStore:becomeActiveProcess":
+        let shistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
+        // Check if we are at the end of the current session history, if we are,
+        // it is safe for us to collect and transmit our session history, so
+        // transmit all of it. Otherwise, we only want to transmit our index changes,
+        // so collect from kLastIndex.
+        if (shistory.globalCount - shistory.globalIndexOffset == shistory.count) {
+          SessionHistoryListener.collect();
+        } else {
+          SessionHistoryListener.collectFrom(kLastIndex);
+        }
+        break;
       default:
         debug("received unknown message '" + name + "'");
         break;
     }
   },
 
   restoreHistory({epoch, tabData, loadArguments, isRemotenessUpdate}) {
     gContentRestore.restoreHistory(tabData, loadArguments, {
@@ -250,19 +263,22 @@ var SessionHistoryListener = {
   uninit: function () {
     let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
     if (sessionHistory) {
       sessionHistory.removeSHistoryListener(this);
     }
   },
 
   collect: function () {
-    this._fromIdx = kNoIndex;
+    // We want to send down a historychange even for full collects in case our
+    // session history is a partial session history, in which case we don't have
+    // enough information for a full update. collectFrom(-1) tells the collect
+    // function to collect all data avaliable in this process.
     if (docShell) {
-      MessageQueue.push("history", () => SessionHistory.collect(docShell));
+      this.collectFrom(-1);
     }
   },
 
   _fromIdx: kNoIndex,
 
   // History can grow relatively big with the nested elements, so if we don't have to, we
   // don't want to send the entire history all the time. For a simple optimization
   // we keep track of the smallest index from after any change has occured and we just send
@@ -281,25 +297,17 @@ var SessionHistoryListener = {
     }
 
     this._fromIdx = idx;
     MessageQueue.push("historychange", () => {
       if (this._fromIdx === kNoIndex) {
         return null;
       }
 
-      let history = SessionHistory.collect(docShell);
-      if (kLastIndex == idx) {
-        history.entries = [];
-      } else {
-        history.entries.splice(0, this._fromIdx + 1);
-      }
-
-      history.fromIdx = this._fromIdx;
-
+      let history = SessionHistory.collect(docShell, this._fromIdx);
       this._fromIdx = kNoIndex;
       return history;
     });
   },
 
   handleEvent(event) {
     this.collect();
   },
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -233,8 +233,10 @@ run-if = e10s
 run-if = e10s
 [browser_background_tab_crash.js]
 run-if = e10s && crashreporter
 
 # Disabled on debug for frequent intermittent failures:
 [browser_undoCloseById.js]
 skip-if = debug
 [browser_docshell_uuid_consistency.js]
+[browser_grouped_session_store.js]
+skip-if = !e10s # GroupedSHistory is e10s-only
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_grouped_session_store.js
@@ -0,0 +1,135 @@
+add_task(function* () {
+  const URIs = [
+    "data:text/html,1",
+    "data:text/html,2",
+    "data:text/html,3",
+    "data:text/html,4",
+    "data:text/html,5",
+  ];
+
+  const {TabStateCache} = Cu.import("resource:///modules/sessionstore/TabStateCache.jsm", {});
+  const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
+
+  yield SpecialPowers.pushPrefEnv({
+    set: [["browser.groupedhistory.enabled", true]]
+  });
+
+  // Check that the data stored in the TabStateCache is correct for the current state.
+  function* validate(browser, length, index) {
+    yield TabStateFlusher.flush(browser);
+    let {history} = TabStateCache.get(browser);
+    is(history.entries.length, length, "Lengths match");
+    for (let i = 0; i < length; ++i) {
+      is(history.entries[i].url, URIs[i], "URI at index " + i + " matches");
+    }
+    is(history.index, index, "Index matches");
+    yield ContentTask.spawn(browser, [index, length], function* ([index, length]) {
+      let webNav = content.window.QueryInterface(Ci.nsIInterfaceRequestor)
+            .getInterface(Ci.nsIWebNavigation);
+      is(webNav.canGoForward, index < length, "canGoForward is correct");
+      is(webNav.canGoBack, index > 1, "canGoBack is correct");
+    });
+  }
+
+  // Wait for a process change and then fulfil the promise.
+  function awaitProcessChange(browser) {
+    return new Promise(resolve => {
+      browser.addEventListener("BrowserChangedProcess", function bcp(e) {
+        browser.removeEventListener("BrowserChangedProcess", bcp);
+        ok(true, "The browser changed process!");
+        resolve();
+      });
+    });
+  }
+
+  // Order of events:
+  // Load [0], load [1], prerender [2], load [2], load [3]
+  // Back [2], Back [1], Forward [2], Back [0], Forward [3]
+  // Prerender [4], Back [0], Forward [2], Load [3'], Back [0].
+  yield BrowserTestUtils.withNewTab({ gBrowser, url: URIs[0] }, function* (browser1) {
+    yield* validate(browser1, 1, 1);
+
+    browser1.loadURI(URIs[1], null, null);
+    yield BrowserTestUtils.browserLoaded(browser1);
+    yield* validate(browser1, 2, 2);
+
+    // Create a new hidden prerendered tab to swap to.
+    let tab2 = gBrowser.loadOneTab(URIs[2], {
+      referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
+      allowThirdPartyFixup: true,
+      relatedToCurrent: true,
+      isPrerendered: true,
+    });
+    yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
+    browser1.frameLoader.appendPartialSessionHistoryAndSwap(
+      tab2.linkedBrowser.frameLoader);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 3, 3);
+
+    browser1.loadURI(URIs[3], null, null);
+    yield BrowserTestUtils.browserLoaded(browser1);
+    yield* validate(browser1, 4, 4);
+
+    // In process navigate back.
+    let p = BrowserTestUtils.waitForContentEvent(browser1, "pageshow");
+    browser1.goBack();
+    yield p;
+    yield* validate(browser1, 4, 3);
+
+    // Cross process navigate back.
+    browser1.goBack();
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 4, 2);
+
+    // Cross process navigate forward.
+    browser1.goForward();
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 4, 3);
+
+    // Navigate across process to a page which was not recently loaded.
+    browser1.gotoIndex(0);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 4, 1);
+
+    // Navigate across process to a page which was not recently loaded in the other direction.
+    browser1.gotoIndex(3);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 4, 4);
+
+    // Create a new hidden prerendered tab to swap to
+    let tab3 = gBrowser.loadOneTab(URIs[4], {
+      referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
+      allowThirdPartyFixup: true,
+      relatedToCurrent: true,
+      isPrerendered: true,
+    });
+    yield BrowserTestUtils.browserLoaded(tab3.linkedBrowser);
+    browser1.frameLoader.appendPartialSessionHistoryAndSwap(
+      tab3.linkedBrowser.frameLoader);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 5, 5);
+
+    browser1.gotoIndex(0);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 5, 1);
+
+    browser1.gotoIndex(2);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 5, 3);
+
+    // Load a new page and make sure it throws out all of the following entries.
+    URIs[3] = "data:text/html,NEW";
+    browser1.loadURI(URIs[3]);
+    yield BrowserTestUtils.browserLoaded(browser1);
+    yield* validate(browser1, 4, 4);
+
+    browser1.gotoIndex(0);
+    yield awaitProcessChange(browser1);
+    yield* validate(browser1, 4, 1);
+
+    // XXX: This will be removed automatically by the owning tab closing in the
+    // future, but this is not supported yet.
+    gBrowser.removeTab(tab2);
+    gBrowser.removeTab(tab3);
+  });
+});
--- a/browser/extensions/flyweb/bootstrap.js
+++ b/browser/extensions/flyweb/bootstrap.js
@@ -153,17 +153,17 @@ const FlyWebPermissionPromptIntegration 
           notificationIcon.id = kAnchorID;
           notificationIcon.setAttribute("src",
                                         "chrome://flyweb/skin/icon-64.png");
           notificationIcon.classList.add("notification-anchor-icon");
           notificationIcon.setAttribute("role", "button");
           notificationIcon.setAttribute("aria-label",
                                         "View the publish-server request");
           notificationIcon.style.filter =
-            "url('chrome://browser/skin/filters.svg#fill')";
+            "url('chrome://global/skin/filters.svg#fill')";
           notificationIcon.style.fill = "currentcolor";
           notificationIcon.style.opacity = "0.4";
           notificationPopupBox.appendChild(notificationIcon);
         }
 
         return kAnchorID;
       },
       get message() {
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,3 +1,3 @@
 This is the pdf.js project output, https://github.com/mozilla/pdf.js
 
-Current extension version is: 1.6.315
+Current extension version is: 1.6.329
--- a/browser/extensions/pdfjs/content/PdfJs.jsm
+++ b/browser/extensions/pdfjs/content/PdfJs.jsm
@@ -88,16 +88,17 @@ function initializeDefaultPreferences() 
   "disableRange": false,
   "disableStream": false,
   "disableAutoFetch": false,
   "disableFontFace": false,
   "disableTextLayer": false,
   "useOnlyCssZoom": false,
   "externalLinkTarget": 0,
   "enhanceTextSelection": false,
+  "renderer": "canvas",
   "renderInteractiveForms": false,
   "disablePageLabels": false
 }
 
 
   var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
   var defaultValue;
   for (var key in DEFAULT_PREFERENCES) {
--- a/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
+++ b/browser/extensions/pdfjs/content/PdfjsChromeUtils.jsm
@@ -46,16 +46,17 @@ var DEFAULT_PREFERENCES =
   "disableRange": false,
   "disableStream": false,
   "disableAutoFetch": false,
   "disableFontFace": false,
   "disableTextLayer": false,
   "useOnlyCssZoom": false,
   "externalLinkTarget": 0,
   "enhanceTextSelection": false,
+  "renderer": "canvas",
   "renderInteractiveForms": false,
   "disablePageLabels": false
 }
 
 
 var PdfjsChromeUtils = {
   // For security purposes when running remote, we restrict preferences
   // content can access.
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -8,3530 +8,2936 @@
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 (function (root, factory) {
-  'use strict';
-  if (typeof define === 'function' && define.amd) {
-    define('pdfjs-dist/build/pdf', ['exports'], factory);
-  } else if (typeof exports !== 'undefined') {
-    factory(exports);
-  } else {
-    factory(root['pdfjsDistBuildPdf'] = {});
-  }
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+  define('pdfjs-dist/build/pdf', ['exports'], factory);
+ } else if (typeof exports !== 'undefined') {
+  factory(exports);
+ } else {
+  factory(root['pdfjsDistBuildPdf'] = {});
+ }
 }(this, function (exports) {
-  // Use strict in our context only - users might not want it
-  'use strict';
-  var pdfjsVersion = '1.6.315';
-  var pdfjsBuild = 'a139c75';
-  var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : null;
-  var pdfjsLibs = {};
-  (function pdfjsWrapper() {
-    (function (root, factory) {
-      factory(root.pdfjsSharedUtil = {});
-    }(this, function (exports) {
-      var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this;
-      var FONT_IDENTITY_MATRIX = [
-        0.001,
-        0,
-        0,
-        0.001,
-        0,
-        0
-      ];
-      var TextRenderingMode = {
-        FILL: 0,
-        STROKE: 1,
-        FILL_STROKE: 2,
-        INVISIBLE: 3,
-        FILL_ADD_TO_PATH: 4,
-        STROKE_ADD_TO_PATH: 5,
-        FILL_STROKE_ADD_TO_PATH: 6,
-        ADD_TO_PATH: 7,
-        FILL_STROKE_MASK: 3,
-        ADD_TO_PATH_FLAG: 4
-      };
-      var ImageKind = {
-        GRAYSCALE_1BPP: 1,
-        RGB_24BPP: 2,
-        RGBA_32BPP: 3
-      };
-      var AnnotationType = {
-        TEXT: 1,
-        LINK: 2,
-        FREETEXT: 3,
-        LINE: 4,
-        SQUARE: 5,
-        CIRCLE: 6,
-        POLYGON: 7,
-        POLYLINE: 8,
-        HIGHLIGHT: 9,
-        UNDERLINE: 10,
-        SQUIGGLY: 11,
-        STRIKEOUT: 12,
-        STAMP: 13,
-        CARET: 14,
-        INK: 15,
-        POPUP: 16,
-        FILEATTACHMENT: 17,
-        SOUND: 18,
-        MOVIE: 19,
-        WIDGET: 20,
-        SCREEN: 21,
-        PRINTERMARK: 22,
-        TRAPNET: 23,
-        WATERMARK: 24,
-        THREED: 25,
-        REDACT: 26
-      };
-      var AnnotationFlag = {
-        INVISIBLE: 0x01,
-        HIDDEN: 0x02,
-        PRINT: 0x04,
-        NOZOOM: 0x08,
-        NOROTATE: 0x10,
-        NOVIEW: 0x20,
-        READONLY: 0x40,
-        LOCKED: 0x80,
-        TOGGLENOVIEW: 0x100,
-        LOCKEDCONTENTS: 0x200
-      };
-      var AnnotationFieldFlag = {
-        READONLY: 0x0000001,
-        REQUIRED: 0x0000002,
-        NOEXPORT: 0x0000004,
-        MULTILINE: 0x0001000,
-        PASSWORD: 0x0002000,
-        NOTOGGLETOOFF: 0x0004000,
-        RADIO: 0x0008000,
-        PUSHBUTTON: 0x0010000,
-        COMBO: 0x0020000,
-        EDIT: 0x0040000,
-        SORT: 0x0080000,
-        FILESELECT: 0x0100000,
-        MULTISELECT: 0x0200000,
-        DONOTSPELLCHECK: 0x0400000,
-        DONOTSCROLL: 0x0800000,
-        COMB: 0x1000000,
-        RICHTEXT: 0x2000000,
-        RADIOSINUNISON: 0x2000000,
-        COMMITONSELCHANGE: 0x4000000
-      };
-      var AnnotationBorderStyleType = {
-        SOLID: 1,
-        DASHED: 2,
-        BEVELED: 3,
-        INSET: 4,
-        UNDERLINE: 5
-      };
-      var StreamType = {
-        UNKNOWN: 0,
-        FLATE: 1,
-        LZW: 2,
-        DCT: 3,
-        JPX: 4,
-        JBIG: 5,
-        A85: 6,
-        AHX: 7,
-        CCF: 8,
-        RL: 9
-      };
-      var FontType = {
-        UNKNOWN: 0,
-        TYPE1: 1,
-        TYPE1C: 2,
-        CIDFONTTYPE0: 3,
-        CIDFONTTYPE0C: 4,
-        TRUETYPE: 5,
-        CIDFONTTYPE2: 6,
-        TYPE3: 7,
-        OPENTYPE: 8,
-        TYPE0: 9,
-        MMTYPE1: 10
-      };
-      var VERBOSITY_LEVELS = {
-        errors: 0,
-        warnings: 1,
-        infos: 5
-      };
-      // All the possible operations for an operator list.
-      var OPS = {
-        // Intentionally start from 1 so it is easy to spot bad operators that will be
-        // 0's.
-        dependency: 1,
-        setLineWidth: 2,
-        setLineCap: 3,
-        setLineJoin: 4,
-        setMiterLimit: 5,
-        setDash: 6,
-        setRenderingIntent: 7,
-        setFlatness: 8,
-        setGState: 9,
-        save: 10,
-        restore: 11,
-        transform: 12,
-        moveTo: 13,
-        lineTo: 14,
-        curveTo: 15,
-        curveTo2: 16,
-        curveTo3: 17,
-        closePath: 18,
-        rectangle: 19,
-        stroke: 20,
-        closeStroke: 21,
-        fill: 22,
-        eoFill: 23,
-        fillStroke: 24,
-        eoFillStroke: 25,
-        closeFillStroke: 26,
-        closeEOFillStroke: 27,
-        endPath: 28,
-        clip: 29,
-        eoClip: 30,
-        beginText: 31,
-        endText: 32,
-        setCharSpacing: 33,
-        setWordSpacing: 34,
-        setHScale: 35,
-        setLeading: 36,
-        setFont: 37,
-        setTextRenderingMode: 38,
-        setTextRise: 39,
-        moveText: 40,
-        setLeadingMoveText: 41,
-        setTextMatrix: 42,
-        nextLine: 43,
-        showText: 44,
-        showSpacedText: 45,
-        nextLineShowText: 46,
-        nextLineSetSpacingShowText: 47,
-        setCharWidth: 48,
-        setCharWidthAndBounds: 49,
-        setStrokeColorSpace: 50,
-        setFillColorSpace: 51,
-        setStrokeColor: 52,
-        setStrokeColorN: 53,
-        setFillColor: 54,
-        setFillColorN: 55,
-        setStrokeGray: 56,
-        setFillGray: 57,
-        setStrokeRGBColor: 58,
-        setFillRGBColor: 59,
-        setStrokeCMYKColor: 60,
-        setFillCMYKColor: 61,
-        shadingFill: 62,
-        beginInlineImage: 63,
-        beginImageData: 64,
-        endInlineImage: 65,
-        paintXObject: 66,
-        markPoint: 67,
-        markPointProps: 68,
-        beginMarkedContent: 69,
-        beginMarkedContentProps: 70,
-        endMarkedContent: 71,
-        beginCompat: 72,
-        endCompat: 73,
-        paintFormXObjectBegin: 74,
-        paintFormXObjectEnd: 75,
-        beginGroup: 76,
-        endGroup: 77,
-        beginAnnotations: 78,
-        endAnnotations: 79,
-        beginAnnotation: 80,
-        endAnnotation: 81,
-        paintJpegXObject: 82,
-        paintImageMaskXObject: 83,
-        paintImageMaskXObjectGroup: 84,
-        paintImageXObject: 85,
-        paintInlineImageXObject: 86,
-        paintInlineImageXObjectGroup: 87,
-        paintImageXObjectRepeat: 88,
-        paintImageMaskXObjectRepeat: 89,
-        paintSolidColorImageMask: 90,
-        constructPath: 91
+ 'use strict';
+ var pdfjsVersion = '1.6.329';
+ var pdfjsBuild = '9c3419d';
+ var pdfjsFilePath = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : null;
+ var pdfjsLibs = {};
+ (function pdfjsWrapper() {
+  (function (root, factory) {
+   factory(root.pdfjsSharedUtil = {});
+  }(this, function (exports) {
+   var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this;
+   var FONT_IDENTITY_MATRIX = [
+    0.001,
+    0,
+    0,
+    0.001,
+    0,
+    0
+   ];
+   var TextRenderingMode = {
+    FILL: 0,
+    STROKE: 1,
+    FILL_STROKE: 2,
+    INVISIBLE: 3,
+    FILL_ADD_TO_PATH: 4,
+    STROKE_ADD_TO_PATH: 5,
+    FILL_STROKE_ADD_TO_PATH: 6,
+    ADD_TO_PATH: 7,
+    FILL_STROKE_MASK: 3,
+    ADD_TO_PATH_FLAG: 4
+   };
+   var ImageKind = {
+    GRAYSCALE_1BPP: 1,
+    RGB_24BPP: 2,
+    RGBA_32BPP: 3
+   };
+   var AnnotationType = {
+    TEXT: 1,
+    LINK: 2,
+    FREETEXT: 3,
+    LINE: 4,
+    SQUARE: 5,
+    CIRCLE: 6,
+    POLYGON: 7,
+    POLYLINE: 8,
+    HIGHLIGHT: 9,
+    UNDERLINE: 10,
+    SQUIGGLY: 11,
+    STRIKEOUT: 12,
+    STAMP: 13,
+    CARET: 14,
+    INK: 15,
+    POPUP: 16,
+    FILEATTACHMENT: 17,
+    SOUND: 18,
+    MOVIE: 19,
+    WIDGET: 20,
+    SCREEN: 21,
+    PRINTERMARK: 22,
+    TRAPNET: 23,
+    WATERMARK: 24,
+    THREED: 25,
+    REDACT: 26
+   };
+   var AnnotationFlag = {
+    INVISIBLE: 0x01,
+    HIDDEN: 0x02,
+    PRINT: 0x04,
+    NOZOOM: 0x08,
+    NOROTATE: 0x10,
+    NOVIEW: 0x20,
+    READONLY: 0x40,
+    LOCKED: 0x80,
+    TOGGLENOVIEW: 0x100,
+    LOCKEDCONTENTS: 0x200
+   };
+   var AnnotationFieldFlag = {
+    READONLY: 0x0000001,
+    REQUIRED: 0x0000002,
+    NOEXPORT: 0x0000004,
+    MULTILINE: 0x0001000,
+    PASSWORD: 0x0002000,
+    NOTOGGLETOOFF: 0x0004000,
+    RADIO: 0x0008000,
+    PUSHBUTTON: 0x0010000,
+    COMBO: 0x0020000,
+    EDIT: 0x0040000,
+    SORT: 0x0080000,
+    FILESELECT: 0x0100000,
+    MULTISELECT: 0x0200000,
+    DONOTSPELLCHECK: 0x0400000,
+    DONOTSCROLL: 0x0800000,
+    COMB: 0x1000000,
+    RICHTEXT: 0x2000000,
+    RADIOSINUNISON: 0x2000000,
+    COMMITONSELCHANGE: 0x4000000
+   };
+   var AnnotationBorderStyleType = {
+    SOLID: 1,
+    DASHED: 2,
+    BEVELED: 3,
+    INSET: 4,
+    UNDERLINE: 5
+   };
+   var StreamType = {
+    UNKNOWN: 0,
+    FLATE: 1,
+    LZW: 2,
+    DCT: 3,
+    JPX: 4,
+    JBIG: 5,
+    A85: 6,
+    AHX: 7,
+    CCF: 8,
+    RL: 9
+   };
+   var FontType = {
+    UNKNOWN: 0,
+    TYPE1: 1,
+    TYPE1C: 2,
+    CIDFONTTYPE0: 3,
+    CIDFONTTYPE0C: 4,
+    TRUETYPE: 5,
+    CIDFONTTYPE2: 6,
+    TYPE3: 7,
+    OPENTYPE: 8,
+    TYPE0: 9,
+    MMTYPE1: 10
+   };
+   var VERBOSITY_LEVELS = {
+    errors: 0,
+    warnings: 1,
+    infos: 5
+   };
+   var OPS = {
+    dependency: 1,
+    setLineWidth: 2,
+    setLineCap: 3,
+    setLineJoin: 4,
+    setMiterLimit: 5,
+    setDash: 6,
+    setRenderingIntent: 7,
+    setFlatness: 8,
+    setGState: 9,
+    save: 10,
+    restore: 11,
+    transform: 12,
+    moveTo: 13,
+    lineTo: 14,
+    curveTo: 15,
+    curveTo2: 16,
+    curveTo3: 17,
+    closePath: 18,
+    rectangle: 19,
+    stroke: 20,
+    closeStroke: 21,
+    fill: 22,
+    eoFill: 23,
+    fillStroke: 24,
+    eoFillStroke: 25,
+    closeFillStroke: 26,
+    closeEOFillStroke: 27,
+    endPath: 28,
+    clip: 29,
+    eoClip: 30,
+    beginText: 31,
+    endText: 32,
+    setCharSpacing: 33,
+    setWordSpacing: 34,
+    setHScale: 35,
+    setLeading: 36,
+    setFont: 37,
+    setTextRenderingMode: 38,
+    setTextRise: 39,
+    moveText: 40,
+    setLeadingMoveText: 41,
+    setTextMatrix: 42,
+    nextLine: 43,
+    showText: 44,
+    showSpacedText: 45,
+    nextLineShowText: 46,
+    nextLineSetSpacingShowText: 47,
+    setCharWidth: 48,
+    setCharWidthAndBounds: 49,
+    setStrokeColorSpace: 50,
+    setFillColorSpace: 51,
+    setStrokeColor: 52,
+    setStrokeColorN: 53,
+    setFillColor: 54,
+    setFillColorN: 55,
+    setStrokeGray: 56,
+    setFillGray: 57,
+    setStrokeRGBColor: 58,
+    setFillRGBColor: 59,
+    setStrokeCMYKColor: 60,
+    setFillCMYKColor: 61,
+    shadingFill: 62,
+    beginInlineImage: 63,
+    beginImageData: 64,
+    endInlineImage: 65,
+    paintXObject: 66,
+    markPoint: 67,
+    markPointProps: 68,
+    beginMarkedContent: 69,
+    beginMarkedContentProps: 70,
+    endMarkedContent: 71,
+    beginCompat: 72,
+    endCompat: 73,
+    paintFormXObjectBegin: 74,
+    paintFormXObjectEnd: 75,
+    beginGroup: 76,
+    endGroup: 77,
+    beginAnnotations: 78,
+    endAnnotations: 79,
+    beginAnnotation: 80,
+    endAnnotation: 81,
+    paintJpegXObject: 82,
+    paintImageMaskXObject: 83,
+    paintImageMaskXObjectGroup: 84,
+    paintImageXObject: 85,
+    paintInlineImageXObject: 86,
+    paintInlineImageXObjectGroup: 87,
+    paintImageXObjectRepeat: 88,
+    paintImageMaskXObjectRepeat: 89,
+    paintSolidColorImageMask: 90,
+    constructPath: 91
+   };
+   var verbosity = VERBOSITY_LEVELS.warnings;
+   function setVerbosityLevel(level) {
+    verbosity = level;
+   }
+   function getVerbosityLevel() {
+    return verbosity;
+   }
+   function info(msg) {
+    if (verbosity >= VERBOSITY_LEVELS.infos) {
+     console.log('Info: ' + msg);
+    }
+   }
+   function warn(msg) {
+    if (verbosity >= VERBOSITY_LEVELS.warnings) {
+     console.log('Warning: ' + msg);
+    }
+   }
+   function deprecated(details) {
+    console.log('Deprecated API usage: ' + details);
+   }
+   function error(msg) {
+    if (verbosity >= VERBOSITY_LEVELS.errors) {
+     console.log('Error: ' + msg);
+     console.log(backtrace());
+    }
+    throw new Error(msg);
+   }
+   function backtrace() {
+    try {
+     throw new Error();
+    } catch (e) {
+     return e.stack ? e.stack.split('\n').slice(2).join('\n') : '';
+    }
+   }
+   function assert(cond, msg) {
+    if (!cond) {
+     error(msg);
+    }
+   }
+   var UNSUPPORTED_FEATURES = {
+    unknown: 'unknown',
+    forms: 'forms',
+    javaScript: 'javaScript',
+    smask: 'smask',
+    shadingPattern: 'shadingPattern',
+    font: 'font'
+   };
+   function isSameOrigin(baseUrl, otherUrl) {
+    try {
+     var base = new URL(baseUrl);
+     if (!base.origin || base.origin === 'null') {
+      return false;
+     }
+    } catch (e) {
+     return false;
+    }
+    var other = new URL(otherUrl, base);
+    return base.origin === other.origin;
+   }
+   function isValidProtocol(url) {
+    if (!url) {
+     return false;
+    }
+    switch (url.protocol) {
+    case 'http:':
+    case 'https:':
+    case 'ftp:':
+    case 'mailto:':
+    case 'tel:':
+     return true;
+    default:
+     return false;
+    }
+   }
+   function createValidAbsoluteUrl(url, baseUrl) {
+    if (!url) {
+     return null;
+    }
+    try {
+     var absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);
+     if (isValidProtocol(absoluteUrl)) {
+      return absoluteUrl;
+     }
+    } catch (ex) {
+    }
+    return null;
+   }
+   function shadow(obj, prop, value) {
+    Object.defineProperty(obj, prop, {
+     value: value,
+     enumerable: true,
+     configurable: true,
+     writable: false
+    });
+    return value;
+   }
+   function getLookupTableFactory(initializer) {
+    var lookup;
+    return function () {
+     if (initializer) {
+      lookup = Object.create(null);
+      initializer(lookup);
+      initializer = null;
+     }
+     return lookup;
+    };
+   }
+   var PasswordResponses = {
+    NEED_PASSWORD: 1,
+    INCORRECT_PASSWORD: 2
+   };
+   var PasswordException = function PasswordExceptionClosure() {
+    function PasswordException(msg, code) {
+     this.name = 'PasswordException';
+     this.message = msg;
+     this.code = code;
+    }
+    PasswordException.prototype = new Error();
+    PasswordException.constructor = PasswordException;
+    return PasswordException;
+   }();
+   var UnknownErrorException = function UnknownErrorExceptionClosure() {
+    function UnknownErrorException(msg, details) {
+     this.name = 'UnknownErrorException';
+     this.message = msg;
+     this.details = details;
+    }
+    UnknownErrorException.prototype = new Error();
+    UnknownErrorException.constructor = UnknownErrorException;
+    return UnknownErrorException;
+   }();
+   var InvalidPDFException = function InvalidPDFExceptionClosure() {
+    function InvalidPDFException(msg) {
+     this.name = 'InvalidPDFException';
+     this.message = msg;
+    }
+    InvalidPDFException.prototype = new Error();
+    InvalidPDFException.constructor = InvalidPDFException;
+    return InvalidPDFException;
+   }();
+   var MissingPDFException = function MissingPDFExceptionClosure() {
+    function MissingPDFException(msg) {
+     this.name = 'MissingPDFException';
+     this.message = msg;
+    }
+    MissingPDFException.prototype = new Error();
+    MissingPDFException.constructor = MissingPDFException;
+    return MissingPDFException;
+   }();
+   var UnexpectedResponseException = function UnexpectedResponseExceptionClosure() {
+    function UnexpectedResponseException(msg, status) {
+     this.name = 'UnexpectedResponseException';
+     this.message = msg;
+     this.status = status;
+    }
+    UnexpectedResponseException.prototype = new Error();
+    UnexpectedResponseException.constructor = UnexpectedResponseException;
+    return UnexpectedResponseException;
+   }();
+   var NotImplementedException = function NotImplementedExceptionClosure() {
+    function NotImplementedException(msg) {
+     this.message = msg;
+    }
+    NotImplementedException.prototype = new Error();
+    NotImplementedException.prototype.name = 'NotImplementedException';
+    NotImplementedException.constructor = NotImplementedException;
+    return NotImplementedException;
+   }();
+   var MissingDataException = function MissingDataExceptionClosure() {
+    function MissingDataException(begin, end) {
+     this.begin = begin;
+     this.end = end;
+     this.message = 'Missing data [' + begin + ', ' + end + ')';
+    }
+    MissingDataException.prototype = new Error();
+    MissingDataException.prototype.name = 'MissingDataException';
+    MissingDataException.constructor = MissingDataException;
+    return MissingDataException;
+   }();
+   var XRefParseException = function XRefParseExceptionClosure() {
+    function XRefParseException(msg) {
+     this.message = msg;
+    }
+    XRefParseException.prototype = new Error();
+    XRefParseException.prototype.name = 'XRefParseException';
+    XRefParseException.constructor = XRefParseException;
+    return XRefParseException;
+   }();
+   var NullCharactersRegExp = /\x00/g;
+   function removeNullCharacters(str) {
+    if (typeof str !== 'string') {
+     warn('The argument for removeNullCharacters must be a string.');
+     return str;
+    }
+    return str.replace(NullCharactersRegExp, '');
+   }
+   function bytesToString(bytes) {
+    assert(bytes !== null && typeof bytes === 'object' && bytes.length !== undefined, 'Invalid argument for bytesToString');
+    var length = bytes.length;
+    var MAX_ARGUMENT_COUNT = 8192;
+    if (length < MAX_ARGUMENT_COUNT) {
+     return String.fromCharCode.apply(null, bytes);
+    }
+    var strBuf = [];
+    for (var i = 0; i < length; i += MAX_ARGUMENT_COUNT) {
+     var chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);
+     var chunk = bytes.subarray(i, chunkEnd);
+     strBuf.push(String.fromCharCode.apply(null, chunk));
+    }
+    return strBuf.join('');
+   }
+   function stringToBytes(str) {
+    assert(typeof str === 'string', 'Invalid argument for stringToBytes');
+    var length = str.length;
+    var bytes = new Uint8Array(length);
+    for (var i = 0; i < length; ++i) {
+     bytes[i] = str.charCodeAt(i) & 0xFF;
+    }
+    return bytes;
+   }
+   function arrayByteLength(arr) {
+    if (arr.length !== undefined) {
+     return arr.length;
+    }
+    assert(arr.byteLength !== undefined);
+    return arr.byteLength;
+   }
+   function arraysToBytes(arr) {
+    if (arr.length === 1 && arr[0] instanceof Uint8Array) {
+     return arr[0];
+    }
+    var resultLength = 0;
+    var i, ii = arr.length;
+    var item, itemLength;
+    for (i = 0; i < ii; i++) {
+     item = arr[i];
+     itemLength = arrayByteLength(item);
+     resultLength += itemLength;
+    }
+    var pos = 0;
+    var data = new Uint8Array(resultLength);
+    for (i = 0; i < ii; i++) {
+     item = arr[i];
+     if (!(item instanceof Uint8Array)) {
+      if (typeof item === 'string') {
+       item = stringToBytes(item);
+      } else {
+       item = new Uint8Array(item);
+      }
+     }
+     itemLength = item.byteLength;
+     data.set(item, pos);
+     pos += itemLength;
+    }
+    return data;
+   }
+   function string32(value) {
+    return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
+   }
+   function log2(x) {
+    var n = 1, i = 0;
+    while (x > n) {
+     n <<= 1;
+     i++;
+    }
+    return i;
+   }
+   function readInt8(data, start) {
+    return data[start] << 24 >> 24;
+   }
+   function readUint16(data, offset) {
+    return data[offset] << 8 | data[offset + 1];
+   }
+   function readUint32(data, offset) {
+    return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;
+   }
+   function isLittleEndian() {
+    var buffer8 = new Uint8Array(2);
+    buffer8[0] = 1;
+    var buffer16 = new Uint16Array(buffer8.buffer);
+    return buffer16[0] === 1;
+   }
+   function isEvalSupported() {
+    try {
+     new Function('');
+     return true;
+    } catch (e) {
+     return false;
+    }
+   }
+   var IDENTITY_MATRIX = [
+    1,
+    0,
+    0,
+    1,
+    0,
+    0
+   ];
+   var Util = function UtilClosure() {
+    function Util() {
+    }
+    var rgbBuf = [
+     'rgb(',
+     0,
+     ',',
+     0,
+     ',',
+     0,
+     ')'
+    ];
+    Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
+     rgbBuf[1] = r;
+     rgbBuf[3] = g;
+     rgbBuf[5] = b;
+     return rgbBuf.join('');
+    };
+    Util.transform = function Util_transform(m1, m2) {
+     return [
+      m1[0] * m2[0] + m1[2] * m2[1],
+      m1[1] * m2[0] + m1[3] * m2[1],
+      m1[0] * m2[2] + m1[2] * m2[3],
+      m1[1] * m2[2] + m1[3] * m2[3],
+      m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
+      m1[1] * m2[4] + m1[3] * m2[5] + m1[5]
+     ];
+    };
+    Util.applyTransform = function Util_applyTransform(p, m) {
+     var xt = p[0] * m[0] + p[1] * m[2] + m[4];
+     var yt = p[0] * m[1] + p[1] * m[3] + m[5];
+     return [
+      xt,
+      yt
+     ];
+    };
+    Util.applyInverseTransform = function Util_applyInverseTransform(p, m) {
+     var d = m[0] * m[3] - m[1] * m[2];
+     var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;
+     var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;
+     return [
+      xt,
+      yt
+     ];
+    };
+    Util.getAxialAlignedBoundingBox = function Util_getAxialAlignedBoundingBox(r, m) {
+     var p1 = Util.applyTransform(r, m);
+     var p2 = Util.applyTransform(r.slice(2, 4), m);
+     var p3 = Util.applyTransform([
+      r[0],
+      r[3]
+     ], m);
+     var p4 = Util.applyTransform([
+      r[2],
+      r[1]
+     ], m);
+     return [
+      Math.min(p1[0], p2[0], p3[0], p4[0]),
+      Math.min(p1[1], p2[1], p3[1], p4[1]),
+      Math.max(p1[0], p2[0], p3[0], p4[0]),
+      Math.max(p1[1], p2[1], p3[1], p4[1])
+     ];
+    };
+    Util.inverseTransform = function Util_inverseTransform(m) {
+     var d = m[0] * m[3] - m[1] * m[2];
+     return [
+      m[3] / d,
+      -m[1] / d,
+      -m[2] / d,
+      m[0] / d,
+      (m[2] * m[5] - m[4] * m[3]) / d,
+      (m[4] * m[1] - m[5] * m[0]) / d
+     ];
+    };
+    Util.apply3dTransform = function Util_apply3dTransform(m, v) {
+     return [
+      m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
+      m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
+      m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
+     ];
+    };
+    Util.singularValueDecompose2dScale = function Util_singularValueDecompose2dScale(m) {
+     var transpose = [
+      m[0],
+      m[2],
+      m[1],
+      m[3]
+     ];
+     var a = m[0] * transpose[0] + m[1] * transpose[2];
+     var b = m[0] * transpose[1] + m[1] * transpose[3];
+     var c = m[2] * transpose[0] + m[3] * transpose[2];
+     var d = m[2] * transpose[1] + m[3] * transpose[3];
+     var first = (a + d) / 2;
+     var second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2;
+     var sx = first + second || 1;
+     var sy = first - second || 1;
+     return [
+      Math.sqrt(sx),
+      Math.sqrt(sy)
+     ];
+    };
+    Util.normalizeRect = function Util_normalizeRect(rect) {
+     var r = rect.slice(0);
+     if (rect[0] > rect[2]) {
+      r[0] = rect[2];
+      r[2] = rect[0];
+     }
+     if (rect[1] > rect[3]) {
+      r[1] = rect[3];
+      r[3] = rect[1];
+     }
+     return r;
+    };
+    Util.intersect = function Util_intersect(rect1, rect2) {
+     function compare(a, b) {
+      return a - b;
+     }
+     var orderedX = [
+       rect1[0],
+       rect1[2],
+       rect2[0],
+       rect2[2]
+      ].sort(compare), orderedY = [
+       rect1[1],
+       rect1[3],
+       rect2[1],
+       rect2[3]
+      ].sort(compare), result = [];
+     rect1 = Util.normalizeRect(rect1);
+     rect2 = Util.normalizeRect(rect2);
+     if (orderedX[0] === rect1[0] && orderedX[1] === rect2[0] || orderedX[0] === rect2[0] && orderedX[1] === rect1[0]) {
+      result[0] = orderedX[1];
+      result[2] = orderedX[2];
+     } else {
+      return false;
+     }
+     if (orderedY[0] === rect1[1] && orderedY[1] === rect2[1] || orderedY[0] === rect2[1] && orderedY[1] === rect1[1]) {
+      result[1] = orderedY[1];
+      result[3] = orderedY[2];
+     } else {
+      return false;
+     }
+     return result;
+    };
+    Util.sign = function Util_sign(num) {
+     return num < 0 ? -1 : 1;
+    };
+    var ROMAN_NUMBER_MAP = [
+     '',
+     'C',
+     'CC',
+     'CCC',
+     'CD',
+     'D',
+     'DC',
+     'DCC',
+     'DCCC',
+     'CM',
+     '',
+     'X',
+     'XX',
+     'XXX',
+     'XL',
+     'L',
+     'LX',
+     'LXX',
+     'LXXX',
+     'XC',
+     '',
+     'I',
+     'II',
+     'III',
+     'IV',
+     'V',
+     'VI',
+     'VII',
+     'VIII',
+     'IX'
+    ];
+    Util.toRoman = function Util_toRoman(number, lowerCase) {
+     assert(isInt(number) && number > 0, 'The number should be a positive integer.');
+     var pos, romanBuf = [];
+     while (number >= 1000) {
+      number -= 1000;
+      romanBuf.push('M');
+     }
+     pos = number / 100 | 0;
+     number %= 100;
+     romanBuf.push(ROMAN_NUMBER_MAP[pos]);
+     pos = number / 10 | 0;
+     number %= 10;
+     romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
+     romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
+     var romanStr = romanBuf.join('');
+     return lowerCase ? romanStr.toLowerCase() : romanStr;
+    };
+    Util.appendToArray = function Util_appendToArray(arr1, arr2) {
+     Array.prototype.push.apply(arr1, arr2);
+    };
+    Util.prependToArray = function Util_prependToArray(arr1, arr2) {
+     Array.prototype.unshift.apply(arr1, arr2);
+    };
+    Util.extendObj = function extendObj(obj1, obj2) {
+     for (var key in obj2) {
+      obj1[key] = obj2[key];
+     }
+    };
+    Util.getInheritableProperty = function Util_getInheritableProperty(dict, name, getArray) {
+     while (dict && !dict.has(name)) {
+      dict = dict.get('Parent');
+     }
+     if (!dict) {
+      return null;
+     }
+     return getArray ? dict.getArray(name) : dict.get(name);
+    };
+    Util.inherit = function Util_inherit(sub, base, prototype) {
+     sub.prototype = Object.create(base.prototype);
+     sub.prototype.constructor = sub;
+     for (var prop in prototype) {
+      sub.prototype[prop] = prototype[prop];
+     }
+    };
+    Util.loadScript = function Util_loadScript(src, callback) {
+     var script = document.createElement('script');
+     var loaded = false;
+     script.setAttribute('src', src);
+     if (callback) {
+      script.onload = function () {
+       if (!loaded) {
+        callback();
+       }
+       loaded = true;
       };
-      var verbosity = VERBOSITY_LEVELS.warnings;
-      function setVerbosityLevel(level) {
-        verbosity = level;
-      }
-      function getVerbosityLevel() {
-        return verbosity;
-      }
-      // A notice for devs. These are good for things that are helpful to devs, such
-      // as warning that Workers were disabled, which is important to devs but not
-      // end users.
-      function info(msg) {
-        if (verbosity >= VERBOSITY_LEVELS.infos) {
-          console.log('Info: ' + msg);
-        }
-      }
-      // Non-fatal warnings.
-      function warn(msg) {
-        if (verbosity >= VERBOSITY_LEVELS.warnings) {
-          console.log('Warning: ' + msg);
-        }
-      }
-      // Deprecated API function -- display regardless of the PDFJS.verbosity setting.
-      function deprecated(details) {
-        console.log('Deprecated API usage: ' + details);
-      }
-      // Fatal errors that should trigger the fallback UI and halt execution by
-      // throwing an exception.
-      function error(msg) {
-        if (verbosity >= VERBOSITY_LEVELS.errors) {
-          console.log('Error: ' + msg);
-          console.log(backtrace());
-        }
-        throw new Error(msg);
-      }
-      function backtrace() {
-        try {
-          throw new Error();
-        } catch (e) {
-          return e.stack ? e.stack.split('\n').slice(2).join('\n') : '';
-        }
-      }
-      function assert(cond, msg) {
-        if (!cond) {
-          error(msg);
-        }
-      }
-      var UNSUPPORTED_FEATURES = {
-        unknown: 'unknown',
-        forms: 'forms',
-        javaScript: 'javaScript',
-        smask: 'smask',
-        shadingPattern: 'shadingPattern',
-        font: 'font'
-      };
-      // Checks if URLs have the same origin. For non-HTTP based URLs, returns false.
-      function isSameOrigin(baseUrl, otherUrl) {
-        try {
-          var base = new URL(baseUrl);
-          if (!base.origin || base.origin === 'null') {
-            return false;
-          }
-        } // non-HTTP url
-        catch (e) {
-          return false;
-        }
-        var other = new URL(otherUrl, base);
-        return base.origin === other.origin;
-      }
-      // Checks if URLs use one of the whitelisted protocols, e.g. to avoid XSS.
-      function isValidProtocol(url) {
-        if (!url) {
-          return false;
-        }
-        switch (url.protocol) {
-        case 'http:':
-        case 'https:':
-        case 'ftp:':
-        case 'mailto:':
-        case 'tel:':
-          return true;
-        default:
-          return false;
-        }
-      }
-      /**
-       * Attempts to create a valid absolute URL (utilizing `isValidProtocol`).
-       * @param {URL|string} url - An absolute, or relative, URL.
-       * @param {URL|string} baseUrl - An absolute URL.
-       * @returns Either a valid {URL}, or `null` otherwise.
-       */
-      function createValidAbsoluteUrl(url, baseUrl) {
-        if (!url) {
-          return null;
-        }
-        try {
-          var absoluteUrl = baseUrl ? new URL(url, baseUrl) : new URL(url);
-          if (isValidProtocol(absoluteUrl)) {
-            return absoluteUrl;
-          }
-        } catch (ex) {
-        }
-        return null;
-      }
-      function shadow(obj, prop, value) {
-        Object.defineProperty(obj, prop, {
-          value: value,
-          enumerable: true,
-          configurable: true,
-          writable: false
-        });
-        return value;
-      }
-      function getLookupTableFactory(initializer) {
-        var lookup;
-        return function () {
-          if (initializer) {
-            lookup = Object.create(null);
-            initializer(lookup);
-            initializer = null;
-          }
-          return lookup;
-        };
-      }
-      var PasswordResponses = {
-        NEED_PASSWORD: 1,
-        INCORRECT_PASSWORD: 2
-      };
-      var PasswordException = function PasswordExceptionClosure() {
-        function PasswordException(msg, code) {
-          this.name = 'PasswordException';
-          this.message = msg;
-          this.code = code;
-        }
-        PasswordException.prototype = new Error();
-        PasswordException.constructor = PasswordException;
-        return PasswordException;
-      }();
-      var UnknownErrorException = function UnknownErrorExceptionClosure() {
-        function UnknownErrorException(msg, details) {
-          this.name = 'UnknownErrorException';
-          this.message = msg;
-          this.details = details;
-        }
-        UnknownErrorException.prototype = new Error();
-        UnknownErrorException.constructor = UnknownErrorException;
-        return UnknownErrorException;
-      }();
-      var InvalidPDFException = function InvalidPDFExceptionClosure() {
-        function InvalidPDFException(msg) {
-          this.name = 'InvalidPDFException';
-          this.message = msg;
-        }
-        InvalidPDFException.prototype = new Error();
-        InvalidPDFException.constructor = InvalidPDFException;
-        return InvalidPDFException;
-      }();
-      var MissingPDFException = function MissingPDFExceptionClosure() {
-        function MissingPDFException(msg) {
-          this.name = 'MissingPDFException';
-          this.message = msg;
-        }
-        MissingPDFException.prototype = new Error();
-        MissingPDFException.constructor = MissingPDFException;
-        return MissingPDFException;
-      }();
-      var UnexpectedResponseException = function UnexpectedResponseExceptionClosure() {
-        function UnexpectedResponseException(msg, status) {
-          this.name = 'UnexpectedResponseException';
-          this.message = msg;
-          this.status = status;
-        }
-        UnexpectedResponseException.prototype = new Error();
-        UnexpectedResponseException.constructor = UnexpectedResponseException;
-        return UnexpectedResponseException;
-      }();
-      var NotImplementedException = function NotImplementedExceptionClosure() {
-        function NotImplementedException(msg) {
-          this.message = msg;
-        }
-        NotImplementedException.prototype = new Error();
-        NotImplementedException.prototype.name = 'NotImplementedException';
-        NotImplementedException.constructor = NotImplementedException;
-        return NotImplementedException;
-      }();
-      var MissingDataException = function MissingDataExceptionClosure() {
-        function MissingDataException(begin, end) {
-          this.begin = begin;
-          this.end = end;
-          this.message = 'Missing data [' + begin + ', ' + end + ')';
-        }
-        MissingDataException.prototype = new Error();
-        MissingDataException.prototype.name = 'MissingDataException';
-        MissingDataException.constructor = MissingDataException;
-        return MissingDataException;
-      }();
-      var XRefParseException = function XRefParseExceptionClosure() {
-        function XRefParseException(msg) {
-          this.message = msg;
-        }
-        XRefParseException.prototype = new Error();
-        XRefParseException.prototype.name = 'XRefParseException';
-        XRefParseException.constructor = XRefParseException;
-        return XRefParseException;
-      }();
-      var NullCharactersRegExp = /\x00/g;
-      function removeNullCharacters(str) {
-        if (typeof str !== 'string') {
-          warn('The argument for removeNullCharacters must be a string.');
-          return str;
-        }
-        return str.replace(NullCharactersRegExp, '');
-      }
-      function bytesToString(bytes) {
-        assert(bytes !== null && typeof bytes === 'object' && bytes.length !== undefined, 'Invalid argument for bytesToString');
-        var length = bytes.length;
-        var MAX_ARGUMENT_COUNT = 8192;
-        if (length < MAX_ARGUMENT_COUNT) {
-          return String.fromCharCode.apply(null, bytes);
-        }
-        var strBuf = [];
-        for (var i = 0; i < length; i += MAX_ARGUMENT_COUNT) {
-          var chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length);
-          var chunk = bytes.subarray(i, chunkEnd);
-          strBuf.push(String.fromCharCode.apply(null, chunk));
-        }
-        return strBuf.join('');
-      }
-      function stringToBytes(str) {
-        assert(typeof str === 'string', 'Invalid argument for stringToBytes');
-        var length = str.length;
-        var bytes = new Uint8Array(length);
-        for (var i = 0; i < length; ++i) {
-          bytes[i] = str.charCodeAt(i) & 0xFF;
-        }
-        return bytes;
-      }
-      /**
-       * Gets length of the array (Array, Uint8Array, or string) in bytes.
-       * @param {Array|Uint8Array|string} arr
-       * @returns {number}
-       */
-      function arrayByteLength(arr) {
-        if (arr.length !== undefined) {
-          return arr.length;
-        }
-        assert(arr.byteLength !== undefined);
-        return arr.byteLength;
-      }
-      /**
-       * Combines array items (arrays) into single Uint8Array object.
-       * @param {Array} arr - the array of the arrays (Array, Uint8Array, or string).
-       * @returns {Uint8Array}
-       */
-      function arraysToBytes(arr) {
-        // Shortcut: if first and only item is Uint8Array, return it.
-        if (arr.length === 1 && arr[0] instanceof Uint8Array) {
-          return arr[0];
-        }
-        var resultLength = 0;
-        var i, ii = arr.length;
-        var item, itemLength;
-        for (i = 0; i < ii; i++) {
-          item = arr[i];
-          itemLength = arrayByteLength(item);
-          resultLength += itemLength;
-        }
-        var pos = 0;
-        var data = new Uint8Array(resultLength);
-        for (i = 0; i < ii; i++) {
-          item = arr[i];
-          if (!(item instanceof Uint8Array)) {
-            if (typeof item === 'string') {
-              item = stringToBytes(item);
-            } else {
-              item = new Uint8Array(item);
-            }
-          }
-          itemLength = item.byteLength;
-          data.set(item, pos);
-          pos += itemLength;
-        }
-        return data;
-      }
-      function string32(value) {
-        return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
-      }
-      function log2(x) {
-        var n = 1, i = 0;
-        while (x > n) {
-          n <<= 1;
-          i++;
-        }
-        return i;
-      }
-      function readInt8(data, start) {
-        return data[start] << 24 >> 24;
-      }
-      function readUint16(data, offset) {
-        return data[offset] << 8 | data[offset + 1];
-      }
-      function readUint32(data, offset) {
-        return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;
-      }
-      // Lazy test the endianness of the platform
-      // NOTE: This will be 'true' for simulated TypedArrays
-      function isLittleEndian() {
-        var buffer8 = new Uint8Array(2);
-        buffer8[0] = 1;
-        var buffer16 = new Uint16Array(buffer8.buffer);
-        return buffer16[0] === 1;
-      }
-      // Checks if it's possible to eval JS expressions.
-      function isEvalSupported() {
-        try {
-          new Function('');
-          return true;
-        } catch (e) {
-          return false;
-        }
-      }
-      var IDENTITY_MATRIX = [
-        1,
-        0,
-        0,
-        1,
-        0,
-        0
+     }
+     document.getElementsByTagName('head')[0].appendChild(script);
+    };
+    return Util;
+   }();
+   var PageViewport = function PageViewportClosure() {
+    function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) {
+     this.viewBox = viewBox;
+     this.scale = scale;
+     this.rotation = rotation;
+     this.offsetX = offsetX;
+     this.offsetY = offsetY;
+     var centerX = (viewBox[2] + viewBox[0]) / 2;
+     var centerY = (viewBox[3] + viewBox[1]) / 2;
+     var rotateA, rotateB, rotateC, rotateD;
+     rotation = rotation % 360;
+     rotation = rotation < 0 ? rotation + 360 : rotation;
+     switch (rotation) {
+     case 180:
+      rotateA = -1;
+      rotateB = 0;
+      rotateC = 0;
+      rotateD = 1;
+      break;
+     case 90:
+      rotateA = 0;
+      rotateB = 1;
+      rotateC = 1;
+      rotateD = 0;
+      break;
+     case 270:
+      rotateA = 0;
+      rotateB = -1;
+      rotateC = -1;
+      rotateD = 0;
+      break;
+     default:
+      rotateA = 1;
+      rotateB = 0;
+      rotateC = 0;
+      rotateD = -1;
+      break;
+     }
+     if (dontFlip) {
+      rotateC = -rotateC;
+      rotateD = -rotateD;
+     }
+     var offsetCanvasX, offsetCanvasY;
+     var width, height;
+     if (rotateA === 0) {
+      offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
+      offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
+      width = Math.abs(viewBox[3] - viewBox[1]) * scale;
+      height = Math.abs(viewBox[2] - viewBox[0]) * scale;
+     } else {
+      offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
+      offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
+      width = Math.abs(viewBox[2] - viewBox[0]) * scale;
+      height = Math.abs(viewBox[3] - viewBox[1]) * scale;
+     }
+     this.transform = [
+      rotateA * scale,
+      rotateB * scale,
+      rotateC * scale,
+      rotateD * scale,
+      offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
+      offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
+     ];
+     this.width = width;
+     this.height = height;
+     this.fontScale = scale;
+    }
+    PageViewport.prototype = {
+     clone: function PageViewPort_clone(args) {
+      args = args || {};
+      var scale = 'scale' in args ? args.scale : this.scale;
+      var rotation = 'rotation' in args ? args.rotation : this.rotation;
+      return new PageViewport(this.viewBox.slice(), scale, rotation, this.offsetX, this.offsetY, args.dontFlip);
+     },
+     convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
+      return Util.applyTransform([
+       x,
+       y
+      ], this.transform);
+     },
+     convertToViewportRectangle: function PageViewport_convertToViewportRectangle(rect) {
+      var tl = Util.applyTransform([
+       rect[0],
+       rect[1]
+      ], this.transform);
+      var br = Util.applyTransform([
+       rect[2],
+       rect[3]
+      ], this.transform);
+      return [
+       tl[0],
+       tl[1],
+       br[0],
+       br[1]
       ];
-      var Util = function UtilClosure() {
-        function Util() {
+     },
+     convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) {
+      return Util.applyInverseTransform([
+       x,
+       y
+      ], this.transform);
+     }
+    };
+    return PageViewport;
+   }();
+   var PDFStringTranslateTable = [
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0x2D8,
+    0x2C7,
+    0x2C6,
+    0x2D9,
+    0x2DD,
+    0x2DB,
+    0x2DA,
+    0x2DC,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0x2022,
+    0x2020,
+    0x2021,
+    0x2026,
+    0x2014,
+    0x2013,
+    0x192,
+    0x2044,
+    0x2039,
+    0x203A,
+    0x2212,
+    0x2030,
+    0x201E,
+    0x201C,
+    0x201D,
+    0x2018,
+    0x2019,
+    0x201A,
+    0x2122,
+    0xFB01,
+    0xFB02,
+    0x141,
+    0x152,
+    0x160,
+    0x178,
+    0x17D,
+    0x131,
+    0x142,
+    0x153,
+    0x161,
+    0x17E,
+    0,
+    0x20AC
+   ];
+   function stringToPDFString(str) {
+    var i, n = str.length, strBuf = [];
+    if (str[0] === '\xFE' && str[1] === '\xFF') {
+     for (i = 2; i < n; i += 2) {
+      strBuf.push(String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1)));
+     }
+    } else {
+     for (i = 0; i < n; ++i) {
+      var code = PDFStringTranslateTable[str.charCodeAt(i)];
+      strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));
+     }
+    }
+    return strBuf.join('');
+   }
+   function stringToUTF8String(str) {
+    return decodeURIComponent(escape(str));
+   }
+   function utf8StringToString(str) {
+    return unescape(encodeURIComponent(str));
+   }
+   function isEmptyObj(obj) {
+    for (var key in obj) {
+     return false;
+    }
+    return true;
+   }
+   function isBool(v) {
+    return typeof v === 'boolean';
+   }
+   function isInt(v) {
+    return typeof v === 'number' && (v | 0) === v;
+   }
+   function isNum(v) {
+    return typeof v === 'number';
+   }
+   function isString(v) {
+    return typeof v === 'string';
+   }
+   function isArray(v) {
+    return v instanceof Array;
+   }
+   function isArrayBuffer(v) {
+    return typeof v === 'object' && v !== null && v.byteLength !== undefined;
+   }
+   function isSpace(ch) {
+    return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
+   }
+   function createPromiseCapability() {
+    var capability = {};
+    capability.promise = new Promise(function (resolve, reject) {
+     capability.resolve = resolve;
+     capability.reject = reject;
+    });
+    return capability;
+   }
+   (function PromiseClosure() {
+    if (globalScope.Promise) {
+     if (typeof globalScope.Promise.all !== 'function') {
+      globalScope.Promise.all = function (iterable) {
+       var count = 0, results = [], resolve, reject;
+       var promise = new globalScope.Promise(function (resolve_, reject_) {
+        resolve = resolve_;
+        reject = reject_;
+       });
+       iterable.forEach(function (p, i) {
+        count++;
+        p.then(function (result) {
+         results[i] = result;
+         count--;
+         if (count === 0) {
+          resolve(results);
+         }
+        }, reject);
+       });
+       if (count === 0) {
+        resolve(results);
+       }
+       return promise;
+      };
+     }
+     if (typeof globalScope.Promise.resolve !== 'function') {
+      globalScope.Promise.resolve = function (value) {
+       return new globalScope.Promise(function (resolve) {
+        resolve(value);
+       });
+      };
+     }
+     if (typeof globalScope.Promise.reject !== 'function') {
+      globalScope.Promise.reject = function (reason) {
+       return new globalScope.Promise(function (resolve, reject) {
+        reject(reason);
+       });
+      };
+     }
+     if (typeof globalScope.Promise.prototype.catch !== 'function') {
+      globalScope.Promise.prototype.catch = function (onReject) {
+       return globalScope.Promise.prototype.then(undefined, onReject);
+      };
+     }
+     return;
+    }
+    throw new Error('DOM Promise is not present');
+   }());
+   var StatTimer = function StatTimerClosure() {
+    function rpad(str, pad, length) {
+     while (str.length < length) {
+      str += pad;
+     }
+     return str;
+    }
+    function StatTimer() {
+     this.started = Object.create(null);
+     this.times = [];
+     this.enabled = true;
+    }
+    StatTimer.prototype = {
+     time: function StatTimer_time(name) {
+      if (!this.enabled) {
+       return;
+      }
+      if (name in this.started) {
+       warn('Timer is already running for ' + name);
+      }
+      this.started[name] = Date.now();
+     },
+     timeEnd: function StatTimer_timeEnd(name) {
+      if (!this.enabled) {
+       return;
+      }
+      if (!(name in this.started)) {
+       warn('Timer has not been started for ' + name);
+      }
+      this.times.push({
+       'name': name,
+       'start': this.started[name],
+       'end': Date.now()
+      });
+      delete this.started[name];
+     },
+     toString: function StatTimer_toString() {
+      var i, ii;
+      var times = this.times;
+      var out = '';
+      var longest = 0;
+      for (i = 0, ii = times.length; i < ii; ++i) {
+       var name = times[i]['name'];
+       if (name.length > longest) {
+        longest = name.length;
+       }
+      }
+      for (i = 0, ii = times.length; i < ii; ++i) {
+       var span = times[i];
+       var duration = span.end - span.start;
+       out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
+      }
+      return out;
+     }
+    };
+    return StatTimer;
+   }();
+   var createBlob = function createBlob(data, contentType) {
+    if (typeof Blob !== 'undefined') {
+     return new Blob([data], { type: contentType });
+    }
+    warn('The "Blob" constructor is not supported.');
+   };
+   var createObjectURL = function createObjectURLClosure() {
+    var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+    return function createObjectURL(data, contentType, forceDataSchema) {
+     if (!forceDataSchema && typeof URL !== 'undefined' && URL.createObjectURL) {
+      var blob = createBlob(data, contentType);
+      return URL.createObjectURL(blob);
+     }
+     var buffer = 'data:' + contentType + ';base64,';
+     for (var i = 0, ii = data.length; i < ii; i += 3) {
+      var b1 = data[i] & 0xFF;
+      var b2 = data[i + 1] & 0xFF;
+      var b3 = data[i + 2] & 0xFF;
+      var d1 = b1 >> 2, d2 = (b1 & 3) << 4 | b2 >> 4;
+      var d3 = i + 1 < ii ? (b2 & 0xF) << 2 | b3 >> 6 : 64;
+      var d4 = i + 2 < ii ? b3 & 0x3F : 64;
+      buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
+     }
+     return buffer;
+    };
+   }();
+   function MessageHandler(sourceName, targetName, comObj) {
+    this.sourceName = sourceName;
+    this.targetName = targetName;
+    this.comObj = comObj;
+    this.callbackIndex = 1;
+    this.postMessageTransfers = true;
+    var callbacksCapabilities = this.callbacksCapabilities = Object.create(null);
+    var ah = this.actionHandler = Object.create(null);
+    this._onComObjOnMessage = function messageHandlerComObjOnMessage(event) {
+     var data = event.data;
+     if (data.targetName !== this.sourceName) {
+      return;
+     }
+     if (data.isReply) {
+      var callbackId = data.callbackId;
+      if (data.callbackId in callbacksCapabilities) {
+       var callback = callbacksCapabilities[callbackId];
+       delete callbacksCapabilities[callbackId];
+       if ('error' in data) {
+        callback.reject(data.error);
+       } else {
+        callback.resolve(data.data);
+       }
+      } else {
+       error('Cannot resolve callback ' + callbackId);
+      }
+     } else if (data.action in ah) {
+      var action = ah[data.action];
+      if (data.callbackId) {
+       var sourceName = this.sourceName;
+       var targetName = data.sourceName;
+       Promise.resolve().then(function () {
+        return action[0].call(action[1], data.data);
+       }).then(function (result) {
+        comObj.postMessage({
+         sourceName: sourceName,
+         targetName: targetName,
+         isReply: true,
+         callbackId: data.callbackId,
+         data: result
+        });
+       }, function (reason) {
+        if (reason instanceof Error) {
+         reason = reason + '';
         }
-        var rgbBuf = [
-          'rgb(',
-          0,
-          ',',
-          0,
-          ',',
-          0,
-          ')'
-        ];
-        // makeCssRgb() can be called thousands of times. Using |rgbBuf| avoids
-        // creating many intermediate strings.
-        Util.makeCssRgb = function Util_makeCssRgb(r, g, b) {
-          rgbBuf[1] = r;
-          rgbBuf[3] = g;
-          rgbBuf[5] = b;
-          return rgbBuf.join('');
-        };
-        // Concatenates two transformation matrices together and returns the result.
-        Util.transform = function Util_transform(m1, m2) {
-          return [
-            m1[0] * m2[0] + m1[2] * m2[1],
-            m1[1] * m2[0] + m1[3] * m2[1],
-            m1[0] * m2[2] + m1[2] * m2[3],
-            m1[1] * m2[2] + m1[3] * m2[3],
-            m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
-            m1[1] * m2[4] + m1[3] * m2[5] + m1[5]
-          ];
-        };
-        // For 2d affine transforms
-        Util.applyTransform = function Util_applyTransform(p, m) {
-          var xt = p[0] * m[0] + p[1] * m[2] + m[4];
-          var yt = p[0] * m[1] + p[1] * m[3] + m[5];
-          return [
-            xt,
-            yt
-          ];
-        };
-        Util.applyInverseTransform = function Util_applyInverseTransform(p, m) {
-          var d = m[0] * m[3] - m[1] * m[2];
-          var xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d;
-          var yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d;
-          return [
-            xt,
-            yt
-          ];
-        };
-        // Applies the transform to the rectangle and finds the minimum axially
-        // aligned bounding box.
-        Util.getAxialAlignedBoundingBox = function Util_getAxialAlignedBoundingBox(r, m) {
-          var p1 = Util.applyTransform(r, m);
-          var p2 = Util.applyTransform(r.slice(2, 4), m);
-          var p3 = Util.applyTransform([
-            r[0],
-            r[3]
-          ], m);
-          var p4 = Util.applyTransform([
-            r[2],
-            r[1]
-          ], m);
-          return [
-            Math.min(p1[0], p2[0], p3[0], p4[0]),
-            Math.min(p1[1], p2[1], p3[1], p4[1]),
-            Math.max(p1[0], p2[0], p3[0], p4[0]),
-            Math.max(p1[1], p2[1], p3[1], p4[1])
-          ];
-        };
-        Util.inverseTransform = function Util_inverseTransform(m) {
-          var d = m[0] * m[3] - m[1] * m[2];
-          return [
-            m[3] / d,
-            -m[1] / d,
-            -m[2] / d,
-            m[0] / d,
-            (m[2] * m[5] - m[4] * m[3]) / d,
-            (m[4] * m[1] - m[5] * m[0]) / d
-          ];
-        };
-        // Apply a generic 3d matrix M on a 3-vector v:
-        //   | a b c |   | X |
-        //   | d e f | x | Y |
-        //   | g h i |   | Z |
-        // M is assumed to be serialized as [a,b,c,d,e,f,g,h,i],
-        // with v as [X,Y,Z]
-        Util.apply3dTransform = function Util_apply3dTransform(m, v) {
-          return [
-            m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
-            m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
-            m[6] * v[0] + m[7] * v[1] + m[8] * v[2]
-          ];
-        };
-        // This calculation uses Singular Value Decomposition.
-        // The SVD can be represented with formula A = USV. We are interested in the
-        // matrix S here because it represents the scale values.
-        Util.singularValueDecompose2dScale = function Util_singularValueDecompose2dScale(m) {
-          var transpose = [
-            m[0],
-            m[2],
-            m[1],
-            m[3]
-          ];
-          // Multiply matrix m with its transpose.
-          var a = m[0] * transpose[0] + m[1] * transpose[2];
-          var b = m[0] * transpose[1] + m[1] * transpose[3];
-          var c = m[2] * transpose[0] + m[3] * transpose[2];
-          var d = m[2] * transpose[1] + m[3] * transpose[3];
-          // Solve the second degree polynomial to get roots.
-          var first = (a + d) / 2;
-          var second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2;
-          var sx = first + second || 1;
-          var sy = first - second || 1;
-          // Scale values are the square roots of the eigenvalues.
-          return [
-            Math.sqrt(sx),
-            Math.sqrt(sy)
-          ];
-        };
-        // Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
-        // For coordinate systems whose origin lies in the bottom-left, this
-        // means normalization to (BL,TR) ordering. For systems with origin in the
-        // top-left, this means (TL,BR) ordering.
-        Util.normalizeRect = function Util_normalizeRect(rect) {
-          var r = rect.slice(0);
-          // clone rect
-          if (rect[0] > rect[2]) {
-            r[0] = rect[2];
-            r[2] = rect[0];
-          }
-          if (rect[1] > rect[3]) {
-            r[1] = rect[3];
-            r[3] = rect[1];
+        comObj.postMessage({
+         sourceName: sourceName,
+         targetName: targetName,
+         isReply: true,
+         callbackId: data.callbackId,
+         error: reason
+        });
+       });
+      } else {
+       action[0].call(action[1], data.data);
+      }
+     } else {
+      error('Unknown action from worker: ' + data.action);
+     }
+    }.bind(this);
+    comObj.addEventListener('message', this._onComObjOnMessage);
+   }
+   MessageHandler.prototype = {
+    on: function messageHandlerOn(actionName, handler, scope) {
+     var ah = this.actionHandler;
+     if (ah[actionName]) {
+      error('There is already an actionName called "' + actionName + '"');
+     }
+     ah[actionName] = [
+      handler,
+      scope
+     ];
+    },
+    send: function messageHandlerSend(actionName, data, transfers) {
+     var message = {
+      sourceName: this.sourceName,
+      targetName: this.targetName,
+      action: actionName,
+      data: data
+     };
+     this.postMessage(message, transfers);
+    },
+    sendWithPromise: function messageHandlerSendWithPromise(actionName, data, transfers) {
+     var callbackId = this.callbackIndex++;
+     var message = {
+      sourceName: this.sourceName,
+      targetName: this.targetName,
+      action: actionName,
+      data: data,
+      callbackId: callbackId
+     };
+     var capability = createPromiseCapability();
+     this.callbacksCapabilities[callbackId] = capability;
+     try {
+      this.postMessage(message, transfers);
+     } catch (e) {
+      capability.reject(e);
+     }
+     return capability.promise;
+    },
+    postMessage: function (message, transfers) {
+     if (transfers && this.postMessageTransfers) {
+      this.comObj.postMessage(message, transfers);
+     } else {
+      this.comObj.postMessage(message);
+     }
+    },
+    destroy: function () {
+     this.comObj.removeEventListener('message', this._onComObjOnMessage);
+    }
+   };
+   function loadJpegStream(id, imageUrl, objs) {
+    var img = new Image();
+    img.onload = function loadJpegStream_onloadClosure() {
+     objs.resolve(id, img);
+    };
+    img.onerror = function loadJpegStream_onerrorClosure() {
+     objs.resolve(id, null);
+     warn('Error during JPEG image loading');
+    };
+    img.src = imageUrl;
+   }
+   exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX;
+   exports.IDENTITY_MATRIX = IDENTITY_MATRIX;
+   exports.OPS = OPS;
+   exports.VERBOSITY_LEVELS = VERBOSITY_LEVELS;
+   exports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
+   exports.AnnotationBorderStyleType = AnnotationBorderStyleType;
+   exports.AnnotationFieldFlag = AnnotationFieldFlag;
+   exports.AnnotationFlag = AnnotationFlag;
+   exports.AnnotationType = AnnotationType;
+   exports.FontType = FontType;
+   exports.ImageKind = ImageKind;
+   exports.InvalidPDFException = InvalidPDFException;
+   exports.MessageHandler = MessageHandler;
+   exports.MissingDataException = MissingDataException;
+   exports.MissingPDFException = MissingPDFException;
+   exports.NotImplementedException = NotImplementedException;
+   exports.PageViewport = PageViewport;
+   exports.PasswordException = PasswordException;
+   exports.PasswordResponses = PasswordResponses;
+   exports.StatTimer = StatTimer;
+   exports.StreamType = StreamType;
+   exports.TextRenderingMode = TextRenderingMode;
+   exports.UnexpectedResponseException = UnexpectedResponseException;
+   exports.UnknownErrorException = UnknownErrorException;
+   exports.Util = Util;
+   exports.XRefParseException = XRefParseException;
+   exports.arrayByteLength = arrayByteLength;
+   exports.arraysToBytes = arraysToBytes;
+   exports.assert = assert;
+   exports.bytesToString = bytesToString;
+   exports.createBlob = createBlob;
+   exports.createPromiseCapability = createPromiseCapability;
+   exports.createObjectURL = createObjectURL;
+   exports.deprecated = deprecated;
+   exports.error = error;
+   exports.getLookupTableFactory = getLookupTableFactory;
+   exports.getVerbosityLevel = getVerbosityLevel;
+   exports.globalScope = globalScope;
+   exports.info = info;
+   exports.isArray = isArray;
+   exports.isArrayBuffer = isArrayBuffer;
+   exports.isBool = isBool;
+   exports.isEmptyObj = isEmptyObj;
+   exports.isInt = isInt;
+   exports.isNum = isNum;
+   exports.isString = isString;
+   exports.isSpace = isSpace;
+   exports.isSameOrigin = isSameOrigin;
+   exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
+   exports.isLittleEndian = isLittleEndian;
+   exports.isEvalSupported = isEvalSupported;
+   exports.loadJpegStream = loadJpegStream;
+   exports.log2 = log2;
+   exports.readInt8 = readInt8;
+   exports.readUint16 = readUint16;
+   exports.readUint32 = readUint32;
+   exports.removeNullCharacters = removeNullCharacters;
+   exports.setVerbosityLevel = setVerbosityLevel;
+   exports.shadow = shadow;
+   exports.string32 = string32;
+   exports.stringToBytes = stringToBytes;
+   exports.stringToPDFString = stringToPDFString;
+   exports.stringToUTF8String = stringToUTF8String;
+   exports.utf8StringToString = utf8StringToString;
+   exports.warn = warn;
+  }));
+  (function (root, factory) {
+   factory(root.pdfjsDisplayDOMUtils = {}, root.pdfjsSharedUtil);
+  }(this, function (exports, sharedUtil) {
+   var removeNullCharacters = sharedUtil.removeNullCharacters;
+   var warn = sharedUtil.warn;
+   var deprecated = sharedUtil.deprecated;
+   var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
+   var CustomStyle = function CustomStyleClosure() {
+    var prefixes = [
+     'ms',
+     'Moz',
+     'Webkit',
+     'O'
+    ];
+    var _cache = Object.create(null);
+    function CustomStyle() {
+    }
+    CustomStyle.getProp = function get(propName, element) {
+     if (arguments.length === 1 && typeof _cache[propName] === 'string') {
+      return _cache[propName];
+     }
+     element = element || document.documentElement;
+     var style = element.style, prefixed, uPropName;
+     if (typeof style[propName] === 'string') {
+      return _cache[propName] = propName;
+     }
+     uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
+     for (var i = 0, l = prefixes.length; i < l; i++) {
+      prefixed = prefixes[i] + uPropName;
+      if (typeof style[prefixed] === 'string') {
+       return _cache[propName] = prefixed;
+      }
+     }
+     return _cache[propName] = 'undefined';
+    };
+    CustomStyle.setProp = function set(propName, element, str) {
+     var prop = this.getProp(propName);
+     if (prop !== 'undefined') {
+      element.style[prop] = str;
+     }
+    };
+    return CustomStyle;
+   }();
+   var hasCanvasTypedArrays;
+   hasCanvasTypedArrays = function () {
+    return true;
+   };
+   var LinkTarget = {
+    NONE: 0,
+    SELF: 1,
+    BLANK: 2,
+    PARENT: 3,
+    TOP: 4
+   };
+   var LinkTargetStringMap = [
+    '',
+    '_self',
+    '_blank',
+    '_parent',
+    '_top'
+   ];
+   function addLinkAttributes(link, params) {
+    var url = params && params.url;
+    link.href = link.title = url ? removeNullCharacters(url) : '';
+    if (url) {
+     var target = params.target;
+     if (typeof target === 'undefined') {
+      target = getDefaultSetting('externalLinkTarget');
+     }
+     link.target = LinkTargetStringMap[target];
+     var rel = params.rel;
+     if (typeof rel === 'undefined') {
+      rel = getDefaultSetting('externalLinkRel');
+     }
+     link.rel = rel;
+    }
+   }
+   function getFilenameFromUrl(url) {
+    var anchor = url.indexOf('#');
+    var query = url.indexOf('?');
+    var end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);
+    return url.substring(url.lastIndexOf('/', end) + 1, end);
+   }
+   function getDefaultSetting(id) {
+    var globalSettings = sharedUtil.globalScope.PDFJS;
+    switch (id) {
+    case 'pdfBug':
+     return globalSettings ? globalSettings.pdfBug : false;
+    case 'disableAutoFetch':
+     return globalSettings ? globalSettings.disableAutoFetch : false;
+    case 'disableStream':
+     return globalSettings ? globalSettings.disableStream : false;
+    case 'disableRange':
+     return globalSettings ? globalSettings.disableRange : false;
+    case 'disableFontFace':
+     return globalSettings ? globalSettings.disableFontFace : false;
+    case 'disableCreateObjectURL':
+     return globalSettings ? globalSettings.disableCreateObjectURL : false;
+    case 'disableWebGL':
+     return globalSettings ? globalSettings.disableWebGL : true;
+    case 'cMapUrl':
+     return globalSettings ? globalSettings.cMapUrl : null;
+    case 'cMapPacked':
+     return globalSettings ? globalSettings.cMapPacked : false;
+    case 'postMessageTransfers':
+     return globalSettings ? globalSettings.postMessageTransfers : true;
+    case 'workerSrc':
+     return globalSettings ? globalSettings.workerSrc : null;
+    case 'disableWorker':
+     return globalSettings ? globalSettings.disableWorker : false;
+    case 'maxImageSize':
+     return globalSettings ? globalSettings.maxImageSize : -1;
+    case 'imageResourcesPath':
+     return globalSettings ? globalSettings.imageResourcesPath : '';
+    case 'isEvalSupported':
+     return globalSettings ? globalSettings.isEvalSupported : true;
+    case 'externalLinkTarget':
+     if (!globalSettings) {
+      return LinkTarget.NONE;
+     }
+     switch (globalSettings.externalLinkTarget) {
+     case LinkTarget.NONE:
+     case LinkTarget.SELF:
+     case LinkTarget.BLANK:
+     case LinkTarget.PARENT:
+     case LinkTarget.TOP:
+      return globalSettings.externalLinkTarget;
+     }
+     warn('PDFJS.externalLinkTarget is invalid: ' + globalSettings.externalLinkTarget);
+     globalSettings.externalLinkTarget = LinkTarget.NONE;
+     return LinkTarget.NONE;
+    case 'externalLinkRel':
+     return globalSettings ? globalSettings.externalLinkRel : 'noreferrer';
+    case 'enableStats':
+     return !!(globalSettings && globalSettings.enableStats);
+    default:
+     throw new Error('Unknown default setting: ' + id);
+    }
+   }
+   function isExternalLinkTargetSet() {
+    var externalLinkTarget = getDefaultSetting('externalLinkTarget');
+    switch (externalLinkTarget) {
+    case LinkTarget.NONE:
+     return false;
+    case LinkTarget.SELF:
+    case LinkTarget.BLANK:
+    case LinkTarget.PARENT:
+    case LinkTarget.TOP:
+     return true;
+    }
+   }
+   function isValidUrl(url, allowRelative) {
+    deprecated('isValidUrl(), please use createValidAbsoluteUrl() instead.');
+    var baseUrl = allowRelative ? 'http://example.com' : null;
+    return createValidAbsoluteUrl(url, baseUrl) !== null;
+   }
+   exports.CustomStyle = CustomStyle;
+   exports.addLinkAttributes = addLinkAttributes;
+   exports.isExternalLinkTargetSet = isExternalLinkTargetSet;
+   exports.isValidUrl = isValidUrl;
+   exports.getFilenameFromUrl = getFilenameFromUrl;
+   exports.LinkTarget = LinkTarget;
+   exports.hasCanvasTypedArrays = hasCanvasTypedArrays;
+   exports.getDefaultSetting = getDefaultSetting;
+  }));
+  (function (root, factory) {
+   factory(root.pdfjsDisplayFontLoader = {}, root.pdfjsSharedUtil);
+  }(this, function (exports, sharedUtil) {
+   var assert = sharedUtil.assert;
+   var bytesToString = sharedUtil.bytesToString;
+   var string32 = sharedUtil.string32;
+   var shadow = sharedUtil.shadow;
+   var warn = sharedUtil.warn;
+   function FontLoader(docId) {
+    this.docId = docId;
+    this.styleElement = null;
+   }
+   FontLoader.prototype = {
+    insertRule: function fontLoaderInsertRule(rule) {
+     var styleElement = this.styleElement;
+     if (!styleElement) {
+      styleElement = this.styleElement = document.createElement('style');
+      styleElement.id = 'PDFJS_FONT_STYLE_TAG_' + this.docId;
+      document.documentElement.getElementsByTagName('head')[0].appendChild(styleElement);
+     }
+     var styleSheet = styleElement.sheet;
+     styleSheet.insertRule(rule, styleSheet.cssRules.length);
+    },
+    clear: function fontLoaderClear() {
+     var styleElement = this.styleElement;
+     if (styleElement) {
+      styleElement.parentNode.removeChild(styleElement);
+      styleElement = this.styleElement = null;
+     }
+    }
+   };
+   FontLoader.prototype.bind = function fontLoaderBind(fonts, callback) {
+    for (var i = 0, ii = fonts.length; i < ii; i++) {
+     var font = fonts[i];
+     if (font.attached) {
+      continue;
+     }
+     font.attached = true;
+     var rule = font.createFontFaceRule();
+     if (rule) {
+      this.insertRule(rule);
+     }
+    }
+    setTimeout(callback);
+   };
+   var IsEvalSupportedCached = {
+    get value() {
+     return shadow(this, 'value', sharedUtil.isEvalSupported());
+    }
+   };
+   var FontFaceObject = function FontFaceObjectClosure() {
+    function FontFaceObject(translatedData, options) {
+     this.compiledGlyphs = Object.create(null);
+     for (var i in translatedData) {
+      this[i] = translatedData[i];
+     }
+     this.options = options;
+    }
+    FontFaceObject.prototype = {
+     createNativeFontFace: function FontFaceObject_createNativeFontFace() {
+      throw new Error('Not implemented: createNativeFontFace');
+     },
+     createFontFaceRule: function FontFaceObject_createFontFaceRule() {
+      if (!this.data) {
+       return null;
+      }
+      if (this.options.disableFontFace) {
+       this.disableFontFace = true;
+       return null;
+      }
+      var data = bytesToString(new Uint8Array(this.data));
+      var fontName = this.loadedName;
+      var url = 'url(data:' + this.mimetype + ';base64,' + btoa(data) + ');';
+      var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}';
+      if (this.options.fontRegistry) {
+       this.options.fontRegistry.registerFont(this, url);
+      }
+      return rule;
+     },
+     getPathGenerator: function FontFaceObject_getPathGenerator(objs, character) {
+      if (!(character in this.compiledGlyphs)) {
+       var cmds = objs.get(this.loadedName + '_path_' + character);
+       var current, i, len;
+       if (this.options.isEvalSupported && IsEvalSupportedCached.value) {
+        var args, js = '';
+        for (i = 0, len = cmds.length; i < len; i++) {
+         current = cmds[i];
+         if (current.args !== undefined) {
+          args = current.args.join(',');
+         } else {
+          args = '';
+         }
+         js += 'c.' + current.cmd + '(' + args + ');\n';
+        }
+        this.compiledGlyphs[character] = new Function('c', 'size', js);
+       } else {
+        this.compiledGlyphs[character] = function (c, size) {
+         for (i = 0, len = cmds.length; i < len; i++) {
+          current = cmds[i];
+          if (current.cmd === 'scale') {
+           current.args = [
+            size,
+            -size
+           ];
           }
-          return r;
-        };
-        // Returns a rectangle [x1, y1, x2, y2] corresponding to the
-        // intersection of rect1 and rect2. If no intersection, returns 'false'
-        // The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
-        Util.intersect = function Util_intersect(rect1, rect2) {
-          function compare(a, b) {
-            return a - b;
-          }
-          // Order points along the axes
-          var orderedX = [
-              rect1[0],
-              rect1[2],
-              rect2[0],
-              rect2[2]
-            ].sort(compare), orderedY = [
-              rect1[1],
-              rect1[3],
-              rect2[1],
-              rect2[3]
-            ].sort(compare), result = [];
-          rect1 = Util.normalizeRect(rect1);
-          rect2 = Util.normalizeRect(rect2);
-          // X: first and second points belong to different rectangles?
-          if (orderedX[0] === rect1[0] && orderedX[1] === rect2[0] || orderedX[0] === rect2[0] && orderedX[1] === rect1[0]) {
-            // Intersection must be between second and third points
-            result[0] = orderedX[1];
-            result[2] = orderedX[2];
-          } else {
-            return false;
-          }
-          // Y: first and second points belong to different rectangles?
-          if (orderedY[0] === rect1[1] && orderedY[1] === rect2[1] || orderedY[0] === rect2[1] && orderedY[1] === rect1[1]) {
-            // Intersection must be between second and third points
-            result[1] = orderedY[1];
-            result[3] = orderedY[2];
-          } else {
-            return false;
-          }
-          return result;
-        };
-        Util.sign = function Util_sign(num) {
-          return num < 0 ? -1 : 1;
-        };
-        var ROMAN_NUMBER_MAP = [
-          '',
-          'C',
-          'CC',
-          'CCC',
-          'CD',
-          'D',
-          'DC',
-          'DCC',
-          'DCCC',
-          'CM',
-          '',
-          'X',
-          'XX',
-          'XXX',
-          'XL',
-          'L',
-          'LX',
-          'LXX',
-          'LXXX',
-          'XC',
-          '',
-          'I',
-          'II',
-          'III',
-          'IV',
-          'V',
-          'VI',
-          'VII',
-          'VIII',
-          'IX'
-        ];
-        /**
-         * Converts positive integers to (upper case) Roman numerals.
-         * @param {integer} number - The number that should be converted.
-         * @param {boolean} lowerCase - Indicates if the result should be converted
-         *   to lower case letters. The default is false.
-         * @return {string} The resulting Roman number.
-         */
-        Util.toRoman = function Util_toRoman(number, lowerCase) {
-          assert(isInt(number) && number > 0, 'The number should be a positive integer.');
-          var pos, romanBuf = [];
-          // Thousands
-          while (number >= 1000) {
-            number -= 1000;
-            romanBuf.push('M');
-          }
-          // Hundreds
-          pos = number / 100 | 0;
-          number %= 100;
-          romanBuf.push(ROMAN_NUMBER_MAP[pos]);
-          // Tens
-          pos = number / 10 | 0;
-          number %= 10;
-          romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]);
-          // Ones
-          romanBuf.push(ROMAN_NUMBER_MAP[20 + number]);
-          var romanStr = romanBuf.join('');
-          return lowerCase ? romanStr.toLowerCase() : romanStr;
-        };
-        Util.appendToArray = function Util_appendToArray(arr1, arr2) {
-          Array.prototype.push.apply(arr1, arr2);
-        };
-        Util.prependToArray = function Util_prependToArray(arr1, arr2) {
-          Array.prototype.unshift.apply(arr1, arr2);
-        };
-        Util.extendObj = function extendObj(obj1, obj2) {
-          for (var key in obj2) {
-            obj1[key] = obj2[key];
-          }
-        };
-        Util.getInheritableProperty = function Util_getInheritableProperty(dict, name, getArray) {
-          while (dict && !dict.has(name)) {
-            dict = dict.get('Parent');
-          }
-          if (!dict) {
-            return null;
-          }
-          return getArray ? dict.getArray(name) : dict.get(name);
-        };
-        Util.inherit = function Util_inherit(sub, base, prototype) {
-          sub.prototype = Object.create(base.prototype);
-          sub.prototype.constructor = sub;
-          for (var prop in prototype) {
-            sub.prototype[prop] = prototype[prop];
-          }
-        };
-        Util.loadScript = function Util_loadScript(src, callback) {
-          var script = document.createElement('script');
-          var loaded = false;
-          script.setAttribute('src', src);
-          if (callback) {
-            script.onload = function () {
-              if (!loaded) {
-                callback();
-              }
-              loaded = true;
-            };
-          }
-          document.getElementsByTagName('head')[0].appendChild(script);
+          c[current.cmd].apply(c, current.args);
+         }
         };
-        return Util;
-      }();
-      /**
-       * PDF page viewport created based on scale, rotation and offset.
-       * @class
-       * @alias PageViewport
-       */
-      var PageViewport = function PageViewportClosure() {
-        /**
-         * @constructor
-         * @private
-         * @param viewBox {Array} xMin, yMin, xMax and yMax coordinates.
-         * @param scale {number} scale of the viewport.
-         * @param rotation {number} rotations of the viewport in degrees.
-         * @param offsetX {number} offset X
-         * @param offsetY {number} offset Y
-         * @param dontFlip {boolean} if true, axis Y will not be flipped.
-         */
-        function PageViewport(viewBox, scale, rotation, offsetX, offsetY, dontFlip) {
-          this.viewBox = viewBox;
-          this.scale = scale;
-          this.rotation = rotation;
-          this.offsetX = offsetX;
-          this.offsetY = offsetY;
-          // creating transform to convert pdf coordinate system to the normal
-          // canvas like coordinates taking in account scale and rotation
-          var centerX = (viewBox[2] + viewBox[0]) / 2;
-          var centerY = (viewBox[3] + viewBox[1]) / 2;
-          var rotateA, rotateB, rotateC, rotateD;
-          rotation = rotation % 360;
-          rotation = rotation < 0 ? rotation + 360 : rotation;
-          switch (rotation) {
-          case 180:
-            rotateA = -1;
-            rotateB = 0;
-            rotateC = 0;
-            rotateD = 1;
-            break;
-          case 90:
-            rotateA = 0;
-            rotateB = 1;
-            rotateC = 1;
-            rotateD = 0;
-            break;
-          case 270:
-            rotateA = 0;
-            rotateB = -1;
-            rotateC = -1;
-            rotateD = 0;
-            break;
-          //case 0:
-          default:
-            rotateA = 1;
-            rotateB = 0;
-            rotateC = 0;
-            rotateD = -1;
-            break;
-          }
-          if (dontFlip) {
-            rotateC = -rotateC;
-            rotateD = -rotateD;
-          }
-          var offsetCanvasX, offsetCanvasY;
-          var width, height;
-          if (rotateA === 0) {
-            offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
-            offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
-            width = Math.abs(viewBox[3] - viewBox[1]) * scale;
-            height = Math.abs(viewBox[2] - viewBox[0]) * scale;
-          } else {
-            offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
-            offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
-            width = Math.abs(viewBox[2] - viewBox[0]) * scale;
-            height = Math.abs(viewBox[3] - viewBox[1]) * scale;
-          }
-          // creating transform for the following operations:
-          // translate(-centerX, -centerY), rotate and flip vertically,
-          // scale, and translate(offsetCanvasX, offsetCanvasY)
-          this.transform = [
-            rotateA * scale,
-            rotateB * scale,
-            rotateC * scale,
-            rotateD * scale,
-            offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
-            offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY
-          ];
-          this.width = width;
-          this.height = height;
-          this.fontScale = scale;
-        }
-        PageViewport.prototype = /** @lends PageViewport.prototype */
-        {
-          /**
-           * Clones viewport with additional properties.
-           * @param args {Object} (optional) If specified, may contain the 'scale' or
-           * 'rotation' properties to override the corresponding properties in
-           * the cloned viewport.
-           * @returns {PageViewport} Cloned viewport.
-           */
-          clone: function PageViewPort_clone(args) {
-            args = args || {};
-            var scale = 'scale' in args ? args.scale : this.scale;
-            var rotation = 'rotation' in args ? args.rotation : this.rotation;
-            return new PageViewport(this.viewBox.slice(), scale, rotation, this.offsetX, this.offsetY, args.dontFlip);
-          },
-          /**
-           * Converts PDF point to the viewport coordinates. For examples, useful for
-           * converting PDF location into canvas pixel coordinates.
-           * @param x {number} X coordinate.
-           * @param y {number} Y coordinate.
-           * @returns {Object} Object that contains 'x' and 'y' properties of the
-           * point in the viewport coordinate space.
-           * @see {@link convertToPdfPoint}
-           * @see {@link convertToViewportRectangle}
-           */
-          convertToViewportPoint: function PageViewport_convertToViewportPoint(x, y) {
-            return Util.applyTransform([
-              x,
-              y
-            ], this.transform);
-          },
-          /**
-           * Converts PDF rectangle to the viewport coordinates.
-           * @param rect {Array} xMin, yMin, xMax and yMax coordinates.
-           * @returns {Array} Contains corresponding coordinates of the rectangle
-           * in the viewport coordinate space.
-           * @see {@link convertToViewportPoint}
-           */
-          convertToViewportRectangle: function PageViewport_convertToViewportRectangle(rect) {
-            var tl = Util.applyTransform([
-              rect[0],
-              rect[1]
-            ], this.transform);
-            var br = Util.applyTransform([
-              rect[2],
-              rect[3]
-            ], this.transform);
-            return [
-              tl[0],
-              tl[1],
-              br[0],
-              br[1]
-            ];
-          },
-          /**
-           * Converts viewport coordinates to the PDF location. For examples, useful
-           * for converting canvas pixel location into PDF one.
-           * @param x {number} X coordinate.
-           * @param y {number} Y coordinate.
-           * @returns {Object} Object that contains 'x' and 'y' properties of the
-           * point in the PDF coordinate space.
-           * @see {@link convertToViewportPoint}
-           */
-          convertToPdfPoint: function PageViewport_convertToPdfPoint(x, y) {
-            return Util.applyInverseTransform([
-              x,
-              y
-            ], this.transform);
-          }
-        };
-        return PageViewport;
-      }();
-      var PDFStringTranslateTable = [
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0x2D8,
-        0x2C7,
-        0x2C6,
-        0x2D9,
-        0x2DD,
-        0x2DB,
-        0x2DA,
-        0x2DC,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
+       }
+      }
+      return this.compiledGlyphs[character];
+     }
+    };
+    return FontFaceObject;
+   }();
+   exports.FontFaceObject = FontFaceObject;
+   exports.FontLoader = FontLoader;
+  }));
+  (function (root, factory) {
+   factory(root.pdfjsDisplayMetadata = {}, root.pdfjsSharedUtil);
+  }(this, function (exports, sharedUtil) {
+   var error = sharedUtil.error;
+   function fixMetadata(meta) {
+    return meta.replace(/>\\376\\377([^<]+)/g, function (all, codes) {
+     var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) {
+      return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
+     });
+     var chars = '';
+     for (var i = 0; i < bytes.length; i += 2) {
+      var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
+      chars += code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38 && false ? String.fromCharCode(code) : '&#x' + (0x10000 + code).toString(16).substring(1) + ';';
+     }
+     return '>' + chars;
+    });
+   }
+   function Metadata(meta) {
+    if (typeof meta === 'string') {
+     meta = fixMetadata(meta);
+     var parser = new DOMParser();
+     meta = parser.parseFromString(meta, 'application/xml');
+    } else if (!(meta instanceof Document)) {
+     error('Metadata: Invalid metadata object');
+    }
+    this.metaDocument = meta;
+    this.metadata = Object.create(null);
+    this.parse();
+   }
+   Metadata.prototype = {
+    parse: function Metadata_parse() {
+     var doc = this.metaDocument;
+     var rdf = doc.documentElement;
+     if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
+      rdf = rdf.firstChild;
+      while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
+       rdf = rdf.nextSibling;
+      }
+     }
+     var nodeName = rdf ? rdf.nodeName.toLowerCase() : null;
+     if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) {
+      return;
+     }
+     var children = rdf.childNodes, desc, entry, name, i, ii, length, iLength;
+     for (i = 0, length = children.length; i < length; i++) {
+      desc = children[i];
+      if (desc.nodeName.toLowerCase() !== 'rdf:description') {
+       continue;
+      }
+      for (ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) {
+       if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text') {
+        entry = desc.childNodes[ii];
+        name = entry.nodeName.toLowerCase();
+        this.metadata[name] = entry.textContent.trim();
+       }
+      }
+     }
+    },
+    get: function Metadata_get(name) {
+     return this.metadata[name] || null;
+    },
+    has: function Metadata_has(name) {
+     return typeof this.metadata[name] !== 'undefined';
+    }
+   };
+   exports.Metadata = Metadata;
+  }));
+  (function (root, factory) {
+   factory(root.pdfjsDisplaySVG = {}, root.pdfjsSharedUtil);
+  }(this, function (exports, sharedUtil) {
+  }));
+  (function (root, factory) {
+   factory(root.pdfjsDisplayAnnotationLayer = {}, root.pdfjsSharedUtil, root.pdfjsDisplayDOMUtils);
+  }(this, function (exports, sharedUtil, displayDOMUtils) {
+   var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType;
+   var AnnotationType = sharedUtil.AnnotationType;
+   var Util = sharedUtil.Util;
+   var addLinkAttributes = displayDOMUtils.addLinkAttributes;
+   var LinkTarget = displayDOMUtils.LinkTarget;
+   var getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl;
+   var warn = sharedUtil.warn;
+   var CustomStyle = displayDOMUtils.CustomStyle;
+   var getDefaultSetting = displayDOMUtils.getDefaultSetting;
+   function AnnotationElementFactory() {
+   }
+   AnnotationElementFactory.prototype = {
+    create: function AnnotationElementFactory_create(parameters) {
+     var subtype = parameters.data.annotationType;
+     switch (subtype) {
+     case AnnotationType.LINK:
+      return new LinkAnnotationElement(parameters);
+     case AnnotationType.TEXT:
+      return new TextAnnotationElement(parameters);
+     case AnnotationType.WIDGET:
+      var fieldType = parameters.data.fieldType;
+      switch (fieldType) {
+      case 'Tx':
+       return new TextWidgetAnnotationElement(parameters);
+      case 'Ch':
+       return new ChoiceWidgetAnnotationElement(parameters);
+      }
+      return new WidgetAnnotationElement(parameters);
+     case AnnotationType.POPUP:
+      return new PopupAnnotationElement(parameters);
+     case AnnotationType.HIGHLIGHT:
+      return new HighlightAnnotationElement(parameters);
+     case AnnotationType.UNDERLINE:
+      return new UnderlineAnnotationElement(parameters);
+     case AnnotationType.SQUIGGLY:
+      return new SquigglyAnnotationElement(parameters);
+     case AnnotationType.STRIKEOUT:
+      return new StrikeOutAnnotationElement(parameters);
+     case AnnotationType.FILEATTACHMENT:
+      return new FileAttachmentAnnotationElement(parameters);
+     default:
+      return new AnnotationElement(parameters);
+     }
+    }
+   };
+   var AnnotationElement = function AnnotationElementClosure() {
+    function AnnotationElement(parameters, isRenderable) {
+     this.isRenderable = isRenderable || false;
+     this.data = parameters.data;
+     this.layer = parameters.layer;
+     this.page = parameters.page;
+     this.viewport = parameters.viewport;
+     this.linkService = parameters.linkService;
+     this.downloadManager = parameters.downloadManager;
+     this.imageResourcesPath = parameters.imageResourcesPath;
+     this.renderInteractiveForms = parameters.renderInteractiveForms;
+     if (isRenderable) {
+      this.container = this._createContainer();
+     }
+    }
+    AnnotationElement.prototype = {
+     _createContainer: function AnnotationElement_createContainer() {
+      var data = this.data, page = this.page, viewport = this.viewport;
+      var container = document.createElement('section');
+      var width = data.rect[2] - data.rect[0];
+      var height = data.rect[3] - data.rect[1];
+      container.setAttribute('data-annotation-id', data.id);
+      var rect = Util.normalizeRect([
+       data.rect[0],
+       page.view[3] - data.rect[1] + page.view[1],
+       data.rect[2],
+       page.view[3] - data.rect[3] + page.view[1]
+      ]);
+      CustomStyle.setProp('transform', container, 'matrix(' + viewport.transform.join(',') + ')');
+      CustomStyle.setProp('transformOrigin', container, -rect[0] + 'px ' + -rect[1] + 'px');
+      if (data.borderStyle.width > 0) {
+       container.style.borderWidth = data.borderStyle.width + 'px';
+       if (data.borderStyle.style !== AnnotationBorderStyleType.UNDERLINE) {
+        width = width - 2 * data.borderStyle.width;
+        height = height - 2 * data.borderStyle.width;
+       }
+       var horizontalRadius = data.borderStyle.horizontalCornerRadius;
+       var verticalRadius = data.borderStyle.verticalCornerRadius;
+       if (horizontalRadius > 0 || verticalRadius > 0) {
+        var radius = horizontalRadius + 'px / ' + verticalRadius + 'px';
+        CustomStyle.setProp('borderRadius', container, radius);
+       }
+       switch (data.borderStyle.style) {
+       case AnnotationBorderStyleType.SOLID:
+        container.style.borderStyle = 'solid';
+        break;
+       case AnnotationBorderStyleType.DASHED:
+        container.style.borderStyle = 'dashed';
+        break;
+       case AnnotationBorderStyleType.BEVELED:
+        warn('Unimplemented border style: beveled');
+        break;
+       case AnnotationBorderStyleType.INSET:
+        warn('Unimplemented border style: inset');
+        break;
+       case AnnotationBorderStyleType.UNDERLINE:
+        container.style.borderBottomStyle = 'solid';
+        break;
+       default:
+        break;
+       }
+       if (data.color) {
+        container.style.borderColor = Util.makeCssRgb(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);
+       } else {
+        container.style.borderWidth = 0;
+       }
+      }
+      container.style.left = rect[0] + 'px';
+      container.style.top = rect[1] + 'px';
+      container.style.width = width + 'px';
+      container.style.height = height + 'px';
+      return container;
+     },
+     _createPopup: function AnnotationElement_createPopup(container, trigger, data) {
+      if (!trigger) {
+       trigger = document.createElement('div');
+       trigger.style.height = container.style.height;
+       trigger.style.width = container.style.width;
+       container.appendChild(trigger);
+      }
+      var popupElement = new PopupElement({
+       container: container,
+       trigger: trigger,
+       color: data.color,
+       title: data.title,
+       contents: data.contents,
+       hideWrapper: true
+      });
+      var popup = popupElement.render();
+      popup.style.left = container.style.width;
+      container.appendChild(popup);
+     },
+     render: function AnnotationElement_render() {
+      throw new Error('Abstract method AnnotationElement.render called');
+     }
+    };
+    return AnnotationElement;
+   }();
+   var LinkAnnotationElement = function LinkAnnotationElementClosure() {
+    function LinkAnnotationElement(parameters) {
+     AnnotationElement.call(this, parameters, true);
+    }
+    Util.inherit(LinkAnnotationElement, AnnotationElement, {
+     render: function LinkAnnotationElement_render() {
+      this.container.className = 'linkAnnotation';
+      var link = document.createElement('a');
+      addLinkAttributes(link, {
+       url: this.data.url,
+       target: this.data.newWindow ? LinkTarget.BLANK : undefined
+      });
+      if (!this.data.url) {
+       if (this.data.action) {
+        this._bindNamedAction(link, this.data.action);
+       } else {
+        this._bindLink(link, this.data.dest);
+       }
+      }
+      this.container.appendChild(link);
+      return this.container;
+     },
+     _bindLink: function LinkAnnotationElement_bindLink(link, destination) {
+      var self = this;
+      link.href = this.linkService.getDestinationHash(destination);
+      link.onclick = function () {
+       if (destination) {
+        self.linkService.navigateTo(destination);
+       }
+       return false;
+      };
+      if (destination) {
+       link.className = 'internalLink';
+      }
+     },
+     _bindNamedAction: function LinkAnnotationElement_bindNamedAction(link, action) {
+      var self = this;
+      link.href = this.linkService.getAnchorUrl('');
+      link.onclick = function () {
+       self.linkService.executeNamedAction(action);
+       return false;
+      };
+      link.className = 'internalLink';
+     }
+    });
+    return LinkAnnotationElement;
+   }();
+   var TextAnnotationElement = function TextAnnotationElementClosure() {
+    function TextAnnotationElement(parameters) {
+     var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(TextAnnotationElement, AnnotationElement, {
+     render: function TextAnnotationElement_render() {
+      this.container.className = 'textAnnotation';
+      var image = document.createElement('img');
+      image.style.height = this.container.style.height;
+      image.style.width = this.container.style.width;
+      image.src = this.imageResourcesPath + 'annotation-' + this.data.name.toLowerCase() + '.svg';
+      image.alt = '[{{type}} Annotation]';
+      image.dataset.l10nId = 'text_annotation_type';
+      image.dataset.l10nArgs = JSON.stringify({ type: this.data.name });
+      if (!this.data.hasPopup) {
+       this._createPopup(this.container, image, this.data);
+      }
+      this.container.appendChild(image);
+      return this.container;
+     }
+    });
+    return TextAnnotationElement;
+   }();
+   var WidgetAnnotationElement = function WidgetAnnotationElementClosure() {
+    function WidgetAnnotationElement(parameters, isRenderable) {
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(WidgetAnnotationElement, AnnotationElement, {
+     render: function WidgetAnnotationElement_render() {
+      return this.container;
+     }
+    });
+    return WidgetAnnotationElement;
+   }();
+   var TextWidgetAnnotationElement = function TextWidgetAnnotationElementClosure() {
+    var TEXT_ALIGNMENT = [
+     'left',
+     'center',
+     'right'
+    ];
+    function TextWidgetAnnotationElement(parameters) {
+     var isRenderable = parameters.renderInteractiveForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue;
+     WidgetAnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(TextWidgetAnnotationElement, WidgetAnnotationElement, {
+     render: function TextWidgetAnnotationElement_render() {
+      this.container.className = 'textWidgetAnnotation';
+      var element = null;
+      if (this.renderInteractiveForms) {
+       if (this.data.multiLine) {
+        element = document.createElement('textarea');
+        element.textContent = this.data.fieldValue;
+       } else {
+        element = document.createElement('input');
+        element.type = 'text';
+        element.setAttribute('value', this.data.fieldValue);
+       }
+       element.disabled = this.data.readOnly;
+       if (this.data.maxLen !== null) {
+        element.maxLength = this.data.maxLen;
+       }
+       if (this.data.comb) {
+        var fieldWidth = this.data.rect[2] - this.data.rect[0];
+        var combWidth = fieldWidth / this.data.maxLen;
+        element.classList.add('comb');
+        element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)';
+       }
+      } else {
+       element = document.createElement('div');
+       element.textContent = this.data.fieldValue;
+       element.style.verticalAlign = 'middle';
+       element.style.display = 'table-cell';
+       var font = null;
+       if (this.data.fontRefName) {
+        font = this.page.commonObjs.getData(this.data.fontRefName);
+       }
+       this._setTextStyle(element, font);
+      }
+      if (this.data.textAlignment !== null) {
+       element.style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
+      }
+      this.container.appendChild(element);
+      return this.container;
+     },
+     _setTextStyle: function TextWidgetAnnotationElement_setTextStyle(element, font) {
+      var style = element.style;
+      style.fontSize = this.data.fontSize + 'px';
+      style.direction = this.data.fontDirection < 0 ? 'rtl' : 'ltr';
+      if (!font) {
+       return;
+      }
+      style.fontWeight = font.black ? font.bold ? '900' : 'bold' : font.bold ? 'bold' : 'normal';
+      style.fontStyle = font.italic ? 'italic' : 'normal';
+      var fontFamily = font.loadedName ? '"' + font.loadedName + '", ' : '';
+      var fallbackName = font.fallbackName || 'Helvetica, sans-serif';
+      style.fontFamily = fontFamily + fallbackName;
+     }
+    });
+    return TextWidgetAnnotationElement;
+   }();
+   var ChoiceWidgetAnnotationElement = function ChoiceWidgetAnnotationElementClosure() {
+    function ChoiceWidgetAnnotationElement(parameters) {
+     WidgetAnnotationElement.call(this, parameters, parameters.renderInteractiveForms);
+    }
+    Util.inherit(ChoiceWidgetAnnotationElement, WidgetAnnotationElement, {
+     render: function ChoiceWidgetAnnotationElement_render() {
+      this.container.className = 'choiceWidgetAnnotation';
+      var selectElement = document.createElement('select');
+      selectElement.disabled = this.data.readOnly;
+      if (!this.data.combo) {
+       selectElement.size = this.data.options.length;
+       if (this.data.multiSelect) {
+        selectElement.multiple = true;
+       }
+      }
+      for (var i = 0, ii = this.data.options.length; i < ii; i++) {
+       var option = this.data.options[i];
+       var optionElement = document.createElement('option');
+       optionElement.textContent = option.displayValue;
+       optionElement.value = option.exportValue;
+       if (this.data.fieldValue.indexOf(option.displayValue) >= 0) {
+        optionElement.setAttribute('selected', true);
+       }
+       selectElement.appendChild(optionElement);
+      }
+      this.container.appendChild(selectElement);
+      return this.container;
+     }
+    });
+    return ChoiceWidgetAnnotationElement;
+   }();
+   var PopupAnnotationElement = function PopupAnnotationElementClosure() {
+    function PopupAnnotationElement(parameters) {
+     var isRenderable = !!(parameters.data.title || parameters.data.contents);
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(PopupAnnotationElement, AnnotationElement, {
+     render: function PopupAnnotationElement_render() {
+      this.container.className = 'popupAnnotation';
+      var selector = '[data-annotation-id="' + this.data.parentId + '"]';
+      var parentElement = this.layer.querySelector(selector);
+      if (!parentElement) {
+       return this.container;
+      }
+      var popup = new PopupElement({
+       container: this.container,
+       trigger: parentElement,
+       color: this.data.color,
+       title: this.data.title,
+       contents: this.data.contents
+      });
+      var parentLeft = parseFloat(parentElement.style.left);
+      var parentWidth = parseFloat(parentElement.style.width);
+      CustomStyle.setProp('transformOrigin', this.container, -(parentLeft + parentWidth) + 'px -' + parentElement.style.top);
+      this.container.style.left = parentLeft + parentWidth + 'px';
+      this.container.appendChild(popup.render());
+      return this.container;
+     }
+    });
+    return PopupAnnotationElement;
+   }();
+   var PopupElement = function PopupElementClosure() {
+    var BACKGROUND_ENLIGHT = 0.7;
+    function PopupElement(parameters) {
+     this.container = parameters.container;
+     this.trigger = parameters.trigger;
+     this.color = parameters.color;
+     this.title = parameters.title;
+     this.contents = parameters.contents;
+     this.hideWrapper = parameters.hideWrapper || false;
+     this.pinned = false;
+    }
+    PopupElement.prototype = {
+     render: function PopupElement_render() {
+      var wrapper = document.createElement('div');
+      wrapper.className = 'popupWrapper';
+      this.hideElement = this.hideWrapper ? wrapper : this.container;
+      this.hideElement.setAttribute('hidden', true);
+      var popup = document.createElement('div');
+      popup.className = 'popup';
+      var color = this.color;
+      if (color) {
+       var r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0];
+       var g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1];
+       var b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2];
+       popup.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0);
+      }
+      var contents = this._formatContents(this.contents);
+      var title = document.createElement('h1');
+      title.textContent = this.title;
+      this.trigger.addEventListener('click', this._toggle.bind(this));
+      this.trigger.addEventListener('mouseover', this._show.bind(this, false));
+      this.trigger.addEventListener('mouseout', this._hide.bind(this, false));
+      popup.addEventListener('click', this._hide.bind(this, true));
+      popup.appendChild(title);
+      popup.appendChild(contents);
+      wrapper.appendChild(popup);
+      return wrapper;
+     },
+     _formatContents: function PopupElement_formatContents(contents) {
+      var p = document.createElement('p');
+      var lines = contents.split(/(?:\r\n?|\n)/);
+      for (var i = 0, ii = lines.length; i < ii; ++i) {
+       var line = lines[i];
+       p.appendChild(document.createTextNode(line));
+       if (i < ii - 1) {
+        p.appendChild(document.createElement('br'));
+       }
+      }
+      return p;
+     },
+     _toggle: function PopupElement_toggle() {
+      if (this.pinned) {
+       this._hide(true);
+      } else {
+       this._show(true);
+      }
+     },
+     _show: function PopupElement_show(pin) {
+      if (pin) {
+       this.pinned = true;
+      }
+      if (this.hideElement.hasAttribute('hidden')) {
+       this.hideElement.removeAttribute('hidden');
+       this.container.style.zIndex += 1;
+      }
+     },
+     _hide: function PopupElement_hide(unpin) {
+      if (unpin) {
+       this.pinned = false;
+      }
+      if (!this.hideElement.hasAttribute('hidden') && !this.pinned) {
+       this.hideElement.setAttribute('hidden', true);
+       this.container.style.zIndex -= 1;
+      }
+     }
+    };
+    return PopupElement;
+   }();
+   var HighlightAnnotationElement = function HighlightAnnotationElementClosure() {
+    function HighlightAnnotationElement(parameters) {
+     var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(HighlightAnnotationElement, AnnotationElement, {
+     render: function HighlightAnnotationElement_render() {
+      this.container.className = 'highlightAnnotation';
+      if (!this.data.hasPopup) {
+       this._createPopup(this.container, null, this.data);
+      }
+      return this.container;
+     }
+    });
+    return HighlightAnnotationElement;
+   }();
+   var UnderlineAnnotationElement = function UnderlineAnnotationElementClosure() {
+    function UnderlineAnnotationElement(parameters) {
+     var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(UnderlineAnnotationElement, AnnotationElement, {
+     render: function UnderlineAnnotationElement_render() {
+      this.container.className = 'underlineAnnotation';
+      if (!this.data.hasPopup) {
+       this._createPopup(this.container, null, this.data);
+      }
+      return this.container;
+     }
+    });
+    return UnderlineAnnotationElement;
+   }();
+   var SquigglyAnnotationElement = function SquigglyAnnotationElementClosure() {
+    function SquigglyAnnotationElement(parameters) {
+     var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(SquigglyAnnotationElement, AnnotationElement, {
+     render: function SquigglyAnnotationElement_render() {
+      this.container.className = 'squigglyAnnotation';
+      if (!this.data.hasPopup) {
+       this._createPopup(this.container, null, this.data);
+      }
+      return this.container;
+     }
+    });
+    return SquigglyAnnotationElement;
+   }();
+   var StrikeOutAnnotationElement = function StrikeOutAnnotationElementClosure() {
+    function StrikeOutAnnotationElement(parameters) {
+     var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
+     AnnotationElement.call(this, parameters, isRenderable);
+    }
+    Util.inherit(StrikeOutAnnotationElement, AnnotationElement, {
+     render: function StrikeOutAnnotationElement_render() {
+      this.container.className = 'strikeoutAnnotation';
+      if (!this.data.hasPopup) {
+       this._createPopup(this.container, null, this.data);
+      }
+      return this.container;
+     }
+    });
+    return StrikeOutAnnotationElement;
+   }();
+   var FileAttachmentAnnotationElement = function FileAttachmentAnnotationElementClosure() {
+    function FileAttachmentAnnotationElement(parameters) {
+     AnnotationElement.call(this, parameters, true);
+     this.filename = getFilenameFromUrl(parameters.data.file.filename);
+     this.content = parameters.data.file.content;
+    }
+    Util.inherit(FileAttachmentAnnotationElement, AnnotationElement, {
+     render: function FileAttachmentAnnotationElement_render() {
+      this.container.className = 'fileAttachmentAnnotation';
+      var trigger = document.createElement('div');
+      trigger.style.height = this.container.style.height;
+      trigger.style.width = this.container.style.width;
+      trigger.addEventListener('dblclick', this._download.bind(this));
+      if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
+       this._createPopup(this.container, trigger, this.data);
+      }
+      this.container.appendChild(trigger);
+      return this.container;
+     },
+     _download: function FileAttachmentAnnotationElement_download() {
+      if (!this.downloadManager) {
+       warn('Download cannot be started due to unavailable download manager');
+       return;
+      }
+      this.downloadManager.downloadData(this.content, this.filename, '');
+     }
+    });
+    return FileAttachmentAnnotationElement;
+   }();
+   var AnnotationLayer = function AnnotationLayerClosure() {
+    return {
+     render: function AnnotationLayer_render(parameters) {
+      var annotationElementFactory = new AnnotationElementFactory();
+      for (var i = 0, ii = parameters.annotations.length; i < ii; i++) {
+       var data = parameters.annotations[i];
+       if (!data) {
+        continue;
+       }
+       var properties = {
+        data: data,
+        layer: parameters.div,
+        page: parameters.page,
+        viewport: parameters.viewport,
+        linkService: parameters.linkService,
+        downloadManager: parameters.downloadManager,
+        imageResourcesPath: parameters.imageResourcesPath || getDefaultSetting('imageResourcesPath'),
+        renderInteractiveForms: parameters.renderInteractiveForms || false
+       };
+       var element = annotationElementFactory.create(properties);
+       if (element.isRenderable) {
+        parameters.div.appendChild(element.render());
+       }
+      }
+     },
+     update: function AnnotationLayer_update(parameters) {
+      for (var i = 0, ii = parameters.annotations.length; i < ii; i++) {
+       var data = parameters.annotations[i];
+       var element = parameters.div.querySelector('[data-annotation-id="' + data.id + '"]');
+       if (element) {
+        CustomStyle.setProp('transform', element, 'matrix(' + parameters.viewport.transform.join(',') + ')');
+       }
+      }
+      parameters.div.removeAttribute('hidden');
+     }
+    };
+   }();
+   exports.AnnotationLayer = AnnotationLayer;
+  }));
+  (function (root, factory) {
+   factory(root.pdfjsDisplayTextLayer = {}, root.pdfjsSharedUtil, root.pdfjsDisplayDOMUtils);
+  }(this, function (exports, sharedUtil, displayDOMUtils) {
+   var Util = sharedUtil.Util;
+   var createPromiseCapability = sharedUtil.createPromiseCapability;
+   var CustomStyle = displayDOMUtils.CustomStyle;
+   var getDefaultSetting = displayDOMUtils.getDefaultSetting;
+   var renderTextLayer = function renderTextLayerClosure() {
+    var MAX_TEXT_DIVS_TO_RENDER = 100000;
+    var NonWhitespaceRegexp = /\S/;
+    function isAllWhitespace(str) {
+     return !NonWhitespaceRegexp.test(str);
+    }
+    var styleBuf = [
+     'left: ',
+     0,
+     'px; top: ',
+     0,
+     'px; font-size: ',
+     0,
+     'px; font-family: ',
+     '',
+     ';'
+    ];
+    function appendText(task, geom, styles) {
+     var textDiv = document.createElement('div');
+     var textDivProperties = {
+      style: null,
+      angle: 0,
+      canvasWidth: 0,
+      isWhitespace: false,
+      originalTransform: null,
+      paddingBottom: 0,
+      paddingLeft: 0,
+      paddingRight: 0,
+      paddingTop: 0,
+      scale: 1
+     };
+     task._textDivs.push(textDiv);
+     if (isAllWhitespace(geom.str)) {
+      textDivProperties.isWhitespace = true;
+      task._textDivProperties.set(textDiv, textDivProperties);
+      return;
+     }
+     var tx = Util.transform(task._viewport.transform, geom.transform);
+     var angle = Math.atan2(tx[1], tx[0]);
+     var style = styles[geom.fontName];
+     if (style.vertical) {
+      angle += Math.PI / 2;
+     }
+     var fontHeight = Math.sqrt(tx[2] * tx[2] + tx[3] * tx[3]);
+     var fontAscent = fontHeight;
+     if (style.ascent) {
+      fontAscent = style.ascent * fontAscent;
+     } else if (style.descent) {
+      fontAscent = (1 + style.descent) * fontAscent;
+     }
+     var left;
+     var top;
+     if (angle === 0) {
+      left = tx[4];
+      top = tx[5] - fontAscent;
+     } else {
+      left = tx[4] + fontAscent * Math.sin(angle);
+      top = tx[5] - fontAscent * Math.cos(angle);
+     }
+     styleBuf[1] = left;
+     styleBuf[3] = top;
+     styleBuf[5] = fontHeight;
+     styleBuf[7] = style.fontFamily;
+     textDivProperties.style = styleBuf.join('');
+     textDiv.setAttribute('style', textDivProperties.style);
+     textDiv.textContent = geom.str;
+     if (getDefaultSetting('pdfBug')) {
+      textDiv.dataset.fontName = geom.fontName;
+     }
+     if (angle !== 0) {
+      textDivProperties.angle = angle * (180 / Math.PI);
+     }
+     if (geom.str.length > 1) {
+      if (style.vertical) {
+       textDivProperties.canvasWidth = geom.height * task._viewport.scale;
+      } else {
+       textDivProperties.canvasWidth = geom.width * task._viewport.scale;
+      }
+     }
+     task._textDivProperties.set(textDiv, textDivProperties);
+     if (task._enhanceTextSelection) {
+      var angleCos = 1, angleSin = 0;
+      if (angle !== 0) {
+       angleCos = Math.cos(angle);
+       angleSin = Math.sin(angle);
+      }
+      var divWidth = (style.vertical ? geom.height : geom.width) * task._viewport.scale;
+      var divHeight = fontHeight;
+      var m, b;
+      if (angle !== 0) {
+       m = [
+        angleCos,
+        angleSin,
+        -angleSin,
+        angleCos,
+        left,
+        top
+       ];
+       b = Util.getAxialAlignedBoundingBox([
         0,
         0,
-        0x2022,
-        0x2020,
-        0x2021,
-        0x2026,
-        0x2014,
-        0x2013,
-        0x192,
-        0x2044,
-        0x2039,
-        0x203A,
-        0x2212,
-        0x2030,
-        0x201E,
-        0x201C,
-        0x201D,
-        0x2018,
-        0x2019,
-        0x201A,
-        0x2122,
-        0xFB01,
-        0xFB02,
-        0x141,
-        0x152,
-        0x160,
-        0x178,
-        0x17D,
-        0x131,
-        0x142,
-        0x153,
-        0x161,
-        0x17E,
+        divWidth,
+        divHeight
+       ], m);
+      } else {
+       b = [
+        left,
+        top,
+        left + divWidth,
+        top + divHeight
+       ];
+      }
+      task._bounds.push({
+       left: b[0],
+       top: b[1],
+       right: b[2],
+       bottom: b[3],
+       div: textDiv,
+       size: [
+        divWidth,
+        divHeight
+       ],
+       m: m
+      });
+     }
+    }
+    function render(task) {
+     if (task._canceled) {
+      return;
+     }
+     var textLayerFrag = task._container;
+     var textDivs = task._textDivs;
+     var capability = task._capability;
+     var textDivsLength = textDivs.length;
+     if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {
+      task._renderingDone = true;
+      capability.resolve();
+      return;
+     }
+     var canvas = document.createElement('canvas');
+     canvas.mozOpaque = true;
+     var ctx = canvas.getContext('2d', { alpha: false });
+     var lastFontSize;
+     var lastFontFamily;
+     for (var i = 0; i < textDivsLength; i++) {
+      var textDiv = textDivs[i];
+      var textDivProperties = task._textDivProperties.get(textDiv);
+      if (textDivProperties.isWhitespace) {
+       continue;
+      }
+      var fontSize = textDiv.style.fontSize;
+      var fontFamily = textDiv.style.fontFamily;
+      if (fontSize !== lastFontSize || fontFamily !== lastFontFamily) {
+       ctx.font = fontSize + ' ' + fontFamily;
+       lastFontSize = fontSize;
+       lastFontFamily = fontFamily;
+      }
+      var width = ctx.measureText(textDiv.textContent).width;
+      textLayerFrag.appendChild(textDiv);
+      var transform = '';
+      if (textDivProperties.canvasWidth !== 0 && width > 0) {
+       textDivProperties.scale = textDivProperties.canvasWidth / width;
+       transform = 'scaleX(' + textDivProperties.scale + ')';
+      }
+      if (textDivProperties.angle !== 0) {
+       transform = 'rotate(' + textDivProperties.angle + 'deg) ' + transform;
+      }
+      if (transform !== '') {
+       textDivProperties.originalTransform = transform;
+       CustomStyle.setProp('transform', textDiv, transform);
+      }
+      task._textDivProperties.set(textDiv, textDivProperties);
+     }
+     task._renderingDone = true;
+     capability.resolve();
+    }
+    function expand(task) {
+     var bounds = task._bounds;
+     var viewport = task._viewport;
+     var expanded = expandBounds(viewport.width, viewport.height, bounds);
+     for (var i = 0; i < expanded.length; i++) {
+      var div = bounds[i].div;
+      var divProperties = task._textDivProperties.get(div);
+      if (divProperties.angle === 0) {
+       divProperties.paddingLeft = bounds[i].left - expanded[i].left;
+       divProperties.paddingTop = bounds[i].top - expanded[i].top;
+       divProperties.paddingRight = expanded[i].right - bounds[i].right;
+       divProperties.paddingBottom = expanded[i].bottom - bounds[i].bottom;
+       task._textDivProperties.set(div, divProperties);
+       continue;
+      }
+      var e = expanded[i], b = bounds[i];
+      var m = b.m, c = m[0], s = m[1];
+      var points = [
+       [
         0,
-        0x20AC
-      ];
-      function stringToPDFString(str) {
-        var i, n = str.length, strBuf = [];
-        if (str[0] === '\xFE' && str[1] === '\xFF') {
-          // UTF16BE BOM
-          for (i = 2; i < n; i += 2) {
-            strBuf.push(String.fromCharCode(str.charCodeAt(i) << 8 | str.charCodeAt(i + 1)));
-          }
-        } else {
-          for (i = 0; i < n; ++i) {
-            var code = PDFStringTranslateTable[str.charCodeAt(i)];
-            strBuf.push(code ? String.fromCharCode(code) : str.charAt(i));
-          }
-        }
-        return strBuf.join('');
-      }
-      function stringToUTF8String(str) {
-        return decodeURIComponent(escape(str));
-      }
-      function utf8StringToString(str) {
-        return unescape(encodeURIComponent(str));
-      }
-      function isEmptyObj(obj) {
-        for (var key in obj) {
-          return false;
-        }
-        return true;
-      }
-      function isBool(v) {
-        return typeof v === 'boolean';
-      }
-      function isInt(v) {
-        return typeof v === 'number' && (v | 0) === v;
-      }
-      function isNum(v) {
-        return typeof v === 'number';
-      }
-      function isString(v) {
-        return typeof v === 'string';
-      }
-      function isArray(v) {
-        return v instanceof Array;
-      }
-      function isArrayBuffer(v) {
-        return typeof v === 'object' && v !== null && v.byteLength !== undefined;
-      }
-      // Checks if ch is one of the following characters: SPACE, TAB, CR or LF.
-      function isSpace(ch) {
-        return ch === 0x20 || ch === 0x09 || ch === 0x0D || ch === 0x0A;
-      }
-      /**
-       * Promise Capability object.
-       *
-       * @typedef {Object} PromiseCapability
-       * @property {Promise} promise - A promise object.
-       * @property {function} resolve - Fulfills the promise.
-       * @property {function} reject - Rejects the promise.
-       */
-      /**
-       * Creates a promise capability object.
-       * @alias createPromiseCapability
-       *
-       * @return {PromiseCapability} A capability object contains:
-       * - a Promise, resolve and reject methods.
-       */
-      function createPromiseCapability() {
-        var capability = {};
-        capability.promise = new Promise(function (resolve, reject) {
-          capability.resolve = resolve;
-          capability.reject = reject;
-        });
-        return capability;
-      }
-      /**
-       * Polyfill for Promises:
-       * The following promise implementation tries to generally implement the
-       * Promise/A+ spec. Some notable differences from other promise libraries are:
-       * - There currently isn't a separate deferred and promise object.
-       * - Unhandled rejections eventually show an error if they aren't handled.
-       *
-       * Based off of the work in:
-       * https://bugzilla.mozilla.org/show_bug.cgi?id=810490
-       */
-      (function PromiseClosure() {
-        if (globalScope.Promise) {
-          // Promises existing in the DOM/Worker, checking presence of all/resolve
-          if (typeof globalScope.Promise.all !== 'function') {
-            globalScope.Promise.all = function (iterable) {
-              var count = 0, results = [], resolve, reject;
-              var promise = new globalScope.Promise(function (resolve_, reject_) {
-                resolve = resolve_;
-                reject = reject_;
-              });
-              iterable.forEach(function (p, i) {
-                count++;
-                p.then(function (result) {
-                  results[i] = result;
-                  count--;
-                  if (count === 0) {
-                    resolve(results);
-                  }
-                }, reject);
-              });
-              if (count === 0) {
-                resolve(results);
-              }
-              return promise;
-            };
-          }
-          if (typeof globalScope.Promise.resolve !== 'function') {
-            globalScope.Promise.resolve = function (value) {
-              return new globalScope.Promise(function (resolve) {
-                resolve(value);
-              });
-            };
-          }
-          if (typeof globalScope.Promise.reject !== 'function') {
-            globalScope.Promise.reject = function (reason) {
-              return new globalScope.Promise(function (resolve, reject) {
-                reject(reason);
-              });
-            };
-          }
-          if (typeof globalScope.Promise.prototype.catch !== 'function') {
-            globalScope.Promise.prototype.catch = function (onReject) {
-              return globalScope.Promise.prototype.then(undefined, onReject);
-            };
-          }
-          return;
-        }
-        throw new Error('DOM Promise is not present');
-      }());
-      var StatTimer = function StatTimerClosure() {
-        function rpad(str, pad, length) {
-          while (str.length < length) {
-            str += pad;
-          }
-          return str;
-        }
-        function StatTimer() {
-          this.started = Object.create(null);
-          this.times = [];
-          this.enabled = true;
-        }
-        StatTimer.prototype = {
-          time: function StatTimer_time(name) {
-            if (!this.enabled) {
-              return;
-            }
-            if (name in this.started) {
-              warn('Timer is already running for ' + name);
-            }
-            this.started[name] = Date.now();
-          },
-          timeEnd: function StatTimer_timeEnd(name) {
-            if (!this.enabled) {
-              return;
-            }
-            if (!(name in this.started)) {
-              warn('Timer has not been started for ' + name);
-            }
-            this.times.push({
-              'name': name,
-              'start': this.started[name],
-              'end': Date.now()
-            });
-            // Remove timer from started so it can be called again.
-            delete this.started[name];
-          },
-          toString: function StatTimer_toString() {
-            var i, ii;
-            var times = this.times;
-            var out = '';
-            // Find the longest name for padding purposes.
-            var longest = 0;
-            for (i = 0, ii = times.length; i < ii; ++i) {
-              var name = times[i]['name'];
-              if (name.length > longest) {
-                longest = name.length;
-              }
-            }
-            for (i = 0, ii = times.length; i < ii; ++i) {
-              var span = times[i];
-              var duration = span.end - span.start;
-              out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
-            }
-            return out;
-          }
-        };
-        return StatTimer;
-      }();
-      var createBlob = function createBlob(data, contentType) {
-        if (typeof Blob !== 'undefined') {
-          return new Blob([data], { type: contentType });
-        }
-        warn('The "Blob" constructor is not supported.');
-      };
-      var createObjectURL = function createObjectURLClosure() {
-        // Blob/createObjectURL is not available, falling back to data schema.
-        var digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
-        return function createObjectURL(data, contentType, forceDataSchema) {
-          if (!forceDataSchema && typeof URL !== 'undefined' && URL.createObjectURL) {
-            var blob = createBlob(data, contentType);
-            return URL.createObjectURL(blob);
-          }
-          var buffer = 'data:' + contentType + ';base64,';
-          for (var i = 0, ii = data.length; i < ii; i += 3) {
-            var b1 = data[i] & 0xFF;
-            var b2 = data[i + 1] & 0xFF;
-            var b3 = data[i + 2] & 0xFF;
-            var d1 = b1 >> 2, d2 = (b1 & 3) << 4 | b2 >> 4;
-            var d3 = i + 1 < ii ? (b2 & 0xF) << 2 | b3 >> 6 : 64;
-            var d4 = i + 2 < ii ? b3 & 0x3F : 64;
-            buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
-          }
-          return buffer;
-        };
-      }();
-      function MessageHandler(sourceName, targetName, comObj) {
-        this.sourceName = sourceName;
-        this.targetName = targetName;
-        this.comObj = comObj;
-        this.callbackIndex = 1;
-        this.postMessageTransfers = true;
-        var callbacksCapabilities = this.callbacksCapabilities = Object.create(null);
-        var ah = this.actionHandler = Object.create(null);
-        this._onComObjOnMessage = function messageHandlerComObjOnMessage(event) {
-          var data = event.data;
-          if (data.targetName !== this.sourceName) {
-            return;
-          }
-          if (data.isReply) {
-            var callbackId = data.callbackId;
-            if (data.callbackId in callbacksCapabilities) {
-              var callback = callbacksCapabilities[callbackId];
-              delete callbacksCapabilities[callbackId];
-              if ('error' in data) {
-                callback.reject(data.error);
-              } else {
-                callback.resolve(data.data);
-              }
-            } else {
-              error('Cannot resolve callback ' + callbackId);
-            }
-          } else if (data.action in ah) {
-            var action = ah[data.action];
-            if (data.callbackId) {
-              var sourceName = this.sourceName;
-              var targetName = data.sourceName;
-              Promise.resolve().then(function () {
-                return action[0].call(action[1], data.data);
-              }).then(function (result) {
-                comObj.postMessage({
-                  sourceName: sourceName,
-                  targetName: targetName,
-                  isReply: true,
-                  callbackId: data.callbackId,
-                  data: result
-                });
-              }, function (reason) {
-                if (reason instanceof Error) {
-                  // Serialize error to avoid "DataCloneError"
-                  reason = reason + '';
-                }
-                comObj.postMessage({
-                  sourceName: sourceName,
-                  targetName: targetName,
-                  isReply: true,
-                  callbackId: data.callbackId,
-                  error: reason
-                });
-              });
-            } else {
-              action[0].call(action[1], data.data);
-            }
-          } else {
-            error('Unknown action from worker: ' + data.action);
-          }
-        }.bind(this);
-        comObj.addEventListener('message', this._onComObjOnMessage);
-      }
-      MessageHandler.prototype = {
-        on: function messageHandlerOn(actionName, handler, scope) {
-          var ah = this.actionHandler;
-          if (ah[actionName]) {
-            error('There is already an actionName called "' + actionName + '"');
-          }
-          ah[actionName] = [
-            handler,
-            scope
-          ];
-        },
-        /**
-         * Sends a message to the comObj to invoke the action with the supplied data.
-         * @param {String} actionName Action to call.
-         * @param {JSON} data JSON data to send.
-         * @param {Array} [transfers] Optional list of transfers/ArrayBuffers
-         */
-        send: function messageHandlerSend(actionName, data, transfers) {
-          var message = {
-            sourceName: this.sourceName,
-            targetName: this.targetName,
-            action: actionName,
-            data: data
-          };
-          this.postMessage(message, transfers);
-        },
-        /**
-         * Sends a message to the comObj to invoke the action with the supplied data.
-         * Expects that other side will callback with the response.
-         * @param {String} actionName Action to call.
-         * @param {JSON} data JSON data to send.
-         * @param {Array} [transfers] Optional list of transfers/ArrayBuffers.
-         * @returns {Promise} Promise to be resolved with response data.
-         */
-        sendWithPromise: function messageHandlerSendWithPromise(actionName, data, transfers) {
-          var callbackId = this.callbackIndex++;
-          var message = {
-            sourceName: this.sourceName,
-            targetName: this.targetName,
-            action: actionName,
-            data: data,
-            callbackId: callbackId
-          };
-          var capability = createPromiseCapability();
-          this.callbacksCapabilities[callbackId] = capability;
-          try {
-            this.postMessage(message, transfers);
-          } catch (e) {
-            capability.reject(e);
-          }
-          return capability.promise;
-        },
-        /**
-         * Sends raw message to the comObj.
-         * @private
-         * @param message {Object} Raw message.
-         * @param transfers List of transfers/ArrayBuffers, or undefined.
-         */
-        postMessage: function (message, transfers) {
-          if (transfers && this.postMessageTransfers) {
-            this.comObj.postMessage(message, transfers);
-          } else {
-            this.comObj.postMessage(message);
-          }
-        },
-        destroy: function () {
-          this.comObj.removeEventListener('message', this._onComObjOnMessage);
-        }
-      };
-      function loadJpegStream(id, imageUrl, objs) {
-        var img = new Image();
-        img.onload = function loadJpegStream_onloadClosure() {
-          objs.resolve(id, img);
-        };
-        img.onerror = function loadJpegStream_onerrorClosure() {
-          objs.resolve(id, null);
-          warn('Error during JPEG image loading');
-        };
-        img.src = imageUrl;
-      }
-      exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX;
-      exports.IDENTITY_MATRIX = IDENTITY_MATRIX;
-      exports.OPS = OPS;
-      exports.VERBOSITY_LEVELS = VERBOSITY_LEVELS;
-      exports.UNSUPPORTED_FEATURES = UNSUPPORTED_FEATURES;
-      exports.AnnotationBorderStyleType = AnnotationBorderStyleType;
-      exports.AnnotationFieldFlag = AnnotationFieldFlag;
-      exports.AnnotationFlag = AnnotationFlag;
-      exports.AnnotationType = AnnotationType;
-      exports.FontType = FontType;
-      exports.ImageKind = ImageKind;
-      exports.InvalidPDFException = InvalidPDFException;
-      exports.MessageHandler = MessageHandler;
-      exports.MissingDataException = MissingDataException;
-      exports.MissingPDFException = MissingPDFException;
-      exports.NotImplementedException = NotImplementedException;
-      exports.PageViewport = PageViewport;
-      exports.PasswordException = PasswordException;
-      exports.PasswordResponses = PasswordResponses;
-      exports.StatTimer = StatTimer;
-      exports.StreamType = StreamType;
-      exports.TextRenderingMode = TextRenderingMode;
-      exports.UnexpectedResponseException = UnexpectedResponseException;
-      exports.UnknownErrorException = UnknownErrorException;
-      exports.Util = Util;
-      exports.XRefParseException = XRefParseException;
-      exports.arrayByteLength = arrayByteLength;
-      exports.arraysToBytes = arraysToBytes;
-      exports.assert = assert;
-      exports.bytesToString = bytesToString;
-      exports.createBlob = createBlob;
-      exports.createPromiseCapability = createPromiseCapability;
-      exports.createObjectURL = createObjectURL;
-      exports.deprecated = deprecated;
-      exports.error = error;
-      exports.getLookupTableFactory = getLookupTableFactory;
-      exports.getVerbosityLevel = getVerbosityLevel;
-      exports.globalScope = globalScope;
-      exports.info = info;
-      exports.isArray = isArray;
-      exports.isArrayBuffer = isArrayBuffer;
-      exports.isBool = isBool;
-      exports.isEmptyObj = isEmptyObj;
-      exports.isInt = isInt;
-      exports.isNum = isNum;
-      exports.isString = isString;
-      exports.isSpace = isSpace;
-      exports.isSameOrigin = isSameOrigin;
-      exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
-      exports.isLittleEndian = isLittleEndian;
-      exports.isEvalSupported = isEvalSupported;
-      exports.loadJpegStream = loadJpegStream;
-      exports.log2 = log2;
-      exports.readInt8 = readInt8;
-      exports.readUint16 = readUint16;
-      exports.readUint32 = readUint32;
-      exports.removeNullCharacters = removeNullCharacters;
-      exports.setVerbosityLevel = setVerbosityLevel;
-      exports.shadow = shadow;
-      exports.string32 = string32;
-      exports.stringToBytes = stringToBytes;
-      exports.stringToPDFString = stringToPDFString;
-      exports.stringToUTF8String = stringToUTF8String;
-      exports.utf8StringToString = utf8StringToString;
-      exports.warn = warn;
-    }));
-    (function (root, factory) {
-      factory(root.pdfjsDisplayDOMUtils = {}, root.pdfjsSharedUtil);
-    }(this, function (exports, sharedUtil) {
-      var removeNullCharacters = sharedUtil.removeNullCharacters;
-      var warn = sharedUtil.warn;
-      var deprecated = sharedUtil.deprecated;
-      var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;
-      /**
-       * Optimised CSS custom property getter/setter.
-       * @class
-       */
-      var CustomStyle = function CustomStyleClosure() {
-        // As noted on: http://www.zachstronaut.com/posts/2009/02/17/
-        //              animate-css-transforms-firefox-webkit.html
-        // in some versions of IE9 it is critical that ms appear in this list
-        // before Moz
-        var prefixes = [
-          'ms',
-          'Moz',
-          'Webkit',
-          'O'
-        ];
-        var _cache = Object.create(null);
-        function CustomStyle() {
-        }
-        CustomStyle.getProp = function get(propName, element) {
-          // check cache only when no element is given
-          if (arguments.length === 1 && typeof _cache[propName] === 'string') {
-            return _cache[propName];
-          }
-          element = element || document.documentElement;
-          var style = element.style, prefixed, uPropName;
-          // test standard property first
-          if (typeof style[propName] === 'string') {
-            return _cache[propName] = propName;
-          }
-          // capitalize
-          uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
-          // test vendor specific properties
-          for (var i = 0, l = prefixes.length; i < l; i++) {
-            prefixed = prefixes[i] + uPropName;
-            if (typeof style[prefixed] === 'string') {
-              return _cache[propName] = prefixed;
-            }
-          }
-          //if all fails then set to undefined
-          return _cache[propName] = 'undefined';
-        };
-        CustomStyle.setProp = function set(propName, element, str) {
-          var prop = this.getProp(propName);
-          if (prop !== 'undefined') {
-            element.style[prop] = str;
-          }
-        };
-        return CustomStyle;
-      }();
-      var hasCanvasTypedArrays;
-      hasCanvasTypedArrays = function () {
-        return true;
-      };
-      var LinkTarget = {
-        NONE: 0,
-        // Default value.
-        SELF: 1,
-        BLANK: 2,
-        PARENT: 3,
-        TOP: 4
-      };
-      var LinkTargetStringMap = [
-        '',
-        '_self',
-        '_blank',
-        '_parent',
-        '_top'
+        0
+       ],
+       [
+        0,
+        b.size[1]
+       ],
+       [
+        b.size[0],
+        0
+       ],
+       b.size
       ];
-      /**
-       * @typedef ExternalLinkParameters
-       * @typedef {Object} ExternalLinkParameters
-       * @property {string} url - An absolute URL.
-       * @property {LinkTarget} target - The link target.
-       * @property {string} rel - The link relationship.
-       */
-      /**
-       * Adds various attributes (href, title, target, rel) to hyperlinks.
-       * @param {HTMLLinkElement} link - The link element.
-       * @param {ExternalLinkParameters} params
-       */
-      function addLinkAttributes(link, params) {
-        var url = params && params.url;
-        link.href = link.title = url ? removeNullCharacters(url) : '';
-        if (url) {
-          var target = params.target;
-          if (typeof target === 'undefined') {
-            target = getDefaultSetting('externalLinkTarget');
-          }
-          link.target = LinkTargetStringMap[target];
-          var rel = params.rel;
-          if (typeof rel === 'undefined') {
-            rel = getDefaultSetting('externalLinkRel');
-          }
-          link.rel = rel;
-        }
-      }
-      // Gets the file name from a given URL.
-      function getFilenameFromUrl(url) {
-        var anchor = url.indexOf('#');
-        var query = url.indexOf('?');
-        var end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);
-        return url.substring(url.lastIndexOf('/', end) + 1, end);
-      }
-      function getDefaultSetting(id) {
-        // The list of the settings and their default is maintained for backward
-        // compatibility and shall not be extended or modified. See also global.js.
-        var globalSettings = sharedUtil.globalScope.PDFJS;
-        switch (id) {
-        case 'pdfBug':
-          return globalSettings ? globalSettings.pdfBug : false;
-        case 'disableAutoFetch':
-          return globalSettings ? globalSettings.disableAutoFetch : false;
-        case 'disableStream':
-          return globalSettings ? globalSettings.disableStream : false;
-        case 'disableRange':
-          return globalSettings ? globalSettings.disableRange : false;
-        case 'disableFontFace':
-          return globalSettings ? globalSettings.disableFontFace : false;
-        case 'disableCreateObjectURL':
-          return globalSettings ? globalSettings.disableCreateObjectURL : false;
-        case 'disableWebGL':
-          return globalSettings ? globalSettings.disableWebGL : true;
-        case 'cMapUrl':
-          return globalSettings ? globalSettings.cMapUrl : null;
-        case 'cMapPacked':
-          return globalSettings ? globalSettings.cMapPacked : false;
-        case 'postMessageTransfers':
-          return globalSettings ? globalSettings.postMessageTransfers : true;
-        case 'workerSrc':
-          return globalSettings ? globalSettings.workerSrc : null;
-        case 'disableWorker':
-          return globalSettings ? globalSettings.disableWorker : false;
-        case 'maxImageSize':
-          return globalSettings ? globalSettings.maxImageSize : -1;
-        case 'imageResourcesPath':
-          return globalSettings ? globalSettings.imageResourcesPath : '';
-        case 'isEvalSupported':
-          return globalSettings ? globalSettings.isEvalSupported : true;
-        case 'externalLinkTarget':
-          if (!globalSettings) {
-            return LinkTarget.NONE;
-          }
-          switch (globalSettings.externalLinkTarget) {
-          case LinkTarget.NONE:
-          case LinkTarget.SELF:
-          case LinkTarget.BLANK:
-          case LinkTarget.PARENT:
-          case LinkTarget.TOP:
-            return globalSettings.externalLinkTarget;
-          }
-          warn('PDFJS.externalLinkTarget is invalid: ' + globalSettings.externalLinkTarget);
-          // Reset the external link target, to suppress further warnings.
-          globalSettings.externalLinkTarget = LinkTarget.NONE;
-          return LinkTarget.NONE;
-        case 'externalLinkRel':
-          return globalSettings ? globalSettings.externalLinkRel : 'noreferrer';
-        case 'enableStats':
-          return !!(globalSettings && globalSettings.enableStats);
-        default:
-          throw new Error('Unknown default setting: ' + id);
-        }
-      }
-      function isExternalLinkTargetSet() {
-        var externalLinkTarget = getDefaultSetting('externalLinkTarget');
-        switch (externalLinkTarget) {
-        case LinkTarget.NONE:
-          return false;
-        case LinkTarget.SELF:
-        case LinkTarget.BLANK:
-        case LinkTarget.PARENT:
-        case LinkTarget.TOP:
-          return true;
-        }
-      }
-      function isValidUrl(url, allowRelative) {
-        deprecated('isValidUrl(), please use createValidAbsoluteUrl() instead.');
-        var baseUrl = allowRelative ? 'http://example.com' : null;
-        return createValidAbsoluteUrl(url, baseUrl) !== null;
-      }
-      exports.CustomStyle = CustomStyle;
-      exports.addLinkAttributes = addLinkAttributes;
-      exports.isExternalLinkTargetSet = isExternalLinkTargetSet;
-      exports.isValidUrl = isValidUrl;
-      exports.getFilenameFromUrl = getFilenameFromUrl;
-      exports.LinkTarget = LinkTarget;
-      exports.hasCanvasTypedArrays = hasCanvasTypedArrays;
-      exports.getDefaultSetting = getDefaultSetting;
-    }));
-    (function (root, factory) {
-      factory(root.pdfjsDisplayFontLoader = {}, root.pdfjsSharedUtil);
-    }(this, function (exports, sharedUtil) {
-      var assert = sharedUtil.assert;
-      var bytesToString = sharedUtil.bytesToString;
-      var string32 = sharedUtil.string32;
-      var shadow = sharedUtil.shadow;
-      var warn = sharedUtil.warn;
-      function FontLoader(docId) {
-        this.docId = docId;
-        this.styleElement = null;
-      }
-      FontLoader.prototype = {
-        insertRule: function fontLoaderInsertRule(rule) {
-          var styleElement = this.styleElement;
-          if (!styleElement) {
-            styleElement = this.styleElement = document.createElement('style');
-            styleElement.id = 'PDFJS_FONT_STYLE_TAG_' + this.docId;
-            document.documentElement.getElementsByTagName('head')[0].appendChild(styleElement);
-          }
-          var styleSheet = styleElement.sheet;
-          styleSheet.insertRule(rule, styleSheet.cssRules.length);
-        },
-        clear: function fontLoaderClear() {
-          var styleElement = this.styleElement;
-          if (styleElement) {
-            styleElement.parentNode.removeChild(styleElement);
-            styleElement = this.styleElement = null;
-          }
-        }
-      };
-      FontLoader.prototype.bind = function fontLoaderBind(fonts, callback) {
-        for (var i = 0, ii = fonts.length; i < ii; i++) {
-          var font = fonts[i];
-          if (font.attached) {
-            continue;
-          }
-          font.attached = true;
-          var rule = font.createFontFaceRule();
-          if (rule) {
-            this.insertRule(rule);
-          }
-        }
-        setTimeout(callback);
-      };
-      var IsEvalSupportedCached = {
-        get value() {
-          return shadow(this, 'value', sharedUtil.isEvalSupported());
-        }
-      };
-      var FontFaceObject = function FontFaceObjectClosure() {
-        function FontFaceObject(translatedData, options) {
-          this.compiledGlyphs = Object.create(null);
-          // importing translated data
-          for (var i in translatedData) {
-            this[i] = translatedData[i];
-          }
-          this.options = options;
-        }
-        FontFaceObject.prototype = {
-          createNativeFontFace: function FontFaceObject_createNativeFontFace() {
-            throw new Error('Not implemented: createNativeFontFace');
-          },
-          createFontFaceRule: function FontFaceObject_createFontFaceRule() {
-            if (!this.data) {
-              return null;
-            }
-            if (this.options.disableFontFace) {
-              this.disableFontFace = true;
-              return null;
-            }
-            var data = bytesToString(new Uint8Array(this.data));
-            var fontName = this.loadedName;
-            // Add the font-face rule to the document
-            var url = 'url(data:' + this.mimetype + ';base64,' + btoa(data) + ');';
-            var rule = '@font-face { font-family:"' + fontName + '";src:' + url + '}';
-            if (this.options.fontRegistry) {
-              this.options.fontRegistry.registerFont(this, url);
-            }
-            return rule;
-          },
-          getPathGenerator: function FontFaceObject_getPathGenerator(objs, character) {
-            if (!(character in this.compiledGlyphs)) {
-              var cmds = objs.get(this.loadedName + '_path_' + character);
-              var current, i, len;
-              // If we can, compile cmds into JS for MAXIMUM SPEED
-              if (this.options.isEvalSupported && IsEvalSupportedCached.value) {
-                var args, js = '';
-                for (i = 0, len = cmds.length; i < len; i++) {
-                  current = cmds[i];
-                  if (current.args !== undefined) {
-                    args = current.args.join(',');
-                  } else {
-                    args = '';
-                  }
-                  js += 'c.' + current.cmd + '(' + args + ');\n';
-                }
-                this.compiledGlyphs[character] = new Function('c', 'size', js);
-              } else {
-                // But fall back on using Function.prototype.apply() if we're
-                // blocked from using eval() for whatever reason (like CSP policies)
-                this.compiledGlyphs[character] = function (c, size) {
-                  for (i = 0, len = cmds.length; i < len; i++) {
-                    current = cmds[i];
-                    if (current.cmd === 'scale') {
-                      current.args = [
-                        size,
-                        -size
-                      ];
-                    }
-                    c[current.cmd].apply(c, current.args);
-                  }
-                };
-              }
-            }
-            return this.compiledGlyphs[character];
-          }
-        };
-        return FontFaceObject;
-      }();
-      exports.FontFaceObject = FontFaceObject;
-      exports.FontLoader = FontLoader;
-    }));
-    (function (root, factory) {
-      factory(root.pdfjsDisplayMetadata = {}, root.pdfjsSharedUtil);
-    }(this, function (exports, sharedUtil) {
-      var error = sharedUtil.error;
-      function fixMetadata(meta) {
-        return meta.replace(/>\\376\\377([^<]+)/g, function (all, codes) {
-          var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) {
-            return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
-          });
-          var chars = '';
-          for (var i = 0; i < bytes.length; i += 2) {
-            var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
-            chars += code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38 && false ? String.fromCharCode(code) : '&#x' + (0x10000 + code).toString(16).substring(1) + ';';
-          }
-          return '>' + chars;
-        });
-      }
-      function Metadata(meta) {
-        if (typeof meta === 'string') {
-          // Ghostscript produces invalid metadata
-          meta = fixMetadata(meta);
-          var parser = new DOMParser();
-          meta = parser.parseFromString(meta, 'application/xml');
-        } else if (!(meta instanceof Document)) {
-          error('Metadata: Invalid metadata object');
-        }
-        this.metaDocument = meta;
-        this.metadata = Object.create(null);
-        this.parse();
-      }
-      Metadata.prototype = {
-        parse: function Metadata_parse() {
-          var doc = this.metaDocument;
-          var rdf = doc.documentElement;
-          if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
-            // Wrapped in <xmpmeta>
-            rdf = rdf.firstChild;
-            while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') {
-              rdf = rdf.nextSibling;
-            }
-          }
-          var nodeName = rdf ? rdf.nodeName.toLowerCase() : null;
-          if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) {
-            return;
-          }
-          var children = rdf.childNodes, desc, entry, name, i, ii, length, iLength;
-          for (i = 0, length = children.length; i < length; i++) {
-            desc = children[i];
-            if (desc.nodeName.toLowerCase() !== 'rdf:description') {
-              continue;
-            }
-            for (ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) {
-              if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text') {
-                entry = desc.childNodes[ii];
-                name = entry.nodeName.toLowerCase();
-                this.metadata[name] = entry.textContent.trim();
-              }
-            }
-          }
-        },
-        get: function Metadata_get(name) {
-          return this.metadata[name] || null;
-        },
-        has: function Metadata_has(name) {
-          return typeof this.metadata[name] !== 'undefined';
-        }
-      };
-      exports.Metadata = Metadata;
-    }));
-    (function (root, factory) {
-      factory(root.pdfjsDisplaySVG = {}, root.pdfjsSharedUtil);
-    }(this, function (exports, sharedUtil) {
-    }));
-    (function (root, factory) {
-      factory(root.pdfjsDisplayAnnotationLayer = {}, root.pdfjsSharedUtil, root.pdfjsDisplayDOMUtils);
-    }(this, function (exports, sharedUtil, displayDOMUtils) {
-      var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType;
-      var AnnotationType = sharedUtil.AnnotationType;
-      var Util = sharedUtil.Util;
-      var addLinkAttributes = displayDOMUtils.addLinkAttributes;
-      var LinkTarget = displayDOMUtils.LinkTarget;
-      var getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl;
-      var warn = sharedUtil.warn;
-      var CustomStyle = displayDOMUtils.CustomStyle;
-      var getDefaultSetting = displayDOMUtils.getDefaultSetting;
-      /**
-       * @typedef {Object} AnnotationElementParameters
-       * @property {Object} data
-       * @property {HTMLDivElement} layer
-       * @property {PDFPage} page
-       * @property {PageViewport} viewport
-       * @property {IPDFLinkService} linkService
-       * @property {DownloadManager} downloadManager
-       * @property {string} imageResourcesPath
-       * @property {boolean} renderInteractiveForms
-       */
-      /**
-       * @class
-       * @alias AnnotationElementFactory
-       */
-      function AnnotationElementFactory() {
-      }
-      AnnotationElementFactory.prototype = /** @lends AnnotationElementFactory.prototype */
-      {
-        /**
-         * @param {AnnotationElementParameters} parameters
-         * @returns {AnnotationElement}
-         */
-        create: function AnnotationElementFactory_create(parameters) {
-          var subtype = parameters.data.annotationType;
-          switch (subtype) {
-          case AnnotationType.LINK:
-            return new LinkAnnotationElement(parameters);
-          case AnnotationType.TEXT:
-            return new TextAnnotationElement(parameters);
-          case AnnotationType.WIDGET:
-            var fieldType = parameters.data.fieldType;
-            switch (fieldType) {
-            case 'Tx':
-              return new TextWidgetAnnotationElement(parameters);
-            case 'Ch':
-              return new ChoiceWidgetAnnotationElement(parameters);
-            }
-            return new WidgetAnnotationElement(parameters);
-          case AnnotationType.POPUP:
-            return new PopupAnnotationElement(parameters);
-          case AnnotationType.HIGHLIGHT:
-            return new HighlightAnnotationElement(parameters);
-          case AnnotationType.UNDERLINE:
-            return new UnderlineAnnotationElement(parameters);
-          case AnnotationType.SQUIGGLY:
-            return new SquigglyAnnotationElement(parameters);
-          case AnnotationType.STRIKEOUT:
-            return new StrikeOutAnnotationElement(parameters);
-          case AnnotationType.FILEATTACHMENT:
-            return new FileAttachmentAnnotationElement(parameters);
-          default:
-            return new AnnotationElement(parameters);
-          }
-        }
-      };
-      /**
-       * @class
-       * @alias AnnotationElement
-       */
-      var AnnotationElement = function AnnotationElementClosure() {
-        function AnnotationElement(parameters, isRenderable) {
-          this.isRenderable = isRenderable || false;
-          this.data = parameters.data;
-          this.layer = parameters.layer;
-          this.page = parameters.page;
-          this.viewport = parameters.viewport;
-          this.linkService = parameters.linkService;
-          this.downloadManager = parameters.downloadManager;
-          this.imageResourcesPath = parameters.imageResourcesPath;
-          this.renderInteractiveForms = parameters.renderInteractiveForms;
-          if (isRenderable) {
-            this.container = this._createContainer();
-          }
-        }
-        AnnotationElement.prototype = /** @lends AnnotationElement.prototype */
-        {
-          /**
-           * Create an empty container for the annotation's HTML element.
-           *
-           * @private
-           * @memberof AnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          _createContainer: function AnnotationElement_createContainer() {
-            var data = this.data, page = this.page, viewport = this.viewport;
-            var container = document.createElement('section');
-            var width = data.rect[2] - data.rect[0];
-            var height = data.rect[3] - data.rect[1];
-            container.setAttribute('data-annotation-id', data.id);
-            // Do *not* modify `data.rect`, since that will corrupt the annotation
-            // position on subsequent calls to `_createContainer` (see issue 6804).
-            var rect = Util.normalizeRect([
-              data.rect[0],
-              page.view[3] - data.rect[1] + page.view[1],
-              data.rect[2],
-              page.view[3] - data.rect[3] + page.view[1]
-            ]);
-            CustomStyle.setProp('transform', container, 'matrix(' + viewport.transform.join(',') + ')');
-            CustomStyle.setProp('transformOrigin', container, -rect[0] + 'px ' + -rect[1] + 'px');
-            if (data.borderStyle.width > 0) {
-              container.style.borderWidth = data.borderStyle.width + 'px';
-              if (data.borderStyle.style !== AnnotationBorderStyleType.UNDERLINE) {
-                // Underline styles only have a bottom border, so we do not need
-                // to adjust for all borders. This yields a similar result as
-                // Adobe Acrobat/Reader.
-                width = width - 2 * data.borderStyle.width;
-                height = height - 2 * data.borderStyle.width;
-              }
-              var horizontalRadius = data.borderStyle.horizontalCornerRadius;
-              var verticalRadius = data.borderStyle.verticalCornerRadius;
-              if (horizontalRadius > 0 || verticalRadius > 0) {
-                var radius = horizontalRadius + 'px / ' + verticalRadius + 'px';
-                CustomStyle.setProp('borderRadius', container, radius);
-              }
-              switch (data.borderStyle.style) {
-              case AnnotationBorderStyleType.SOLID:
-                container.style.borderStyle = 'solid';
-                break;
-              case AnnotationBorderStyleType.DASHED:
-                container.style.borderStyle = 'dashed';
-                break;
-              case AnnotationBorderStyleType.BEVELED:
-                warn('Unimplemented border style: beveled');
-                break;
-              case AnnotationBorderStyleType.INSET:
-                warn('Unimplemented border style: inset');
-                break;
-              case AnnotationBorderStyleType.UNDERLINE:
-                container.style.borderBottomStyle = 'solid';
-                break;
-              default:
-                break;
-              }
-              if (data.color) {
-                container.style.borderColor = Util.makeCssRgb(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);
-              } else {
-                // Transparent (invisible) border, so do not draw it at all.
-                container.style.borderWidth = 0;
-              }
-            }
-            container.style.left = rect[0] + 'px';
-            container.style.top = rect[1] + 'px';
-            container.style.width = width + 'px';
-            container.style.height = height + 'px';
-            return container;
-          },
-          /**
-           * Create a popup for the annotation's HTML element. This is used for
-           * annotations that do not have a Popup entry in the dictionary, but
-           * are of a type that works with popups (such as Highlight annotations).
-           *
-           * @private
-           * @param {HTMLSectionElement} container
-           * @param {HTMLDivElement|HTMLImageElement|null} trigger
-           * @param {Object} data
-           * @memberof AnnotationElement
-           */
-          _createPopup: function AnnotationElement_createPopup(container, trigger, data) {
-            // If no trigger element is specified, create it.
-            if (!trigger) {
-              trigger = document.createElement('div');
-              trigger.style.height = container.style.height;
-              trigger.style.width = container.style.width;
-              container.appendChild(trigger);
-            }
-            var popupElement = new PopupElement({
-              container: container,
-              trigger: trigger,
-              color: data.color,
-              title: data.title,
-              contents: data.contents,
-              hideWrapper: true
-            });
-            var popup = popupElement.render();
-            // Position the popup next to the annotation's container.
-            popup.style.left = container.style.width;
-            container.appendChild(popup);
-          },
-          /**
-           * Render the annotation's HTML element in the empty container.
-           *
-           * @public
-           * @memberof AnnotationElement
-           */
-          render: function AnnotationElement_render() {
-            throw new Error('Abstract method AnnotationElement.render called');
-          }
-        };
-        return AnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias LinkAnnotationElement
-       */
-      var LinkAnnotationElement = function LinkAnnotationElementClosure() {
-        function LinkAnnotationElement(parameters) {
-          AnnotationElement.call(this, parameters, true);
-        }
-        Util.inherit(LinkAnnotationElement, AnnotationElement, {
-          /**
-           * Render the link annotation's HTML element in the empty container.
-           *
-           * @public
-           * @memberof LinkAnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          render: function LinkAnnotationElement_render() {
-            this.container.className = 'linkAnnotation';
-            var link = document.createElement('a');
-            addLinkAttributes(link, {
-              url: this.data.url,
-              target: this.data.newWindow ? LinkTarget.BLANK : undefined
-            });
-            if (!this.data.url) {
-              if (this.data.action) {
-                this._bindNamedAction(link, this.data.action);
-              } else {
-                this._bindLink(link, this.data.dest);
-              }
-            }
-            this.container.appendChild(link);
-            return this.container;
-          },
-          /**
-           * Bind internal links to the link element.
-           *
-           * @private
-           * @param {Object} link
-           * @param {Object} destination
-           * @memberof LinkAnnotationElement
-           */
-          _bindLink: function LinkAnnotationElement_bindLink(link, destination) {
-            var self = this;
-            link.href = this.linkService.getDestinationHash(destination);
-            link.onclick = function () {
-              if (destination) {
-                self.linkService.navigateTo(destination);
-              }
-              return false;
-            };
-            if (destination) {
-              link.className = 'internalLink';
-            }
-          },
-          /**
-           * Bind named actions to the link element.
-           *
-           * @private
-           * @param {Object} link
-           * @param {Object} action
-           * @memberof LinkAnnotationElement
-           */
-          _bindNamedAction: function LinkAnnotationElement_bindNamedAction(link, action) {
-            var self = this;
-            link.href = this.linkService.getAnchorUrl('');
-            link.onclick = function () {
-              self.linkService.executeNamedAction(action);
-              return false;
-            };
-            link.className = 'internalLink';
-          }
-        });
-        return LinkAnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias TextAnnotationElement
-       */
-      var TextAnnotationElement = function TextAnnotationElementClosure() {
-        function TextAnnotationElement(parameters) {
-          var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
-          AnnotationElement.call(this, parameters, isRenderable);
-        }
-        Util.inherit(TextAnnotationElement, AnnotationElement, {
-          /**
-           * Render the text annotation's HTML element in the empty container.
-           *
-           * @public
-           * @memberof TextAnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          render: function TextAnnotationElement_render() {
-            this.container.className = 'textAnnotation';
-            var image = document.createElement('img');
-            image.style.height = this.container.style.height;
-            image.style.width = this.container.style.width;
-            image.src = this.imageResourcesPath + 'annotation-' + this.data.name.toLowerCase() + '.svg';
-            image.alt = '[{{type}} Annotation]';
-            image.dataset.l10nId = 'text_annotation_type';
-            image.dataset.l10nArgs = JSON.stringify({ type: this.data.name });
-            if (!this.data.hasPopup) {
-              this._createPopup(this.container, image, this.data);
-            }
-            this.container.appendChild(image);
-            return this.container;
-          }
-        });
-        return TextAnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias WidgetAnnotationElement
-       */
-      var WidgetAnnotationElement = function WidgetAnnotationElementClosure() {
-        function WidgetAnnotationElement(parameters, isRenderable) {
-          AnnotationElement.call(this, parameters, isRenderable);
+      var ts = new Float64Array(64);
+      points.forEach(function (p, i) {
+       var t = Util.applyTransform(p, m);
+       ts[i + 0] = c && (e.left - t[0]) / c;
+       ts[i + 4] = s && (e.top - t[1]) / s;
+       ts[i + 8] = c && (e.right - t[0]) / c;
+       ts[i + 12] = s && (e.bottom - t[1]) / s;
+       ts[i + 16] = s && (e.left - t[0]) / -s;
+       ts[i + 20] = c && (e.top - t[1]) / c;
+       ts[i + 24] = s && (e.right - t[0]) / -s;
+       ts[i + 28] = c && (e.bottom - t[1]) / c;
+       ts[i + 32] = c && (e.left - t[0]) / -c;
+       ts[i + 36] = s && (e.top - t[1]) / -s;
+       ts[i + 40] = c && (e.right - t[0]) / -c;
+       ts[i + 44] = s && (e.bottom - t[1]) / -s;
+       ts[i + 48] = s && (e.left - t[0]) / s;
+       ts[i + 52] = c && (e.top - t[1]) / -c;
+       ts[i + 56] = s && (e.right - t[0]) / s;
+       ts[i + 60] = c && (e.bottom - t[1]) / -c;
+      });
+      var findPositiveMin = function (ts, offset, count) {
+       var result = 0;
+       for (var i = 0; i < count; i++) {
+        var t = ts[offset++];
+        if (t > 0) {
+         result = result ? Math.min(t, result) : t;
         }
-        Util.inherit(WidgetAnnotationElement, AnnotationElement, {
-          /**
-           * Render the widget annotation's HTML element in the empty container.
-           *
-           * @public
-           * @memberof WidgetAnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          render: function WidgetAnnotationElement_render() {
-            // Show only the container for unsupported field types.
-            return this.container;
-          }
-        });
-        return WidgetAnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias TextWidgetAnnotationElement
-       */
-      var TextWidgetAnnotationElement = function TextWidgetAnnotationElementClosure() {
-        var TEXT_ALIGNMENT = [
-          'left',
-          'center',
-          'right'
-        ];
-        function TextWidgetAnnotationElement(parameters) {
-          var isRenderable = parameters.renderInteractiveForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue;
-          WidgetAnnotationElement.call(this, parameters, isRenderable);
-        }
-        Util.inherit(TextWidgetAnnotationElement, WidgetAnnotationElement, {
-          /**
-           * Render the text widget annotation's HTML element in the empty container.
-           *
-           * @public
-           * @memberof TextWidgetAnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          render: function TextWidgetAnnotationElement_render() {
-            this.container.className = 'textWidgetAnnotation';
-            var element = null;
-            if (this.renderInteractiveForms) {
-              // NOTE: We cannot set the values using `element.value` below, since it
-              //       prevents the AnnotationLayer rasterizer in `test/driver.js`
-              //       from parsing the elements correctly for the reference tests.
-              if (this.data.multiLine) {
-                element = document.createElement('textarea');
-                element.textContent = this.data.fieldValue;
-              } else {
-                element = document.createElement('input');
-                element.type = 'text';
-                element.setAttribute('value', this.data.fieldValue);
-              }
-              element.disabled = this.data.readOnly;
-              if (this.data.maxLen !== null) {
-                element.maxLength = this.data.maxLen;
-              }
-              if (this.data.comb) {
-                var fieldWidth = this.data.rect[2] - this.data.rect[0];
-                var combWidth = fieldWidth / this.data.maxLen;
-                element.classList.add('comb');
-                element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)';
-              }
-            } else {
-              element = document.createElement('div');
-              element.textContent = this.data.fieldValue;
-              element.style.verticalAlign = 'middle';
-              element.style.display = 'table-cell';
-              var font = null;
-              if (this.data.fontRefName) {
-                font = this.page.commonObjs.getData(this.data.fontRefName);
-              }
-              this._setTextStyle(element, font);
-            }
-            if (this.data.textAlignment !== null) {
-              element.style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
-            }
-            this.container.appendChild(element);
-            return this.container;
-          },
-          /**
-           * Apply text styles to the text in the element.
-           *
-           * @private
-           * @param {HTMLDivElement} element
-           * @param {Object} font
-           * @memberof TextWidgetAnnotationElement
-           */
-          _setTextStyle: function TextWidgetAnnotationElement_setTextStyle(element, font) {
-            // TODO: This duplicates some of the logic in CanvasGraphics.setFont().
-            var style = element.style;
-            style.fontSize = this.data.fontSize + 'px';
-            style.direction = this.data.fontDirection < 0 ? 'rtl' : 'ltr';
-            if (!font) {
-              return;
-            }
-            style.fontWeight = font.black ? font.bold ? '900' : 'bold' : font.bold ? 'bold' : 'normal';
-            style.fontStyle = font.italic ? 'italic' : 'normal';
-            // Use a reasonable default font if the font doesn't specify a fallback.
-            var fontFamily = font.loadedName ? '"' + font.loadedName + '", ' : '';
-            var fallbackName = font.fallbackName || 'Helvetica, sans-serif';
-            style.fontFamily = fontFamily + fallbackName;
-          }
-        });
-        return TextWidgetAnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias ChoiceWidgetAnnotationElement
-       */
-      var ChoiceWidgetAnnotationElement = function ChoiceWidgetAnnotationElementClosure() {
-        function ChoiceWidgetAnnotationElement(parameters) {
-          WidgetAnnotationElement.call(this, parameters, parameters.renderInteractiveForms);
-        }
-        Util.inherit(ChoiceWidgetAnnotationElement, WidgetAnnotationElement, {
-          /**
-           * Render the choice widget annotation's HTML element in the empty
-           * container.
-           *
-           * @public
-           * @memberof ChoiceWidgetAnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          render: function ChoiceWidgetAnnotationElement_render() {
-            this.container.className = 'choiceWidgetAnnotation';
-            var selectElement = document.createElement('select');
-            selectElement.disabled = this.data.readOnly;
-            if (!this.data.combo) {
-              // List boxes have a size and (optionally) multiple selection.
-              selectElement.size = this.data.options.length;
-              if (this.data.multiSelect) {
-                selectElement.multiple = true;
-              }
-            }
-            // Insert the options into the choice field.
-            for (var i = 0, ii = this.data.options.length; i < ii; i++) {
-              var option = this.data.options[i];
-              var optionElement = document.createElement('option');
-              optionElement.textContent = option.displayValue;
-              optionElement.value = option.exportValue;
-              if (this.data.fieldValue.indexOf(option.displayValue) >= 0) {
-                optionElement.setAttribute('selected', true);
-              }
-              selectElement.appendChild(optionElement);
-            }
-            this.container.appendChild(selectElement);
-            return this.container;
-          }
-        });
-        return ChoiceWidgetAnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias PopupAnnotationElement
-       */
-      var PopupAnnotationElement = function PopupAnnotationElementClosure() {
-        function PopupAnnotationElement(parameters) {
-          var isRenderable = !!(parameters.data.title || parameters.data.contents);
-          AnnotationElement.call(this, parameters, isRenderable);
-        }
-        Util.inherit(PopupAnnotationElement, AnnotationElement, {
-          /**
-           * Render the popup annotation's HTML element in the empty container.
-           *
-           * @public
-           * @memberof PopupAnnotationElement
-           * @returns {HTMLSectionElement}
-           */
-          render: function PopupAnnotationElement_render() {
-            this.container.className = 'popupAnnotation';
-            var selector = '[data-annotation-id="' + this.data.parentId + '"]';
-            var parentElement = this.layer.querySelector(selector);
-            if (!parentElement) {
-              return this.container;
-            }
-            var popup = new PopupElement({
-              container: this.container,
-              trigger: parentElement,
-              color: this.data.color,
-              title: this.data.title,
-              contents: this.data.contents
-            });
-            // Position the popup next to the parent annotation's container.
-            // PDF viewers ignore a popup annotation's rectangle.
-            var parentLeft = parseFloat(parentElement.style.left);
-            var parentWidth = parseFloat(parentElement.style.width);
-            CustomStyle.setProp('transformOrigin', this.container, -(parentLeft + parentWidth) + 'px -' + parentElement.style.top);
-            this.container.style.left = parentLeft + parentWidth + 'px';
-            this.container.appendChild(popup.render());
-            return this.container;
-          }
-        });
-        return PopupAnnotationElement;
-      }();
-      /**
-       * @class
-       * @alias PopupElement
-       */
-      var PopupElement = function PopupElementClosure() {
-        var BACKGROUND_ENLIGHT = 0.7;
-        function PopupElement(parameters) {
-          this.container = parameters.container;
-          this.trigger = parameters.trigger;
-          this.color = parameters.color;
-          this.title = parameters.title;
-          this.contents = parameters.contents;
-          this.hideWrapper = parameters.hideWrapper || false;
-          this.pinned = false;
-        }
-        PopupElement.prototype = /** @lends PopupElement.prototype */
-        {