--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -12,9 +12,10 @@ DIRS += [
'webcompat',
]
# Only include the following system add-ons if building Aurora or Nightly
if 'a' in CONFIG['GRE_MILESTONE']:
DIRS += [
'flyweb',
'formautofill',
+ 'presentation',
]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/bootstrap.js
@@ -0,0 +1,84 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+const {classes: Cc, interfaces: Ci, utils: Cu, manager: Cm} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const PRESENTATION_DEVICE_PROMPT_PATH =
+ "chrome://presentation/content/PresentationDevicePrompt.jsm";
+
+function log(aMsg) {
+ // dump("@ Presentation: " + aMsg + "\n");
+}
+
+function install(aData, aReason) {
+}
+
+function uninstall(aData, aReason) {
+}
+
+function startup(aData, aReason) {
+ log("startup");
+ Presentation.init();
+}
+
+function shutdown(aData, aReason) {
+ log("shutdown");
+ Presentation.uninit();
+}
+
+// Register/unregister a constructor as a factory.
+function Factory() {}
+Factory.prototype = {
+ register: function(targetConstructor) {
+ let proto = targetConstructor.prototype;
+ this._classID = proto.classID;
+
+ let factory = XPCOMUtils._getFactory(targetConstructor);
+ this._factory = factory;
+
+ let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.registerFactory(proto.classID, proto.classDescription,
+ proto.contractID, factory);
+ },
+
+ unregister: function() {
+ let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.unregisterFactory(this._classID, this._factory);
+ this._factory = null;
+ this._classID = null;
+ },
+};
+
+var Presentation = {
+ // PUBLIC APIs
+ init: function() {
+ log("init");
+ // Register PresentationDevicePrompt into a XPCOM component.
+ Cu.import(PRESENTATION_DEVICE_PROMPT_PATH);
+ this._register();
+ },
+
+ uninit: function() {
+ log("uninit");
+ // Unregister PresentationDevicePrompt XPCOM component.
+ this._unregister();
+ Cu.unload(PRESENTATION_DEVICE_PROMPT_PATH);
+ },
+
+ // PRIVATE APIs
+ _register: function() {
+ log("_register");
+ this._devicePromptFactory = new Factory();
+ this._devicePromptFactory.register(PresentationDevicePrompt);
+ },
+
+ _unregister: function() {
+ log("_unregister");
+ this._devicePromptFactory.unregister();
+ delete this._devicePromptFactory;
+ },
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/content/PresentationDevicePrompt.jsm
@@ -0,0 +1,254 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+/*
+ * This is the implementation of nsIPresentationDevicePrompt XPCOM.
+ * It will be registered into a XPCOM component by Presentation.jsm.
+ *
+ * This component will prompt a device selection UI for users to choose which
+ * devices they want to connect, when PresentationRequest is started.
+ */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["PresentationDevicePrompt"];
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+// An string bundle for localization.
+XPCOMUtils.defineLazyGetter(this, "Strings", function() {
+ return Services.strings.createBundle("chrome://presentation/locale/presentation.properties");
+});
+// To generate a device selection prompt.
+XPCOMUtils.defineLazyModuleGetter(this, "PermissionUI",
+ "resource:///modules/PermissionUI.jsm");
+/*
+ * Utils
+ */
+function log(aMsg) {
+ // Prefix is useful to grep log.
+ // dump("@ PresentationDevicePrompt: " + aMsg + "\n");
+}
+
+function GetString(aName) {
+ return Strings.GetStringFromName(aName);
+}
+
+/*
+ * Device Selection UI
+ */
+const kNotificationId = "presentation-device-selection";
+const kNotificationPopupIcon = "chrome://presentation-shared/skin/link.svg";
+
+// There is no dependancy between kNotificationId and kNotificationAnchorId,
+// so it's NOT necessary to name them by same prefix
+// (e.g., presentation-device-selection-notification-icon).
+const kNotificationAnchorId = "presentation-device-notification-icon";
+const kNotificationAnchorIcon = "chrome://presentation-shared/skin/link.svg";
+
+// This will insert our own popupnotification content with the device list
+// into the displayed popupnotification element.
+// PopupNotifications.jsm will automatically generate a popupnotification
+// element whose id is <notification id> + "-notification" and show it,
+// so kPopupNotificationId must be kNotificationId + "-notification".
+// Read more detail in PopupNotifications._refreshPanel.
+const kPopupNotificationId = kNotificationId + "-notification";
+
+function PresentationPermissionPrompt(aRequest, aDevices) {
+ this.request = aRequest;
+ this._isResponded = false;
+ this._devices = aDevices;
+}
+
+PresentationPermissionPrompt.prototype = {
+ __proto__: PermissionUI.PermissionPromptForRequestPrototype,
+ // PUBLIC APIs
+ get browser() {
+ return this.request.chromeEventHandler;
+ },
+ get principal() {
+ return this.request.principal;
+ },
+ get popupOptions() {
+ return {
+ hideNotNow: true,
+ removeOnDismissal: true,
+ popupIconURL: kNotificationPopupIcon, // Icon shown on prompt content
+ eventCallback: (aTopic, aNewBrowser) => {
+ log("eventCallback: " + aTopic);
+ let handler = {
+ // dismissed: () => { // Won't be fired if removeOnDismissal is true.
+ // log("Dismissed by user. Cancel the request.");
+ // },
+ removed: () => {
+ log("Prompt is removed.");
+ if (!this._isResponded) {
+ log("Dismissed by user. Cancel the request.");
+ this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
+ }
+ },
+ showing: () => {
+ log("Prompt is showing.");
+ // We cannot insert the device list at "showing" phase because
+ // the popupnotification content whose id is kPopupNotificationId
+ // is not generated yet.
+ },
+ shown: () => {
+ log("Prompt is shown.");
+ // Insert device selection list into popupnotification element.
+ this._createPopupContent();
+ },
+ };
+
+ // Call the handler for Notification events.
+ handler[aTopic]();
+ },
+ };
+ },
+ get notificationID() {
+ return kNotificationId;
+ },
+ get anchorID() {
+ let chromeDoc = this.browser.ownerDocument;
+ let anchor = chromeDoc.getElementById(kNotificationAnchorId);
+ if (!anchor) {
+ let notificationPopupBox =
+ chromeDoc.getElementById("notification-popup-box");
+ // Icon shown on URL bar
+ let notificationIcon = chromeDoc.createElement("image");
+ notificationIcon.id = kNotificationAnchorId;
+ notificationIcon.setAttribute("src", kNotificationAnchorIcon);
+ notificationIcon.classList.add("notification-anchor-icon");
+ notificationIcon.setAttribute("role", "button");
+ notificationIcon.setAttribute("tooltiptext",
+ GetString("presentation.urlbar.tooltiptext"));
+ notificationIcon.style.filter = "url('chrome://browser/skin/filters.svg#fill')";
+ notificationIcon.style.fill = "currentcolor";
+ notificationIcon.style.opacity = "0.4";
+ notificationPopupBox.appendChild(notificationIcon);
+ }
+
+ return kNotificationAnchorId;
+ },
+ get message() {
+ return GetString("presentation.message", this._domainName);
+ },
+ get promptActions() {
+ return [{
+ label: GetString("presentation.deviceprompt.select.label"),
+ accessKey: GetString("presentation.deviceprompt.select.accessKey"),
+ callback: () => {
+ log("Select");
+ this._isResponded = true;
+ if (!this._listbox || !this._devices.length) {
+ log("No device can be selected!");
+ this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
+ return;
+ }
+ let device = this._devices[this._listbox.selectedIndex];
+ this.request.select(device);
+ log("device: " + device.name + "(" + device.id + ") is selected!");
+ },
+ }, {
+ label: GetString("presentation.deviceprompt.cancel.label"),
+ accessKey: GetString("presentation.deviceprompt.cancel.accessKey"),
+ callback: () => {
+ log("Cancel selection.");
+ this._isResponded = true;
+ this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
+ },
+ dismiss: true, // For hideNotNow.
+ }];
+ },
+ // PRIVATE APIs
+ get _domainName() {
+ if (this.principal.URI instanceof Ci.nsIFileURL) {
+ return this.principal.URI.path.split('/')[1];
+ }
+ return this.principal.URI.hostPort;
+ },
+ _createPopupContent: function() {
+ log("_createPopupContent");
+
+ if (!this._devices.length) {
+ log("No available devices can be listed!");
+ return;
+ }
+
+ let chromeDoc = this.browser.ownerDocument;
+
+ let popupnotification = chromeDoc.getElementById(kPopupNotificationId);
+ if (!popupnotification) {
+ log("No available popupnotification element to be inserted!");
+ return;
+ }
+
+ let popupnotificationcontent =
+ chromeDoc.createElement("popupnotificationcontent");
+
+ this._listbox = chromeDoc.createElement("richlistbox");
+ this._listbox.setAttribute("flex", "1");
+ this._devices.forEach((device) => {
+ let listitem = chromeDoc.createElement("richlistitem");
+ let label = chromeDoc.createElement("label");
+ label.setAttribute("value", device.name);
+ listitem.appendChild(label);
+ this._listbox.appendChild(listitem);
+ });
+
+ popupnotificationcontent.appendChild(this._listbox);
+ popupnotification.appendChild(popupnotificationcontent);
+ },
+};
+
+
+/*
+ * nsIPresentationDevicePrompt
+ */
+// For XPCOM registration
+const PRESENTATIONDEVICEPROMPT_CONTRACTID = "@mozilla.org/presentation-device/prompt;1";
+const PRESENTATIONDEVICEPROMPT_CID = Components.ID("{388bd149-c919-4a43-b646-d7ec57877689}");
+
+function PresentationDevicePrompt() {}
+
+PresentationDevicePrompt.prototype = {
+ // properties required for XPCOM registration:
+ classID: PRESENTATIONDEVICEPROMPT_CID,
+ classDescription: "Presentation API Device Prompt",
+ contractID: PRESENTATIONDEVICEPROMPT_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt]),
+
+ // This will be fired when window.PresentationRequest(URL).start() is called.
+ promptDeviceSelection: function(aRequest) {
+ log("promptDeviceSelection");
+
+ // Cancel request if no available device.
+ let devices = this._loadDevices();
+ if (!devices.length) {
+ log("No available device.");
+ aRequest.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
+ return;
+ }
+
+ // Show the prompt to users.
+ let promptUI = new PresentationPermissionPrompt(aRequest, devices);
+ promptUI.prompt();
+ },
+ _loadDevices: function() {
+ let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"]
+ .getService(Ci.nsIPresentationDeviceManager);
+ let devices = deviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray);
+ let list = [];
+ for (let i = 0; i < devices.length; i++) {
+ let device = devices.queryElementAt(i, Ci.nsIPresentationDevice);
+ list.push(device);
+ }
+
+ return list;
+ },
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/install.rdf.in
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!-- 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/. -->
+
+#filter substitution
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>presentation@mozilla.org</em:id>
+ <em:version>1.0.0</em:version>
+ <em:type>2</em:type>
+ <em:bootstrap>true</em:bootstrap>
+ <em:multiprocessCompatible>true</em:multiprocessCompatible>
+
+ <!-- Target Application this theme can install into,
+ with minimum and maximum supported versions. -->
+ <em:targetApplication>
+ <Description>
+ <!-- Firefox GUID -->
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
+ <em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+ <!-- Front End MetaData -->
+ <em:name>Presentation</em:name>
+ <em:description>Discover nearby devices in the browser</em:description>
+ </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/jar.mn
@@ -0,0 +1,5 @@
+[features/presentation@mozilla.org] chrome.jar:
+% content presentation %content/
+ content/ (content/*)
+% skin presentation-shared classic/1.0 %skin/shared/
+ skin/ (skin/*)
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/locale/en-US/presentation.properties
@@ -0,0 +1,6 @@
+presentation.message=Select one device to send the content.
+presentation.urlbar.tooltiptext=View the device-selection request
+presentation.deviceprompt.select.label=Send
+presentation.deviceprompt.select.accessKey=S
+presentation.deviceprompt.cancel.label=Cancel
+presentation.deviceprompt.cancel.accessKey=C
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/locale/jar.mn
@@ -0,0 +1,8 @@
+#filter substitution
+# 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/.
+
+[features/presentation@mozilla.org] @AB_CD@.jar:
+% locale presentation @AB_CD@ %locale/@AB_CD@/
+ locale/@AB_CD@/ (en-US/*)
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/locale/moz.build
@@ -0,0 +1,7 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+JAR_MANIFESTS += ['jar.mn']
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/moz.build
@@ -0,0 +1,14 @@
+DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
+DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
+
+DIRS += ['locale']
+
+FINAL_TARGET_FILES.features['presentation@mozilla.org'] += [
+ 'bootstrap.js'
+]
+
+FINAL_TARGET_PP_FILES.features['presentation@mozilla.org'] += [
+ 'install.rdf.in'
+]
+
+JAR_MANIFESTS += ['jar.mn']
new file mode 100644
--- /dev/null
+++ b/browser/extensions/presentation/skin/shared/link.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="gray" x="0px" y="0px" width="32px"
+ height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve">
+<g id="layer_2">
+</g>
+<g id="layer_1">
+ <g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M16.968,9.895c3.293,0,6.117,1.995,7.338,4.841l1.603-1.216
+ c-1.628-3.3-4.994-5.591-8.923-5.591c-3.942,0-7.319,2.305-8.94,5.624l1.594,1.166C10.865,11.883,13.682,9.895,16.968,9.895z
+ M17.135,13.964c1.948,0,3.566,1.397,3.917,3.244l1.779-1.35c-0.849-2.276-3.023-3.904-5.595-3.904
+ c-2.669,0-4.904,1.758-5.677,4.171l1.647,1.205C13.509,15.424,15.145,13.964,17.135,13.964z M8.756,16.025H1.833
+ c-0.737,0-1.729,0.598-1.729,1.335v11.271c0,0.738,0.596,1.335,1.334,1.335h7.318c0.738,0,1.336-0.597,1.336-1.335V17.36
+ C10.092,16.623,9.494,16.025,8.756,16.025z M8.113,27.472c0,0.299-0.243,0.541-0.541,0.541H2.599
+ c-0.298,0-0.541-0.242-0.541-0.541v-8.949c0-0.299,0.243-0.541,0.541-0.541h4.973c0.298,0,0.541,0.242,0.541,0.541V27.472z
+ M15.246,17.992c0,1.064,0.862,1.926,1.926,1.926c1.064,0,1.926-0.862,1.926-1.926c0-1.064-0.862-1.926-1.926-1.926
+ C16.108,16.066,15.246,16.929,15.246,17.992z M29.962,2.034H4.011c-1.102,0-1.996,0.894-1.996,1.996v10.008h4.042V5.937
+ c0-1.102,0.894-1.996,1.996-1.996h17.973c1.103,0,1.996,0.894,1.996,1.996v16.075c0,1.103-0.894,1.996-1.996,1.996H12.089v1.918
+ h17.873c1.102,0,1.996-0.894,1.996-1.996V4.03C31.958,2.927,31.064,2.034,29.962,2.034z"/>
+ </g>
+ </g>
+</g>
+</svg>
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -95,16 +95,17 @@ searchplugins:: $(list-json)
DEFINES += -DBOOKMARKS_INCLUDE_DIR=$(dir $(call MERGE_FILE,profile/bookmarks.inc))
libs-%:
$(NSINSTALL) -D $(DIST)/install
@$(MAKE) -C ../../toolkit/locales libs-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../extensions/pocket/locale AB_CD=$* XPI_NAME=locale-$*
+ @$(MAKE) -C ../extensions/presentation/locale AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) -C ../../devtools/client/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
@$(MAKE) -B searchplugins AB_CD=$* XPI_NAME=locale-$*
@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$*
repackage-win32-installer: WIN32_INSTALLER_OUT=$(ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
repackage-win32-installer: $(call ESCAPE_WILDCARD,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD)
--- a/testing/talos/talos/xtalos/xperf_whitelist.json
+++ b/testing/talos/talos/xtalos/xperf_whitelist.json
@@ -1,41 +1,42 @@
-{"{firefox}\\Crash Reports\\{time}": {"ignore": true},
- "C:\\$Mft": {"ignore": true},
- "C:\\$Extend\\$UsnJrnl:$J": {"ignore": true},
- "C:\\Windows\\Prefetch\\{prefetch}.pf": {"ignore": true},
+{"{firefox}\\Crash Reports\\{time}": {"ignore": true},
+ "C:\\$Mft": {"ignore": true},
+ "C:\\$Extend\\$UsnJrnl:$J": {"ignore": true},
+ "C:\\Windows\\Prefetch\\{prefetch}.pf": {"ignore": true},
"C:\\$Secure": {"ignore": true},
"C:\\$logfile": {"ignore": true},
"{firefox}\\omni.ja": {"mincount": 0, "maxcount": 46, "minbytes": 0, "maxbytes": 3014656},
"{firefox}\\browser\\omni.ja": {"mincount": 0, "maxcount": 28, "minbytes": 0, "maxbytes": 1835008},
"{firefox}\\browser\\features\\aushelper@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\e10srollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\flyweb@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\formautofill@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\loop@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\firefox@getpocket.com.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
+ "{firefox}\\browser\\features\\presentation@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\webcompat@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{talos}\\tests\\tp5n\\tp5n.manifest": {"mincount": 0, "maxcount": 8, "minbytes": 0, "maxbytes": 32786},
"{talos}\\talos\\tests\\tp5n\\tp5n.manifest": {"mincount": 0, "maxcount": 8, "minbytes": 0, "maxbytes": 32786},
"{talos}\\tests\\tp5n\\tp5n.manifest.develop": {"mincount": 0, "maxcount": 8, "minbytes": 0, "maxbytes": 32786},
"{talos}\\talos\\tests\\tp5n\\tp5n.manifest.develop": {"mincount": 0, "maxcount": 8, "minbytes": 0, "maxbytes": 32786},
"{profile}\\localstore.rdf": {"mincount": 2, "maxcount": 2, "minbytes": 8192, "maxbytes": 8192},
"{firefox}\\dependentlibs.list": {"mincount": 4, "maxcount": 4, "minbytes": 16384, "maxbytes": 16384},
- "{profile}\\content-prefs.sqlite": {"mincount": 6, "maxcount": 6, "minbytes": 65768, "maxbytes": 65768},
+ "{profile}\\content-prefs.sqlite": {"mincount": 6, "maxcount": 6, "minbytes": 65768, "maxbytes": 65768},
"{profile}\\extensions.ini": {"mincount": 2, "maxcount": 2, "minbytes": 8192, "maxbytes": 8192},
"{profile}\\extensions\\pageloader@mozilla.org\\chrome.manifest": {"mincount": 2, "maxcount": 2, "minbytes": 600, "maxbytes": 600},
"{profile}\\extensions\\talos-powers@mozilla.org\\chrome.manifest": {"mincount": 2, "maxcount": 2, "minbytes": 600, "maxbytes": 600},
"{profile}\\extensions\\talos-powers@mozilla.org\\chrome\\talos-powers-content.js": {"mincount": 2, "maxcount": 2, "minbytes": 2000, "maxbytes": 2000},
"{profile}\\mimetypes.rdf": {"mincount": 2, "maxcount": 2, "minbytes": 8192, "maxbytes": 8192},
"{firefox}\\profiles.ini": {"mincount": 2, "maxcount": 2, "minbytes": 8192, "maxbytes": 8192},
"c:\\program files\\nvidia corporation\\3d vision\\nvstereoapii.dll": {"mincount": 0, "maxcount": 4, "minbytes": 2, "maxbytes": 33792},
"c:\\programdata\\nvidia corporation\\drs\\nvdrssel.bin": {"mincount": 2, "maxcount": 2, "minbytes": 2, "maxbytes": 2},
"c:\\programdata\\nvidia corporation\\drs\\nvapptimestamps": {"mincount": 22, "maxcount": 22, "minbytes": 704, "maxbytes": 704},
"{firefox}\\browser\\components\\components.manifest": {"mincount": 2, "maxcount": 2, "minbytes": 68, "maxbytes": 68},
- "{profile}\\places.sqlite": {"mincount": 8, "maxcount": 8, "minbytes": 196808, "maxbytes": 196808},
+ "{profile}\\places.sqlite": {"mincount": 8, "maxcount": 8, "minbytes": 196808, "maxbytes": 196808},
"{profile}\\pluginreg.dat": {"mincount": 2, "maxcount": 2, "minbytes": 1892, "maxbytes": 1892},
"{firefox}\\defaults\\pref\\channel-prefs.js": {"mincount": 4, "maxcount": 4, "minbytes": 1432, "maxbytes": 1432},
"c:\\windows\\system32\\dwrite.dll": {"mincount": 4, "maxcount": 4, "minbytes": 16384, "maxbytes": 90112},
"c:\\users\\desktop.ini": {"mincount": 2, "maxcount": 2, "minbytes": 352, "maxbytes": 352},
"{desktop}\\desktop.ini": {"mincount": 6, "maxcount": 6, "minbytes": 1692, "maxbytes": 1692},
"c:\\windows\\fonts\\staticcache.dat": {"mincount": 2, "maxcount": 2, "minbytes": 120, "maxbytes": 120},
"c:\\windows\\system32\\spool\\drivers\\color\\srgb color space profile.icm": {"mincount": 2, "maxcount": 2, "minbytes": 8192, "maxbytes": 8192},
"{profile}\\search.json": {"mincount": 12, "maxcount": 12, "minbytes": 33350, "maxbytes": 33350},