Bug 1287827 - Part 1. Remove Loop code from Firefox. rs=dmose
authorMark Banner <standard8@mozilla.com>
Tue, 26 Jul 2016 20:32:59 +0100
changeset 349349 b0c4a9c609c8fa6b013e448e15b984ea8c61b122
parent 349348 890f2ada97ac7069caa65ea6d472722423868488
child 349350 9c726a68ebc224e4fed901f5f41dfbd74126abb7
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmose
bugs1287827
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1287827 - Part 1. Remove Loop code from Firefox. rs=dmose
browser/extensions/loop/.gitignore
browser/extensions/loop/README.txt
browser/extensions/loop/bootstrap.js
browser/extensions/loop/chrome/content/modules/DomainWhitelist.jsm
browser/extensions/loop/chrome/content/modules/LoopRooms.jsm
browser/extensions/loop/chrome/content/modules/LoopRoomsCache.jsm
browser/extensions/loop/chrome/content/modules/MozLoopAPI.jsm
browser/extensions/loop/chrome/content/modules/MozLoopPushHandler.jsm
browser/extensions/loop/chrome/content/modules/MozLoopService.jsm
browser/extensions/loop/chrome/content/modules/MozLoopWorker.js
browser/extensions/loop/chrome/content/modules/tabFrame.js
browser/extensions/loop/chrome/content/panels/conversation.html
browser/extensions/loop/chrome/content/panels/copy.html
browser/extensions/loop/chrome/content/panels/css/copy.css
browser/extensions/loop/chrome/content/panels/css/desktop.css
browser/extensions/loop/chrome/content/panels/css/panel.css
browser/extensions/loop/chrome/content/panels/css/slideshow.css
browser/extensions/loop/chrome/content/panels/js/conversation.js
browser/extensions/loop/chrome/content/panels/js/conversationAppStore.js
browser/extensions/loop/chrome/content/panels/js/copy.js
browser/extensions/loop/chrome/content/panels/js/desktopViews.js
browser/extensions/loop/chrome/content/panels/js/feedbackViews.js
browser/extensions/loop/chrome/content/panels/js/models.js
browser/extensions/loop/chrome/content/panels/js/otconfig.js
browser/extensions/loop/chrome/content/panels/js/panel.js
browser/extensions/loop/chrome/content/panels/js/roomStore.js
browser/extensions/loop/chrome/content/panels/js/roomViews.js
browser/extensions/loop/chrome/content/panels/js/slideshow.js
browser/extensions/loop/chrome/content/panels/panel.html
browser/extensions/loop/chrome/content/panels/slideshow.html
browser/extensions/loop/chrome/content/panels/test/.eslintrc
browser/extensions/loop/chrome/content/panels/test/conversationAppStore_test.js
browser/extensions/loop/chrome/content/panels/test/conversation_test.js
browser/extensions/loop/chrome/content/panels/test/copy_test.js
browser/extensions/loop/chrome/content/panels/test/desktopViews_test.js
browser/extensions/loop/chrome/content/panels/test/fake-components.js
browser/extensions/loop/chrome/content/panels/test/feedbackViews_test.js
browser/extensions/loop/chrome/content/panels/test/index.html
browser/extensions/loop/chrome/content/panels/test/l10n_test.js
browser/extensions/loop/chrome/content/panels/test/panel_test.js
browser/extensions/loop/chrome/content/panels/test/roomStore_test.js
browser/extensions/loop/chrome/content/panels/test/roomViews_test.js
browser/extensions/loop/chrome/content/panels/test/slideshow_test.js
browser/extensions/loop/chrome/content/panels/test/test_desktop_all.py
browser/extensions/loop/chrome/content/panels/vendor/l10n.js
browser/extensions/loop/chrome/content/panels/vendor/simpleSlideshow.css
browser/extensions/loop/chrome/content/panels/vendor/simpleSlideshow.js
browser/extensions/loop/chrome/content/preferences/prefs.js
browser/extensions/loop/chrome/content/shared/css/common.css
browser/extensions/loop/chrome/content/shared/css/conversation.css
browser/extensions/loop/chrome/content/shared/css/reset.css
browser/extensions/loop/chrome/content/shared/img/02.png
browser/extensions/loop/chrome/content/shared/img/02@2x.png
browser/extensions/loop/chrome/content/shared/img/animated-spinner.svg
browser/extensions/loop/chrome/content/shared/img/arrow-01.svg
browser/extensions/loop/chrome/content/shared/img/audio-call-avatar.svg
browser/extensions/loop/chrome/content/shared/img/audio-default-16x16@1.5x.png
browser/extensions/loop/chrome/content/shared/img/audio-default-16x16@2x.png
browser/extensions/loop/chrome/content/shared/img/audio-hover.svg
browser/extensions/loop/chrome/content/shared/img/audio-mute-hover.svg
browser/extensions/loop/chrome/content/shared/img/audio-mute.svg
browser/extensions/loop/chrome/content/shared/img/audio-muted-darkgrey.svg
browser/extensions/loop/chrome/content/shared/img/audio.svg
browser/extensions/loop/chrome/content/shared/img/avatars.svg
browser/extensions/loop/chrome/content/shared/img/beta-ribbon.svg
browser/extensions/loop/chrome/content/shared/img/cam_audio-no.svg
browser/extensions/loop/chrome/content/shared/img/cam_audio.svg
browser/extensions/loop/chrome/content/shared/img/cam_audio_h.svg
browser/extensions/loop/chrome/content/shared/img/chatbubble-arrow-left.svg
browser/extensions/loop/chrome/content/shared/img/chatbubble-arrow-right.svg
browser/extensions/loop/chrome/content/shared/img/check.svg
browser/extensions/loop/chrome/content/shared/img/close-02.svg
browser/extensions/loop/chrome/content/shared/img/cursor.svg
browser/extensions/loop/chrome/content/shared/img/ellipsis-v.svg
browser/extensions/loop/chrome/content/shared/img/empty_search.svg
browser/extensions/loop/chrome/content/shared/img/exit.svg
browser/extensions/loop/chrome/content/shared/img/facemute-14x14.png
browser/extensions/loop/chrome/content/shared/img/facemute-14x14@2x.png
browser/extensions/loop/chrome/content/shared/img/firefox-avatar.svg
browser/extensions/loop/chrome/content/shared/img/firefox-hello_logo.svg
browser/extensions/loop/chrome/content/shared/img/firefox-hello_tour-slide-01.svg
browser/extensions/loop/chrome/content/shared/img/firefox-hello_tour-slide-02.svg
browser/extensions/loop/chrome/content/shared/img/firefox-hello_tour-slide-03.svg
browser/extensions/loop/chrome/content/shared/img/firefox-hello_tour-slide-04.svg
browser/extensions/loop/chrome/content/shared/img/firefox-logo.png
browser/extensions/loop/chrome/content/shared/img/glyph-email-16x16.svg
browser/extensions/loop/chrome/content/shared/img/glyph-facebook-16x16.svg
browser/extensions/loop/chrome/content/shared/img/glyph-help-16x16.svg
browser/extensions/loop/chrome/content/shared/img/glyph-help-no-circle-16x16.svg
browser/extensions/loop/chrome/content/shared/img/glyph-help-no-circle-blue-16x16.svg
browser/extensions/loop/chrome/content/shared/img/glyph-link-16x16.svg
browser/extensions/loop/chrome/content/shared/img/glyph-user-16x16.svg
browser/extensions/loop/chrome/content/shared/img/hangup-inverse-14x14.png
browser/extensions/loop/chrome/content/shared/img/hangup-inverse-14x14@2x.png
browser/extensions/loop/chrome/content/shared/img/happy.png
browser/extensions/loop/chrome/content/shared/img/hello-web-share.svg
browser/extensions/loop/chrome/content/shared/img/hello_logo.svg
browser/extensions/loop/chrome/content/shared/img/helloicon.svg
browser/extensions/loop/chrome/content/shared/img/icon_32.png
browser/extensions/loop/chrome/content/shared/img/icon_64.png
browser/extensions/loop/chrome/content/shared/img/icons-10x10.svg
browser/extensions/loop/chrome/content/shared/img/icons-14x14.svg
browser/extensions/loop/chrome/content/shared/img/icons-16x16.svg
browser/extensions/loop/chrome/content/shared/img/join_notification.svg
browser/extensions/loop/chrome/content/shared/img/leave.svg
browser/extensions/loop/chrome/content/shared/img/leave_notification.svg
browser/extensions/loop/chrome/content/shared/img/media-group-left-hover.svg
browser/extensions/loop/chrome/content/shared/img/media-group-right-hover.svg
browser/extensions/loop/chrome/content/shared/img/media-group.svg
browser/extensions/loop/chrome/content/shared/img/movistar.png
browser/extensions/loop/chrome/content/shared/img/movistar@2x.png
browser/extensions/loop/chrome/content/shared/img/mute-inverse-14x14.png
browser/extensions/loop/chrome/content/shared/img/mute-inverse-14x14@2x.png
browser/extensions/loop/chrome/content/shared/img/pause-12x12.svg
browser/extensions/loop/chrome/content/shared/img/paused-hello.svg
browser/extensions/loop/chrome/content/shared/img/play-12x12.svg
browser/extensions/loop/chrome/content/shared/img/sad.png
browser/extensions/loop/chrome/content/shared/img/sad_hello_icon_64x64.svg
browser/extensions/loop/chrome/content/shared/img/settings-hover.svg
browser/extensions/loop/chrome/content/shared/img/settings.svg
browser/extensions/loop/chrome/content/shared/img/sharing-active.svg
browser/extensions/loop/chrome/content/shared/img/sharing-hover.svg
browser/extensions/loop/chrome/content/shared/img/sharing-pending.svg
browser/extensions/loop/chrome/content/shared/img/sharing.svg
browser/extensions/loop/chrome/content/shared/img/spinner.png
browser/extensions/loop/chrome/content/shared/img/spinner.svg
browser/extensions/loop/chrome/content/shared/img/spinner@2x.png
browser/extensions/loop/chrome/content/shared/img/stop-12x12.svg
browser/extensions/loop/chrome/content/shared/img/telefonica-logo.svg
browser/extensions/loop/chrome/content/shared/img/video-hover.svg
browser/extensions/loop/chrome/content/shared/img/video-mute-hover.svg
browser/extensions/loop/chrome/content/shared/img/video-mute.svg
browser/extensions/loop/chrome/content/shared/img/video-muted-darkgrey.svg
browser/extensions/loop/chrome/content/shared/img/video.svg
browser/extensions/loop/chrome/content/shared/img/vivo.png
browser/extensions/loop/chrome/content/shared/img/vivo@2x.png
browser/extensions/loop/chrome/content/shared/js/actions.js
browser/extensions/loop/chrome/content/shared/js/activeRoomStore.js
browser/extensions/loop/chrome/content/shared/js/crypto.js
browser/extensions/loop/chrome/content/shared/js/dispatcher.js
browser/extensions/loop/chrome/content/shared/js/linkifiedTextView.js
browser/extensions/loop/chrome/content/shared/js/loopapi-client.js
browser/extensions/loop/chrome/content/shared/js/mixins.js
browser/extensions/loop/chrome/content/shared/js/otSdkDriver.js
browser/extensions/loop/chrome/content/shared/js/remoteCursorStore.js
browser/extensions/loop/chrome/content/shared/js/store.js
browser/extensions/loop/chrome/content/shared/js/textChatStore.js
browser/extensions/loop/chrome/content/shared/js/textChatView.js
browser/extensions/loop/chrome/content/shared/js/urlRegExps.js
browser/extensions/loop/chrome/content/shared/js/utils.js
browser/extensions/loop/chrome/content/shared/js/validate.js
browser/extensions/loop/chrome/content/shared/js/views.js
browser/extensions/loop/chrome/content/shared/sounds/connected.ogg
browser/extensions/loop/chrome/content/shared/sounds/connecting.ogg
browser/extensions/loop/chrome/content/shared/sounds/failure.ogg
browser/extensions/loop/chrome/content/shared/sounds/message.ogg
browser/extensions/loop/chrome/content/shared/sounds/room-joined-in.ogg
browser/extensions/loop/chrome/content/shared/sounds/room-joined.ogg
browser/extensions/loop/chrome/content/shared/sounds/room-left.ogg
browser/extensions/loop/chrome/content/shared/sounds/terminated.ogg
browser/extensions/loop/chrome/content/shared/test/.eslintrc
browser/extensions/loop/chrome/content/shared/test/activeRoomStore_test.js
browser/extensions/loop/chrome/content/shared/test/crypto_test.js
browser/extensions/loop/chrome/content/shared/test/dispatcher_test.js
browser/extensions/loop/chrome/content/shared/test/frontend_tester.py
browser/extensions/loop/chrome/content/shared/test/index.html
browser/extensions/loop/chrome/content/shared/test/linkifiedTextView_test.js
browser/extensions/loop/chrome/content/shared/test/loop_mocha_utils.js
browser/extensions/loop/chrome/content/shared/test/loopapi-client_test.js
browser/extensions/loop/chrome/content/shared/test/mixins_test.js
browser/extensions/loop/chrome/content/shared/test/otSdkDriver_test.js
browser/extensions/loop/chrome/content/shared/test/remoteCursorStore_test.js
browser/extensions/loop/chrome/content/shared/test/sdk_mock.js
browser/extensions/loop/chrome/content/shared/test/store_test.js
browser/extensions/loop/chrome/content/shared/test/test_shared_all.py
browser/extensions/loop/chrome/content/shared/test/textChatStore_test.js
browser/extensions/loop/chrome/content/shared/test/textChatView_test.js
browser/extensions/loop/chrome/content/shared/test/utils_test.js
browser/extensions/loop/chrome/content/shared/test/validate_test.js
browser/extensions/loop/chrome/content/shared/test/vendor/chai-as-promised.js
browser/extensions/loop/chrome/content/shared/test/vendor/chai.js
browser/extensions/loop/chrome/content/shared/test/vendor/mocha.css
browser/extensions/loop/chrome/content/shared/test/vendor/mocha.js
browser/extensions/loop/chrome/content/shared/test/vendor/react-dom-server.js
browser/extensions/loop/chrome/content/shared/test/vendor/sinon.js
browser/extensions/loop/chrome/content/shared/test/views_test.js
browser/extensions/loop/chrome/content/shared/vendor/backbone.js
browser/extensions/loop/chrome/content/shared/vendor/classnames.js
browser/extensions/loop/chrome/content/shared/vendor/lodash.js
browser/extensions/loop/chrome/content/shared/vendor/react-dom-prod.js
browser/extensions/loop/chrome/content/shared/vendor/react-dom.js
browser/extensions/loop/chrome/content/shared/vendor/react-prod.js
browser/extensions/loop/chrome/content/shared/vendor/react.js
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/css/ot.css
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/access-denied-chrome.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/access-denied-copy-firefox.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/access-denied-firefox.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/access-predenied-chrome.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/access-prompt-chrome.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/audioonly-publisher.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/audioonly-subscriber.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/buttons.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/loader.gif
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/mic-off.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/mic-on.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/speaker-off.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/images/rtc/speaker-on.png
browser/extensions/loop/chrome/content/shared/vendor/sdk-content/js/dynamic_config.min.js
browser/extensions/loop/chrome/content/shared/vendor/sdk.js
browser/extensions/loop/chrome/locale/af/loop.properties
browser/extensions/loop/chrome/locale/ar/loop.properties
browser/extensions/loop/chrome/locale/as/loop.properties
browser/extensions/loop/chrome/locale/ast/loop.properties
browser/extensions/loop/chrome/locale/az/loop.properties
browser/extensions/loop/chrome/locale/be/loop.properties
browser/extensions/loop/chrome/locale/bg/loop.properties
browser/extensions/loop/chrome/locale/bn-BD/loop.properties
browser/extensions/loop/chrome/locale/bn-IN/loop.properties
browser/extensions/loop/chrome/locale/bs/loop.properties
browser/extensions/loop/chrome/locale/ca/loop.properties
browser/extensions/loop/chrome/locale/cs/loop.properties
browser/extensions/loop/chrome/locale/cy/loop.properties
browser/extensions/loop/chrome/locale/da/loop.properties
browser/extensions/loop/chrome/locale/de/loop.properties
browser/extensions/loop/chrome/locale/dsb/loop.properties
browser/extensions/loop/chrome/locale/el/loop.properties
browser/extensions/loop/chrome/locale/en-GB/loop.properties
browser/extensions/loop/chrome/locale/en-US/loop.properties
browser/extensions/loop/chrome/locale/eo/loop.properties
browser/extensions/loop/chrome/locale/es-AR/loop.properties
browser/extensions/loop/chrome/locale/es-CL/loop.properties
browser/extensions/loop/chrome/locale/es-ES/loop.properties
browser/extensions/loop/chrome/locale/es-MX/loop.properties
browser/extensions/loop/chrome/locale/et/loop.properties
browser/extensions/loop/chrome/locale/eu/loop.properties
browser/extensions/loop/chrome/locale/fa/loop.properties
browser/extensions/loop/chrome/locale/ff/loop.properties
browser/extensions/loop/chrome/locale/fi/loop.properties
browser/extensions/loop/chrome/locale/fr/loop.properties
browser/extensions/loop/chrome/locale/fy-NL/loop.properties
browser/extensions/loop/chrome/locale/fy/loop.properties
browser/extensions/loop/chrome/locale/ga/loop.properties
browser/extensions/loop/chrome/locale/gd/loop.properties
browser/extensions/loop/chrome/locale/gl/loop.properties
browser/extensions/loop/chrome/locale/gu-IN/loop.properties
browser/extensions/loop/chrome/locale/he/loop.properties
browser/extensions/loop/chrome/locale/hi-IN/loop.properties
browser/extensions/loop/chrome/locale/hr/loop.properties
browser/extensions/loop/chrome/locale/hsb/loop.properties
browser/extensions/loop/chrome/locale/ht/loop.properties
browser/extensions/loop/chrome/locale/hu/loop.properties
browser/extensions/loop/chrome/locale/hy-AM/loop.properties
browser/extensions/loop/chrome/locale/id/loop.properties
browser/extensions/loop/chrome/locale/it/loop.properties
browser/extensions/loop/chrome/locale/ja/loop.properties
browser/extensions/loop/chrome/locale/jar.mn
browser/extensions/loop/chrome/locale/kk/loop.properties
browser/extensions/loop/chrome/locale/km/loop.properties
browser/extensions/loop/chrome/locale/kn/loop.properties
browser/extensions/loop/chrome/locale/ko/loop.properties
browser/extensions/loop/chrome/locale/ku/loop.properties
browser/extensions/loop/chrome/locale/lij/loop.properties
browser/extensions/loop/chrome/locale/lt/loop.properties
browser/extensions/loop/chrome/locale/lv/loop.properties
browser/extensions/loop/chrome/locale/mk/loop.properties
browser/extensions/loop/chrome/locale/ml/loop.properties
browser/extensions/loop/chrome/locale/mn/loop.properties
browser/extensions/loop/chrome/locale/moz.build
browser/extensions/loop/chrome/locale/ms/loop.properties
browser/extensions/loop/chrome/locale/my/loop.properties
browser/extensions/loop/chrome/locale/nb-NO/loop.properties
browser/extensions/loop/chrome/locale/ne-NP/loop.properties
browser/extensions/loop/chrome/locale/nl/loop.properties
browser/extensions/loop/chrome/locale/nn-NO/loop.properties
browser/extensions/loop/chrome/locale/or/loop.properties
browser/extensions/loop/chrome/locale/pa-IN/loop.properties
browser/extensions/loop/chrome/locale/pa/loop.properties
browser/extensions/loop/chrome/locale/pl/loop.properties
browser/extensions/loop/chrome/locale/pt-BR/loop.properties
browser/extensions/loop/chrome/locale/pt-PT/loop.properties
browser/extensions/loop/chrome/locale/pt/loop.properties
browser/extensions/loop/chrome/locale/rm/loop.properties
browser/extensions/loop/chrome/locale/ro/loop.properties
browser/extensions/loop/chrome/locale/ru/loop.properties
browser/extensions/loop/chrome/locale/si/loop.properties
browser/extensions/loop/chrome/locale/sk/loop.properties
browser/extensions/loop/chrome/locale/sl/loop.properties
browser/extensions/loop/chrome/locale/son/loop.properties
browser/extensions/loop/chrome/locale/sq/loop.properties
browser/extensions/loop/chrome/locale/sr/loop.properties
browser/extensions/loop/chrome/locale/sv-SE/loop.properties
browser/extensions/loop/chrome/locale/ta/loop.properties
browser/extensions/loop/chrome/locale/te/loop.properties
browser/extensions/loop/chrome/locale/th/loop.properties
browser/extensions/loop/chrome/locale/tr/loop.properties
browser/extensions/loop/chrome/locale/uk/loop.properties
browser/extensions/loop/chrome/locale/ur/loop.properties
browser/extensions/loop/chrome/locale/vi/loop.properties
browser/extensions/loop/chrome/locale/xh/loop.properties
browser/extensions/loop/chrome/locale/zh-CN/loop.properties
browser/extensions/loop/chrome/locale/zh-TW/loop.properties
browser/extensions/loop/chrome/locale/zu/loop.properties
browser/extensions/loop/chrome/skin/linux/menuPanel.png
browser/extensions/loop/chrome/skin/linux/menuPanel@2x.png
browser/extensions/loop/chrome/skin/linux/platform.css
browser/extensions/loop/chrome/skin/linux/toolbar-inverted.png
browser/extensions/loop/chrome/skin/linux/toolbar-inverted@2x.png
browser/extensions/loop/chrome/skin/linux/toolbar.png
browser/extensions/loop/chrome/skin/linux/toolbar@2x.png
browser/extensions/loop/chrome/skin/osx/menuPanel-yosemite.png
browser/extensions/loop/chrome/skin/osx/menuPanel-yosemite@2x.png
browser/extensions/loop/chrome/skin/osx/menuPanel.png
browser/extensions/loop/chrome/skin/osx/menuPanel@2x.png
browser/extensions/loop/chrome/skin/osx/platform.css
browser/extensions/loop/chrome/skin/osx/toolbar-inverted.png
browser/extensions/loop/chrome/skin/osx/toolbar-inverted@2x.png
browser/extensions/loop/chrome/skin/osx/toolbar-yosemite.png
browser/extensions/loop/chrome/skin/osx/toolbar-yosemite@2x.png
browser/extensions/loop/chrome/skin/osx/toolbar.png
browser/extensions/loop/chrome/skin/osx/toolbar@2x.png
browser/extensions/loop/chrome/skin/shared/loop.css
browser/extensions/loop/chrome/skin/windows/menuPanel-aero.png
browser/extensions/loop/chrome/skin/windows/menuPanel-aero@2x.png
browser/extensions/loop/chrome/skin/windows/menuPanel.png
browser/extensions/loop/chrome/skin/windows/menuPanel@2x.png
browser/extensions/loop/chrome/skin/windows/platform.css
browser/extensions/loop/chrome/skin/windows/toolbar-XP.png
browser/extensions/loop/chrome/skin/windows/toolbar-XP@2x.png
browser/extensions/loop/chrome/skin/windows/toolbar-aero.png
browser/extensions/loop/chrome/skin/windows/toolbar-aero@2x.png
browser/extensions/loop/chrome/skin/windows/toolbar-inverted.png
browser/extensions/loop/chrome/skin/windows/toolbar-inverted@2x.png
browser/extensions/loop/chrome/skin/windows/toolbar-lunaSilver.png
browser/extensions/loop/chrome/skin/windows/toolbar-lunaSilver@2x.png
browser/extensions/loop/chrome/skin/windows/toolbar-win8.png
browser/extensions/loop/chrome/skin/windows/toolbar-win8@2x.png
browser/extensions/loop/chrome/skin/windows/toolbar.png
browser/extensions/loop/chrome/skin/windows/toolbar@2x.png
browser/extensions/loop/chrome/test/mochitest/.eslintrc
browser/extensions/loop/chrome/test/mochitest/browser.ini
browser/extensions/loop/chrome/test/mochitest/browser_LoopRooms_channel.js
browser/extensions/loop/chrome/test/mochitest/browser_copypanel.js
browser/extensions/loop/chrome/test/mochitest/browser_fxa_login.js
browser/extensions/loop/chrome/test/mochitest/browser_loop_fxa_server.js
browser/extensions/loop/chrome/test/mochitest/browser_menuitem.js
browser/extensions/loop/chrome/test/mochitest/browser_mozLoop_appVersionInfo.js
browser/extensions/loop/chrome/test/mochitest/browser_mozLoop_chat.js
browser/extensions/loop/chrome/test/mochitest/browser_mozLoop_context.js
browser/extensions/loop/chrome/test/mochitest/browser_mozLoop_infobar.js
browser/extensions/loop/chrome/test/mochitest/browser_mozLoop_sharingListeners.js
browser/extensions/loop/chrome/test/mochitest/browser_mozLoop_telemetry.js
browser/extensions/loop/chrome/test/mochitest/browser_panel_privateBrowsing.js
browser/extensions/loop/chrome/test/mochitest/browser_sharingTitleListeners.js
browser/extensions/loop/chrome/test/mochitest/browser_throttler.js
browser/extensions/loop/chrome/test/mochitest/browser_toolbarbutton.js
browser/extensions/loop/chrome/test/mochitest/head.js
browser/extensions/loop/chrome/test/mochitest/loop_fxa.sjs
browser/extensions/loop/chrome/test/mochitest/test_loopLinkClicker_channel.html
browser/extensions/loop/chrome/test/xpcshell/.eslintrc
browser/extensions/loop/chrome/test/xpcshell/head.js
browser/extensions/loop/chrome/test/xpcshell/test_loopapi_app_version.js
browser/extensions/loop/chrome/test/xpcshell/test_loopapi_doNotDisturb.js
browser/extensions/loop/chrome/test/xpcshell/test_loopapi_ftu_url.js
browser/extensions/loop/chrome/test/xpcshell/test_loopapi_internal.js
browser/extensions/loop/chrome/test/xpcshell/test_loopapi_prefs.js
browser/extensions/loop/chrome/test/xpcshell/test_looppush_initialize.js
browser/extensions/loop/chrome/test/xpcshell/test_looprooms.js
browser/extensions/loop/chrome/test/xpcshell/test_looprooms_encryption_in_fxa.js
browser/extensions/loop/chrome/test/xpcshell/test_looprooms_first_notification.js
browser/extensions/loop/chrome/test/xpcshell/test_looprooms_getall.js
browser/extensions/loop/chrome/test/xpcshell/test_looprooms_upgrade_to_encryption.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_dnd.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_encryptionkey.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_hawk_errors.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_hawk_request.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_initialize.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_locales.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_loop_prefs.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_registration.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_registration_retry.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_restart.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_token_invalid.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_token_save.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_token_send.js
browser/extensions/loop/chrome/test/xpcshell/test_loopservice_token_validation.js
browser/extensions/loop/chrome/test/xpcshell/xpcshell.ini
browser/extensions/loop/install.rdf.in
browser/extensions/loop/jar.mn
browser/extensions/loop/manifest.ini
browser/extensions/loop/moz.build
browser/extensions/loop/run-all-loop-tests.sh
browser/extensions/loop/test/functional/config.py
browser/extensions/loop/test/functional/hanging_threads.py
browser/extensions/loop/test/functional/loopTestDriver.py
browser/extensions/loop/test/functional/manifest.ini
browser/extensions/loop/test/functional/serversetup.py
browser/extensions/loop/test/functional/test_1_browser_call.py
browser/extensions/loop/test/functional/test_2_linkclicker.py
deleted file mode 100644
--- a/browser/extensions/loop/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.module-cache
-test/coverage/desktop
-test/coverage/shared_standalone
-test/node_modules
-test/visual-regression/diff
-test/visual-regression/new
-test/visual-regression/refs
deleted file mode 100644
--- a/browser/extensions/loop/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This is the loop project output, https://github.com/mozilla/loop
-
-Current extension version is: 0.1
deleted file mode 100644
--- a/browser/extensions/loop/bootstrap.js
+++ /dev/null
@@ -1,1495 +0,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/. */
-"use strict";
-
-/* exported startup, shutdown, install, uninstall */var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;};function _toConsumableArray(arr) {if (Array.isArray(arr)) {for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {arr2[i] = arr[i];}return arr2;} else {return Array.from(arr);}}var _Components = 
-
-Components;var Ci = _Components.interfaces;var Cu = _Components.utils;var Cc = _Components.classes;
-
-var kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-var kBrowserSharingNotificationId = "loop-sharing-notification";
-
-var CURSOR_MIN_DELTA = 3;
-var CURSOR_MIN_INTERVAL = 100;
-var CURSOR_CLICK_DELAY = 1000;
-// Due to bug 1051238 frame scripts are cached forever, so we can't update them
-// as a restartless add-on. The Math.random() is the work around for this.
-var FRAME_SCRIPT = "chrome://loop/content/modules/tabFrame.js?" + Math.random();
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", 
-"resource://gre/modules/PrivateBrowsingUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI", 
-"resource:///modules/CustomizableUI.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task", 
-"resource://gre/modules/Task.jsm");
-
-// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
-var PREF_LOG_LEVEL = "loop.debug.loglevel";
-
-XPCOMUtils.defineLazyGetter(this, "log", function () {
-  var ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
-  var consoleOptions = { 
-    maxLogLevelPref: PREF_LOG_LEVEL, 
-    prefix: "Loop" };
-
-  return new ConsoleAPI(consoleOptions);});
-
-
-/**
- * This window listener gets loaded into each browser.xul window and is used
- * to provide the required loop functions for the window.
- */
-var WindowListener = { 
-  // Records the add-on version once we know it.
-  addonVersion: "unknown", 
-
-  /**
-   * Sets up the chrome integration within browser windows for Loop.
-   *
-   * @param {Object} window The window to inject the integration into.
-   */
-  setupBrowserUI: function setupBrowserUI(window) {
-    var document = window.document;var 
-    gBrowser = window.gBrowser;var gURLBar = window.gURLBar;
-    var xhrClass = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"];
-    var FileReader = window.FileReader;
-    var menuItem = null;
-    var isSlideshowOpen = false;
-    var titleChangedListener = null;
-
-    // the "exported" symbols
-    var LoopUI = { 
-      /**
-       * @var {XULWidgetSingleWrapper} toolbarButton Getter for the Loop toolbarbutton
-       *                                             instance for this window. This should
-       *                                             not be used in the hidden window.
-       */
-      get toolbarButton() {
-        delete this.toolbarButton;
-        return this.toolbarButton = CustomizableUI.getWidget("loop-button").forWindow(window);}, 
-
-
-      /**
-       * @var {XULElement} panel Getter for the Loop panel element.
-       */
-      get panel() {
-        delete this.panel;
-        return this.panel = document.getElementById("loop-notification-panel");}, 
-
-
-      /**
-       * @var {XULElement|null} browser Getter for the Loop panel browser element.
-       *                                Will be NULL if the panel hasn't loaded yet.
-       */
-      get browser() {
-        var browser = document.querySelector("#loop-notification-panel > #loop-panel-iframe");
-        if (browser) {
-          delete this.browser;
-          this.browser = browser;}
-
-        return browser;}, 
-
-
-      get isSlideshowOpen() {
-        return isSlideshowOpen;}, 
-
-
-      set isSlideshowOpen(aOpen) {
-        isSlideshowOpen = aOpen;
-        this.updateToolbarState();}, 
-
-      /**
-       * @return {Object} Getter for the Loop constants
-       */
-      get constants() {var _this = this;
-        if (!this._constants) {
-          // GetAllConstants is synchronous even though it's using a callback.
-          this.LoopAPI.sendMessageToHandler({ 
-            name: "GetAllConstants" }, 
-          function (result) {
-            _this._constants = result;});}
-
-
-
-        return this._constants;}, 
-
-
-      get mm() {
-        return window.getGroupMessageManager("browsers");}, 
-
-
-      /**
-       * @return {Promise}
-       */
-      promiseDocumentVisible: function promiseDocumentVisible(aDocument) {
-        if (!aDocument.hidden) {
-          return Promise.resolve(aDocument);}
-
-
-        return new Promise(function (resolve) {
-          aDocument.addEventListener("visibilitychange", function onVisibilityChanged() {
-            aDocument.removeEventListener("visibilitychange", onVisibilityChanged);
-            resolve(aDocument);});});}, 
-
-
-
-
-      /**
-       * Toggle between opening or hiding the Loop panel.
-       *
-       * @param {DOMEvent} [event] Optional event that triggered the call to this
-       *                           function.
-       * @return {Promise}
-       */
-      togglePanel: function togglePanel(event) {var _this2 = this;
-        if (!this.panel) {var _ret = function () {
-            // We're on the hidden window! What fun!
-            var obs = function obs(win) {
-              Services.obs.removeObserver(obs, "browser-delayed-startup-finished");
-              win.LoopUI.togglePanel(event);};
-
-            Services.obs.addObserver(obs, "browser-delayed-startup-finished", false);
-            return { v: window.OpenBrowserWindow() };}();if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v;}
-
-        if (this.panel.state == "open") {
-          return new Promise(function (resolve) {
-            _this2.panel.hidePopup();
-            resolve();});}
-
-
-
-        if (this.isSlideshowOpen) {
-          return Promise.resolve();}
-
-
-        return this.openPanel(event).then(function (mm) {
-          if (mm) {
-            mm.sendAsyncMessage("Social:EnsureFocusElement");}}).
-
-        catch(function (err) {
-          Cu.reportError(err);});}, 
-
-
-
-      /**
-       * Called when a closing room has just been created, so we offer the
-       * user the chance to modify the name. For that we need to open the panel.
-       * Showing the proper layout is done on panel.jsx
-       */
-      renameRoom: function renameRoom() {
-        this.openPanel();}, 
-
-
-      /**
-       * Opens the panel for Loop and sizes it appropriately.
-       *
-       * @param {event}  event   The event opening the panel, used to anchor
-       *                         the panel to the button which triggers it.
-       * @return {Promise}
-       */
-      openPanel: function openPanel(event) {var _this3 = this;
-        if (PrivateBrowsingUtils.isWindowPrivate(window)) {
-          return Promise.reject();}
-
-
-        return new Promise(function (resolve) {
-          var callback = function callback(iframe) {
-            var mm = iframe.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
-            if (!("messageManager" in iframe)) {
-              iframe.messageManager = mm;}
-
-
-            if (!_this3._panelInitialized) {
-              _this3.hookWindowCloseForPanelClose(iframe);
-              _this3._panelInitialized = true;}
-
-
-            mm.sendAsyncMessage("Social:WaitForDocumentVisible");
-            mm.addMessageListener("Social:DocumentVisible", function onDocumentVisible() {
-              mm.removeMessageListener("Social:DocumentVisible", onDocumentVisible);
-              resolve(mm);});
-
-
-            var buckets = _this3.constants.LOOP_MAU_TYPE;
-            _this3.LoopAPI.sendMessageToHandler({ 
-              name: "TelemetryAddValue", 
-              data: ["LOOP_ACTIVITY_COUNTER", buckets.OPEN_PANEL] });};
-
-
-
-          // Used to clear the temporary "login" state from the button.
-          Services.obs.notifyObservers(null, "loop-status-changed", null);
-
-          _this3.shouldResumeTour().then(function (resume) {
-            if (resume) {
-              // Assume the conversation with the visitor wasn't open since we would
-              // have resumed the tour as soon as the visitor joined if it was (and
-              // the pref would have been set to false already.
-              _this3.MozLoopService.resumeTour("waiting");
-              resolve(null);
-              return;}
-
-
-            _this3.LoopAPI.initialize();
-
-            var anchor = event ? event.target : _this3.toolbarButton.anchor;
-            _this3.PanelFrame.showPopup(
-            window, 
-            anchor, 
-            "loop", // Notification Panel Type
-            null, // Origin
-            "about:looppanel", // Source
-            null, // Size
-            callback);});});}, 
-
-
-
-
-      /**
-       * Wrapper for openPanel - to support Firefox 46 and 45.
-       *
-       * @param {event}  event   The event opening the panel, used to anchor
-       *                         the panel to the button which triggers it.
-       * @return {Promise}
-       */
-      openCallPanel: function openCallPanel(event) {
-        return this.openPanel(event);}, 
-
-
-      /**
-       * Method to know whether actions to open the panel should instead resume the tour.
-       *
-       * We need the panel to be opened via UITour so that it gets @noautohide.
-       *
-       * @return {Promise} resolving with a {Boolean} of whether the tour should be resumed instead of
-       *                   opening the panel.
-       */
-      shouldResumeTour: Task.async(function* () {
-        // Resume the FTU tour if this is the first time a room was joined by
-        // someone else since the tour.
-        if (!Services.prefs.getBoolPref("loop.gettingStarted.resumeOnFirstJoin")) {
-          return false;}
-
-
-        if (!this.LoopRooms.participantsCount) {
-          // Nobody is in the rooms
-          return false;}
-
-
-        var roomsWithNonOwners = yield this.roomsWithNonOwners();
-        if (!roomsWithNonOwners.length) {
-          // We were the only one in a room but we want to know about someone else joining.
-          return false;}
-
-
-        return true;}), 
-
-
-      /**
-       * @return {Promise} resolved with an array of Rooms with participants (excluding owners)
-       */
-      roomsWithNonOwners: function roomsWithNonOwners() {var _this4 = this;
-        return new Promise(function (resolve) {
-          _this4.LoopRooms.getAll(function (error, rooms) {
-            var roomsWithNonOwners = [];var _iteratorNormalCompletion = true;var _didIteratorError = false;var _iteratorError = undefined;try {
-              for (var _iterator = rooms[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var room = _step.value;
-                if (!("participants" in room)) {
-                  continue;}
-
-                var numNonOwners = room.participants.filter(function (participant) {return !participant.owner;}).length;
-                if (!numNonOwners) {
-                  continue;}
-
-                roomsWithNonOwners.push(room);}} catch (err) {_didIteratorError = true;_iteratorError = err;} finally {try {if (!_iteratorNormalCompletion && _iterator.return) {_iterator.return();}} finally {if (_didIteratorError) {throw _iteratorError;}}}
-
-            resolve(roomsWithNonOwners);});});}, 
-
-
-
-
-      /**
-       * Triggers the initialization of the loop service if necessary.
-       * Also adds appropraite observers for the UI.
-       */
-      init: function init() {var _this5 = this;
-        // This is a promise for test purposes, but we don't want to be logging
-        // expected errors to the console, so we catch them here.
-        this.MozLoopService.initialize(WindowListener.addonVersion).catch(function (ex) {
-          if (!ex.message || 
-          !ex.message.contains("not enabled") && 
-          !ex.message.contains("not needed")) {
-            console.error(ex);}});
-
-
-
-        // If we're in private browsing mode, then don't add the menu item,
-        // also don't add the listeners as we don't want to update the button.
-        if (PrivateBrowsingUtils.isWindowPrivate(window)) {
-          return;}
-
-
-        this.addMenuItem();
-
-        // Don't do the rest if this is for the hidden window - we don't
-        // have a toolbar there.
-        if (window == Services.appShell.hiddenDOMWindow) {
-          return;}
-
-
-        // Load the frame script into any tab, plus any that get created in the
-        // future.
-        this.mm.loadFrameScript(FRAME_SCRIPT, true);
-
-        // Cleanup when the window unloads.
-        window.addEventListener("unload", function () {
-          Services.obs.removeObserver(_this5, "loop-status-changed");});
-
-
-        Services.obs.addObserver(this, "loop-status-changed", false);
-
-        this.maybeAddCopyPanel();
-        this.updateToolbarState();}, 
-
-
-      /**
-       * Adds a menu item to the browsers' Tools menu that open the Loop panel
-       * when selected.
-       */
-      addMenuItem: function addMenuItem() {var _this6 = this;
-        var menu = document.getElementById("menu_ToolsPopup");
-        if (!menu || menuItem) {
-          return;}
-
-
-        menuItem = document.createElementNS(kNSXUL, "menuitem");
-        menuItem.setAttribute("id", "menu_openLoop");
-        menuItem.setAttribute("label", this._getString("loopMenuItem_label"));
-        menuItem.setAttribute("accesskey", this._getString("loopMenuItem_accesskey"));
-
-        menuItem.addEventListener("command", function () {return _this6.togglePanel();});
-
-        menu.insertBefore(menuItem, document.getElementById("sync-setup"));}, 
-
-
-      /**
-       * Removes the menu item from the browsers' Tools menu.
-       */
-      removeMenuItem: function removeMenuItem() {
-        if (menuItem) {
-          menuItem.parentNode.removeChild(menuItem);}}, 
-
-
-
-      /**
-       * Maybe add the copy panel if it's not throttled and passes other checks.
-       * @return {Promise} Resolved when decided and maybe panel-added.
-       */
-      maybeAddCopyPanel: function maybeAddCopyPanel() {var _this7 = this;
-        // Don't bother adding the copy panel if we're in private browsing or
-        // the user wants to never see it again or we've shown it enough times.
-        if (PrivateBrowsingUtils.isWindowPrivate(window) || 
-        Services.prefs.getBoolPref("loop.copy.shown") || 
-        Services.prefs.getIntPref("loop.copy.showLimit") <= 0) {
-          return Promise.resolve();}
-
-
-        return Throttler.check("loop.copy").then(function () {return _this7.addCopyPanel();});}, 
-
-
-      /**
-       * Hook into the location bar copy command to open up the copy panel.
-       * @param {Function} onClickHandled Optional callback for finished clicks.
-       */
-      addCopyPanel: function addCopyPanel(onClickHandled) {var _this8 = this, _arguments = arguments;
-        // Make a copy of the loop panel as a starting point for the copy panel.
-        var copy = this.panel.cloneNode(false);
-        copy.id = "loop-copy-notification-panel";
-        this.panel.parentNode.appendChild(copy);
-
-        // Record a telemetry copy panel action.
-        var addTelemetry = function addTelemetry(bucket) {
-          _this8.LoopAPI.sendMessageToHandler({ 
-            data: ["LOOP_COPY_PANEL_ACTIONS", _this8.constants.COPY_PANEL[bucket]], 
-            name: "TelemetryAddValue" });};
-
-
-
-        // Handle events from the copy panel iframe content.
-        var onIframe = function onIframe(iframe) {
-          // Watch for events from the copy panel when loaded.
-          iframe.addEventListener("DOMContentLoaded", function onLoad() {
-            iframe.removeEventListener("DOMContentLoaded", onLoad);
-
-            // Size the panel to fit the rendered content adjusting for borders.
-            iframe.contentWindow.requestAnimationFrame(function () {
-              var height = iframe.contentDocument.documentElement.offsetHeight;
-              height += copy.boxObject.height - iframe.boxObject.height;
-              copy.style.height = height + "px";});
-
-
-            // Hide the copy panel then show the loop panel.
-            iframe.contentWindow.addEventListener("CopyPanelClick", function (event) {
-              iframe.parentNode.hidePopup();
-
-              // Show the Loop panel if the user wants it.
-              var _event$detail = event.detail;var accept = _event$detail.accept;var stop = _event$detail.stop;
-              if (accept) {
-                LoopUI.openPanel();}
-
-
-              // Stop showing the panel if the user says so.
-              if (stop) {
-                LoopUI.removeCopyPanel();
-                Services.prefs.setBoolPref("loop.copy.shown", true);}
-
-
-              // Generate the appropriate NO_AGAIN, NO_NEVER, YES_AGAIN,
-              // YES_NEVER probe based on the user's action.
-              var probe = (accept ? "YES" : "NO") + "_" + (stop ? "NEVER" : "AGAIN");
-              addTelemetry(probe);
-
-              // For testing, indicate that handling the click has finished.
-              try {
-                onClickHandled(event.detail);} 
-              catch (ex) {
-                // Do nothing.
-              }});});};
-
-
-
-
-        // Override the default behavior of the copy command.
-        var controller = gURLBar._copyCutController;
-        controller._doCommand = controller.doCommand;
-        controller.doCommand = function () {
-          // Do the normal behavior first.
-          controller._doCommand.apply(controller, _arguments);
-
-          // Remove the panel if the user has seen it enough times.
-          var showLimit = Services.prefs.getIntPref("loop.copy.showLimit");
-          if (showLimit <= 0) {
-            LoopUI.removeCopyPanel();
-            return;}
-
-
-          // Don't bother prompting the user if already sharing.
-          if (_this8.MozLoopService.screenShareActive) {
-            return;}
-
-
-          // Update various counters.
-          Services.prefs.setIntPref("loop.copy.showLimit", showLimit - 1);
-          addTelemetry("SHOWN");
-
-          // Open up the copy panel at the loop button.
-          LoopUI.PanelFrame.showPopup(window, LoopUI.toolbarButton.anchor, "loop-copy", 
-          null, "chrome://loop/content/panels/copy.html", null, onIframe);};}, 
-
-
-
-      /**
-       * Removes the copy panel copy hook and the panel.
-       */
-      removeCopyPanel: function removeCopyPanel() {
-        var controller = gURLBar && gURLBar._copyCutController;
-        if (controller && controller._doCommand) {
-          controller.doCommand = controller._doCommand;
-          delete controller._doCommand;}
-
-
-        var copy = document.getElementById("loop-copy-notification-panel");
-        if (copy) {
-          copy.parentNode.removeChild(copy);}}, 
-
-
-
-      // Implements nsIObserver
-      observe: function observe(subject, topic, data) {
-        if (topic != "loop-status-changed") {
-          return;}
-
-        this.updateToolbarState(data);}, 
-
-
-      /**
-       * Updates the toolbar/menu-button state to reflect Loop status. This should
-       * not be called from the hidden window.
-       *
-       * @param {string} [aReason] Some states are only shown if
-       *                           a related reason is provided.
-       *
-       *                 aReason="login": Used after a login is completed
-       *                   successfully. This is used so the state can be
-       *                   temporarily shown until the next state change.
-       */
-      updateToolbarState: function updateToolbarState() {var _this9 = this;var aReason = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
-        if (!this.toolbarButton.node) {
-          return;}
-
-        var state = "";
-        var mozL10nId = "loop-call-button3";
-        var suffix = ".tooltiptext";
-        if (this.MozLoopService.errors.size) {
-          state = "error";
-          mozL10nId += "-error";} else 
-        if (this.isSlideshowOpen) {
-          state = "slideshow";
-          suffix = ".label";} else 
-        if (this.MozLoopService.screenShareActive) {
-          state = "action";
-          mozL10nId += "-screensharing";} else 
-        if (aReason == "login" && this.MozLoopService.userProfile) {
-          state = "active";
-          mozL10nId += "-active";
-          suffix += "2";} else 
-        if (this.MozLoopService.doNotDisturb) {
-          state = "disabled";
-          mozL10nId += "-donotdisturb";} else 
-        if (this.MozLoopService.roomsParticipantsCount > 0) {
-          state = "active";
-          this.roomsWithNonOwners().then(function (roomsWithNonOwners) {
-            if (roomsWithNonOwners.length > 0) {
-              mozL10nId += "-participantswaiting";} else 
-            {
-              mozL10nId += "-active";}
-
-
-            suffix += "2";
-            _this9.updateTooltiptext(mozL10nId + suffix);
-            _this9.toolbarButton.node.setAttribute("state", state);});
-
-          return;} else 
-        {
-          suffix += "2";}
-
-
-        this.toolbarButton.node.setAttribute("state", state);
-        this.updateTooltiptext(mozL10nId + suffix);}, 
-
-
-      /**
-       * Updates the tootltiptext to reflect Loop status. This should not be called
-       * from the hidden window.
-       *
-       * @param {string} [mozL10nId] l10n ID that refelct the current
-       *                           Loop status.
-       */
-      updateTooltiptext: function updateTooltiptext(mozL10nId) {
-        this.toolbarButton.node.setAttribute("tooltiptext", mozL10nId);
-        var tooltiptext = CustomizableUI.getLocalizedProperty(this.toolbarButton, "tooltiptext");
-        this.toolbarButton.node.setAttribute("tooltiptext", tooltiptext);}, 
-
-
-      /**
-       * Show a desktop notification when 'do not disturb' isn't enabled.
-       *
-       * @param {Object} options Set of options that may tweak the appearance and
-       *                         behavior of the notification.
-       *                         Option params:
-       *                         - {String}   title       Notification title message
-       *                         - {String}   [message]   Notification body text
-       *                         - {String}   [icon]      Notification icon
-       *                         - {String}   [sound]     Sound to play
-       *                         - {String}   [selectTab] Tab to select when the panel
-       *                                                  opens
-       *                         - {Function} [onclick]   Callback to invoke when
-       *                                                  the notification is clicked.
-       *                                                  Opens the panel by default.
-       */
-      showNotification: function showNotification(options) {var _this10 = this;
-        if (this.MozLoopService.doNotDisturb) {
-          return;}
-
-
-        if (!options.title) {
-          throw new Error("Missing title, can not display notification");}
-
-
-        var notificationOptions = { 
-          body: options.message || "" };
-
-        if (options.icon) {
-          notificationOptions.icon = options.icon;}
-
-        if (options.sound) {
-          // This will not do anything, until bug bug 1105222 is resolved.
-          notificationOptions.mozbehavior = { 
-            soundFile: "" };
-
-          this.playSound(options.sound);}
-
-
-        var notification = new window.Notification(options.title, notificationOptions);
-        notification.addEventListener("click", function () {
-          if (window.closed) {
-            return;}
-
-
-          try {
-            window.focus();} 
-          catch (ex) {}
-          // Do nothing.
-
-
-          // We need a setTimeout here, otherwise the panel won't show after the
-          // window received focus.
-          window.setTimeout(function () {
-            if (typeof options.onclick == "function") {
-              options.onclick();} else 
-            {
-              // Open the Loop panel as a default action.
-              _this10.openPanel(null, options.selectTab || null);}}, 
-
-          0);});}, 
-
-
-
-      /**
-       * Play a sound in this window IF there's no sound playing yet.
-       *
-       * @param {String} name Name of the sound, like 'ringtone' or 'room-joined'
-       */
-      playSound: function playSound(name) {var _this11 = this;
-        if (this.ActiveSound || this.MozLoopService.doNotDisturb) {
-          return;}
-
-
-        this.activeSound = new window.Audio();
-        this.activeSound.src = "chrome://loop/content/shared/sounds/" + name + ".ogg";
-        this.activeSound.load();
-        this.activeSound.play();
-
-        this.activeSound.addEventListener("ended", function () {
-          _this11.activeSound = undefined;}, 
-        false);}, 
-
-
-      /**
-       * Start listening to selected tab changes and notify any content page that's
-       * listening to 'BrowserSwitch' push messages.  Also sets up a "joined"
-       * and "left" listener for LoopRooms so that we can toggle the infobar
-       * sharing messages when people come and go.
-       *
-       * @param {(String)} roomToken  The current room that the link generator is connecting to.
-       */
-      startBrowserSharing: function startBrowserSharing(roomToken) {var _this12 = this;
-        if (!this._listeningToTabSelect) {
-          gBrowser.tabContainer.addEventListener("TabSelect", this);
-          this._listeningToTabSelect = true;
-
-          titleChangedListener = this.handleDOMTitleChanged.bind(this);
-
-          this._roomsListener = this.handleRoomJoinedOrLeft.bind(this);
-
-          this.LoopRooms.on("joined", this._roomsListener);
-          this.LoopRooms.on("left", this._roomsListener);
-
-          // Watch for title changes as opposed to location changes as more
-          // metadata about the page is available when this event fires.
-          this.mm.addMessageListener("loop@mozilla.org:DOMTitleChanged", 
-          titleChangedListener);
-
-          this._browserSharePaused = false;
-
-          // Add this event to the parent gBrowser to avoid adding and removing
-          // it for each individual tab's browsers.
-          gBrowser.addEventListener("mousemove", this);
-          gBrowser.addEventListener("click", this);}
-
-
-        this._currentRoomToken = roomToken;
-        this._maybeShowBrowserSharingInfoBar(roomToken);
-
-        // Get the first window Id for the listener.
-        var browser = gBrowser.selectedBrowser;
-        return new Promise(function (resolve) {
-          if (browser.outerWindowID) {
-            resolve(browser.outerWindowID);
-            return;}
-
-
-          browser.messageManager.addMessageListener("Browser:Init", function initListener() {
-            browser.messageManager.removeMessageListener("Browser:Init", initListener);
-            resolve(browser.outerWindowID);});}).
-
-        then(function (outerWindowID) {return (
-            _this12.LoopAPI.broadcastPushMessage("BrowserSwitch", outerWindowID));});}, 
-
-
-      /**
-       * Stop listening to selected tab changes.
-       */
-      stopBrowserSharing: function stopBrowserSharing() {
-        if (!this._listeningToTabSelect) {
-          return;}
-
-
-        this._hideBrowserSharingInfoBar();
-        gBrowser.tabContainer.removeEventListener("TabSelect", this);
-        this.LoopRooms.off("joined", this._roomsListener);
-        this.LoopRooms.off("left", this._roomsListener);
-
-        if (titleChangedListener) {
-          this.mm.removeMessageListener("loop@mozilla.org:DOMTitleChanged", 
-          titleChangedListener);
-          titleChangedListener = null;}
-
-
-        // Remove shared pointers related events
-        gBrowser.removeEventListener("mousemove", this);
-        gBrowser.removeEventListener("click", this);
-        this.removeRemoteCursor();
-
-        this._listeningToTabSelect = false;
-        this._browserSharePaused = false;
-        this._currentRoomToken = null;}, 
-
-
-      /**
-       *  If sharing is active, paints and positions the remote cursor
-       *  over the screen
-       *
-       *  @param cursorData Object with the correct position for the cursor
-       *                    {
-       *                      ratioX: position on the X axis (percentage value)
-       *                      ratioY: position on the Y axis (percentage value)
-       *                    }
-       */
-      addRemoteCursor: function addRemoteCursor(cursorData) {
-        if (this._browserSharePaused || !this._listeningToTabSelect) {
-          return;}
-
-
-        var browser = gBrowser.selectedBrowser;
-        var cursor = document.getElementById("loop-remote-cursor");
-        if (!cursor) {
-          // Create a container to keep the pointer inside.
-          // This allows us to hide the overflow when out of bounds.
-          var cursorContainer = document.createElement("div");
-          cursorContainer.setAttribute("id", "loop-remote-cursor-container");
-
-          cursor = document.createElement("img");
-          cursor.setAttribute("id", "loop-remote-cursor");
-          cursorContainer.appendChild(cursor);
-          // Note that browser.parent is a xul:stack so container will use
-          // 100% of space if no other constrains added.
-          browser.parentNode.appendChild(cursorContainer);}
-
-
-        // Update the cursor's position with CSS.
-        cursor.style.left = 
-        Math.abs(cursorData.ratioX * browser.boxObject.width) + "px";
-        cursor.style.top = 
-        Math.abs(cursorData.ratioY * browser.boxObject.height) + "px";}, 
-
-
-      /**
-       *  Adds the ripple effect animation to the cursor to show a click on the
-       *  remote end of the conversation.
-       *  Will only add it when:
-       *  - A click is received (cursorData = true)
-       *  - Sharing is active (this._listeningToTabSelect = true)
-       *  - Remote cursor is being painted (cursor != undefined)
-       *
-       *  @param clickData bool click event
-       */
-      clickRemoteCursor: function clickRemoteCursor(clickData) {
-        if (!clickData || !this._listeningToTabSelect) {
-          return;}
-
-
-        var class_name = "clicked";
-        var cursor = document.getElementById("loop-remote-cursor");
-        if (!cursor) {
-          return;}
-
-
-        cursor.classList.add(class_name);
-
-        // after the proper time, we get rid of the animation
-        window.setTimeout(function () {
-          cursor.classList.remove(class_name);}, 
-        CURSOR_CLICK_DELAY);}, 
-
-
-      /**
-       *  Removes the remote cursor from the screen
-       */
-      removeRemoteCursor: function removeRemoteCursor() {
-        var cursor = document.getElementById("loop-remote-cursor");
-
-        if (cursor) {
-          cursor.parentNode.removeChild(cursor);}}, 
-
-
-
-      /**
-       * Helper function to fetch a localized string via the MozLoopService API.
-       * It's currently inconveniently wrapped inside a string of stringified JSON.
-       *
-       * @param  {String} key The element id to get strings for.
-       * @return {String}
-       */
-      _getString: function _getString(key) {
-        var str = this.MozLoopService.getStrings(key);
-        if (str) {
-          str = JSON.parse(str).textContent;}
-
-        return str;}, 
-
-
-      /**
-       * Set correct strings for infobar notification based on if paused or empty.
-       */
-
-      _setInfoBarStrings: function _setInfoBarStrings(nonOwnerParticipants, sharePaused) {
-        var message = void 0;
-        if (nonOwnerParticipants) {
-          // More than just the owner in the room.
-          message = this._getString(
-          sharePaused ? "infobar_screenshare_stop_sharing_message2" : 
-          "infobar_screenshare_browser_message3");} else 
-
-        {
-          // Just the owner in the room.
-          message = this._getString(
-          sharePaused ? "infobar_screenshare_stop_no_guest_message" : 
-          "infobar_screenshare_no_guest_message");}
-
-        var label = this._getString(
-        sharePaused ? "infobar_button_restart_label2" : "infobar_button_stop_label2");
-        var accessKey = this._getString(
-        sharePaused ? "infobar_button_restart_accesskey" : "infobar_button_stop_accesskey");
-
-        return { message: message, label: label, accesskey: accessKey };}, 
-
-
-      /**
-       * Indicates if tab sharing is paused.
-       * Set by tab pause button, startBrowserSharing and stopBrowserSharing.
-       * Defaults to false as link generator(owner) enters room we are sharing tabs.
-       */
-      _browserSharePaused: false, 
-
-      /**
-       * Stores details about the last notification.
-       *
-       * @type {Object}
-       */
-      _lastNotification: {}, 
-
-      /**
-       * Used to determine if the browser sharing info bar is currently being
-       * shown or not.
-       */
-      _showingBrowserSharingInfoBar: function _showingBrowserSharingInfoBar() {
-        var browser = gBrowser.selectedBrowser;
-        var box = gBrowser.getNotificationBox(browser);
-        var notification = box.getNotificationWithValue(kBrowserSharingNotificationId);
-
-        return !!notification;}, 
-
-
-      /**
-       * Shows an infobar notification at the top of the browser window that warns
-       * the user that their browser tabs are being broadcasted through the current
-       * conversation.
-       * @param  {String} currentRoomToken Room we are currently joined.
-       * @return {void}
-       */
-      _maybeShowBrowserSharingInfoBar: function _maybeShowBrowserSharingInfoBar(currentRoomToken) {var _this13 = this;
-        var participantsCount = this.LoopRooms.getNumParticipants(currentRoomToken);
-
-        if (this._showingBrowserSharingInfoBar()) {
-          // When we first open the room, there will be one or zero partipicants
-          // in the room. The notification box changes when there's more than one,
-          // so work that out here.
-          var notAlone = participantsCount > 1;
-          var previousNotAlone = this._lastNotification.participantsCount <= 1;
-
-          // If we're not actually changing the notification bar, then don't
-          // re-display it. This avoids the bar sliding in twice.
-          if (notAlone !== previousNotAlone && 
-          this._browserSharePaused === this._lastNotification.paused) {
-            return;}
-
-
-          this._hideBrowserSharingInfoBar();}
-
-
-        var initStrings = this._setInfoBarStrings(participantsCount > 1, this._browserSharePaused);
-
-        var box = gBrowser.getNotificationBox();
-        var bar = box.appendNotification(
-        initStrings.message, // label
-        kBrowserSharingNotificationId, // value
-        // Icon defined in browser theme CSS.
-        null, // image
-        box.PRIORITY_WARNING_LOW, // priority
-        [{ // buttons (Pause, Stop)
-          label: initStrings.label, 
-          accessKey: initStrings.accesskey, 
-          isDefault: false, 
-          callback: function callback(event, buttonInfo, buttonNode) {
-            _this13._browserSharePaused = !_this13._browserSharePaused;
-            var guestPresent = _this13.LoopRooms.getNumParticipants(_this13._currentRoomToken) > 1;
-            var stringObj = _this13._setInfoBarStrings(guestPresent, _this13._browserSharePaused);
-            bar.label = stringObj.message;
-            bar.classList.toggle("paused", _this13._browserSharePaused);
-            buttonNode.label = stringObj.label;
-            buttonNode.accessKey = stringObj.accesskey;
-            LoopUI.MozLoopService.toggleBrowserSharing(_this13._browserSharePaused);
-            if (_this13._browserSharePaused) {
-              // if paused we stop sharing remote cursors
-              _this13.removeRemoteCursor();}
-
-            return true;}, 
-
-          type: "pause" }, 
-
-        { 
-          label: this._getString("infobar_button_disconnect_label"), 
-          accessKey: this._getString("infobar_button_disconnect_accesskey"), 
-          isDefault: true, 
-          callback: function callback() {
-            _this13.removeRemoteCursor();
-            _this13._hideBrowserSharingInfoBar();
-            LoopUI.MozLoopService.hangupAllChatWindows();}, 
-
-          type: "stop" }]);
-
-
-
-        // Sets 'paused' class if needed.
-        bar.classList.toggle("paused", !!this._browserSharePaused);
-
-        // Keep showing the notification bar until the user explicitly closes it.
-        bar.persistence = -1;
-
-        this._lastNotification.participantsCount = participantsCount;
-        this._lastNotification.paused = this._browserSharePaused;}, 
-
-
-      /**
-       * Hides the infobar, permanantly if requested.
-       *
-       * @param   {Object}  browser Optional link to the browser we want to
-       *                    remove the infobar from. If not present, defaults
-       *                    to current browser instance.
-       * @return  {Boolean} |true| if the infobar was hidden here.
-       */
-      _hideBrowserSharingInfoBar: function _hideBrowserSharingInfoBar(browser) {
-        browser = browser || gBrowser.selectedBrowser;
-        var box = gBrowser.getNotificationBox(browser);
-        var notification = box.getNotificationWithValue(kBrowserSharingNotificationId);
-        var removed = false;
-        if (notification) {
-          box.removeNotification(notification);
-          removed = true;}
-
-
-        return removed;}, 
-
-
-      /**
-       * Broadcast 'BrowserSwitch' event.
-       */
-      _notifyBrowserSwitch: function _notifyBrowserSwitch() {
-        // Get the first window Id for the listener.
-        this.LoopAPI.broadcastPushMessage("BrowserSwitch", 
-        gBrowser.selectedBrowser.outerWindowID);}, 
-
-
-      /**
-       * Handles updating of the sharing infobar when the room participants
-       * change.
-       */
-      handleRoomJoinedOrLeft: function handleRoomJoinedOrLeft() {
-        // Don't attempt to show it if we're not actively sharing.
-        if (!this._listeningToTabSelect) {
-          return;}
-
-        this._maybeShowBrowserSharingInfoBar(this._currentRoomToken);}, 
-
-
-      /**
-       * Handles events from the frame script.
-       *
-       * @param {Object} message The message received from the frame script.
-       */
-      handleDOMTitleChanged: function handleDOMTitleChanged(message) {
-        if (!this._listeningToTabSelect || this._browserSharePaused) {
-          return;}
-
-
-        if (gBrowser.selectedBrowser == message.target) {
-          // Get the new title of the shared tab
-          this._notifyBrowserSwitch();}}, 
-
-
-
-      /**
-       * Handles events from gBrowser.
-       */
-      handleEvent: function handleEvent(event) {
-
-        switch (event.type) {
-          case "TabSelect":{
-              var wasVisible = false;
-              // Hide the infobar from the previous tab.
-              if (event.detail.previousTab) {
-                wasVisible = this._hideBrowserSharingInfoBar(
-                event.detail.previousTab.linkedBrowser);
-                // And remove the cursor.
-                this.removeRemoteCursor();}
-
-
-              // We've changed the tab, so get the new window id.
-              this._notifyBrowserSwitch();
-
-              if (wasVisible) {
-                // If the infobar was visible before, we should show it again after the
-                // switch.
-                this._maybeShowBrowserSharingInfoBar(this._currentRoomToken);}
-
-              break;}
-
-          case "mousemove":
-            this.handleMousemove(event);
-            break;
-          case "click":
-            this.handleMouseClick(event);
-            break;}}, 
-
-
-
-      /**
-       * Handles mousemove events from gBrowser and send a broadcast message
-       * with all the data needed for sending link generator cursor position
-       * through the sdk.
-       */
-      handleMousemove: function handleMousemove(event) {
-        // Won't send events if not sharing (paused or not started).
-        if (this._browserSharePaused || !this._listeningToTabSelect) {
-          return;}
-
-
-        // Only update every so often.
-        var now = Date.now();
-        if (now - this.lastCursorTime < CURSOR_MIN_INTERVAL) {
-          return;}
-
-        this.lastCursorTime = now;
-
-        // Skip the update if cursor is out of bounds or didn't move much.
-        var browserBox = gBrowser.selectedBrowser.boxObject;
-        var deltaX = event.screenX - browserBox.screenX;
-        var deltaY = event.screenY - browserBox.screenY;
-        if (deltaX < 0 || deltaX > browserBox.width || 
-        deltaY < 0 || deltaY > browserBox.height || 
-        Math.abs(deltaX - this.lastCursorX) < CURSOR_MIN_DELTA && 
-        Math.abs(deltaY - this.lastCursorY) < CURSOR_MIN_DELTA) {
-          return;}
-
-        this.lastCursorX = deltaX;
-        this.lastCursorY = deltaY;
-
-        this.LoopAPI.broadcastPushMessage("CursorPositionChange", { 
-          ratioX: deltaX / browserBox.width, 
-          ratioY: deltaY / browserBox.height });}, 
-
-
-
-      /**
-       * Handles mouse click events from gBrowser and send a broadcast message
-       * with all the data needed for sending link generator cursor click position
-       * through the sdk.
-       */
-      handleMouseClick: function handleMouseClick() {
-        // We want to stop sending events if sharing is paused.
-        if (this._browserSharePaused) {
-          return;}
-
-
-        this.LoopAPI.broadcastPushMessage("CursorClick");}, 
-
-
-      /**
-       * Fetch the favicon of the currently selected tab in the format of a data-uri.
-       *
-       * @param  {Function} callback Function to be invoked with an error object as
-       *                             its first argument when an error occurred or
-       *                             a string as second argument when the favicon
-       *                             has been fetched.
-       */
-      getFavicon: function getFavicon(callback) {
-        var pageURI = gBrowser.selectedTab.linkedBrowser.currentURI.spec;
-        // If the tab page’s url starts with http(s), fetch icon.
-        if (!/^https?:/.test(pageURI)) {
-          callback();
-          return;}
-
-
-        this.PlacesUtils.promiseFaviconLinkUrl(pageURI).then(function (uri) {
-          // We XHR the favicon to get a File object, which we can pass to the FileReader
-          // object. The FileReader turns the File object into a data-uri.
-          var xhr = xhrClass.createInstance(Ci.nsIXMLHttpRequest);
-          xhr.open("get", uri.spec, true);
-          xhr.responseType = "blob";
-          xhr.overrideMimeType("image/x-icon");
-          xhr.onload = function () {
-            if (xhr.status != 200) {
-              callback(new Error("Invalid status code received for favicon XHR: " + xhr.status));
-              return;}
-
-
-            var reader = new FileReader();
-            reader.onload = reader.onload = function () {return callback(null, reader.result);};
-            reader.onerror = callback;
-            reader.readAsDataURL(xhr.response);};
-
-          xhr.onerror = callback;
-          xhr.send();}).
-        catch(function (err) {
-          callback(err || new Error("No favicon found"));});} };
-
-
-
-
-    XPCOMUtils.defineLazyModuleGetter(LoopUI, "hookWindowCloseForPanelClose", "resource://gre/modules/MozSocialAPI.jsm");
-    XPCOMUtils.defineLazyModuleGetter(LoopUI, "LoopAPI", "chrome://loop/content/modules/MozLoopAPI.jsm");
-    XPCOMUtils.defineLazyModuleGetter(LoopUI, "LoopRooms", "chrome://loop/content/modules/LoopRooms.jsm");
-    XPCOMUtils.defineLazyModuleGetter(LoopUI, "MozLoopService", "chrome://loop/content/modules/MozLoopService.jsm");
-    XPCOMUtils.defineLazyModuleGetter(LoopUI, "PanelFrame", "resource:///modules/PanelFrame.jsm");
-    XPCOMUtils.defineLazyModuleGetter(LoopUI, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
-
-    LoopUI.init();
-    window.LoopUI = LoopUI;
-
-    // Export the Throttler to allow tests to overwrite parts of it.
-    window.LoopThrottler = Throttler;}, 
-
-
-  /**
-   * Take any steps to remove UI or anything from the browser window
-   * document.getElementById() etc. will work here.
-   *
-   * @param {Object} window The window to remove the integration from.
-   */
-  tearDownBrowserUI: function tearDownBrowserUI(window) {
-    if (window.LoopUI) {
-      window.LoopUI.removeCopyPanel();
-      window.LoopUI.removeMenuItem();
-
-      // This stops the frame script being loaded to new tabs, but doesn't
-      // remove it from existing tabs (there's no way to do that).
-      window.LoopUI.mm.removeDelayedFrameScript(FRAME_SCRIPT);
-
-      // XXX Bug 1229352 - Add in tear-down of the panel.
-    }}, 
-
-
-  // nsIWindowMediatorListener functions.
-  onOpenWindow: function onOpenWindow(xulWindow) {
-    // A new window has opened.
-    var domWindow = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor).
-    getInterface(Ci.nsIDOMWindow);
-
-    // Wait for it to finish loading.
-    domWindow.addEventListener("load", function listener() {
-      domWindow.removeEventListener("load", listener, false);
-
-      // If this is a browser window then setup its UI.
-      if (domWindow.document.documentElement.getAttribute("windowtype") == "navigator:browser") {
-        WindowListener.setupBrowserUI(domWindow);}}, 
-
-    false);}, 
-
-
-  onCloseWindow: function onCloseWindow() {}, 
-
-
-  onWindowTitleChange: function onWindowTitleChange() {} };
-
-
-
-/**
- * Provide a way to throttle functionality using DNS to distribute 3 numbers for
- * various distributions channels. DNS is used to scale distribution of the
- * numbers as an A record pointing to a loopback address (127.*.*.*). Prefs are
- * used to control behavior (what domain to check) and keep state (a ticket
- * number to track if it needs to initialize, to wait for its turn, or is
- * completed).
- */
-var Throttler = { 
-  // Each 8-bit block of the IP address allows for 0% rollout (value 0) to 100%
-  // rollout (value 255).
-  TICKET_LIMIT: 255, 
-
-  // Allow the DNS service to be overwritten for testing.
-  _dns: Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService), 
-
-  /**
-   * Check if a given feature should be throttled or not.
-   * @param {string} [prefPrefix] Start of the preference name for the feature.
-   * @return {Promise} Resolved on success, and rejected on throttled.
-   */
-  check: function check(prefPrefix) {var _this14 = this;
-    return new Promise(function (resolve, reject) {
-      // Initialize the ticket (0-254) if it doesn't have a valid value yet.
-      var prefTicket = prefPrefix + ".ticket";
-      var ticket = Services.prefs.getIntPref(prefTicket);
-      if (ticket < 0) {
-        ticket = Math.floor(Math.random() * _this14.TICKET_LIMIT);
-        Services.prefs.setIntPref(prefTicket, ticket);}
-
-      // Short circuit if the special ticket value indicates we're good to go.
-      else if (ticket >= _this14.TICKET_LIMIT) {
-          resolve();
-          return;}
-
-
-      // Handle responses from the DNS resolution service request.
-      var onDNS = function onDNS(request, record) {
-        // Failed to get A-record, so skip for now.
-        if (record === null) {
-          reject();
-          return;}
-
-
-        // Ensure we have a special loopback value before checking other blocks.
-        var ipBlocks = record.getNextAddrAsString().split(".");
-        if (ipBlocks[0] !== "127") {
-          reject();
-          return;}
-
-
-        // Use a specific part of the A-record IP address depending on the
-        // channel. I.e., 127.[release/other].[beta].[aurora/nightly].
-        var index = 1;
-        switch (Services.prefs.getCharPref("app.update.channel")) {
-          case "beta":
-            index = 2;
-            break;
-          case "aurora":
-          case "nightly":
-            index = 3;
-            break;}
-
-
-        // Select the 1 out of 4 parts of the "."-separated IP address to check
-        // if the 8-bit threshold (0-255) exceeds the ticket (0-254).
-        if (ticket < ipBlocks[index]) {
-          // Remember that we're good to go to avoid future DNS checks.
-          Services.prefs.setIntPref(prefTicket, _this14.TICKET_LIMIT);
-          resolve();} else 
-
-        {
-          reject();}};
-
-
-
-      // Look up the DNS A-record of a throttler hostname to decide to show.
-      _this14._dns.asyncResolve(Services.prefs.getCharPref(prefPrefix + ".throttler"), 
-      _this14._dns.RESOLVE_DISABLE_IPV6, onDNS, Services.tm.mainThread);});} };
-
-
-
-
-/**
- * Creates the loop button on the toolbar. Due to loop being a system-addon
- * CustomizableUI already has a placement location for the button, so that
- * we can be on the toolbar.
- */
-function createLoopButton() {
-  CustomizableUI.createWidget({ 
-    id: "loop-button", 
-    type: "custom", 
-    label: "loop-call-button3.label", 
-    tooltiptext: "loop-call-button3.tooltiptext2", 
-    privateBrowsingTooltiptext: "loop-call-button3-pb.tooltiptext", 
-    defaultArea: CustomizableUI.AREA_NAVBAR, 
-    removable: true, 
-    onBuild: function onBuild(aDocument) {
-      // If we're not supposed to see the button, return zip.
-      if (!Services.prefs.getBoolPref("loop.enabled")) {
-        return null;}
-
-
-      var isWindowPrivate = PrivateBrowsingUtils.isWindowPrivate(aDocument.defaultView);
-
-      var node = aDocument.createElementNS(kNSXUL, "toolbarbutton");
-      node.setAttribute("id", this.id);
-      node.classList.add("toolbarbutton-1");
-      node.classList.add("chromeclass-toolbar-additional");
-      node.classList.add("badged-button");
-      node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
-      if (isWindowPrivate) {
-        node.setAttribute("disabled", "true");}
-
-      var tooltiptext = isWindowPrivate ? 
-      CustomizableUI.getLocalizedProperty(this, "privateBrowsingTooltiptext", 
-      [CustomizableUI.getLocalizedProperty(this, "label")]) : 
-      CustomizableUI.getLocalizedProperty(this, "tooltiptext");
-      node.setAttribute("tooltiptext", tooltiptext);
-      node.setAttribute("removable", "true");
-      node.addEventListener("command", function (event) {
-        aDocument.defaultView.LoopUI.togglePanel(event);});
-
-
-      return node;} });}
-
-
-
-
-/**
- * Loads the default preferences from the prefs file. This loads the preferences
- * into the default branch, so they don't appear as user preferences.
- */
-function loadDefaultPrefs() {
-  var branch = Services.prefs.getDefaultBranch("");
-  Services.scriptloader.loadSubScript("chrome://loop/content/preferences/prefs.js", { 
-    pref: function pref(key, val) {
-      // If a previously set default pref exists don't overwrite it.  This can
-      // happen for ESR or distribution.ini.
-      if (branch.getPrefType(key) != branch.PREF_INVALID) {
-        return;}
-
-      switch (typeof val === "undefined" ? "undefined" : _typeof(val)) {
-        case "boolean":
-          branch.setBoolPref(key, val);
-          break;
-        case "number":
-          branch.setIntPref(key, val);
-          break;
-        case "string":
-          branch.setCharPref(key, val);
-          break;}} });
-
-
-
-
-  if (Services.vc.compare(Services.appinfo.version, "47.0a1") < 0) {
-    branch.setBoolPref("loop.remote.autostart", false);}}
-
-
-
-/**
- * Called when the add-on is started, e.g. when installed or when Firefox starts.
- */
-function startup(data) {
-  // Record the add-on version for when the UI is initialised.
-  WindowListener.addonVersion = data.version;
-
-  loadDefaultPrefs();
-  if (!Services.prefs.getBoolPref("loop.enabled")) {
-    return;}
-
-
-  createLoopButton();
-
-  // Attach to hidden window (for OS X).
-  if (AppConstants.platform == "macosx") {
-    try {
-      WindowListener.setupBrowserUI(Services.appShell.hiddenDOMWindow);} 
-    catch (ex) {(function () {
-        // Hidden window didn't exist, so wait until startup is done.
-        var topic = "browser-delayed-startup-finished";
-        Services.obs.addObserver(function observer() {
-          Services.obs.removeObserver(observer, topic);
-          WindowListener.setupBrowserUI(Services.appShell.hiddenDOMWindow);}, 
-        topic, false);})();}}
-
-
-
-  // Attach to existing browser windows, for modifying UI.
-  var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
-  var windows = wm.getEnumerator("navigator:browser");
-  while (windows.hasMoreElements()) {
-    var domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
-    WindowListener.setupBrowserUI(domWindow);}
-
-
-  // Wait for any new browser windows to open.
-  wm.addListener(WindowListener);
-
-  // Load our stylesheets.
-  var styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].
-  getService(Components.interfaces.nsIStyleSheetService);
-  var sheets = [
-  "chrome://loop-shared/skin/loop.css", 
-  "chrome://loop/skin/platform.css"];var _iteratorNormalCompletion2 = true;var _didIteratorError2 = false;var _iteratorError2 = undefined;try {
-
-
-
-    for (var _iterator2 = sheets[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {var sheet = _step2.value;
-      var styleSheetURI = Services.io.newURI(sheet, null, null);
-      styleSheetService.loadAndRegisterSheet(styleSheetURI, 
-      styleSheetService.AUTHOR_SHEET);}} catch (err) {_didIteratorError2 = true;_iteratorError2 = err;} finally {try {if (!_iteratorNormalCompletion2 && _iterator2.return) {_iterator2.return();}} finally {if (_didIteratorError2) {throw _iteratorError2;}}}}
-
-
-
-/**
- * Called when the add-on is shutting down, could be for re-installation
- * or just uninstall.
- */
-function shutdown(data, reason) {
-  // Close any open chat windows
-  Cu.import("resource:///modules/Chat.jsm");
-  var isLoopURL = function isLoopURL(_ref) {var src = _ref.src;return (/^about:loopconversation#/.test(src));};
-  [].concat(_toConsumableArray(Chat.chatboxes)).filter(isLoopURL).forEach(function (chatbox) {
-    chatbox.content.contentWindow.close();});
-
-
-  // Detach from hidden window (for OS X).
-  if (AppConstants.platform == "macosx") {
-    WindowListener.tearDownBrowserUI(Services.appShell.hiddenDOMWindow);}
-
-
-  // Detach from browser windows.
-  var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
-  var windows = wm.getEnumerator("navigator:browser");
-  while (windows.hasMoreElements()) {
-    var domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
-    WindowListener.tearDownBrowserUI(domWindow);}
-
-
-  // Stop waiting for browser windows to open.
-  wm.removeListener(WindowListener);
-
-  // If the app is shutting down, don't worry about cleaning up, just let
-  // it fade away...
-  if (reason == APP_SHUTDOWN) {
-    return;}
-
-
-  CustomizableUI.destroyWidget("loop-button");
-
-  // Unload stylesheets.
-  var styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].
-  getService(Components.interfaces.nsIStyleSheetService);
-  var sheets = ["chrome://loop/content/addon/css/loop.css", 
-  "chrome://loop/skin/platform.css"];var _iteratorNormalCompletion3 = true;var _didIteratorError3 = false;var _iteratorError3 = undefined;try {
-    for (var _iterator3 = sheets[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {var sheet = _step3.value;
-      var styleSheetURI = Services.io.newURI(sheet, null, null);
-      if (styleSheetService.sheetRegistered(styleSheetURI, 
-      styleSheetService.AUTHOR_SHEET)) {
-        styleSheetService.unregisterSheet(styleSheetURI, 
-        styleSheetService.AUTHOR_SHEET);}}
-
-
-
-    // Unload modules.
-  } catch (err) {_didIteratorError3 = true;_iteratorError3 = err;} finally {try {if (!_iteratorNormalCompletion3 && _iterator3.return) {_iterator3.return();}} finally {if (_didIteratorError3) {throw _iteratorError3;}}}Cu.unload("chrome://loop/content/modules/MozLoopAPI.jsm");
-  Cu.unload("chrome://loop/content/modules/LoopRooms.jsm");
-  Cu.unload("chrome://loop/content/modules/MozLoopService.jsm");}
-
-
-function install() {}
-
-function uninstall() {}
deleted file mode 100644
--- a/browser/extensions/loop/chrome/content/modules/DomainWhitelist.jsm
+++ /dev/null
@@ -1,3018 +0,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/. */
-
-"use strict";
-
-/* exported DomainWhitelist */
-this.EXPORTED_SYMBOLS = ["DomainWhitelist"];
-
-this.DomainWhitelist = Object.freeze({ 
-  check: function check(domain) {
-    return gWhitelist.has(domain);} });
-
-
-
-// Convert the multiline list of domains into a Set for lookup.
-var gWhitelist = new Set("\n01net.com\n07073.com\n10086.cn\n104.com.tw\n1111.com.tw\n114la.com\n11st.co.kr\n120ask.com\n12306.cn\n123cha.com\n123rf.com\n126.com\n1337x.to\n163.com\n1688.com\n16lao.com\n17173.com\n178.com\n17k.com\n17ok.com\n17track.net\n189.cn\n1905.com\n1and1.com\n1edisource.com\n1tv.ru\n1und1.de\n20minutes.fr\n20minutos.es\n2345.com\n247sports.com\n24h.com.vn\n24hourfitness.com\n28.com\n2ch-c.net\n2ch.net\n2chan.net\n2chblog.jp\n2gis.ru\n315che.com\n360.cn\n360.com\n360doc.com\n39.net\n3dmgame.com\n3m.com\n3tailer.com\n42mr.com\n4399.com\n4chan.org\n4dsply.com\n4gamer.net\n4pda.ru\n4shared.com\n500px.com\n51.la\n51auto.com\n51cto.com\n51sole.com\n51yes.com\n525j.com.cn\n58.com\n58pic.com\n5dcar.com\n6park.com\n6pm.com\n7769domain.com\n99acres.com\n9gag.com\na10.com\naa.com\naafp.org\naamc.org\naao.org\naaos.org\naarp.org\naastocks.com\nabc.es\nabc.net.au\nabchina.com\nabebooks.com\nabercrombie.com\nabout.com\nabplive.in\nabril.com.br\nabs-cbn.com\nabsoluteclickscom.com\nacademia.edu\nacademy.com\naccommodationforstudents.com\naccorhotels.com\naccuweather.com\nacer.com\nacfun.tv\nactiverain.com\nad-tech.com\nad4game.com\nadcash.com\nadditudemag.com\naddthis.com\nadf.ly\nadidas.com\nadk2x.com\nadmaimai.com\nadme.ru\nadnetworkperformance.com\nadobe.com\nadorama.com\nadp.com\nadplxmd.com\nadservingsolutionsinc.com\nadservone.com\nadslgate.com\nae.com\naegeanair.com\naerlingus.com\naeroflot.ru\naeromexico.com\naeroplan.com\naerosoles.com\naftonbladet.se\nagar.io\nagoda.com\nahg.com\nahit.com\nahrq.gov\nairarabia.com\nairasia.com\nairastana.com\nairberlin.com\nairbnb.com\naircanada.com\naireuropa.com\nairfrance.com\nairlinequality.com\nairmiles.ca\nairnewzealand.co.nz\nairtel.in\najanshaber.com\nakamaihd.net\nakb48matomemory.com\nalarabiya.net\nalaskaair.com\nalbawabhnews.com\nalexa.cn\nalexa.com\nalfabank.ru\nalfalfalfa.com\nalfredangelo.com\nali213.net\nalibaba.com\nalicdn.com\nalice.it\naliexpress.com\nalimama.com\nalipay.com\nalitalia.com\naliyun.com\naljaras.com\naljazeera.net\nall-free-download.com\nall2lnk.com\nallabout.co.jp\nallegiantair.com\nallegro.pl\nallmyvideos.net\nallocine.fr\nallrecipes.com\nalmasryalyoum.com\naltervista.org\nalwafd.org\nalz.org\nam15.net\nama-assn.org\namadeus.net\namarujala.com\namazon.ca\namazon.cn\namazon.co.jp\namazon.co.uk\namazon.com\namazon.de\namazon.es\namazon.fr\namazon.in\namazon.it\namazonaws.com\nameba.jp\nameblo.jp\namericanas.com.br\namericanexpress.com\namericanschoolnj.com\namorepacific.com\nampclicks.com\nampxchange.com\nana.co.jp\nancestry.com\nandroid.com\nandroidauthority.com\nandroidcentral.com\nangieslist.com\nanitube.se\nanjuke.com\nannualcreditreport.com\nanswers.com\nanthropologie.com\naol.com\napa.org\napache.org\naparat.com\napartmenttherapy.com\naplaceformom.com\napple.com\nappledaily.com.tw\nappraisalbuzz.com\nappraisalinstitute.org\nappraisers.org\nappraisersforum.com\nappraiserusa.com\narbeitsagentur.de\narcelik.com.tr\narchive.org\narchiveofourown.org\narcot.com\narcteryx.com\narduino.cc\nareaa.org\nargaam.com\nargos.co.uk\nariba.com\narinet.com\narstechnica.com\nas.com\nasahi.com\nasana.com\nascii.jp\nasda.com\nasha.org\nashleyfurniture.com\nasia-lists.com\nasiatravel.com\nasicsamerica.com\nask.com\nask.fm\naskmebazaar.com\naskubuntu.com\nasos.com\nasriran.com\nassetline.com\nasus.com\natkins.com\natlassian.net\natt.com\natt.net\natwiki.jp\naucfan.com\nauction.co.kr\naudible.com\naudio-technica.com\nauntyacid.com\nausopen.com\naustrian.com\nauthoritynutrition.com\nauto.ru\nautoblog.com\nautobytel.com\nautodesk.com\nautohome.com.cn\nautoscout24.de\nautotrader.co.uk\nautotrader.com\navast.com\navclub.com\naveda.com\navery.com\navforums.com\navg.com\navira.com\navito.ma\navito.ru\naweber.com\naxia.com\naxisbank.co.in\naxisbank.com\nazet.sk\nazlyrics.com\nb2btech.com\nb3net.com\nb9dm.com\nbab.la\nbabycenter.com\nbabylon.com\nbabytree.com\nbackcountry.com\nbackpage.com\nbackyardchickens.com\nbadoo.com\nbahn.de\nbaidu.com\nbaike.com\nbaimao.com\nbaixaki.com.br\nbandcamp.com\nbanggood.com\nbanki.ru\nbankmellat.ir\nbankofamerica.com\nbankrate.com\nbarbie.com\nbarbour.com\nbarcelo.com\nbarclaycardus.com\nbarclays.co.uk\nbarnesandnoble.com\nbartarinha.ir\nbasecamp.com\nbassettfurniture.com\nbasspro.com\nbastillepost.com\nbathandbodyworks.com\nbattle.net\nbattlefield.com\nbayt.com\nbb.com.br\nbbb.org\nbbc.co.uk\nbbc.com\nbbt.com\nbbteam.com\nbc.vc\nbedandbreakfast.com\nbedbathandbeyond.com\nbeeline.ru\nbehance.net\nbelkin.com\nbenetton.com\nberetta.com\nberkeley.edu\nbestadbid.com\nbestbuy.com\nbestwestern.com\nbet365.com\nbettycrocker.com\nbeytoote.com\nbgr.com\nbhaskar.com\nbhg.com\nbhphotovideo.com\nbiblegateway.com\nbidvertiser.com\nbig5sportinggoods.com\nbiglike.com\nbiglobe.ne.jp\nbild.de\nbilibili.com\nbillboard.com\nbilldesk.com\nbing.com\nbintang.com\nbiobiochile.cl\nbiomedcentral.com\nbioyun.com\nbirdsallinteractive.com\nbissell.com\nbitauto.com\nbitbucket.org\nbitly.com\nbizjournals.com\nbkstr.com\nblablacar.es\nblackboard.com\nblackhatworld.com\nbleacherreport.com\nblkget.com\nblobla.com\nblocket.se\nblog.com\nblog.ir\nblog.jp\nblog.me\nblogfa.com\nblogger.com\nblogimg.jp\nblogphongthuy.com\nblogsky.com\nblomaga.jp\nbloomberg.com\nblu-ray.com\nbluehost.com\nbmi.ir\nbmj.com\nbobvila.com\nboc.cn\nbodybuilding.com\nbol.com\nbollywoodbubble.com\nbom.gov.au\nboma.org\nbomb01.com\nbonanza.com\nbonappetit.com\nbongda60.net\nbooking.com\nbookmyshow.com\nboredpanda.com\nbose.com\nbottlenose-wine.com\nbox.com\nboxofficemojo.com\nboylesoftware.com\nbp.blogspot.com\nbradesco.com.br\nbrainyquote.com\nbrassring.com\nbraun.com\nbreastcancer.org\nbreitbart.com\nbrides.com.cn\nbridgestreet.com\nbritishairways.com\nbrusselsairlines.com\nbs.to\nbsnl.in\nbt.com\nbtolat.com\nbttiantang.com\nbuffiniandcompany.com\nbukalapak.com\nbullhorn.com\nburton.com\nbuscape.com.br\nbusinessinsider.com\nbusinessol.com\nbusinessweekly.com.tw\nbustle.com\nbuyerzone.com\nbuyreman.com\nbuzzfeed.com\nbuzzfil.net\nbuzzlie.com\nc-loans.com\nc3i-inc.com\nca.gov\ncabelas.com\ncaf.fr\ncafemom.com\ncafepress.com\ncaijing.com.cn\ncaisse-epargne.fr\ncaixa.gov.br\ncaixin.com\ncambridge.org\ncamdenliving.com\ncamelbak.com\ncameloteurope.com\ncancer.gov\ncancer.org\ncankaoxiaoxi.com\ncannondale.com\ncanva.com\ncapitalone.com\ncapitalone360.com\ncarcomplaints.com\ncare.com\ncareerbuilder.com\ncareerwebschool.com\ncarfax.com\ncargurus.com\ncarhartt.com\ncarmax.com\ncarnival.com\ncars.com\ncarsensor.net\ncarters.com\ncartier.com\ncarview.co.jp\ncarwale.com\ncasasbahia.com.br\ncateye.com\ncathaypacific.com\ncb01.co\ncbc.ca\ncbre.com\ncbrehotels.com\ncbs.com\ncbslocal.com\ncbsnews.com\ncbssports.com\ncc.com\nccb.com\nccb.com.cn\nccim.com\nccm.net\ncda.pl\ncdc.gov\ncdiscount.com\ncdstm.cn\nce.cn\ncebupacificair.com\ncecil.de\nceconline.com\ncelebritycruises.com\nceneo.pl\ncentury21.com\ncerner.com\ncesweb.org\nchampionat.com\nchampionsschool.com\nchange.org\ncharitynavigator.org\ncharter.net\nchase.com\nchatwork.com\ncheapflights.co.uk\ncheaptickets.com\ncheezburger.com\nchefkoch.de\nchegg.com\nchekb.com\nchess.com\nchicagotribune.com\nchildrensplace.com\nchina-airlines.com\nchina.com\nchina.com.cn\nchinadaily.com.cn\nchinaso.com\nchinatimes.com\nchinaz.com\nchip.de\nchiphell.com\nchoicehotels.com\nchosun.com\nchouftv.ma\nchristian-dogma.com\nchristianlouboutin.com\nchron.com\nci123.com\ncimls.com\ncinemablend.com\ncisco.com\nciti.com\ncitibank.co.in\ncitibankonline.com\ncitilink.ru\ncitizensadvice.org.uk\ncitrixonline.com\ncity-data.com\ncityadspix.com\ncityheaven.net\nck101.com\nclarin.com\nclarkhoward.com\ncleartrip.com\nclevelandclinic.org\nclickadu.com\nclickbank.com\nclicksvenue.com\nclien.net\ncliftonlabs.com\nclinicaltrials.gov\nclinique.com\nclipconverter.cc\nclixsense.com\ncloudflare.com\ncloudsrvtrk.com\ncms.gov\ncna.com.tw\ncnbc.com\ncnbeta.com\ncnblogs.com\ncnet.com\ncnmo.com\ncnn.com\ncnnic.cn\ncntraveler.com\ncntv.cn\ncnzz.com\ncoccoc.com\ncocolog-nifty.com\ncodecademy.com\ncodecanyon.net\ncodepen.io\ncodeproject.com\ncoldwellbanker.com\ncolgate.com\ncollegeboard.org\ncollegerentals.com\ncolliers.com\ncolumbia.com\ncolumbia.edu\ncomcast.net\ncomenity.net\ncommbank.com.au\ncommentcamarche.net\ncommerx.com\ncomplaintsboard.com\ncomplex.com\ncomputerbild.de\nconcursolutions.com\ncondor.com\nconservativetribune.com\nconstantcontact.com\nconsumeraffairs.com\nconsumercomplaints.in\nconsumerist.com\nconsumerlab.com\nconsumerreports.org\nconsumersearch.com\ncontainerstore.com\ncontentabc.com\ncontinuingedexpress.com\nconvert2mp3.net\ncookinglight.com\ncookpad.com\ncooks.com\ncooksillustrated.com\ncoolmath-games.com\ncopaair.com\ncorelogic.com\ncornell.edu\ncorporatehousingbyowner.com\ncorreios.com.br\ncorriere.it\ncosmopolitan.com\ncostar.com\ncostco.com\ncouchsurfing.com\ncountryliving.com\ncoupons.com\ncoursera.org\ncovalentworks.com\ncox.net\ncpasbien.io\ncpsc.gov\ncqnews.net\ncracked.com\ncraigslist.ca\ncraigslist.org\ncrateandbarrel.com\ncreativemarket.com\ncredai.org\ncredit-agricole.fr\ncreditkarma.com\ncreditmutuel.fr\ncrefcoa.com\ncrewnetwork.org\ncrhoy.com\ncricbuzz.com\ncriteo.com\ncrm-daily.com\ncrmbuyer.com\ncrs.com\ncrunchbase.com\ncrunchyroll.com\ncrutchfield.com\ncsc.com\ncsdn.net\nctitv.com.tw\nctrip.com\ncuisinart.com\ncushwake.com\ncusthelp.com\ncvs.com\ncxml.org\ncygnet-infotech.com\ndafont.com\ndaikynguyenvn.com\ndaily.co.jp\ndailykos.com\ndailymail.co.uk\ndailymotion.com\ndailypakistan.com.pk\ndailysnark.com\ndanawa.com\ndangdang.com\ndantri.com.vn\ndartappraisal.com\ndataart.com\ndaum.net\ndaveramsey.com\ndavidsbridal.com\ndavita.com\ndawn.com\ndeadspin.com\ndealnews.com\ndebate.com.mx\ndecathlon.co.uk\ndeere.com\ndeesign.com\ndeezer.com\ndell.com\ndelta.com\ndemandstar.com\ndemc.com\ndepositphotos.com\ndescartes.com\ndessy.com\ndetik.com\ndeviantart.com\ndeviantart.net\ndhgate.com\ndhl.com\ndhl.de\ndiabetes.co.uk\ndiabetes.org\ndiamondresorts.com\ndianping.com\ndickssportinggoods.com\ndict.cc\ndiesel.com\ndigg.com\ndigikala.com\ndigitalenterprise.org\ndigitalmesh.com\ndigitalocean.com\ndigitalriver.com\ndigitaltrends.com\ndigitas.com\ndillards.com\ndingit.tv\ndiply.com\ndirectrev.com\ndirectv.com\ndiscogs.com\ndiscover.com\ndiscovercard.com\ndiscuss.com.hk\ndish.com\ndisney.com\ndisneystore.com\ndisq.us\ndisqus.com\ndivar.ir\ndiynetwork.com\ndjpunjab.info\ndl-protect.com\ndmm.com\ndmv.org\ndnaindia.com\ndns-shop.ru\ndocin.com\ndoculabs.com\ndocusign.net\ndogfoodadvisor.com\ndoisongphapluat.com\ndomaintools.com\ndominos.com\ndonanimhaber.com\ndonga.com\ndoodle.com\ndoorblog.jp\ndostor.org\ndouban.com\ndoubleclick.net\ndouguo.com\ndouyutv.com\ndpreview.com\ndreamstime.com\ndribbble.com\ndrive2.ru\ndrom.ru\ndropbooks.tv\ndropbox.com\ndropboxusercontent.com\ndrudgereport.com\ndrugabuse.gov\ndrugs.com\ndrugstore.com\ndrweil.com\ndslreports.com\ndsw.com\ndtz.com\nduba.com\nduckduckgo.com\ndummies.com\nduolingo.com\nduowan.com\ndw.com\ndx.com\ndynamicnet.net\ndytt8.net\ne-bizsoft.com\ne-global.es\nea.com\nearthclinic.com\nearthlink.net\nearthwaterfire.com\neastday.com\neastmoney.com\neasyjet.com\neasypano.com\neatingwell.com\nebates.com\nebay-kleinanzeigen.de\nebay.ca\nebay.co.uk\nebay.com\nebay.com.au\nebay.de\nebay.es\nebay.fr\nebay.in\nebay.it\nebookers.com\nebrun.com\necco.com\necho.msk.ru\necnavi.jp\necollege.com\necommerce-digest.com\necommercebytes.com\necommercepartners.net\necommercetimes.com\neconomist.com\ned.gov\neddiebauer.com\nedeal.com\nedmodo.com\nedmunds.com\nedx.org\neenadu.net\negain.com\negou.com\nehow.com\neia.gov\nekantipur.com\neksisozluk.com\nel-nacional.com\nelcomercio.com\nelcomercio.pe\nelconfidencial.com\nelcorteingles.es\neldorado.ru\nelectronicmarkets.org\nelevenia.co.id\nelfagr.org\nelintransigente.com\nelmogaz.com\nelmundo.es\nelpais.com\nelsevier.com\neluniverso.com\nelwatannews.com\nemao.com\nemarketingassociation.com\nemgn.com\nemirates.com\nemol.com\nenet.com.cn\nenews.com.tw\nengadget.com\nengageya.com\nensonhaber.com\nentrepreneur.com\nenvato.com\neonline.com\nepic.com\nepicurious.com\nepochtimes.com\nepweike.com\nera.com\neram.fr\nergotron.com\nernestjones.co.uk\nero-advertising.com\nero-video.net\neroterest.net\nespncricinfo.com\nesquire.com\nesuteru.com\netao.com\nethanallen.com\netrade.com\netsy.com\nettoday.net\neuropa.eu\neventbrite.com\nevernote.com\nevite.com\new.com\nex.ua\nexamine.com\nexblog.jp\nexcite.co.jp\nexecustay.com\nexhentai.org\nexhibitions.co.uk\nexoclick.com\nexpedia.ca\nexpedia.com\nexpress-scripts.com\nexpress.co.uk\nexpress.pk\nextra.com.br\nextratorrent.cc\neyny.com\neztv.ag\nface-masr.com\nfacebook.com\nfacenama.com\nfaithtap.com\nfamilydoctor.com.cn\nfamilydoctor.org\nfamitsu.com\nfanatik.com.tr\nfandango.com\nfanfiction.net\nfang.com\nfanhuan.com\nfanli.com\nfanniemae.com\nfanpage.gr\nfarfesh.com\nfarsnews.com\nfashiongo.net\nfastclass.com\nfastcompany.com\nfatosdesconhecidos.com.br\nfatwallet.com\nfaz.net\nfbcdn.net\nfc2.com\nfda.gov\nfederaltitle.com\nfedex.com\nfeedly.com\nfema.gov\nfeng.com\nfibre2fashion.com\nfidelity.com\nfiducia.de\nfilehippo.com\nfilmesonlinegratis.net\nfilmibeat.com\nfilmon.com\nfilmweb.pl\nfinecooking.com\nfinishclueobscure.info\nfinishline.com\nfinn.no\nfinnair.com\nfirmseek.com\nfirstpost.com\nfisher-price.com\nfitbit.com\nfitnessmagazine.com\nfitpregnancy.com\nfiverr.com\nfivethirtyeight.com\nfixya.com\nflashscore.com\nflashx.tv\nflatmates.com.au\nflickr.com\nflightnetwork.com\nflightradar24.com\nflipboard.com\nflipkart.com\nflirchi.com\nflybe.com\nflyfrontier.com\nflysaa.com\nflyuia.com\nfnac.com\nfnb.co.za\nfntic.com\nfocus.cn\nfocus.de\nfodors.com\nfood.com\nfood52.com\nfoodandwine.com\nfoodnetwork.com\nfool.com\nforbes.com\nforce.com\nford.com\nforestcity.net\nforever21.com\nforgeofempires.com\nforocoches.com\nfortune.com\nfotostrana.ru\nfoursquare.com\nfoxnews.com\nfoxsports.com\nfree.fr\nfreecharge.in\nfreejobalert.com\nfreelancer.com\nfreepeople.com\nfreepik.com\nfrigidaire.com\nfriv.com\nfromdoctopdf.com\nfrommers.com\nfrontpoint.it\nfrys.com\nft.com\nfueleconomy.gov\nfurnishedhousing.com\ng2a.com\ngaana.com\ngalleryofguns.com\ngamefactory.jp\ngamefaqs.com\ngameforge.com\ngamepedia.com\ngamer.com.tw\ngamersky.com\ngamespot.com\ngamestop.com\ngamewith.jp\ngamme.com.tw\ngap.com\ngaranti.com.tr\ngardenweb.com\ngarmin.com\ngasbuddy.com\ngawker.com\ngazeta.pl\ngazeta.ru\ngazetaexpress.com\ngazetevatan.com\ngazzetta.it\nge.com\ngeappliances.com\ngearbest.com\ngeekologie.com\ngeico.com\ngemius.pl\ngenius.com\ngeocities.jp\ngetbootstrap.com\ngethuman.com\ngetpocket.com\ngfycat.com\nghanaweb.com\ngia.edu\ngiant-bicycles.com\ngidonline.club\ngigazine.net\ngiphy.com\ngismeteo.ru\ngithub.com\ngittigidiyor.com\ngivemesport.com\ngizmodo.com\ngizmodo.jp\nglassdoor.com\nglobalpropertyguide.com\nglobalsources.com\nglobaltestmarket.com\nglobaltimes.cn\nglobest.com\nglobo.com\nglock.com\ngmanetwork.com\ngmarket.co.kr\ngmw.cn\ngmx.net\ngnavi.co.jp\ngnc.com\ngo.com\ngo2000.com\ngo2cloud.org\ngoal.com\ngocomics.com\ngodaddy.com\ngofundme.com\ngoibibo.com\ngoldcoastschools.com\ngome.com.cn\ngongchang.com\ngoo-net.com\ngoo.gl\ngoo.ne.jp\ngoodgamestudios.com\ngoodhousekeeping.com\ngoodreads.com\ngoodrx.com\ngoogle-analytics.com\ngoogle.ae\ngoogle.at\ngoogle.az\ngoogle.ba\ngoogle.be\ngoogle.bg\ngoogle.by\ngoogle.ca\ngoogle.ch\ngoogle.cl\ngoogle.cn\ngoogle.co.id\ngoogle.co.il\ngoogle.co.in\ngoogle.co.jp\ngoogle.co.kr\ngoogle.co.ma\ngoogle.co.nz\ngoogle.co.th\ngoogle.co.tz\ngoogle.co.uk\ngoogle.co.ve\ngoogle.co.za\ngoogle.com\ngoogle.com.af\ngoogle.com.ar\ngoogle.com.au\ngoogle.com.bd\ngoogle.com.bo\ngoogle.com.br\ngoogle.com.co\ngoogle.com.do\ngoogle.com.ec\ngoogle.com.eg\ngoogle.com.gh\ngoogle.com.gt\ngoogle.com.hk\ngoogle.com.kw\ngoogle.com.ly\ngoogle.com.mx\ngoogle.com.my\ngoogle.com.ng\ngoogle.com.pe\ngoogle.com.ph\ngoogle.com.pk\ngoogle.com.pr\ngoogle.com.sa\ngoogle.com.sg\ngoogle.com.tr\ngoogle.com.tw\ngoogle.com.ua\ngoogle.com.vn\ngoogle.cz\ngoogle.de\ngoogle.dk\ngoogle.dz\ngoogle.es\ngoogle.fi\ngoogle.fr\ngoogle.gr\ngoogle.hr\ngoogle.hu\ngoogle.ie\ngoogle.iq\ngoogle.it\ngoogle.kz\ngoogle.lk\ngoogle.lt\ngoogle.lv\ngoogle.nl\ngoogle.no\ngoogle.pl\ngoogle.pt\ngoogle.ro\ngoogle.rs\ngoogle.ru\ngoogle.se\ngoogle.si\ngoogle.sk\ngoogle.tn\ngoogleadservices.com\ngoogleusercontent.com\ngorillavid.in\ngotomeeting.com\ngotowebinar.com\ngotporn.com\ngougou.com\ngovome.com\ngracobaby.com\ngrammarly.com\ngraphicriver.net\ngreatandhra.com\ngreatclips.com\ngreatergood.com\ngroupon.com\ngs1.org\ngsmarena.com\ngstatic.com\nguess.com\nguidestar.org\ngulfair.com\ngumtree.co.za\ngumtree.com\ngumtree.com.au\ngumtree.pl\ngunbroker.com\ngutefrage.net\ngyazo.com\ngymboree.com\nhaber7.com\nhaberler.com\nhaberturk.com\nhabrahabr.ru\nhaier.com\nhalifax-online.co.uk\nhamariweb.com\nhamusoku.com\nhanleywood.com\nhao123.com\nhaosou.com\nharborfreight.com\nharmankardon.com\nharrods.com\nharvard.edu\nhasbro.com\nhatena.ne.jp\nhatenablog.com\nhawaiianairlines.com\nhclips.com\nhdfcbank.com\nhdfilmifullizle.com.tr\nhealth.com\nhealthboards.com\nhealthcare.gov\nhealthgrades.com\nhealthline.com\nhealthstream.com\nheart.org\nheise.de\nhellou.co.uk\nhellyhansen.com\nhepsiburada.com\nhere.com\nhermanmiller.com\nhespress.com\nhexun.com\nhfflp.com\nhgtv.com\nhh.ru\nhibapress.com\nhighrisehq.com\nhihi2.com\nhillspet.com\nhilton.com\nhimado.in\nhimasoku.com\nhindustantimes.com\nhines.com\nhistats.com\nhitc.com\nhizliresim.com\nhm.com\nholiday-weather.com\nhollandamerica.com\nhollywoodlife.com\nhollywoodreporter.com\nhomeaway.com\nhomedepot.com\nhomepage-web.com\nhomes.co.jp\nhomesalez.com\nhongkiat.com\nhootsuite.com\nhopkinsmedicine.org\nhorizonhobby.com\nhostelbookers.com\nhostelworld.com\nhostgator.com\nhotel.de\nhotels.com\nhoteltravel.com\nhotnewhiphop.com\nhotpepper.jp\nhotstar.com\nhottopic.com\nhotukdeals.com\nhotwire.com\nhouse365.com\nhousemaster.com\nhouzz.com\nhowardforums.com\nhowstuffworks.com\nhowtogeek.com\nhp.com\nhrblock.com\nhref.li\nhrs.de\nhsbc.co.uk\nhsbc.com.hk\nhse.gov.uk\nhsn.com\nhuaban.com\nhuanqiu.com\nhuawei.com\nhubpages.com\nhubspot.com\nhud.gov\nhuffingtonpost.com\nhulu.com\nhulu.jp\nhumblebundle.com\nhupu.com\nhurriyet.com.tr\nhusqvarna.com\nhuya.com\nhyatt.com\ni.ua\ni2x.net\nibanking-services.com\nibba.org\niberia.com\nibm.com\nibnlive.com\nibtimes.co.in\nibtimes.co.uk\nibtimes.com\nicbc.com.cn\nicc.net\niciba.com\nicicibank.com\nicims.com\nicloud.com\nicolor.com.cn\niconosquare.com\nicook.tw\nid.net\nidata.com\nideafit.com\nidealista.com\nidealo.de\nidnes.cz\nifeng.com\niflscience.com\nifma.org\nig.com.br\nign.com\niheart.com\niherb.com\nihg.com\nihwy.com\nijreview.com\nikea.com\nilfattoquotidiano.it\nilmeteo.it\niltalehti.fi\niltasanomat.fi\nimagebam.com\nimages-amazon.com\nimaging-resource.com\nimamerchants.org\nimdb.com\nimgchili.net\nimgur.com\nimmobilienscout24.de\nimobile.com.cn\nimpress.co.jp\ninc.com\nindeed.co.in\nindeed.co.uk\nindeed.com\nindependent.co.uk\nindex.hu\nindia.com\nindiamart.com\nindianexpress.com\nindianrail.gov.in\nindiatimes.com\nindiegogo.com\ninfoaccess.net\ninfobae.com\ninformaticsinc.com\ninformer.com\ninfoseek.co.jp\ninfusionsoft.com\ning.nl\nink361.com\ninman.com\ninmotionhosting.com\ninnfrad.com\ninnotrac.com\ninnshopper.com\ninquirer.net\ninquisitr.com\ninspectionnews.net\ninspectorsjournal.com\ninspsearch.com\ninstacommerce.net\ninstagram.com\ninstituteonline.com\ninstructables.com\ninstructure.com\nintegrativenutrition.com\nintegro.com\nintel.com\ninteractivesoftware.co.uk\ninteria.pl\nintermountainhealthcare.org\ninternetdownloadmanager.com\ninternethaber.com\ninterpark.com\nintervalworld.com\nintoday.in\nintrabench.com\nintuit.com\ninvaluable.com\ninvesting.com\ninvestopedia.com\nioffer.com\nionidea.com\nipko.pl\niqiyi.com\nirctc.co.in\nirecommend.ru\nirei.com\nirem.org\nironplanet.com\nirpopup.ir\nirs.gov\nissuu.com\nistockphoto.com\nit4profit.com\nitasoftware.com\nitau.com.br\nitelligencegroup.com\nitmedia.co.jp\nivanhoecambridge.com\nivc.cn\nivc.com\nivenue.com\nivi.ru\niwillteachyoutoberich.com\niza.ne.jp\nj-cast.com\njabong.com\njagran.com\njal.co.jp\njalan.net\njalopnik.com\njamieoliver.com\njapanpost.jp\njav68.me\njava.com\njavedch.com\njb51.net\njbl.com\njcpenney.com\njcrew.com\njd.com\njet.com\njetairways.com\njetblue.com\njeuxvideo.com\njezebel.com\njia360.com\njimdo.com\njin115.com\njjwxc.net\njma.go.jp\njnj.com\njoann.com\njobrapido.com\njohnlewis.com\njoins.com\njomashop.com\njoneslanglasalle.com\njournaldesfemmes.com\njquery.com\njqw.com\njrj.com.cn\njsfiddle.net\njugem.jp\njumeirah.com\njumia.com.ng\njunbi-tracker.com\njustdial.com\njw.org\nk618.cn\nkaiserpermanente.org\nkakaku.com\nkana.com\nkao.com\nkapook.com\nkapre.com\nkaskus.co.id\nkaspersky.com\nkat.cr\nkay.com\nkayak.com\nkbb.com\nkddi.com\nkdnet.net\nkeenfootwear.com\nkeepvid.com\nkenh14.vn\nkenwood.com\nkevinmd.com\nkhabaronline.ir\nkhanacademy.org\nkicker.de\nkickstarter.com\nkidshealth.org\nkidspot.com.au\nkienthuc.net.vn\nkijiji.ca\nkimberamerica.com\nkinja.com\nkinogo.co\nkinopoisk.ru\nkinox.to\nkinozal.tv\nkiplinger.com\nkissanime.to\nkizi.com\nkizlarsoruyor.com\nklikbca.com\nklipsch.com\nklm.com\nkmart.com\nkmp.co.uk\nkohls.com\nkompas.com\nkompasiana.com\nkonga.com\nkongregate.com\nkooora.com\nkorabia.com\nkoreanair.com\nkotaku.com\nkouclo.com\nkp.ru\nkraftrecipes.com\nksl.com\nkt9267.com\nkuronekoyamato.co.jp\nkuwo.cn\nkyosho.com\nla-z-boy.com\nlabanquepostale.fr\nlabcorp.com\nlabtestsonline.org\nlacaixa.es\nlady8844.com\nlagaceta.com.ar\nlamoda.ru\nlan.com\nlanacion.com.ar\nlancome-usa.com\nlandcentral.com\nlandflip.com\nlandlords.org.uk\nlandsend.com\nlandwatch.com\nlapatilla.com\nlaposte.net\nlaredoute.fr\nlast.fm\nlastpass.com\nlaterooms.com\nlatimes.com\nlayalina.com\nlazada.co.id\nldblog.jp\nlds.com\nlds.org\nleadzupc.com\nleagueoflegends.com\nleboncoin.fr\nlefigaro.fr\nlegacy.com\nlego.com\nlemonde.fr\nlenovo.com\nlenscrafters.com\nlenta.ru\nleo.org\nlequipe.fr\nletv.com\nlg.com\nlibero.it\nlifebuzz.com\nlifehack.org\nlifehacker.com\nlifenews.ru\nlightinthebox.com\nlightwellinc.com\nlikemag.com\nlikes.com\nlindaikejisblog.com\nline.me\nlinkedin.com\nlinkwithin.com\nlinternaute.com\nliputan6.com\nliquor.com\nlist-manage.com\nlist-manage1.com\nlittlethings.com\nlive.com\nliveadexchanger.com\nlivedoor.biz\nlivedoor.com\nlivedoor.jp\nlivehelper.com\nliveinternet.ru\nlivejournal.com\nliveleak.com\nliveperson.net\nlivescore.com\nlivestrong.com\nlivetv.sx\nlivingsocial.com\nllbean.com\nlloydsbank.co.uk\nloading-delivery2.com\nlockerdome.com\nlogicsoftware.co.uk\nlogitech.com\nlohaco.jp\nlolesports.com\nlonelyplanet.com\nlongchamp.com\nloopnet.com\nlordandtaylor.com\nlorealparisusa.com\nlostfilm.tv\nlot.com\nlotterypost.com\nlowensign.com\nlowes.com\nltn.com.tw\nlufthansa.com\nlululemon.com\nlun.com\nluxtarget.com\nluxuryhomemarketing.com\nluxuryhomes.com\nluxuryrealestate.com\nlvmama.com\nlynda.com\nmackeeper.com\nmackolik.com\nmacromill.com\nmacrumors.com\nmacys.com\nmade-in-china.com\nmail.com\nmail.ru\nmailchimp.com\nmainichi.jp\nmakeleio.gr\nmakemytrip.com\nmakeupalley.com\nmakeuseof.com\nmama.cn\nmangafox.me\nmangahere.co\nmangareader.net\nmango.com\nmanoramaonline.com\nmanta.com\nmanualsonline.com\nmanufacturing.net\nmapquest.com\nmapsofindia.com\nmarc-o-polo.com\nmarca.com\nmarketgid.com\nmarketwatch.com\nmarksandspencer.com\nmarktplaats.nl\nmarmiton.org\nmarmot.com\nmarriott.com\nmarthastewart.com\nmarykay.com\nmashable.com\nmashreghnews.ir\nmasralarabia.com\nmasrawy.com\nmassageenvy.com\nmatch.com\nmattel.com\nmaxtalk.com\nmaybank2u.com.my\nmaybelline.com\nmayoclinic.org\nmbank.pl\nmbc.net\nmcafee.com\nmcfadyen.com\nmckesson.com\nmckissock.com\nmdanderson.org\nmeaww.com\nmeb.gov.tr\nmec.gov.br\nmediafire.com\nmediaplex.com\nmediaset.it\nmedicare.gov\nmedicinenet.com\nmedium.com\nmedscape.com\nmeetup.com\nmega.co.nz\nmega.nz\nmegapopads.com\nmeituan.com\nmelia.com\nmemecats.com\nmensfitness.com\nmenshealth.co.uk\nmenshealth.com\nmentalfloss.com\nmeowshare.com\nmercadolibre.com.ar\nmercadolibre.com.mx\nmercadolibre.com.ve\nmercadolivre.com.br\nmercola.com\nmerdeka.com\nmergent.com\nmerriam-webster.com\nmessenger.com\nmesteel.com\nmetacritic.com\nmeteofrance.com\nmetro.co.uk\nmetroer.com\nmetrolyrics.com\nmetrotvnews.com\nmgid.com\nmheducation.com\nmi.com\nmic.com\nmicrosoft.com\nmicrosoftonline.com\nmicrosoftstore.com\nmidwayusa.com\nmihanblog.com\nmikeferry.com\nmilanuncios.com\nmileroticos.com\nmilitary.com\nmillersamuel.com\nmilliyet.com.tr\nminecraft.net\nminiclip.com\nmint.com\nmirror.co.uk\nmirtesen.ru\nmisr5.com\nmit.edu\nmiui.com\nmixi.jp\nmizuhobank.co.jp\nmlb.com\nmobafire.com\nmobfactory.info\nmobikwik.com\nmobile.de\nmobile01.com\nmobile9.com\nmodcloth.com\nmomoshop.com.tw\nmonarch.co.uk\nmoneycontrol.com\nmoneysavingexpert.com\nmoneytalksnews.com\nmonotaro.com\nmonster.com\nmontblanc.com\nmontgomerycountymd.gov\nmos.ru\nmoseley.org\nmotherearthnews.com\nmotortrend.com\nmoudamepo.com\nmountainhardwear.com\nmouthshut.com\nmoveandstay.com\nmovoto.com\nmoz.com\nmozilla.org\nmr-johal.com\nmskcc.org\nmsn.com\nmsnbc.com\nmts.ru\nmtsindia.in\nmtv.com\nmufg.jp\nmultihousingnews.com\nmundo.com\nmundosexanuncio.com\nmunrvscurlms.com\nmusica.com\nmusiciansfriend.com\nmvideo.ru\nmxttrf.com\nmy-hit.org\nmyanimelist.net\nmydala.com\nmydomainadvisor.com\nmydrivers.com\nmyfico.com\nmyfitnesspal.com\nmynavi.jp\nmynet.com\nmypearson.com\nmyshopify.com\nmysmartprice.com\nmyspace.com\nmysql.com\nmystart.com\nmystartsearch.com\nmyway.com\nn-tv.de\nn11.com\nn121adserv.com\nnaahq.org\nnachi.org\nnacion.com\nnahi.org\nnaiglobal.com\nnaiop.org\nnairaland.com\nnamecheap.com\nnametests.com\nnamu.wiki\nnarod.ru\nnarpm.org\nnasa.gov\nnat.com\nnate.com\nnational-lottery.co.uk\nnationalgeographic.com\nnationalmssociety.org\nnaturallycurly.com\nnature.com\nnaukri.com\nnautica.com\nnaver.com\nnaver.jp\nnavyfederal.org\nnba.com\nnbc.com\nnbcnews.com\nnbcsports.com\nncl.com\nncsha.org\nndtv.com\nneimanmarcus.com\nnejm.org\nneobux.com\nnesn.com\nnespresso.com\nnet-a-porter.com\nnetcasters.com\nnetdna-cdn.com\nnetdoctor.co.uk\nnetflix.com\nnetpartnering.com\nnetshoes.com.br\nnetsuite.com\nnetteller.com\nnetx.net\nnewbalance.com\nnewegg.com\nnewhomesdirectory.com\nnews-us.jp\nnews.com.au\nnews24.com\nnewsmth.net\nnewsnow.co.uk\nnewtab-tv.com\nnewyorker.com\nnextag.com\nnextdoor.com\nnexternal.com\nnextmedia.com\nnexusmods.com\nnfl.com\nngacn.cc\nnguoiduatin.vn\nnguyentandung.org\nnhadatso.com\nnhk.or.jp\nnhl.com\nnicovideo.jp\nnifty.com\nnih.gov\nniiz.info\nnike.com\nnikkansports.com\nnikkei.com\nnikkeibp.co.jp\nning.com\nnipic.com\nnitroflare.com\nniuche.com\nnj.com\nnlihc.org\nnmhc.org\nnmisr.com\nnnm-club.me\nnoaa.gov\nnocookie.net\nnomadicmatt.com\nnordictrack.com\nnordstrom.com\nnorton.com\nnosub.tv\nnouvelobs.com\nnovinky.cz\nnownews.com\nnowtv.de\nnowvideo.sx\nnpr.org\nnreionline.com\nnrk.no\nns5n.com\nnta.go.jp\nntdtv.com\nnttdocomo.co.jp\nnu.nl\nnuance.com\nnur.kz\nnutrition.org\nny.gov\nnyaa.eu\nnyaa.se\nnydailynews.com\nnymag.com\nnypost.com\nnyrei.com\nnytimes.com\no2.pl\noakley.com\noakwood.com\nobeo.com\nocn.ne.jp\noeeee.com\noffice.com\noffice365.com\nofficedepot.com\nok.ru\nokcupid.com\nokezone.com\nokta.com\nokwave.jp\noldnavy.com\noldrepublictitle.com\nolx.co.id\nolx.com.br\nolx.in\nolx.kz\nolx.pl\nolx.ro\nolx.ua\nomegawatches.com\nonclickads.net\nonclicktop.com\nonedio.com\noneindia.com\nonestopclick.com\nonet.pl\nonetravel.com\nonkyo.com\nonline-convert.com\nonlinecreditcenter6.com\nonlinekhabar.com\nonliner.by\nonlinesbi.com\nontests.me\nopencrm.co.uk\nopendns.com\nopenload.co\nopensooq.com\nopensubtitles.org\nopentable.com\noracle.com\norange.fr\norbitz.com\norf.at\norientaltrading.com\norigin.com\noschina.net\nosha.gov\notomoto.pl\notto.de\nouo.io\noutbrain.com\nouteredgeuk.com\nover-blog.com\noverdrive.com\noverstock.com\nownersdirect.co.uk\noyaide.com\nozon.ru\np30download.com\np5w.net\npadsdel.com\npagesjaunes.fr\npaidverts.com\npampers.com\npanasonic.com\npanasonic.jp\npanda.tv\npandora.com\npandora.net\npanet.co.il\npantip.com\npapajohns.com\nparenting.com\nparents.com\npartners.org\npastebin.com\npatagonia.com\npatch.com\npatheos.com\npatient.info\npaulaschoice.com\npayoneer.com\npaypal.com\npayseal.com\npaytm.com\npaytm.in\npbs.org\npcadvisor.co.uk\npcgamer.com\npch.com\npchome.com.tw\npchome.net\npcmag.com\npcworld.com\npearsoncmg.com\npelis24.com\npendleton-usa.com\npeople.com\nperfect.com\nperiscope.tv\npersianblog.ir\npetco.com\npetmd.com\npetsafe.net\npetsmart.com\npex.jp\npeyvandha.ir\npeza.gov.ph\nphilippineairlines.com\nphilips.com\nphoenixads.co.in\nphonearena.com\nphotobucket.com\nphotoplan.co.uk\nphotosigns.com.au\nphp.net\npiac.com.pk\npicmonkey.com\npicofile.com\npier1.com\npikabu.ru\npillsbury.com\npinimg.com\npinterest.com\npioneerelectronics.com\npiriform.com\npissedconsumer.com\npitchfork.com\npixabay.com\npixelplanet.com\npixiv.net\npixlr.com\npixnet.net\npizzahut.com\nplanetecomsolutions.com\nplanetromeo.com\nplannedparenthood.org\nplarium.com\nplay1topgame.com\nplaystation.com\nplurk.com\nplurotech.com\nplymouth.ac.uk\npnc.com\npo.st\npochta.ru\npof.com\npogo.com\npolar.com\npole-emploi.fr\npolitico.com\npolyvore.com\nponparemall.com\npopads.net\npopcash.net\npopmaster.ir\npopmyads.com\npopped.biz\npopsugar.com\npopundertotal.com\nportplus.com\npostbank.de\nposte.it\npostimg.org\npotterybarn.com\npowerball.com\nppomppu.co.kr\npps.tv\nprana.com\npredictivadvertising.com\npremierleague.com\npretty52.com\nprevention.com\nprezi.com\npricegrabber.com\npriceline.com\npriceminister.com\nprimewire.ag\nprincess.com\nprinciplevaluation.com\nprivatbank.ua\nprivateislandsonline.com\nprntscr.com\nproboards.com\nprodapt.com\nprogramme-tv.net\nprojectfreetv.so\nprologis.com\nprom.ua\npronto.com\npropertypanorama.com\nproschools.com\nprospectsoft.com\nprotect0r.com\nprothom-alo.com\nprotothema.gr\nprou.net\nprovidence.org\nprpops.com\npsu.edu\npsychologytoday.com\nptt.cc\npubcon.com\npudelek.pl\npurdue.edu\npureadexchange.com\nputlocker.is\npython.org\nqantas.com.au\nqatarairways.com\nqidian.com\nqingdaonews.com\nqiwi.com\nqq.com\nqualtrics.com\nquanjing.com\nquikr.com\nquiksilver.com\nquizlet.com\nquora.com\nqvc.com\nqz.com\nr10.net\nrabobank.nl\nrackcdn.com\nrackspace.com\nradikal.com.tr\nrakuten-bank.co.jp\nrakuten-card.co.jp\nrakuten.co.jp\nrakuten.com\nrakuten.ne.jp\nralphlauren.com\nrambler.ru\nranker.com\nrapidgator.net\nrappler.com\nrarbg.to\nravelry.com\nrbc.ru\nrbcroyalbank.com\nrci.com\nrdsa2012.com\nrealclearpolitics.com\nrealestate.com.au\nrealestatece.com\nrealestateexpress.com\nrealestatetomato.com\nrealogy.com\nrealsimple.com\nrealstar.ca\nrealtor.com\nrealtourvision.com\nrealtyexecutives.com\nrealtytimes.com\nrebac.net\nreclameaqui.com.br\nredappleapartments.com\nredbox.com\nredbubble.com\nredcrossblood.org\nreddit.com\nredfin.com\nrediff.com\nredirectvoluum.com\nrednet.cn\nreduxmediia.com\nredwingshoes.com\nreference.com\nrefinery29.com\nrei.com\nreimageplus.com\nreis.com\nrejournals.com\nrelated.com\nremax.com\nremedi.com\nremington.com\nremonline.com\nrenren.com\nrentalsite.com\nrepelis.tv\nrepubblica.it\nrepublika.co.id\nresearchgate.net\nresellerratings.com\nresultados-futbol.com\nretailmenot.com\nreuters.com\nrevacomm.com\nreverb.com\nreverso.net\nrfptemplates.org\nria.ru\nricksteves.com\nricoh-usa.com\nrightmove.co.uk\nrimanews.com\nripoffreport.com\nrismedia.com\nrivals.com\nroblox.com\nrockanddirt.com\nrocketnews24.com\nrockport.com\nrockwellinstitute.com\nrodalesorganiclife.com\nroku.com\nrolex.com\nrollingstone.com\nrottentomatoes.com\nroughguides.com\nroyalbank.com\nroyalcaribbean.com\nrozblog.com\nrozetka.com.ua\nrr.com\nrrbonlinereg.in\nrrbonlinereg.net\nrt.com\nruger.com\nrusbiz.com\nrush.edu\nruten.com.tw\nrutracker.org\nrutube.ru\nrxlist.com\nryanair.com\nsabah.com.tr\nsabq.org\nsahibinden.com\nsaisoncard.co.jp\nsaksfifthavenue.com\nsakura.ne.jp\nsalesforce.com\nsalespage.com\nsalon.com\nsamhsa.gov\nsammydress.com\nsamplicio.us\nsamsclub.com\nsamsung.com\nsankei.com\nsanook.com\nsanspo.com\nsantander.co.uk\nsap.com\nsapient.com\nsapo.pt\nsaramin.co.kr\nsasontnwc.net\nsaudiairlines.com\nsavefrom.net\nsaveur.com\nsavills.com\nsavingstar.com\nsberbank.ru\nsbisec.co.jp\nsbnation.com\nscarymommy.com\nscholastic.com\nschwab.com\nsciencedirect.com\nscoop.it\nscoopwhoop.com\nscotiabank.com\nscribd.com\nsdsu.edu\nsearchalgo.com\nsearchengineland.com\nsearchlock.com\nsears.com\nseasonvar.ru\nseatguru.com\nsecureinternetbank.com\nsecureserver.net\nseek.com.au\nseekingalpha.com\nseesaa.net\nselectleaders.com\nself.com\nseniorsrealestate.com\nsennheiser.com\nsephora.com\nserverfault.com\nserving-sys.com\nsesconference.com\nsetn.com\nseznam.cz\nsfgate.com\nsfr.fr\nsh.st\nshaadi.com\nshahrekhabar.com\nshangri-la.com\nshaparak.ir\nshareasale.com\nsharecare.com\nsharepoint.com\nsharpusa.com\nshasha.ps\nshermanstravel.com\nshimano.com\nshine.com\nshiseido.co.jp\nshoecarnival.com\nshop-pro.jp\nshopathome.com\nshopbop.com\nshopclues.com\nshopify.com\nshopping.com\nshoutmeloud.com\nshufoo.net\nshutterfly.com\nshutterstock.com\nsi.com\nsierratradingpost.com\nsigsauer.com\nsimilarweb.com\nsimplyrecipes.com\nsina.com.cn\nsinaimg.cn\nsindonews.com\nsiriusxm.com\nsiteadvisor.com\nsitepoint.com\nskroutz.gr\nsky.com\nskycn.com\nskype.com\nskyscanner.com\nskyscanner.net\nskysports.com\nslack.com\nslashdot.org\nslate.com\nslickdeals.net\nslideshare.net\nslidesharecdn.com\nslimspots.com\nslopeaota.com\nsmallpdf.com\nsmallseotools.com\nsmartnewtab.com\nsmartshopping.com\nsmbc-card.com\nsmh.com.au\nsmi2.ru\nsmith-wesson.com\nsmittenkitchen.com\nsmzdm.com\nsnapdeal.com\nsnopes.com\nso-net.ne.jp\nso.com\nsocialsecurity.gov\nsocietegenerale.fr\nsoftbank.jp\nsoftcare.com\nsoftonic.com\nsoftpedia.com\nsoftwarefolks.com\nsogou.com\nsohu.com\nsolarmovie.ph\nsonos.com\nsony.com\nsony.jp\nsonyentertainmentnetwork.com\nsopitas.com\nsoso.com\nsothebysrealty.com\nsou300.com\nsoundcloud.com\nsouq.com\nsourceforge.net\nsouthernliving.com\nsouthwest.com\nsozcu.com.tr\nsp.gov.br\nspaceshipads.com\nspanishdict.com\nspecialized.com\nspeedtest.net\nspicejet.com\nspiegel.de\nspine-health.com\nspirit.com\nsponichi.co.jp\nsport1.de\nsports.ru\nsportsauthority.com\nsportsdirect.com\nsportsmansguide.com\nspotify.com\nspringer.com\nspringfield-armory.com\nsprint.com\nspscommerce.com\nsputniknews.com\nsq.cn\nsquare-enix.com\nsquarespace.com\nsquaretrade.com\nsquareup.com\nsquiz.net\nsram.com\nsrilankan.com\nsrv2trking.com\nssa.gov\nssisurveys.com\nstackexchange.com\nstackoverflow.com\nstandardmedia.co.ke\nstanford.edu\nstaples.com\nstarbucks.com\nstarsports.com\nstartimes.com\nstarwoodhotels.com\nstatcounter.com\nstate.gov\nstate.tx.us\nstaticflickr.com\nstaticwebdom.com\nsteamcommunity.com\nsteampowered.com\nsterlingcommerce.com\nstjude.org\nstockstar.com\nstokke.com\nstorebuilder.co.uk\nstorefrontconsulting.com\nstraightsell.com.au\nstrava.com\nstreamcloud.eu\nstreamin.to\nstubhub.com\nstudentdoctor.net\nstudentuniverse.com\nstudy.com\nstuff.tv\nstumbleupon.com\nstyleforum.net\nsuara.com\nsubito.it\nsubmarino.com.br\nsubscene.com\nsueddeutsche.de\nsugarcrm.com\nsulekha.com\nsunbeltnetwork.com\nsuning.com\nsunset.com\nsuntrust.com\nsuper.cz\nsuperuser.com\nsurplusglobal.com\nsuruga-ya.jp\nsurveymonkey.com\nsutterhealth.org\nsuumo.jp\nsuunto.com\nsvmsolutions.com\nswagbucks.com\nswarovski.com\nswatch.com\nsweetwater.com\nswiss.com\nsynchronycredit.com\nsyosetu.com\nszn.cz\nsznews.com\nt-mobile.com\nt-online.de\nt.co\nt411.in\ntabelog.com\ntabnak.ir\ntaboola.com\ntagged.com\ntagheuer.com\ntagonline.com\ntahrirnews.com\ntaimienphi.vn\ntakungpao.com\ntaleo.net\ntalk.tw\ntamiya.com\ntaobao.com\ntarget.com\ntaringa.net\ntarladalal.com\ntasify.com\ntattoodo.com\ntaxact.com\ntd.com\ntdbank.com\nteacherspayteachers.com\nteamviewer.com\ntebyan.net\ntechbang.com\ntechcrunch.com\ntechindia.com\ntechradar.com\ntechtarget.com\ntechtudo.com.br\nted.com\nteepr.com\ntelegraaf.nl\ntelegraf.com.ua\ntelegrafi.com\ntelegram.me\ntelegram.org\ntelegraph.co.uk\ntelekom.com\ntemplatemonster.com\ntempo.co\ntenki.jp\nterra.com.br\nterraclicks.com\ntesco.com\ntf1.fr\ntgbus.com\nthaiairways.com\ntheatlantic.com\ntheblaze.com\nthechive.com\nthedailybeast.com\nthefreedictionary.com\ntheguardian.com\nthehill.com\nthehindu.com\nthekitchn.com\nthekrazycouponlady.com\ntheladbible.com\nthelancet.com\nthemeforest.net\nthemoneyconverter.com\nthemovechannel.com\nthenextweb.com\nthenorthface.com\ntheonion.com\nthepennyhoarder.com\nthepiratebay.se\nthesaurus.com\nthesimpledollar.com\nthesportbible.com\nthestreet.com\ntheverge.com\nthevideo.me\nthewatchseries.to\ntheweathernetwork.com\nthewhizmarketing.com\nthisav.com\nthomascook.com\nthriftyfun.com\nthrillist.com\ntianya.cn\nticketmaster.com\nticketmonster.co.kr\ntigerdirect.com\ntilestwra.com\ntim.it\ntimberland.com\ntime.com\ntimeanddate.com\ntimeout.com\ntimewarnercable.com\ntinypic.com\ntirerack.com\ntiscali.it\ntistory.com\ntitleonecorp.com\ntiu.ru\ntlbb8.com\ntmall.com\ntmz.com\nto8to.com\ntoday.com\ntodayhumor.co.kr\ntogetter.com\ntokopedia.com\ntomsguide.com\ntomshardware.com\ntomtop.com\ntonyrobbins.com\ntop10homeremedies.com\ntopix.com\ntoptenreviews.com\ntoranoana.jp\ntorcache.net\ntorrentkim1.net\ntorrentz.com\ntorrentz.eu\ntorrentz.in\ntoshiba.com\ntotalbeauty.com\ntourfactory.com\ntoyokeizai.net\ntoysrus.com\ntpmco.com\ntrackingclick.net\ntrackvoluum.com\ntradeadexchange.com\ntradedoubler.com\ntrademe.co.nz\ntraffichunt.com\ntrafficmonsoon.com\ntrafficserving.com\ntraidnt.net\ntravelandleisure.com\ntravelocity.com\ntravelzoo.com\ntraxxas.com\ntreasury.gov\ntrekbikes.com\ntrello.com\ntribunnews.com\ntrinityinsight.com\ntripadvisor.co.uk\ntripadvisor.com\ntripadvisor.in\ntriseptsolutions.com\ntriumph.com\ntrklnks.com\ntrkute.com\ntruecaller.com\ntrulia.com\ntruste.com\ntrustpilot.com\ntsite.jp\ntubepatrol.net\ntudou.com\ntumblr.com\ntums.ac.ir\ntunein.com\nturbobit.net\nturkishairlines.com\ntut.by\ntutorialspoint.com\ntutsplus.com\ntv.com\ntvguide.com\ntvn24.pl\ntwimg.com\ntwitch.tv\ntwitter.com\ntwoo.com\ntxxx.com\ntypepad.com\nuber.com\nubergizmo.com\nubi.com\nubuntu.com\nucla.edu\nucoz.ru\nudacity.com\nudemy.com\nudn.com\nukr.net\nulmart.ru\nulta.com\nultimate-guitar.com\numblr.com\numich.edu\nunam.mx\nunblocked.li\nunderarmour.com\nunicredit.it\nunikron.com\nunilever.com\nuniqlo.com\nuniquehomes.com\nunited.com\nunity3d.com\nuol.com.br\nuploaded.net\nupmc.com\nupornia.com\nuproxx.com\nups.com\nuptobox.com\nuptodown.com\nupwork.com\nurbandictionary.com\nurbanoutfitters.com\nurdupoint.com\nusaa.com\nusatoday.com\nusbank.com\nuserscloud.com\nusmagazine.com\nusnews.com\nusps.com\nustream.tv\nutexas.edu\nutorrent.com\nuzone.id\nv1.cn\nvacationstogo.com\nvagalume.com.br\nvaned.com\nvanguard.com\nvariety.com\nvarzesh3.com\nvcommission.com\nvector.co.jp\nvegas.com\nvegrecipesofindia.com\nvendormanagedinventory.com\nvenere.com\nvente-privee.com\nventuread.com\nverizon.com\nverizonwireless.com\nvesti.ru\nvetogate.com\nvg.no\nviamichelin.com\nvice.com\nvictoriassecret.com\nvid.me\nvideodownloadconverter.com\nvideomega.tv\nvideoyoum7.com\nvidto.me\nvidzi.tv\nvikingrivercruises.com\nvimeo.com\nvine.co\nvip.com\nviralands.com\nviralthread.com\nvirgilio.it\nvirgin-atlantic.com\nvirginaustralia.com\nvirginmedia.com\nvirtualtourist.com\nvisahq.com\nvistaprint.com\nvisualtour.com\nvitacost.com\nvitals.com\nvitamix.com\nviva.co.id\nviviun.com\nvk.com\nvk.me\nvmware.com\nvnexpress.net\nvoc.com.cn\nvodafone.in\nvodlocker.com\nvoluumtrk.com\nvox.com\nvrbo.com\nvsuch.com\nvulture.com\nw3.org\nw3schools.com\nwalgreens.com\nwalmart.com\nwanyh.com\nwargaming.net\nwarmportrait.com\nwarriorforum.com\nwashington.edu\nwashingtonpost.com\nwatchfree.to\nwatchseries.li\nwattpad.com\nwav.tv\nway2sms.com\nwayfair.com\nwbresearch.com\nwcr.org\nweather.com\nweather.com.cn\nweather.gov\nweathernews.jp\nweb.de\nwebcrawler.com\nweber.com\nwebex.com\nwebjaguar.com\nwebkinz.com\nweblio.jp\nwebmd.com\nwebmoney.ru\nwebmonkey.com\nwebpro.com\nwebssearches.com\nwebsta.me\nwebtretho.com\nweebly.com\nweheartit.com\nweibo.com\nweightwatchers.com\nwellness.com\nwellsfargo.com\nwelt.de\nwestelm.com\nwesternjournalism.com\nwestjet.com\nwestmonroepartners.com\nwetalk.tw\nwetransfer.com\nwetter.com\nwgsn.com\nwhat-character-are-you.com\nwhatsapp.com\nwhfoods.com\nwhirlpool.com\nwhitecapcanada.com\nwhitepages.com\nwho.int\nwho.is\nwholesalesuppliesplus.com\nwikia.com\nwikihow.com\nwikimedia.org\nwikipedia.org\nwikispaces.com\nwikitravel.org\nwikivoyage.org\nwikiwiki.jp\nwiktionary.org\nwildberries.ru\nwiley.com\nwilliamhill.com\nwilliams-sonoma.com\nwindows.com\nwindows.net\nwingtaiasia.com.sg\nwiocha.pl\nwipro.com\nwired.com\nwisc.edu\nwish.com\nwitiger.com\nwittyfeed.com\nwix.com\nwmaraci.com\nwmpoweruser.com\nwnd.com\nwolframalpha.com\nwoot.com\nwordpress.com\nwordpress.org\nwordreference.com\nworkercn.cn\nworkingre.com\nworldfirst.com\nworldlifestyle.com\nworldmarket.com\nworldoftanks.ru\nworldstarhiphop.com\nworldweb.com\nworldwise.net\nwotif.com\nwowhead.com\nwp.com\nwp.pl\nwpbeginner.com\nwsj.com\nwunderground.com\nwunderlist.com\nwuxiaworld.com\nwwe.com\nwww.gov.uk\nwww.nhs.uk\nwyborcza.pl\nwyndham.com\nx-rates.com\nxbox.com\nxda-developers.com\nxe.com\nxerox.com\nxfinity.com\nxiami.com\nxiaomi.com\nxing.com\nxinhuanet.com\nxkcd.com\nxl415.com\nxmediaserve.com\nxn--igbhe7b5a3d5a.com\nxoriant.com\nxuite.net\nxunlei.com\nxywy.com\ny8.com\nyadi.sk\nyahoo-mbga.jp\nyahoo.co.jp\nyahoo.com\nyallakora.com\nyam.com\nyandex.by\nyandex.com\nyandex.com.tr\nyandex.kz\nyandex.ru\nyandex.ua\nyaolan.com\nyaplakal.com\nyaraon-blog.com\nyellowpages.com\nyelp.com\nyenisafak.com\nyesky.com\nyhd.com\nyjc.ir\nynet.co.il\nyodobashi.com\nyomiuri.co.jp\nyoo.com\nyoox.com\nyouboy.com\nyoudao.com\nyouku.com\nyoum7.com\nyouneedabudget.com\nyouradexchange.com\nyourdictionary.com\nyouth.cn\nyoutube-mp3.org\nyoutube.com\nyr.no\nytimg.com\nyts.ag\nzalando.de\nzalukaj.tv\nzaman.com.tr\nzappos.com\nzara.com\nzazzle.com\nzdf.de\nzdnet.com\nzedo.com\nzeit.de\nzendesk.com\nzergnet.com\nzerohedge.com\nzeroredirect1.com\nzhaopin.com\nzhihu.com\nzillow.com\nzimbio.com\nzimuzu.tv\nzing.vn\nzippyshare.com\nzocdoc.com\nzoho.com\nzol.com.cn\nzomato.com\nzone-telechargement.com\nzoopla.co.uk\nzougla.gr\nzozo.jp\nzulily.com\nzwaar.net\nzybang.com\n".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-trim().split("\n"));
deleted file mode 100644
--- a/browser/extensions/loop/chrome/content/modules/LoopRooms.jsm
+++ /dev/null
@@ -1,1268 +0,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/. */
-"use strict";var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();function _toConsumableArray(arr) {if (Array.isArray(arr)) {for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {arr2[i] = arr[i];}return arr2;} else {return Array.from(arr);}}var _Components = 
-
-Components;var Cu = _Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/Timer.jsm");var _Cu$import = 
-
-Cu.import("chrome://loop/content/modules/MozLoopService.jsm", {});var MozLoopService = _Cu$import.MozLoopService;var LOOP_SESSION_TYPE = _Cu$import.LOOP_SESSION_TYPE;
-XPCOMUtils.defineLazyModuleGetter(this, "Promise", 
-"resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", 
-"resource://services-common/utils.js");
-XPCOMUtils.defineLazyModuleGetter(this, "WebChannel", 
-"resource://gre/modules/WebChannel.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "eventEmitter", function () {var _Cu$import2 = 
-  Cu.import("resource://devtools/shared/event-emitter.js", {});var EventEmitter = _Cu$import2.EventEmitter;
-  return new EventEmitter();});
-
-
-XPCOMUtils.defineLazyModuleGetter(this, "DomainWhitelist", 
-"chrome://loop/content/modules/DomainWhitelist.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "LoopRoomsCache", 
-"chrome://loop/content/modules/LoopRoomsCache.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "loopUtils", 
-"chrome://loop/content/modules/utils.js", "utils");
-XPCOMUtils.defineLazyModuleGetter(this, "loopCrypto", 
-"chrome://loop/content/shared/js/crypto.js", "LoopCrypto");
-XPCOMUtils.defineLazyModuleGetter(this, "ObjectUtils", 
-"resource://gre/modules/ObjectUtils.jsm");
-
-/* exported LoopRooms, roomsPushNotification */
-
-this.EXPORTED_SYMBOLS = ["LoopRooms", "roomsPushNotification"];
-
-// The maximum number of clients that we support currently.
-var CLIENT_MAX_SIZE = 2;
-
-// Wait at least 5 seconds before doing opportunistic encryption.
-var MIN_TIME_BEFORE_ENCRYPTION = 5 * 1000;
-// Wait at maximum of 30 minutes before doing opportunistic encryption.
-var MAX_TIME_BEFORE_ENCRYPTION = 30 * 60 * 1000;
-// Wait time between individual re-encryption cycles (1 second).
-var TIME_BETWEEN_ENCRYPTIONS = 1000;
-
-// This is the pref name for the url of the standalone pages.
-var LINKCLICKER_URL_PREFNAME = "loop.linkClicker.url";
-
-var roomsPushNotification = function roomsPushNotification(version, channelID) {
-  return LoopRoomsInternal.onNotification(version, channelID);};
-
-
-// Since the LoopRoomsInternal.rooms map as defined below is a local cache of
-// room objects that are retrieved from the server, this is list may become out
-// of date. The Push server may notify us of this event, which will set the global
-// 'dirty' flag to TRUE.
-var gDirty = true;
-// Global variable that keeps track of the currently used account.
-var gCurrentUser = null;
-// Global variable that keeps track of the room cache.
-var gRoomsCache = null;
-// Global variable that keeps track of the link clicker channel.
-var gLinkClickerChannel = null;
-// Global variable that keeps track of in-progress getAll requests.
-var gGetAllPromise = null;
-
-/**
- * Extend a `target` object with the properties defined in `source`.
- *
- * @param {Object} target The target object to receive properties defined in `source`
- * @param {Object} source The source object to copy properties from
- */
-var extend = function extend(target, source) {var _iteratorNormalCompletion = true;var _didIteratorError = false;var _iteratorError = undefined;try {
-    for (var _iterator = Object.getOwnPropertyNames(source)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var key = _step.value;
-      target[key] = source[key];}} catch (err) {_didIteratorError = true;_iteratorError = err;} finally {try {if (!_iteratorNormalCompletion && _iterator.return) {_iterator.return();}} finally {if (_didIteratorError) {throw _iteratorError;}}}
-
-  return target;};
-
-
-/**
- * Checks whether a participant is already part of a room.
- *
- * @see https://wiki.mozilla.org/Loop/Architecture/Rooms#User_Identification_in_a_Room
- *
- * @param {Object} room        A room object that contains a list of current participants
- * @param {Object} participant Participant to check if it's already there
- * @returns {Boolean} TRUE when the participant is already a member of the room,
- *                    FALSE when it's not.
- */
-var containsParticipant = function containsParticipant(room, participant) {var _iteratorNormalCompletion2 = true;var _didIteratorError2 = false;var _iteratorError2 = undefined;try {
-    for (var _iterator2 = room.participants[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {var user = _step2.value;
-      if (user.roomConnectionId == participant.roomConnectionId) {
-        return true;}}} catch (err) {_didIteratorError2 = true;_iteratorError2 = err;} finally {try {if (!_iteratorNormalCompletion2 && _iterator2.return) {_iterator2.return();}} finally {if (_didIteratorError2) {throw _iteratorError2;}}}
-
-
-  return false;};
-
-
-/**
- * Compares the list of participants of the room currently in the cache and an
- * updated version of that room. When a new participant is found, the 'joined'
- * event is emitted. When a participant is not found in the update, it emits a
- * 'left' event.
- *
- * @param {Object} room        A room object to compare the participants list
- *                             against
- * @param {Object} updatedRoom A room object that contains the most up-to-date
- *                             list of participants
- */
-var checkForParticipantsUpdate = function checkForParticipantsUpdate(room, updatedRoom) {
-  // Partially fetched rooms don't contain the participants list yet. Skip the
-  // check for now.
-  if (!("participants" in room)) {
-    return;}
-
-
-  var participant = void 0;
-  // Check for participants that joined.
-  var _iteratorNormalCompletion3 = true;var _didIteratorError3 = false;var _iteratorError3 = undefined;try {for (var _iterator3 = updatedRoom.participants[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {participant = _step3.value;
-      if (!containsParticipant(room, participant)) {
-        eventEmitter.emit("joined", room, participant);
-        eventEmitter.emit("joined:" + room.roomToken, participant);}}
-
-
-
-    // Check for participants that left.
-  } catch (err) {_didIteratorError3 = true;_iteratorError3 = err;} finally {try {if (!_iteratorNormalCompletion3 && _iterator3.return) {_iterator3.return();}} finally {if (_didIteratorError3) {throw _iteratorError3;}}}var _iteratorNormalCompletion4 = true;var _didIteratorError4 = false;var _iteratorError4 = undefined;try {for (var _iterator4 = room.participants[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {participant = _step4.value;
-      if (!containsParticipant(updatedRoom, participant)) {
-        eventEmitter.emit("left", room, participant);
-        eventEmitter.emit("left:" + room.roomToken, participant);}}} catch (err) {_didIteratorError4 = true;_iteratorError4 = err;} finally {try {if (!_iteratorNormalCompletion4 && _iterator4.return) {_iterator4.return();}} finally {if (_didIteratorError4) {throw _iteratorError4;}}}};
-
-
-
-
-/**
- * These are wrappers which can be overriden by tests to allow us to manually
- * handle the timeouts.
- */
-var timerHandlers = { 
-  /**
-   * Wrapper for setTimeout.
-   *
-   * @param  {Function} callback The callback function.
-   * @param  {Number}   delay    The delay in milliseconds.
-   * @return {Number}            The timer identifier.
-   */
-  startTimer: function startTimer(callback, delay) {
-    return setTimeout(callback, delay);} };
-
-
-
-/**
- * The Rooms class.
- *
- * Each method that is a member of this class requires the last argument to be a
- * callback Function. MozLoopAPI will cause things to break if this invariant is
- * violated. You'll notice this as well in the documentation for each method.
- */
-var LoopRoomsInternal = { 
-  /**
-   * @var {Map} rooms Collection of rooms currently in cache.
-   */
-  rooms: new Map(), 
-
-  get roomsCache() {
-    if (!gRoomsCache) {
-      gRoomsCache = new LoopRoomsCache();}
-
-    return gRoomsCache;}, 
-
-
-  /**
-   * @var {Object} encryptionQueue  This stores the list of rooms awaiting
-   *                                encryption and associated timers.
-   */
-  encryptionQueue: { 
-    queue: [], 
-    timer: null, 
-    reset: function reset() {
-      this.queue = [];
-      this.timer = null;} }, 
-
-
-
-  /**
-   * Initialises the rooms, sets up the link clicker listener.
-   */
-  init: function init() {
-    Services.prefs.addObserver(LINKCLICKER_URL_PREFNAME, 
-    this.setupLinkClickerListener.bind(this), false);
-
-    this.setupLinkClickerListener();}, 
-
-
-  /**
-   * Sets up a WebChannel listener for the link clicker so that we can open
-   * rooms in the Firefox UI.
-   */
-  setupLinkClickerListener: function setupLinkClickerListener() {
-    // Ensure any existing channel is tidied up.
-    if (gLinkClickerChannel) {
-      gLinkClickerChannel.stopListening();
-      gLinkClickerChannel = null;}
-
-
-    var linkClickerUrl = Services.prefs.getCharPref(LINKCLICKER_URL_PREFNAME);
-
-    // Don't do anything if there's no url.
-    if (!linkClickerUrl) {
-      return;}
-
-
-    var uri = Services.io.newURI(linkClickerUrl, null, null);
-
-    gLinkClickerChannel = new WebChannel("loop-link-clicker", uri);
-    gLinkClickerChannel.listen(this._handleLinkClickerMessage.bind(this));}, 
-
-
-  /**
-   * @var {String} sessionType The type of user session. May be 'FXA' or 'GUEST'.
-   */
-  get sessionType() {
-    return MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA : 
-    LOOP_SESSION_TYPE.GUEST;}, 
-
-
-  /**
-   * @var {Number} participantsCount The total amount of participants currently
-   *                                 inside all rooms.
-   */
-  get participantsCount() {
-    var count = 0;var _iteratorNormalCompletion5 = true;var _didIteratorError5 = false;var _iteratorError5 = undefined;try {
-      for (var _iterator5 = this.rooms.values()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {var room = _step5.value;
-        if (room.deleted || !("participants" in room)) {
-          continue;}
-
-        count += room.participants.length;}} catch (err) {_didIteratorError5 = true;_iteratorError5 = err;} finally {try {if (!_iteratorNormalCompletion5 && _iterator5.return) {_iterator5.return();}} finally {if (_didIteratorError5) {throw _iteratorError5;}}}
-
-    return count;}, 
-
-
-  /**
-   * Processes the encryption queue. Takes the next item off the queue,
-   * restarts the timer if necessary.
-   *
-   * Although this is only called from a timer callback, it is an async function
-   * so that tests can call it and be deterministic.
-   */
-  processEncryptionQueue: Task.async(function* () {
-    var roomToken = this.encryptionQueue.queue.shift();
-
-    // Performed in sync fashion so that we don't queue a timer until it has
-    // completed, and to make it easier to run tests.
-    var roomData = this.rooms.get(roomToken);
-
-    if (roomData) {
-      try {
-        // Passing the empty object for roomData is enough for the room to be
-        // re-encrypted.
-        yield LoopRooms.promise("update", roomToken, {});} 
-      catch (error) {
-        MozLoopService.log.error("Upgrade encryption of room failed", error);
-        // No need to remove the room from the list as that's done in the shift above.
-      }}
-
-
-    if (this.encryptionQueue.queue.length) {
-      this.encryptionQueue.timer = 
-      timerHandlers.startTimer(this.processEncryptionQueue.bind(this), TIME_BETWEEN_ENCRYPTIONS);} else 
-    {
-      this.encryptionQueue.timer = null;}}), 
-
-
-
-  /**
-   * Queues a room for encryption sometime in the future. This is done so as
-   * not to overload the server or the browser when we initially request the
-   * list of rooms.
-   *
-   * @param {String} roomToken The token for the room that needs encrypting.
-   */
-  queueForEncryption: function queueForEncryption(roomToken) {
-    if (this.encryptionQueue.queue.indexOf(roomToken) == -1) {
-      this.encryptionQueue.queue.push(roomToken);}
-
-
-    // Set up encryption to happen at a random time later. There's a minimum
-    // wait time - we don't need to do this straight away, so no need if the user
-    // is starting up. We then add a random factor on top of that. This is to
-    // try and avoid any potential with a set of clients being restarted at the
-    // same time and flooding the server.
-    if (!this.encryptionQueue.timer) {
-      var waitTime = (MAX_TIME_BEFORE_ENCRYPTION - MIN_TIME_BEFORE_ENCRYPTION) * 
-      Math.random() + MIN_TIME_BEFORE_ENCRYPTION;
-      this.encryptionQueue.timer = 
-      timerHandlers.startTimer(this.processEncryptionQueue.bind(this), waitTime);}}, 
-
-
-
-  /**
-   * Gets or creates a room key for a room.
-   *
-   * It assumes that the room data is decrypted.
-   *
-   * @param {Object} roomData The roomData to get the key for.
-   * @return {Promise} A promise that is resolved whith the room key.
-   */
-  promiseGetOrCreateRoomKey: Task.async(function* (roomData) {
-    if (roomData.roomKey) {
-      return roomData.roomKey;}
-
-
-    return yield loopCrypto.generateKey();}), 
-
-
-  /**
-   * Encrypts a room key for sending to the server using the profile encryption
-   * key.
-   *
-   * @param {String} key The JSON web key to encrypt.
-   * @return {Promise} A promise that is resolved with the encrypted room key.
-   */
-  promiseEncryptedRoomKey: Task.async(function* (key) {
-    var profileKey = yield MozLoopService.promiseProfileEncryptionKey();
-
-    var encryptedRoomKey = yield loopCrypto.encryptBytes(profileKey, key);
-    return encryptedRoomKey;}), 
-
-
-  /**
-   * Decryptes a room key from the server using the profile encryption key.
-   *
-   * @param  {String} encryptedKey The room key to decrypt.
-   * @return {Promise} A promise that is resolved with the decrypted room key.
-   */
-  promiseDecryptRoomKey: Task.async(function* (encryptedKey) {
-    var profileKey = yield MozLoopService.promiseProfileEncryptionKey();
-
-    var decryptedRoomKey = yield loopCrypto.decryptBytes(profileKey, encryptedKey);
-    return decryptedRoomKey;}), 
-
-
-  /**
-   * Updates a roomUrl to add a new key onto the end of the url.
-   *
-   * @param  {String} roomUrl The existing url that may or may not have a key
-   *                          on the end.
-   * @param  {String} roomKey The new key to put on the url.
-   * @return {String}         The revised url.
-   */
-  refreshRoomUrlWithNewKey: function refreshRoomUrlWithNewKey(roomUrl, roomKey) {
-    // Strip any existing key from the url.
-    roomUrl = roomUrl.split("#")[0];
-    // Now add the key to the url.
-    return roomUrl + "#" + roomKey;}, 
-
-
-  /**
-   * Encrypts room data in a format appropriate to sending to the loop
-   * server.
-   *
-   * @param  {Object} roomData The room data to encrypt.
-   * @return {Promise} A promise that is resolved with an object containing
-   *                   two objects:
-   *                   - encrypted: The encrypted data to send. This excludes
-   *                                any decrypted data.
-   *                   - all: The roomData with both encrypted and decrypted
-   *                          information.
-   *                   If rejected, encryption has failed. This could be due to
-   *                   missing keys for FxA, which this process can't manage. It
-   *                   is generally expected the panel will prompt the user for
-   *                   re-auth if the FxA keys are missing.
-   */
-  promiseEncryptRoomData: Task.async(function* (roomData) {
-    var newRoomData = extend({}, roomData);
-
-    if (!newRoomData.context) {
-      newRoomData.context = {};}
-
-
-    // First get the room key.
-    var key = yield this.promiseGetOrCreateRoomKey(newRoomData);
-
-    newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key);
-
-    // Now encrypt the actual data.
-    newRoomData.context.value = yield loopCrypto.encryptBytes(key, 
-    JSON.stringify(newRoomData.decryptedContext));
-
-    // The algorithm is currently hard-coded as AES-GCM, in case of future
-    // changes.
-    newRoomData.context.alg = "AES-GCM";
-    newRoomData.roomKey = key;
-
-    var serverRoomData = extend({}, newRoomData);
-
-    // We must not send these items to the server.
-    delete serverRoomData.decryptedContext;
-    delete serverRoomData.roomKey;
-
-    return { 
-      encrypted: serverRoomData, 
-      all: newRoomData };}), 
-
-
-
-  /**
-   * Decrypts room data recevied from the server.
-   *
-   * @param  {Object} roomData The roomData with encrypted context.
-   * @return {Promise} A promise that is resolved with the decrypted room data.
-   */
-  promiseDecryptRoomData: Task.async(function* (roomData) {
-    if (!roomData.context) {
-      return roomData;}
-
-
-    if (!roomData.context.wrappedKey) {
-      throw new Error("Missing wrappedKey");}
-
-
-    var savedRoomKey = yield this.roomsCache.getKey(this.sessionType, roomData.roomToken);
-    var fallback = false;
-    var key = void 0;
-
-    try {
-      key = yield this.promiseDecryptRoomKey(roomData.context.wrappedKey);} 
-    catch (error) {
-      // If we don't have a key saved, then we can't do anything.
-      if (!savedRoomKey) {
-        throw error;}
-
-
-      // We failed to decrypt the room key, so has our FxA key changed?
-      // If so, we fall-back to the saved room key.
-      key = savedRoomKey;
-      fallback = true;}
-
-
-    var decryptedData = yield loopCrypto.decryptBytes(key, roomData.context.value);
-
-    if (fallback) {
-      // Fallback decryption succeeded, so we need to re-encrypt the room key and
-      // save the data back again.
-      MozLoopService.log.debug("Fell back to saved key, queuing for encryption", 
-      roomData.roomToken);
-      this.queueForEncryption(roomData.roomToken);} else 
-    if (!savedRoomKey || key != savedRoomKey) {
-      // Decryption succeeded, but we don't have the right key saved.
-      try {
-        yield this.roomsCache.setKey(this.sessionType, roomData.roomToken, key);} 
-
-      catch (error) {
-        MozLoopService.log.error("Failed to save room key:", error);}}
-
-
-
-    roomData.roomKey = key;
-    roomData.decryptedContext = JSON.parse(decryptedData);
-
-    roomData.roomUrl = this.refreshRoomUrlWithNewKey(roomData.roomUrl, roomData.roomKey);
-
-    return roomData;}), 
-
-
-  /**
-   * Saves room information and notifies updates to any listeners.
-   *
-   * @param {Object}  roomData The new room data to save.
-   * @param {Boolean} isUpdate true if this is an update, false if its an add.
-   */
-  saveAndNotifyUpdate: function saveAndNotifyUpdate(roomData, isUpdate) {
-    this.rooms.set(roomData.roomToken, roomData);
-
-    var eventName = isUpdate ? "update" : "add";
-    eventEmitter.emit(eventName, roomData);
-    eventEmitter.emit(eventName + ":" + roomData.roomToken, roomData);}, 
-
-
-  /**
-   * Either adds or updates the room to the room store and notifies to any
-   * listeners.
-   *
-   * This will decrypt information if necessary, and adjust for the legacy
-   * "roomName" field.
-   *
-   * @param {Object}  room     The new room to add.
-   * @param {Boolean} isUpdate true if this is an update to an existing room.
-   */
-  addOrUpdateRoom: Task.async(function* (room, isUpdate) {
-    if (!room.context) {
-      // We don't do anything with roomUrl here as it doesn't need a key
-      // string adding at this stage.
-
-      // No encrypted data yet, use the old roomName field.
-      room.decryptedContext = { 
-        roomName: room.roomName };
-
-      delete room.roomName;
-
-      // This room doesn't have context, so we'll save it for a later encryption
-      // cycle.
-      this.queueForEncryption(room.roomToken);
-
-      this.saveAndNotifyUpdate(room, isUpdate);} else 
-    {
-      // We could potentially optimise this later by not decrypting if the
-      // encrypted context hasn't already changed. However perf doesn't seem
-      // to be too bigger an issue at the moment, so we just decrypt for now.
-      // If we do change this, then we need to make sure we get the new room
-      // data setup properly, as happens at the end of promiseDecryptRoomData.
-      try {
-        var roomData = yield this.promiseDecryptRoomData(room);
-
-        this.saveAndNotifyUpdate(roomData, isUpdate);} 
-      catch (error) {
-        MozLoopService.log.error("Failed to decrypt room data: ", error);
-        // Do what we can to save the room data.
-        room.decryptedContext = {};
-        this.saveAndNotifyUpdate(room, isUpdate);}}}), 
-
-
-
-
-  /**
-   * Fetch a list of rooms that the currently registered user is a member of.
-   *
-   * @param {String}   [version] If set, we will fetch a list of changed rooms since
-   *                             `version`. Optional.
-   * @return {Promise}           A promise that is resolved with a list of rooms
-   *                             on success, or rejected with an error if it fails.
-   */
-  getAll: function getAll(version) {
-    if (gGetAllPromise && !version) {
-      return gGetAllPromise;}
-
-
-    if (!gDirty) {
-      return Promise.resolve([].concat(_toConsumableArray(this.rooms.values())));}
-
-
-    gGetAllPromise = Task.spawn(function* () {
-      // Fetch the rooms from the server.
-      var url = "/rooms" + (version ? "?version=" + encodeURIComponent(version) : "");
-      var response = yield MozLoopService.hawkRequest(this.sessionType, url, "GET");
-      var roomsList = JSON.parse(response.body);
-      if (!Array.isArray(roomsList)) {
-        throw new Error("Missing array of rooms in response.");}var _iteratorNormalCompletion6 = true;var _didIteratorError6 = false;var _iteratorError6 = undefined;try {
-
-
-        for (var _iterator6 = roomsList[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {var room = _step6.value;
-          // See if we already have this room in our cache.
-          var orig = this.rooms.get(room.roomToken);
-
-          if (room.deleted) {
-            // If this client deleted the room, then we'll already have
-            // deleted the room in the function below.
-            if (orig) {
-              this.rooms.delete(room.roomToken);}
-
-
-            eventEmitter.emit("delete", room);
-            eventEmitter.emit("delete:" + room.roomToken, room);} else 
-          {
-            yield this.addOrUpdateRoom(room, !!orig);
-
-            if (orig) {
-              checkForParticipantsUpdate(orig, room);}}}
-
-
-
-
-        // If there's no rooms in the list, remove the guest created room flag, so that
-        // we don't keep registering for guest when we don't need to.
-      } catch (err) {_didIteratorError6 = true;_iteratorError6 = err;} finally {try {if (!_iteratorNormalCompletion6 && _iterator6.return) {_iterator6.return();}} finally {if (_didIteratorError6) {throw _iteratorError6;}}}if (this.sessionType == LOOP_SESSION_TYPE.GUEST && !this.rooms.size) {
-        this.setGuestCreatedRoom(false);}
-
-
-      // Set the 'dirty' flag back to FALSE, since the list is as fresh as can be now.
-      gDirty = false;
-      gGetAllPromise = null;
-      return [].concat(_toConsumableArray(this.rooms.values()));}.
-    bind(this)).catch(function (error) {
-      gGetAllPromise = null;
-      // Re-throw error so callers get notified.
-      throw error;});
-
-
-    return gGetAllPromise;}, 
-
-
-  /**
-   * Request information about number of participants joined to a specific room from the server.
-   * Used to determine infobar message state on the number of participants in the room.
-   *
-   * @param {String}  roomToken Room identifier
-   * @return {Number} Count of participants in the room.
-   */
-  getNumParticipants: function getNumParticipants(roomToken) {
-    try {
-      if (this.rooms && this.rooms.has(roomToken)) {
-        return this.rooms.get(roomToken).participants.length;}
-
-      return 0;} 
-
-    catch (ex) {
-      // No room, log error and send back 0 to indicate none in room.
-      MozLoopService.log.error("No room found in current session: ", ex);
-      return 0;}}, 
-
-
-
-  /**
-   * Request information about a specific room from the server. It will be
-   * returned from the cache if it's already in it.
-   *
-   * @param {String}   roomToken Room identifier
-   * @param {Function} callback  Function that will be invoked once the operation
-   *                             finished. The first argument passed will be an
-   *                             `Error` object or `null`. The second argument will
-   *                             be the list of rooms, if it was fetched successfully.
-   */
-  get: function get(roomToken, callback) {
-    var room = this.rooms.has(roomToken) ? this.rooms.get(roomToken) : {};
-    // Check if we need to make a request to the server to collect more room data.
-    var needsUpdate = !("participants" in room);
-    if (!gDirty && !needsUpdate) {
-      // Dirty flag is not set AND the necessary data is available, so we can
-      // simply return the room.
-      callback(null, room);
-      return;}
-
-
-    Task.spawn(function* () {
-      var response = yield MozLoopService.hawkRequest(this.sessionType, 
-      "/rooms/" + encodeURIComponent(roomToken), "GET");
-
-      var data = JSON.parse(response.body);
-
-      room.roomToken = roomToken;
-
-      if (data.deleted) {
-        this.rooms.delete(room.roomToken);
-
-        extend(room, data);
-        eventEmitter.emit("delete", room);
-        eventEmitter.emit("delete:" + room.roomToken, room);} else 
-      {
-        yield this.addOrUpdateRoom(data, !needsUpdate);
-
-        checkForParticipantsUpdate(room, data);}
-
-      callback(null, room);}.
-    bind(this)).catch(callback);}, 
-
-
-  /**
-   * Create a room.
-   *
-   * @param {Object}   room     Properties to be sent to the LoopServer
-   * @param {Function} callback Function that will be invoked once the operation
-   *                            finished. The first argument passed will be an
-   *                            `Error` object or `null`. The second argument will
-   *                            be the room, if it was created successfully.
-   */
-  create: function create(room, callback) {
-    if (!("decryptedContext" in room) || !("maxSize" in room)) {
-      callback(new Error("Missing required property to create a room"));
-      return;}
-
-
-    if (!("roomOwner" in room)) {
-      room.roomOwner = "-";}
-
-
-    Task.spawn(function* () {var _ref = 
-      yield this.promiseEncryptRoomData(room);var all = _ref.all;var encrypted = _ref.encrypted;
-
-      // Save both sets of data...
-      room = all;
-      // ...but only send the encrypted data.
-      var response = yield MozLoopService.hawkRequest(this.sessionType, "/rooms", 
-      "POST", encrypted);
-
-      extend(room, JSON.parse(response.body));
-      // Do not keep this value - it is a request to the server.
-      delete room.expiresIn;
-      // Make sure the url has the key on it.
-      room.roomUrl = this.refreshRoomUrlWithNewKey(room.roomUrl, room.roomKey);
-      this.rooms.set(room.roomToken, room);
-
-      if (this.sessionType == LOOP_SESSION_TYPE.GUEST) {
-        this.setGuestCreatedRoom(true);}
-
-
-      // Now we've got the room token, we can save the key to disk.
-      yield this.roomsCache.setKey(this.sessionType, room.roomToken, room.roomKey);
-
-      eventEmitter.emit("add", room);
-      callback(null, room);}.
-    bind(this)).catch(callback);}, 
-
-
-  /**
-   * Sets whether or not the user has created a room in guest mode.
-   *
-   * @param {Boolean} created If the user has created the room.
-   */
-  setGuestCreatedRoom: function setGuestCreatedRoom(created) {
-    if (created) {
-      Services.prefs.setBoolPref("loop.createdRoom", created);} else 
-    {
-      Services.prefs.clearUserPref("loop.createdRoom");}}, 
-
-
-
-  /**
-   * Returns true if the user has a created room in guest mode.
-   */
-  getGuestCreatedRoom: function getGuestCreatedRoom() {
-    try {
-      return Services.prefs.getBoolPref("loop.createdRoom");} 
-    catch (x) {
-      return false;}}, 
-
-
-
-  open: function open(roomToken) {
-    var windowData = { 
-      roomToken: roomToken, 
-      type: "room" };
-
-
-    eventEmitter.emit("open", roomToken);
-
-    return MozLoopService.openChatWindow(windowData, function () {
-      eventEmitter.emit("close");});}, 
-
-
-
-  /**
-   * Deletes a room.
-   *
-   * @param {String}   roomToken The room token.
-   * @param {Function} callback  Function that will be invoked once the operation
-   *                             finished. The first argument passed will be an
-   *                             `Error` object or `null`.
-   */
-  delete: function _delete(roomToken, callback) {var _this = this;
-    // XXX bug 1092954: Before deleting a room, the client should check room
-    //     membership and forceDisconnect() all current participants.
-    var room = this.rooms.get(roomToken);
-    var url = "/rooms/" + encodeURIComponent(roomToken);
-    MozLoopService.hawkRequest(this.sessionType, url, "DELETE").
-    then(function () {
-      _this.rooms.delete(roomToken);
-      eventEmitter.emit("delete", room);
-      eventEmitter.emit("delete:" + room.roomToken, room);
-      callback(null, room);}, 
-    function (error) {return callback(error);}).catch(function (error) {return callback(error);});}, 
-
-
-  /**
-   * Internal function to handle POSTs to a room.
-   *
-   * @param {String} roomToken  The room token.
-   * @param {Object} postData   The data to post to the room.
-   * @param {Function} callback Function that will be invoked once the operation
-   *                            finished. The first argument passed will be an
-   *                            `Error` object or `null`.
-   */
-  _postToRoom: function _postToRoom(roomToken, postData, callback) {var _this2 = this;
-    var url = "/rooms/" + encodeURIComponent(roomToken);
-    MozLoopService.hawkRequest(this.sessionType, url, "POST", postData).then(function (response) {
-      // Delete doesn't have a body return.
-      var joinData = response.body ? JSON.parse(response.body) : {};
-      if ("sessionToken" in joinData) {
-        var room = _this2.rooms.get(roomToken);
-        room.sessionToken = joinData.sessionToken;}
-
-      callback(null, joinData);}, 
-    function (error) {return callback(error);}).catch(function (error) {return callback(error);});}, 
-
-
-  /**
-   * Joins a room. The sessionToken that is returned by the server will be stored
-   * locally, for future use.
-   *
-   * @param {String} roomToken   The room token.
-   * @param {String} displayName The user's display name.
-   * @param {Function} callback  Function that will be invoked once the operation
-   *                             finished. The first argument passed will be an
-   *                             `Error` object or `null`.
-   */
-  join: function join(roomToken, displayName, callback) {
-    this._postToRoom(roomToken, { 
-      action: "join", 
-      displayName: displayName, 
-      clientMaxSize: CLIENT_MAX_SIZE }, 
-    callback);}, 
-
-
-  /**
-   * Refreshes a room
-   *
-   * @param {String} roomToken    The room token.
-   * @param {String} sessionToken The session token for the session that has been
-   *                              joined.
-   * @param {Function} callback   Function that will be invoked once the operation
-   *                              finished. The first argument passed will be an
-   *                              `Error` object or `null`.
-   */
-  refreshMembership: function refreshMembership(roomToken, sessionToken, callback) {
-    this._postToRoom(roomToken, { 
-      action: "refresh", 
-      sessionToken: sessionToken }, 
-    callback);}, 
-
-
-  /**
-   * Leaves a room. Although this is an sync function, no data is returned
-   * from the server.
-   *
-   * @param {String} roomToken    The room token.
-   * @param {String} sessionToken The session token for the session that has been
-   *                              joined
-   * @param {Function} callback   Optional. Function that will be invoked once the operation
-   *                              finished. The first argument passed will be an
-   *                              `Error` object or `null`.
-   */
-  leave: function leave(roomToken, sessionToken, callback) {
-    if (!callback) {
-      callback = function callback(error) {
-        if (error) {
-          MozLoopService.log.error(error);}};}
-
-
-
-    var room = this.rooms.get(roomToken);
-    if (!sessionToken && room && room.sessionToken) {
-      if (!room || !room.sessionToken) {
-        return;}
-
-      sessionToken = room.sessionToken;
-      delete room.sessionToken;}
-
-    this._postToRoom(roomToken, { 
-      action: "leave", 
-      sessionToken: sessionToken }, 
-    callback);}, 
-
-
-  /**
-   * Forwards connection status to the server.
-   *
-   * @param {String}                  roomToken The room token.
-   * @param {String}                  sessionToken The session token for the
-   *                                               session that has been
-   *                                               joined.
-   * @param {sharedActions.SdkStatus} status The connection status.
-   * @param {Function} callback Optional. Function that will be invoked once
-   *                            the operation finished. The first argument
-   *                            passed will be an `Error` object or `null`.
-   */
-  sendConnectionStatus: function sendConnectionStatus(roomToken, sessionToken, status, callback) {
-    if (!callback) {
-      callback = function callback(error) {
-        if (error) {
-          MozLoopService.log.error(error);}};}
-
-
-
-    this._postToRoom(roomToken, { 
-      action: "status", 
-      event: status.event, 
-      state: status.state, 
-      connections: status.connections, 
-      sendStreams: status.sendStreams, 
-      recvStreams: status.recvStreams, 
-      sessionToken: sessionToken }, 
-    callback);}, 
-
-
-  _domainLog: { 
-    domainMap: new Map(), 
-    roomToken: null }, 
-
-
-  /**
-   * Record a url associated to a room for batch submission if whitelisted.
-   *
-   * @param {String} roomToken The room token
-   * @param {String} url       Url with the domain to record
-   */
-  _recordUrl: function _recordUrl(roomToken, url) {
-    // Reset the log of domains if somehow we changed room tokens.
-    if (this._domainLog.roomToken !== roomToken) {
-      this._domainLog.roomToken = roomToken;
-      this._domainLog.domainMap.clear();}
-
-
-    var domain = void 0;
-    try {
-      domain = Services.eTLD.getBaseDomain(Services.io.newURI(url, null, null));} 
-
-    catch (ex) {
-      // Failed to extract domain, so don't record it.
-      return;}
-
-
-    // Only record domains that are whitelisted.
-    if (!DomainWhitelist.check(domain)) {
-      return;}
-
-
-    // Increment the count for previously recorded domains.
-    if (this._domainLog.domainMap.has(domain)) {
-      this._domainLog.domainMap.get(domain).count++;}
-
-    // Initialize the map for the domain with a value that can be submitted.
-    else {
-        this._domainLog.domainMap.set(domain, { count: 1, domain: domain });}}, 
-
-
-
-  /**
-   * Log the domains associated to a room token.
-   *
-   * @param {String} roomToken  The room token
-   * @param {Function} callback Function that will be invoked once the operation
-   *                            finished. The first argument passed will be an
-   *                            `Error` object or `null`.
-   */
-  logDomains: function logDomains(roomToken, callback) {
-    if (!callback) {
-      callback = function callback(error) {
-        if (error) {
-          MozLoopService.log.error(error);}};}
-
-
-
-
-    // Submit the domains that have been collected so far.
-    if (this._domainLog.roomToken === roomToken && 
-    this._domainLog.domainMap.size > 0) {
-      this._postToRoom(roomToken, { 
-        action: "logDomain", 
-        domains: [].concat(_toConsumableArray(this._domainLog.domainMap.values())) }, 
-      callback);
-      this._domainLog.domainMap.clear();}
-
-    // Indicate that nothing was logged.
-    else {
-        callback(null);}}, 
-
-
-
-  /**
-   * Updates a room.
-   *
-   * @param {String} roomToken  The room token
-   * @param {Object} roomData   Updated context data for the room. The following
-   *                            properties are expected: `roomName` and `urls`.
-   *                            IMPORTANT: Data in the `roomData::urls` array
-   *                            will be stored as-is, so any data omitted therein
-   *                            will be gone forever.
-   * @param {Function} callback Function that will be invoked once the operation
-   *                            finished. The first argument passed will be an
-   *                            `Error` object or `null`.
-   */
-  update: function update(roomToken, roomData, callback) {
-    var room = this.rooms.get(roomToken);
-    var url = "/rooms/" + encodeURIComponent(roomToken);
-    if (!room.decryptedContext) {
-      room.decryptedContext = { 
-        roomName: roomData.roomName || room.roomName };} else 
-
-    {
-      // room.roomName is the final fallback as this is pre-encryption support.
-      // Bug 1166283 is tracking the removal of the fallback.
-      room.decryptedContext.roomName = roomData.roomName || 
-      room.decryptedContext.roomName || 
-      room.roomName;}
-
-    if (roomData.urls && roomData.urls.length) {
-      // For now we only support adding one URL to the room context.
-      var context = roomData.urls[0];
-      room.decryptedContext.urls = [context];
-
-      // Record the url for reporting if enabled.
-      if (Services.prefs.getBoolPref("loop.logDomains")) {
-        this._recordUrl(roomToken, context.location);}}
-
-
-
-    Task.spawn(function* () {var _ref2 = 
-      yield this.promiseEncryptRoomData(room);var all = _ref2.all;var encrypted = _ref2.encrypted;
-
-      // For patch, we only send the context data.
-      var sendData = { 
-        context: encrypted.context };
-
-
-      // This might be an upgrade to encrypted rename, so store the key
-      // just in case.
-      yield this.roomsCache.setKey(this.sessionType, all.roomToken, all.roomKey);
-
-      var response = yield MozLoopService.hawkRequest(this.sessionType, 
-      url, "PATCH", sendData);
-
-      var newRoomData = all;
-
-      extend(newRoomData, JSON.parse(response.body));
-      this.rooms.set(roomToken, newRoomData);
-      callback(null, newRoomData);}.
-    bind(this)).catch(callback);}, 
-
-
-  /**
-   * Callback used to indicate changes to rooms data on the LoopServer.
-   *
-   * @param {String} version   Version number assigned to this change set.
-   * @param {String} channelID Notification channel identifier.
-   */
-  onNotification: function onNotification(version, channelID) {
-    // See if we received a notification for the channel that's currently active:
-    var channelIDs = MozLoopService.channelIDs;
-    if (this.sessionType == LOOP_SESSION_TYPE.GUEST && channelID != channelIDs.roomsGuest || 
-    this.sessionType == LOOP_SESSION_TYPE.FXA && channelID != channelIDs.roomsFxA) {
-      return;}
-
-
-    var oldDirty = gDirty;
-    gDirty = true;
-
-    // If we were already dirty, then get the full set of rooms. For example,
-    // we'd already be dirty if we had started up but not got the list of rooms
-    // yet.
-    this.getAll(oldDirty ? null : version, function () {});}, 
-
-
-  /**
-   * When a user logs in or out, this method should be invoked to check whether
-   * the rooms cache needs to be refreshed.
-   *
-   * @param {String|null} user The FxA userID or NULL
-   */
-  maybeRefresh: function maybeRefresh() {var user = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
-    if (gCurrentUser == user) {
-      return;}
-
-
-    gCurrentUser = user;
-    if (!gDirty) {
-      gDirty = true;
-      this.rooms.clear();
-      eventEmitter.emit("refresh");
-      this.getAll(null, function () {});}}, 
-
-
-
-  /**
-   * Handles a message received from the content channel.
-   *
-   * @param {String} id              The channel id.
-   * @param {Object} message         The message received.
-   * @param {Object} sendingContext  The context for the sending location.
-   */
-  _handleLinkClickerMessage: function _handleLinkClickerMessage(id, message, sendingContext) {
-    if (!message) {
-      return;}
-
-
-    var sendResponse = function sendResponse(response, alreadyOpen) {
-      gLinkClickerChannel.send({ 
-        response: response, 
-        alreadyOpen: alreadyOpen }, 
-      sendingContext);};
-
-
-    var hasRoom = this.rooms.has(message.roomToken);
-
-    switch (message.command) {
-      case "checkWillOpenRoom":
-        sendResponse(hasRoom, false);
-        break;
-      case "openRoom":
-        if (hasRoom) {
-          if (MozLoopService.isChatWindowOpen(message.roomToken)) {
-            sendResponse(hasRoom, true);} else 
-          {
-            this.open(message.roomToken);
-            sendResponse(hasRoom, false);}} else 
-
-        {
-          sendResponse(hasRoom, false);}
-
-        break;
-      default:
-        sendResponse(false, false);
-        break;}} };
-
-
-
-Object.freeze(LoopRoomsInternal);
-
-/**
- * Public Loop Rooms API.
- *
- * LoopRooms implements the EventEmitter interface by exposing three methods -
- * `on`, `once` and `off` - to subscribe to events.
- * At this point the following events may be subscribed to:
- *  - 'add[:{room-id}]':    A new room object was successfully added to the data
- *                          store.
- *  - 'delete[:{room-id}]': A room was successfully removed from the data store.
- *  - 'update[:{room-id}]': A room object was successfully updated with changed
- *                          properties in the data store.
- *  - 'joined[:{room-id}]': A participant joined a room.
- *  - 'left[:{room-id}]':   A participant left a room.
- *
- * See the internal code for the API documentation.
- */
-this.LoopRooms = { 
-  init: function init() {
-    LoopRoomsInternal.init();}, 
-
-
-  get participantsCount() {
-    return LoopRoomsInternal.participantsCount;}, 
-
-
-  getAll: function getAll(version, callback) {
-    if (!callback) {
-      callback = version;
-      version = null;}
-
-
-    LoopRoomsInternal.getAll(version).then(function (result) {return callback(null, result);}).
-    catch(function (error) {return callback(error);});}, 
-
-
-  get: function get(roomToken, callback) {
-    return LoopRoomsInternal.get(roomToken, callback);}, 
-
-
-  create: function create(options, callback) {
-    return LoopRoomsInternal.create(options, callback);}, 
-
-
-  open: function open(roomToken) {
-    return LoopRoomsInternal.open(roomToken);}, 
-
-
-  delete: function _delete(roomToken, callback) {
-    return LoopRoomsInternal.delete(roomToken, callback);}, 
-
-
-  join: function join(roomToken, displayName, callback) {
-    return LoopRoomsInternal.join(roomToken, displayName, callback);}, 
-
-
-  refreshMembership: function refreshMembership(roomToken, sessionToken, callback) {
-    return LoopRoomsInternal.refreshMembership(roomToken, sessionToken, 
-    callback);}, 
-
-
-  leave: function leave(roomToken, sessionToken, callback) {
-    return LoopRoomsInternal.leave(roomToken, sessionToken, callback);}, 
-
-
-  sendConnectionStatus: function sendConnectionStatus(roomToken, sessionToken, status, callback) {
-    return LoopRoomsInternal.sendConnectionStatus(roomToken, sessionToken, status, callback);}, 
-
-
-  logDomains: function logDomains(roomToken, callback) {
-    return LoopRoomsInternal.logDomains(roomToken, callback);}, 
-
-
-  update: function update(roomToken, roomData, callback) {
-    return LoopRoomsInternal.update(roomToken, roomData, callback);}, 
-
-
-  getGuestCreatedRoom: function getGuestCreatedRoom() {
-    return LoopRoomsInternal.getGuestCreatedRoom();}, 
-
-
-  maybeRefresh: function maybeRefresh(user) {
-    return LoopRoomsInternal.maybeRefresh(user);}, 
-
-
-  getNumParticipants: function getNumParticipants(roomToken) {
-    return LoopRoomsInternal.getNumParticipants(roomToken);}, 
-
-
-  /**
-   * This method is only useful for unit tests to set the rooms cache to contain
-   * a list of fake room data that can be asserted in tests.
-   *
-   * @param {Map} stub Stub cache containing fake rooms data
-   */
-  stubCache: function stubCache(stub) {
-    LoopRoomsInternal.rooms.clear();
-    if (stub) {
-      // Fill up the rooms cache with room objects provided in the `stub` Map.
-      var _iteratorNormalCompletion7 = true;var _didIteratorError7 = false;var _iteratorError7 = undefined;try {for (var _iterator7 = stub.entries()[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {var _ref3 = _step7.value;var _ref4 = _slicedToArray(_ref3, 2);var key = _ref4[0];var value = _ref4[1];
-          LoopRoomsInternal.rooms.set(key, value);}} catch (err) {_didIteratorError7 = true;_iteratorError7 = err;} finally {try {if (!_iteratorNormalCompletion7 && _iterator7.return) {_iterator7.return();}} finally {if (_didIteratorError7) {throw _iteratorError7;}}}
-
-      gDirty = false;} else 
-    {
-      // Restore the cache to not be stubbed anymore, but it'll need a refresh
-      // from the server for sure.
-      gDirty = true;}}, 
-
-
-
-  promise: function promise(method) {var _this3 = this;for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {params[_key - 1] = arguments[_key];}
-    if (method == "getAll") {
-      return LoopRoomsInternal.getAll.apply(LoopRoomsInternal, params);}
-
-
-    return new Promise(function (resolve, reject) {
-      _this3[method].apply(_this3, params.concat([function (error, result) {
-        if (error) {
-          reject(error);} else 
-        {
-          resolve(result);}}]));});}, 
-
-
-
-
-
-  on: function on() {var _eventEmitter;return (_eventEmitter = eventEmitter).on.apply(_eventEmitter, arguments);}, 
-
-  once: function once() {var _eventEmitter2;return (_eventEmitter2 = eventEmitter).once.apply(_eventEmitter2, arguments);}, 
-
-  off: function off() {var _eventEmitter3;return (_eventEmitter3 = eventEmitter).off.apply(_eventEmitter3, arguments);}, 
-
-  /**
-   * Expose the internal rooms map for testing purposes only. This avoids
-   * needing to mock the server interfaces.
-   *
-   * @param {Map} roomsCache The new cache data to set for testing purposes. If
-   *                         not specified, it will reset the cache.
-   */
-  _setRoomsCache: function _setRoomsCache(roomsCache, orig) {
-    LoopRoomsInternal.rooms.clear();
-    gDirty = true;
-
-    if (roomsCache) {
-      // Need a clone as the internal map is read-only.
-      var _iteratorNormalCompletion8 = true;var _didIteratorError8 = false;var _iteratorError8 = undefined;try {for (var _iterator8 = roomsCache[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {var _ref5 = _step8.value;var _ref6 = _slicedToArray(_ref5, 2);var key = _ref6[0];var value = _ref6[1];
-
-          LoopRoomsInternal.rooms.set(key, value);
-          if (orig) {
-            checkForParticipantsUpdate(orig, value);}}} catch (err) {_didIteratorError8 = true;_iteratorError8 = err;} finally {try {if (!_iteratorNormalCompletion8 && _iterator8.return) {_iterator8.return();}} finally {if (_didIteratorError8) {throw _iteratorError8;}}}
-
-
-      gGetAllPromise = null;
-      gDirty = false;}} };
-
-
-
-Object.freeze(this.LoopRooms);
deleted file mode 100644
--- a/browser/extensions/loop/chrome/content/modules/LoopRoomsCache.jsm
+++ /dev/null
@@ -1,157 +0,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/. */
-"use strict";var _Components = 
-
-Components;var Cu = _Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Task.jsm");var _Cu$import = 
-
-Cu.import("chrome://loop/content/modules/MozLoopService.jsm", {});var MozLoopService = _Cu$import.MozLoopService;var LOOP_SESSION_TYPE = _Cu$import.LOOP_SESSION_TYPE;
-XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", 
-"resource://services-common/utils.js");
-XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
-
-this.EXPORTED_SYMBOLS = ["LoopRoomsCache"];
-
-var LOOP_ROOMS_CACHE_FILENAME = "loopRoomsCache.json";
-XPCOMUtils.defineConstant(this, "LOOP_ROOMS_CACHE_FILENAME", LOOP_ROOMS_CACHE_FILENAME);
-
-/**
- * RoomsCache is a cache for saving simple rooms data to the disk in case we
- * need it for back-up purposes, e.g. recording room keys for FxA if the user
- * changes their password.
- *
- * The format of the data is:
- *
- * {
- *   <sessionType>: {
- *     <roomToken>: {
- *       "key": <roomKey>
- *     }
- *   }
- * }
- *
- * It is intended to try and keep the data forward and backwards compatible in
- * a reasonable manner, hence why the structure is more complex than it needs
- * to be to store tokens and keys.
- *
- * @param {Object} options The options for the RoomsCache, containing:
- *   - {String} baseDir   The base directory in which to save the file.
- *   - {String} filename  The filename for the cache file.
- */
-function LoopRoomsCache(options) {
-  options = options || {};
-
-  this.baseDir = options.baseDir || OS.Constants.Path.profileDir;
-  this.path = OS.Path.join(
-  this.baseDir, 
-  options.filename || LOOP_ROOMS_CACHE_FILENAME);
-
-  this._cache = null;}
-
-
-LoopRoomsCache.prototype = { 
-  /**
-   * Updates the local copy of the cache and saves it to disk.
-   *
-   * @param  {Object} contents An object to be saved in json format.
-   * @return {Promise} A promise that is resolved once the save is complete.
-   */
-  _setCache: function _setCache(contents) {var _this = this;
-    this._cache = contents;
-
-    return OS.File.makeDir(this.baseDir, { ignoreExisting: true }).then(function () {return (
-        CommonUtils.writeJSON(contents, _this.path));});}, 
-
-
-  /**
-   * Returns the local copy of the cache if there is one, otherwise it reads
-   * it from the disk.
-   *
-   * @return {Promise} A promise that is resolved once the read is complete.
-   */
-  _getCache: Task.async(function* () {
-    if (this._cache) {
-      return this._cache;}
-
-
-    try {
-      return this._cache = yield CommonUtils.readJSON(this.path);} 
-    catch (error) {
-      if (!error.becauseNoSuchFile) {
-        MozLoopService.log.debug("Error reading the cache:", error);}
-
-      return this._cache = {};}}), 
-
-
-
-  /**
-   * Function for testability purposes. Clears the cache.
-   *
-   * @return {Promise} A promise that is resolved once the clear is complete.
-   */
-  clear: function clear() {
-    this._cache = null;
-    return OS.File.remove(this.path);}, 
-
-
-  /**
-   * Gets a room key from the cache.
-   *
-   * @param {LOOP_SESSION_TYPE} sessionType  The session type for the room.
-   * @param {String}            roomToken    The token for the room.
-   * @return {Promise} A promise that is resolved when the data has been read
-   *                   with the value of the key, or null if it isn't present.
-   */
-  getKey: Task.async(function* (sessionType, roomToken) {
-    if (sessionType != LOOP_SESSION_TYPE.FXA) {
-      return null;}
-
-
-    var sessionData = (yield this._getCache())[sessionType];
-
-    if (!sessionData || !sessionData[roomToken]) {
-      return null;}
-
-    return sessionData[roomToken].key;}), 
-
-
-  /**
-   * Stores a room key into the cache. Note, if the key has not changed,
-   * the store will not be re-written.
-   *
-   * @param {LOOP_SESSION_TYPE} sessionType  The session type for the room.
-   * @param {String}            roomToken    The token for the room.
-   * @param {String}            roomKey      The encryption key for the room.
-   * @return {Promise} A promise that is resolved when the data has been stored.
-   */
-  setKey: Task.async(function* (sessionType, roomToken, roomKey) {
-    if (sessionType != LOOP_SESSION_TYPE.FXA) {
-      return Promise.resolve();}
-
-
-    var cache = yield this._getCache();
-
-    // Create these objects if they don't exist.
-    // We aim to do this creation and setting of the room key in a
-    // forwards-compatible way so that if new fields are added to rooms later
-    // then we don't mess them up (if there's no keys).
-    if (!cache[sessionType]) {
-      cache[sessionType] = {};}
-
-
-    if (!cache[sessionType][roomToken]) {
-      cache[sessionType][roomToken] = {};}
-
-
-    // Only save it if there's no key, or it is different.
-    if (!cache[sessionType][roomToken].key || 
-    cache[sessionType][roomToken].key != roomKey) {
-      cache[sessionType][roomToken].key = roomKey;
-      return yield this._setCache(cache);}
-
-
-    return Promise.resolve();}) };
deleted file mode 100644
--- a/browser/extensions/loop/chrome/content/modules/MozLoopAPI.jsm
+++ /dev/null
@@ -1,1373 +0,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/. */
-
-"use strict";var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;};function _toConsumableArray(arr) {if (Array.isArray(arr)) {for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {arr2[i] = arr[i];}return arr2;} else {return Array.from(arr);}}var _Components = 
-
-Components;var Cc = _Components.classes;var Ci = _Components.interfaces;var Cu = _Components.utils;
-
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("chrome://loop/content/modules/MozLoopService.jsm");
-Cu.import("chrome://loop/content/modules/LoopRooms.jsm");
-Cu.importGlobalProperties(["Blob"]);
-
-XPCOMUtils.defineLazyModuleGetter(this, "NewTabURL", 
-"resource:///modules/NewTabURL.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata", 
-"resource://gre/modules/PageMetadata.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", 
-"resource://gre/modules/PluralForm.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils", 
-"resource://gre/modules/UpdateUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "UITour", 
-"resource:///modules/UITour.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Social", 
-"resource:///modules/Social.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise", 
-"resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyGetter(this, "appInfo", function () {
-  return Cc["@mozilla.org/xre/app-info;1"].
-  getService(Ci.nsIXULAppInfo).
-  QueryInterface(Ci.nsIXULRuntime);});
-
-XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper", 
-"@mozilla.org/widget/clipboardhelper;1", 
-"nsIClipboardHelper");
-XPCOMUtils.defineLazyServiceGetter(this, "extProtocolSvc", 
-"@mozilla.org/uriloader/external-protocol-service;1", 
-"nsIExternalProtocolService");
-this.EXPORTED_SYMBOLS = ["LoopAPI"];
-
-var cloneableError = function cloneableError(source) {
-  // Simple Object that can be cloned over.
-  var error = {};
-  if (typeof source == "string") {
-    source = new Error(source);}
-
-
-  var props = Object.getOwnPropertyNames(source);
-  // nsIException properties are not enumerable, so we'll try to copy the most
-  // common and useful ones.
-  if (!props.length) {
-    props.push("message", "filename", "lineNumber", "columnNumber", "stack");}var _iteratorNormalCompletion = true;var _didIteratorError = false;var _iteratorError = undefined;try {
-
-    for (var _iterator = props[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var prop = _step.value;
-      var value = source[prop];
-      var type = typeof value === "undefined" ? "undefined" : _typeof(value);
-
-      // Functions can't be cloned. Period.
-      // For nsIException objects, the property may not be defined.
-      if (type == "function" || type == "undefined") {
-        continue;}
-
-      // Don't do anything to members that are already cloneable.
-      if (/boolean|number|string/.test(type)) {
-        error[prop] = value;} else 
-      {
-        // Convert non-compatible types to a String.
-        error[prop] = "" + value;}}
-
-
-
-    // Mark the object as an Error, otherwise it won't be discernable from other,
-    // regular objects.
-  } catch (err) {_didIteratorError = true;_iteratorError = err;} finally {try {if (!_iteratorNormalCompletion && _iterator.return) {_iterator.return();}} finally {if (_didIteratorError) {throw _iteratorError;}}}error.isError = true;
-
-  return error;};
-
-
-var getObjectAPIFunctionName = function getObjectAPIFunctionName(action) {
-  var funcName = action.split(":").pop();
-  return funcName.charAt(0).toLowerCase() + funcName.substr(1);};
-
-
-/**
- *  Checks that [browser.js]'s global variable `gMultiProcessBrowser` is active,
- *  instead of checking on first available browser element.
- *  :see bug 1257243 comment 5:
- */
-var isMultiProcessActive = function isMultiProcessActive() {
-  var win = Services.wm.getMostRecentWindow("navigator:browser");
-  return !!win.gMultiProcessBrowser;};
-
-
-var gAppVersionInfo = null;
-var gBrowserSharingListeners = new Set();
-var gBrowserSharingWindows = new Set();
-var gPageListeners = null;
-var gOriginalPageListeners = null;
-var gStringBundle = null;
-var gStubbedMessageHandlers = null;
-var kBatchMessage = "Batch";
-var kMaxLoopCount = 10;
-var kMessageName = "Loop:Message";
-var kPushMessageName = "Loop:Message:Push";
-var kPushSubscription = "pushSubscription";
-var kRoomsPushPrefix = "Rooms:";
-var kMauPrefMap = new Map(
-Object.getOwnPropertyNames(LOOP_MAU_TYPE).map(function (name) {
-  var parts = name.toLowerCase().split("_");
-  return [LOOP_MAU_TYPE[name], parts[0] + parts[1].charAt(0).toUpperCase() + parts[1].substr(1)];}));
-
-
-
-/**
- * WARNING: Every function in kMessageHandlers must call the reply() function,
- * as otherwise the content requesters can be left hanging.
- *
- * Ideally, we should rewrite them to handle failure/long times better, at which
- * point this could be relaxed slightly.
- */
-var kMessageHandlers = { 
-  /**
-   * Start browser sharing, which basically means to start listening for tab
-   * switches and passing the new window ID to the sender whenever that happens.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} roomToken The room ID to start browser sharing and listeners.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  AddBrowserSharingListener: function AddBrowserSharingListener(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    var browser = win && win.gBrowser.selectedBrowser;
-    if (!win || !browser) {
-      // This may happen when an undocked conversation window is the only
-      // window left.
-      var err = new Error("No tabs available to share.");
-      MozLoopService.log.error(err);
-      reply(cloneableError(err));
-      return;}
-
-
-    var autoStart = MozLoopService.getLoopPref("remote.autostart");
-    if (!autoStart && browser.getAttribute("remote") == "true") {
-      // Tab sharing might not be supported yet for e10s-enabled browsers.
-      var _err = new Error("Tab sharing is not supported for e10s-enabled browsers");
-      MozLoopService.log.error(_err);
-      reply(cloneableError(_err));
-      return;}
-
-
-    // get room token from message
-    var _message$data = _slicedToArray(message.data, 1);var windowId = _message$data[0];
-    // For rooms, the windowId === roomToken. If we change the type of place we're
-    // sharing from in the future, we may need to change this.
-    win.LoopUI.startBrowserSharing(windowId);
-
-    // Point new tab to load about:home to avoid accidentally sharing top sites.
-    NewTabURL.override("about:home");
-
-    gBrowserSharingWindows.add(Cu.getWeakReference(win));
-    gBrowserSharingListeners.add(windowId);
-    reply();}, 
-
-
-  /**
-   * Creates a layout for the remote cursor on the browser chrome,
-   * and positions it on the received coordinates.
-   *
-   * @param {Object}  message Message meant for the handler function, contains
-   *                          the following parameters in its 'data' property:
-   *                          {
-   *                            ratioX: cursor's X position (between 0-1)
-   *                            ratioY: cursor's Y position (between 0-1)
-   *                          }
-   *
-   * @param {Function} reply  Callback function, invoked with the result of the
-   *                          message handler. The result will be sent back to
-   *                          the senders' channel.
-   */
-  AddRemoteCursorOverlay: function AddRemoteCursorOverlay(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    if (win) {
-      win.LoopUI.addRemoteCursor(message.data[0]);}
-
-
-    reply();}, 
-
-
-  /**
-   * Shows the click event on the remote cursor.
-   *
-   * @param {Object}  message Message meant for the handler function, contains
-   *                          a boolean for the click event in its 'data' prop.
-   *
-   * @param {Function} reply  Callback function, invoked with the result of the
-   *                          message handler. The result will be sent back to
-   *                          the senders' channel.
-   */
-  ClickRemoteCursor: function ClickRemoteCursor(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    if (win) {
-      win.LoopUI.clickRemoteCursor(message.data[0]);}
-
-
-    reply();}, 
-
-
-  /**
-   * Associates a session-id and a call-id with a window for debugging.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} windowId  The window id.
-   *                             {String} sessionId OT session id.
-   *                             {String} callId    The callId on the server.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  AddConversationContext: function AddConversationContext(message, reply) {var _message$data2 = _slicedToArray(
-    message.data, 3);var windowId = _message$data2[0];var sessionId = _message$data2[1];var callid = _message$data2[2];
-    MozLoopService.addConversationContext(windowId, { 
-      sessionId: sessionId, 
-      callId: callid });
-
-    reply();}, 
-
-
-  /**
-   * Composes an email via the external protocol service.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} subject   Subject of the email to send
-   *                             {String} body      Body message of the email to send
-   *                             {String} recipient Recipient email address (optional)
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  ComposeEmail: function ComposeEmail(message, reply) {var _message$data3 = _slicedToArray(
-    message.data, 3);var subject = _message$data3[0];var body = _message$data3[1];var recipient = _message$data3[2];
-    recipient = recipient || "";
-    var mailtoURL = "mailto:" + encodeURIComponent(recipient) + 
-    "?subject=" + encodeURIComponent(subject) + 
-    "&body=" + encodeURIComponent(body);
-    extProtocolSvc.loadURI(CommonUtils.makeURI(mailtoURL));
-    reply();}, 
-
-
-  /**
-   * Show a confirmation dialog with the standard - localized - 'Yes'/ 'No'
-   * buttons or custom labels.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {Object} options Options for the confirm dialog:
-   *                               - {String} message        Message body for the dialog
-   *                               - {String} [okButton]     Label for the OK button
-   *                               - {String} [cancelButton] Label for the Cancel button
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  Confirm: function Confirm(message, reply) {
-    var options = message.data[0];
-    var buttonFlags = void 0;
-    if (options.okButton && options.cancelButton) {
-      buttonFlags = 
-      Ci.nsIPrompt.BUTTON_POS_0 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING + 
-      Ci.nsIPrompt.BUTTON_POS_1 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING;} else 
-    if (!options.okButton && !options.cancelButton) {
-      buttonFlags = Services.prompt.STD_YES_NO_BUTTONS;} else 
-    {
-      reply(cloneableError("confirm: missing button options"));
-      return;}
-
-
-    try {
-      var chosenButton = Services.prompt.confirmEx(null, "", 
-      options.message, buttonFlags, options.okButton, options.cancelButton, 
-      null, null, {});
-
-      reply(chosenButton == 0);} 
-    catch (ex) {
-      reply(ex);}}, 
-
-
-
-  /**
-   * Copies passed string onto the system clipboard.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} str The string to copy
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  CopyString: function CopyString(message, reply) {
-    var str = message.data[0];
-    clipboardHelper.copyString(str);
-    reply();}, 
-
-
-  /**
-   * Returns a new GUID (UUID) in curly braces format.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GenerateUUID: function GenerateUUID(message, reply) {
-    reply(MozLoopService.generateUUID());}, 
-
-
-  /**
-   * Fetch the JSON blob of localized strings from the loop.properties bundle.
-   * @see MozLoopService#getStrings
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetAllStrings: function GetAllStrings(message, reply) {
-    if (gStringBundle) {
-      reply(gStringBundle);
-      return;}
-
-
-    // Get the map of strings.
-    var strings = MozLoopService.getStrings();
-    // Convert it to an object.
-    gStringBundle = {};var _iteratorNormalCompletion2 = true;var _didIteratorError2 = false;var _iteratorError2 = undefined;try {
-      for (var _iterator2 = strings.entries()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {var _ref = _step2.value;var _ref2 = _slicedToArray(_ref, 2);var key = _ref2[0];var value = _ref2[1];
-        gStringBundle[key] = value;}} catch (err) {_didIteratorError2 = true;_iteratorError2 = err;} finally {try {if (!_iteratorNormalCompletion2 && _iterator2.return) {_iterator2.return();}} finally {if (_didIteratorError2) {throw _iteratorError2;}}}
-
-    reply(gStringBundle);}, 
-
-
-  /**
-   * Fetch all constants that are used both on the client and the chrome-side.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetAllConstants: function GetAllConstants(message, reply) {
-    reply({ 
-      COPY_PANEL: COPY_PANEL, 
-      LOOP_SESSION_TYPE: LOOP_SESSION_TYPE, 
-      LOOP_MAU_TYPE: LOOP_MAU_TYPE, 
-      ROOM_CREATE: ROOM_CREATE, 
-      SHARING_ROOM_URL: SHARING_ROOM_URL });}, 
-
-
-
-  /**
-   * Returns the app version information for use during feedback.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @return {Object} An object containing:
-   *   - channel: The update channel the application is on
-   *   - version: The application version
-   *   - OS: The operating system the application is running on
-   */
-  GetAppVersionInfo: function GetAppVersionInfo(message, reply) {
-    if (!gAppVersionInfo) {
-      // If the lazy getter explodes, we're probably loaded in xpcshell,
-      // which doesn't have what we need, so log an error.
-      try {
-        gAppVersionInfo = { 
-          channel: UpdateUtils.UpdateChannel, 
-          version: appInfo.version, 
-          OS: appInfo.OS };} 
-
-      catch (ex) {
-        // Do nothing
-      }}
-
-    reply(gAppVersionInfo);}, 
-
-
-  /**
-   * Fetch the contents of a specific audio file and return it as a Blob object.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} name Name of the sound to fetch
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetAudioBlob: function GetAudioBlob(message, reply) {
-    var name = message.data[0];
-    var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
-    createInstance(Ci.nsIXMLHttpRequest);
-    var url = "chrome://loop/content/shared/sounds/" + name + ".ogg";
-
-    request.open("GET", url, true);
-    request.responseType = "arraybuffer";
-    request.onload = function () {
-      if (request.status < 200 || request.status >= 300) {
-        reply(cloneableError(request.status + " " + request.statusText));
-        return;}
-
-
-      var blob = new Blob([request.response], { type: "audio/ogg" });
-      reply(blob);};
-
-
-    request.send();}, 
-
-
-  /**
-   * Returns the window data for a specific conversation window id.
-   *
-   * This data will be relevant to the type of window, e.g. rooms or calls.
-   * See LoopRooms for more information.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} conversationWindowId
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @returns {Object} The window data or null if error.
-   */
-  GetConversationWindowData: function GetConversationWindowData(message, reply) {
-    reply(MozLoopService.getConversationWindowData(message.data[0]));}, 
-
-
-  /**
-   * Gets the "do not disturb" mode activation flag.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetDoNotDisturb: function GetDoNotDisturb(message, reply) {
-    reply(MozLoopService.doNotDisturb);}, 
-
-
-  /**
-   * Retrieve the list of errors that are currently pending on the MozLoopService
-   * class.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetErrors: function GetErrors(message, reply) {
-    var errors = {};var _iteratorNormalCompletion3 = true;var _didIteratorError3 = false;var _iteratorError3 = undefined;try {
-      for (var _iterator3 = MozLoopService.errors[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {var _ref3 = _step3.value;var _ref4 = _slicedToArray(_ref3, 2);var type = _ref4[0];var error = _ref4[1];
-        // if error.error is an nsIException, just delete it since it's hard
-        // to clone across the boundary.
-        if (error.error instanceof Ci.nsIException) {
-          MozLoopService.log.debug("Warning: Some errors were omitted from MozLoopAPI.errors " + 
-          "due to issues copying nsIException across boundaries.", 
-          error.error);
-          delete error.error;}
-
-
-        errors[type] = cloneableError(error);}} catch (err) {_didIteratorError3 = true;_iteratorError3 = err;} finally {try {if (!_iteratorNormalCompletion3 && _iterator3.return) {_iterator3.return();}} finally {if (_didIteratorError3) {throw _iteratorError3;}}}
-
-    return reply(errors);}, 
-
-
-  /**
-   * Returns true if this profile has an encryption key.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @return {Boolean} True if the profile has an encryption key.
-   */
-  GetHasEncryptionKey: function GetHasEncryptionKey(message, reply) {
-    reply(MozLoopService.hasEncryptionKey);}, 
-
-
-  /**
-   * Returns the current locale of the browser.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @returns {String} The locale string
-   */
-  GetLocale: function GetLocale(message, reply) {
-    reply(MozLoopService.locale);}, 
-
-
-  /**
-   * Returns the version number for the addon.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @returns {String} Addon Version string.
-   */
-  GetAddonVersion: function GetAddonVersion(message, reply) {
-    reply(MozLoopService.addonVersion);}, 
-
-
-  /**
-   * Return any preference under "loop.".
-   * Any errors thrown by the Mozilla pref API are logged to the console
-   * and cause null to be returned. This includes the case of the preference
-   * not being found.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} prefName The name of the pref without
-   *                                               the preceding "loop."
-   *                             {Enum}   prefType Type of preference, defined
-   *                                               at Ci.nsIPrefBranch. Optional.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @return {*} on success, null on error
-   */
-  GetLoopPref: function GetLoopPref(message, reply) {var _message$data4 = _slicedToArray(
-    message.data, 2);var prefName = _message$data4[0];var prefType = _message$data4[1];
-    reply(MozLoopService.getLoopPref(prefName, prefType));}, 
-
-
-  /**
-   * Retrieve the plural rule number of the active locale.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetPluralRule: function GetPluralRule(message, reply) {
-    reply(PluralForm.ruleNum);}, 
-
-
-  /**
-   * Gets the metadata related to the currently selected tab in
-   * the most recent window.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GetSelectedTabMetadata: function GetSelectedTabMetadata(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    var browser = win && win.gBrowser.selectedBrowser;
-    if (!win || !browser) {
-      MozLoopService.log.error("Error occurred whilst fetching page metadata");
-      reply();
-      return;}
-
-
-    // non-remote pages have no metadata
-    if (!browser.getAttribute("remote") === "true") {
-      reply(null);}
-
-
-    win.messageManager.addMessageListener("PageMetadata:PageDataResult", 
-    function onPageDataResult(msg) {
-
-      win.messageManager.removeMessageListener("PageMetadata:PageDataResult", 
-      onPageDataResult);
-      var pageData = msg.json;
-      win.LoopUI.getFavicon(function (err, favicon) {
-        if (err && err !== "favicon not found for uri") {
-          MozLoopService.log.error("Error occurred whilst fetching favicon", err);
-          // We don't return here intentionally to make sure the callback is
-          // invoked at all times. We just report the error here.
-        }
-        pageData.favicon = favicon || null;
-
-        reply(pageData);});});
-
-
-    win.gBrowser.selectedBrowser.messageManager.sendAsyncMessage("PageMetadata:GetPageData");}, 
-
-
-  /**
-   * Gets an object with data that represents the currently
-   * authenticated user's identity.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @return null if user not logged in; profile object otherwise
-   */
-  GetUserProfile: function GetUserProfile(message, reply) {
-    if (!MozLoopService.userProfile) {
-      reply(null);
-      return;}
-
-
-    reply({ 
-      email: MozLoopService.userProfile.email, 
-      uid: MozLoopService.userProfile.uid });}, 
-
-
-
-  /**
-   * Hangup and close all chat windows that are open.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  HangupAllChatWindows: function HangupAllChatWindows(message, reply) {
-    MozLoopService.hangupAllChatWindows();
-    reply();}, 
-
-
-  /**
-   * Hangup a specific chay window or room, by leaving a room, resetting the
-   * screensharing state and removing any active browser switch listeners.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} roomToken The token of the room to leave
-   *                             {Number} windowId  The window ID of the chat window
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  HangupNow: function HangupNow(message, reply) {var _message$data5 = _slicedToArray(
-    message.data, 3);var roomToken = _message$data5[0];var sessionToken = _message$data5[1];var windowId = _message$data5[2];
-    if (!windowId) {
-      windowId = sessionToken;}
-
-
-    LoopRooms.logDomains(roomToken);
-    LoopRooms.leave(roomToken);
-    MozLoopService.setScreenShareState(windowId, false);
-    LoopAPI.sendMessageToHandler({ 
-      name: "RemoveBrowserSharingListener", 
-      data: [windowId] });
-
-    reply();}, 
-
-
-  /**
-   * Check if the current browser has e10s enabled or not
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           []
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  IsMultiProcessActive: function IsMultiProcessActive(message, reply) {
-    reply(isMultiProcessActive());}, 
-
-
-  /**
-   *  Checks that the current tab can be shared.
-   *  Non-shareable tabs are the non-remote ones when e10s is enabled.
-   *
-   *  @param {Object}   message Message meant for the handler function,
-   *                            with no data attached.
-   *  @param {Function} reply   Callback function, invoked with the result of
-   *                            the check. The result will be sent back to
-   *                            the senders' channel.
-   */
-  IsTabShareable: function IsTabShareable(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    var browser = win && win.gBrowser.selectedBrowser;
-    if (!win || !browser) {
-      reply(false);
-      return;}
-
-
-    var e10sActive = isMultiProcessActive();
-    var tabRemote = browser.getAttribute("remote") === "true";
-
-    reply(!e10sActive || e10sActive && tabRemote);}, 
-
-
-  /**
-   * Start the FxA login flow using the OAuth client and params from the Loop
-   * server.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {Boolean} forceReAuth Set to true to force FxA
-   *                                                   into a re-auth even if the
-   *                                                   user is already logged in.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   * @return {Promise} Returns a promise that is resolved on successful
-   *                   completion, or rejected otherwise.
-   */
-  LoginToFxA: function LoginToFxA(message, reply) {
-    var forceReAuth = message.data[0];
-    MozLoopService.logInToFxA(forceReAuth);
-    reply();}, 
-
-
-  /**
-   * Logout completely from FxA.
-   * @see MozLoopService#logOutFromFxA
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  LogoutFromFxA: function LogoutFromFxA(message, reply) {
-    MozLoopService.logOutFromFxA();
-    reply();}, 
-
-
-  /**
-   * Notifies the UITour module that an event occurred that it might be
-   * interested in.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} subject  Subject of the notification
-   *                             {mixed}  [params] Optional parameters, providing
-   *                                               more details to the notification
-   *                                               subject
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  NotifyUITour: function NotifyUITour(message, reply) {var _message$data6 = _slicedToArray(
-    message.data, 2);var subject = _message$data6[0];var params = _message$data6[1];
-    UITour.notify(subject, params);
-    reply();}, 
-
-
-  /**
-   * Opens the Getting Started tour in the browser.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           []
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  OpenGettingStartedTour: function OpenGettingStartedTour(message, reply) {
-    MozLoopService.openGettingStartedTour();
-    reply();}, 
-
-
-  /**
-   * Retrieves the Getting Started tour url.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [aSrc, aAdditionalParams]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  GettingStartedURL: function GettingStartedURL(message, reply) {
-    var aSrc = message.data[0] || null;
-    var aAdditionalParams = message.data[1] || {};
-    reply(MozLoopService.getTourURL(aSrc, aAdditionalParams).href);}, 
-
-
-  /**
-   * Open the FxA profile/ settings page.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  OpenFxASettings: function OpenFxASettings(message, reply) {
-    MozLoopService.openFxASettings();
-    reply();}, 
-
-
-  /**
-   * Opens a non e10s window
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [url]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  OpenNonE10sWindow: function OpenNonE10sWindow(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    var url = message.data[0] ? message.data[0] : "about:home";
-    win.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no,non-remote", url);
-    reply();}, 
-
-
-  /**
-   * Opens a URL in a new tab in the browser.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} url The new url to open
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  OpenURL: function OpenURL(message, reply) {
-    var url = message.data[0];
-    MozLoopService.openURL(url);
-    reply();}, 
-
-
-  /**
-   * Removes a listener that was previously added.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {Number} windowId The window ID of the chat
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  RemoveBrowserSharingListener: function RemoveBrowserSharingListener(message, reply) {
-    if (!gBrowserSharingListeners.size) {
-      reply();
-      return;}var _message$data7 = _slicedToArray(
-
-
-    message.data, 1);var windowId = _message$data7[0];
-    gBrowserSharingListeners.delete(windowId);
-    if (gBrowserSharingListeners.size > 0) {
-      // There are still clients listening in, so keep on listening...
-      reply();
-      return;}var _iteratorNormalCompletion4 = true;var _didIteratorError4 = false;var _iteratorError4 = undefined;try {
-
-
-      for (var _iterator4 = gBrowserSharingWindows[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {var win = _step4.value;
-        win = win.get();
-        if (!win) {
-          continue;}
-
-        win.LoopUI.stopBrowserSharing();}} catch (err) {_didIteratorError4 = true;_iteratorError4 = err;} finally {try {if (!_iteratorNormalCompletion4 && _iterator4.return) {_iterator4.return();}} finally {if (_didIteratorError4) {throw _iteratorError4;}}}
-
-
-    NewTabURL.reset();
-
-    gBrowserSharingWindows.clear();
-    reply();}, 
-
-
-  "Rooms:*": function Rooms(action, message, reply) {
-    LoopAPIInternal.handleObjectAPIMessage(LoopRooms, kRoomsPushPrefix, 
-    action, message, reply);}, 
-
-
-  /**
-   * Sets the "do not disturb" mode activation flag.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [ ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  SetDoNotDisturb: function SetDoNotDisturb(message, reply) {
-    MozLoopService.doNotDisturb = message.data[0];
-    reply();}, 
-
-
-  /**
-   * Set any preference under "loop."
-   * Any errors thrown by the Mozilla pref API are logged to the console
-   * and cause false to be returned.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} prefName The name of the pref without
-   *                                               the preceding "loop."
-   *                             {*}      value    The value to set.
-   *                             {Enum}   prefType Type of preference, defined at
-   *                                               Ci.nsIPrefBranch. Optional.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  SetLoopPref: function SetLoopPref(message, reply) {var _message$data8 = _slicedToArray(
-    message.data, 3);var prefName = _message$data8[0];var value = _message$data8[1];var prefType = _message$data8[2];
-    MozLoopService.setLoopPref(prefName, value, prefType);
-    reply();}, 
-
-
-  /**
-   * Called when a closing room has just been created, so user can change
-   * the name of the room to be stored.
-   *
-   * @param {Object}   message Message meant for the handler function, shouldn't
-                               contain any data.
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  SetNameNewRoom: function SetNameNewRoom(message, reply) {
-    var win = Services.wm.getMostRecentWindow("navigator:browser");
-    win && win.LoopUI.renameRoom();
-
-    reply();}, 
-
-
-  /**
-   * Used to record the screen sharing state for a window so that it can
-   * be reflected on the toolbar button.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} windowId The id of the conversation window
-   *                                               the state is being changed for.
-   *                             {Boolean} active  Whether or not screen sharing
-   *                                               is now active.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  SetScreenShareState: function SetScreenShareState(message, reply) {var _message$data9 = _slicedToArray(
-    message.data, 2);var windowId = _message$data9[0];var active = _message$data9[1];
-    MozLoopService.setScreenShareState(windowId, active);
-    reply();}, 
-
-
-  /**
-   * Adds a value to a telemetry histogram.
-   *
-   * @param {Object}   message Message meant for the handler function, containing
-   *                           the following parameters in its `data` property:
-   *                           [
-   *                             {String} histogramId Name of the telemetry histogram
-   *                                                  to update.
-   *                             {String} value       Label of bucket to increment
-   *                                                   in the histogram.
-   *                           ]
-   * @param {Function} reply   Callback function, invoked with the result of this
-   *                           message handler. The result will be sent back to
-   *                           the senders' channel.
-   */
-  TelemetryAddValue: function TelemetryAddValue(message, reply) {var _message$data10 = _slicedToArray(
-    message.data, 2);var histogramId = _message$data10[0];var value = _message$data10[1];
-
-    if (histogramId === "LOOP_ACTIVITY_COUNTER") {
-      var pref = "mau." + kMauPrefMap.get(value);
-      var prefDate = MozLoopService.getLoopPref(pref) * 1000;
-      var delta = Date.now() - prefDate;
-
-      // Send telemetry event if period (30 days) passed.
-      // 0 is default value for pref.
-      // 2592000 seconds in 30 days
-      if (pref === 0 || delta >= 2592000 * 1000) {
-        try {
-          Services.telemetry.getHistogramById(histogramId).add(value);} 
-        catch (ex) {
-          MozLoopService.log.error("TelemetryAddValue failed for histogram '" + histogramId + "'", ex);}
-
-        MozLoopService.setLoopPref(pref, Math.floor(Date.now() / 1000));}} else 
-
-    {
-      try {
-        Services.telemetry.getHistogramById(histogramId).add(value);} 
-      catch (ex) {
-        MozLoopService.log.error("TelemetryAddValue failed for histogram '" + histogramId + "'", ex);}}
-
-
-    reply();} };
-
-
-
-var LoopAPIInternal = { 
-  /**
-   * Initialize the Loop API, which means:
-   * 1) setup RemotePageManager to hook into loop documents as channels and
-   *    start listening for messages therein.
-   * 2) start listening for other events that may be interesting.
-   */
-  initialize: function initialize() {
-    if (gPageListeners) {
-      return;}
-
-
-    Cu.import("resource://gre/modules/RemotePageManager.jsm");
-
-    gPageListeners = [new RemotePages("about:looppanel"), 
-    new RemotePages("about:loopconversation"), 
-    // Slideshow added here to expose the loop api to make L10n work.
-    // XXX Can remove once slideshow is made remote.
-    new RemotePages("chrome://loop/content/panels/slideshow.html")];var _iteratorNormalCompletion5 = true;var _didIteratorError5 = false;var _iteratorError5 = undefined;try {
-      for (var _iterator5 = gPageListeners[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {var page = _step5.value;
-        page.addMessageListener(kMessageName, this.handleMessage.bind(this));}
-
-
-      // Subscribe to global events:
-    } catch (err) {_didIteratorError5 = true;_iteratorError5 = err;} finally {try {if (!_iteratorNormalCompletion5 && _iterator5.return) {_iterator5.return();}} finally {if (_didIteratorError5) {throw _iteratorError5;}}}Services.obs.addObserver(this.handleStatusChanged, "loop-status-changed", false);}, 
-
-
-  /**
-   * Handles incoming messages from RemotePageManager that are sent from Loop
-   * content pages.
-   *
-   * @param {Object} message Object containing the following fields:
-   *                         - {MessageManager} target Where the message came from
-   *                         - {String}         name   Name of the message
-   *                         - {Array}          data   Payload of the message
-   * @param {Function} [reply]
-   */
-  handleMessage: function handleMessage(message, reply) {
-    var seq = message.data.shift();
-    var action = message.data.shift();
-
-    var actionParts = action.split(":");
-
-    // The name that is supposed to match with a handler function is tucked inside
-    // the second part of the message name. If all is well.
-    var handlerName = actionParts.shift();
-
-    if (!reply) {
-      reply = function reply(result) {
-        try {
-          message.target.sendAsyncMessage(message.name, [seq, result]);} 
-        catch (ex) {
-          MozLoopService.log.error("Failed to send reply back to content:", ex);}};}
-
-
-
-
-    // First, check if this is a batch call.
-    if (handlerName == kBatchMessage) {
-      this.handleBatchMessage(seq, message, reply);
-      return;}
-
-
-    // Second, check if the message is meant for one of our Object APIs.
-    // If so, a wildcard entry should exist for the message name in the
-    // `kMessageHandlers` dictionary.
-    var wildcardName = handlerName + ":*";
-    if (kMessageHandlers[wildcardName]) {
-      // A unit test might've stubbed the handler.
-      if (gStubbedMessageHandlers && gStubbedMessageHandlers[wildcardName]) {
-        gStubbedMessageHandlers[wildcardName](action, message, reply);} else 
-      {
-        // Alright, pass the message forward.
-        kMessageHandlers[wildcardName](action, message, reply);}
-
-      // Aaaaand we're done.
-      return;}
-
-
-    // A unit test might've stubbed the handler.
-    if (gStubbedMessageHandlers && gStubbedMessageHandlers[handlerName]) {
-      gStubbedMessageHandlers[handlerName](message, reply);
-      return;}
-
-
-    if (!kMessageHandlers[handlerName]) {
-      var msg = "Ouch, no message handler available for '" + handlerName + "'";
-      MozLoopService.log.error(msg);
-      reply(cloneableError(msg));
-      return;}
-
-
-    kMessageHandlers[handlerName](message, reply);}, 
-
-
-  /**
-   * If `sendMessage` above detects that the incoming message consists of a whole
-   * set of messages, this function is tasked with handling them.
-   * It iterates over all the messages, sends each to their appropriate handler
-   * and collects their results. The results will be sent back in one go as response
-   * to the batch message.
-   *
-   * @param {Number} seq       Sequence ID of this message
-   * @param {Object} message   Message containing the following parameters in
-   *                           its `data` property:
-   *