diff --git a/DEPS b/DEPS
index b57ba6f..9b41aae 100644
--- a/DEPS
+++ b/DEPS
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'f49ec2dcbd4701deac2247e4aa59e9cbf281b4dc',
+  'catapult_revision': 'fe5e396b07f8f81d7cd56ad930fdae77533fcc6b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc
index 1c9f37c..26f2b94 100644
--- a/android_webview/native/aw_autofill_client.cc
+++ b/android_webview/native/aw_autofill_client.cc
@@ -87,6 +87,11 @@
   return nullptr;
 }
 
+autofill::SaveCardBubbleController*
+AwAutofillClient::GetSaveCardBubbleController() {
+  return nullptr;
+}
+
 autofill::PersonalDataManager* AwAutofillClient::GetPersonalDataManager() {
   return nullptr;
 }
@@ -251,6 +256,7 @@
 void AwAutofillClient::ConfirmSaveCreditCardToCloud(
     const autofill::CreditCard& card,
     std::unique_ptr<base::DictionaryValue> legal_message,
+    bool should_cvc_be_requested,
     const base::Closure& callback) {
   NOTIMPLEMENTED();
 }
diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h
index 04c343d7..0316127 100644
--- a/android_webview/native/aw_autofill_client.h
+++ b/android_webview/native/aw_autofill_client.h
@@ -25,6 +25,7 @@
 class CreditCard;
 class FormStructure;
 class PersonalDataManager;
+class SaveCardBubbleController;
 }
 
 namespace content {
@@ -67,6 +68,7 @@
   IdentityProvider* GetIdentityProvider() override;
   rappor::RapporServiceImpl* GetRapporServiceImpl() override;
   ukm::UkmService* GetUkmService() override;
+  autofill::SaveCardBubbleController* GetSaveCardBubbleController() override;
   void ShowAutofillSettings() override;
   void ShowUnmaskPrompt(
       const autofill::CreditCard& card,
@@ -78,6 +80,7 @@
   void ConfirmSaveCreditCardToCloud(
       const autofill::CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
+      bool should_cvc_be_requested,
       const base::Closure& callback) override;
   void ConfirmCreditCardFillAssist(const autofill::CreditCard& card,
                                    const base::Closure& callback) override;
diff --git a/ash/display/resolution_notification_controller.cc b/ash/display/resolution_notification_controller.cc
index b6db541..8d472b6 100644
--- a/ash/display/resolution_notification_controller.cc
+++ b/ash/display/resolution_notification_controller.cc
@@ -162,7 +162,7 @@
   display::Screen::GetScreen()->RemoveObserver(this);
 }
 
-void ResolutionNotificationController::PrepareNotification(
+bool ResolutionNotificationController::PrepareNotificationAndSetDisplayMode(
     int64_t display_id,
     const scoped_refptr<display::ManagedDisplayMode>& old_resolution,
     const scoped_refptr<display::ManagedDisplayMode>& new_resolution,
@@ -170,7 +170,14 @@
   DCHECK(old_resolution);
   DCHECK(new_resolution);
 
-  DCHECK(!display::Display::IsInternalDisplayId(display_id));
+  display::DisplayManager* const display_manager =
+      Shell::Get()->display_manager();
+  if (display::Display::IsInternalDisplayId(display_id)) {
+    // We don't show notifications to confirm/revert the resolution change in
+    // the case of an internal display.
+    return display_manager->SetDisplayMode(display_id, new_resolution);
+  }
+
   // If multiple resolution changes are invoked for the same display,
   // the original resolution for the first resolution change has to be used
   // instead of the specified |old_resolution|.
@@ -192,6 +199,15 @@
                                               new_resolution, accept_callback));
   if (original_resolution && !original_resolution->size().IsEmpty())
     change_info_->old_resolution = original_resolution;
+
+  if (!display_manager->SetDisplayMode(display_id, new_resolution)) {
+    // Discard the prepared notification data since we failed to set the new
+    // resolution.
+    change_info_.reset();
+    return false;
+  }
+
+  return true;
 }
 
 bool ResolutionNotificationController::DoesNotificationTimeout() {
diff --git a/ash/display/resolution_notification_controller.h b/ash/display/resolution_notification_controller.h
index e12e1ba..c00150b 100644
--- a/ash/display/resolution_notification_controller.h
+++ b/ash/display/resolution_notification_controller.h
@@ -31,23 +31,34 @@
   ResolutionNotificationController();
   ~ResolutionNotificationController() override;
 
-  // Prepare a resolution change notification for |display_id| from
-  // |old_resolution| to |new_resolution|, which offers a button to revert the
-  // change in case something goes wrong. The notification times out if there's
-  // only one display connected and the user is trying to modify its resolution.
-  // In that case, the timeout has to be set since the user cannot make any
-  // changes if something goes wrong.
+  // If |display_id| is not the internal display, Prepare a resolution change
+  // notification for |display_id| from |old_resolution| to |new_resolution|,
+  // which offers a button to revert the change in case something goes wrong.
+  // The notification times out if there's only one display connected and the
+  // user is trying to modify its resolution. In that case, the timeout has to
+  // be set since the user cannot make any changes if something goes wrong.
+  //
+  // Then call DisplayManager::SetDisplayMode() to apply the resolution change,
+  // and return the result; true if success, false otherwise.
+  // In case SetDisplayMode() fails, the prepared notification will be
+  // discarded.
+  //
+  // If |display_id| is the internal display, the resolution change is applied
+  // directly without preparing the confirm/revert notification (this kind of
+  // notification is only useful for external displays).
   //
   // This method does not create a notification itself. The notification will be
   // created the next OnDisplayConfigurationChanged(), which will be called
-  // asynchronously after the resolution change is requested. So typically this
-  // method will be combined with resolution change methods like
-  // DisplayManager::SetDisplayMode().
-  void PrepareNotification(
+  // asynchronously after the resolution change is requested by this method.
+  //
+  // |accept_callback| will be called when the user accepts the resoltion change
+  // by closing the notification bubble or clicking on the accept button (if
+  // any).
+  bool PrepareNotificationAndSetDisplayMode(
       int64_t display_id,
       const scoped_refptr<display::ManagedDisplayMode>& old_resolution,
       const scoped_refptr<display::ManagedDisplayMode>& new_resolution,
-      const base::Closure& accept_callback);
+      const base::Closure& accept_callback) WARN_UNUSED_RESULT;
 
   // Returns true if the notification is visible or scheduled to be visible and
   // the notification times out.
diff --git a/ash/display/resolution_notification_controller_unittest.cc b/ash/display/resolution_notification_controller_unittest.cc
index 977eacc..b1064f98 100644
--- a/ash/display/resolution_notification_controller_unittest.cc
+++ b/ash/display/resolution_notification_controller_unittest.cc
@@ -66,12 +66,10 @@
             old_mode->native(), old_mode->ui_scale(),
             old_mode->device_scale_factor()));
 
-    if (display_manager()->SetDisplayMode(display.id(), new_mode)) {
-      controller()->PrepareNotification(
-          display.id(), old_mode, new_mode,
-          base::Bind(&ResolutionNotificationControllerTest::OnAccepted,
-                     base::Unretained(this)));
-    }
+    EXPECT_TRUE(controller()->PrepareNotificationAndSetDisplayMode(
+        display.id(), old_mode, new_mode,
+        base::Bind(&ResolutionNotificationControllerTest::OnAccepted,
+                   base::Unretained(this))));
 
     // OnConfigurationChanged event won't be emitted in the test environment,
     // so invoke UpdateDisplay() to emit that event explicitly.
diff --git a/base/process/process_metrics_unittest.cc b/base/process/process_metrics_unittest.cc
index ed98020..8abdb264 100644
--- a/base/process/process_metrics_unittest.cc
+++ b/base/process/process_metrics_unittest.cc
@@ -418,7 +418,8 @@
 #endif  // defined(OS_LINUX) || defined(OS_ANDROID)
 
   // All the values should be less than the total amount of memory.
-#if !defined(OS_WIN)
+#if !defined(OS_WIN) && !defined(OS_IOS)
+  // TODO(crbug.com/711450): re-enable the following assertion on iOS.
   EXPECT_LT(info.free, info.total);
 #endif
 #if defined(OS_LINUX) || defined(OS_ANDROID)
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index c62ac3a..f7918544 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -647,8 +647,6 @@
     "test/test_occlusion_tracker.h",
     "test/test_shared_bitmap_manager.cc",
     "test/test_shared_bitmap_manager.h",
-    "test/test_skcanvas.cc",
-    "test/test_skcanvas.h",
     "test/test_task_graph_runner.cc",
     "test/test_task_graph_runner.h",
     "test/test_texture.cc",
@@ -766,7 +764,6 @@
     "output/texture_mailbox_deleter_unittest.cc",
     "paint/discardable_image_map_unittest.cc",
     "paint/display_item_list_unittest.cc",
-    "paint/paint_op_buffer_unittest.cc",
     "quads/draw_polygon_unittest.cc",
     "quads/draw_quad_unittest.cc",
     "quads/nine_patch_generator_unittest.cc",
@@ -937,7 +934,6 @@
     "//cc/ipc",
     "//cc/ipc:interfaces",
     "//cc/paint",
-    "//cc/paint",
     "//cc/surfaces",
     "//cc/surfaces:surface_id",
     "//gpu",
diff --git a/cc/output/dc_layer_overlay.cc b/cc/output/dc_layer_overlay.cc
index 9a02f93..eda508e 100644
--- a/cc/output/dc_layer_overlay.cc
+++ b/cc/output/dc_layer_overlay.cc
@@ -30,6 +30,16 @@
   return DCLayerOverlayProcessor::DC_LAYER_SUCCESS;
 }
 
+// This returns the smallest rectangle in target space that contains the quad.
+gfx::RectF ClippedQuadRectangle(const DrawQuad* quad) {
+  gfx::RectF quad_rect = MathUtil::MapClippedRect(
+      quad->shared_quad_state->quad_to_target_transform,
+      gfx::RectF(quad->rect));
+  if (quad->shared_quad_state->is_clipped)
+    quad_rect.Intersect(gfx::RectF(quad->shared_quad_state->clip_rect));
+  return quad_rect;
+}
+
 // Find a rectangle containing all the quads in a list that occlude the area
 // in target_quad.
 gfx::RectF GetOcclusionBounds(const gfx::RectF& target_quad,
@@ -38,13 +48,11 @@
   gfx::RectF occlusion_bounding_box;
   for (auto overlap_iter = quad_list_begin; overlap_iter != quad_list_end;
        ++overlap_iter) {
-    gfx::RectF overlap_rect = MathUtil::MapClippedRect(
-        overlap_iter->shared_quad_state->quad_to_target_transform,
-        gfx::RectF(overlap_iter->rect));
     float opacity = overlap_iter->shared_quad_state->opacity;
     if (opacity < std::numeric_limits<float>::epsilon())
       continue;
     const DrawQuad* quad = *overlap_iter;
+    gfx::RectF overlap_rect = ClippedQuadRectangle(quad);
     if (quad->material == DrawQuad::SOLID_COLOR) {
       SkColor color = SolidColorDrawQuad::MaterialCast(quad)->color;
       float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
@@ -130,8 +138,7 @@
       continue;
     }
 
-    gfx::Rect quad_rectangle = MathUtil::MapEnclosingClippedRect(
-        it->shared_quad_state->quad_to_target_transform, it->rect);
+    gfx::Rect quad_rectangle = gfx::ToEnclosingRect(ClippedQuadRectangle(*it));
     gfx::RectF occlusion_bounding_box =
         GetOcclusionBounds(gfx::RectF(quad_rectangle), quad_list->begin(), it);
     if (occlusion_bounding_box.IsEmpty()) {
@@ -139,7 +146,7 @@
       // underneath it.
       if (it->shared_quad_state->quad_to_target_transform
               .Preserves2dAxisAlignment() &&
-          !display_rect_changed) {
+          !display_rect_changed && !it->ShouldDrawWithBlending()) {
         damage_rect->Subtract(quad_rectangle);
       }
       quad_list->EraseAndInvalidateAllPointers(it);
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index 2abe158..c989fbd 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -1873,6 +1873,80 @@
   }
 }
 
+TEST_F(DCLayerOverlayTest, ClipRect) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(features::kDirectCompositionUnderlays);
+
+  // Process twice. The second time through the overlay list shouldn't change,
+  // which will allow the damage rect to reflect just the changes in that
+  // frame.
+  for (size_t i = 0; i < 2; ++i) {
+    std::unique_ptr<RenderPass> pass = CreateRenderPass();
+    CreateOpaqueQuadAt(resource_provider_.get(),
+                       pass->shared_quad_state_list.back(), pass.get(),
+                       gfx::Rect(0, 2, 100, 100), SK_ColorWHITE);
+    pass->shared_quad_state_list.back()->is_clipped = true;
+    pass->shared_quad_state_list.back()->clip_rect = gfx::Rect(0, 3, 100, 100);
+    SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
+    shared_state->opacity = 1.f;
+    CreateFullscreenCandidateYUVVideoQuad(resource_provider_.get(),
+                                          shared_state, pass.get());
+    shared_state->is_clipped = true;
+    // Clipped rect shouldn't be overlapped by clipped opaque quad rect.
+    shared_state->clip_rect = gfx::Rect(0, 0, 100, 3);
+
+    DCLayerOverlayList dc_layer_list;
+    OverlayCandidateList overlay_list;
+    RenderPassFilterList render_pass_filters;
+    RenderPassFilterList render_pass_background_filters;
+    damage_rect_ = gfx::Rect(1, 1, 10, 10);
+    overlay_processor_->ProcessForOverlays(
+        resource_provider_.get(), pass.get(), render_pass_filters,
+        render_pass_background_filters, &overlay_list, nullptr, &dc_layer_list,
+        &damage_rect_, &content_bounds_);
+    EXPECT_EQ(0U, overlay_list.size());
+    EXPECT_EQ(1U, dc_layer_list.size());
+    // Because of clip rects the overlay isn't occluded and shouldn't be an
+    // underlay.
+    EXPECT_EQ(1, dc_layer_list.back().shared_state->z_order);
+    if (i == 1) {
+      // The damage rect should only contain contents that aren't in the
+      // clipped overlay rect.
+      EXPECT_EQ(gfx::Rect(1, 3, 10, 8), damage_rect_);
+    }
+  }
+}
+
+TEST_F(DCLayerOverlayTest, TransparentOnTop) {
+  base::test::ScopedFeatureList feature_list;
+
+  // Process twice. The second time through the overlay list shouldn't change,
+  // which will allow the damage rect to reflect just the changes in that
+  // frame.
+  for (size_t i = 0; i < 2; ++i) {
+    std::unique_ptr<RenderPass> pass = CreateRenderPass();
+    CreateFullscreenCandidateYUVVideoQuad(resource_provider_.get(),
+                                          pass->shared_quad_state_list.back(),
+                                          pass.get());
+    pass->shared_quad_state_list.back()->opacity = 0.5f;
+
+    DCLayerOverlayList dc_layer_list;
+    OverlayCandidateList overlay_list;
+    RenderPassFilterList render_pass_filters;
+    RenderPassFilterList render_pass_background_filters;
+    damage_rect_ = gfx::Rect(1, 1, 10, 10);
+    overlay_processor_->ProcessForOverlays(
+        resource_provider_.get(), pass.get(), render_pass_filters,
+        render_pass_background_filters, &overlay_list, nullptr, &dc_layer_list,
+        &damage_rect_, &content_bounds_);
+    EXPECT_EQ(0U, overlay_list.size());
+    EXPECT_EQ(1U, dc_layer_list.size());
+    EXPECT_EQ(1, dc_layer_list.back().shared_state->z_order);
+    // Quad isn't opaque, so underlying damage must remain the same.
+    EXPECT_EQ(gfx::Rect(1, 1, 10, 10), damage_rect_);
+  }
+}
+
 class OverlayInfoRendererGL : public GLRenderer {
  public:
   OverlayInfoRendererGL(const RendererSettings* settings,
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn
index 23b0f8b1..c442f04 100644
--- a/cc/paint/BUILD.gn
+++ b/cc/paint/BUILD.gn
@@ -32,17 +32,11 @@
     "paint_canvas.cc",
     "paint_canvas.h",
     "paint_export.h",
-    "paint_flags.cc",
     "paint_flags.h",
-    "paint_op_buffer.cc",
-    "paint_op_buffer.h",
-    "paint_record.cc",
     "paint_record.h",
     "paint_recorder.cc",
     "paint_recorder.h",
     "paint_shader.h",
-    "record_paint_canvas.cc",
-    "record_paint_canvas.h",
     "skia_paint_canvas.cc",
     "skia_paint_canvas.h",
     "transform_display_item.cc",
diff --git a/cc/paint/display_item_list.cc b/cc/paint/display_item_list.cc
index c1b069548..8359948 100644
--- a/cc/paint/display_item_list.cc
+++ b/cc/paint/display_item_list.cc
@@ -100,13 +100,9 @@
       if (canvas->quickReject(item.picture->cullRect()))
         break;
 
-      // TODO(enne): Maybe the PaintRecord itself could know whether this
-      // was needed?  It's not clear whether these save/restore semantics
-      // that SkPicture handles during playback are things that should be
-      // kept around.
-      canvas->save();
+      // SkPicture always does a wrapping save/restore on the canvas, so it is
+      // not necessary here.
       item.picture->playback(canvas, callback);
-      canvas->restore();
       break;
     }
     case DisplayItem::FLOAT_CLIP: {
@@ -180,33 +176,6 @@
   canvas->restore();
 }
 
-// Atttempts to merge a CompositingDisplayItem and DrawingDisplayItem
-// into a single "draw with alpha".  This function returns true if
-// it was successful.  If false, then the caller is responsible for
-// drawing these items.  This is a DisplayItemList version of the
-// SkRecord optimization SkRecordNoopSaveLayerDrawRestores.
-static bool MergeAndDrawIfPossible(const CompositingDisplayItem& save_item,
-                                   const DrawingDisplayItem& draw_item,
-                                   SkCanvas* canvas) {
-  if (save_item.color_filter)
-    return false;
-  if (save_item.xfermode != SkBlendMode::kSrcOver)
-    return false;
-  // TODO(enne): I believe that lcd_text_requires_opaque_layer is not
-  // relevant here and that lcd text is preserved post merge, but I haven't
-  // tested that.
-  const PaintRecord* record = draw_item.picture.get();
-  if (record->approximateOpCount() != 1)
-    return false;
-
-  const PaintOp* op = record->GetFirstOp();
-  if (!op->IsDrawOp())
-    return false;
-
-  op->RasterWithAlpha(canvas, save_item.alpha);
-  return true;
-}
-
 void DisplayItemList::Raster(SkCanvas* canvas,
                              SkPicture::AbortCallback* callback) const {
   gfx::Rect canvas_playback_rect;
@@ -215,33 +184,14 @@
 
   std::vector<size_t> indices;
   rtree_.Search(canvas_playback_rect, &indices);
-  for (size_t i = 0; i < indices.size(); ++i) {
+  for (size_t index : indices) {
+    RasterItem(items_[index], canvas, callback);
+
     // We use a callback during solid color analysis on the compositor thread to
     // break out early. Since we're handling a sequence of pictures via rtree
     // query results ourselves, we have to respect the callback and early out.
     if (callback && callback->abort())
       break;
-
-    const DisplayItem& item = items_[indices[i]];
-    // Optimize empty begin/end compositing and merge begin/draw/end compositing
-    // where possible.
-    // TODO(enne): remove empty clips here too?
-    // TODO(enne): does this happen recursively? Or is this good enough?
-    if (i < indices.size() - 2 && item.type == DisplayItem::COMPOSITING) {
-      const DisplayItem& second = items_[indices[i + 1]];
-      const DisplayItem& third = items_[indices[i + 2]];
-      if (second.type == DisplayItem::DRAWING &&
-          third.type == DisplayItem::END_COMPOSITING) {
-        if (MergeAndDrawIfPossible(
-                static_cast<const CompositingDisplayItem&>(item),
-                static_cast<const DrawingDisplayItem&>(second), canvas)) {
-          i += 2;
-          continue;
-        }
-      }
-    }
-
-    RasterItem(item, canvas, callback);
   }
 }
 
diff --git a/cc/paint/display_item_list_unittest.cc b/cc/paint/display_item_list_unittest.cc
index b166229c6..f1b9e75 100644
--- a/cc/paint/display_item_list_unittest.cc
+++ b/cc/paint/display_item_list_unittest.cc
@@ -17,17 +17,16 @@
 #include "cc/paint/compositing_display_item.h"
 #include "cc/paint/drawing_display_item.h"
 #include "cc/paint/filter_display_item.h"
+
 #include "cc/paint/float_clip_display_item.h"
 #include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_flags.h"
 #include "cc/paint/paint_record.h"
 #include "cc/paint/paint_recorder.h"
-#include "cc/paint/skia_paint_canvas.h"
 #include "cc/paint/transform_display_item.h"
 #include "cc/test/geometry_test_utils.h"
 #include "cc/test/pixel_test_utils.h"
 #include "cc/test/skia_common.h"
-#include "cc/test/test_skcanvas.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -81,19 +80,6 @@
   return recorder.finishRecordingAsPicture();
 }
 
-sk_sp<const PaintRecord> CreateRectPictureWithAlpha(const gfx::Rect& bounds,
-                                                    uint8_t alpha) {
-  PaintRecorder recorder;
-  PaintCanvas* canvas =
-      recorder.beginRecording(bounds.width(), bounds.height());
-  PaintFlags flags;
-  flags.setAlpha(alpha);
-  canvas->drawRect(
-      SkRect::MakeXYWH(bounds.x(), bounds.y(), bounds.width(), bounds.height()),
-      flags);
-  return recorder.finishRecordingAsPicture();
-}
-
 void AppendFirstSerializationTestPicture(scoped_refptr<DisplayItemList> list,
                                          const gfx::Size& layer_size) {
   gfx::PointF offset(2.f, 3.f);
@@ -718,110 +704,4 @@
   EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(3));
 }
 
-// Verify that raster time optimizations for compositing item / draw single op /
-// end compositing item can be collapsed together into a single draw op
-// with the opacity from the compositing item folded in.
-TEST(DisplayItemListTest, SaveDrawRestore) {
-  auto list = make_scoped_refptr(new DisplayItemList);
-
-  list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>(
-      80, SkBlendMode::kSrcOver, nullptr, nullptr, false);
-  list->CreateAndAppendDrawingItem<DrawingDisplayItem>(
-      kVisualRect, CreateRectPictureWithAlpha(kVisualRect, 40));
-  list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>();
-  list->Finalize();
-
-  SaveCountingCanvas canvas;
-  list->Raster(&canvas, nullptr);
-
-  EXPECT_EQ(0, canvas.save_count_);
-  EXPECT_EQ(0, canvas.restore_count_);
-  EXPECT_EQ(gfx::RectToSkRect(kVisualRect), canvas.draw_rect_);
-
-  float expected_alpha = 80 * 40 / 255.f;
-  EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f);
-}
-
-// Verify that compositing item / end compositing item is a noop.
-// Here we're testing that Skia does an optimization that skips
-// save/restore with nothing in between.  If skia stops doing this
-// then we should reimplement this optimization in display list raster.
-TEST(DisplayItemListTest, SaveRestoreNoops) {
-  auto list = make_scoped_refptr(new DisplayItemList);
-
-  list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>(
-      80, SkBlendMode::kSrcOver, nullptr, nullptr, false);
-  list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>();
-  list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>(
-      255, SkBlendMode::kSrcOver, nullptr, nullptr, false);
-  list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>();
-  list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>(
-      255, SkBlendMode::kSrc, nullptr, nullptr, false);
-  list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>();
-  list->Finalize();
-
-  SaveCountingCanvas canvas;
-  list->Raster(&canvas, nullptr);
-
-  EXPECT_EQ(0, canvas.save_count_);
-  EXPECT_EQ(0, canvas.restore_count_);
-}
-
-// The same as SaveDrawRestore, but with save flags that prevent the
-// optimization.
-TEST(DisplayItemListTest, SaveDrawRestoreFail_BadSaveFlags) {
-  auto list = make_scoped_refptr(new DisplayItemList);
-
-  // Use a blend mode that's not compatible with the SaveDrawRestore
-  // optimization.
-  list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>(
-      80, SkBlendMode::kSrc, nullptr, nullptr, false);
-  list->CreateAndAppendDrawingItem<DrawingDisplayItem>(
-      kVisualRect, CreateRectPictureWithAlpha(kVisualRect, 40));
-  list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>();
-  list->Finalize();
-
-  SaveCountingCanvas canvas;
-  list->Raster(&canvas, nullptr);
-
-  EXPECT_EQ(1, canvas.save_count_);
-  EXPECT_EQ(1, canvas.restore_count_);
-  EXPECT_EQ(gfx::RectToSkRect(kVisualRect), canvas.draw_rect_);
-  EXPECT_LE(40, canvas.paint_.getAlpha());
-}
-
-// The same as SaveDrawRestore, but with too many ops in the PaintRecord.
-TEST(DisplayItemListTest, SaveDrawRestoreFail_TooManyOps) {
-  sk_sp<const PaintRecord> record;
-  {
-    PaintRecorder recorder;
-    PaintCanvas* canvas =
-        recorder.beginRecording(kVisualRect.width(), kVisualRect.height());
-    PaintFlags flags;
-    flags.setAlpha(40);
-    canvas->drawRect(gfx::RectToSkRect(kVisualRect), flags);
-    // Add an extra op here.
-    canvas->drawRect(gfx::RectToSkRect(kVisualRect), flags);
-    record = recorder.finishRecordingAsPicture();
-  }
-  EXPECT_GT(record->approximateOpCount(), 1);
-
-  auto list = make_scoped_refptr(new DisplayItemList);
-
-  list->CreateAndAppendPairedBeginItem<CompositingDisplayItem>(
-      80, SkBlendMode::kSrcOver, nullptr, nullptr, false);
-  list->CreateAndAppendDrawingItem<DrawingDisplayItem>(kVisualRect,
-                                                       std::move(record));
-  list->CreateAndAppendPairedEndItem<EndCompositingDisplayItem>();
-  list->Finalize();
-
-  SaveCountingCanvas canvas;
-  list->Raster(&canvas, nullptr);
-
-  EXPECT_EQ(1, canvas.save_count_);
-  EXPECT_EQ(1, canvas.restore_count_);
-  EXPECT_EQ(gfx::RectToSkRect(kVisualRect), canvas.draw_rect_);
-  EXPECT_LE(40, canvas.paint_.getAlpha());
-}
-
 }  // namespace cc
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index 199d9d9..daacc301 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -10,24 +10,19 @@
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
 #include "cc/paint/paint_export.h"
+#include "cc/paint/paint_record.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 
 namespace cc {
 
 class DisplayItemList;
 class PaintFlags;
-class PaintOpBuffer;
-
-using PaintRecord = PaintOpBuffer;
 
 class CC_PAINT_EXPORT PaintCanvas {
  public:
   virtual ~PaintCanvas() {}
 
   virtual SkMetaData& getMetaData() = 0;
-
-  // TODO(enne): this only appears to mostly be used to determine if this is
-  // recording or not, so could be simplified or removed.
   virtual SkImageInfo imageInfo() const = 0;
 
   // TODO(enne): It would be nice to get rid of flush() entirely, as it
@@ -46,7 +41,7 @@
                            int y) = 0;
   virtual int save() = 0;
   virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0;
-  virtual int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) = 0;
+  virtual int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) = 0;
 
   virtual void restore() = 0;
   virtual int getSaveCount() const = 0;
@@ -97,8 +92,6 @@
   virtual bool getDeviceClipBounds(SkIRect* bounds) const = 0;
   virtual void drawColor(SkColor color, SkBlendMode mode) = 0;
   void drawColor(SkColor color) { drawColor(color, SkBlendMode::kSrcOver); }
-
-  // TODO(enne): This is a synonym for drawColor with kSrc.  Remove it.
   virtual void clear(SkColor color) = 0;
 
   virtual void drawLine(SkScalar x0,
diff --git a/cc/paint/paint_flags.cc b/cc/paint/paint_flags.cc
deleted file mode 100644
index e16a8bb..0000000
--- a/cc/paint/paint_flags.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/paint/paint_flags.h"
-
-namespace cc {
-
-bool PaintFlags::IsSimpleOpacity() const {
-  uint32_t color = getColor();
-  if (SK_ColorTRANSPARENT != SkColorSetA(color, SK_AlphaTRANSPARENT))
-    return false;
-  if (!isSrcOver())
-    return false;
-  if (getLooper())
-    return false;
-  if (getPathEffect())
-    return false;
-  if (getShader())
-    return false;
-  if (getMaskFilter())
-    return false;
-  if (getColorFilter())
-    return false;
-  if (getImageFilter())
-    return false;
-  return true;
-}
-
-bool PaintFlags::SupportsFoldingAlpha() const {
-  if (!isSrcOver())
-    return false;
-  if (getColorFilter())
-    return false;
-  if (getImageFilter())
-    return false;
-  if (getLooper())
-    return false;
-  return true;
-}
-
-}  // namespace cc
diff --git a/cc/paint/paint_flags.h b/cc/paint/paint_flags.h
index 37b460d6..b7e96c6 100644
--- a/cc/paint/paint_flags.h
+++ b/cc/paint/paint_flags.h
@@ -7,6 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "cc/paint/paint_export.h"
+#include "cc/paint/paint_shader.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkColorFilter.h"
 #include "third_party/skia/include/core/SkDrawLooper.h"
@@ -18,8 +19,6 @@
 
 namespace cc {
 
-using PaintShader = SkShader;
-
 class CC_PAINT_EXPORT PaintFlags {
  public:
   enum Style {
@@ -199,14 +198,6 @@
     return paint_.computeFastBounds(orig, storage);
   }
 
-  bool operator==(const PaintFlags& flags) { return flags.paint_ == paint_; }
-  bool operator!=(const PaintFlags& flags) { return flags.paint_ != paint_; }
-
-  // Returns true if this just represents an opacity blend when
-  // used as saveLayer flags.
-  bool IsSimpleOpacity() const;
-  bool SupportsFoldingAlpha() const;
-
  private:
   friend const SkPaint& ToSkPaint(const PaintFlags& flags);
   friend const SkPaint* ToSkPaint(const PaintFlags* flags);
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
deleted file mode 100644
index a0170bd..0000000
--- a/cc/paint/paint_op_buffer.cc
+++ /dev/null
@@ -1,555 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/paint/paint_op_buffer.h"
-
-#include "cc/paint/display_item_list.h"
-#include "cc/paint/paint_record.h"
-#include "third_party/skia/include/core/SkAnnotation.h"
-
-namespace cc {
-
-#define TYPES(M)           \
-  M(AnnotateOp)            \
-  M(ClipPathOp)            \
-  M(ClipRectOp)            \
-  M(ClipRRectOp)           \
-  M(ConcatOp)              \
-  M(DrawArcOp)             \
-  M(DrawCircleOp)          \
-  M(DrawColorOp)           \
-  M(DrawDisplayItemListOp) \
-  M(DrawDRRectOp)          \
-  M(DrawImageOp)           \
-  M(DrawImageRectOp)       \
-  M(DrawIRectOp)           \
-  M(DrawLineOp)            \
-  M(DrawOvalOp)            \
-  M(DrawPathOp)            \
-  M(DrawPosTextOp)         \
-  M(DrawRecordOp)          \
-  M(DrawRectOp)            \
-  M(DrawRRectOp)           \
-  M(DrawTextOp)            \
-  M(DrawTextBlobOp)        \
-  M(NoopOp)                \
-  M(RestoreOp)             \
-  M(RotateOp)              \
-  M(SaveOp)                \
-  M(SaveLayerOp)           \
-  M(SaveLayerAlphaOp)      \
-  M(ScaleOp)               \
-  M(SetMatrixOp)           \
-  M(TranslateOp)
-
-// Helper template to share common code for RasterWithAlpha when paint ops
-// have or don't have PaintFlags.
-template <typename T, bool HasFlags>
-struct Rasterizer {
-  static void Raster(const T* op,
-                     SkCanvas* canvas,
-                     const SkMatrix& original_ctm) {
-    // Paint ops with kHasPaintFlags need to declare RasterWithPaintFlags
-    // otherwise, the paint op needs its own Raster function.  Without its
-    // own, this becomes an infinite loop as PaintOp::Raster calls itself.
-    static_assert(
-        !std::is_same<decltype(&PaintOp::Raster), decltype(&T::Raster)>::value,
-        "No Raster function");
-
-    op->Raster(canvas);
-  }
-  static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) {
-    DCHECK(T::kIsDrawOp);
-    // TODO(enne): is it ok to just drop the bounds here?
-    canvas->saveLayerAlpha(nullptr, alpha);
-    op->Raster(canvas);
-    canvas->restore();
-  }
-};
-
-template <typename T>
-struct Rasterizer<T, true> {
-  static void Raster(const T* op,
-                     SkCanvas* canvas,
-                     const SkMatrix& original_ctm) {
-    op->RasterWithFlags(canvas, op->flags);
-  }
-  static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) {
-    DCHECK(T::kIsDrawOp);
-    SkMatrix unused_matrix;
-    if (alpha == 255) {
-      Raster(op, canvas, unused_matrix);
-    } else if (op->flags.SupportsFoldingAlpha()) {
-      PaintFlags flags = op->flags;
-      flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha));
-      op->RasterWithFlags(canvas, flags);
-    } else {
-      canvas->saveLayerAlpha(nullptr, alpha);
-      op->RasterWithFlags(canvas, op->flags);
-      canvas->restore();
-    }
-  }
-};
-
-template <>
-struct Rasterizer<SetMatrixOp, false> {
-  static void Raster(const SetMatrixOp* op,
-                     SkCanvas* canvas,
-                     const SkMatrix& original_ctm) {
-    op->Raster(canvas, original_ctm);
-  }
-  static void RasterWithAlpha(const SetMatrixOp* op,
-                              SkCanvas* canvas,
-                              uint8_t alpha) {
-    NOTREACHED();
-  }
-};
-
-template <>
-struct Rasterizer<DrawRecordOp, false> {
-  static void Raster(const DrawRecordOp* op,
-                     SkCanvas* canvas,
-                     const SkMatrix& original_ctm) {
-    op->Raster(canvas);
-  }
-  static void RasterWithAlpha(const DrawRecordOp* op,
-                              SkCanvas* canvas,
-                              uint8_t alpha) {
-    // This "looking into records" optimization is done here instead of
-    // in the PaintOpBuffer::Raster function as DisplayItemList calls
-    // into RasterWithAlpha directly.
-    if (op->record->approximateOpCount() == 1) {
-      op->record->GetFirstOp()->RasterWithAlpha(canvas, alpha);
-      return;
-    }
-
-    canvas->saveLayerAlpha(nullptr, alpha);
-    op->Raster(canvas);
-    canvas->restore();
-  }
-};
-
-// TODO(enne): partially specialize RasterWithAlpha for draw color?
-
-static constexpr size_t kNumOpTypes =
-    static_cast<size_t>(PaintOpType::LastPaintOpType) + 1;
-
-// Verify that every op is in the TYPES macro.
-#define M(T) +1
-static_assert(kNumOpTypes == TYPES(M), "Missing op in list");
-#undef M
-
-using RasterFunction = void (*)(const PaintOp* op,
-                                SkCanvas* canvas,
-                                const SkMatrix& original_ctm);
-#define M(T)                                                              \
-  [](const PaintOp* op, SkCanvas* canvas, const SkMatrix& original_ctm) { \
-    Rasterizer<T, T::kHasPaintFlags>::Raster(static_cast<const T*>(op),   \
-                                             canvas, original_ctm);       \
-  },
-static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)};
-#undef M
-
-using RasterAlphaFunction = void (*)(const PaintOp* op,
-                                     SkCanvas* canvas,
-                                     uint8_t alpha);
-#define M(T) \
-  T::kIsDrawOp ? \
-  [](const PaintOp* op, SkCanvas* canvas, uint8_t alpha) { \
-    Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \
-        static_cast<const T*>(op), canvas, alpha); \
-  } : static_cast<RasterAlphaFunction>(nullptr),
-static const RasterAlphaFunction g_raster_alpha_functions[kNumOpTypes] = {
-    TYPES(M)};
-#undef M
-
-// Most state ops (matrix, clip, save, restore) have a trivial destructor.
-// TODO(enne): evaluate if we need the nullptr optimization or if
-// we even need to differentiate trivial destructors here.
-using VoidFunction = void (*)(PaintOp* op);
-#define M(T)                                           \
-  !std::is_trivially_destructible<T>::value            \
-      ? [](PaintOp* op) { static_cast<T*>(op)->~T(); } \
-      : static_cast<VoidFunction>(nullptr),
-static const VoidFunction g_destructor_functions[kNumOpTypes] = {TYPES(M)};
-#undef M
-
-#define M(T) T::kIsDrawOp,
-static bool g_is_draw_op[kNumOpTypes] = {TYPES(M)};
-#undef M
-
-#define M(T)                                         \
-  static_assert(sizeof(T) <= sizeof(LargestPaintOp), \
-                #T " must be no bigger than LargestPaintOp");
-TYPES(M);
-#undef M
-
-#undef TYPES
-
-SkRect PaintOp::kUnsetRect = {SK_ScalarInfinity, 0, 0, 0};
-
-void AnnotateOp::Raster(SkCanvas* canvas) const {
-  switch (annotation_type) {
-    case PaintCanvas::AnnotationType::URL:
-      SkAnnotateRectWithURL(canvas, rect, data.get());
-      break;
-    case PaintCanvas::AnnotationType::LINK_TO_DESTINATION:
-      SkAnnotateLinkToDestination(canvas, rect, data.get());
-      break;
-    case PaintCanvas::AnnotationType::NAMED_DESTINATION: {
-      SkPoint point = SkPoint::Make(rect.x(), rect.y());
-      SkAnnotateNamedDestination(canvas, point, data.get());
-      break;
-    }
-  }
-}
-
-void ClipPathOp::Raster(SkCanvas* canvas) const {
-  canvas->clipPath(path, op, antialias);
-}
-
-void ClipRectOp::Raster(SkCanvas* canvas) const {
-  canvas->clipRect(rect, op, antialias);
-}
-
-void ClipRRectOp::Raster(SkCanvas* canvas) const {
-  canvas->clipRRect(rrect, op, antialias);
-}
-
-void ConcatOp::Raster(SkCanvas* canvas) const {
-  canvas->concat(matrix);
-}
-
-void DrawArcOp::RasterWithFlags(SkCanvas* canvas,
-                                const PaintFlags& flags) const {
-  canvas->drawArc(oval, start_angle, sweep_angle, use_center, ToSkPaint(flags));
-}
-
-void DrawCircleOp::RasterWithFlags(SkCanvas* canvas,
-                                   const PaintFlags& flags) const {
-  canvas->drawCircle(cx, cy, radius, ToSkPaint(flags));
-}
-
-void DrawColorOp::Raster(SkCanvas* canvas) const {
-  canvas->drawColor(color, mode);
-}
-
-void DrawDisplayItemListOp::Raster(SkCanvas* canvas) const {
-  list->Raster(canvas, nullptr);
-}
-
-void DrawDRRectOp::RasterWithFlags(SkCanvas* canvas,
-                                   const PaintFlags& flags) const {
-  canvas->drawDRRect(outer, inner, ToSkPaint(flags));
-}
-
-void DrawImageOp::RasterWithFlags(SkCanvas* canvas,
-                                  const PaintFlags& flags) const {
-  canvas->drawImage(image.get(), left, top, ToSkPaint(&flags));
-}
-
-void DrawImageRectOp::RasterWithFlags(SkCanvas* canvas,
-                                      const PaintFlags& flags) const {
-  // TODO(enne): Probably PaintCanvas should just use the skia enum directly.
-  SkCanvas::SrcRectConstraint skconstraint =
-      static_cast<SkCanvas::SrcRectConstraint>(constraint);
-  canvas->drawImageRect(image.get(), src, dst, ToSkPaint(&flags), skconstraint);
-}
-
-void DrawIRectOp::RasterWithFlags(SkCanvas* canvas,
-                                  const PaintFlags& flags) const {
-  canvas->drawIRect(rect, ToSkPaint(flags));
-}
-
-void DrawLineOp::RasterWithFlags(SkCanvas* canvas,
-                                 const PaintFlags& flags) const {
-  canvas->drawLine(x0, y0, x1, y1, ToSkPaint(flags));
-}
-
-void DrawOvalOp::RasterWithFlags(SkCanvas* canvas,
-                                 const PaintFlags& flags) const {
-  canvas->drawOval(oval, ToSkPaint(flags));
-}
-
-void DrawPathOp::RasterWithFlags(SkCanvas* canvas,
-                                 const PaintFlags& flags) const {
-  canvas->drawPath(path, ToSkPaint(flags));
-}
-
-void DrawPosTextOp::RasterWithFlags(SkCanvas* canvas,
-                                    const PaintFlags& flags) const {
-  canvas->drawPosText(paint_op_data(this), bytes, paint_op_array<SkPoint>(this),
-                      ToSkPaint(flags));
-}
-
-void DrawRecordOp::Raster(SkCanvas* canvas) const {
-  record->playback(canvas);
-}
-
-void DrawRectOp::RasterWithFlags(SkCanvas* canvas,
-                                 const PaintFlags& flags) const {
-  canvas->drawRect(rect, ToSkPaint(flags));
-}
-
-void DrawRRectOp::RasterWithFlags(SkCanvas* canvas,
-                                  const PaintFlags& flags) const {
-  canvas->drawRRect(rrect, ToSkPaint(flags));
-}
-
-void DrawTextOp::RasterWithFlags(SkCanvas* canvas,
-                                 const PaintFlags& flags) const {
-  canvas->drawText(paint_op_data(this), bytes, x, y, ToSkPaint(flags));
-}
-
-void DrawTextBlobOp::RasterWithFlags(SkCanvas* canvas,
-                                     const PaintFlags& flags) const {
-  canvas->drawTextBlob(blob.get(), x, y, ToSkPaint(flags));
-}
-
-void RestoreOp::Raster(SkCanvas* canvas) const {
-  canvas->restore();
-}
-
-void RotateOp::Raster(SkCanvas* canvas) const {
-  canvas->rotate(degrees);
-}
-
-void SaveOp::Raster(SkCanvas* canvas) const {
-  canvas->save();
-}
-
-void SaveLayerOp::RasterWithFlags(SkCanvas* canvas,
-                                  const PaintFlags& flags) const {
-  // See PaintOp::kUnsetRect
-  bool unset = bounds.left() == SK_ScalarInfinity;
-
-  canvas->saveLayer(unset ? nullptr : &bounds, ToSkPaint(&flags));
-}
-
-void SaveLayerAlphaOp::Raster(SkCanvas* canvas) const {
-  // See PaintOp::kUnsetRect
-  bool unset = bounds.left() == SK_ScalarInfinity;
-  canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha);
-}
-
-void ScaleOp::Raster(SkCanvas* canvas) const {
-  canvas->scale(sx, sy);
-}
-
-void SetMatrixOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const {
-  canvas->setMatrix(SkMatrix::Concat(original_ctm, matrix));
-}
-
-void TranslateOp::Raster(SkCanvas* canvas) const {
-  canvas->translate(dx, dy);
-}
-
-bool PaintOp::IsDrawOp() const {
-  return g_is_draw_op[type];
-}
-
-void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const {
-  g_raster_functions[type](this, canvas, original_ctm);
-}
-
-void PaintOp::RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const {
-  g_raster_alpha_functions[type](this, canvas, alpha);
-}
-
-DrawDisplayItemListOp::DrawDisplayItemListOp(
-    scoped_refptr<DisplayItemList> list)
-    : list(list) {}
-
-size_t DrawDisplayItemListOp::AdditionalBytesUsed() const {
-  return list->ApproximateMemoryUsage();
-}
-
-int ClipPathOp::CountSlowPaths() const {
-  return antialias && !path.isConvex() ? 1 : 0;
-}
-
-int DrawLineOp::CountSlowPaths() const {
-  if (const SkPathEffect* effect = flags.getPathEffect()) {
-    SkPathEffect::DashInfo info;
-    SkPathEffect::DashType dashType = effect->asADash(&info);
-    if (flags.getStrokeCap() != PaintFlags::kRound_Cap &&
-        dashType == SkPathEffect::kDash_DashType && info.fCount == 2) {
-      // The PaintFlags will count this as 1, so uncount that here as
-      // this kind of line is special cased and not slow.
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int DrawPathOp::CountSlowPaths() const {
-  // This logic is copied from SkPathCounter instead of attempting to expose
-  // that from Skia.
-  if (!flags.isAntiAlias() || path.isConvex())
-    return 0;
-
-  PaintFlags::Style paintStyle = flags.getStyle();
-  const SkRect& pathBounds = path.getBounds();
-  if (paintStyle == PaintFlags::kStroke_Style && flags.getStrokeWidth() == 0) {
-    // AA hairline concave path is not slow.
-    return 0;
-  } else if (paintStyle == PaintFlags::kFill_Style &&
-             pathBounds.width() < 64.f && pathBounds.height() < 64.f &&
-             !path.isVolatile()) {
-    // AADF eligible concave path is not slow.
-    return 0;
-  } else {
-    return 1;
-  }
-}
-
-AnnotateOp::AnnotateOp(PaintCanvas::AnnotationType annotation_type,
-                       const SkRect& rect,
-                       sk_sp<SkData> data)
-    : annotation_type(annotation_type), rect(rect), data(std::move(data)) {}
-
-AnnotateOp::~AnnotateOp() = default;
-
-DrawDisplayItemListOp::~DrawDisplayItemListOp() = default;
-
-DrawImageOp::DrawImageOp(sk_sp<const SkImage> image,
-                         SkScalar left,
-                         SkScalar top,
-                         const PaintFlags* flags)
-    : image(std::move(image)),
-      left(left),
-      top(top),
-      flags(flags ? *flags : PaintFlags()) {}
-
-DrawImageOp::~DrawImageOp() = default;
-
-DrawImageRectOp::DrawImageRectOp(sk_sp<const SkImage> image,
-                                 const SkRect& src,
-                                 const SkRect& dst,
-                                 const PaintFlags* flags,
-                                 PaintCanvas::SrcRectConstraint constraint)
-    : image(std::move(image)),
-      flags(flags ? *flags : PaintFlags()),
-      src(src),
-      dst(dst),
-      constraint(constraint) {}
-
-DrawImageRectOp::~DrawImageRectOp() = default;
-
-DrawPosTextOp::DrawPosTextOp(size_t bytes,
-                             size_t count,
-                             const PaintFlags& flags)
-    : PaintOpWithDataArray(bytes, count), flags(flags) {}
-
-DrawPosTextOp::~DrawPosTextOp() = default;
-
-DrawRecordOp::DrawRecordOp(sk_sp<const PaintRecord> record)
-    : record(std::move(record)) {}
-
-DrawRecordOp::~DrawRecordOp() = default;
-
-size_t DrawRecordOp::AdditionalBytesUsed() const {
-  return record->approximateBytesUsed();
-}
-
-DrawTextBlobOp::DrawTextBlobOp(sk_sp<SkTextBlob> blob,
-                               SkScalar x,
-                               SkScalar y,
-                               const PaintFlags& flags)
-    : blob(std::move(blob)), x(x), y(y), flags(flags) {}
-
-DrawTextBlobOp::~DrawTextBlobOp() = default;
-
-PaintOpBuffer::PaintOpBuffer() : cull_rect_(SkRect::MakeEmpty()) {}
-
-PaintOpBuffer::PaintOpBuffer(const SkRect& cull_rect) : cull_rect_(cull_rect) {}
-
-PaintOpBuffer::~PaintOpBuffer() {
-  Reset();
-}
-
-void PaintOpBuffer::Reset() {
-  for (auto* op : Iterator(this)) {
-    auto func = g_destructor_functions[op->type];
-    if (func)
-      func(op);
-  }
-
-  // Leave data_ allocated, reserved_ unchanged.
-  used_ = 0;
-  op_count_ = 0;
-  num_slow_paths_ = 0;
-}
-
-void PaintOpBuffer::playback(SkCanvas* canvas) const {
-  // TODO(enne): a PaintRecord that contains a SetMatrix assumes that the
-  // SetMatrix is local to that PaintRecord itself.  Said differently, if you
-  // translate(x, y), then draw a paint record with a SetMatrix(identity),
-  // the translation should be preserved instead of clobbering the top level
-  // transform.  This could probably be done more efficiently.
-  SkMatrix original = canvas->getTotalMatrix();
-
-  for (Iterator iter(this); iter; ++iter) {
-    // Optimize out save/restores or save/draw/restore that can be a single
-    // draw.  See also: similar code in SkRecordOpts and cc's DisplayItemList.
-    // TODO(enne): consider making this recursive?
-    const PaintOp* op = *iter;
-    if (op->GetType() == PaintOpType::SaveLayerAlpha) {
-      const PaintOp* second = iter.peek1();
-      if (second) {
-        if (second->GetType() == PaintOpType::Restore) {
-          ++iter;
-          continue;
-        }
-        if (second->IsDrawOp()) {
-          const PaintOp* third = iter.peek2();
-          if (third && third->GetType() == PaintOpType::Restore) {
-            const SaveLayerAlphaOp* save_op =
-                static_cast<const SaveLayerAlphaOp*>(op);
-            second->RasterWithAlpha(canvas, save_op->alpha);
-            ++iter;
-            ++iter;
-            continue;
-          }
-        }
-      }
-    }
-    // TODO(enne): skip SaveLayer followed by restore with nothing in
-    // between, however SaveLayer with image filters on it (or maybe
-    // other PaintFlags options) are not a noop.  Figure out what these
-    // are so we can skip them correctly.
-
-    op->Raster(canvas, original);
-  }
-}
-
-void PaintOpBuffer::playback(SkCanvas* canvas,
-                             SkPicture::AbortCallback* callback) const {
-  // The abort callback is only used for analysis, in general, so
-  // this playback code can be more straightforward and not do the
-  // optimizations in the other function.
-  if (!callback) {
-    playback(canvas);
-    return;
-  }
-
-  SkMatrix original = canvas->getTotalMatrix();
-
-  // TODO(enne): ideally callers would just iterate themselves and we
-  // can remove the entire notion of an abort callback.
-  for (auto* op : Iterator(this)) {
-    op->Raster(canvas, original);
-    if (callback && callback->abort())
-      return;
-  }
-}
-
-void PaintOpBuffer::ShrinkToFit() {
-  if (!used_ || used_ == reserved_)
-    return;
-  data_.realloc(used_);
-  reserved_ = used_;
-}
-
-}  // namespace cc
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
deleted file mode 100644
index 03a4e6b..0000000
--- a/cc/paint/paint_op_buffer.h
+++ /dev/null
@@ -1,782 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_PAINT_PAINT_OP_BUFFER_H_
-#define CC_PAINT_PAINT_OP_BUFFER_H_
-
-#include <stdint.h>
-
-#include "base/logging.h"
-#include "cc/paint/paint_canvas.h"
-#include "cc/paint/paint_export.h"
-#include "cc/paint/paint_flags.h"
-#include "third_party/skia/include/core/SkPicture.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkTextBlob.h"
-
-// PaintOpBuffer is a reimplementation of SkLiteDL.
-// See: third_party/skia/src/core/SkLiteDL.h.
-
-namespace cc {
-
-class DisplayItemList;
-
-class ThreadsafeMatrix : public SkMatrix {
- public:
-  explicit ThreadsafeMatrix(const SkMatrix& matrix) : SkMatrix(matrix) {
-    (void)getType();
-  }
-};
-
-class ThreadsafePath : public SkPath {
- public:
-  explicit ThreadsafePath(const SkPath& path) : SkPath(path) {
-    updateBoundsCache();
-  }
-};
-
-enum class PaintOpType : uint8_t {
-  Annotate,
-  ClipPath,
-  ClipRect,
-  ClipRRect,
-  Concat,
-  DrawArc,
-  DrawCircle,
-  DrawColor,
-  DrawDisplayItemList,
-  DrawDRRect,
-  DrawImage,
-  DrawImageRect,
-  DrawIRect,
-  DrawLine,
-  DrawOval,
-  DrawPath,
-  DrawPosText,
-  DrawRecord,
-  DrawRect,
-  DrawRRect,
-  DrawText,
-  DrawTextBlob,
-  Noop,
-  Restore,
-  Rotate,
-  Save,
-  SaveLayer,
-  SaveLayerAlpha,
-  Scale,
-  SetMatrix,
-  Translate,
-  LastPaintOpType = Translate,
-};
-
-struct CC_PAINT_EXPORT PaintOp {
-  uint32_t type : 8;
-  uint32_t skip : 24;
-
-  PaintOpType GetType() const { return static_cast<PaintOpType>(type); }
-
-  void Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const;
-  bool IsDrawOp() const;
-
-  // Only valid for draw ops.
-  void RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const;
-
-  int CountSlowPaths() const { return 0; }
-
-  // Returns the number of bytes used by this op in referenced sub records
-  // and display lists.  This doesn't count other objects like paths or blobs.
-  size_t AdditionalBytesUsed() const { return 0; }
-
-  static constexpr bool kIsDrawOp = false;
-  // If an op has |kHasPaintFlags| set to true, it must:
-  // (1) Provide a PaintFlags member called |flags|
-  // (2) Provide a RasterWithFlags function instead of a Raster function.
-  static constexpr bool kHasPaintFlags = false;
-  static SkRect kUnsetRect;
-};
-
-struct PaintOpWithData : PaintOp {
-  // Having data is just a helper for ops that have a varying amount of data and
-  // want a way to store that inline.  This is for ops that pass in a
-  // void* and a length.
-  explicit PaintOpWithData(size_t bytes) : bytes(bytes) {}
-
-  // Get data out by calling paint_op_data.  This can't be part of the class
-  // because it needs to know the size of the derived type.
-  size_t bytes;
-};
-
-template <typename T>
-const void* paint_op_data(const T* op) {
-  static_assert(std::is_convertible<T, PaintOpWithData>::value,
-                "T is not a PaintOpWithData");
-  // Arbitrary data for a PaintOp is stored after the PaintOp itself
-  // in the PaintOpBuffer.  Therefore, to access this data, it's
-  // pointer math to increment past the size of T.  Accessing the
-  // next op in the buffer is ((char*)op) + op->skip, with the data
-  // fitting between.
-  return op + 1;
-}
-
-template <typename T>
-void* paint_op_data(T* op) {
-  static_assert(std::is_convertible<T, PaintOpWithData>::value,
-                "T is not a PaintOpWithData");
-  return op + 1;
-}
-
-struct PaintOpWithDataArrayBase : PaintOpWithData {
-  // Helper class for static asserts in push functions.
-  using PaintOpWithData::PaintOpWithData;
-};
-
-template <typename T>
-struct PaintOpWithDataArray : PaintOpWithDataArrayBase {
-  // Paint op that has a T[count] and a char[bytes].
-  PaintOpWithDataArray(size_t bytes, size_t count)
-      : PaintOpWithDataArrayBase(bytes), count(count) {}
-  // Use paint_op_array to get array data.
-
-  size_t count;
-};
-
-template <typename M, typename T>
-const M* paint_op_array(const T* op) {
-  static_assert(std::is_convertible<T, PaintOpWithDataArrayBase>::value,
-                "T is not a PaintOpWithDataArray");
-  // See comment in paint_op_data.  Array data is stored after
-  // any void* data.  Memory layout here is: |op|data|array data|next op|
-  return SkTAddOffset<const M>(op + 1, op->bytes);
-}
-template <typename M, typename T>
-M* paint_op_array(T* op) {
-  static_assert(std::is_convertible<T, PaintOpWithDataArrayBase>::value,
-                "T is not a PaintOpWithDataArray");
-  return SkTAddOffset<M>(op + 1, op->bytes);
-}
-
-struct AnnotateOp final : PaintOp {
-  enum class AnnotationType {
-    URL,
-    LinkToDestination,
-    NamedDestination,
-  };
-
-  static constexpr PaintOpType kType = PaintOpType::Annotate;
-  AnnotateOp(PaintCanvas::AnnotationType annotation_type,
-             const SkRect& rect,
-             sk_sp<SkData> data);
-  ~AnnotateOp();
-  void Raster(SkCanvas* canvas) const;
-
-  PaintCanvas::AnnotationType annotation_type;
-  SkRect rect;
-  sk_sp<SkData> data;
-};
-
-struct ClipPathOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::ClipPath;
-  ClipPathOp(SkPath path, SkClipOp op, bool antialias)
-      : path(path), op(op), antialias(antialias) {}
-  void Raster(SkCanvas* canvas) const;
-  int CountSlowPaths() const;
-
-  ThreadsafePath path;
-  SkClipOp op;
-  bool antialias;
-};
-
-struct ClipRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::ClipRect;
-  ClipRectOp(const SkRect& rect, SkClipOp op, bool antialias)
-      : rect(rect), op(op), antialias(antialias) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkRect rect;
-  SkClipOp op;
-  bool antialias;
-};
-
-struct ClipRRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::ClipRRect;
-  ClipRRectOp(const SkRRect& rrect, SkClipOp op, bool antialias)
-      : rrect(rrect), op(op), antialias(antialias) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkRRect rrect;
-  SkClipOp op;
-  bool antialias;
-};
-
-struct ConcatOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Concat;
-  explicit ConcatOp(const SkMatrix& matrix) : matrix(matrix) {}
-  void Raster(SkCanvas* canvas) const;
-
-  ThreadsafeMatrix matrix;
-};
-
-struct DrawArcOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawArc;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawArcOp(const SkRect& oval,
-            SkScalar start_angle,
-            SkScalar sweep_angle,
-            bool use_center,
-            const PaintFlags& flags)
-      : oval(oval),
-        start_angle(start_angle),
-        sweep_angle(sweep_angle),
-        use_center(use_center),
-        flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkRect oval;
-  SkScalar start_angle;
-  SkScalar sweep_angle;
-  bool use_center;
-  PaintFlags flags;
-};
-
-struct DrawCircleOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawCircle;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawCircleOp(SkScalar cx,
-               SkScalar cy,
-               SkScalar radius,
-               const PaintFlags& flags)
-      : cx(cx), cy(cy), radius(radius), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkScalar cx;
-  SkScalar cy;
-  SkScalar radius;
-  PaintFlags flags;
-};
-
-struct DrawColorOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawColor;
-  static constexpr bool kIsDrawOp = true;
-  DrawColorOp(SkColor color, SkBlendMode mode) : color(color), mode(mode) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkColor color;
-  SkBlendMode mode;
-};
-
-struct DrawDisplayItemListOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawDisplayItemList;
-  static constexpr bool kIsDrawOp = true;
-  explicit DrawDisplayItemListOp(scoped_refptr<DisplayItemList> list);
-  ~DrawDisplayItemListOp();
-  void Raster(SkCanvas* canvas) const;
-  size_t AdditionalBytesUsed() const;
-  // TODO(enne): DisplayItemList should know number of slow paths.
-
-  scoped_refptr<DisplayItemList> list;
-};
-
-struct DrawDRRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawDRRect;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawDRRectOp(const SkRRect& outer,
-               const SkRRect& inner,
-               const PaintFlags& flags)
-      : outer(outer), inner(inner), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkRRect outer;
-  SkRRect inner;
-  PaintFlags flags;
-};
-
-struct DrawImageOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawImage;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawImageOp(sk_sp<const SkImage> image,
-              SkScalar left,
-              SkScalar top,
-              const PaintFlags* flags);
-  ~DrawImageOp();
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  sk_sp<const SkImage> image;
-  SkScalar left;
-  SkScalar top;
-  PaintFlags flags;
-};
-
-struct DrawImageRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawImageRect;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawImageRectOp(sk_sp<const SkImage> image,
-                  const SkRect& src,
-                  const SkRect& dst,
-                  const PaintFlags* flags,
-                  PaintCanvas::SrcRectConstraint constraint);
-  ~DrawImageRectOp();
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  sk_sp<const SkImage> image;
-  PaintFlags flags;
-  SkRect src;
-  SkRect dst;
-  PaintCanvas::SrcRectConstraint constraint;
-};
-
-struct DrawIRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawIRect;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawIRectOp(const SkIRect& rect, const PaintFlags& flags)
-      : rect(rect), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkIRect rect;
-  PaintFlags flags;
-};
-
-struct DrawLineOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawLine;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawLineOp(SkScalar x0,
-             SkScalar y0,
-             SkScalar x1,
-             SkScalar y1,
-             const PaintFlags& flags)
-      : x0(x0), y0(y0), x1(x1), y1(y1), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-  int CountSlowPaths() const;
-
-  SkScalar x0;
-  SkScalar y0;
-  SkScalar x1;
-  SkScalar y1;
-  PaintFlags flags;
-};
-
-struct DrawOvalOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawOval;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawOvalOp(const SkRect& oval, const PaintFlags& flags)
-      : oval(oval), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkRect oval;
-  PaintFlags flags;
-};
-
-struct DrawPathOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawPath;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawPathOp(const SkPath& path, const PaintFlags& flags)
-      : path(path), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-  int CountSlowPaths() const;
-
-  ThreadsafePath path;
-  PaintFlags flags;
-};
-
-struct DrawPosTextOp final : PaintOpWithDataArray<SkPoint> {
-  static constexpr PaintOpType kType = PaintOpType::DrawPosText;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawPosTextOp(size_t bytes, size_t count, const PaintFlags& flags);
-  ~DrawPosTextOp();
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  PaintFlags flags;
-};
-
-struct DrawRecordOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawRecord;
-  static constexpr bool kIsDrawOp = true;
-  explicit DrawRecordOp(sk_sp<const PaintRecord> record);
-  ~DrawRecordOp();
-  void Raster(SkCanvas* canvas) const;
-  size_t AdditionalBytesUsed() const;
-
-  sk_sp<const PaintRecord> record;
-};
-
-struct DrawRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawRect;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawRectOp(const SkRect& rect, const PaintFlags& flags)
-      : rect(rect), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkRect rect;
-  PaintFlags flags;
-};
-
-struct DrawRRectOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawRRect;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawRRectOp(const SkRRect& rrect, const PaintFlags& flags)
-      : rrect(rrect), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkRRect rrect;
-  PaintFlags flags;
-};
-
-struct DrawTextOp final : PaintOpWithData {
-  static constexpr PaintOpType kType = PaintOpType::DrawText;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawTextOp(size_t bytes, SkScalar x, SkScalar y, const PaintFlags& flags)
-      : PaintOpWithData(bytes), x(x), y(y), flags(flags) {}
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkScalar x;
-  SkScalar y;
-  PaintFlags flags;
-};
-
-struct DrawTextBlobOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::DrawTextBlob;
-  static constexpr bool kIsDrawOp = true;
-  static constexpr bool kHasPaintFlags = true;
-  DrawTextBlobOp(sk_sp<SkTextBlob> blob,
-                 SkScalar x,
-                 SkScalar y,
-                 const PaintFlags& flags);
-  ~DrawTextBlobOp();
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  sk_sp<SkTextBlob> blob;
-  SkScalar x;
-  SkScalar y;
-  PaintFlags flags;
-};
-
-struct NoopOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Noop;
-  void Raster(SkCanvas* canvas) const {}
-};
-
-struct RestoreOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Restore;
-  void Raster(SkCanvas* canvas) const;
-};
-
-struct RotateOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Rotate;
-  explicit RotateOp(SkScalar degrees) : degrees(degrees) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkScalar degrees;
-};
-
-struct SaveOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Save;
-  void Raster(SkCanvas* canvas) const;
-};
-
-struct SaveLayerOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::SaveLayer;
-  static constexpr bool kHasPaintFlags = true;
-  SaveLayerOp(const SkRect* bounds, const PaintFlags* flags)
-      : bounds(bounds ? *bounds : kUnsetRect) {
-    if (flags)
-      this->flags = *flags;
-  }
-  void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
-
-  SkRect bounds;
-  PaintFlags flags;
-};
-
-struct SaveLayerAlphaOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::SaveLayerAlpha;
-  SaveLayerAlphaOp(const SkRect* bounds, uint8_t alpha)
-      : bounds(bounds ? *bounds : kUnsetRect), alpha(alpha) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkRect bounds;
-  uint8_t alpha;
-};
-
-struct ScaleOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Scale;
-  ScaleOp(SkScalar sx, SkScalar sy) : sx(sx), sy(sy) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkScalar sx;
-  SkScalar sy;
-};
-
-struct SetMatrixOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::SetMatrix;
-  explicit SetMatrixOp(const SkMatrix& matrix) : matrix(matrix) {}
-  // This is the only op that needs the original ctm of the SkCanvas
-  // used for raster (since SetMatrix is relative to the recording origin and
-  // shouldn't clobber the SkCanvas raster origin).
-  //
-  // TODO(enne): Find some cleaner way to do this, possibly by making
-  // all SetMatrix calls Concat??
-  void Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const;
-
-  ThreadsafeMatrix matrix;
-};
-
-struct TranslateOp final : PaintOp {
-  static constexpr PaintOpType kType = PaintOpType::Translate;
-  TranslateOp(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {}
-  void Raster(SkCanvas* canvas) const;
-
-  SkScalar dx;
-  SkScalar dy;
-};
-
-using LargestPaintOp = DrawDRRectOp;
-
-class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt {
- public:
-  enum { kPageSize = 4096 };
-
-  PaintOpBuffer();
-  explicit PaintOpBuffer(const SkRect& cull_rect);
-  ~PaintOpBuffer() override;
-
-  void Reset();
-
-  void playback(SkCanvas* canvas) const;
-  void playback(SkCanvas* canvas, SkPicture::AbortCallback* callback) const;
-
-  // TODO(enne): These are no longer approximate.  Rename these.
-  int approximateOpCount() const { return op_count_; }
-  size_t approximateBytesUsed() const {
-    return sizeof(*this) + reserved_ + subrecord_bytes_used_;
-  }
-  int numSlowPaths() const { return num_slow_paths_; }
-
-  // Resize the PaintOpBuffer to exactly fit the current amount of used space.
-  void ShrinkToFit();
-
-  const SkRect& cullRect() const { return cull_rect_; }
-
-  PaintOp* GetFirstOp() const {
-    return reinterpret_cast<PaintOp*>(const_cast<char*>(&first_op_[0]));
-  }
-
-  template <typename T, typename... Args>
-  void push(Args&&... args) {
-    static_assert(std::is_convertible<T, PaintOp>::value, "T not a PaintOp.");
-    static_assert(!std::is_convertible<T, PaintOpWithData>::value,
-                  "Type needs to use push_with_data");
-    push_internal<T>(0, std::forward<Args>(args)...);
-  }
-
-  template <typename T, typename... Args>
-  void push_with_data(const void* data, size_t bytes, Args&&... args) {
-    static_assert(std::is_convertible<T, PaintOpWithData>::value,
-                  "T is not a PaintOpWithData");
-#if !defined(OS_CHROMEOS)
-    // TODO(enne): non-linux chromeos builds think that DrawTextOp
-    // can be converted to a PaintOpWithDataArrayBase.  OOPS.
-    static_assert(!std::is_convertible<T, PaintOpWithDataArrayBase>::value,
-                  "Type needs to use push_with_data_array");
-#endif
-    DCHECK_GE(bytes, 0u);
-    T* op = push_internal<T>(bytes, bytes, std::forward<Args>(args)...);
-    memcpy(paint_op_data(op), data, bytes);
-
-#if DCHECK_IS_ON()
-    // Double check the data fits between op and next op and doesn't clobber.
-    char* op_start = reinterpret_cast<char*>(op);
-    char* op_end = op_start + sizeof(T);
-    char* next_op = op_start + op->skip;
-    char* data_start = reinterpret_cast<char*>(paint_op_data(op));
-    char* data_end = data_start + bytes;
-    DCHECK_GE(data_start, op_end);
-    DCHECK_LT(data_start, next_op);
-    DCHECK_LE(data_end, next_op);
-#endif
-  }
-
-  template <typename T, typename M, typename... Args>
-  void push_with_data_array(const void* data,
-                            size_t bytes,
-                            const M* array,
-                            size_t count,
-                            Args&&... args) {
-    static_assert(std::is_convertible<T, PaintOpWithDataArray<M>>::value,
-                  "T is not a PaintOpWithDataArray");
-    DCHECK_GE(bytes, 0u);
-    DCHECK_GE(count, 0u);
-    size_t array_size = sizeof(M) * count;
-    size_t total_size = bytes + array_size;
-    T* op =
-        push_internal<T>(total_size, bytes, count, std::forward<Args>(args)...);
-    memcpy(paint_op_data(op), data, bytes);
-    memcpy(paint_op_array<M>(op), array, array_size);
-
-#if DCHECK_IS_ON()
-    // Double check data and array don't clobber op, next op, or each other
-    char* op_start = reinterpret_cast<char*>(op);
-    char* op_end = op_start + sizeof(T);
-    char* next_op = op_start + op->skip;
-    char* data_start = reinterpret_cast<char*>(paint_op_data(op));
-    char* data_end = data_start + bytes;
-    char* array_start = reinterpret_cast<char*>(paint_op_array<M>(op));
-    char* array_end = array_start + array_size;
-    DCHECK_GE(data_start, op_end);
-    DCHECK_LE(data_start, array_start);
-    DCHECK_GE(array_start, data_end);
-    DCHECK_LE(array_end, next_op);
-#endif
-  }
-
-  class Iterator {
-   public:
-    explicit Iterator(const PaintOpBuffer* buffer)
-        : buffer_(buffer), ptr_(buffer_->data_.get()) {}
-
-    PaintOp* operator->() const {
-      return op_idx_ ? reinterpret_cast<PaintOp*>(ptr_) : buffer_->GetFirstOp();
-    }
-    PaintOp* operator*() const { return operator->(); }
-    Iterator begin() { return Iterator(buffer_, buffer_->data_.get(), 0); }
-    Iterator end() {
-      return Iterator(buffer_, buffer_->data_.get() + buffer_->used_,
-                      buffer_->approximateOpCount());
-    }
-    bool operator!=(const Iterator& other) {
-      // Not valid to compare iterators on different buffers.
-      DCHECK_EQ(other.buffer_, buffer_);
-      return other.op_idx_ != op_idx_;
-    }
-    Iterator& operator++() {
-      if (!op_idx_++)
-        return *this;
-      PaintOp* op = **this;
-      uint32_t type = op->type;
-      CHECK_LE(type, static_cast<uint32_t>(PaintOpType::LastPaintOpType));
-      ptr_ += op->skip;
-      return *this;
-    }
-    operator bool() const { return op_idx_ < buffer_->approximateOpCount(); }
-
-    int op_idx() const { return op_idx_; }
-
-    // Return the next op without advancing the iterator, or nullptr if none.
-    PaintOp* peek1() const {
-      if (op_idx_ + 1 >= buffer_->approximateOpCount())
-        return nullptr;
-      if (!op_idx_)
-        return reinterpret_cast<PaintOp*>(ptr_);
-      return reinterpret_cast<PaintOp*>(ptr_ + (*this)->skip);
-    }
-
-    // Return the op two ops ahead without advancing the iterator, or nullptr if
-    // none.
-    PaintOp* peek2() const {
-      if (op_idx_ + 2 >= buffer_->approximateOpCount())
-        return nullptr;
-      char* next = ptr_ + reinterpret_cast<PaintOp*>(ptr_)->skip;
-      PaintOp* next_op = reinterpret_cast<PaintOp*>(next);
-      if (!op_idx_)
-        return next_op;
-      return reinterpret_cast<PaintOp*>(next + next_op->skip);
-    }
-
-   private:
-    Iterator(const PaintOpBuffer* buffer, char* ptr, int op_idx)
-        : buffer_(buffer), ptr_(ptr), op_idx_(op_idx) {}
-
-    const PaintOpBuffer* buffer_ = nullptr;
-    char* ptr_ = nullptr;
-    int op_idx_ = 0;
-  };
-
- private:
-  template <typename T, bool HasFlags>
-  struct CountSlowPathsFromFlags {
-    static int Count(const T* op) { return 0; }
-  };
-
-  template <typename T>
-  struct CountSlowPathsFromFlags<T, true> {
-    static int Count(const T* op) { return op->flags.getPathEffect() ? 1 : 0; }
-  };
-
-  template <typename T, typename... Args>
-  T* push_internal(size_t bytes, Args&&... args) {
-    size_t skip = SkAlignPtr(sizeof(T) + bytes);
-    DCHECK_LT(skip, static_cast<size_t>(1) << 24);
-    if (used_ + skip > reserved_ || !op_count_) {
-      if (!op_count_) {
-        if (bytes) {
-          // Internal first_op buffer doesn't have room for extra data.
-          // If the op wants extra bytes, then we'll just store a Noop
-          // in the first_op and proceed from there.  This seems unlikely
-          // to be a common case.
-          push<NoopOp>();
-        } else {
-          T* op = reinterpret_cast<T*>(&first_op_[0]);
-          new (op) T{std::forward<Args>(args)...};
-          op->type = static_cast<uint32_t>(T::kType);
-          op->skip = 0;
-          op_count_++;
-          return op;
-        }
-      }
-
-      static_assert(SkIsPow2(kPageSize),
-                    "This math needs updating for non-pow2.");
-      // Next greater multiple of kPageSize.
-      reserved_ = (used_ + skip + kPageSize) & ~(kPageSize - 1);
-      data_.realloc(reserved_);
-    }
-    DCHECK_LE(used_ + skip, reserved_);
-
-    T* op = reinterpret_cast<T*>(data_.get() + used_);
-    used_ += skip;
-    new (op) T(std::forward<Args>(args)...);
-    op->type = static_cast<uint32_t>(T::kType);
-    op->skip = skip;
-    op_count_++;
-
-    num_slow_paths_ += CountSlowPathsFromFlags<T, T::kHasPaintFlags>::Count(op);
-    num_slow_paths_ += op->CountSlowPaths();
-
-    subrecord_bytes_used_ += op->AdditionalBytesUsed();
-
-    return op;
-  }
-
-  // As a performance optimization because n=1 is an extremely common case just
-  // store the first op in the PaintOpBuffer itself to avoid an extra alloc.
-  char first_op_[sizeof(LargestPaintOp)];
-  SkAutoTMalloc<char> data_;
-  size_t used_ = 0;
-  size_t reserved_ = 0;
-  int op_count_ = 0;
-
-  // Record paths for veto-to-msaa for gpu raster.
-  int num_slow_paths_ = 0;
-  // Record additional bytes used by referenced sub-records and display lists.
-  size_t subrecord_bytes_used_ = 0;
-  SkRect cull_rect_;
-
-  DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer);
-};
-
-}  // namespace cc
-
-#endif  // CC_PAINT_PAINT_OP_BUFFER_H_
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc
deleted file mode 100644
index f3b22da..0000000
--- a/cc/paint/paint_op_buffer_unittest.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/paint/paint_op_buffer.h"
-#include "cc/test/test_skcanvas.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-TEST(PaintOpBufferTest, Empty) {
-  PaintOpBuffer buffer;
-  EXPECT_EQ(buffer.approximateOpCount(), 0);
-  EXPECT_EQ(buffer.approximateBytesUsed(), sizeof(PaintOpBuffer));
-  EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false);
-
-  buffer.Reset();
-  EXPECT_EQ(buffer.approximateOpCount(), 0);
-  EXPECT_EQ(buffer.approximateBytesUsed(), sizeof(PaintOpBuffer));
-  EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false);
-}
-
-TEST(PaintOpBufferTest, SimpleAppend) {
-  SkRect rect = SkRect::MakeXYWH(2, 3, 4, 5);
-  PaintFlags flags;
-  flags.setColor(SK_ColorMAGENTA);
-  flags.setAlpha(100);
-  SkColor draw_color = SK_ColorRED;
-  SkBlendMode blend = SkBlendMode::kSrc;
-
-  PaintOpBuffer buffer;
-  buffer.push<SaveLayerOp>(&rect, &flags);
-  buffer.push<SaveOp>();
-  buffer.push<DrawColorOp>(draw_color, blend);
-  buffer.push<RestoreOp>();
-
-  EXPECT_EQ(buffer.approximateOpCount(), 4);
-
-  PaintOpBuffer::Iterator iter(&buffer);
-  ASSERT_EQ(iter->GetType(), PaintOpType::SaveLayer);
-  SaveLayerOp* save_op = static_cast<SaveLayerOp*>(*iter);
-  EXPECT_EQ(save_op->bounds, rect);
-  EXPECT_TRUE(save_op->flags == flags);
-  ++iter;
-
-  ASSERT_EQ(iter->GetType(), PaintOpType::Save);
-  ++iter;
-
-  ASSERT_EQ(iter->GetType(), PaintOpType::DrawColor);
-  DrawColorOp* op = static_cast<DrawColorOp*>(*iter);
-  EXPECT_EQ(op->color, draw_color);
-  EXPECT_EQ(op->mode, blend);
-  ++iter;
-
-  ASSERT_EQ(iter->GetType(), PaintOpType::Restore);
-  ++iter;
-
-  EXPECT_FALSE(iter);
-}
-
-// PaintOpBuffer has a special case for first ops stored locally, so
-// make sure that appending different kind of ops as a first op works
-// properly, as well as resetting and reusing the first local op.
-TEST(PaintOpBufferTest, FirstOpWithAndWithoutData) {
-  PaintOpBuffer buffer;
-  char text[] = "asdf";
-
-  // Use a color filter and its ref count to verify that the destructor
-  // is called on ops after reset.
-  PaintFlags flags;
-  sk_sp<SkColorFilter> filter =
-      SkColorFilter::MakeModeFilter(SK_ColorMAGENTA, SkBlendMode::kSrcOver);
-  flags.setColorFilter(filter);
-  EXPECT_EQ(filter->getRefCnt(), 2);
-
-  buffer.push_with_data<DrawTextOp>(text, arraysize(text), 0.f, 0.f, flags);
-  EXPECT_EQ(filter->getRefCnt(), 3);
-
-  // Verify that when the first op has data, which may not fit in the
-  // PaintRecord internal buffer, that it adds a noop as the first op
-  // and then appends the "op with data" into the heap buffer.
-  ASSERT_EQ(buffer.approximateOpCount(), 2);
-  EXPECT_EQ(buffer.GetFirstOp()->GetType(), PaintOpType::Noop);
-
-  // Verify iteration behavior and brief smoke test of op state.
-  {
-    PaintOpBuffer::Iterator iter(&buffer);
-    PaintOp* noop = *iter;
-    EXPECT_EQ(buffer.GetFirstOp(), noop);
-    ++iter;
-
-    PaintOp* op = *iter;
-    ASSERT_EQ(op->GetType(), PaintOpType::DrawText);
-    DrawTextOp* draw_text_op = static_cast<DrawTextOp*>(op);
-    EXPECT_EQ(draw_text_op->bytes, arraysize(text));
-
-    void* data = paint_op_data(draw_text_op);
-    EXPECT_EQ(memcmp(data, text, arraysize(text)), 0);
-
-    ++iter;
-    EXPECT_FALSE(iter);
-  }
-
-  // Reset, verify state, and append an op that will fit in the first slot.
-  buffer.Reset();
-  EXPECT_EQ(filter->getRefCnt(), 2);
-
-  ASSERT_EQ(buffer.approximateOpCount(), 0);
-  EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false);
-
-  SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
-  buffer.push<DrawRectOp>(rect, flags);
-  EXPECT_EQ(filter->getRefCnt(), 3);
-
-  ASSERT_EQ(buffer.approximateOpCount(), 1);
-  EXPECT_EQ(buffer.GetFirstOp()->GetType(), PaintOpType::DrawRect);
-
-  PaintOpBuffer::Iterator iter(&buffer);
-  ASSERT_EQ(iter->GetType(), PaintOpType::DrawRect);
-  DrawRectOp* draw_rect_op = static_cast<DrawRectOp*>(*iter);
-  EXPECT_EQ(draw_rect_op->rect, rect);
-
-  ++iter;
-  EXPECT_FALSE(iter);
-
-  buffer.Reset();
-  ASSERT_EQ(buffer.approximateOpCount(), 0);
-  EXPECT_EQ(filter->getRefCnt(), 2);
-}
-
-TEST(PaintOpBufferTest, Peek) {
-  PaintOpBuffer buffer;
-
-  uint8_t alpha = 100;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
-  PaintFlags draw_flags;
-  buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 2, 3, 4), draw_flags);
-  buffer.push<RestoreOp>();
-  buffer.push<SaveOp>();
-  buffer.push<NoopOp>();
-  buffer.push<RestoreOp>();
-
-  PaintOpBuffer::Iterator init_iter(&buffer);
-  PaintOp* peek[2] = {*init_iter, init_iter.peek1()};
-
-  // Expect that while iterating that next = current.peek1() and that
-  // next.peek1() == current.peek2().
-  for (PaintOpBuffer::Iterator iter(&buffer); iter; ++iter) {
-    EXPECT_EQ(*iter, peek[0]) << iter.op_idx();
-    EXPECT_EQ(iter.peek1(), peek[1]) << iter.op_idx();
-
-    peek[0] = iter.peek1();
-    peek[1] = iter.peek2();
-  }
-}
-
-TEST(PaintOpBufferTest, PeekEmpty) {
-  PaintOpBuffer empty;
-  PaintOpBuffer::Iterator empty_iter(&empty);
-  EXPECT_EQ(nullptr, empty_iter.peek1());
-  EXPECT_EQ(nullptr, empty_iter.peek2());
-}
-
-// Verify that a SaveLayerAlpha / Draw / Restore can be optimized to just
-// a draw with opacity.
-TEST(PaintOpBufferTest, SaveDrawRestore) {
-  PaintOpBuffer buffer;
-
-  uint8_t alpha = 100;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
-
-  PaintFlags draw_flags;
-  draw_flags.setColor(SK_ColorMAGENTA);
-  draw_flags.setAlpha(50);
-  EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
-  SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
-  buffer.push<DrawRectOp>(rect, draw_flags);
-  buffer.push<RestoreOp>();
-
-  SaveCountingCanvas canvas;
-  buffer.playback(&canvas);
-
-  EXPECT_EQ(0, canvas.save_count_);
-  EXPECT_EQ(0, canvas.restore_count_);
-  EXPECT_EQ(rect, canvas.draw_rect_);
-
-  // Expect the alpha from the draw and the save layer to be folded together.
-  // Since alpha is stored in a uint8_t and gets rounded, so use tolerance.
-  float expected_alpha = alpha * 50 / 255.f;
-  EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f);
-}
-
-// The same as SaveDrawRestore, but test that the optimization doesn't apply
-// when the drawing op's flags are not compatible with being folded into the
-// save layer with opacity.
-TEST(PaintOpBufferTest, SaveDrawRestoreFail_BadFlags) {
-  PaintOpBuffer buffer;
-
-  uint8_t alpha = 100;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
-
-  PaintFlags draw_flags;
-  draw_flags.setColor(SK_ColorMAGENTA);
-  draw_flags.setAlpha(50);
-  draw_flags.setBlendMode(SkBlendMode::kSrc);
-  EXPECT_FALSE(draw_flags.SupportsFoldingAlpha());
-  SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
-  buffer.push<DrawRectOp>(rect, draw_flags);
-  buffer.push<RestoreOp>();
-
-  SaveCountingCanvas canvas;
-  buffer.playback(&canvas);
-
-  EXPECT_EQ(1, canvas.save_count_);
-  EXPECT_EQ(1, canvas.restore_count_);
-  EXPECT_EQ(rect, canvas.draw_rect_);
-  EXPECT_EQ(draw_flags.getAlpha(), canvas.paint_.getAlpha());
-}
-
-// The same as SaveDrawRestore, but test that the optimization doesn't apply
-// when there are more than one ops between the save and restore.
-TEST(PaintOpBufferTest, SaveDrawRestoreFail_TooManyOps) {
-  PaintOpBuffer buffer;
-
-  uint8_t alpha = 100;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
-
-  PaintFlags draw_flags;
-  draw_flags.setColor(SK_ColorMAGENTA);
-  draw_flags.setAlpha(50);
-  draw_flags.setBlendMode(SkBlendMode::kSrcOver);
-  EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
-  SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
-  buffer.push<DrawRectOp>(rect, draw_flags);
-  buffer.push<NoopOp>();
-  buffer.push<RestoreOp>();
-
-  SaveCountingCanvas canvas;
-  buffer.playback(&canvas);
-
-  EXPECT_EQ(1, canvas.save_count_);
-  EXPECT_EQ(1, canvas.restore_count_);
-  EXPECT_EQ(rect, canvas.draw_rect_);
-  EXPECT_EQ(draw_flags.getAlpha(), canvas.paint_.getAlpha());
-}
-
-}  // namespace cc
diff --git a/cc/paint/paint_record.cc b/cc/paint/paint_record.cc
deleted file mode 100644
index 52cb2524..0000000
--- a/cc/paint/paint_record.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/paint/paint_record.h"
-
-#include "cc/paint/paint_op_buffer.h"
-#include "third_party/skia/include/core/SkPictureRecorder.h"
-
-namespace cc {
-
-sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record) {
-  SkPictureRecorder recorder;
-  SkCanvas* canvas = recorder.beginRecording(record->cullRect());
-  record->playback(canvas);
-  return recorder.finishRecordingAsPicture();
-}
-
-sk_sp<const SkPicture> ToSkPicture(sk_sp<const PaintRecord> record) {
-  SkPictureRecorder recorder;
-  SkCanvas* canvas = recorder.beginRecording(record->cullRect());
-  record->playback(canvas);
-  return recorder.finishRecordingAsPicture();
-}
-
-}  // namespace cc
diff --git a/cc/paint/paint_record.h b/cc/paint/paint_record.h
index daeee004..8506606b 100644
--- a/cc/paint/paint_record.h
+++ b/cc/paint/paint_record.h
@@ -5,22 +5,19 @@
 #ifndef CC_PAINT_PAINT_RECORD_H_
 #define CC_PAINT_PAINT_RECORD_H_
 
-#include "cc/paint/paint_export.h"
-#include "cc/paint/paint_op_buffer.h"
 #include "third_party/skia/include/core/SkPicture.h"
 
 namespace cc {
 
-// TODO(enne): Don't want to rename the world for this.  Using these as the
-// same types for now prevents an extra allocation.  Probably PaintRecord
-// will become an interface in the future.
-using PaintRecord = PaintOpBuffer;
+using PaintRecord = SkPicture;
 
-// TODO(enne): Remove these if possible, they are really expensive.
-CC_PAINT_EXPORT sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record);
+inline sk_sp<SkPicture> ToSkPicture(sk_sp<PaintRecord> record) {
+  return record;
+}
 
-CC_PAINT_EXPORT sk_sp<const SkPicture> ToSkPicture(
-    sk_sp<const PaintRecord> record);
+inline sk_sp<const SkPicture> ToSkPicture(sk_sp<const PaintRecord> record) {
+  return record;
+}
 
 }  // namespace cc
 
diff --git a/cc/paint/paint_recorder.cc b/cc/paint/paint_recorder.cc
index c43f965..672f0712 100644
--- a/cc/paint/paint_recorder.cc
+++ b/cc/paint/paint_recorder.cc
@@ -4,36 +4,9 @@
 
 #include "cc/paint/paint_recorder.h"
 
-#include "cc/paint/paint_op_buffer.h"
-
 namespace cc {
 
 PaintRecorder::PaintRecorder() = default;
-
 PaintRecorder::~PaintRecorder() = default;
 
-PaintCanvas* PaintRecorder::beginRecording(const SkRect& bounds) {
-  buffer_.reset(new PaintOpBuffer(bounds));
-  canvas_.emplace(buffer_.get(), bounds);
-  return getRecordingCanvas();
-}
-
-sk_sp<PaintRecord> PaintRecorder::finishRecordingAsPicture() {
-  // SkPictureRecorder users expect that their saves are automatically
-  // closed for them.
-  //
-  // NOTE: Blink paint in general doesn't appear to need this, but the
-  // RecordingImageBufferSurface::fallBackToRasterCanvas finishing off the
-  // current frame depends on this.  Maybe we could remove this assumption and
-  // just have callers do it.
-  canvas_->restoreToCount(1);
-
-  // Some users (e.g. printing) use the existence of the recording canvas
-  // to know if recording is finished, so reset it here.
-  canvas_.reset();
-
-  buffer_->ShrinkToFit();
-  return std::move(buffer_);
-}
-
 }  // namespace cc
diff --git a/cc/paint/paint_recorder.h b/cc/paint/paint_recorder.h
index 7f582b85..2bbea83b 100644
--- a/cc/paint/paint_recorder.h
+++ b/cc/paint/paint_recorder.h
@@ -9,36 +9,47 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
+#include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_record.h"
-#include "cc/paint/record_paint_canvas.h"
+#include "cc/paint/skia_paint_canvas.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
 
 namespace cc {
 
-class PaintOpBuffer;
-
 class CC_PAINT_EXPORT PaintRecorder {
  public:
   PaintRecorder();
   ~PaintRecorder();
 
-  PaintCanvas* beginRecording(const SkRect& bounds);
+  ALWAYS_INLINE PaintCanvas* beginRecording(const SkRect& bounds) {
+    uint32_t record_flags = 0;
+    canvas_.emplace(recorder_.beginRecording(bounds, nullptr, record_flags));
+    return getRecordingCanvas();
+  }
 
-  // TODO(enne): should make everything go through the non-rect version.
-  // See comments in RecordPaintCanvas ctor for why.
-  PaintCanvas* beginRecording(SkScalar width, SkScalar height) {
-    return beginRecording(SkRect::MakeWH(width, height));
+  ALWAYS_INLINE PaintCanvas* beginRecording(SkScalar width, SkScalar height) {
+    uint32_t record_flags = 0;
+    canvas_.emplace(
+        recorder_.beginRecording(width, height, nullptr, record_flags));
+    return getRecordingCanvas();
   }
 
   // Only valid between between and finish recording.
-  ALWAYS_INLINE RecordPaintCanvas* getRecordingCanvas() {
+  ALWAYS_INLINE PaintCanvas* getRecordingCanvas() {
     return canvas_.has_value() ? &canvas_.value() : nullptr;
   }
 
-  sk_sp<PaintRecord> finishRecordingAsPicture();
+  ALWAYS_INLINE sk_sp<PaintRecord> finishRecordingAsPicture() {
+    sk_sp<SkPicture> picture = recorder_.finishRecordingAsPicture();
+    // Some users (e.g. printing) use the existence of the recording canvas
+    // to know if recording is finished, so reset it here.
+    canvas_.reset();
+    return sk_ref_sp(static_cast<PaintRecord*>(picture.get()));
+  }
 
  private:
-  sk_sp<PaintOpBuffer> buffer_;
-  base::Optional<RecordPaintCanvas> canvas_;
+  SkPictureRecorder recorder_;
+  base::Optional<SkiaPaintCanvas> canvas_;
 
   DISALLOW_COPY_AND_ASSIGN(PaintRecorder);
 };
diff --git a/cc/paint/record_paint_canvas.cc b/cc/paint/record_paint_canvas.cc
deleted file mode 100644
index 63e134f..0000000
--- a/cc/paint/record_paint_canvas.cc
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/paint/record_paint_canvas.h"
-
-#include "base/memory/ptr_util.h"
-#include "cc/paint/display_item_list.h"
-#include "cc/paint/paint_op_buffer.h"
-#include "cc/paint/paint_record.h"
-#include "cc/paint/paint_recorder.h"
-#include "third_party/skia/include/core/SkAnnotation.h"
-#include "third_party/skia/include/core/SkMetaData.h"
-#include "third_party/skia/include/utils/SkNWayCanvas.h"
-
-namespace cc {
-
-RecordPaintCanvas::RecordPaintCanvas(PaintOpBuffer* buffer,
-                                     const SkRect& cull_rect)
-    : buffer_(buffer),
-      canvas_(static_cast<int>(std::ceil(cull_rect.right())),
-              static_cast<int>(std::ceil(cull_rect.bottom()))) {
-  DCHECK(buffer_);
-
-  // This is part of the "recording canvases have a size, but why" dance.
-  // By creating a canvas of size (right x bottom) and then clipping it,
-  // It makes getDeviceClipBounds return the original cull rect, which code
-  // in GraphicsContextCanvas on Mac expects.  (Just creating an SkNoDrawCanvas
-  // with the cull_rect makes a canvas of size (width x height) instead
-  // which is incorrect.  SkRecorder cheats with private resetForNextCanvas.
-  canvas_.clipRect(SkRect::Make(cull_rect.roundOut()), SkClipOp::kIntersect,
-                   false);
-}
-
-RecordPaintCanvas::~RecordPaintCanvas() = default;
-
-SkMetaData& RecordPaintCanvas::getMetaData() {
-  // This could just be SkMetaData owned by RecordPaintCanvas, but since
-  // SkCanvas already has one, we might as well use it directly.
-  return canvas_.getMetaData();
-}
-
-SkImageInfo RecordPaintCanvas::imageInfo() const {
-  return canvas_.imageInfo();
-}
-
-void RecordPaintCanvas::flush() {
-  // This is a noop when recording.
-}
-
-SkISize RecordPaintCanvas::getBaseLayerSize() const {
-  return canvas_.getBaseLayerSize();
-}
-
-bool RecordPaintCanvas::writePixels(const SkImageInfo& info,
-                                    const void* pixels,
-                                    size_t row_bytes,
-                                    int x,
-                                    int y) {
-  NOTREACHED();
-  return false;
-}
-
-int RecordPaintCanvas::save() {
-  buffer_->push<SaveOp>();
-  return canvas_.save();
-}
-
-int RecordPaintCanvas::saveLayer(const SkRect* bounds,
-                                 const PaintFlags* flags) {
-  if (flags) {
-    if (flags->IsSimpleOpacity()) {
-      // TODO(enne): maybe more callers should know this and call
-      // saveLayerAlpha instead of needing to check here.
-      uint8_t alpha = SkColorGetA(flags->getColor());
-      return saveLayerAlpha(bounds, alpha);
-    }
-
-    // TODO(enne): it appears that image filters affect matrices and color
-    // matrices affect transparent flags on SkCanvas layers, but it's not clear
-    // whether those are actually needed and we could just skip ToSkPaint here.
-    buffer_->push<SaveLayerOp>(bounds, flags);
-    const SkPaint& paint = ToSkPaint(*flags);
-    return canvas_.saveLayer(bounds, &paint);
-  }
-  buffer_->push<SaveLayerOp>(bounds, flags);
-  return canvas_.saveLayer(bounds, nullptr);
-}
-
-int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
-  buffer_->push<SaveLayerAlphaOp>(bounds, alpha);
-  return canvas_.saveLayerAlpha(bounds, alpha);
-}
-
-void RecordPaintCanvas::restore() {
-  buffer_->push<RestoreOp>();
-  canvas_.restore();
-}
-
-int RecordPaintCanvas::getSaveCount() const {
-  return canvas_.getSaveCount();
-}
-
-void RecordPaintCanvas::restoreToCount(int save_count) {
-  DCHECK_GE(save_count, 1);
-  int diff = canvas_.getSaveCount() - save_count;
-  DCHECK_GE(diff, 0);
-  for (int i = 0; i < diff; ++i)
-    restore();
-}
-
-void RecordPaintCanvas::translate(SkScalar dx, SkScalar dy) {
-  buffer_->push<TranslateOp>(dx, dy);
-  canvas_.translate(dx, dy);
-}
-
-void RecordPaintCanvas::scale(SkScalar sx, SkScalar sy) {
-  buffer_->push<ScaleOp>(sx, sy);
-  canvas_.scale(sx, sy);
-}
-
-void RecordPaintCanvas::rotate(SkScalar degrees) {
-  buffer_->push<RotateOp>(degrees);
-  canvas_.rotate(degrees);
-}
-
-void RecordPaintCanvas::concat(const SkMatrix& matrix) {
-  buffer_->push<ConcatOp>(matrix);
-  canvas_.concat(matrix);
-}
-
-void RecordPaintCanvas::setMatrix(const SkMatrix& matrix) {
-  buffer_->push<SetMatrixOp>(matrix);
-  canvas_.setMatrix(matrix);
-}
-
-void RecordPaintCanvas::clipRect(const SkRect& rect,
-                                 SkClipOp op,
-                                 bool antialias) {
-  buffer_->push<ClipRectOp>(rect, op, antialias);
-  canvas_.clipRect(rect, op, antialias);
-}
-
-void RecordPaintCanvas::clipRRect(const SkRRect& rrect,
-                                  SkClipOp op,
-                                  bool antialias) {
-  // TODO(enne): does this happen? Should the caller know this?
-  if (rrect.isRect()) {
-    clipRect(rrect.getBounds(), op, antialias);
-    return;
-  }
-  buffer_->push<ClipRRectOp>(rrect, op, antialias);
-  canvas_.clipRRect(rrect, op, antialias);
-}
-
-void RecordPaintCanvas::clipPath(const SkPath& path,
-                                 SkClipOp op,
-                                 bool antialias) {
-  if (!path.isInverseFillType() && canvas_.getTotalMatrix().rectStaysRect()) {
-    // TODO(enne): do these cases happen? should the caller know that this isn't
-    // a path?
-    SkRect rect;
-    if (path.isRect(&rect)) {
-      clipRect(rect, op, antialias);
-      return;
-    }
-    SkRRect rrect;
-    if (path.isOval(&rect)) {
-      rrect.setOval(rect);
-      clipRRect(rrect, op, antialias);
-      return;
-    }
-    if (path.isRRect(&rrect)) {
-      clipRRect(rrect, op, antialias);
-      return;
-    }
-  }
-
-  buffer_->push<ClipPathOp>(path, op, antialias);
-  canvas_.clipPath(path, op, antialias);
-  return;
-}
-
-bool RecordPaintCanvas::quickReject(const SkRect& rect) const {
-  return canvas_.quickReject(rect);
-}
-
-bool RecordPaintCanvas::quickReject(const SkPath& path) const {
-  return canvas_.quickReject(path);
-}
-
-SkRect RecordPaintCanvas::getLocalClipBounds() const {
-  return canvas_.getLocalClipBounds();
-}
-
-bool RecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const {
-  return canvas_.getLocalClipBounds(bounds);
-}
-
-SkIRect RecordPaintCanvas::getDeviceClipBounds() const {
-  return canvas_.getDeviceClipBounds();
-}
-
-bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const {
-  return canvas_.getDeviceClipBounds(bounds);
-}
-
-void RecordPaintCanvas::drawColor(SkColor color, SkBlendMode mode) {
-  buffer_->push<DrawColorOp>(color, mode);
-}
-
-void RecordPaintCanvas::clear(SkColor color) {
-  buffer_->push<DrawColorOp>(color, SkBlendMode::kSrc);
-}
-
-void RecordPaintCanvas::drawLine(SkScalar x0,
-                                 SkScalar y0,
-                                 SkScalar x1,
-                                 SkScalar y1,
-                                 const PaintFlags& flags) {
-  buffer_->push<DrawLineOp>(x0, y0, x1, y1, flags);
-}
-
-void RecordPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) {
-  buffer_->push<DrawRectOp>(rect, flags);
-}
-
-void RecordPaintCanvas::drawIRect(const SkIRect& rect,
-                                  const PaintFlags& flags) {
-  buffer_->push<DrawIRectOp>(rect, flags);
-}
-
-void RecordPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) {
-  buffer_->push<DrawOvalOp>(oval, flags);
-}
-
-void RecordPaintCanvas::drawRRect(const SkRRect& rrect,
-                                  const PaintFlags& flags) {
-  buffer_->push<DrawRRectOp>(rrect, flags);
-}
-
-void RecordPaintCanvas::drawDRRect(const SkRRect& outer,
-                                   const SkRRect& inner,
-                                   const PaintFlags& flags) {
-  if (outer.isEmpty())
-    return;
-  if (inner.isEmpty()) {
-    drawRRect(outer, flags);
-    return;
-  }
-  buffer_->push<DrawDRRectOp>(outer, inner, flags);
-}
-
-void RecordPaintCanvas::drawCircle(SkScalar cx,
-                                   SkScalar cy,
-                                   SkScalar radius,
-                                   const PaintFlags& flags) {
-  buffer_->push<DrawCircleOp>(cx, cy, radius, flags);
-}
-
-void RecordPaintCanvas::drawArc(const SkRect& oval,
-                                SkScalar start_angle,
-                                SkScalar sweep_angle,
-                                bool use_center,
-                                const PaintFlags& flags) {
-  buffer_->push<DrawArcOp>(oval, start_angle, sweep_angle, use_center, flags);
-}
-
-void RecordPaintCanvas::drawRoundRect(const SkRect& rect,
-                                      SkScalar rx,
-                                      SkScalar ry,
-                                      const PaintFlags& flags) {
-  // TODO(enne): move this into base class?
-  if (rx > 0 && ry > 0) {
-    SkRRect rrect;
-    rrect.setRectXY(rect, rx, ry);
-    drawRRect(rrect, flags);
-  } else {
-    drawRect(rect, flags);
-  }
-}
-
-void RecordPaintCanvas::drawPath(const SkPath& path, const PaintFlags& flags) {
-  buffer_->push<DrawPathOp>(path, flags);
-}
-
-void RecordPaintCanvas::drawImage(sk_sp<const SkImage> image,
-                                  SkScalar left,
-                                  SkScalar top,
-                                  const PaintFlags* flags) {
-  buffer_->push<DrawImageOp>(image, left, top, flags);
-}
-
-void RecordPaintCanvas::drawImageRect(sk_sp<const SkImage> image,
-                                      const SkRect& src,
-                                      const SkRect& dst,
-                                      const PaintFlags* flags,
-                                      SrcRectConstraint constraint) {
-  buffer_->push<DrawImageRectOp>(image, src, dst, flags, constraint);
-}
-
-void RecordPaintCanvas::drawBitmap(const SkBitmap& bitmap,
-                                   SkScalar left,
-                                   SkScalar top,
-                                   const PaintFlags* flags) {
-  // TODO(enne): Move into base class?
-  if (bitmap.drawsNothing())
-    return;
-  drawImage(SkImage::MakeFromBitmap(bitmap), left, top, flags);
-}
-
-void RecordPaintCanvas::drawText(const void* text,
-                                 size_t byte_length,
-                                 SkScalar x,
-                                 SkScalar y,
-                                 const PaintFlags& flags) {
-  buffer_->push_with_data<DrawTextOp>(text, byte_length, x, y, flags);
-}
-
-void RecordPaintCanvas::drawPosText(const void* text,
-                                    size_t byte_length,
-                                    const SkPoint pos[],
-                                    const PaintFlags& flags) {
-  size_t count = ToSkPaint(flags).countText(text, byte_length);
-  buffer_->push_with_data_array<DrawPosTextOp>(text, byte_length, pos, count,
-                                               flags);
-}
-
-void RecordPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob,
-                                     SkScalar x,
-                                     SkScalar y,
-                                     const PaintFlags& flags) {
-  buffer_->push<DrawTextBlobOp>(blob, x, y, flags);
-}
-
-void RecordPaintCanvas::drawDisplayItemList(
-    scoped_refptr<DisplayItemList> list) {
-  buffer_->push<DrawDisplayItemListOp>(list);
-}
-
-void RecordPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) {
-  // TODO(enne): If this is small, maybe flatten it?
-  buffer_->push<DrawRecordOp>(record);
-}
-
-bool RecordPaintCanvas::isClipEmpty() const {
-  return canvas_.isClipEmpty();
-}
-
-bool RecordPaintCanvas::isClipRect() const {
-  return canvas_.isClipRect();
-}
-
-const SkMatrix& RecordPaintCanvas::getTotalMatrix() const {
-  return canvas_.getTotalMatrix();
-}
-
-void RecordPaintCanvas::temporary_internal_describeTopLayer(
-    SkMatrix* matrix,
-    SkIRect* clip_bounds) {
-  return canvas_.temporary_internal_describeTopLayer(matrix, clip_bounds);
-}
-
-bool RecordPaintCanvas::ToPixmap(SkPixmap* output) {
-  // TODO(enne): It'd be nice to make this NOTREACHED() or remove this from
-  // RecordPaintCanvas, but this is used by GraphicsContextCanvas for knowing
-  // whether or not it can raster directly into pixels with Cg.
-  return false;
-}
-
-void RecordPaintCanvas::Annotate(AnnotationType type,
-                                 const SkRect& rect,
-                                 sk_sp<SkData> data) {
-  buffer_->push<AnnotateOp>(type, rect, data);
-}
-
-void RecordPaintCanvas::PlaybackPaintRecord(sk_sp<const PaintRecord> record) {
-  drawPicture(record);
-}
-
-}  // namespace cc
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h
deleted file mode 100644
index e39697c..0000000
--- a/cc/paint/record_paint_canvas.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_PAINT_RECORD_PAINT_CANVAS_H_
-#define CC_PAINT_RECORD_PAINT_CANVAS_H_
-
-#include <memory>
-
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "cc/paint/paint_canvas.h"
-#include "cc/paint/paint_flags.h"
-#include "cc/paint/paint_record.h"
-#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
-
-namespace cc {
-
-class PaintOpBuffer;
-class PaintFlags;
-
-class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas {
- public:
-  explicit RecordPaintCanvas(PaintOpBuffer* buffer, const SkRect& cull_rect);
-  ~RecordPaintCanvas() override;
-
-  SkMetaData& getMetaData() override;
-  SkImageInfo imageInfo() const override;
-
-  void flush() override;
-
-  SkISize getBaseLayerSize() const override;
-  bool writePixels(const SkImageInfo& info,
-                   const void* pixels,
-                   size_t row_bytes,
-                   int x,
-                   int y) override;
-  int save() override;
-  int saveLayer(const SkRect* bounds, const PaintFlags* flags) override;
-  int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
-
-  void restore() override;
-  int getSaveCount() const override;
-  void restoreToCount(int save_count) override;
-  void translate(SkScalar dx, SkScalar dy) override;
-  void scale(SkScalar sx, SkScalar sy) override;
-  void rotate(SkScalar degrees) override;
-  void concat(const SkMatrix& matrix) override;
-  void setMatrix(const SkMatrix& matrix) override;
-
-  void clipRect(const SkRect& rect, SkClipOp op, bool antialias) override;
-  void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) override;
-  void clipPath(const SkPath& path, SkClipOp op, bool antialias) override;
-  bool quickReject(const SkRect& rect) const override;
-  bool quickReject(const SkPath& path) const override;
-  SkRect getLocalClipBounds() const override;
-  bool getLocalClipBounds(SkRect* bounds) const override;
-  SkIRect getDeviceClipBounds() const override;
-  bool getDeviceClipBounds(SkIRect* bounds) const override;
-  void drawColor(SkColor color, SkBlendMode mode) override;
-  void clear(SkColor color) override;
-
-  void drawLine(SkScalar x0,
-                SkScalar y0,
-                SkScalar x1,
-                SkScalar y1,
-                const PaintFlags& flags) override;
-  void drawRect(const SkRect& rect, const PaintFlags& flags) override;
-  void drawIRect(const SkIRect& rect, const PaintFlags& flags) override;
-  void drawOval(const SkRect& oval, const PaintFlags& flags) override;
-  void drawRRect(const SkRRect& rrect, const PaintFlags& flags) override;
-  void drawDRRect(const SkRRect& outer,
-                  const SkRRect& inner,
-                  const PaintFlags& flags) override;
-  void drawCircle(SkScalar cx,
-                  SkScalar cy,
-                  SkScalar radius,
-                  const PaintFlags& flags) override;
-  void drawArc(const SkRect& oval,
-               SkScalar start_angle,
-               SkScalar sweep_angle,
-               bool use_center,
-               const PaintFlags& flags) override;
-  void drawRoundRect(const SkRect& rect,
-                     SkScalar rx,
-                     SkScalar ry,
-                     const PaintFlags& flags) override;
-  void drawPath(const SkPath& path, const PaintFlags& flags) override;
-  void drawImage(sk_sp<const SkImage> image,
-                 SkScalar left,
-                 SkScalar top,
-                 const PaintFlags* flags) override;
-  void drawImageRect(sk_sp<const SkImage> image,
-                     const SkRect& src,
-                     const SkRect& dst,
-                     const PaintFlags* flags,
-                     SrcRectConstraint constraint) override;
-  void drawBitmap(const SkBitmap& bitmap,
-                  SkScalar left,
-                  SkScalar top,
-                  const PaintFlags* flags) override;
-
-  void drawText(const void* text,
-                size_t byte_length,
-                SkScalar x,
-                SkScalar y,
-                const PaintFlags& flags) override;
-  void drawPosText(const void* text,
-                   size_t byte_length,
-                   const SkPoint pos[],
-                   const PaintFlags& flags) override;
-  void drawTextBlob(sk_sp<SkTextBlob> blob,
-                    SkScalar x,
-                    SkScalar y,
-                    const PaintFlags& flags) override;
-
-  void drawDisplayItemList(
-      scoped_refptr<DisplayItemList> display_item_list) override;
-
-  void drawPicture(sk_sp<const PaintRecord> record) override;
-
-  bool isClipEmpty() const override;
-  bool isClipRect() const override;
-  const SkMatrix& getTotalMatrix() const override;
-
-  void temporary_internal_describeTopLayer(SkMatrix* matrix,
-                                           SkIRect* clip_bounds) override;
-
-  bool ToPixmap(SkPixmap* output) override;
-  void Annotate(AnnotationType type,
-                const SkRect& rect,
-                sk_sp<SkData> data) override;
-
-  void PlaybackPaintRecord(sk_sp<const PaintRecord> record) override;
-
-  // Don't shadow non-virtual helper functions.
-  using PaintCanvas::clipRect;
-  using PaintCanvas::clipRRect;
-  using PaintCanvas::clipPath;
-  using PaintCanvas::drawBitmap;
-  using PaintCanvas::drawColor;
-  using PaintCanvas::drawImage;
-  using PaintCanvas::drawPicture;
-
- private:
-  PaintOpBuffer* buffer_;
-
-  // TODO(enne): Although RecordPaintCanvas is mostly a write-only interface
-  // where paint commands are stored, occasionally users of PaintCanvas want
-  // to ask stateful questions mid-stream of clip and transform state.
-  // To avoid duplicating all this code (for now?), just forward to an SkCanvas
-  // that's not backed by anything but can answer these questions.
-  SkNoDrawCanvas canvas_;
-};
-
-}  // namespace cc
-
-#endif  // CC_PAINT_RECORD_PAINT_CANVAS_H_
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc
index 4000942d..94b0cfb7 100644
--- a/cc/paint/skia_paint_canvas.cc
+++ b/cc/paint/skia_paint_canvas.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/paint/skia_paint_canvas.h"
+#include "cc/paint/paint_canvas.h"
 
 #include "base/memory/ptr_util.h"
 #include "cc/paint/display_item_list.h"
@@ -58,7 +58,7 @@
   return canvas_->saveLayer(bounds, ToSkPaint(flags));
 }
 
-int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
+int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
   return canvas_->saveLayerAlpha(bounds, alpha);
 }
 
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h
index aaed2b4..669ca9b 100644
--- a/cc/paint/skia_paint_canvas.h
+++ b/cc/paint/skia_paint_canvas.h
@@ -46,7 +46,7 @@
                    int y) override;
   int save() override;
   int saveLayer(const SkRect* bounds, const PaintFlags* flags) override;
-  int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
+  int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) override;
 
   void restore() override;
   int getSaveCount() const override;
diff --git a/cc/test/test_skcanvas.cc b/cc/test/test_skcanvas.cc
deleted file mode 100644
index e45f42de..0000000
--- a/cc/test/test_skcanvas.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/test/test_skcanvas.h"
-
-namespace cc {
-
-SaveCountingCanvas::SaveCountingCanvas() : SkNoDrawCanvas(100, 100) {}
-
-SkCanvas::SaveLayerStrategy SaveCountingCanvas::getSaveLayerStrategy(
-    const SaveLayerRec& rec) {
-  save_count_++;
-  return SkNoDrawCanvas::getSaveLayerStrategy(rec);
-}
-
-void SaveCountingCanvas::willRestore() {
-  restore_count_++;
-}
-
-void SaveCountingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
-  draw_rect_ = rect;
-  paint_ = paint;
-}
-
-}  // namespace cc
diff --git a/cc/test/test_skcanvas.h b/cc/test/test_skcanvas.h
deleted file mode 100644
index 2b130a4..0000000
--- a/cc/test/test_skcanvas.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TEST_TEST_SKCANVAS_H_
-#define CC_TEST_TEST_SKCANVAS_H_
-
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
-
-namespace cc {
-
-class SaveCountingCanvas : public SkNoDrawCanvas {
- public:
-  SaveCountingCanvas();
-
-  // Note: getSaveLayerStrategy is used as "willSave", as willSave
-  // is not always called.
-  SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override;
-  void willRestore() override;
-  void onDrawRect(const SkRect& rect, const SkPaint& paint) override;
-
-  int save_count_ = 0;
-  int restore_count_ = 0;
-  SkRect draw_rect_;
-  SkPaint paint_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_SKCANVAS_H_
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index 0f152a44..39a8226 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -1130,9 +1130,6 @@
     }
   }
 
-  // TODO(ccameron,msarett): Convert image to target color space.
-  // http://crbug.com/706613
-
   if (image_data->decode.data()) {
     // An at-raster task decoded this before us. Ingore our decode.
     return;
@@ -1196,6 +1193,14 @@
   image_data->decode.mark_used();
   DCHECK(uploaded_image);
 
+  if (draw_image.target_color_space().IsValid()) {
+    TRACE_EVENT0("cc", "GpuImageDecodeCache::UploadImage - color conversion");
+    uploaded_image = uploaded_image->makeColorSpace(
+        draw_image.target_color_space().ToSkColorSpace(),
+        SkTransferFunctionBehavior::kIgnore);
+  }
+  DCHECK(uploaded_image);
+
   // At-raster may have decoded this while we were unlocked. If so, ignore our
   // result.
   if (!image_data->upload.image())
@@ -1214,8 +1219,7 @@
       draw_image.matrix(), CalculateUploadScaleFilterQuality(draw_image),
       upload_scale_mip_level);
   size_t data_size = draw_image.image()->getDeferredTextureImageData(
-      *context_threadsafe_proxy_.get(), &params, 1, nullptr,
-      draw_image.target_color_space().ToSkColorSpace().get());
+      *context_threadsafe_proxy_.get(), &params, 1, nullptr, nullptr);
 
   if (data_size == 0) {
     // Can't upload image, too large or other failure. Try to use SW fallback.
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc
index d7c1059..716d1f4 100644
--- a/cc/tiles/software_image_decode_cache.cc
+++ b/cc/tiles/software_image_decode_cache.cc
@@ -446,7 +446,7 @@
     case kLow_SkFilterQuality:
       if (key.should_use_subrect())
         return GetSubrectImageDecode(key, std::move(image));
-      return GetOriginalImageDecode(std::move(image));
+      return GetOriginalSizeImageDecode(key, std::move(image));
     case kMedium_SkFilterQuality:
     case kHigh_SkFilterQuality:
       return GetScaledImageDecode(key, std::move(image));
@@ -563,22 +563,35 @@
 }
 
 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
-SoftwareImageDecodeCache::GetOriginalImageDecode(sk_sp<const SkImage> image) {
+SoftwareImageDecodeCache::GetOriginalSizeImageDecode(
+    const ImageKey& key,
+    sk_sp<const SkImage> image) {
   SkImageInfo decoded_info =
       CreateImageInfo(image->width(), image->height(), format_);
+  sk_sp<SkColorSpace> target_color_space =
+      key.target_color_space().ToSkColorSpace();
+
   std::unique_ptr<base::DiscardableMemory> decoded_pixels;
   {
     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-                 "SoftwareImageDecodeCache::GetOriginalImageDecode - "
+                 "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
                  "allocate decoded pixels");
     decoded_pixels =
         base::DiscardableMemoryAllocator::GetInstance()
             ->AllocateLockedDiscardableMemory(decoded_info.minRowBytes() *
                                               decoded_info.height());
   }
+  if (target_color_space) {
+    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+                 "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
+                 "color conversion");
+    image = image->makeColorSpace(target_color_space,
+                                  SkTransferFunctionBehavior::kIgnore);
+    DCHECK(image);
+  }
   {
     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-                 "SoftwareImageDecodeCache::GetOriginalImageDecode - "
+                 "SoftwareImageDecodeCache::GetOriginalSizeImageDecode - "
                  "read pixels");
     bool result = image->readPixels(decoded_info, decoded_pixels->data(),
                                     decoded_info.minRowBytes(), 0, 0,
@@ -590,12 +603,10 @@
     }
   }
 
-  // TODO(ccameron,msarett): Convert image to target color space.
-  // http://crbug.com/706613
-
-  return base::MakeUnique<DecodedImage>(decoded_info, std::move(decoded_pixels),
-                                        SkSize::Make(0, 0),
-                                        next_tracing_id_.GetNext());
+  return base::MakeUnique<DecodedImage>(
+      decoded_info.makeColorSpace(target_color_space),
+      std::move(decoded_pixels), SkSize::Make(0, 0),
+      next_tracing_id_.GetNext());
 }
 
 std::unique_ptr<SoftwareImageDecodeCache::DecodedImage>
@@ -609,6 +620,9 @@
       kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space());
   ImageKey original_size_key =
       ImageKey::FromDrawImage(original_size_draw_image);
+  sk_sp<SkColorSpace> target_color_space =
+      key.target_color_space().ToSkColorSpace();
+
   // Sanity checks.
   DCHECK(original_size_key.can_use_original_size_decode())
       << original_size_key.ToString();
@@ -621,6 +635,8 @@
   if (!decoded_draw_image.image())
     return nullptr;
 
+  DCHECK(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
+                              target_color_space.get()));
   SkImageInfo subrect_info = CreateImageInfo(
       key.target_size().width(), key.target_size().height(), format_);
   std::unique_ptr<base::DiscardableMemory> subrect_pixels;
@@ -649,11 +665,9 @@
     DCHECK(result);
   }
 
-  // TODO(ccameron,msarett): Convert image to target color space.
-  // http://crbug.com/706613
-
   return base::WrapUnique(
-      new DecodedImage(subrect_info, std::move(subrect_pixels),
+      new DecodedImage(subrect_info.makeColorSpace(target_color_space),
+                       std::move(subrect_pixels),
                        SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
                        next_tracing_id_.GetNext()));
 }
@@ -669,6 +683,9 @@
       kNone_SkFilterQuality, SkMatrix::I(), key.target_color_space());
   ImageKey original_size_key =
       ImageKey::FromDrawImage(original_size_draw_image);
+  sk_sp<SkColorSpace> target_color_space =
+      key.target_color_space().ToSkColorSpace();
+
   // Sanity checks.
   DCHECK(original_size_key.can_use_original_size_decode())
       << original_size_key.ToString();
@@ -691,6 +708,8 @@
   }
 
   DCHECK(!key.target_size().IsEmpty());
+  DCHECK(SkColorSpace::Equals(decoded_draw_image.image()->colorSpace(),
+                              target_color_space.get()));
   SkImageInfo scaled_info = CreateImageInfo(
       key.target_size().width(), key.target_size().height(), format_);
   std::unique_ptr<base::DiscardableMemory> scaled_pixels;
@@ -714,11 +733,9 @@
     DCHECK(result) << key.ToString();
   }
 
-  // TODO(ccameron,msarett): Convert image to target color space.
-  // http://crbug.com/706613
-
   return base::MakeUnique<DecodedImage>(
-      scaled_info, std::move(scaled_pixels),
+      scaled_info.makeColorSpace(decoded_draw_image.image()->refColorSpace()),
+      std::move(scaled_pixels),
       SkSize::Make(-key.src_rect().x(), -key.src_rect().y()),
       next_tracing_id_.GetNext());
 }
diff --git a/cc/tiles/software_image_decode_cache.h b/cc/tiles/software_image_decode_cache.h
index 86b9d7f..1d3e2ac 100644
--- a/cc/tiles/software_image_decode_cache.h
+++ b/cc/tiles/software_image_decode_cache.h
@@ -249,18 +249,20 @@
   DecodedDrawImage GetDecodedImageForDrawInternal(const ImageKey& key,
                                                   const DrawImage& draw_image);
 
-  // GetOriginalImageDecode is called by DecodeImageInternal when the quality
-  // does not scale the image. Like DecodeImageInternal, it should be called
-  // with no lock acquired and it returns nullptr if the decoding failed.
-  std::unique_ptr<DecodedImage> GetOriginalImageDecode(
+  // GetOriginalSizeImageDecode is called by DecodeImageInternal when the
+  // quality does not scale the image. Like DecodeImageInternal, it should be
+  // called with no lock acquired and it returns nullptr if the decoding failed.
+  std::unique_ptr<DecodedImage> GetOriginalSizeImageDecode(
+      const ImageKey& key,
       sk_sp<const SkImage> image);
 
-  // GetSubrectImageDecode is similar to GetOriginalImageDecode in that no scale
-  // is performed on the image. However, we extract a subrect (copy it out) and
-  // only return this subrect in order to cache a smaller amount of memory. Note
-  // that this uses GetOriginalImageDecode to get the initial data, which
-  // ensures that we cache an unlocked version of the original image in case we
-  // need to extract multiple subrects (as would be the case in an atlas).
+  // GetSubrectImageDecode is similar to GetOriginalSizeImageDecode in that no
+  // scale is performed on the image. However, we extract a subrect (copy it
+  // out) and only return this subrect in order to cache a smaller amount of
+  // memory. Note that this uses GetOriginalSizeImageDecode to get the initial
+  // data, which ensures that we cache an unlocked version of the original image
+  // in case we need to extract multiple subrects (as would be the case in an
+  // atlas).
   std::unique_ptr<DecodedImage> GetSubrectImageDecode(
       const ImageKey& key,
       sk_sp<const SkImage> image);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 57b41d5d..2d73b88 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -360,7 +360,10 @@
     "//components/web_restrictions:web_restrictions_java",
     "//content/public/android:content_java",
     "//device/geolocation:geolocation_java",
+    "//mojo/public/java:bindings_java",
+    "//mojo/public/java:system_java",
     "//net/android:net_java",
+    "//third_party/WebKit/public:android_mojo_bindings_java",
     "//third_party/WebKit/public:blink_headers_java",
     "//third_party/WebKit/public:mojo_bindings_java",
     "//third_party/android_tools:android_support_annotations_java",
@@ -370,6 +373,7 @@
     "//third_party/cacheinvalidation:cacheinvalidation_javalib",
     "//third_party/hamcrest:hamcrest_java",
     "//ui/android:ui_java",
+    "//url/mojo:url_mojom_gurl_java",
     google_play_services_library,
   ]
   srcjar_deps = [ "//base:base_build_config_gen" ]
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index a528f07..46c4a51 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -36,6 +36,7 @@
     {% endif %}
     <uses-permission-sdk-m android:name="android.permission.BLUETOOTH"/>
     <uses-permission-sdk-m android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission-sdk-m android:name="android.permission.REORDER_TASKS"/>
     <uses-permission-sdk-m android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
 
     <uses-permission android:name="android.permission.CAMERA" />
@@ -365,41 +366,7 @@
             {% block supports_video_persistence %}
             {% endblock %}
             >
-            <!--
-              See the VRChromeTabbedActivity alias below for an explanation of this dummy intent
-              filter. We need to add these filters here as well, or non-presenting webVR pages will
-              trigger a daydream incompatible app message.
-            -->
-            <intent-filter>
-                <action android:name="org.chromium.chrome.browser.dummy.action" />
-                <category android:name="com.google.intent.category.DAYDREAM" />
-                <category android:name="com.google.intent.category.CARDBOARD" />
-            </intent-filter>
         </activity>
-
-        {% if enable_vr == "true" %}
-        <!--
-            TODO(mthiesse): Temporarily skip ChromeLauncherActivity when returning from Daydream
-            DON flow to avoid polluting metrics.
-        -->
-        <activity-alias android:name="org.chromium.chrome.browser.VRChromeTabbedActivity"
-            android:targetActivity="org.chromium.chrome.browser.ChromeTabbedActivity"
-            android:enableVrMode="@string/gvr_vr_mode_component">
-            <!--
-              Daydream api categorizes an activity to three categories: Cardboard only, hybrid
-              or Daydream. It does so by testing if intents can be resolved by the activity
-              that requests it.
-              In Chrome, CTA is the activity that uses Daydream api and we want to be in hybrid
-              category. So add an intent filter that could pass Daydream tests here.
-            -->
-            <intent-filter>
-                <action android:name="org.chromium.chrome.browser.dummy.action" />
-                <category android:name="com.google.intent.category.DAYDREAM" />
-                <category android:name="com.google.intent.category.CARDBOARD" />
-            </intent-filter>
-        </activity-alias>
-        {% endif %}
-
         <activity android:name="org.chromium.chrome.browser.ChromeTabbedActivity2"
              android:theme="@style/TabbedModeTheme"
              android:exported="false"
@@ -731,8 +698,7 @@
 
         {% if channel in ['canary', 'default'] %}
         <!-- Search widget -->
-        <receiver android:name="org.chromium.chrome.browser.searchwidget.SearchWidgetProvider"
-            android:process=":search_widget">
+        <receiver android:name="org.chromium.chrome.browser.searchwidget.SearchWidgetProvider">
             <intent-filter>
                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
             </intent-filter>
@@ -748,7 +714,7 @@
 
         <!-- Search Activity -->
         <activity android:name="org.chromium.chrome.browser.searchwidget.SearchActivity"
-            android:theme="@style/MainTheme"
+            android:theme="@style/SearchActivityTheme"
             android:label="Search"
             android:exported="false"
             android:launchMode="singleTask"
diff --git a/chrome/android/java/res/layout/search_activity.xml b/chrome/android/java/res/layout/search_activity.xml
index 739da14..b468890f 100644
--- a/chrome/android/java/res/layout/search_activity.xml
+++ b/chrome/android/java/res/layout/search_activity.xml
@@ -6,8 +6,7 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/control_container"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@color/google_grey_500" >
+        android:layout_height="match_parent" >
 
     <!-- This view is unnecessary visually, but required for the LocationBarLayout. -->
     <org.chromium.chrome.browser.searchwidget.SearchActivityFadingBackgroundView
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml
index beace155..a88aab4c8 100644
--- a/chrome/android/java/res/values-v17/styles.xml
+++ b/chrome/android/java/res/values-v17/styles.xml
@@ -42,6 +42,10 @@
         <item name="android:windowSharedElementExitTransition" tools:targetApi="21">@transition/move_image</item>
     </style>
 
+    <style name="SearchActivityTheme" parent="MainTheme">
+        <item name="android:windowBackground">@color/google_grey_500</item>
+    </style>
+
     <style name="TabbedModeTheme" parent="MainTheme">
         <item name="android:windowBackground">@drawable/window_background</item>
     </style>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
index 4e4aca0..8b54604ab 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
@@ -4,9 +4,12 @@
 
 package org.chromium.chrome.browser;
 
+import android.os.SystemClock;
+import android.util.LruCache;
 import android.webkit.URLUtil;
 
 import org.chromium.base.SysUtils;
+import org.chromium.base.VisibleForTesting;
 import org.chromium.blink.mojom.document_metadata.CopylessPaste;
 import org.chromium.blink.mojom.document_metadata.WebPage;
 import org.chromium.chrome.browser.historyreport.AppIndexingReporter;
@@ -19,31 +22,124 @@
  * This is the top-level CopylessPaste metadata extraction for AppIndexing.
  */
 public class AppIndexingUtil {
-    public static void extractCopylessPasteMetadata(final Tab tab) {
-        String url = tab.getUrl();
+    private static final int CACHE_SIZE = 100;
+    private static final int CACHE_VISIT_CUTOFF_MS = 60 * 60 * 1000; // 1 hour
+    // Cache of recently seen urls. If a url is among the CACHE_SIZE most recent pages visited, and
+    // the parse was in the last CACHE_VISIT_CUTOFF_MS milliseconds, then we don't parse the page,
+    // and instead just report the view (not the content) to App Indexing.
+    private LruCache<String, CacheEntry> mPageCache;
+
+    /**
+     * Extracts entities from document metadata and reports it to on-device App Indexing.
+     * This call can cache entities from recently parsed webpages, in which case, only the url and
+     * title of the page is reported to App Indexing.
+     */
+    public void extractCopylessPasteMetadata(final Tab tab) {
+        final String url = tab.getUrl();
         boolean isHttpOrHttps = URLUtil.isHttpsUrl(url) || URLUtil.isHttpUrl(url);
-        if (SysUtils.isLowEndDevice() || tab.isIncognito()
-                || !ChromeFeatureList.isEnabled(ChromeFeatureList.COPYLESS_PASTE)
-                || !isHttpOrHttps) {
+        if (!isEnabledForDevice() || tab.isIncognito() || !isHttpOrHttps) {
             return;
         }
 
+        // There are three conditions that can occur with respect to the cache.
+        // 1. Cache hit, and an entity was found previously. Report only the page view to App
+        //    Indexing.
+        // 2. Cache hit, but no entity was found. Ignore.
+        // 3. Cache miss, we need to parse the page.
+        if (wasPageVisitedRecently(url)) {
+            if (lastPageVisitContainedEntity(url)) {
+                // Condition 1
+                getAppIndexingReporter().reportWebPageView(url, tab.getTitle());
+            }
+            // Condition 2
+        } else {
+            // Condition 3
+            CopylessPaste copylessPaste = getCopylessPasteInterface(tab);
+            if (copylessPaste == null) {
+                return;
+            }
+            copylessPaste.getEntities(new CopylessPaste.GetEntitiesResponse() {
+                @Override
+                public void call(WebPage webpage) {
+                    putCacheEntry(url, webpage != null);
+                    if (webpage == null) return;
+                    getAppIndexingReporter().reportWebPage(webpage);
+                }
+            });
+        }
+    }
+
+    private boolean wasPageVisitedRecently(String url) {
+        if (url == null) {
+            return false;
+        }
+        CacheEntry entry = getPageCache().get(url);
+        if (entry == null || (getElapsedTime() - entry.lastSeenTimeMs > CACHE_VISIT_CUTOFF_MS)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the page is in the cache and it contained an entity the last time it was
+     * parsed.
+     */
+    private boolean lastPageVisitContainedEntity(String url) {
+        if (url == null) {
+            return false;
+        }
+        CacheEntry entry = getPageCache().get(url);
+        if (entry == null || !entry.containedEntity) {
+            return false;
+        }
+        return true;
+    }
+
+    private void putCacheEntry(String url, boolean containedEntity) {
+        CacheEntry entry = new CacheEntry();
+        entry.lastSeenTimeMs = getElapsedTime();
+        entry.containedEntity = containedEntity;
+        getPageCache().put(url, entry);
+    }
+
+    @VisibleForTesting
+    AppIndexingReporter getAppIndexingReporter() {
+        return AppIndexingReporter.getInstance();
+    }
+
+    @VisibleForTesting
+    CopylessPaste getCopylessPasteInterface(Tab tab) {
         WebContents webContents = tab.getWebContents();
-        if (webContents == null) return;
+        if (webContents == null) return null;
 
         RenderFrameHost mainFrame = webContents.getMainFrame();
-        if (mainFrame == null) return;
+        if (mainFrame == null) return null;
 
         InterfaceProvider interfaces = mainFrame.getRemoteInterfaces();
-        if (interfaces == null) return;
+        if (interfaces == null) return null;
 
-        CopylessPaste copylesspaste = interfaces.getInterface(CopylessPaste.MANAGER);
-        copylesspaste.getEntities(new CopylessPaste.GetEntitiesResponse() {
-            @Override
-            public void call(WebPage webpage) {
-                if (webpage == null) return;
-                AppIndexingReporter.getInstance().reportWebPage(webpage);
-            }
-        });
+        return interfaces.getInterface(CopylessPaste.MANAGER);
+    }
+
+    @VisibleForTesting
+    long getElapsedTime() {
+        return SystemClock.elapsedRealtime();
+    }
+
+    boolean isEnabledForDevice() {
+        return !SysUtils.isLowEndDevice()
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.COPYLESS_PASTE);
+    }
+
+    private LruCache<String, CacheEntry> getPageCache() {
+        if (mPageCache == null) {
+            mPageCache = new LruCache<String, CacheEntry>(CACHE_SIZE);
+        }
+        return mPageCache;
+    }
+
+    private static class CacheEntry {
+        public long lastSeenTimeMs;
+        public boolean containedEntity;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index 3fae79dc..aff7e4b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -853,7 +853,7 @@
                 MultiWindowUtils.getInstance().isInMultiWindowMode(this));
 
         VideoPersister.getInstance().cleanup(this);
-        VrShellDelegate.maybeRegisterVREntryHook(this);
+        VrShellDelegate.maybeRegisterVrEntryHook(this);
     }
 
     @Override
@@ -869,7 +869,7 @@
         if (tab != null) getTabContentManager().cacheTabThumbnail(tab);
         ContentViewCore cvc = getContentViewCore();
         if (cvc != null) cvc.onPause();
-        VrShellDelegate.maybeUnregisterVREntryHook(this);
+        VrShellDelegate.maybeUnregisterVrEntryHook(this);
         markSessionEnd();
         super.onPauseWithNative();
     }
@@ -2131,15 +2131,25 @@
         }
     }
 
+    @Override
+    public boolean onActivityResultWithNative(int requestCode, int resultCode, Intent intent) {
+        if (super.onActivityResultWithNative(requestCode, resultCode, intent)) return true;
+        if (requestCode == VrShellDelegate.EXIT_VR_RESULT) {
+            VrShellDelegate.onExitVrResult(resultCode);
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Called when VR mode is entered using this activity. 2D UI components that steal focus or
      * draw over VR contents should be hidden in this call.
      */
-    public void onEnterVR() {}
+    public void onEnterVr() {}
 
     /**
      * Called when VR mode using this activity is exited. Any state set for VR should be restored
      * in this call, including showing 2D UI that was hidden.
      */
-    public void onExitVR() {}
+    public void onExitVr() {}
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java
index 9c8fddfb..f357f06 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java
@@ -182,6 +182,9 @@
     public static final String ALWAYS_EXTRACT_WEBAPK_RUNTIME_DEX_ON_STARTUP =
             "always-extract-webapk-dex-on-startup";
 
+    /** Enable non-'org.chromium.webapk' prefixed package names with proper signature. */
+    public static final String ENABLE_ANY_WEBAPK_PACKAGE_NAME = "any-webapk-package-name";
+
     /**
      * Forces a check for whether the WebAPK's Web Manifest has changed each time that a WebAPK is
      * launched.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 8e454fe..e7b6ff7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -231,6 +231,8 @@
 
     private LocaleManager mLocaleManager;
 
+    private AppIndexingUtil mAppIndexingUtil;
+
     /**
      * Keeps track of whether or not a specific tab was created based on the startup intent.
      */
@@ -267,13 +269,13 @@
 
         @Override
         public boolean isShowingBrowserControlsEnabled() {
-            if (VrShellDelegate.isInVR()) return false;
+            if (VrShellDelegate.isInVr()) return false;
             return super.isShowingBrowserControlsEnabled();
         }
 
         @Override
         public boolean isHidingBrowserControlsEnabled() {
-            if (VrShellDelegate.isInVR()) return true;
+            if (VrShellDelegate.isInVr()) return true;
             return super.isHidingBrowserControlsEnabled();
         }
     }
@@ -314,6 +316,7 @@
     public ChromeTabbedActivity() {
         mActivityStopMetrics = new ActivityStopMetrics();
         mMainIntentMetrics = new MainIntentBehaviorMetrics(this);
+        mAppIndexingUtil = new AppIndexingUtil();
     }
 
     @Override
@@ -444,7 +447,7 @@
     @SuppressLint("NewApi")
     private boolean shouldDestroyIncognitoProfile() {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return false;
-        if (VrShellDelegate.isInVR()) return false; // VR uses an incognito profile for rendering.
+        if (VrShellDelegate.isInVr()) return false; // VR uses an incognito profile for rendering.
 
         Context context = ContextUtils.getApplicationContext();
         ActivityManager manager =
@@ -578,10 +581,7 @@
             if (CommandLine.getInstance().hasSwitch(ContentSwitches.ENABLE_TEST_INTENTS)) {
                 handleDebugIntent(intent);
             }
-            if (VrShellDelegate.isDaydreamVrIntent(intent)) {
-                // TODO(mthiesse): Move this into ChromeActivity. crbug.com/688611
-                VrShellDelegate.enterVRFromIntent(intent);
-            } else if (ShortcutHelper.isShowToastIntent(intent)) {
+            if (ShortcutHelper.isShowToastIntent(intent)) {
                 ShortcutHelper.showAddedToHomescreenToastFromIntent(intent);
             }
         } finally {
@@ -817,12 +817,7 @@
 
             mIntentWithEffect = false;
             if ((mIsOnFirstRun || getSavedInstanceState() == null) && intent != null) {
-                if (VrShellDelegate.isDaydreamVrIntent(intent)) {
-                    // TODO(mthiesse): Improve startup when started from a VR intent.
-                    //     crbug.com/668541
-                    // TODO(mthiesse): Move this into ChromeActivity. crbug.com/688611
-                    VrShellDelegate.enterVRIfNecessary();
-                } else if (!mIntentHandler.shouldIgnoreIntent(intent)) {
+                if (!mIntentHandler.shouldIgnoreIntent(intent)) {
                     mIntentWithEffect = mIntentHandler.onNewIntent(intent);
                 }
 
@@ -900,10 +895,6 @@
                 }
             }
             return true;
-        } else if (requestCode == VrShellDelegate.EXIT_VR_RESULT) {
-            // TODO(mthiesse): Move this into ChromeActivity. crbug.com/688611
-            VrShellDelegate.onExitVRResult(resultCode);
-            return true;
         }
         return false;
     }
@@ -1249,7 +1240,7 @@
 
             @Override
             public void onPageLoadFinished(final Tab tab) {
-                AppIndexingUtil.extractCopylessPasteMetadata(tab);
+                mAppIndexingUtil.extractCopylessPasteMetadata(tab);
             }
 
             @Override
@@ -1468,7 +1459,7 @@
             if (!currentModel.isIncognito()) currentModel.openMostRecentlyClosedTab();
             RecordUserAction.record("MobileTabClosedUndoShortCut");
         } else if (id == R.id.enter_vr_id) {
-            VrShellDelegate.enterVRIfNecessary();
+            VrShellDelegate.enterVrIfNecessary();
         } else {
             return super.onMenuOrKeyboardAction(id, fromMenu);
         }
@@ -1941,14 +1932,14 @@
     }
 
     @Override
-    public void onEnterVR() {
-        super.onEnterVR();
+    public void onEnterVr() {
+        super.onEnterVr();
         mControlContainer.setVisibility(View.INVISIBLE);
     }
 
     @Override
-    public void onExitVR() {
-        super.onExitVR();
+    public void onExitVr() {
+        super.onExitVr();
         mControlContainer.setVisibility(View.VISIBLE);
 
         // We prevent the incognito profile from being destroyed while in VR, so upon exiting VR we
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
index 1894998..80350eb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -961,7 +961,7 @@
      * {@link CompositorViewHolder} so that VR can take ownership of Chrome's rendering.
      * @return The detached {@link TabModelSelector}.
      */
-    public TabModelSelector detachForVR() {
+    public TabModelSelector detachForVr() {
         if (mTabModelSelector != null) mTabModelSelector.removeObserver(mTabModelSelectorObserver);
         TabModelSelector selector = mTabModelSelector;
         mTabModelSelector = null;
@@ -976,7 +976,7 @@
      * so that it can take back ownership of Chrome's rendering.
      * @param tabModelSelector
      */
-    public void onExitVR(TabModelSelector tabModelSelector) {
+    public void onExitVr(TabModelSelector tabModelSelector) {
         getCompositorView().setVisibility(View.VISIBLE);
         attachToTabModelSelector(tabModelSelector);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
index 92670c0..a50ca8d4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
@@ -29,6 +29,15 @@
     }
 
     /**
+     * Reports view of provided url to on-device index.
+     * Base class does not implement any reporting, and call is a no-op. Child classes should
+     * implement this functionality.
+     */
+    public void reportWebPageView(String url, String title) {
+        // Overriden by private class. Base class does nothing.
+    }
+
+    /**
      * Clears history of reported entities.
      * Currently, we do not support clearing only a subset of history. Base class does not implement
      * any reporting, and call is a no-op. Child classes should implement this functionality.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java
index 9a26c64..d767d0b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java
@@ -159,11 +159,6 @@
     private int mNumRecentTabPages;
 
     /**
-     * Whether GCM Upstream should be used for sending upstream messages.
-     */
-    private boolean mUseGcmUpstream;
-
-    /**
      * Whether GCM has been initialized for Invalidations.
      */
     private boolean mGcmInitialized;
@@ -209,7 +204,8 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... arg0) {
-                AndroidGcmController.get(mContext).initializeGcm(mUseGcmUpstream);
+                boolean useGcmUpstream = true;
+                AndroidGcmController.get(mContext).initializeGcm(useGcmUpstream);
                 return null;
             }
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -308,10 +304,7 @@
                 boolean canDisableSessionInvalidations = !requireInvalidationsForInstrumentation
                         && !requireInvalidationsForSuggestions;
 
-                boolean canUseGcmUpstream =
-                        FieldTrialList.findFullName("InvalidationsGCMUpstream").equals("Enabled");
-                sInstance = new InvalidationController(
-                        context, canDisableSessionInvalidations, canUseGcmUpstream);
+                sInstance = new InvalidationController(context, canDisableSessionInvalidations);
             }
             return sInstance;
         }
@@ -343,12 +336,10 @@
      * Creates an instance using {@code context} to send intents.
      */
     @VisibleForTesting
-    InvalidationController(
-            Context context, boolean canDisableSessionInvalidations, boolean canUseGcmUpstream) {
+    InvalidationController(Context context, boolean canDisableSessionInvalidations) {
         Context appContext = context.getApplicationContext();
         if (appContext == null) throw new NullPointerException("Unable to get application context");
         mContext = appContext;
-        mUseGcmUpstream = canUseGcmUpstream;
         mCanDisableSessionInvalidations = canDisableSessionInvalidations;
         mSessionInvalidationsEnabled = !mCanDisableSessionInvalidations;
         mEnableSessionInvalidationsTimer = new Timer();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java
index 4e295e37c..59bdeeb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java
@@ -42,7 +42,8 @@
     public static final int EVENT_SHOWN = 1 << 0;
     public static final int EVENT_PAY_CLICKED = 1 << 1;
     public static final int EVENT_RECEIVED_INSTRUMENT_DETAILS = 1 << 2;
-    public static final int EVENT_MAX = 8;
+    public static final int EVENT_SKIPPED_SHOW = 1 << 3;
+    public static final int EVENT_MAX = 16;
 
     // The minimum expected value of CustomCountHistograms is always set to 1. It is still possible
     // to log the value 0 to that type of histogram.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index 843622c..3a39415c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -598,8 +598,8 @@
 
             mDidRecordShowEvent = true;
             mShouldRecordAbortReason = true;
-            recordSuccessFunnelHistograms("Shown");
-            mJourneyLogger.setEventOccurred(JourneyLogger.EVENT_SHOWN);
+            recordSuccessFunnelHistograms("SkippedShow");
+            mJourneyLogger.setEventOccurred(JourneyLogger.EVENT_SKIPPED_SHOW);
             mJourneyLogger.setShowCalled();
 
             onPayClicked(null /* selectedShippingAddress */, null /* selectedShippingOption */,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
index 7313f57..665f1a3b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestSection.java
@@ -458,7 +458,7 @@
             mChevronView.setVisibility(
                     mDisplayMode == DISPLAY_MODE_EXPANDABLE ? VISIBLE : GONE);
         } else {
-            // Show the edit button and hide the chevron and the summary.
+            // Show the edit button and hide the chevron.
             boolean isButtonAllowed = mDisplayMode == DISPLAY_MODE_EXPANDABLE
                     || mDisplayMode == DISPLAY_MODE_NORMAL;
             mChevronView.setVisibility(GONE);
@@ -677,6 +677,13 @@
                     new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
             breakdownParams.gravity = Gravity.END;
             mainSectionLayout.addView(mBreakdownLayout, breakdownParams);
+
+            // Sets the summary right text view takes the same available space as the summary left
+            // text view.
+            LinearLayout.LayoutParams rightTextViewLayoutParams =
+                    (LinearLayout.LayoutParams) getSummaryRightTextView().getLayoutParams();
+            rightTextViewLayoutParams.width = 0;
+            rightTextViewLayoutParams.weight = 1f;
         }
 
         /**
@@ -699,6 +706,9 @@
             ApiCompatibilityUtils.setTextAlignment(mUpdatedView, TEXT_ALIGNMENT_TEXT_END);
             mUpdatedView.setTextColor(ApiCompatibilityUtils.getColor(
                     context.getResources(), R.color.google_green_700));
+            ApiCompatibilityUtils.setMarginStart(updatedLayoutParams,
+                    context.getResources().getDimensionPixelSize(
+                            R.dimen.payments_section_small_spacing));
             ApiCompatibilityUtils.setMarginEnd(
                     updatedLayoutParams, context.getResources().getDimensionPixelSize(
                                                  R.dimen.payments_section_small_spacing));
@@ -834,6 +844,23 @@
         }
 
         @Override
+        public void setDisplayMode(int displayMode) {
+            // Displays the summary left text view in at most three lines if in focus mode,
+            // otherwise display it in a single line.
+            if (displayMode == DISPLAY_MODE_FOCUSED) {
+                setSummaryProperties(TruncateAt.END, false /* leftIsSingleLine */,
+                        null /* rightTruncate */, false /* rightIsSingleLine */);
+                getSummaryLeftTextView().setMaxLines(3);
+            } else {
+                setSummaryProperties(TruncateAt.END, true /* leftIsSingleLine */,
+                        null /* rightTruncate */, false /* rightIsSingleLine */);
+                getSummaryLeftTextView().setMaxLines(1);
+            }
+
+            super.setDisplayMode(displayMode);
+        }
+
+        @Override
         protected void updateControlLayout() {
             if (!mIsLayoutInitialized) return;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
index 864caba7..609ff7c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
@@ -45,6 +45,7 @@
     private static final String HERB_FLAVOR_KEY = "herb_flavor";
     private static final String WEBAPK_COMMAND_LINE_KEY = "webapk.command_line_enabled";
     private static final String WEBAPK_RUNTIME_KEY = "webapk.runtime_enabled";
+    private static final String WEBAPK_ANY_PACKAGE_KEY = "webapk.any_package_name";
     private static final String CHROME_HOME_ENABLED_KEY = "chrome_home_enabled";
 
     private static final String CHROME_DEFAULT_BROWSER = "applink.chrome_default_browser";
@@ -351,6 +352,16 @@
         writeBoolean(WEBAPK_RUNTIME_KEY, isEnabled);
     }
 
+    /** Checks the cached value for the webapk any package name feature. */
+    public boolean getCachedWebApkAnyPackageName() {
+        return mSharedPreferences.getBoolean(WEBAPK_ANY_PACKAGE_KEY, false);
+    }
+
+    /** Writes the cached value for the webapk any package name feature is enabled. */
+    public void setCachedWebApkAnyPackageNameEnabled(boolean isEnabled) {
+        writeBoolean(WEBAPK_ANY_PACKAGE_KEY, isEnabled);
+    }
+
     public boolean getCachedChromeDefaultBrowser() {
         return mSharedPreferences.getBoolean(CHROME_DEFAULT_BROWSER, false);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java
index 161a60a..5fe5f3a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java
@@ -38,6 +38,7 @@
 import org.chromium.chrome.browser.preferences.Preferences;
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
 import org.chromium.chrome.browser.preferences.website.Website.StoredDataClearedCallback;
+import org.chromium.chrome.browser.searchwidget.SearchWidgetProvider;
 
 import java.util.Collection;
 
@@ -257,6 +258,8 @@
                         RecordHistogram.recordEnumeratedHistogram("Android.ManageSpace.ActionTaken",
                                 OPTION_CLEAR_APP_DATA, OPTION_MAX);
                     }
+
+                    SearchWidgetProvider.reset();
                     activityManager.clearApplicationUserData();
                 }
             });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
index deeb6a1..84d23c9b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivity.java
@@ -7,20 +7,17 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Handler;
-import android.support.customtabs.CustomTabsIntent;
 import android.support.v4.app.ActivityOptionsCompat;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
-import org.chromium.base.ContextUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.WebContentsFactory;
 import org.chromium.chrome.browser.WindowDelegate;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
-import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.init.AsyncInitializationActivity;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.omnibox.AutocompleteController;
@@ -171,22 +168,12 @@
         // resending a queued query after the user deleted it.
         if (TextUtils.isEmpty(url)) return;
 
-        // Fix up the URL and send it to a tab.
+        // Fix up the URL and send it to the full browser.
         String fixedUrl = UrlFormatter.fixupUrl(url);
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(fixedUrl));
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
-
-        boolean useHerbTab = ContextUtils.getAppSharedPreferences().getBoolean(
-                SearchWidgetProvider.PREF_USE_HERB_TAB, false);
-        if (useHerbTab) {
-            intent = ChromeLauncherActivity.createCustomTabActivityIntent(this, intent, true);
-            intent.putExtra(CustomTabsIntent.EXTRA_TITLE_VISIBILITY_STATE,
-                    CustomTabsIntent.SHOW_PAGE_TITLE);
-        } else {
-            intent.setPackage(getPackageName());
-            IntentHandler.addTrustedIntentExtras(intent);
-        }
-
+        intent.setPackage(getPackageName());
+        IntentHandler.addTrustedIntentExtras(intent);
         IntentUtils.safeStartActivity(this, intent,
                 ActivityOptionsCompat
                         .makeCustomAnimation(this, android.R.anim.fade_in, android.R.anim.fade_out)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java
index bd189f4b..76487ba 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java
@@ -75,12 +75,13 @@
 
     /** Called when the SearchActivity has finished initialization. */
     void onDeferredStartup(boolean isVoiceSearchIntent) {
+        SearchWidgetProvider.updateCachedVoiceSearchAvailability(isVoiceSearchEnabled());
         if (isVoiceSearchIntent && mUrlBar.isFocused()) onUrlFocusChange(true);
     }
 
     /** Begins a new query. */
     void beginQuery(boolean isVoiceSearchIntent) {
-        if (isVoiceSearchIntent) {
+        if (isVoiceSearchEnabled() && isVoiceSearchIntent) {
             startVoiceRecognition();
         } else {
             focusTextBox();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java
index 8527aed..e3a01fd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java
@@ -15,6 +15,7 @@
 import android.os.Bundle;
 import android.support.v4.app.ActivityOptionsCompat;
 import android.text.TextUtils;
+import android.view.View;
 import android.widget.RemoteViews;
 
 import org.chromium.base.ContextUtils;
@@ -23,13 +24,13 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.init.AsyncInitializationActivity;
 import org.chromium.chrome.browser.search_engines.TemplateUrlService;
 import org.chromium.chrome.browser.search_engines.TemplateUrlService.LoadListener;
 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrlServiceObserver;
 
 /**
- * Widget that lets the user search using the default search engine in Chrome.
+ * Widget that lets the user search using their default search engine.
+ *
  * Because this is a BroadcastReceiver, it dies immediately after it runs.  A new one is created
  * for each new broadcast.
  */
@@ -59,20 +60,19 @@
     static final String EXTRA_START_VOICE_SEARCH =
             "org.chromium.chrome.browser.searchwidget.START_VOICE_SEARCH";
 
+    private static final String PREF_IS_VOICE_SEARCH_AVAILABLE =
+            "org.chromium.chrome.browser.searchwidget.IS_VOICE_SEARCH_AVAILABLE";
     private static final String PREF_SEARCH_ENGINE_SHORTNAME =
             "org.chromium.chrome.browser.searchwidget.SEARCH_ENGINE_SHORTNAME";
-    static final String PREF_USE_HERB_TAB = "org.chromium.chrome.browser.searchwidget.USE_HERB_TAB";
 
     private static final String TAG = "searchwidget";
     private static final Object OBSERVER_LOCK = new Object();
 
     private static SearchWidgetTemplateUrlServiceObserver sObserver;
-    private static String sCachedSearchEngineName;
 
     /**
      * Creates the singleton instance of the observer that will monitor for search engine changes.
-     * The native library and the browser process must have been fully loaded before calling this,
-     * after {@link AsyncInitializationActivity#finishNativeInitialization}.
+     * The native library and the browser process must have been fully loaded before calling this.
      */
     public static void initialize() {
         ThreadUtils.assertOnUiThread();
@@ -84,13 +84,19 @@
             sObserver = new SearchWidgetTemplateUrlServiceObserver();
 
             TemplateUrlService service = TemplateUrlService.getInstance();
+            service.registerLoadListener(sObserver);
             service.addObserver(sObserver);
-            if (!service.isLoaded()) {
-                service.registerLoadListener(sObserver);
-                service.load();
-            }
+            if (!service.isLoaded()) service.load();
         }
-        updateCachedEngineName();
+    }
+
+    /** Nukes all cached information and forces all widgets to start with a blank slate. */
+    public static void reset() {
+        SharedPreferences.Editor editor = ContextUtils.getAppSharedPreferences().edit();
+        editor.remove(PREF_IS_VOICE_SEARCH_AVAILABLE);
+        editor.remove(PREF_SEARCH_ENGINE_SHORTNAME);
+        editor.apply();
+        updateAllWidgets();
     }
 
     @Override
@@ -98,13 +104,11 @@
         if (IntentHandler.isIntentChromeOrFirstParty(intent)) {
             if (ACTION_START_TEXT_QUERY.equals(intent.getAction())) {
                 startSearchActivity(context, false);
-                return;
             } else if (ACTION_START_VOICE_QUERY.equals(intent.getAction())) {
                 startSearchActivity(context, true);
-                return;
+            } else if (ACTION_UPDATE_ALL_WIDGETS.equals(intent.getAction())) {
+                performUpdate(context);
             }
-        } else if (ACTION_UPDATE_ALL_WIDGETS.equals(intent.getAction())) {
-            performUpdate(context);
             return;
         }
         super.onReceive(context, intent);
@@ -115,13 +119,12 @@
 
         // Launch the SearchActivity.
         Intent searchIntent = new Intent();
-        searchIntent.setClassName(context, SearchActivity.class.getName());
+        searchIntent.setClass(context, SearchActivity.class);
         searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         searchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
         searchIntent.putExtra(EXTRA_START_VOICE_SEARCH, startVoiceSearch);
 
-        Bundle optionsBundle;
-        optionsBundle =
+        Bundle optionsBundle =
                 ActivityOptionsCompat.makeCustomAnimation(context, R.anim.activity_open_enter, 0)
                         .toBundle();
         context.startActivity(searchIntent, optionsBundle);
@@ -130,20 +133,29 @@
     @Override
     public void onUpdate(Context context, AppWidgetManager manager, int[] ids) {
         performUpdate(context, ids);
-        super.onUpdate(context, manager, ids);
     }
 
-    private void performUpdate(Context context) {
+    private static void performUpdate(Context context) {
         AppWidgetManager manager = AppWidgetManager.getInstance(context);
         performUpdate(context, getAllSearchWidgetIds(manager));
     }
 
-    private void performUpdate(Context context, int[] ids) {
-        for (int id : ids) updateWidget(context, id);
+    private static void performUpdate(Context context, int[] ids) {
+        if (ids.length == 0) return;
+
+        AppWidgetManager manager = AppWidgetManager.getInstance(context);
+        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
+        boolean isVoiceSearchAvailable = prefs.getBoolean(PREF_IS_VOICE_SEARCH_AVAILABLE, true);
+        String engineName = prefs.getString(PREF_SEARCH_ENGINE_SHORTNAME, null);
+
+        for (int id : ids) {
+            RemoteViews views = createWidgetViews(context, id, engineName, isVoiceSearchAvailable);
+            manager.updateAppWidget(id, views);
+        }
     }
 
-    private void updateWidget(Context context, int id) {
-        AppWidgetManager manager = AppWidgetManager.getInstance(context);
+    private static RemoteViews createWidgetViews(
+            Context context, int id, String engineName, boolean isVoiceSearchAvailable) {
         RemoteViews views =
                 new RemoteViews(context.getPackageName(), R.layout.search_widget_template);
 
@@ -154,74 +166,72 @@
                 PendingIntent.getBroadcast(
                         context, 0, textIntent, PendingIntent.FLAG_UPDATE_CURRENT));
 
-        Intent voiceIntent = createStartQueryIntent(context, ACTION_START_VOICE_QUERY, id);
-        views.setOnClickPendingIntent(R.id.microphone_icon,
-                PendingIntent.getBroadcast(
-                        context, 0, voiceIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+        // If voice search is available, clicking on the microphone triggers a voice query.
+        if (isVoiceSearchAvailable) {
+            Intent voiceIntent = createStartQueryIntent(context, ACTION_START_VOICE_QUERY, id);
+            views.setOnClickPendingIntent(R.id.microphone_icon,
+                    PendingIntent.getBroadcast(
+                            context, 0, voiceIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+            views.setViewVisibility(R.id.microphone_icon, View.VISIBLE);
+        } else {
+            views.setViewVisibility(R.id.microphone_icon, View.GONE);
+        }
 
         // Update what string is displayed by the widget.
-        String engineName = getCachedEngineName();
         String text = TextUtils.isEmpty(engineName)
                 ? context.getString(R.string.search_widget_default)
                 : context.getString(R.string.search_with_product, engineName);
         views.setTextViewText(R.id.title, text);
 
-        manager.updateAppWidget(id, views);
+        return views;
     }
 
-    /** Force all widgets to update their state. */
-    static void updateAllWidgets() {
-        Intent intent = new Intent(ACTION_UPDATE_ALL_WIDGETS);
-        intent.setPackage(ContextUtils.getApplicationContext().getPackageName());
-        ContextUtils.getApplicationContext().sendBroadcast(intent);
-    }
-
-    /** Updates the name of the user's default search engine that is cached in SharedPreferences. */
-    static void updateCachedEngineName() {
-        assert LibraryLoader.isInitialized();
-
-        // Getting an instance of the TemplateUrlService requires that the native library be
-        // loaded, but the TemplateUrlService itself needs to be initialized.
-        TemplateUrlService service = TemplateUrlService.getInstance();
-        if (!service.isLoaded()) return;
-
-        String engineName = service.getDefaultSearchEngineTemplateUrl().getShortName();
-        if (!TextUtils.equals(sCachedSearchEngineName, engineName)) {
-            sCachedSearchEngineName = engineName;
-
-            SharedPreferences.Editor editor = ContextUtils.getAppSharedPreferences().edit();
-            editor.putString(PREF_SEARCH_ENGINE_SHORTNAME, engineName);
-            editor.apply();
-
+    /** Caches whether or not a voice search is possible. */
+    static void updateCachedVoiceSearchAvailability(boolean isVoiceSearchAvailable) {
+        SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
+        if (prefs.getBoolean(PREF_IS_VOICE_SEARCH_AVAILABLE, true) != isVoiceSearchAvailable) {
+            prefs.edit().putBoolean(PREF_IS_VOICE_SEARCH_AVAILABLE, isVoiceSearchAvailable).apply();
             updateAllWidgets();
         }
     }
 
     /**
-     * Returns the cached name of the user's default search engine.  Caching it in SharedPreferences
-     * prevents us from having to load the native library and the TemplateUrlService.
-     *
-     * @return The cached name of the user's default search engine.
+     * Updates the name of the user's default search engine that is cached in SharedPreferences.
+     * Caching it in SharedPreferences prevents us from having to load the native library and the
+     * TemplateUrlService whenever the widget is updated.
      */
-    private static String getCachedEngineName() {
-        if (sCachedSearchEngineName != null) return sCachedSearchEngineName;
+    private static void updateCachedEngineName() {
+        assert LibraryLoader.isInitialized();
+
+        // Getting an instance of the TemplateUrlService requires that the native library be
+        // loaded, but the TemplateUrlService itself needs to be initialized.
+        TemplateUrlService service = TemplateUrlService.getInstance();
+        assert service.isLoaded();
+        String engineName = service.getDefaultSearchEngineTemplateUrl().getShortName();
 
         SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
-        sCachedSearchEngineName = prefs.getString(PREF_SEARCH_ENGINE_SHORTNAME, null);
-        return sCachedSearchEngineName;
+        if (!TextUtils.equals(prefs.getString(PREF_SEARCH_ENGINE_SHORTNAME, null), engineName)) {
+            prefs.edit().putString(PREF_SEARCH_ENGINE_SHORTNAME, engineName).apply();
+            updateAllWidgets();
+        }
     }
 
-    /** Get the IDs of all of Chrome's search widgets. */
+    /** Get the IDs of all existing search widgets. */
     private static int[] getAllSearchWidgetIds(AppWidgetManager manager) {
         return manager.getAppWidgetIds(new ComponentName(
                 ContextUtils.getApplicationContext(), SearchWidgetProvider.class.getName()));
     }
 
     /** Creates a trusted Intent that lets the user begin performing queries. */
-    private Intent createStartQueryIntent(Context context, String action, int widgetId) {
+    private static Intent createStartQueryIntent(Context context, String action, int widgetId) {
         Intent intent = new Intent(action, Uri.parse(String.valueOf(widgetId)));
-        intent.setClass(context, getClass());
+        intent.setClass(context, SearchWidgetProvider.class);
         IntentHandler.addTrustedIntentExtras(intent);
         return intent;
     }
+
+    /** Immediately updates all widgets. */
+    private static void updateAllWidgets() {
+        performUpdate(ContextUtils.getApplicationContext());
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
index 6bc3a53..73b52ad 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -2272,7 +2272,7 @@
                 TabSwitcherCallout.showIfNecessary(getContext(), mToggleTabStackButton);
         if (mTabSwitcherCallout == null) return;
 
-        mTabSwitcherCallout.setOnDismissListener(new OnDismissListener() {
+        mTabSwitcherCallout.addOnDismissListener(new OnDismissListener() {
             @Override
             public void onDismiss() {
                 if (mControlsVisibilityDelegate != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index 6feb3f6d..57117f0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -5,10 +5,12 @@
 package org.chromium.chrome.browser.vr_shell;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.PendingIntent;
-import android.content.ComponentName;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.net.Uri;
@@ -36,14 +38,16 @@
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
-import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.webapps.WebappActivity;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 
@@ -57,30 +61,32 @@
     // Pseudo-random number to avoid request id collisions.
     public static final int EXIT_VR_RESULT = 721251;
 
-    public static final int ENTER_VR_NOT_NECESSARY = 0;
-    public static final int ENTER_VR_CANCELLED = 1;
-    public static final int ENTER_VR_REQUESTED = 2;
-    public static final int ENTER_VR_SUCCEEDED = 3;
+    private static final int ENTER_VR_NOT_NECESSARY = 0;
+    private static final int ENTER_VR_CANCELLED = 1;
+    private static final int ENTER_VR_REQUESTED = 2;
+    private static final int ENTER_VR_SUCCEEDED = 3;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({ENTER_VR_NOT_NECESSARY, ENTER_VR_CANCELLED, ENTER_VR_REQUESTED, ENTER_VR_SUCCEEDED})
-    public @interface EnterVRResult {}
+    private @interface EnterVRResult {}
 
-    public static final int VR_NOT_AVAILABLE = 0;
-    public static final int VR_CARDBOARD = 1;
-    public static final int VR_DAYDREAM = 2; // Supports both Cardboard and Daydream viewer.
+    private static final int VR_NOT_AVAILABLE = 0;
+    private static final int VR_CARDBOARD = 1;
+    private static final int VR_DAYDREAM = 2; // Supports both Cardboard and Daydream viewer.
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({VR_NOT_AVAILABLE, VR_CARDBOARD, VR_DAYDREAM})
-    public @interface VrSupportLevel {}
+    private @interface VrSupportLevel {}
 
     // TODO(bshe): These should be replaced by string provided by NDK. Currently, it only available
     // in SDK and we don't want add dependency to SDK just to get these strings.
     private static final String DAYDREAM_CATEGORY = "com.google.intent.category.DAYDREAM";
     private static final String CARDBOARD_CATEGORY = "com.google.intent.category.CARDBOARD";
 
-    private static final String VR_ACTIVITY_ALIAS =
-            "org.chromium.chrome.browser.VRChromeTabbedActivity";
+    // Linter and formatter disagree on how the line below should be formatted.
+    /* package */
+    static final String VR_ENTRY_RESULT_ACTION =
+            "org.chromium.chrome.browser.vr_shell.VrEntryResult";
 
     private static final long REENTER_VR_TIMEOUT_MS = 1000;
 
@@ -93,6 +99,7 @@
             "market://details?id=" + VrCoreVersionChecker.VR_CORE_PACKAGE_ID;
 
     private static VrShellDelegate sInstance;
+    private static VrBroadcastReceiver sVrBroadcastReceiver;
 
     private ChromeActivity mActivity;
 
@@ -107,16 +114,46 @@
     private TabModelSelector mTabModelSelector;
 
     private boolean mInVr;
-    private boolean mEnteringVr;
+
+    // Whether or not the VR Device ON flow succeeded. If this is true it means the user has a VR
+    // headset on, but we haven't switched into VR mode yet.
+    // See further documentation here: https://developers.google.com/vr/daydream/guides/vr-entry
+    private boolean mDonSucceeded;
     private boolean mPaused;
     private int mRestoreSystemUiVisibilityFlag = -1;
     private Integer mRestoreOrientation = null;
     private long mNativeVrShellDelegate;
-    private boolean mRequestedWebVR;
-    private long mLastVRExit;
+    private boolean mRequestedWebVr;
+    private long mLastVrExit;
     private boolean mListeningForWebVrActivate;
     private boolean mListeningForWebVrActivateBeforePause;
 
+    private static class VrBroadcastReceiver extends BroadcastReceiver {
+        private final WeakReference<ChromeActivity> mTargetActivity;
+
+        public VrBroadcastReceiver(ChromeActivity activity) {
+            mTargetActivity = new WeakReference<ChromeActivity>(activity);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            ChromeActivity activity = mTargetActivity.get();
+            if (activity == null) return;
+            getInstance(activity).mDonSucceeded = true;
+            ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE))
+                    .moveTaskToFront(activity.getTaskId(), 0);
+        }
+
+        /**
+         * Unregisters this {@link BroadcastReceiver} from the activity it's registered to.
+         */
+        public void unregister() {
+            ChromeActivity activity = mTargetActivity.get();
+            if (activity == null) return;
+            activity.unregisterReceiver(VrBroadcastReceiver.this);
+        }
+    }
+
     /**
      * Called when the native library is first available.
      */
@@ -136,7 +173,7 @@
     /**
      * Whether or not we are currently in VR.
      */
-    public static boolean isInVR() {
+    public static boolean isInVr() {
         if (sInstance == null) return false;
         return sInstance.mInVr;
     }
@@ -153,27 +190,16 @@
     /**
      * Enters VR on the current tab if possible.
      */
-    public static void enterVRIfNecessary() {
+    public static void enterVrIfNecessary() {
         boolean created_delegate = sInstance == null;
         VrShellDelegate instance = getInstance();
         if (instance == null) return;
-        if (instance.enterVRInternal() == ENTER_VR_CANCELLED && created_delegate) {
+        if (instance.enterVrInternal() == ENTER_VR_CANCELLED && created_delegate) {
             instance.destroy();
         }
     }
 
     /**
-     * Handles a VR intent, entering VR in the process.
-     */
-    public static void enterVRFromIntent(Intent intent) {
-        assert isDaydreamVrIntent(intent);
-        boolean created_delegate = sInstance == null;
-        VrShellDelegate instance = getInstance();
-        if (instance == null) return;
-        if (!instance.enterVRFromIntent() && created_delegate) instance.destroy();
-    }
-
-    /**
      * Whether or not the intent is a Daydream VR Intent.
      */
     public static boolean isDaydreamVrIntent(Intent intent) {
@@ -184,9 +210,9 @@
     /**
      * Handles the result of the exit VR flow (DOFF).
      */
-    public static void onExitVRResult(int resultCode) {
+    public static void onExitVrResult(int resultCode) {
         if (sInstance == null) return;
-        sInstance.onExitVRResult(resultCode == Activity.RESULT_OK);
+        sInstance.onExitVrResult(resultCode == Activity.RESULT_OK);
     }
 
     /**
@@ -208,10 +234,10 @@
      * If VR Shell is enabled, and the activity is supported, register with the Daydream
      * platform that this app would like to be launched in VR when the device enters VR.
      */
-    public static void maybeRegisterVREntryHook(Activity activity) {
+    public static void maybeRegisterVrEntryHook(ChromeActivity activity) {
         if (sInstance != null) return; // Will be handled in onResume.
-        if (!(activity instanceof ChromeTabbedActivity)) return;
-        VrClassesWrapper wrapper = createVrClassesWrapper();
+        if (!activitySupportsVrBrowsing(activity)) return;
+        VrClassesWrapper wrapper = getVrClassesWrapper();
         if (wrapper == null) return;
         VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
         if (api == null) return;
@@ -223,10 +249,10 @@
      * When the app is pausing we need to unregister with the Daydream platform to prevent this app
      * from being launched from the background when the device enters VR.
      */
-    public static void maybeUnregisterVREntryHook(Activity activity) {
+    public static void maybeUnregisterVrEntryHook(ChromeActivity activity) {
         if (sInstance != null) return; // Will be handled in onPause.
-        if (!(activity instanceof ChromeTabbedActivity)) return;
-        VrClassesWrapper wrapper = createVrClassesWrapper();
+        if (!activitySupportsVrBrowsing(activity)) return;
+        VrClassesWrapper wrapper = getVrClassesWrapper();
         if (wrapper == null) return;
         VrDaydreamApi api = wrapper.createVrDaydreamApi(activity);
         if (api == null) return;
@@ -235,21 +261,28 @@
 
     @CalledByNative
     private static VrShellDelegate getInstance() {
-        return getInstance(ApplicationStatus.getLastTrackedFocusedActivity());
+        Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
+        if (!(activity instanceof ChromeActivity)) return null;
+        return getInstance((ChromeActivity) activity);
     }
 
-    private static VrShellDelegate getInstance(Activity activity) {
+    private static VrShellDelegate getInstance(ChromeActivity activity) {
         if (!LibraryLoader.isInitialized()) return null;
-        if (activity == null || !isSupportedActivity(activity)) return null;
+        if (activity == null || !activitySupportsPresentation(activity)) return null;
         if (sInstance != null) return sInstance;
         VrClassesWrapper wrapper = getVrClassesWrapper();
         if (wrapper == null) return null;
-        sInstance = new VrShellDelegate((ChromeActivity) activity, wrapper);
+        sInstance = new VrShellDelegate(activity, wrapper);
 
         return sInstance;
     }
 
-    private static boolean isSupportedActivity(Activity activity) {
+    private static boolean activitySupportsPresentation(Activity activity) {
+        return activity instanceof ChromeTabbedActivity || activity instanceof CustomTabActivity
+                || activity instanceof WebappActivity;
+    }
+
+    private static boolean activitySupportsVrBrowsing(Activity activity) {
         return activity instanceof ChromeTabbedActivity;
     }
 
@@ -279,25 +312,29 @@
         }
     }
 
-    private static PendingIntent getEnterVRPendingIntent(
-            VrDaydreamApi dayreamApi, Activity activity) {
-        return PendingIntent.getActivity(activity, 0,
-                dayreamApi.createVrIntent(new ComponentName(activity, VR_ACTIVITY_ALIAS)),
-                PendingIntent.FLAG_ONE_SHOT);
+    private static PendingIntent getEnterVrPendingIntent(ChromeActivity activity) {
+        Intent vrIntent = new Intent(VR_ENTRY_RESULT_ACTION);
+        return PendingIntent.getBroadcast(activity, 0, vrIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
     }
 
     /**
      * Registers the Intent to fire after phone inserted into a headset.
      */
-    private static void registerDaydreamIntent(VrDaydreamApi dayreamApi, Activity activity) {
-        dayreamApi.registerDaydreamIntent(getEnterVRPendingIntent(dayreamApi, activity));
+    private static void registerDaydreamIntent(
+            final VrDaydreamApi daydreamApi, final ChromeActivity activity) {
+        if (sVrBroadcastReceiver != null) sVrBroadcastReceiver.unregister();
+        IntentFilter filter = new IntentFilter(VR_ENTRY_RESULT_ACTION);
+        sVrBroadcastReceiver = new VrBroadcastReceiver(activity);
+        activity.registerReceiver(sVrBroadcastReceiver, filter);
+        daydreamApi.registerDaydreamIntent(getEnterVrPendingIntent(activity));
     }
 
     /**
      * Unregisters the Intent which registered by this context if any.
      */
-    private static void unregisterDaydreamIntent(VrDaydreamApi dayreamApi) {
-        dayreamApi.unregisterDaydreamIntent();
+    private static void unregisterDaydreamIntent(VrDaydreamApi daydreamApi) {
+        daydreamApi.unregisterDaydreamIntent();
     }
 
     /**
@@ -337,13 +374,13 @@
                 if (activity == mActivity) destroy();
                 break;
             case ActivityState.PAUSED:
-                if (activity == mActivity) pauseVR();
+                if (activity == mActivity) pauseVr();
                 break;
             case ActivityState.RESUMED:
                 assert !mInVr;
-                if (!isSupportedActivity(activity)) return;
+                if (!activitySupportsPresentation(activity)) return;
                 mActivity = (ChromeActivity) activity;
-                resumeVR();
+                resumeVr();
                 break;
             default:
                 break;
@@ -370,46 +407,41 @@
                 mVrDaydreamApi, mVrCoreVersionChecker, mActivity.getActivityTab());
     }
 
-    /**
-     * Handle a VR intent, entering VR in the process unless we're unable to.
-     */
-    private boolean enterVRFromIntent() {
-        // Vr Intent is only used on Daydream devices.
-        if (mVrSupportLevel != VR_DAYDREAM) return false;
-        if (mNativeVrShellDelegate == 0) return false;
-        if (mListeningForWebVrActivateBeforePause && !mRequestedWebVR) {
-            nativeDisplayActivate(mNativeVrShellDelegate);
-            return false;
+    private void maybeSetPresentResult(boolean result) {
+        if (mNativeVrShellDelegate != 0 && mRequestedWebVr) {
+            nativeSetPresentResult(mNativeVrShellDelegate, result);
         }
+        mRequestedWebVr = false;
+    }
+
+    /**
+     * Handle a successful VR DON flow, entering VR in the process unless we're unable to.
+     * @return False if VR entry failed.
+     */
+    private boolean enterVrAfterDon() {
+        if (mNativeVrShellDelegate == 0) return false;
+        if (mListeningForWebVrActivateBeforePause && !mRequestedWebVr) {
+            nativeDisplayActivate(mNativeVrShellDelegate);
+            return true;
+        }
+
         // Normally, if the active page doesn't have a vrdisplayactivate listener, and WebVR was not
-        // presenting and VrShell was not enabled, we shouldn't enter VR and Daydream Homescreen
-        // should show after DON flow. But due to a failure in unregisterDaydreamIntent, we still
-        // try to enterVR. Here we detect this case and force switch to Daydream Homescreen.
-        if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVR
-                && !isVrShellEnabled(mVrSupportLevel)) {
-            mVrDaydreamApi.launchVrHomescreen();
+        // presenting and VrShell was not enabled, the Daydream Homescreen should show after the DON
+        // flow. However, due to a failure in unregisterDaydreamIntent, we still try to enterVR, so
+        // detect this case and fail to enter VR.
+        if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVr
+                && !canEnterVr(mActivity.getActivityTab())) {
             return false;
         }
 
-        if (mInVr) {
-            setEnterVRResult(true);
-            return false;
-        }
-        if (!canEnterVR(mActivity.getActivityTab())) {
-            setEnterVRResult(false);
-            return false;
-        }
-        if (mPaused) {
-            // We can't enter VR before the application resumes, or we encounter bizarre crashes
-            // related to gpu surfaces. Set this flag to enter VR on the next resume.
-            mEnteringVr = true;
-        } else {
-            enterVR();
-        }
+        enterVr();
         return true;
     }
 
-    private void enterVR() {
+    private void enterVr() {
+        // We can't enter VR before the application resumes, or we encounter bizarre crashes
+        // related to gpu surfaces.
+        assert !mPaused;
         if (mNativeVrShellDelegate == 0) return;
         if (mInVr) return;
         if (!isWindowModeCorrectForVr()) {
@@ -417,15 +449,14 @@
             new Handler().post(new Runnable() {
                 @Override
                 public void run() {
-                    enterVR();
+                    enterVr();
                 }
             });
             return;
         }
-        mEnteringVr = false;
         if (!createVrShell()) {
-            restoreWindowMode();
-            setEnterVRResult(false);
+            maybeSetPresentResult(false);
+            mVrDaydreamApi.launchVrHomescreen();
             return;
         }
         mVrClassesWrapper.setVrModeEnabled(mActivity, true);
@@ -434,14 +465,14 @@
         mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
 
         addVrViews();
-        mVrShell.initializeNative(mActivity.getActivityTab(), mRequestedWebVR);
-        mVrShell.setWebVrModeEnabled(mRequestedWebVR);
+        mVrShell.initializeNative(mActivity.getActivityTab(), mRequestedWebVr);
+        mVrShell.setWebVrModeEnabled(mRequestedWebVr);
 
         // onResume needs to be called on GvrLayout after initialization to make sure DON flow work
         // properly.
         mVrShell.resume();
 
-        setEnterVRResult(true);
+        maybeSetPresentResult(true);
         mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this);
     }
 
@@ -472,24 +503,14 @@
         clearVrModeWindowFlags();
     }
 
-    private void setEnterVRResult(boolean success) {
-        if (mRequestedWebVR && mNativeVrShellDelegate != 0) {
-            nativeSetPresentResult(mNativeVrShellDelegate, success);
-        }
-        if (!success && !mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) {
-            mVrClassesWrapper.setVrModeEnabled(mActivity, false);
-        }
-        mRequestedWebVR = false;
-    }
-
-    /* package */ boolean canEnterVR(Tab tab) {
+    /* package */ boolean canEnterVr(Tab tab) {
         if (!LibraryLoader.isInitialized()) {
             return false;
         }
         if (mVrSupportLevel == VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0) return false;
         // If vr shell is not enabled and this is not a web vr request, then return false.
         if (!isVrShellEnabled(mVrSupportLevel)
-                && !(mRequestedWebVR || mListeningForWebVrActivate)) {
+                && !(mRequestedWebVr || mListeningForWebVrActivate)) {
             return false;
         }
         // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be
@@ -501,40 +522,24 @@
         if (tab.isShowingSadTab()) {
             return false;
         }
-        // crbug.com/667781
-        if (MultiWindowUtils.getInstance().isInMultiWindowMode(mActivity)) {
-            return false;
-        }
         return true;
     }
 
     @CalledByNative
     private void presentRequested() {
-        // TODO(mthiesse): There's a GVR bug where they're not calling us back with the intent we
-        // ask them to when we call DaydreamApi#launchInVr. As a temporary hack, remember locally
-        // that we want to enter webVR.
-        mRequestedWebVR = true;
-        switch (enterVRInternal()) {
+        mRequestedWebVr = true;
+        switch (enterVrInternal()) {
             case ENTER_VR_NOT_NECESSARY:
                 mVrShell.setWebVrModeEnabled(true);
-                if (mNativeVrShellDelegate != 0) {
-                    nativeSetPresentResult(mNativeVrShellDelegate, true);
-                }
-                mRequestedWebVR = false;
+                maybeSetPresentResult(true);
                 break;
             case ENTER_VR_CANCELLED:
-                if (mNativeVrShellDelegate != 0) {
-                    nativeSetPresentResult(mNativeVrShellDelegate, false);
-                }
-                mRequestedWebVR = false;
+                maybeSetPresentResult(false);
                 break;
             case ENTER_VR_REQUESTED:
                 break;
             case ENTER_VR_SUCCEEDED:
-                if (mNativeVrShellDelegate != 0) {
-                    nativeSetPresentResult(mNativeVrShellDelegate, true);
-                }
-                mRequestedWebVR = false;
+                maybeSetPresentResult(true);
                 break;
             default:
                 Log.e(TAG, "Unexpected enum.");
@@ -545,23 +550,23 @@
      * Enters VR Shell if necessary, displaying browser UI and tab contents in VR.
      */
     @EnterVRResult
-    private int enterVRInternal() {
+    private int enterVrInternal() {
         // Update VR support level as it can change at runtime
         updateVrSupportLevel();
         if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
         if (mInVr) return ENTER_VR_NOT_NECESSARY;
-        if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
+        if (!canEnterVr(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
 
         if (mVrSupportLevel == VR_CARDBOARD || !mVrDaydreamApi.isDaydreamCurrentViewer()) {
             // Avoid using launchInVr which would trigger DON flow regardless current viewer type
             // due to the lack of support for unexported activities.
-            enterVR();
+            enterVr();
         } else {
             // LANDSCAPE orientation is needed before we can safely enter VR. DON can make sure that
             // the device is at LANDSCAPE orientation once it is finished. So here we use SENSOR to
             // avoid forcing LANDSCAPE orientation in order to have a smoother transition.
             setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
-            if (!mVrDaydreamApi.launchInVr(getEnterVRPendingIntent(mVrDaydreamApi, mActivity))) {
+            if (!mVrDaydreamApi.launchInVr(getEnterVrPendingIntent(mActivity))) {
                 restoreWindowMode();
                 return ENTER_VR_CANCELLED;
             }
@@ -574,28 +579,17 @@
         if (!mInVr) return false;
         mVrShell.setWebVrModeEnabled(false);
         if (!isVrShellEnabled(mVrSupportLevel)) {
-            shutdownVR(false /* isPausing */, true /* showTransition */);
+            shutdownVr(false /* isPausing */, true /* showTransition */);
         }
         return true;
     }
 
-    private void resumeVR() {
+    private void resumeVr() {
         mPaused = false;
-        if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
-        if (mVrSupportLevel == VR_DAYDREAM
-                && (isVrShellEnabled(mVrSupportLevel) || mListeningForWebVrActivateBeforePause)) {
-            registerDaydreamIntent(mVrDaydreamApi, mActivity);
-        }
 
-        if (mEnteringVr) {
-            enterVR();
-        } else if (mRequestedWebVR) {
-            // If this is still set, it means the user backed out of the DON flow, and we won't be
-            // receiving an intent from daydream.
-            if (mNativeVrShellDelegate != 0) nativeSetPresentResult(mNativeVrShellDelegate, false);
-            restoreWindowMode();
-            mRequestedWebVR = false;
-        }
+        // TODO(mthiesse): If we ever support staying in VR while paused, make sure to call resume
+        // on VrShell.
+        assert !mInVr;
 
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
         try {
@@ -604,23 +598,32 @@
             StrictMode.setThreadPolicy(oldPolicy);
         }
 
-        if (mInVr) {
-            setupVrModeWindowFlags();
-            oldPolicy = StrictMode.allowThreadDiskWrites();
-            try {
-                mVrShell.resume();
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "Unable to resume VrShell", e);
-            } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
+        if (mVrSupportLevel != VR_DAYDREAM) return;
+        if (mListeningForWebVrActivateBeforePause
+                || (isVrShellEnabled(mVrSupportLevel) && activitySupportsVrBrowsing(mActivity))) {
+            registerDaydreamIntent(mVrDaydreamApi, mActivity);
+        }
+
+        if (mVrDaydreamApi.isDaydreamCurrentViewer()
+                && mLastVrExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMillis()) {
+            mDonSucceeded = true;
+        }
+
+        if (mDonSucceeded) {
+            mDonSucceeded = false;
+            // If we fail to enter VR when we should have entered VR, return to the home screen.
+            if (!enterVrAfterDon()) {
+                maybeSetPresentResult(false);
+                mVrDaydreamApi.launchVrHomescreen();
             }
-        } else if (mVrSupportLevel == VR_DAYDREAM && mVrDaydreamApi.isDaydreamCurrentViewer()
-                && mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMillis()) {
-            enterVRInternal();
+        } else if (mRestoreOrientation != null) {
+            // This means the user backed out of the DON flow, and we won't be entering VR.
+            maybeSetPresentResult(false);
+            restoreWindowMode();
         }
     }
 
-    private void pauseVR() {
+    private void pauseVr() {
         mPaused = true;
         if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
 
@@ -641,17 +644,17 @@
         // TODO(mthiesse): When VR Shell lives in its own activity, and integrates with Daydream
         // home, pause instead of exiting VR here. For now, because VR Apps shouldn't show up in the
         // non-VR recents, and we don't want ChromeTabbedActivity disappearing, exit VR.
-        shutdownVR(true /* isPausing */, false /* showTransition */);
+        shutdownVr(true /* isPausing */, false /* showTransition */);
     }
 
     private boolean onBackPressedInternal() {
         if (mVrSupportLevel == VR_NOT_AVAILABLE) return false;
         if (!mInVr) return false;
-        shutdownVR(false /* isPausing */, false /* showTransition */);
+        shutdownVr(false /* isPausing */, false /* showTransition */);
         return true;
     }
 
-    private void onExitVRResult(boolean success) {
+    private void onExitVrResult(boolean success) {
         assert mVrSupportLevel != VR_NOT_AVAILABLE;
         // For now, we don't handle re-entering VR when exit fails, so keep trying to exit.
         if (!success && mVrDaydreamApi.exitFromVr(EXIT_VR_RESULT, new Intent())) return;
@@ -692,10 +695,10 @@
     /**
      * Exits VR Shell, performing all necessary cleanup.
      */
-    /* package */ void shutdownVR(boolean isPausing, boolean showTransition) {
+    /* package */ void shutdownVr(boolean isPausing, boolean showTransition) {
         if (!mInVr) return;
         mInVr = false;
-        mRequestedWebVR = false;
+        mRequestedWebVr = false;
         // Transition screen is not available for Cardboard only (non-Daydream) devices.
         // TODO(bshe): Fix this once b/33490788 is fixed.
         boolean transition = mVrSupportLevel == VR_DAYDREAM && showTransition;
@@ -705,7 +708,7 @@
             }
         } else {
             mVrClassesWrapper.setVrModeEnabled(mActivity, false);
-            mLastVRExit = SystemClock.uptimeMillis();
+            mLastVrExit = SystemClock.uptimeMillis();
         }
         restoreWindowMode();
         mVrShell.pause();
@@ -765,7 +768,7 @@
         assert mVrShell == null;
         if (mVrClassesWrapper == null) return false;
         if (mActivity.getCompositorViewHolder() == null) return false;
-        mTabModelSelector = mActivity.getCompositorViewHolder().detachForVR();
+        mTabModelSelector = mActivity.getCompositorViewHolder().detachForVr();
         if (mTabModelSelector == null) return false;
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
         try {
@@ -782,11 +785,11 @@
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT);
         decor.addView(mVrShell.getContainer(), params);
-        mActivity.onEnterVR();
+        mActivity.onEnterVr();
     }
 
     private void removeVrViews() {
-        mActivity.onExitVR();
+        mActivity.onExitVr();
         FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
         decor.removeView(mVrShell.getContainer());
     }
@@ -817,7 +820,7 @@
             mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(null);
             mVrShell.teardown();
             mVrShell = null;
-            mActivity.getCompositorViewHolder().onExitVR(mTabModelSelector);
+            mActivity.getCompositorViewHolder().onExitVr(mTabModelSelector);
             mTabModelSelector = null;
         }
     }
@@ -856,7 +859,7 @@
 
     private void destroy() {
         if (sInstance == null) return;
-        shutdownVR(true, false);
+        shutdownVr(true, false);
         if (mNativeVrShellDelegate != 0) nativeDestroy(mNativeVrShellDelegate);
         mNativeVrShellDelegate = 0;
         ApplicationStatus.unregisterActivityStateListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index f5650c3f..d5ba53c3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -21,18 +21,14 @@
 import com.google.vr.ndk.base.GvrLayout;
 
 import org.chromium.base.CommandLine;
-import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.ChromeVersionInfo;
 import org.chromium.chrome.browser.NativePage;
 import org.chromium.chrome.browser.UrlConstants;
-import org.chromium.chrome.browser.WebContentsFactory;
-import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
@@ -44,15 +40,12 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
-import org.chromium.content.browser.ContentView;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.MotionEventSynthesizer;
 import org.chromium.content.browser.WindowAndroidChangedObserver;
 import org.chromium.content.browser.WindowAndroidProvider;
-import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.UiUtils;
-import org.chromium.ui.base.ViewAndroidDelegate;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.display.DisplayAndroid;
 import org.chromium.ui.display.VirtualDisplayAndroid;
@@ -84,7 +77,6 @@
     private final ChromeActivity mActivity;
     private final VrShellDelegate mDelegate;
     private final VirtualDisplayAndroid mContentVirtualDisplay;
-    private final VirtualDisplayAndroid mUiVirtualDisplay;
     private final TabRedirectHandler mTabRedirectHandler;
     private final TabObserver mTabObserver;
     private final TabModelSelectorObserver mTabModelSelectorObserver;
@@ -93,7 +85,6 @@
 
     private long mNativeVrShell;
 
-    private FrameLayout mUiCVCContainer;
     private FrameLayout mRenderToSurfaceLayout;
     private Surface mSurface;
     private View mPresentationView;
@@ -106,10 +97,6 @@
     private WindowAndroid mOriginalWindowAndroid;
     private VrWindowAndroid mContentVrWindowAndroid;
 
-    private WebContents mUiContents;
-    private ContentViewCore mUiCVC;
-    private VrWindowAndroid mUiVrWindowAndroid;
-
     private boolean mReprojectedRendering;
 
     private TabRedirectHandler mNonVrTabRedirectHandler;
@@ -128,13 +115,6 @@
         mActivity = activity;
         mDelegate = delegate;
         mTabModelSelector = tabModelSelector;
-        mUiCVCContainer = new FrameLayout(getContext()) {
-            @Override
-            public boolean dispatchTouchEvent(MotionEvent event) {
-                return true;
-            }
-        };
-        addView(mUiCVCContainer, 0, new FrameLayout.LayoutParams(0, 0));
 
         mReprojectedRendering = setAsyncReprojectionEnabled(true);
         if (mReprojectedRendering) {
@@ -156,15 +136,13 @@
         getUiLayout().setCloseButtonListener(new Runnable() {
             @Override
             public void run() {
-                mDelegate.shutdownVR(false /* isPausing */, false /* showTransition */);
+                mDelegate.shutdownVr(false /* isPausing */, false /* showTransition */);
             }
         });
 
         DisplayAndroid primaryDisplay = DisplayAndroid.getNonMultiDisplay(activity);
         mContentVirtualDisplay = VirtualDisplayAndroid.createVirtualDisplay();
         mContentVirtualDisplay.setTo(primaryDisplay);
-        mUiVirtualDisplay = VirtualDisplayAndroid.createVirtualDisplay();
-        mUiVirtualDisplay.setTo(primaryDisplay);
 
         mTabRedirectHandler = new TabRedirectHandler(mActivity) {
             @Override
@@ -295,19 +273,10 @@
     public void initializeNative(Tab currentTab, boolean forWebVR) {
         mContentVrWindowAndroid = new VrWindowAndroid(mActivity, mContentVirtualDisplay);
 
-        mUiVrWindowAndroid = new VrWindowAndroid(mActivity, mUiVirtualDisplay);
-        mUiContents = WebContentsFactory.createWebContents(true, false);
-        mUiCVC = new ContentViewCore(mActivity, ChromeVersionInfo.getProductVersion());
-        ContentView uiContentView = ContentView.createContentView(mActivity, mUiCVC);
-        mUiCVC.initialize(ViewAndroidDelegate.createBasicDelegate(uiContentView),
-                uiContentView, mUiContents, mUiVrWindowAndroid);
-
-        mNativeVrShell = nativeInit(mUiContents, mContentVrWindowAndroid.getNativePointer(),
-                mUiVrWindowAndroid.getNativePointer(), forWebVR, mDelegate,
+        mNativeVrShell = nativeInit(mDelegate, mContentVrWindowAndroid.getNativePointer(), forWebVR,
                 getGvrApi().getNativeGvrContext(), mReprojectedRendering);
 
         // Set the UI and content sizes before we load the UI.
-        setUiCssSize(DEFAULT_UI_WIDTH, DEFAULT_UI_HEIGHT, DEFAULT_DPR);
         if (forWebVR) {
             DisplayAndroid primaryDisplay = DisplayAndroid.getNonMultiDisplay(mActivity);
             setContentCssSize(primaryDisplay.getPhysicalDisplayWidth(),
@@ -321,18 +290,7 @@
         mActivity.getTabModelSelector().addObserver(mTabModelSelectorObserver);
         createTabModelSelectorTabObserver();
 
-        nativeLoadUIContent(mNativeVrShell);
-
         mPresentationView.setOnTouchListener(mTouchListener);
-
-        uiContentView.setVisibility(View.VISIBLE);
-        mUiCVC.onShow();
-        mUiCVCContainer.addView(uiContentView, new FrameLayout.LayoutParams(
-                FrameLayout.LayoutParams.MATCH_PARENT,
-                FrameLayout.LayoutParams.MATCH_PARENT));
-        mUiCVC.setBottomControlsHeight(0);
-        mUiCVC.setTopControlsHeight(0, false);
-        mUiVrWindowAndroid.onVisibilityChanged(true);
     }
 
     private void createTabList() {
@@ -355,7 +313,7 @@
     private void swapToForegroundTab() {
         Tab tab = mActivity.getActivityTab();
         if (tab == mTab) return;
-        if (!mDelegate.canEnterVR(tab)) {
+        if (!mDelegate.canEnterVr(tab)) {
             forceExitVr();
             return;
         }
@@ -391,24 +349,7 @@
     // Exits VR, telling the user to remove their headset, and returning to Chromium.
     @CalledByNative
     public void forceExitVr() {
-        mDelegate.shutdownVR(false /* isPausing */, true /* showTransition */);
-    }
-
-    @CalledByNative
-    public void setUiCssSize(float width, float height, float dpr) {
-        ThreadUtils.assertOnUiThread();
-        if (dpr != DEFAULT_DPR) {
-            Log.w(TAG, "Changing UI DPR causes the UI to flicker and should generally not be "
-                    + "done.");
-        }
-        int surfaceWidth = (int) Math.ceil(width * dpr);
-        int surfaceHeight = (int) Math.ceil(height * dpr);
-
-        Point size = new Point(surfaceWidth, surfaceHeight);
-        mUiVirtualDisplay.update(size, size, dpr, null, null, null);
-        mUiCVC.onSizeChanged(surfaceWidth, surfaceHeight, 0, 0);
-        mUiCVC.onPhysicalBackingSizeChanged(surfaceWidth, surfaceHeight);
-        nativeUIPhysicalBoundsChanged(mNativeVrShell, surfaceWidth, surfaceHeight, dpr);
+        mDelegate.shutdownVr(false /* isPausing */, true /* showTransition */);
     }
 
     @CalledByNative
@@ -500,9 +441,7 @@
         mTabModelSelectorTabObserver.destroy();
         mTab.removeObserver(mTabObserver);
         restoreTabFromVR();
-        mUiContents.destroy();
         mContentVirtualDisplay.destroy();
-        mUiVirtualDisplay.destroy();
         super.shutdown();
     }
 
@@ -616,14 +555,6 @@
     }
 
     @CalledByNative
-    public void loadURL(String url, int transition) {
-        LoadUrlParams loadUrlParams = new LoadUrlParams(url);
-        loadUrlParams.setVerbatimHeaders(GeolocationHeader.getGeoHeader(url, mTab));
-        loadUrlParams.setTransitionType(transition);
-        mTab.loadUrl(loadUrlParams);
-    }
-
-    @CalledByNative
     public void reload() {
         mTab.reload();
     }
@@ -655,13 +586,11 @@
         mOnDispatchTouchEventForTesting = callback;
     }
 
-    private native long nativeInit(WebContents uiWebContents, long nativeContentWindowAndroid,
-            long nativeUiWindowAndroid, boolean forWebVR, VrShellDelegate delegate, long gvrApi,
-            boolean reprojectedRendering);
+    private native long nativeInit(VrShellDelegate delegate, long nativeWindowAndroid,
+            boolean forWebVR, long gvrApi, boolean reprojectedRendering);
     private native void nativeSetSurface(long nativeVrShell, Surface surface);
     private native void nativeSwapContents(
             long nativeVrShell, WebContents webContents, MotionEventSynthesizer eventSynthesizer);
-    private native void nativeLoadUIContent(long nativeVrShell);
     private native void nativeDestroy(long nativeVrShell);
     private native void nativeOnTriggerEvent(long nativeVrShell);
     private native void nativeOnPause(long nativeVrShell);
@@ -669,8 +598,6 @@
     private native void nativeOnLoadProgressChanged(long nativeVrShell, double progress);
     private native void nativeContentPhysicalBoundsChanged(long nativeVrShell, int width,
             int height, float dpr);
-    private native void nativeUIPhysicalBoundsChanged(long nativeVrShell, int width, int height,
-            float dpr);
     private native void nativeSetWebVrMode(long nativeVrShell, boolean enabled);
     private native void nativeOnTabListCreated(long nativeVrShell, Tab[] mainTabs,
             Tab[] incognitoTabs);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
index 77f01b87..d6e36d0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
@@ -6,12 +6,14 @@
 
 import android.os.StrictMode;
 
+import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.GooglePlayInstallState;
 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
 import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler;
@@ -30,7 +32,8 @@
     private static Boolean sEnabledForTesting;
 
     public static void init() {
-        WebApkValidator.initWithBrowserHostSignature(ChromeWebApkHostSignature.EXPECTED_SIGNATURE);
+        WebApkValidator.init(isAnyPackageNameEnabledInPrefs(),
+                ChromeWebApkHostSignature.EXPECTED_SIGNATURE, ChromeWebApkHostSignature.PUBLIC_KEY);
     }
 
     public static void initForTesting(boolean enabled) {
@@ -98,6 +101,21 @@
     }
 
     /**
+     * Check the cached value to figure out if any WebAPK package name may be used. We have to use
+     * the cached value because native library may not yet been loaded.
+     * @return Whether the feature is enabled.
+     */
+    private static boolean isAnyPackageNameEnabledInPrefs() {
+        // Will go away once the feature is enabled for everyone by default.
+        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+        try {
+            return ChromePreferenceManager.getInstance().getCachedWebApkAnyPackageName();
+        } finally {
+            StrictMode.setThreadPolicy(oldPolicy);
+        }
+    }
+
+    /**
      * Once native is loaded we can consult the command-line (set via about:flags) and also finch
      * state to see if we should enable WebAPKs.
      */
@@ -110,6 +128,15 @@
             Log.d(TAG, "WebApk setting changed (%s => %s)", wasEnabled, isEnabled);
             preferenceManager.setCachedWebApkRuntimeEnabled(isEnabled);
         }
+
+        boolean wasAnyPackageNameEnabled = isAnyPackageNameEnabledInPrefs();
+        boolean isAnyPackageNameEnabled =
+                CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_ANY_WEBAPK_PACKAGE_NAME);
+        if (wasAnyPackageNameEnabled != isAnyPackageNameEnabled) {
+            Log.d(TAG, "WebApk Any Package name setting changed (%s => %s)",
+                    wasAnyPackageNameEnabled, isAnyPackageNameEnabled);
+            preferenceManager.setCachedWebApkAnyPackageNameEnabled(isAnyPackageNameEnabled);
+        }
     }
 
     private static native boolean nativeCanLaunchRendererInWebApkProcess();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHostSignature.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHostSignature.java
index 8ccf454..ae97bd15 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHostSignature.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHostSignature.java
@@ -4,8 +4,8 @@
 
 package org.chromium.chrome.browser.webapps;
 
+/** Public key and signature for WebAPKs */
 public class ChromeWebApkHostSignature {
-
     // The public key to verify whether a WebAPK is signed by WebAPK Server.
     static final byte[] EXPECTED_SIGNATURE = new byte[] {48, -126, 4, 104, 48, -126, 2, -48, -96, 3,
             2, 1, 2, 2, 20, 120, 33, -22, -36, -115, 7, 116, 66, 116, 113, -122, -126, -124, 32, 44,
@@ -65,4 +65,11 @@
             -27, -68, 62, -81, 98, -54, -80, -23, 59, 38, -127, 96, 71, 123, 34, -113, -23, -80, 32,
             -97, -55, -100, 121, 120, 50, -48, 58, 69, -105, 26, 126, 30, -1, -112, -41, -18, -16,
             62, 48, -22, -2, 19, 117, -6, 59, 74, -13, 92, -1};
+
+    // The public key for comment signed WebAPK's. Elliptic Curve, NIST P-256 in ASN.1 format.
+    static final byte[] PUBLIC_KEY = new byte[] {48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1,
+            6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, -25, 45, 2, 49, 44, -60, 107, -108,
+            -45, 27, -40, -8, -116, 44, 7, -38, -103, 52, -81, 33, -90, -80, -94, 125, -3, -67, 51,
+            -125, -63, 6, -127, 89, 32, 53, 83, -120, -106, -113, -121, -39, 115, -50, 15, 117, 66,
+            78, -89, -124, -120, 4, -61, 8, -90, -67, -6, 71, -120, -120, 23, 23, 77, 75, 103, -28};
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ArrowBubbleDrawable.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ArrowBubbleDrawable.java
index 49f50d0..3bef424 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ArrowBubbleDrawable.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ArrowBubbleDrawable.java
@@ -22,7 +22,7 @@
 /**
  * A {@link Drawable} that is a bubble with an arrow pointing out of either the top or bottom.
  */
-class ArrowBubbleDrawable extends Drawable {
+class ArrowBubbleDrawable extends Drawable implements Drawable.Callback {
     private final Rect mCachedBubblePadding = new Rect();
 
     private final int mRadiusPx;
@@ -40,6 +40,9 @@
                         null, null));
         mArrowDrawable = (BitmapDrawable) ApiCompatibilityUtils.getDrawable(
                 context.getResources(), R.drawable.bubble_point_white);
+
+        mBubbleDrawable.setCallback(this);
+        mArrowDrawable.setCallback(this);
     }
 
     /**
@@ -72,6 +75,13 @@
     }
 
     /**
+     * @return Whether or not the arrow is currently drawing on top of this {@link Drawable}.
+     */
+    public boolean isArrowOnTop() {
+        return mArrowOnTop;
+    }
+
+    /**
      * @param color The color to make the bubble and arrow.
      */
     public void setBubbleColor(@ColorInt int color) {
@@ -80,6 +90,22 @@
         invalidateSelf();
     }
 
+    // Drawable.Callback implementation.
+    @Override
+    public void invalidateDrawable(Drawable who) {
+        invalidateSelf();
+    }
+
+    @Override
+    public void scheduleDrawable(Drawable who, Runnable what, long when) {
+        scheduleSelf(what, when);
+    }
+
+    @Override
+    public void unscheduleDrawable(Drawable who, Runnable what) {
+        unscheduleSelf(what);
+    }
+
     // Drawable implementation.
     @Override
     public void draw(Canvas canvas) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java
index d08608c..4fdbc1e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/TextBubble.java
@@ -21,6 +21,7 @@
 import android.widget.TextView;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.ObserverList;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.util.MathUtils;
 
@@ -29,7 +30,7 @@
  * calls to {@link #setAnchorRect(Rect)}.  This should be called at least once before the
  * {@link #show()} call.  To attach to a {@link View} see {@link ViewAnchoredTextBubble}.
  */
-public class TextBubble implements OnTouchListener, OnDismissListener {
+public class TextBubble implements OnTouchListener {
     /**
      * Specifies no limit to the popup duration.
      * @see #setAutoDismissTimeout(long)
@@ -63,6 +64,16 @@
         }
     };
 
+    private final OnDismissListener mDismissListener = new OnDismissListener() {
+        @Override
+        public void onDismiss() {
+            if (mIgnoreDismissal) return;
+
+            mHandler.removeCallbacks(mDismissRunnable);
+            for (OnDismissListener listener : mDismissListeners) listener.onDismiss();
+        }
+    };
+
     /**
      * How long to wait before automatically dismissing the bubble.  {@link #NO_TIMEOUT} is the
      * default and means the bubble will stay visible indefinitely.
@@ -72,7 +83,7 @@
 
     // Pass through for the internal PopupWindow.  This class needs to intercept these for API
     // purposes, but they are still useful to callers.
-    private OnDismissListener mDismissListener;
+    private ObserverList<OnDismissListener> mDismissListeners = new ObserverList<>();
     private OnTouchListener mTouchListener;
 
     // Positioning/sizing coordinates for the popup bubble.
@@ -81,6 +92,13 @@
     private int mWidth;
     private int mHeight;
 
+    /**
+     * Tracks whether or not we are in the process of updating the bubble, which might include a
+     * dismiss and show.  In that case we don't want to let the world know we're dismissing because
+     * it's only temporary.
+     */
+    private boolean mIgnoreDismissal;
+
     // Content specific variables.
     /** The resource id for the string to show in the bubble. */
     @StringRes
@@ -106,7 +124,7 @@
         mPopupWindow.setAnimationStyle(R.style.TextBubbleAnimation);
 
         mPopupWindow.setTouchInterceptor(this);
-        mPopupWindow.setOnDismissListener(this);
+        mPopupWindow.setOnDismissListener(mDismissListener);
 
         mMarginPx = context.getResources().getDimensionPixelSize(R.dimen.text_bubble_margin);
 
@@ -148,8 +166,16 @@
      * @param onDismissListener A listener to be called when the bubble is dismissed.
      * @see PopupWindow#setOnDismissListener(OnDismissListener)
      */
-    public void setOnDismissListener(OnDismissListener onDismissListener) {
-        mDismissListener = onDismissListener;
+    public void addOnDismissListener(OnDismissListener onDismissListener) {
+        mDismissListeners.addObserver(onDismissListener);
+    }
+
+    /**
+     * @param onDismissListener The listener to remove and not call when the bubble is dismissed.
+     * @see PopupWindow#setOnDismissListener(OnDismissListener)
+     */
+    public void removeOnDismissListener(OnDismissListener onDismissListener) {
+        mDismissListeners.removeObserver(onDismissListener);
     }
 
     /**
@@ -196,7 +222,11 @@
      */
     private void updateBubbleLayout() {
         // Determine the size of the text bubble.
-        mPopupWindow.getBackground().getPadding(mCachedPaddingRect);
+        ArrowBubbleDrawable background = (ArrowBubbleDrawable) mPopupWindow.getBackground();
+        boolean currentPositionBelow = background.isArrowOnTop();
+        boolean preferCurrentOrientation = mPopupWindow.isShowing();
+
+        background.getPadding(mCachedPaddingRect);
         int paddingX = mCachedPaddingRect.left + mCachedPaddingRect.right;
         int paddingY = mCachedPaddingRect.top + mCachedPaddingRect.bottom;
 
@@ -221,6 +251,13 @@
         // available.  This does bias the bubbles to show below the anchors if possible.
         boolean positionBelow =
                 idealHeight <= spaceBelowAnchor || spaceBelowAnchor >= spaceAboveAnchor;
+
+        // Override the ideal bubble orientation if we are trying to maintain the current one.
+        if (preferCurrentOrientation && currentPositionBelow != positionBelow) {
+            if (currentPositionBelow && idealHeight <= spaceBelowAnchor) positionBelow = true;
+            if (!currentPositionBelow && idealHeight <= spaceAboveAnchor) positionBelow = false;
+        }
+
         int maxContentHeight = positionBelow ? spaceBelowAnchor : spaceAboveAnchor;
         contentView.measure(
                 widthSpec, MeasureSpec.makeMeasureSpec(maxContentHeight, MeasureSpec.AT_MOST));
@@ -247,7 +284,20 @@
         // TODO(dtrainor): Figure out how to move the arrow and bubble to make things look better.
 
         mDrawable.setPositionProperties(arrowXOffset, positionBelow);
-        mPopupWindow.update(mX, mY, mWidth, mHeight);
+
+        if (positionBelow != currentPositionBelow) {
+            // This is a hack to deal with the case where the arrow flips between top and bottom.
+            // In this case the padding of the background drawable in the PopupWindow changes.
+            try {
+                mIgnoreDismissal = true;
+                mPopupWindow.dismiss();
+                mPopupWindow.showAtLocation(mRootView, Gravity.TOP | Gravity.START, mX, mY);
+            } finally {
+                mIgnoreDismissal = false;
+            }
+        } else {
+            mPopupWindow.update(mX, mY, mWidth, mHeight);
+        }
     }
 
     private void createContentView() {
@@ -265,11 +315,4 @@
         if (mDismissOnTouchInteraction) dismiss();
         return returnValue;
     }
-
-    // OnDismissListener implementation.
-    @Override
-    public void onDismiss() {
-        mHandler.removeCallbacks(mDismissRunnable);
-        if (mDismissListener != null) mDismissListener.onDismiss();
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ViewAnchoredTextBubble.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ViewAnchoredTextBubble.java
index 3a77d626..816acb3c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ViewAnchoredTextBubble.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/textbubble/ViewAnchoredTextBubble.java
@@ -8,20 +8,31 @@
 import android.graphics.Rect;
 import android.support.annotation.StringRes;
 import android.view.View;
-import android.view.View.OnLayoutChangeListener;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnPreDrawListener;
+import android.widget.PopupWindow.OnDismissListener;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.content.browser.PositionObserver;
+import org.chromium.content.browser.ViewPositionObserver;
 
 /**
  * A helper class that anchors a {@link TextBubble} to a particular {@link View}.  The bubble will
  * listen to layout events on the {@link View} and update accordingly.
  */
-public class ViewAnchoredTextBubble extends TextBubble implements OnLayoutChangeListener {
+public class ViewAnchoredTextBubble extends TextBubble
+        implements PositionObserver.Listener, ViewTreeObserver.OnGlobalLayoutListener,
+                   View.OnAttachStateChangeListener, OnPreDrawListener, OnDismissListener {
     private final int[] mCachedScreenCoordinates = new int[2];
     private final Rect mAnchorRect = new Rect();
     private final Rect mInsetRect = new Rect();
     private final View mAnchorView;
 
+    private final ViewPositionObserver mViewPositionObserver;
+
+    /** If not {@code null}, the {@link ViewTreeObserver} that we are registered to. */
+    private ViewTreeObserver mViewTreeObserver;
+
     /**
      * Creates an instance of a {@link ViewAnchoredTextBubble}.
      * @param context    Context to draw resources from.
@@ -31,6 +42,8 @@
     public ViewAnchoredTextBubble(Context context, View anchorView, @StringRes int stringId) {
         super(context, anchorView.getRootView(), stringId);
         mAnchorView = anchorView;
+
+        mViewPositionObserver = new ViewPositionObserver(mAnchorView);
     }
 
     /**
@@ -45,26 +58,53 @@
     // TextBubble implementation.
     @Override
     public void show() {
-        mAnchorView.addOnLayoutChangeListener(this);
+        mViewPositionObserver.addListener(this);
+        mAnchorView.addOnAttachStateChangeListener(this);
+        mViewTreeObserver = mAnchorView.getViewTreeObserver();
+        mViewTreeObserver.addOnGlobalLayoutListener(this);
+        mViewTreeObserver.addOnPreDrawListener(this);
+
         refreshAnchorBounds();
         super.show();
     }
 
     @Override
-    public void dismiss() {
-        super.dismiss();
-        mAnchorView.removeOnLayoutChangeListener(this);
+    public void onDismiss() {
+        mViewPositionObserver.removeListener(this);
+        mAnchorView.removeOnAttachStateChangeListener(this);
+
+        if (mViewTreeObserver != null && mViewTreeObserver.isAlive()) {
+            mViewTreeObserver.removeOnGlobalLayoutListener(this);
+            mViewTreeObserver.removeOnPreDrawListener(this);
+        }
+        mViewTreeObserver = null;
     }
 
-    // OnLayoutChangeListener implementation.
+    // ViewTreeObserver.OnGlobalLayoutListener implementation.
     @Override
-    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
-            int oldTop, int oldRight, int oldBottom) {
-        if (!mAnchorView.isShown()) {
-            dismiss();
-            return;
-        }
+    public void onGlobalLayout() {
+        if (!mAnchorView.isShown()) dismiss();
+    }
 
+    // ViewTreeObserver.OnPreDrawListener implementation.
+    @Override
+    public boolean onPreDraw() {
+        if (!mAnchorView.isShown()) dismiss();
+        return true;
+    }
+
+    // View.OnAttachStateChangedObserver implementation.
+    @Override
+    public void onViewAttachedToWindow(View v) {}
+
+    @Override
+    public void onViewDetachedFromWindow(View v) {
+        dismiss();
+    }
+
+    // PositionObserver.Listener implementation.
+    @Override
+    public void onPositionChanged(int positionX, int positionY) {
         refreshAnchorBounds();
     }
 
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index e174070..f113f6b 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1611,6 +1611,7 @@
 ]
 
 chrome_junit_test_java_sources = [
+  "junit/src/org/chromium/chrome/browser/AppIndexingUtilTest.java",
   "junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java",
   "junit/src/org/chromium/chrome/browser/ChromeBackgroundServiceWaiterTest.java",
   "junit/src/org/chromium/chrome/browser/DelayedScreenLockIntentHandlerTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
index 5f47ee9..300fad6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
@@ -10,8 +10,10 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.autofill.AutofillTestHelper;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
@@ -263,6 +265,47 @@
     }
 
     /**
+     * Expect that the SkippedShow metric is logged when the UI directly goes
+     * to the payment app UI during a Payment Request.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    public void testMetrics_SkippedShow()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        // Complete a Payment Request with Android Pay.
+        installPaymentApp("https://android.com/pay", HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE);
+        triggerUIAndWait("androidPaySkipUiBuy", mResultReady);
+
+        assertEquals(1,
+                RecordHistogram.getHistogramValueCountForTesting(
+                        "PaymentRequest.CheckoutFunnel.SkippedShow", 1));
+        assertEquals(0,
+                RecordHistogram.getHistogramValueCountForTesting(
+                        "PaymentRequest.CheckoutFunnel.Shown", 1));
+    }
+
+    /**
+     * Expect that the PaymentRequest UI is shown even if all the requirements are met to skip, if
+     * the skip feature is disabled.
+     */
+    @MediumTest
+    @Feature({"Payments"})
+    @CommandLineFlags.Add({"disable-features=" + ChromeFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP})
+    public void testMetrics_SkippedShow_Disabled()
+            throws InterruptedException, ExecutionException, TimeoutException {
+        // Complete a Payment Request with Android Pay.
+        installPaymentApp("https://android.com/pay", HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE);
+        triggerUIAndWait("androidPaySkipUiBuy", mReadyToPay);
+
+        assertEquals(1,
+                RecordHistogram.getHistogramValueCountForTesting(
+                        "PaymentRequest.CheckoutFunnel.Shown", 1));
+        assertEquals(0,
+                RecordHistogram.getHistogramValueCountForTesting(
+                        "PaymentRequest.CheckoutFunnel.SkippedShow", 1));
+    }
+
+    /**
      * Expect that the "Shown" event is recorded only once.
      */
     @MediumTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java
index 6c076b9..027b3ef 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/search_engines/TemplateUrlServiceTest.java
@@ -109,13 +109,6 @@
     @RetryOnFailure
     @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE) // see crbug.com/581268
     public void testLoadUrlService() {
-        Assert.assertFalse(ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                return TemplateUrlService.getInstance().isLoaded();
-            }
-        }));
-
         waitForTemplateUrlServiceToLoad();
 
         Assert.assertTrue(ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
@@ -124,6 +117,29 @@
                 return TemplateUrlService.getInstance().isLoaded();
             }
         }));
+
+        // Add another load listener and ensure that is notified without needing to call load()
+        // again.
+        final AtomicBoolean observerNotified = new AtomicBoolean(false);
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                TemplateUrlService service = TemplateUrlService.getInstance();
+                service.registerLoadListener(new LoadListener() {
+                    @Override
+                    public void onTemplateUrlServiceLoaded() {
+                        observerNotified.set(true);
+                    }
+                });
+            }
+        });
+        CriteriaHelper.pollInstrumentationThread(
+                new Criteria("Observer wasn't notified of TemplateUrlService load.") {
+                    @Override
+                    public boolean isSatisfied() {
+                        return observerNotified.get();
+                    }
+                });
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java
index 9f881de2..c95b75f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellTest.java
@@ -65,13 +65,13 @@
         VrUtils.forceEnterVr();
         if (supported) {
             VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS);
-            assertTrue(VrShellDelegate.isInVR());
+            assertTrue(VrShellDelegate.isInVr());
         } else {
             assertFalse(mockApi.getLaunchInVrCalled());
-            assertFalse(VrShellDelegate.isInVR());
+            assertFalse(VrShellDelegate.isInVr());
         }
         VrUtils.forceExitVr(mDelegate);
-        assertFalse(VrShellDelegate.isInVR());
+        assertFalse(VrShellDelegate.isInVr());
     }
 
     private void enterExitVrModeImage(boolean supported) throws IOException {
@@ -117,9 +117,9 @@
         VrUtils.simNfc(getActivity());
         if (supported) {
             VrUtils.waitForVrSupported(POLL_TIMEOUT_LONG_MS);
-            assertTrue(VrShellDelegate.isInVR());
+            assertTrue(VrShellDelegate.isInVr());
         } else {
-            assertFalse(VrShellDelegate.isInVR());
+            assertFalse(VrShellDelegate.isInVr());
         }
         VrUtils.forceExitVr(mDelegate);
         // TODO(bsheedy): Figure out why NFC tests cause the next test to fail
@@ -210,7 +210,7 @@
             public void run() {
                 CompositorViewHolder compositorViewHolder = (CompositorViewHolder)
                         getActivity().findViewById(R.id.compositor_view_holder);
-                selector.set(compositorViewHolder.detachForVR());
+                selector.set(compositorViewHolder.detachForVr());
                 oldWidth.set(cvc.getViewportWidthPix());
 
                 ViewGroup.LayoutParams layoutParams = compositorViewHolder.getLayoutParams();
@@ -236,7 +236,7 @@
             public void run() {
                 CompositorViewHolder compositorViewHolder = (CompositorViewHolder) getActivity()
                         .findViewById(R.id.compositor_view_holder);
-                compositorViewHolder.onExitVR(selector.get());
+                compositorViewHolder.onExitVr(selector.get());
             }
         });
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java
index 323c312f..e16076e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrUtils.java
@@ -54,7 +54,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                VrShellDelegate.enterVRIfNecessary();
+                VrShellDelegate.enterVrIfNecessary();
             }
         });
     }
@@ -67,7 +67,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                vrDelegate.shutdownVR(false /* isPausing */, false /* showTransition */);
+                vrDelegate.shutdownVr(false /* isPausing */, false /* showTransition */);
             }
         });
     }
@@ -121,7 +121,7 @@
         CriteriaHelper.pollUiThread(Criteria.equals(true, new Callable<Boolean>() {
             @Override
             public Boolean call() {
-                return VrShellDelegate.isInVR();
+                return VrShellDelegate.isInVr();
             }
         }), timeout, POLL_CHECK_INTERVAL_SHORT_MS);
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
index f964109..58444e3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
@@ -234,7 +234,7 @@
         loadUrl(getHtmlTestFile(testName), PAGE_LOAD_TIMEOUT_S);
         assertTrue("VRDisplay found", vrDisplayFound(mWebContents));
         enterVrTapAndWait(mWebContents);
-        assertTrue("VrShellDelegate is in VR", VrShellDelegate.isInVR());
+        assertTrue("VrShellDelegate is in VR", VrShellDelegate.isInVr());
         endTest(mWebContents);
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/AppIndexingUtilTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/AppIndexingUtilTest.java
new file mode 100644
index 0000000..e7a7b00
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/AppIndexingUtilTest.java
@@ -0,0 +1,132 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.annotation.Config;
+
+import org.chromium.blink.mojom.document_metadata.CopylessPaste;
+import org.chromium.blink.mojom.document_metadata.WebPage;
+import org.chromium.chrome.browser.historyreport.AppIndexingReporter;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.chromium.url.mojom.Url;
+
+/**
+ * Unit tests for {@link org.chromium.chrome.browser.AppIndexingUtil}.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class AppIndexingUtilTest {
+    @Spy
+    AppIndexingUtil mUtil = new AppIndexingUtil();
+    @Mock
+    private AppIndexingReporter mReporter;
+    @Mock
+    private CopylessPasteTestImpl mCopylessPaste;
+    @Mock
+    private Tab mTab;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mReporter).when(mUtil).getAppIndexingReporter();
+        doReturn(mCopylessPaste).when(mUtil).getCopylessPasteInterface(any(Tab.class));
+        doReturn(true).when(mUtil).isEnabledForDevice();
+        doReturn(false).when(mTab).isIncognito();
+
+        doReturn("http://www.test.com").when(mTab).getUrl();
+        doReturn("My neat website").when(mTab).getTitle();
+        doReturn(0L).when(mUtil).getElapsedTime();
+        doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) {
+                CopylessPaste.GetEntitiesResponse callback =
+                        (CopylessPaste.GetEntitiesResponse) invocation.getArguments()[0];
+                WebPage webpage = new WebPage();
+                webpage.url = createUrl("http://www.test.com");
+                webpage.title = "My neat website";
+                callback.call(webpage);
+                return null;
+            }
+        })
+                .when(mCopylessPaste)
+                .getEntities(any(CopylessPaste.GetEntitiesResponse.class));
+    }
+
+    @Test
+    public void testNoCacheHit() {
+        mUtil.extractCopylessPasteMetadata(mTab);
+        verify(mCopylessPaste).getEntities(any(CopylessPaste.GetEntitiesResponse.class));
+        verify(mReporter).reportWebPage(any(WebPage.class));
+    }
+
+    @Test
+    public void testCacheHit() {
+        mUtil.extractCopylessPasteMetadata(mTab);
+        verify(mCopylessPaste).getEntities(any(CopylessPaste.GetEntitiesResponse.class));
+        verify(mReporter).reportWebPage(any(WebPage.class));
+        verify(mReporter, never()).reportWebPageView(any(String.class), any(String.class));
+
+        doReturn(1L).when(mUtil).getElapsedTime();
+        mUtil.extractCopylessPasteMetadata(mTab);
+        verify(mReporter).reportWebPageView(eq("http://www.test.com"), eq("My neat website"));
+        verifyNoMoreInteractions(mCopylessPaste);
+        verifyNoMoreInteractions(mReporter);
+    }
+
+    @Test
+    public void testCacheHit_expired() {
+        mUtil.extractCopylessPasteMetadata(mTab);
+
+        doReturn(60 * 60 * 1000L + 1).when(mUtil).getElapsedTime();
+        mUtil.extractCopylessPasteMetadata(mTab);
+        verify(mCopylessPaste, times(2)).getEntities(any(CopylessPaste.GetEntitiesResponse.class));
+    }
+
+    @Test
+    public void testCacheHit_noEntity() {
+        doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) {
+                CopylessPaste.GetEntitiesResponse callback =
+                        (CopylessPaste.GetEntitiesResponse) invocation.getArguments()[0];
+                callback.call(null);
+                return null;
+            }
+        })
+                .when(mCopylessPaste)
+                .getEntities(any(CopylessPaste.GetEntitiesResponse.class));
+        mUtil.extractCopylessPasteMetadata(mTab);
+
+        doReturn(1L).when(mUtil).getElapsedTime();
+        mUtil.extractCopylessPasteMetadata(mTab);
+        verify(mCopylessPaste, times(1)).getEntities(any(CopylessPaste.GetEntitiesResponse.class));
+        verifyNoMoreInteractions(mReporter);
+    }
+
+    private Url createUrl(String s) {
+        Url url = new Url();
+        url.url = s;
+        return url;
+    }
+
+    abstract static class CopylessPasteTestImpl implements CopylessPaste {}
+}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java
index 88534f0..cb79d3e 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java
@@ -145,7 +145,7 @@
     @Test
     @Feature({"Sync"})
     public void testStop() throws Exception {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.stop();
         Intent intent = getOnlyIntent();
         validateIntentComponent(intent);
@@ -160,7 +160,7 @@
     @Test
     @Feature({"Sync"})
     public void testEnsureStartedAndUpdateRegisteredTypes() {
-        InvalidationController controller = new InvalidationController(mContext, false, false);
+        InvalidationController controller = new InvalidationController(mContext, false);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Intent intent = getOnlyIntent();
 
@@ -190,7 +190,7 @@
     public void testPauseAndResumeMainActivityWithSyncDisabled() throws Exception {
         AndroidSyncSettings.disableChromeSync(mContext);
 
-        InvalidationController controller = new InvalidationController(mContext, false, false);
+        InvalidationController controller = new InvalidationController(mContext, false);
         controller.onApplicationStateChange(ApplicationState.HAS_PAUSED_ACTIVITIES);
         controller.onApplicationStateChange(ApplicationState.HAS_RUNNING_ACTIVITIES);
         assertNoNewIntents();
@@ -205,7 +205,7 @@
     public void testNullProfileSyncService() throws Exception {
         ProfileSyncService.overrideForTests(null);
 
-        InvalidationController controller = new InvalidationController(mContext, false, false);
+        InvalidationController controller = new InvalidationController(mContext, false);
         controller.ensureStartedAndUpdateRegisteredTypes();
         assertNoNewIntents();
     }
@@ -219,7 +219,7 @@
         final AtomicBoolean listenerCallbackCalled = new AtomicBoolean();
 
         // Create instance.
-        new InvalidationController(mContext, true, false) {
+        new InvalidationController(mContext, true) {
             @Override
             public void onApplicationStateChange(int newState) {
                 listenerCallbackCalled.set(true);
@@ -241,7 +241,7 @@
     @Test
     @Feature({"Sync"})
     public void testCannotToggleSessionInvalidations() {
-        InvalidationController controller = new InvalidationController(mContext, false, false);
+        InvalidationController controller = new InvalidationController(mContext, false);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mAllTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
 
@@ -265,7 +265,7 @@
     @Test
     @Feature({"Sync"})
     public void testRecentTabsPageShown() {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
 
@@ -286,7 +286,7 @@
     @Test
     @Feature({"Sync"})
     public void testStartWhileRecentTabsPageShown() {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.onRecentTabsPageOpened();
         ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
         assertNoNewIntents();
@@ -307,7 +307,7 @@
     @Test
     @Feature({"Sync"})
     public void testMultipleRecentTabsPages() {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
 
@@ -334,7 +334,7 @@
     @Test
     @Feature({"Sync"})
     public void testOpenCloseRecentTabsPageQuickly() {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
 
@@ -364,7 +364,7 @@
     @Test
     @Feature({"Sync"})
     public void testDisableSessionInvalidationsOnStart() {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
         controller.onRecentTabsPageOpened();
@@ -390,7 +390,7 @@
     @Test
     @Feature({"Sync"})
     public void testDisableSessionInvalidationsOnResume() {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
         controller.onRecentTabsPageOpened();
@@ -415,7 +415,7 @@
     @Test
     @Feature({"Sync"})
     public void testPauseAndResumeMainActivity() throws Exception {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
         controller.onRecentTabsPageOpened();
@@ -439,7 +439,7 @@
     @Test
     @Feature({"Sync"})
     public void testPauseAndResumeMainActivityAfterStop() throws Exception {
-        InvalidationController controller = new InvalidationController(mContext, true, false);
+        InvalidationController controller = new InvalidationController(mContext, true);
         controller.ensureStartedAndUpdateRegisteredTypes();
         Assert.assertEquals(mNonSessionTypes, getRegisterIntentRegisterTypes(getOnlyIntent()));
 
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn
index 4d85d23..bd96ffa 100644
--- a/chrome/android/webapk/libs/client/BUILD.gn
+++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -12,11 +12,13 @@
     "src/org/chromium/webapk/lib/client/WebApkNavigationClient.java",
     "src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java",
     "src/org/chromium/webapk/lib/client/WebApkValidator.java",
+    "src/org/chromium/webapk/lib/client/WebApkVerifySignature.java",
   ]
   deps = [
     "//base:base_java",
     "//chrome/android/webapk/libs/common:common_java",
     "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
+    "//third_party/android_tools:android_support_annotations_java",
   ]
   srcjar_deps = [ ":runtime_library_version_java" ]
 }
@@ -36,9 +38,15 @@
   java_files = [
     "junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java",
     "junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java",
+    "junit/src/org/chromium/webapk/lib/client/WebApkVerifySignatureTest.java",
+  ]
+  data = [
+    "//chrome/test/data/webapks/",
   ]
   deps = [
     ":client_java",
+    "//chrome/android/webapk/libs/common:common_java",
     "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
+    "//testing/android/junit:junit_test_support",
   ]
 }
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java
index dc7ca80..d5eac28 100644
--- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java
+++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java
@@ -5,16 +5,21 @@
 package org.chromium.webapk.lib.client;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.chromium.webapk.lib.common.WebApkMetaDataKeys.START_URL;
 
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
+import android.os.Bundle;
 
-import org.chromium.testing.local.LocalRobolectricTestRunner;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -23,13 +28,14 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.res.builder.RobolectricPackageManager;
 
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.chromium.testing.local.TestDir;
+
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * Unit tests for {@link org.chromium.webapk.lib.client.WebApkValidator}.
- */
+/** Unit tests for {@link org.chromium.webapk.lib.client.WebApkValidator}. */
 @RunWith(LocalRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
 public class WebApkValidatorTest {
@@ -37,29 +43,38 @@
     private static final String INVALID_WEBAPK_PACKAGE_NAME = "invalid.org.chromium.webapk.foo";
     private static final String URL_OF_WEBAPK = "https://www.foo.com";
     private static final String URL_WITHOUT_WEBAPK = "https://www.other.com";
+    private static final String TEST_DATA_DIR = "webapks/";
 
-    private static final byte[] EXPECTED_SIGNATURE = new byte[] {
-        48, -126, 3, -121, 48, -126, 2, 111, -96, 3, 2, 1, 2, 2, 4, 20, -104, -66, -126, 48, 13,
-        6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, 116, 49, 11, 48, 9, 6, 3, 85, 4,
-        6, 19, 2, 67, 65, 49, 16, 48, 14, 6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 97, 114, 105,
-        111, 49, 17, 48, 15, 6, 3, 85, 4, 7, 19, 8, 87, 97, 116, 101, 114, 108, 111, 111, 49,
-        17, 48, 15, 6, 3, 85, 4, 10, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 49, 17, 48};
+    private static final byte[] EXPECTED_SIGNATURE = new byte[] {48, -126, 3, -121, 48, -126, 2,
+            111, -96, 3, 2, 1, 2, 2, 4, 20, -104, -66, -126, 48, 13, 6, 9, 42, -122, 72, -122, -9,
+            13, 1, 1, 11, 5, 0, 48, 116, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 67, 65, 49, 16, 48,
+            14, 6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 97, 114, 105, 111, 49, 17, 48, 15, 6, 3, 85, 4,
+            7, 19, 8, 87, 97, 116, 101, 114, 108, 111, 111, 49, 17, 48, 15, 6, 3, 85, 4, 10, 19, 8,
+            67, 104, 114, 111, 109, 105, 117, 109, 49, 17, 48};
 
-    private static final byte[] SIGNATURE_1 = new byte[] {
-        13, 52, 51, 48, 51, 48, 51, 49, 53, 49, 54, 52, 52, 90, 48, 116, 49, 11, 48, 9, 6, 3,
-        85, 4, 6, 19, 2, 67, 65, 49, 16, 48, 14, 6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 97, 114};
+    private static final byte[] SIGNATURE_1 = new byte[] {13, 52, 51, 48, 51, 48, 51, 49, 53, 49,
+            54, 52, 52, 90, 48, 116, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 67, 65, 49, 16, 48, 14,
+            6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 97, 114};
 
-    private static final byte[] SIGNATURE_2 = new byte[] {
-        49, 17, 48, 15, 6, 3, 85, 4, 10, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 49, 17,
-        48, 15, 6, 3, 85, 4, 11, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 49, 26, 48, 24};
+    private static final byte[] SIGNATURE_2 = new byte[] {49, 17, 48, 15, 6, 3, 85, 4, 10, 19, 8,
+            67, 104, 114, 111, 109, 105, 117, 109, 49, 17, 48, 15, 6, 3, 85, 4, 11, 19, 8, 67, 104,
+            114, 111, 109, 105, 117, 109, 49, 26, 48, 24};
+
+    // This is the public key used for the test files (chrome/test/data/webapks/public.der)
+    private static final byte[] PUBLIC_KEY = new byte[] {48, 89, 48, 19, 6, 7, 42, -122, 72, -50,
+            61, 2, 1, 6, 8, 42, -122, 72, -50, 61, 3, 1, 7, 3, 66, 0, 4, -67, 14, 37, -20, 103, 121,
+            124, -60, -21, 83, -114, -120, -87, -38, 26, 78, 82, 55, 44, -23, -2, 104, 115, 82, -55,
+            -104, 105, -19, -48, 89, -65, 12, -31, 16, -35, 4, -121, -70, -89, 23, 56, 115, 112, 78,
+            -65, 114, -103, 120, -88, -112, -102, -61, 72, -16, 74, 53, 50, 49, -56, -48, -90, 5,
+            -116, 78};
 
     private RobolectricPackageManager mPackageManager;
 
     @Before
     public void setUp() {
-        mPackageManager = (RobolectricPackageManager) RuntimeEnvironment
-                .application.getPackageManager();
-        WebApkValidator.initWithBrowserHostSignature(EXPECTED_SIGNATURE);
+        mPackageManager =
+                (RobolectricPackageManager) RuntimeEnvironment.application.getPackageManager();
+        WebApkValidator.init(true, EXPECTED_SIGNATURE, PUBLIC_KEY);
     }
 
     /**
@@ -76,8 +91,9 @@
             mPackageManager.addPackage(newPackageInfoWithBrowserSignature(
                     WEBAPK_PACKAGE_NAME, new Signature(EXPECTED_SIGNATURE)));
 
-            assertEquals(WEBAPK_PACKAGE_NAME, WebApkValidator.queryWebApkPackage(
-                    RuntimeEnvironment.application, URL_OF_WEBAPK));
+            assertEquals(WEBAPK_PACKAGE_NAME,
+                    WebApkValidator.queryWebApkPackage(
+                            RuntimeEnvironment.application, URL_OF_WEBAPK));
         } catch (URISyntaxException e) {
             Assert.fail("URI is invalid.");
         }
@@ -103,8 +119,8 @@
     }
 
     /**
-     * Tests {@link WebApkValidator.queryWebApkPackage()} returns null if no WebAPK handles
-     * the given URL.
+     * Tests {@link WebApkValidator.queryWebApkPackage()} returns null if no WebAPK handles the
+     * given URL.
      */
     @Test
     public void testQueryWebApkPackageReturnsNullWhenNoWebApkHandlesTheURL() {
@@ -139,8 +155,8 @@
     }
 
     /**
-     * Tests {@link WebApkValidator.findWebApkPackage} returns null if none of the packages for the
-     * ResolveInfos start with {@link WebApkConstants.WEBAPK_PACKAGE_PREFIX}.
+     * Tests {@link WebApkValidator.findWebApkPackage} returns null if null if the package
+     * name is invalid.
      */
     @Test
     public void testFindWebApkPackageReturnsNullForInvalidPackageName() {
@@ -163,7 +179,7 @@
         infos.add(newResolveInfo(WEBAPK_PACKAGE_NAME));
         Signature[] signatures = new Signature[] {new Signature(SIGNATURE_1),
                 new Signature(EXPECTED_SIGNATURE), new Signature(SIGNATURE_2)};
-        mPackageManager.addPackage(newPackageInfo(WEBAPK_PACKAGE_NAME, signatures));
+        mPackageManager.addPackage(newPackageInfo(WEBAPK_PACKAGE_NAME, signatures, null));
 
         assertNull(WebApkValidator.findWebApkPackage(RuntimeEnvironment.application, infos));
     }
@@ -179,11 +195,58 @@
         infos.add(newResolveInfo(WEBAPK_PACKAGE_NAME));
         Signature signatures[] =
                 new Signature[] {new Signature(SIGNATURE_1), new Signature(SIGNATURE_2)};
-        mPackageManager.addPackage(newPackageInfo(WEBAPK_PACKAGE_NAME, signatures));
+        mPackageManager.addPackage(newPackageInfo(WEBAPK_PACKAGE_NAME, signatures, null));
 
         assertNull(WebApkValidator.findWebApkPackage(RuntimeEnvironment.application, infos));
     }
 
+    /**
+     * Tests {@link WebApkValidator#isValidWebApk()} for valid comment signed webapks.
+     */
+    @Test
+    public void testIsValidWebApkCommentSigned() {
+        String[] filenames = {"example.apk", "java-example.apk"};
+        String packageName = "com.webapk.a9c419502bb98fcb7";
+        Signature[] signature = new Signature[] {new Signature(SIGNATURE_1)};
+
+        for (String filename : filenames) {
+            mPackageManager.removePackage(packageName);
+            mPackageManager.addPackage(
+                    newPackageInfo(packageName, signature, testFilePath(filename)));
+            assertTrue(filename + " did not verify",
+                    WebApkValidator.isValidWebApk(RuntimeEnvironment.application, packageName));
+        }
+    }
+
+    /**
+     * Tests {@link WebApkValidator#isValidWebApk()} for failing comment signed webapks.
+     * These  WebAPKs were modified to fail in specific ways.
+     */
+    @Test
+    public void testIsValidWebApkCommentSignedFailures() {
+        String[] filenames = {
+                "bad-sig.apk", "bad-utf8-fname.apk", "empty.apk", "extra-len-too-large.apk",
+                "fcomment-too-large.apk", "no-cd.apk", "no-comment.apk", "no-eocd.apk",
+                "no-lfh.apk", "not-an.apk", "too-many-metainf.apk", "truncated.apk", "zeros.apk",
+                "zeros-at-end.apk",
+        };
+        String packageName = "com.webapk.a9c419502bb98fcb7";
+        Signature[] signature = new Signature[] {new Signature(SIGNATURE_1)};
+
+        for (String filename : filenames) {
+            mPackageManager.removePackage(packageName);
+            mPackageManager.addPackage(
+                    newPackageInfo(packageName, signature, testFilePath(filename)));
+            assertFalse(filename,
+                    WebApkValidator.isValidWebApk(RuntimeEnvironment.application, packageName));
+        }
+    }
+
+    // Get the full test file path.
+    private static String testFilePath(String fileName) {
+        return TestDir.getTestFilePath(TEST_DATA_DIR + fileName);
+    }
+
     private static ResolveInfo newResolveInfo(String packageName) {
         ActivityInfo activityInfo = new ActivityInfo();
         activityInfo.packageName = packageName;
@@ -192,10 +255,15 @@
         return resolveInfo;
     }
 
-    private static PackageInfo newPackageInfo(String packageName, Signature[] signatures) {
+    private static PackageInfo newPackageInfo(
+            String packageName, Signature[] signatures, String sourceDir) {
         PackageInfo packageInfo = new PackageInfo();
         packageInfo.packageName = packageName;
         packageInfo.signatures = signatures;
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.metaData = new Bundle();
+        packageInfo.applicationInfo.metaData.putString(START_URL, "https://non-empty.com/starturl");
+        packageInfo.applicationInfo.sourceDir = sourceDir;
         return packageInfo;
     }
 
@@ -203,6 +271,6 @@
     // additional ones after the second) are ignored.
     private static PackageInfo newPackageInfoWithBrowserSignature(
             String packageName, Signature signature) {
-        return newPackageInfo(packageName, new Signature[] {new Signature(""), signature});
+        return newPackageInfo(packageName, new Signature[] {new Signature(""), signature}, null);
     }
 }
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkVerifySignatureTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkVerifySignatureTest.java
new file mode 100644
index 0000000..4a032a6
--- /dev/null
+++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkVerifySignatureTest.java
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.webapk.lib.client;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+
+/** Unit tests for WebApkVerifySignature for Android. */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class WebApkVerifySignatureTest {
+    /** Elliptical Curves, Digital Signature Algorithm */
+    private static final String KEY_FACTORY = "EC";
+
+    private static final String TEST_DATA_DIR = "/webapks/";
+
+    @Test
+    public void testHexToBytes() throws Exception {
+        byte[] empty = {};
+        assertArrayEquals(empty, WebApkVerifySignature.hexToBytes(""));
+        byte[] test = {(byte) 0xFF, (byte) 0xFE, 0x00, 0x01};
+        assertArrayEquals(test, WebApkVerifySignature.hexToBytes("fffe0001"));
+        assertArrayEquals(test, WebApkVerifySignature.hexToBytes("FFFE0001"));
+        assertEquals(null, WebApkVerifySignature.hexToBytes("f")); // Odd number of nibbles.
+    }
+
+    @Test
+    public void testCommentHash() throws Exception {
+        byte[] bytes = {(byte) 0xde, (byte) 0xca, (byte) 0xfb, (byte) 0xad};
+        assertEquals(null, WebApkVerifySignature.parseCommentSignature("weapk:decafbad"));
+        assertEquals(null, WebApkVerifySignature.parseCommentSignature("webapk:"));
+        assertEquals(null, WebApkVerifySignature.parseCommentSignature("webapk:decafbad"));
+        assertArrayEquals(
+                bytes, WebApkVerifySignature.parseCommentSignature("webapk:12345:decafbad"));
+        assertArrayEquals(
+                bytes, WebApkVerifySignature.parseCommentSignature("XXXwebapk:0000:decafbadXXX"));
+        assertArrayEquals(
+                bytes, WebApkVerifySignature.parseCommentSignature("\n\nwebapk:0000:decafbad\n\n"));
+        assertArrayEquals(bytes,
+                WebApkVerifySignature.parseCommentSignature("chrome-webapk:000:decafbad\n\n"));
+        assertArrayEquals(bytes,
+                WebApkVerifySignature.parseCommentSignature(
+                        "prefixed: chrome-webapk:000:decafbad :suffixed"));
+    }
+}
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java
index 36840fc0..5077fd8 100644
--- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java
+++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkValidator.java
@@ -5,6 +5,7 @@
 package org.chromium.webapk.lib.client;
 
 import static org.chromium.webapk.lib.common.WebApkConstants.WEBAPK_PACKAGE_PREFIX;
+import static org.chromium.webapk.lib.common.WebApkMetaDataKeys.START_URL;
 
 import android.content.Context;
 import android.content.Intent;
@@ -13,10 +14,19 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
+import android.os.StrictMode;
+import android.text.TextUtils;
 import android.util.Log;
 
 import org.chromium.base.annotations.SuppressFBWarnings;
 
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
@@ -26,16 +36,20 @@
  * Server.
  */
 public class WebApkValidator {
-
     private static final String TAG = "WebApkValidator";
+    private static final String KEY_FACTORY = "EC"; // aka "ECDSA"
+
+    private static boolean sAllWebApkPackageNames;
     private static byte[] sExpectedSignature;
+    private static byte[] sCommentSignedPublicKeyBytes;
+    private static PublicKey sCommentSignedPublicKey;
 
     /**
-     * Queries the PackageManager to determine whether a WebAPK can handle the URL. Ignores
-     * whether the user has selected a default handler for the URL and whether the default
-     * handler is the WebAPK.
+     * Queries the PackageManager to determine whether a WebAPK can handle the URL. Ignores whether
+     * the user has selected a default handler for the URL and whether the default handler is the
+     * WebAPK.
      *
-     * NOTE(yfriedman): This can fail if multiple WebAPKs can match the supplied url.
+     * <p>NOTE(yfriedman): This can fail if multiple WebAPKs can match the supplied url.
      *
      * @param context The application context.
      * @param url The url to check.
@@ -47,16 +61,16 @@
     }
 
     /**
-     * Queries the PackageManager to determine whether a WebAPK can handle the URL. Ignores
-     * whether the user has selected a default handler for the URL and whether the default
-     * handler is the WebAPK.
+     * Queries the PackageManager to determine whether a WebAPK can handle the URL. Ignores whether
+     * the user has selected a default handler for the URL and whether the default handler is the
+     * WebAPK.
      *
-     * NOTE: This can fail if multiple WebAPKs can match the supplied url.
+     * <p>NOTE: This can fail if multiple WebAPKs can match the supplied url.
      *
      * @param context The application context.
      * @param url The url to check.
      * @return Resolve Info of a WebAPK which can handle the URL. Null if the url should not be
-     * handled by a WebAPK.
+     *     handled by a WebAPK.
      */
     public static ResolveInfo queryResolveInfo(Context context, String url) {
         return findResolveInfo(context, resolveInfosForUrl(context, url));
@@ -92,7 +106,7 @@
      * @param context The context to use to check whether WebAPK is valid.
      * @param infos The ResolveInfos to search.
      * @return Package name of the ResolveInfo which corresponds to a WebAPK. Null if none of the
-     * ResolveInfos corresponds to a WebAPK.
+     *     ResolveInfos corresponds to a WebAPK.
      */
     public static String findWebApkPackage(Context context, List<ResolveInfo> infos) {
         ResolveInfo resolveInfo = findResolveInfo(context, infos);
@@ -125,47 +139,151 @@
      * @return true iff the WebAPK is installed and passes security checks
      */
     public static boolean isValidWebApk(Context context, String webappPackageName) {
-        if (sExpectedSignature == null) {
-            Log.wtf(TAG, "WebApk validation failure - expected signature not set."
-                    + "missing call to WebApkValidator.initWithBrowserHostSignature");
-        }
-        if (!webappPackageName.startsWith(WEBAPK_PACKAGE_PREFIX)) {
+        if (sExpectedSignature == null || sCommentSignedPublicKeyBytes == null) {
+            Log.wtf(TAG,
+                    "WebApk validation failure - expected signature not set."
+                            + "missing call to WebApkValidator.initWithBrowserHostSignature");
             return false;
         }
-        // check signature
         PackageInfo packageInfo = null;
         try {
             packageInfo = context.getPackageManager().getPackageInfo(webappPackageName,
-                    PackageManager.GET_SIGNATURES);
+                    PackageManager.GET_SIGNATURES | PackageManager.GET_META_DATA);
         } catch (NameNotFoundException e) {
             e.printStackTrace();
             Log.d(TAG, "WebApk not found");
             return false;
         }
+        if (isNotWebApkQuick(packageInfo)) {
+            return false;
+        }
+        if (verifyV1WebApk(packageInfo, webappPackageName)) {
+            return true;
+        }
 
-        final Signature[] arrSignatures = packageInfo.signatures;
-        if (arrSignatures != null && arrSignatures.length == 2) {
-            for (Signature signature : arrSignatures) {
-                if (Arrays.equals(sExpectedSignature, signature.toByteArray())) {
-                    Log.d(TAG, "WebApk valid - signature match!");
-                    return true;
-                }
+        return verifyCommentSignedWebApk(packageInfo, webappPackageName);
+    }
+
+    /** Determine quickly whether this is definitely not a WebAPK */
+    private static boolean isNotWebApkQuick(PackageInfo packageInfo) {
+        if (packageInfo.applicationInfo == null || packageInfo.applicationInfo.metaData == null) {
+            Log.e(TAG, "no application info, or metaData retrieved.");
+            return true;
+        }
+        // Having the startURL in AndroidManifest.xml is a strong signal.
+        String startUrl = packageInfo.applicationInfo.metaData.getString(START_URL);
+        return TextUtils.isEmpty(startUrl);
+    }
+
+    private static boolean verifyV1WebApk(PackageInfo packageInfo, String webappPackageName) {
+        if (packageInfo.signatures == null || packageInfo.signatures.length != 2
+                || !webappPackageName.startsWith(WEBAPK_PACKAGE_PREFIX)) {
+            return false;
+        }
+        for (Signature signature : packageInfo.signatures) {
+            if (Arrays.equals(sExpectedSignature, signature.toByteArray())) {
+                Log.d(TAG, "WebApk valid - signature match!");
+                return true;
             }
         }
-        Log.d(TAG, "WebApk invalid");
         return false;
     }
 
+    /** Verify that the comment signed webapk matches the public key. */
+    private static boolean verifyCommentSignedWebApk(
+            PackageInfo packageInfo, String webappPackageName) {
+        if (!sAllWebApkPackageNames && !webappPackageName.startsWith(WEBAPK_PACKAGE_PREFIX)) {
+            return false;
+        }
+
+        PublicKey commentSignedPublicKey;
+        try {
+            commentSignedPublicKey = getCommentSignedPublicKey();
+        } catch (Exception e) {
+            Log.e(TAG, "WebApk failed to get Public Key", e);
+            return false;
+        }
+        if (commentSignedPublicKey == null) {
+            Log.e(TAG, "WebApk validation failure - unable to decode public key");
+            return false;
+        }
+        if (packageInfo.applicationInfo == null || packageInfo.applicationInfo.sourceDir == null) {
+            Log.e(TAG, "WebApk validation failure - missing applicationInfo sourcedir");
+            return false;
+        }
+
+        String packageFilename = packageInfo.applicationInfo.sourceDir;
+        RandomAccessFile file = null;
+        FileChannel inChannel = null;
+        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+
+        try {
+            file = new RandomAccessFile(packageFilename, "r");
+            inChannel = file.getChannel();
+
+            MappedByteBuffer buf =
+                    inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
+            buf.load();
+
+            WebApkVerifySignature v = new WebApkVerifySignature(buf);
+            int result = v.read();
+            if (result != WebApkVerifySignature.ERROR_OK) {
+                Log.e(TAG, String.format("Failure reading %s: %s", packageFilename, result));
+                return false;
+            }
+            result = v.verifySignature(commentSignedPublicKey);
+
+            // TODO(scottkirkwood): remove this log once well tested.
+            Log.d(TAG, "File " + packageFilename + ": " + result);
+            return result == WebApkVerifySignature.ERROR_OK;
+        } catch (Exception e) {
+            Log.e(TAG, "WebApk file error for file " + packageFilename, e);
+            return false;
+        } finally {
+            StrictMode.setThreadPolicy(oldPolicy);
+            if (inChannel != null) {
+                try {
+                    inChannel.close();
+                } catch (IOException e) {
+                }
+            }
+            if (file != null) {
+                try {
+                    file.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
     /**
-     * Initializes the WebApkValidator with the expected signature that WebAPKs must be signed
-     * with for the current host.
-     * @param expectedSignature
+     * Initializes the WebApkValidator.
+     * @param allWebApkPackageNames Whether we permit any package names for comment signed WebAPKs.
+     * @param expectedSignature V1 WebAPK RSA signature.
+     * @param v2PublicKeyBytes New comment signed public key bytes as x509 encoded public key.
      */
     @SuppressFBWarnings("EI_EXPOSE_STATIC_REP2")
-    public static void initWithBrowserHostSignature(byte[] expectedSignature) {
-        if (sExpectedSignature != null) {
-            return;
+    public static void init(
+            boolean allWebApkPackageNames, byte[] expectedSignature, byte[] v2PublicKeyBytes) {
+        sAllWebApkPackageNames = allWebApkPackageNames;
+        if (sExpectedSignature == null) {
+            sExpectedSignature = expectedSignature;
         }
-        sExpectedSignature = expectedSignature;
+        if (sCommentSignedPublicKeyBytes == null) {
+            sCommentSignedPublicKeyBytes = v2PublicKeyBytes;
+        }
+    }
+
+    /**
+     * Lazy evaluate the creation of the Public Key as the KeyFactories may not yet be initialized.
+     * @return The decoded PublicKey or null
+     */
+    private static PublicKey getCommentSignedPublicKey() throws Exception {
+        if (sCommentSignedPublicKey == null) {
+            sCommentSignedPublicKey =
+                    KeyFactory.getInstance(KEY_FACTORY)
+                            .generatePublic(new X509EncodedKeySpec(sCommentSignedPublicKeyBytes));
+        }
+        return sCommentSignedPublicKey;
     }
 }
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java
new file mode 100644
index 0000000..1c3fb5fa
--- /dev/null
+++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkVerifySignature.java
@@ -0,0 +1,404 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.webapk.lib.client;
+
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
+
+import android.support.annotation.IntDef;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * WebApkVerifySignature reads in the APK file and verifies the WebApk signature. It reads the
+ * signature from the zip comment and verifies that it was signed by the public key passed.
+ */
+public class WebApkVerifySignature {
+    /** Errors codes. */
+    @IntDef({
+            ERROR_OK, ERROR_BAD_APK, ERROR_EXTRA_FIELD_TOO_LARGE, ERROR_COMMENT_TOO_LARGE,
+            ERROR_INCORRECT_SIGNATURE, ERROR_SIGNATURE_NOT_FOUND, ERROR_TOO_MANY_META_INF_FILES,
+    })
+    public @interface Error {}
+    public static final int ERROR_OK = 0;
+    public static final int ERROR_BAD_APK = 1;
+    public static final int ERROR_EXTRA_FIELD_TOO_LARGE = 2;
+    public static final int ERROR_COMMENT_TOO_LARGE = 3;
+    public static final int ERROR_INCORRECT_SIGNATURE = 4;
+    public static final int ERROR_SIGNATURE_NOT_FOUND = 5;
+    public static final int ERROR_TOO_MANY_META_INF_FILES = 6;
+
+    private static final String TAG = "WebApkVerifySignature";
+
+    /** End Of Central Directory Signature. */
+    private static final long EOCD_SIG = 0x06054b50;
+
+    /** Central Directory Signature. */
+    private static final long CD_SIG = 0x02014b50;
+
+    /** Local File Header Signature. */
+    private static final long LFH_SIG = 0x04034b50;
+
+    /** Minimum end-of-central-directory size in bytes, including variable length file comment. */
+    private static final int MIN_EOCD_SIZE = 22;
+
+    /** Max end-of-central-directory size in bytes permitted. */
+    private static final int MAX_EOCD_SIZE = 64 * 1024;
+
+    /** Maximum number of META-INF/ files (allowing for dual signing). */
+    private static final int MAX_META_INF_FILES = 5;
+
+    /** The signature algorithm used (must also match with HASH). */
+    private static final String SIGNING_ALGORITHM = "SHA256withECDSA";
+
+    /**
+     * The pattern we look for in the APK/zip comment for signing key.
+     * An example is "webapk:0000:<hexvalues>". This pattern can appear anywhere
+     * in the comment but must be separated from any other parts with a
+     * separator that doesn't look like a hex character.
+     */
+    private static final Pattern WEBAPK_COMMENT_PATTERN =
+            Pattern.compile("webapk:\\d+:([a-fA-F0-9]+)");
+
+    /** Maximum comment length permitted. */
+    private static final int MAX_COMMENT_LENGTH = 0;
+
+    /** Maximum extra field length permitted. */
+    private static final int MAX_EXTRA_LENGTH = 8;
+
+    /** The memory buffer we are going to read the zip from. */
+    private final ByteBuffer mBuffer;
+
+    /** Number of total central directory (zip entry) records. */
+    private int mRecordCount;
+
+    /** Byte offset from the start where the central directory is found. */
+    private int mCentralDirOffset;
+
+    /** The zip archive comment as a UTF-8 string. */
+    private String mComment;
+
+    /**
+     * Sorted list of 'blocks' of memory we will cryptographically hash. We sort the blocks by
+     * filename to ensure a repeatable order.
+     */
+    private ArrayList<Block> mBlocks;
+
+    /** Block contains metadata about a zip entry. */
+    private static class Block implements Comparable<Block> {
+        String mFilename;
+        int mPosition;
+        int mHeaderSize;
+        int mCompressedSize;
+
+        Block(String filename, int position, int compressedSize) {
+            mFilename = filename;
+            mPosition = position;
+            mHeaderSize = 0;
+            mCompressedSize = compressedSize;
+        }
+
+        /** Added for Comparable, sort lexicographically. */
+        @Override
+        public int compareTo(Block o) {
+            return mFilename.compareTo(o.mFilename);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Block)) return false;
+            return mFilename.equals(((Block) o).mFilename);
+        }
+
+        @Override
+        public int hashCode() {
+            return mFilename.hashCode();
+        }
+    }
+
+    /** Constructor simply 'connects' to buffer passed. */
+    public WebApkVerifySignature(ByteBuffer buffer) {
+        mBuffer = buffer;
+        mBuffer.order(LITTLE_ENDIAN);
+    }
+
+    /**
+     * Read in the comment and directory. If there is no parseable comment we won't read the
+     * directory as there is no point (for speed). On success, all of our private variables will be
+     * set.
+     * @return OK on success.
+     */
+    public int read() {
+        try {
+            int err = readEOCD();
+            if (err != ERROR_OK) {
+                return err;
+            }
+            // Short circuit if no comment found.
+            if (parseCommentSignature(mComment) == null) {
+                return ERROR_SIGNATURE_NOT_FOUND;
+            }
+            err = readDirectory();
+            if (err != ERROR_OK) {
+                return err;
+            }
+        } catch (Exception e) {
+            return ERROR_BAD_APK;
+        }
+        return ERROR_OK;
+    }
+
+    /**
+     * verifySignature hashes all the files and then verifies the signature.
+     * @param pub The public key that it should be verified against.
+     * @return ERROR_OK if the public key signature verifies.
+     */
+    public int verifySignature(PublicKey pub) {
+        byte[] sig = parseCommentSignature(mComment);
+        if (sig == null || sig.length == 0) {
+            return ERROR_SIGNATURE_NOT_FOUND;
+        }
+        try {
+            Signature signature = Signature.getInstance(SIGNING_ALGORITHM);
+            signature.initVerify(pub);
+            int err = calculateHash(signature);
+            if (err != ERROR_OK) {
+                return err;
+            }
+            return signature.verify(sig) ? ERROR_OK : ERROR_INCORRECT_SIGNATURE;
+        } catch (Exception e) {
+            Log.e(TAG, "Exception calculating signature", e);
+            return ERROR_INCORRECT_SIGNATURE;
+        }
+    }
+
+    /**
+     * calculateHash goes through each file listed in blocks and calculates the SHA-256
+     * cryptographic hash.
+     * @param sig Signature object you can call update on.
+     */
+    public int calculateHash(Signature sig) throws Exception {
+        Collections.sort(mBlocks);
+        int metaInfCount = 0;
+        for (Block block : mBlocks) {
+            if (block.mFilename.indexOf("META-INF/") == 0) {
+                metaInfCount++;
+                if (metaInfCount > MAX_META_INF_FILES) {
+                    // TODO(scottkirkwood): Add whitelist of files.
+                    return ERROR_TOO_MANY_META_INF_FILES;
+                }
+
+                // Files that begin with META-INF/ are not part of the hash.
+                // This is because these signatures are added after we comment signed the rest of
+                // the APK.
+                continue;
+            }
+
+            // Hash the filename length and filename to prevent Horton principle violation.
+            byte[] filename = block.mFilename.getBytes();
+            sig.update(intToLittleEndian(filename.length));
+            sig.update(filename);
+
+            // Also hash the block length for the same reason.
+            sig.update(intToLittleEndian(block.mCompressedSize));
+
+            seek(block.mPosition + block.mHeaderSize);
+            ByteBuffer slice = mBuffer.slice();
+            slice.limit(block.mCompressedSize);
+            sig.update(slice);
+        }
+        return ERROR_OK;
+    }
+
+    /**
+     * intToLittleEndian converts an integer to a little endian array of bytes.
+     * @param value Integer value to convert.
+     * @return Array of bytes.
+     */
+    private byte[] intToLittleEndian(int value) {
+        ByteBuffer buffer = ByteBuffer.allocate(4);
+        buffer.order(LITTLE_ENDIAN);
+        buffer.putInt(value);
+        return buffer.array();
+    }
+
+    /**
+     * Extract the bytes of the signature from the comment. We expect
+     * "webapk:0000:<hexvalues>" comment followed by hex values. Currently we ignore the
+     * "key id" which is always "0000".
+     * @return the bytes of the signature.
+     */
+    static byte[] parseCommentSignature(String comment) {
+        Matcher m = WEBAPK_COMMENT_PATTERN.matcher(comment);
+        if (!m.find()) {
+            return null;
+        }
+        String s = m.group(1);
+        return hexToBytes(s);
+    }
+
+    /**
+     * Reads the End of Central Directory Record.
+     * @return ERROR_OK on success.
+     */
+    private int readEOCD() {
+        int start = findEOCDStart();
+        if (start < 0) {
+            return ERROR_BAD_APK;
+        }
+        //  Signature(4), Disk Number(2), Start disk number(2), Records on this disk (2)
+        seek(start + 10);
+        mRecordCount = read2(); // Number of Central Directory records
+        seekDelta(4); // Size of central directory
+        mCentralDirOffset = read4(); // as bytes from start of file.
+        int commentLength = read2();
+        mComment = readString(commentLength);
+        return ERROR_OK;
+    }
+
+    /**
+     * Reads the central directory and populates {@link mBlocks} with data about each entry.
+     * @return ERROR_OK on success.
+     */
+    @Error
+    int readDirectory() {
+        mBlocks = new ArrayList<>(mRecordCount);
+        seek(mCentralDirOffset);
+        for (int i = 0; i < mRecordCount; i++) {
+            int signature = read4();
+            if (signature != CD_SIG) {
+                Log.d(TAG, "Missing Central Directory Signature");
+                return ERROR_BAD_APK;
+            }
+            // CreatorVersion(2), ReaderVersion(2), Flags(2), CompressionMethod(2)
+            // ModifiedTime(2), ModifiedDate(2), CRC32(4) = 16 bytes
+            seekDelta(16);
+            int compressedSize = read4();
+            seekDelta(4); // uncompressed size
+            int fileNameLength = read2();
+            int extraLen = read2();
+            int fileCommentLength = read2();
+            seekDelta(8); // DiskNumberStart(2), Internal Attrs(2), External Attrs(4)
+            int offset = read4();
+            String filename = readString(fileNameLength);
+            seekDelta(extraLen + fileCommentLength);
+            if (extraLen > MAX_EXTRA_LENGTH) {
+                return ERROR_EXTRA_FIELD_TOO_LARGE;
+            }
+            if (fileCommentLength > MAX_COMMENT_LENGTH) {
+                return ERROR_COMMENT_TOO_LARGE;
+            }
+            mBlocks.add(new Block(filename, offset, compressedSize));
+        }
+
+        // Read the 'local file header' block to the size of the header in bytes.
+        for (Block block : mBlocks) {
+            seek(block.mPosition);
+            int signature = read4();
+            if (signature != LFH_SIG) {
+                Log.d(TAG, "LFH Signature missing");
+                return ERROR_BAD_APK;
+            }
+            // ReaderVersion(2), Flags(2), CompressionMethod(2),
+            // ModifiedTime (2), ModifiedDate(2), CRC32(4), CompressedSize(4),
+            // UncompressedSize(4) = 22 bytes
+            seekDelta(22);
+            int fileNameLength = read2();
+            int extraFieldLength = read2();
+            if (extraFieldLength > MAX_EXTRA_LENGTH) {
+                return ERROR_EXTRA_FIELD_TOO_LARGE;
+            }
+
+            block.mHeaderSize =
+                    (mBuffer.position() - block.mPosition) + fileNameLength + extraFieldLength;
+        }
+        return ERROR_OK;
+    }
+
+    /**
+     * We search buffer for EOCD_SIG and return the location where we found it. If the file has no
+     * comment it should seek only once.
+     * TODO(scottkirkwood): Use a Boyer-Moore search algorithm.
+     * @return Offset from start of buffer or -1 if not found.
+     */
+    private int findEOCDStart() {
+        int offset = mBuffer.limit() - MIN_EOCD_SIZE;
+        int minSearchOffset = Math.max(0, offset - MAX_EOCD_SIZE);
+        for (; offset >= minSearchOffset; offset--) {
+            seek(offset);
+            if (read4() == EOCD_SIG) {
+                // found!
+                return offset;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Seek to this position.
+     * @param offset offset from start of file.
+     */
+    private void seek(int offset) {
+        mBuffer.position(offset);
+    }
+
+    /**
+     * Skip forward this number of bytes.
+     * @param delta number of bytes to seek forward.
+     */
+    private void seekDelta(int delta) {
+        mBuffer.position(mBuffer.position() + delta);
+    }
+
+    /**
+     * Reads two bytes in little endian format.
+     * @return short value read (as an int).
+     */
+    private int read2() {
+        return mBuffer.getShort();
+    }
+
+    /**
+     * Reads four bytes in little endian format.
+     * @return value read.
+     */
+    private int read4() {
+        return mBuffer.getInt();
+    }
+
+    /** Read {@link length} many bytes into a string. */
+    private String readString(int length) {
+        if (length <= 0) {
+            return "";
+        }
+        byte[] bytes = new byte[length];
+        mBuffer.get(bytes);
+        return new String(bytes);
+    }
+
+    /**
+     * Convert a hex string into bytes. We store hex in the signature as zip
+     * tools often don't like binary strings.
+     */
+    static byte[] hexToBytes(String s) {
+        int len = s.length();
+        if (len % 2 != 0) {
+            // Odd number of nibbles.
+            return null;
+        }
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                    + Character.digit(s.charAt(i + 1), 16));
+        }
+        return data;
+    }
+}
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index c26d2e2..88298674 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -5627,6 +5627,71 @@
     This device was locked by the owner.
   </message>
 
+  <!-- Encryption migration dialog -->
+  <message name="IDS_ENCRYPTION_MIGRATION_READY_TITLE" desc="Title shown in encryption migration screen, which asks the user to install a critical update.">
+    Install critical update
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_READY_DESCRIPTION" desc="Description shown in encryption migration screen, which asks the user to install a critical update.">
+    To download and use Android apps, first you need to install an update. While your device is updating, you can’t use it. Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> will restart after installation completes.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_MIGRATING_TITLE" desc="Title shown in encryption migration screen when the migration is ongoing.">
+    Installing critical update
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_MIGRATING_DESCRIPTION" desc="Description shown in encryption migration screen when the migration is ongoing.">
+    Don’t turn off or close your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> until the update finishes. Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> will restart after installation completes.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_PROGRESS_LABEL" desc="Label to show the progress of the migration.">
+    <ph name="PROGRESS_PERCENT">$1<ex>90</ex></ph>% done
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_BATTERY_WARNING_LABEL" desc="Label to tell the user that the battery level is too low to start the migration.">
+    Battery too low for update (<ph name="PROGRESS_PERCENT">$1<ex>10</ex></ph>%)
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_ASK_CHARGE_MESSAGE" desc="Label to ask the user to charge the device.">
+    Please plug your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> into a power source.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_NECESSARY_BATTERY_LEVEL_MESSAGE" desc="Explanation about how to start migration when the battery level is low.">
+    Update will begin when battery reaches <ph name="BATTERY_LEVEL">$1<ex>30</ex></ph>%.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_CHARGING_LABEL" desc="Label which is shown when the device is charging.">
+    Charging.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_FAILED_TITLE" desc="Title shown in encryption migration screen when the migration fails.">
+    Something went wrong
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_FAILED_SUBTITLE" desc="In encryption migration screen, explanation about the failure of migration.">
+    Sorry, some files were damaged and the update wasn’t successful. Your synced files are safe.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_FAILED_MESSAGE" desc="In encryption migration screen, label to ask user to create the account again.">
+    Unfortunately, you'll need to add your account to this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> again.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_NOSPACE_WARNING_LABEL" desc="Label to tell the user that migration can not start due to low storage space.">
+    Not enough storage for update
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_ASK_FREE_SPACE_MESSAGE" desc="In encryption migration screen, message to ask the user to free some space on the device.">
+    Please free up some space on your device.
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_AVAILABLE_SPACE_LABEL" desc="In encryption migration screen, label to tell the user how much space is available now.">
+    Available: <ph name="AVAILABLE_SPACE">$1<ex>5 MB</ex></ph>
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_NECESSARY_SPACE_LABEL" desc="In encryption migration screen, label to tell the user how much space is necessary to start migration.">
+    Needed to update: <ph name="NECESSARY_SPACE">$1<ex>10 MB</ex></ph>
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_BUTTON_UPDATE" desc="In encryption migration screen, button label to start migration (i.e. update the encryption of user data).">
+    Update
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_BUTTON_SKIP" desc="In encryption migration screen, button label to skip the migration.">
+    Skip
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_BUTTON_RESTART" desc="In encryption migration screen, button label to restart the device.">
+    Restart
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_BUTTON_CONTINUE" desc="In encryption migration screen, button label to continue to sign in to the user's session.">
+    Continue
+  </message>
+  <message name="IDS_ENCRYPTION_MIGRATION_BUTTON_SIGNIN" desc="In encryption migration screen, button label to sign in to the user's session.">
+    Sign in
+  </message>
+
   <!-- Idle warning dialog -->
   <message name="IDS_IDLE_WARNING_TITLE" desc="Title of the warning dialog shown when the user becomes idle and is about to get logged out.">
     Are you still there?
@@ -6591,9 +6656,6 @@
   </message>
 
   <!-- Print Job Notification -->
-  <message name="IDS_PRINT_JOB_WAITING_NOTIFICATION_MESSAGE" desc="Message of the waiting-for-printing notification.">
-    Waiting to print <ph name="PAGE_NUMBER">$1<ex>5</ex></ph> pages to <ph name="PRINTER_NAME">$2<ex>printer</ex></ph>
-  </message>
   <message name="IDS_PRINT_JOB_PRINTING_NOTIFICATION_MESSAGE" desc="Message of the printing-in-progress notification.">
     Now printing <ph name="PAGE_NUMBER">$1<ex>5</ex></ph> pages to <ph name="PRINTER_NAME">$2<ex>printer</ex></ph>
   </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index cbccc4b..6ccbdb1 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2484,6 +2484,11 @@
          autofill::kAutofillCreditCardLastUsedDateDisplay,
          kAutofillCreditCardLastUsedDateFeatureVariations,
          "AutofillCreditCardLastUsedDate")},
+    {"enable-autofill-credit-card-upload-cvc-prompt",
+     flag_descriptions::kEnableAutofillCreditCardUploadCvcPrompt,
+     flag_descriptions::kEnableAutofillCreditCardUploadCvcPromptDescription,
+     kOsDesktop,
+     FEATURE_VALUE_TYPE(autofill::kAutofillUpstreamRequestCvcIfMissing)},
 #if defined(OS_WIN)
     {"windows10-custom-titlebar",
      flag_descriptions::kWindows10CustomTitlebarName,
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn
index d47cd44..e4369569 100644
--- a/chrome/browser/android/vr_shell/BUILD.gn
+++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -57,8 +57,6 @@
       "vr_gl_util.h",
       "vr_input_manager.cc",
       "vr_input_manager.h",
-      "vr_omnibox.cc",
-      "vr_omnibox.h",
       "vr_shell.cc",
       "vr_shell.h",
       "vr_shell_delegate.cc",
@@ -73,10 +71,6 @@
       "vr_web_contents_observer.h",
     ]
 
-    if (enable_vr_shell_ui_dev) {
-      defines += [ "ENABLE_VR_SHELL_UI_DEV" ]
-    }
-
     deps = [
       ":vr_shell_jni_headers",
       "//base",
diff --git a/chrome/browser/android/vr_shell/animation.h b/chrome/browser/android/vr_shell/animation.h
index 084f4582..db062bbc 100644
--- a/chrome/browser/android/vr_shell/animation.h
+++ b/chrome/browser/android/vr_shell/animation.h
@@ -23,8 +23,7 @@
 class Animation {
  public:
   enum Property {
-    COPYRECT = 0,
-    SIZE,
+    SIZE = 0,
     TRANSLATION,
     SCALE,
     ROTATION,
diff --git a/chrome/browser/android/vr_shell/ui_element.cc b/chrome/browser/android/vr_shell/ui_element.cc
index f38fb7a..8b8c25a3 100644
--- a/chrome/browser/android/vr_shell/ui_element.cc
+++ b/chrome/browser/android/vr_shell/ui_element.cc
@@ -114,12 +114,6 @@
     // If |from| is not specified, start at the current values.
     if (animation.from.size() == 0) {
       switch (animation.property) {
-        case Animation::COPYRECT:
-          animation.from.push_back(copy_rect.x());
-          animation.from.push_back(copy_rect.y());
-          animation.from.push_back(copy_rect.width());
-          animation.from.push_back(copy_rect.height());
-          break;
         case Animation::SIZE:
           animation.from.push_back(size.x());
           animation.from.push_back(size.y());
@@ -161,10 +155,6 @@
           animation.from[i] + (value * (animation.to[i] - animation.from[i]));
     }
     switch (animation.property) {
-      case Animation::COPYRECT:
-        CHECK_EQ(animation.from.size(), 4u);
-        copy_rect.SetRect(values[0], values[1], values[2], values[3]);
-        break;
       case Animation::SIZE:
         CHECK_EQ(animation.from.size(), 2u);
         size.set_x(values[0]);
diff --git a/chrome/browser/android/vr_shell/ui_element.h b/chrome/browser/android/vr_shell/ui_element.h
index 796c1f9..3f40974 100644
--- a/chrome/browser/android/vr_shell/ui_element.h
+++ b/chrome/browser/android/vr_shell/ui_element.h
@@ -34,9 +34,7 @@
 
 enum Fill {
   NONE = 0,
-  // The element is filled with part of the HTML UI as specified by the copy
-  // rect.
-  SPRITE = 1,
+  SKIA = 1,
   // The element is filled with a radial gradient as specified by the edge and
   // center color.
   OPAQUE_GRADIENT = 2,
@@ -118,9 +116,6 @@
   // rather than the world.
   bool lock_to_fov = false;
 
-  // Specifies the region (in pixels) of a texture to render.
-  gfx::Rect copy_rect = {0, 0, 0, 0};
-
   // The size of the object.  This does not affect children.
   gfx::Vector3dF size = {1.0f, 1.0f, 1.0f};
 
diff --git a/chrome/browser/android/vr_shell/ui_element_unittest.cc b/chrome/browser/android/vr_shell/ui_element_unittest.cc
index db5cfe5b9..f9eda14 100644
--- a/chrome/browser/android/vr_shell/ui_element_unittest.cc
+++ b/chrome/browser/android/vr_shell/ui_element_unittest.cc
@@ -43,20 +43,6 @@
 
 }  // namespace
 
-TEST(UiElements, AnimateCopyRect) {
-  UiElement rect;
-  rect.copy_rect = {10, 100, 1000, 10000};
-  std::unique_ptr<Animation> animation(new Animation(
-      0, Animation::Property::COPYRECT,
-      std::unique_ptr<easing::Easing>(new easing::Linear()), {},
-      {20, 200, 2000, 20000}, usToTicks(50000), usToDelta(10000)));
-  rect.animations.emplace_back(std::move(animation));
-  rect.Animate(usToTicks(50000));
-  EXPECT_RECTF_EQ(rect.copy_rect, gfx::RectF(10, 100, 1000, 10000));
-  rect.Animate(usToTicks(60000));
-  EXPECT_RECTF_EQ(rect.copy_rect, gfx::RectF(20, 200, 2000, 20000));
-}
-
 TEST(UiElements, AnimateSize) {
   UiElement rect;
   rect.size = {10, 100, 1};
diff --git a/chrome/browser/android/vr_shell/ui_interface.cc b/chrome/browser/android/vr_shell/ui_interface.cc
index 3eee6f2..fed51cac 100644
--- a/chrome/browser/android/vr_shell/ui_interface.cc
+++ b/chrome/browser/android/vr_shell/ui_interface.cc
@@ -4,146 +4,47 @@
 
 #include "chrome/browser/android/vr_shell/ui_interface.h"
 
-#include <memory>
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "chrome/browser/android/vr_shell/vr_omnibox.h"
-#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h"
 #include "url/gurl.h"
 
 namespace vr_shell {
 
-UiInterface::UiInterface(Mode initial_mode)
-    : omnibox_(base::MakeUnique<VrOmnibox>(this)) {
-  SetMode(initial_mode);
-}
-
-UiInterface::~UiInterface() {}
+UiInterface::UiInterface(Mode initial_mode) : mode_(initial_mode) {}
 
 void UiInterface::SetMode(Mode mode) {
   mode_ = mode;
-  FlushModeState();
 }
 
 void UiInterface::SetFullscreen(bool enabled) {
   fullscreen_ = enabled;
-  FlushModeState();
 }
 
-void UiInterface::HandleOmniboxInput(const base::DictionaryValue& input) {
-  omnibox_->HandleInput(input);
-}
+void UiInterface::SetSecurityLevel(int level) {}
 
-void UiInterface::SetOmniboxSuggestions(
-    std::unique_ptr<base::Value> suggestions) {
-  updates_.Set("suggestions", std::move(suggestions));
-  FlushUpdates();
-}
+void UiInterface::SetWebVRSecureOrigin(bool secure) {}
 
-void UiInterface::FlushModeState() {
-  updates_.SetInteger("mode", static_cast<int>(mode_));
-  updates_.SetBoolean("fullscreen", fullscreen_);
-  FlushUpdates();
-}
+void UiInterface::SetLoading(bool loading) {}
 
-void UiInterface::SetSecurityLevel(int level) {
-  updates_.SetInteger("securityLevel", level);
-  FlushUpdates();
-}
+void UiInterface::SetLoadProgress(double progress) {}
 
-void UiInterface::SetWebVRSecureOrigin(bool secure) {
-  updates_.SetBoolean("webVRSecureOrigin", secure);
-  FlushUpdates();
-}
-
-void UiInterface::SetLoading(bool loading) {
-  updates_.SetBoolean("loading", loading);
-  FlushUpdates();
-}
-
-void UiInterface::SetLoadProgress(double progress) {
-  updates_.SetDouble("loadProgress", progress);
-  FlushUpdates();
-}
-
-void UiInterface::InitTabList() {
-  tab_list_ = base::MakeUnique<base::ListValue>();
-}
+void UiInterface::InitTabList() {}
 
 void UiInterface::AppendToTabList(bool incognito,
                                   int id,
-                                  const base::string16& title) {
-  auto dict = base::MakeUnique<base::DictionaryValue>();
-  dict->SetBoolean("incognito", incognito);
-  dict->SetInteger("id", id);
-  dict->SetString("title", title);
-  tab_list_->Append(std::move(dict));
-}
+                                  const base::string16& title) {}
 
-void UiInterface::FlushTabList() {
-  updates_.Set("setTabs", std::move(tab_list_));
-  FlushUpdates();
-}
+void UiInterface::UpdateTab(bool incognito, int id, const std::string& title) {}
 
-void UiInterface::UpdateTab(bool incognito, int id, const std::string& title) {
-  auto details = base::MakeUnique<base::DictionaryValue>();
-  details->SetBoolean("incognito", incognito);
-  details->SetInteger("id", id);
-  details->SetString("title", title);
-  updates_.Set("updateTab", std::move(details));
-}
+void UiInterface::FlushTabList() {}
 
-void UiInterface::RemoveTab(bool incognito, int id) {
-  auto details = base::MakeUnique<base::DictionaryValue>();
-  details->SetBoolean("incognito", incognito);
-  details->SetInteger("id", id);
-  updates_.Set("removeTab", std::move(details));
-}
+void UiInterface::RemoveTab(bool incognito, int id) {}
 
-void UiInterface::SetURL(const GURL& url) {
-  auto details = base::MakeUnique<base::DictionaryValue>();
-  details->SetString("host", url.host());
-  details->SetString("path", url.path());
+void UiInterface::SetURL(const GURL& url) {}
 
-  updates_.Set("url", std::move(details));
-  FlushUpdates();
-}
+void UiInterface::HandleAppButtonGesturePerformed(Direction direction) {}
 
-void UiInterface::HandleAppButtonGesturePerformed(Direction direction) {
-  updates_.SetInteger("appButtonGesturePerformed", direction);
-  FlushUpdates();
-}
-
-void UiInterface::HandleAppButtonClicked() {
-  updates_.SetBoolean("appButtonClicked", true);
-  FlushUpdates();
-}
+void UiInterface::HandleAppButtonClicked() {}
 
 void UiInterface::SetHistoryButtonsEnabled(bool can_go_back,
-                                           bool can_go_forward) {
-  updates_.SetBoolean("canGoBack", can_go_back);
-  updates_.SetBoolean("canGoForward", can_go_forward);
-  FlushUpdates();
-}
-
-void UiInterface::OnDomContentsLoaded() {
-  loaded_ = true;
-#if defined(ENABLE_VR_SHELL_UI_DEV)
-  updates_.SetBoolean("enableReloadUi", true);
-#endif
-  FlushUpdates();
-}
-
-void UiInterface::SetUiCommandHandler(UiCommandHandler* handler) {
-  handler_ = handler;
-}
-
-void UiInterface::FlushUpdates() {
-  if (loaded_ && handler_) {
-    handler_->SendCommandToUi(updates_);
-    updates_.Clear();
-  }
-}
+                                           bool can_go_forward) {}
 
 }  // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_interface.h b/chrome/browser/android/vr_shell/ui_interface.h
index 3039009a..10e2cc81 100644
--- a/chrome/browser/android/vr_shell/ui_interface.h
+++ b/chrome/browser/android/vr_shell/ui_interface.h
@@ -15,13 +15,6 @@
 
 namespace vr_shell {
 
-class VrOmnibox;
-
-class UiCommandHandler {
- public:
-  virtual void SendCommandToUi(const base::Value& value) = 0;
-};
-
 // This class manages the communication of browser state from VR shell to the
 // HTML UI. State information is asynchronous and unidirectional.
 class UiInterface {
@@ -40,7 +33,7 @@
   };
 
   explicit UiInterface(Mode initial_mode);
-  virtual ~UiInterface();
+  virtual ~UiInterface() = default;
 
   // Set HTML UI state or pass events.
   void SetMode(Mode mode);
@@ -55,29 +48,13 @@
   void UpdateTab(bool incognito, int id, const std::string& title);
   void RemoveTab(bool incognito, int id);
   void SetURL(const GURL& url);
-  void SetOmniboxSuggestions(std::unique_ptr<base::Value> suggestions);
   void HandleAppButtonGesturePerformed(Direction direction);
   void HandleAppButtonClicked();
   void SetHistoryButtonsEnabled(bool can_go_back, bool can_go_forward);
 
-  // Handlers for HTML UI commands and notifications.
-  void OnDomContentsLoaded();
-  void HandleOmniboxInput(const base::DictionaryValue& input);
-
-  void SetUiCommandHandler(UiCommandHandler* handler);
-
  private:
-  void FlushUpdates();
-  void FlushModeState();
-
   Mode mode_;
   bool fullscreen_ = false;
-  UiCommandHandler* handler_;
-  bool loaded_ = false;
-  base::DictionaryValue updates_;
-  std::unique_ptr<base::ListValue> tab_list_;
-
-  std::unique_ptr<VrOmnibox> omnibox_;
 
   DISALLOW_COPY_AND_ASSIGN(UiInterface);
 };
diff --git a/chrome/browser/android/vr_shell/ui_scene.cc b/chrome/browser/android/vr_shell/ui_scene.cc
index d953856..9982c98 100644
--- a/chrome/browser/android/vr_shell/ui_scene.cc
+++ b/chrome/browser/android/vr_shell/ui_scene.cc
@@ -19,129 +19,6 @@
 
 namespace {
 
-// Parse an integer to an int or enum value.
-template <typename T>
-bool ParseInt(const base::DictionaryValue& dict,
-              const std::string& key,
-              T* output) {
-  int value;
-  if (!dict.GetInteger(key, &value)) {
-    return false;
-  }
-  *output = static_cast<T>(value);
-  return true;
-}
-
-// Parse a floating point number to a float or double.
-template <typename T>
-bool ParseFloat(const base::DictionaryValue& dict,
-                const std::string& key,
-                T* output) {
-  double value;
-  if (!dict.GetDouble(key, &value)) {
-    return false;
-  }
-  *output = value;
-  return true;
-}
-
-bool ParseColorf(const base::DictionaryValue& dict,
-                 const std::string& key,
-                 vr::Colorf* output) {
-  const base::DictionaryValue* item_dict;
-  if (dict.GetDictionary(key, &item_dict)) {
-    double value;
-    CHECK(item_dict->GetDouble("r", &value));
-    output->r = value;
-    CHECK(item_dict->GetDouble("g", &value));
-    output->g = value;
-    CHECK(item_dict->GetDouble("b", &value));
-    output->b = value;
-    CHECK(item_dict->GetDouble("a", &value));
-    output->a = value;
-    return true;
-  } else {
-    return false;
-  }
-}
-
-void ParseFloats(const base::DictionaryValue& dict,
-                 const std::vector<std::string>& keys,
-                 std::vector<float>* vec) {
-  for (const auto& key : keys) {
-    double value;
-    CHECK(dict.GetDouble(key, &value)) << "parsing tag " << key;
-    vec->push_back(value);
-  }
-}
-
-bool ParseEndpointToFloats(Animation::Property property,
-                           const base::DictionaryValue& dict,
-                           std::vector<float>* vec) {
-  switch (property) {
-    case Animation::Property::COPYRECT:
-      ParseFloats(dict, {"x", "y", "width", "height"}, vec);
-      return true;
-    case Animation::Property::SIZE:
-      ParseFloats(dict, {"x", "y"}, vec);
-      return true;
-    case Animation::Property::SCALE:
-      ParseFloats(dict, {"x", "y", "z"}, vec);
-      return true;
-    case Animation::Property::ROTATION:
-      ParseFloats(dict, {"x", "y", "z", "a"}, vec);
-      return true;
-    case Animation::Property::TRANSLATION:
-      ParseFloats(dict, {"x", "y", "z"}, vec);
-      return true;
-    case Animation::Property::OPACITY:
-      ParseFloats(dict, {"x"}, vec);
-      return true;
-  }
-  return false;
-}
-
-std::unique_ptr<easing::Easing> ParseEasing(const base::DictionaryValue& dict) {
-  easing::EasingType easingType;
-  CHECK(ParseInt(dict, "type", &easingType));
-  std::unique_ptr<easing::Easing> result;
-
-  switch (easingType) {
-    case easing::EasingType::LINEAR: {
-      result = base::MakeUnique<easing::Linear>();
-      break;
-    }
-    case easing::EasingType::CUBICBEZIER: {
-      double p1x, p1y, p2x, p2y;
-      CHECK(dict.GetDouble("p1x", &p1x));
-      CHECK(dict.GetDouble("p1y", &p1y));
-      CHECK(dict.GetDouble("p2x", &p2x));
-      CHECK(dict.GetDouble("p2y", &p2y));
-      result = base::MakeUnique<easing::CubicBezier>(p1x, p1y, p2x, p2y);
-      break;
-    }
-    case easing::EasingType::EASEIN: {
-      double pow;
-      CHECK(dict.GetDouble("pow", &pow));
-      result = base::MakeUnique<easing::EaseIn>(pow);
-      break;
-    }
-    case easing::EasingType::EASEOUT: {
-      double pow;
-      CHECK(dict.GetDouble("pow", &pow));
-      result = base::MakeUnique<easing::EaseOut>(pow);
-      break;
-    }
-    case easing::EasingType::EASEINOUT: {
-      double pow;
-      CHECK(dict.GetDouble("pow", &pow));
-      result = base::MakeUnique<easing::EaseInOut>(pow);
-      break;
-    }
-  }
-  return result;
-}
-
 void ApplyAnchoring(const UiElement& parent,
                     XAnchoring x_anchoring,
                     YAnchoring y_anchoring,
@@ -188,26 +65,6 @@
   ui_elements_.push_back(std::move(element));
 }
 
-void UiScene::AddUiElementFromDict(const base::DictionaryValue& dict) {
-  int id;
-  CHECK(ParseInt(dict, "id", &id));
-  CHECK_EQ(GetUiElementById(id), nullptr);
-
-  auto element = base::MakeUnique<UiElement>();
-  element->id = id;
-
-  ApplyDictToElement(dict, element.get());
-  ui_elements_.push_back(std::move(element));
-}
-
-void UiScene::UpdateUiElementFromDict(const base::DictionaryValue& dict) {
-  int id;
-  CHECK(ParseInt(dict, "id", &id));
-  UiElement* element = GetUiElementById(id);
-  CHECK_NE(element, nullptr);
-  ApplyDictToElement(dict, element);
-}
-
 void UiScene::RemoveUiElement(int element_id) {
   for (auto it = ui_elements_.begin(); it != ui_elements_.end(); ++it) {
     if ((*it)->id == element_id) {
@@ -230,50 +87,6 @@
   element->animations.emplace_back(std::move(animation));
 }
 
-void UiScene::AddAnimationFromDict(const base::DictionaryValue& dict,
-                                   const base::TimeTicks& current_time) {
-  int animation_id;
-  int element_id;
-  Animation::Property property;
-  double start_time_ms;
-  double duration_ms;
-
-  const base::DictionaryValue* easing_dict = nullptr;
-  const base::DictionaryValue* from_dict = nullptr;
-  const base::DictionaryValue* to_dict = nullptr;
-  std::vector<float> from;
-  std::vector<float> to;
-
-  CHECK(ParseInt(dict, "id", &animation_id));
-  CHECK(ParseInt(dict, "meshId", &element_id));
-  CHECK(ParseInt(dict, "property", &property));
-  CHECK(ParseFloat(dict, "startInMillis", &start_time_ms));
-  CHECK(ParseFloat(dict, "durationMillis", &duration_ms));
-
-  CHECK(dict.GetDictionary("easing", &easing_dict));
-  auto easing = ParseEasing(*easing_dict);
-
-  CHECK(dict.GetDictionary("to", &to_dict));
-  ParseEndpointToFloats(property, *to_dict, &to);
-
-  // The start location is optional.  If not specified, the animation will
-  // start from the element's current location.
-  dict.GetDictionary("from", &from_dict);
-  if (from_dict != nullptr) {
-    ParseEndpointToFloats(property, *from_dict, &from);
-  }
-
-  base::TimeDelta delay = base::TimeDelta::FromMilliseconds(start_time_ms);
-  base::TimeTicks start = current_time + delay;
-  base::TimeDelta duration = base::TimeDelta::FromMilliseconds(duration_ms);
-
-  UiElement* element = GetUiElementById(element_id);
-  CHECK_NE(element, nullptr);
-  element->animations.emplace_back(base::MakeUnique<Animation>(
-      animation_id, static_cast<Animation::Property>(property),
-      std::move(easing), from, to, start, duration));
-}
-
 void UiScene::RemoveAnimation(int element_id, int animation_id) {
   UiElement* element = GetUiElementById(element_id);
   CHECK_NE(element, nullptr);
@@ -287,49 +100,6 @@
   }
 }
 
-void UiScene::HandleCommands(std::unique_ptr<base::ListValue> commands,
-                             const base::TimeTicks& time) {
-  for (auto& item : *commands) {
-    base::DictionaryValue* dict;
-    CHECK(item.GetAsDictionary(&dict));
-
-    Command type;
-    base::DictionaryValue* data;
-    CHECK(ParseInt(*dict, "type", &type));
-    CHECK(dict->GetDictionary("data", &data));
-
-    switch (type) {
-      case Command::ADD_ELEMENT:
-        AddUiElementFromDict(*data);
-        break;
-      case Command::UPDATE_ELEMENT:
-        UpdateUiElementFromDict(*data);
-        break;
-      case Command::REMOVE_ELEMENT: {
-        int element_id;
-        CHECK(ParseInt(*data, "id", &element_id));
-        RemoveUiElement(element_id);
-        break;
-      }
-      case Command::ADD_ANIMATION:
-        AddAnimationFromDict(*data, time);
-        break;
-      case Command::REMOVE_ANIMATION: {
-        int element_id, animation_id;
-        CHECK(ParseInt(*data, "id", &animation_id));
-        CHECK(ParseInt(*data, "meshId", &element_id));
-        RemoveAnimation(element_id, animation_id);
-        break;
-      }
-      case Command::CONFIGURE_SCENE:
-        ParseColorf(*data, "backgroundColor", &background_color_);
-        ParseFloat(*data, "backgroundDistance", &background_distance_);
-        data->GetBoolean("drawWebVr", &webvr_rendering_enabled_);
-        break;
-    }
-  }
-}
-
 void UiScene::UpdateTransforms(const base::TimeTicks& time) {
   for (auto& element : ui_elements_) {
     // Process all animations before calculating object transforms.
@@ -433,92 +203,4 @@
   element->dirty = false;
 }
 
-void UiScene::ApplyDictToElement(const base::DictionaryValue& dict,
-                                 UiElement* element) {
-  int parent_id;
-
-  if (ParseInt(dict, "parentId", &parent_id)) {
-    CHECK_GE(parent_id, 0);
-    CHECK_NE(GetUiElementById(parent_id), nullptr);
-    element->parent_id = parent_id;
-  }
-
-  dict.GetString("name", &element->name);
-  dict.GetBoolean("visible", &element->visible);
-  dict.GetBoolean("hitTestable", &element->hit_testable);
-  dict.GetBoolean("lockToFov", &element->lock_to_fov);
-  ParseInt(dict, "drawPhase", &element->draw_phase);
-  ParseFloat(dict, "opacity", &element->opacity);
-
-  DCHECK(!(element->lock_to_fov && element->parent_id != -1));
-  float val;
-  if (ParseFloat(dict, "sizeX", &val))
-    element->size.set_x(val);
-  if (ParseFloat(dict, "sizeY", &val))
-    element->size.set_y(val);
-  if (ParseFloat(dict, "scaleX", &val))
-    element->scale.set_x(val);
-  if (ParseFloat(dict, "scaleY", &val))
-    element->scale.set_y(val);
-  if (ParseFloat(dict, "scaleZ", &val))
-    element->scale.set_z(val);
-  if (ParseFloat(dict, "translationX", &val))
-    element->translation.set_x(val);
-  if (ParseFloat(dict, "translationY", &val))
-    element->translation.set_y(val);
-  if (ParseFloat(dict, "translationZ", &val))
-    element->translation.set_z(val);
-  ParseFloat(dict, "rotationX", &element->rotation.x);
-  ParseFloat(dict, "rotationY", &element->rotation.y);
-  ParseFloat(dict, "rotationZ", &element->rotation.z);
-  ParseFloat(dict, "rotationAngle", &element->rotation.angle);
-
-  if (ParseInt(dict, "xAnchoring", &element->x_anchoring)) {
-    CHECK_GE(element->parent_id, 0);
-  }
-  if (ParseInt(dict, "yAnchoring", &element->y_anchoring)) {
-    CHECK_GE(element->parent_id, 0);
-  }
-
-  // Parse the element fill.
-  if (ParseInt(dict, "fillType", &element->fill)) {
-    // If the previous content element has a new filling now make sure this is
-    // tracked correctly.
-    if (content_element_ == element && element->fill != Fill::CONTENT) {
-      content_element_ = nullptr;
-    }
-
-    int val;
-    switch (element->fill) {
-      case Fill::SPRITE:
-        CHECK(ParseInt(dict, "copyRectX", &val));
-        element->copy_rect.set_x(val);
-        CHECK(ParseInt(dict, "copyRectY", &val));
-        element->copy_rect.set_y(val);
-        CHECK(ParseInt(dict, "copyRectWidth", &val));
-        element->copy_rect.set_width(val);
-        CHECK(ParseInt(dict, "copyRectHeight", &val));
-        element->copy_rect.set_height(val);
-        break;
-      case Fill::OPAQUE_GRADIENT:
-        CHECK(ParseColorf(dict, "edgeColor", &element->edge_color));
-        CHECK(ParseColorf(dict, "centerColor", &element->center_color));
-        break;
-      case Fill::GRID_GRADIENT:
-        CHECK(ParseColorf(dict, "edgeColor", &element->edge_color));
-        CHECK(ParseColorf(dict, "centerColor", &element->center_color));
-        CHECK(ParseInt(dict, "gridlineCount", &element->gridline_count));
-        CHECK_GE(element->gridline_count, 0);
-        break;
-      case Fill::CONTENT:
-        CHECK_EQ(content_element_, nullptr);
-        content_element_ = element;
-        break;
-      default:
-        element->fill = Fill::NONE;
-        break;
-    }
-  }
-}
-
 }  // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/ui_scene.h b/chrome/browser/android/vr_shell/ui_scene.h
index 2308740..9ab39b6 100644
--- a/chrome/browser/android/vr_shell/ui_scene.h
+++ b/chrome/browser/android/vr_shell/ui_scene.h
@@ -12,7 +12,6 @@
 #include "device/vr/vr_types.h"
 
 namespace base {
-class DictionaryValue;
 class ListValue;
 class TimeTicks;
 }
@@ -38,21 +37,11 @@
 
   void AddUiElement(std::unique_ptr<UiElement> element);
 
-  // Add a UI element according to a dictionary passed from the UI HTML.
-  void AddUiElementFromDict(const base::DictionaryValue& dict);
-
-  // Update an existing element with new properties.
-  void UpdateUiElementFromDict(const base::DictionaryValue& dict);
-
   void RemoveUiElement(int element_id);
 
   // Add an animation to the scene, on element |element_id|.
   void AddAnimation(int element_id, std::unique_ptr<Animation> animation);
 
-  // Add an animation according to a dictionary passed from the UI HTML.
-  void AddAnimationFromDict(const base::DictionaryValue& dict,
-                            const base::TimeTicks& current_time);
-
   // Remove |animation_id| from element |element_id|.
   void RemoveAnimation(int element_id, int animation_id);
 
@@ -79,8 +68,6 @@
 
  private:
   void ApplyRecursiveTransforms(UiElement* element);
-  void ApplyDictToElement(const base::DictionaryValue& dict,
-                          UiElement* element);
 
   std::vector<std::unique_ptr<UiElement>> ui_elements_;
   UiElement* content_element_ = nullptr;
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.cc b/chrome/browser/android/vr_shell/ui_scene_manager.cc
index 915f86b..dfd3fa6e 100644
--- a/chrome/browser/android/vr_shell/ui_scene_manager.cc
+++ b/chrome/browser/android/vr_shell/ui_scene_manager.cc
@@ -70,10 +70,6 @@
   return weak_ptr_factory_.GetWeakPtr();
 }
 
-void UiSceneManager::UpdateScene(std::unique_ptr<base::ListValue> commands) {
-  scene_->HandleCommands(std::move(commands), base::TimeTicks::Now());
-}
-
 void UiSceneManager::SetWebVRMode(bool web_vr) {
   web_vr_mode_ = web_vr;
   ConfigureSecurityWarnings();
diff --git a/chrome/browser/android/vr_shell/ui_scene_manager.h b/chrome/browser/android/vr_shell/ui_scene_manager.h
index df979c4..529d047 100644
--- a/chrome/browser/android/vr_shell/ui_scene_manager.h
+++ b/chrome/browser/android/vr_shell/ui_scene_manager.h
@@ -22,8 +22,6 @@
 
   base::WeakPtr<UiSceneManager> GetWeakPtr();
 
-  void UpdateScene(std::unique_ptr<base::ListValue> commands);
-
   void SetWebVRSecureOrigin(bool secure);
   void SetWebVRMode(bool web_vr);
 
diff --git a/chrome/browser/android/vr_shell/ui_scene_unittest.cc b/chrome/browser/android/vr_shell/ui_scene_unittest.cc
index 9498f85..e57e543 100644
--- a/chrome/browser/android/vr_shell/ui_scene_unittest.cc
+++ b/chrome/browser/android/vr_shell/ui_scene_unittest.cc
@@ -228,227 +228,4 @@
                         AnchoringTest,
                         ::testing::ValuesIn(anchoring_test_cases));
 
-TEST(UiScene, AddUiElementFromDictionary) {
-  UiScene scene;
-  addElement(&scene, 11);
-
-  base::DictionaryValue dict;
-
-  dict.SetInteger("id", 10);
-  dict.SetString("name", "abc");
-  dict.SetInteger("parentId", 11);
-  dict.SetBoolean("visible", false);
-  dict.SetBoolean("hitTestable", false);
-  dict.SetInteger("fillType", Fill::SPRITE);
-  dict.SetInteger("xAnchoring", XAnchoring::XLEFT);
-  dict.SetInteger("yAnchoring", YAnchoring::YTOP);
-  dict.SetDouble("opacity", 0.357);
-
-  dict.SetInteger("copyRectX", 100);
-  dict.SetInteger("copyRectY", 101);
-  dict.SetInteger("copyRectWidth", 102);
-  dict.SetInteger("copyRectHeight", 103);
-
-  dict.SetDouble("sizeX", 200);
-  dict.SetDouble("sizeY", 201);
-
-  dict.SetDouble("scaleX", 300);
-  dict.SetDouble("scaleY", 301);
-  dict.SetDouble("scaleZ", 302);
-
-  dict.SetDouble("rotationX", 400);
-  dict.SetDouble("rotationY", 401);
-  dict.SetDouble("rotationZ", 402);
-  dict.SetDouble("rotationAngle", 403);
-
-  dict.SetDouble("translationX", 500);
-  dict.SetDouble("translationY", 501);
-  dict.SetDouble("translationZ", 502);
-
-  scene.AddUiElementFromDict(dict);
-  const auto* element = scene.GetUiElementById(10);
-  EXPECT_NE(element, nullptr);
-
-  EXPECT_EQ(element->id, 10);
-  EXPECT_EQ(element->name, "abc");
-  EXPECT_EQ(element->parent_id, 11);
-  EXPECT_EQ(element->visible, false);
-  EXPECT_EQ(element->hit_testable, false);
-  EXPECT_EQ(element->fill, Fill::SPRITE);
-  EXPECT_EQ(element->x_anchoring, XAnchoring::XLEFT);
-  EXPECT_EQ(element->y_anchoring, YAnchoring::YTOP);
-  EXPECT_FLOAT_EQ(element->opacity, 0.357);
-
-  EXPECT_EQ(element->copy_rect.x(), 100);
-  EXPECT_EQ(element->copy_rect.y(), 101);
-  EXPECT_EQ(element->copy_rect.width(), 102);
-  EXPECT_EQ(element->copy_rect.height(), 103);
-
-  EXPECT_FLOAT_EQ(element->size.x(), 200);
-  EXPECT_FLOAT_EQ(element->size.y(), 201);
-  EXPECT_FLOAT_EQ(element->size.z(), 1);
-
-  EXPECT_FLOAT_EQ(element->scale.x(), 300);
-  EXPECT_FLOAT_EQ(element->scale.y(), 301);
-  EXPECT_FLOAT_EQ(element->scale.z(), 302);
-
-  EXPECT_FLOAT_EQ(element->rotation.x, 400);
-  EXPECT_FLOAT_EQ(element->rotation.y, 401);
-  EXPECT_FLOAT_EQ(element->rotation.z, 402);
-  EXPECT_FLOAT_EQ(element->rotation.angle, 403);
-
-  EXPECT_FLOAT_EQ(element->translation.x(), 500);
-  EXPECT_FLOAT_EQ(element->translation.y(), 501);
-  EXPECT_FLOAT_EQ(element->translation.z(), 502);
-
-  dict.Clear();
-  dict.SetInteger("id", 12);
-  dict.SetBoolean("lockToFov", true);
-
-  scene.AddUiElementFromDict(dict);
-  element = scene.GetUiElementById(12);
-  EXPECT_NE(element, nullptr);
-
-  EXPECT_EQ(element->id, 12);
-  EXPECT_EQ(element->lock_to_fov, true);
-}
-
-TEST(UiScene, AddUiElementFromDictionary_Fill) {
-  UiScene scene;
-  base::DictionaryValue dict;
-
-  dict.SetInteger("copyRectX", 1);
-  dict.SetInteger("copyRectY", 2);
-  dict.SetInteger("copyRectWidth", 3);
-  dict.SetInteger("copyRectHeight", 4);
-
-  base::DictionaryValue edge_color;
-  edge_color.SetDouble("r", 0.1);
-  edge_color.SetDouble("g", 0.2);
-  edge_color.SetDouble("b", 0.3);
-  edge_color.SetDouble("a", 0.4);
-
-  base::DictionaryValue center_color;
-  center_color.SetDouble("r", 0.5);
-  center_color.SetDouble("g", 0.6);
-  center_color.SetDouble("b", 0.7);
-  center_color.SetDouble("a", 0.8);
-
-  // Test SPRITE filling.
-  dict.SetInteger("id", 9);
-  dict.SetInteger("fillType", Fill::SPRITE);
-  scene.AddUiElementFromDict(dict);
-  const auto* element = scene.GetUiElementById(9);
-
-  EXPECT_EQ(element->fill, Fill::SPRITE);
-  EXPECT_EQ(element->copy_rect.x(), 1);
-  EXPECT_EQ(element->copy_rect.y(), 2);
-  EXPECT_EQ(element->copy_rect.width(), 3);
-  EXPECT_EQ(element->copy_rect.height(), 4);
-
-  // Test OPAQUE_GRADIENT filling.
-  dict.Clear();
-  dict.SetInteger("id", 10);
-  dict.SetInteger("fillType", Fill::OPAQUE_GRADIENT);
-  dict.Set("edgeColor", edge_color.DeepCopy());
-  dict.Set("centerColor", center_color.DeepCopy());
-  scene.AddUiElementFromDict(dict);
-  element = scene.GetUiElementById(10);
-
-  EXPECT_EQ(element->fill, Fill::OPAQUE_GRADIENT);
-  EXPECT_FLOAT_EQ(element->edge_color.r, 0.1);
-  EXPECT_FLOAT_EQ(element->edge_color.g, 0.2);
-  EXPECT_FLOAT_EQ(element->edge_color.b, 0.3);
-  EXPECT_FLOAT_EQ(element->edge_color.a, 0.4);
-  EXPECT_FLOAT_EQ(element->center_color.r, 0.5);
-  EXPECT_FLOAT_EQ(element->center_color.g, 0.6);
-  EXPECT_FLOAT_EQ(element->center_color.b, 0.7);
-  EXPECT_FLOAT_EQ(element->center_color.a, 0.8);
-
-  // Test GRID_GRADIENT filling.
-  dict.Clear();
-  dict.SetInteger("id", 11);
-  dict.SetInteger("fillType", Fill::GRID_GRADIENT);
-  dict.Set("edgeColor", edge_color.DeepCopy());
-  dict.Set("centerColor", center_color.DeepCopy());
-  dict.SetInteger("gridlineCount", 10);
-  scene.AddUiElementFromDict(dict);
-  element = scene.GetUiElementById(11);
-
-  EXPECT_EQ(element->fill, Fill::GRID_GRADIENT);
-  EXPECT_FLOAT_EQ(element->edge_color.r, 0.1);
-  EXPECT_FLOAT_EQ(element->edge_color.g, 0.2);
-  EXPECT_FLOAT_EQ(element->edge_color.b, 0.3);
-  EXPECT_FLOAT_EQ(element->edge_color.a, 0.4);
-  EXPECT_FLOAT_EQ(element->center_color.r, 0.5);
-  EXPECT_FLOAT_EQ(element->center_color.g, 0.6);
-  EXPECT_FLOAT_EQ(element->center_color.b, 0.7);
-  EXPECT_FLOAT_EQ(element->center_color.a, 0.8);
-  EXPECT_EQ(element->gridline_count, 10);
-
-  // Test CONTENT filling.
-  dict.Clear();
-  dict.SetInteger("id", 12);
-  dict.SetInteger("fillType", Fill::CONTENT);
-  scene.AddUiElementFromDict(dict);
-  element = scene.GetUiElementById(12);
-
-  EXPECT_EQ(element->fill, Fill::CONTENT);
-}
-
-TEST(UiScene, AddAnimationFromDictionary) {
-  UiScene scene;
-  addElement(&scene, 0);
-
-  base::DictionaryValue dict;
-
-  dict.SetInteger("id", 10);
-  dict.SetInteger("meshId", 0);
-  dict.SetDouble("startInMillis", 12345);
-  dict.SetDouble("durationMillis", 54321);
-  dict.SetInteger("property", Animation::Property::ROTATION);
-
-  auto easing = base::MakeUnique<base::DictionaryValue>();
-  easing->SetInteger("type", vr_shell::easing::EasingType::CUBICBEZIER);
-  easing->SetInteger("p1x", 101);
-  easing->SetInteger("p1y", 101);
-  easing->SetInteger("p2x", 101);
-  easing->SetInteger("p2y", 101);
-  dict.Set("easing", std::move(easing));
-
-  auto to = base::MakeUnique<base::DictionaryValue>();
-  to->SetInteger("x", 200);
-  to->SetInteger("y", 201);
-  to->SetInteger("z", 202);
-  to->SetInteger("a", 203);
-  dict.Set("to", std::move(to));
-
-  auto from = base::MakeUnique<base::DictionaryValue>();
-  from->SetInteger("x", 300);
-  from->SetInteger("y", 301);
-  from->SetInteger("z", 302);
-  from->SetInteger("a", 303);
-  dict.Set("from", std::move(from));
-
-  scene.AddAnimationFromDict(dict, usToTicks(10000000));
-  const auto* element = scene.GetUiElementById(0);
-  const auto* animation = element->animations[0].get();
-  EXPECT_NE(animation, nullptr);
-
-  EXPECT_EQ(animation->id, 10);
-
-  EXPECT_FLOAT_EQ(200, animation->to[0]);
-  EXPECT_FLOAT_EQ(201, animation->to[1]);
-  EXPECT_FLOAT_EQ(202, animation->to[2]);
-  EXPECT_FLOAT_EQ(203, animation->to[3]);
-
-  EXPECT_FLOAT_EQ(300, animation->from[0]);
-  EXPECT_FLOAT_EQ(301, animation->from[1]);
-  EXPECT_FLOAT_EQ(302, animation->from[2]);
-  EXPECT_FLOAT_EQ(303, animation->from[3]);
-
-  EXPECT_EQ(usToTicks(22345000), animation->start);
-  EXPECT_EQ(usToDelta(54321000), animation->duration);
-}
-
 }  // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/vr_omnibox.cc b/chrome/browser/android/vr_shell/vr_omnibox.cc
deleted file mode 100644
index a76509d753..0000000
--- a/chrome/browser/android/vr_shell/vr_omnibox.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/vr_shell/vr_omnibox.h"
-
-#include <string>
-#include <utility>
-
-#include "base/strings/string16.h"
-#include "chrome/browser/android/vr_shell/ui_interface.h"
-#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "components/omnibox/browser/autocomplete_classifier.h"
-#include "components/omnibox/browser/autocomplete_controller.h"
-#include "components/omnibox/browser/autocomplete_input.h"
-
-namespace vr_shell {
-
-VrOmnibox::VrOmnibox(UiInterface* ui)
-    : ui_(ui),
-      profile_(ProfileManager::GetLastUsedProfile()),
-      autocomplete_controller_(base::MakeUnique<AutocompleteController>(
-          base::MakeUnique<ChromeAutocompleteProviderClient>(profile_),
-          this,
-          AutocompleteClassifier::DefaultOmniboxProviders())) {}
-
-VrOmnibox::~VrOmnibox() = default;
-
-void VrOmnibox::HandleInput(const base::DictionaryValue& dict) {
-  base::string16 text;
-  CHECK(dict.GetString("text", &text));
-
-  // TODO(crbug.com/683344): Scrub and appropriately tune these parameters.
-  GURL current_url;
-  size_t cursor_pos = base::string16::npos;
-  std::string desired_tld;
-  metrics::OmniboxEventProto::PageClassification page_classification =
-      metrics::OmniboxEventProto::OTHER;
-  bool prevent_inline_autocomplete = false;
-  bool prefer_keyword = false;
-  bool allow_exact_keyword_match = false;
-  bool want_asynchronous_matches = true;
-  bool from_omnibox_focus = false;
-
-  autocomplete_controller_->Start(AutocompleteInput(
-      text, cursor_pos, desired_tld, current_url, page_classification,
-      prevent_inline_autocomplete, prefer_keyword, allow_exact_keyword_match,
-      want_asynchronous_matches, from_omnibox_focus,
-      ChromeAutocompleteSchemeClassifier(profile_)));
-}
-
-void VrOmnibox::OnResultChanged(bool default_match_changed) {
-  const AutocompleteResult& result = autocomplete_controller_->result();
-  auto suggestions = base::MakeUnique<base::ListValue>();
-
-  for (const AutocompleteMatch& match : result) {
-    auto entry = base::MakeUnique<base::DictionaryValue>();
-    entry->SetString("description", match.contents);
-    entry->SetString("url", match.destination_url.spec());
-    suggestions->Append(std::move(entry));
-  }
-
-  ui_->SetOmniboxSuggestions(std::move(suggestions));
-}
-
-}  // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/vr_omnibox.h b/chrome/browser/android/vr_shell/vr_omnibox.h
deleted file mode 100644
index d4d058a7..0000000
--- a/chrome/browser/android/vr_shell/vr_omnibox.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_VR_SHELL_VR_OMNIBOX_H_
-#define CHROME_BROWSER_ANDROID_VR_SHELL_VR_OMNIBOX_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/values.h"
-#include "components/omnibox/browser/autocomplete_controller_delegate.h"
-
-class AutocompleteController;
-class Profile;
-
-namespace vr_shell {
-
-class UiInterface;
-
-class VrOmnibox : public AutocompleteControllerDelegate {
- public:
-  explicit VrOmnibox(UiInterface* ui);
-  ~VrOmnibox() override;
-
-  void HandleInput(const base::DictionaryValue& dict);
-
- private:
-  void OnResultChanged(bool default_match_changed) override;
-
-  UiInterface* ui_;
-
-  Profile* profile_;
-  std::unique_ptr<AutocompleteController> autocomplete_controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(VrOmnibox);
-};
-
-}  // namespace vr_shell
-
-#endif  // CHROME_BROWSER_ANDROID_VR_SHELL_VR_OMNIBOX_H_
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 76a7142..224ea19 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -61,8 +61,6 @@
 namespace {
 vr_shell::VrShell* g_instance;
 
-static const char kVrShellUIURL[] = "chrome://vr-shell-ui";
-
 void SetIsInVR(content::WebContents* contents, bool is_in_vr) {
   if (contents && contents->GetRenderWidgetHostView())
     contents->GetRenderWidgetHostView()->SetIsInVR(is_in_vr);
@@ -83,20 +81,14 @@
 
 VrShell::VrShell(JNIEnv* env,
                  jobject obj,
-                 ui::WindowAndroid* content_window,
-                 content::WebContents* ui_contents,
-                 ui::WindowAndroid* ui_window,
+                 ui::WindowAndroid* window,
                  bool for_web_vr,
                  VrShellDelegate* delegate,
                  gvr_context* gvr_api,
                  bool reprojected_rendering)
-    : WebContentsObserver(ui_contents),
-      vr_shell_enabled_(base::FeatureList::IsEnabled(features::kVrShell)),
-      content_window_(content_window),
-      content_compositor_(
-          base::MakeUnique<VrCompositor>(content_window_, false)),
-      ui_contents_(ui_contents),
-      ui_compositor_(base::MakeUnique<VrCompositor>(ui_window, true)),
+    : vr_shell_enabled_(base::FeatureList::IsEnabled(features::kVrShell)),
+      window_(window),
+      compositor_(base::MakeUnique<VrCompositor>(window_, false)),
       delegate_provider_(delegate),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       reprojected_rendering_(reprojected_rendering),
@@ -107,9 +99,6 @@
   g_instance = this;
   j_vr_shell_.Reset(env, obj);
 
-  ui_input_manager_ = base::MakeUnique<VrInputManager>(ui_contents_);
-  ui_compositor_->SetLayer(ui_contents_);
-
   gl_thread_ = base::MakeUnique<VrGLThread>(weak_ptr_factory_.GetWeakPtr(),
                                             main_thread_task_runner_, gvr_api,
                                             for_web_vr, reprojected_rendering_);
@@ -118,8 +107,8 @@
   options.priority = base::ThreadPriority::DISPLAY;
   gl_thread_->StartWithOptions(options);
 
-  html_interface_ = base::MakeUnique<UiInterface>(
-      for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD);
+  ui_ = base::MakeUnique<UiInterface>(for_web_vr ? UiInterface::Mode::WEB_VR
+                                                 : UiInterface::Mode::STANDARD);
 
   content::BrowserThread::PostTask(
       content::BrowserThread::FILE, FROM_HERE,
@@ -138,57 +127,50 @@
     const JavaParamRef<jobject>& touch_event_synthesizer) {
   content::WebContents* contents =
       content::WebContents::FromJavaWebContents(web_contents);
-  if (contents == main_contents_ &&
+  if (contents == web_contents_ &&
       touch_event_synthesizer.obj() == j_motion_event_synthesizer_.obj())
     return;
 
-  SetIsInVR(main_contents_, false);
+  SetIsInVR(web_contents_, false);
   j_motion_event_synthesizer_.Reset(env, touch_event_synthesizer);
-  main_contents_ = contents;
-  content_compositor_->SetLayer(main_contents_);
-  SetIsInVR(main_contents_, true);
+  web_contents_ = contents;
+  compositor_->SetLayer(web_contents_);
+  SetIsInVR(web_contents_, true);
   ContentFrameWasResized(false /* unused */);
   SetUiState();
 
-  if (!main_contents_) {
+  if (!web_contents_) {
     android_ui_gesture_target_ = base::MakeUnique<AndroidUiGestureTarget>(
         j_motion_event_synthesizer_.obj(),
         Java_VrShellImpl_getNativePageScrollRatio(env, j_vr_shell_.obj()));
-    content_input_manager_ = nullptr;
+    input_manager_ = nullptr;
     vr_web_contents_observer_ = nullptr;
     metrics_helper_ = nullptr;
     return;
   }
-  content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_);
-  vr_web_contents_observer_ = base::MakeUnique<VrWebContentsObserver>(
-      main_contents_, html_interface_.get(), this);
+  input_manager_ = base::MakeUnique<VrInputManager>(web_contents_);
+  vr_web_contents_observer_ =
+      base::MakeUnique<VrWebContentsObserver>(web_contents_, ui_.get(), this);
   // TODO(billorr): Make VrMetricsHelper tab-aware and able to track multiple
   // tabs. crbug.com/684661
-  metrics_helper_ = base::MakeUnique<VrMetricsHelper>(main_contents_);
+  metrics_helper_ = base::MakeUnique<VrMetricsHelper>(web_contents_);
   metrics_helper_->SetVRActive(true);
   metrics_helper_->SetWebVREnabled(webvr_mode_);
 }
 
 void VrShell::SetUiState() {
-  if (!main_contents_) {
+  if (!web_contents_) {
     // TODO(mthiesse): Properly handle native page URLs.
-    html_interface_->SetURL(GURL());
-    html_interface_->SetLoading(false);
-    html_interface_->SetFullscreen(false);
+    ui_->SetURL(GURL());
+    ui_->SetLoading(false);
+    ui_->SetFullscreen(false);
   } else {
-    html_interface_->SetURL(main_contents_->GetVisibleURL());
-    html_interface_->SetLoading(main_contents_->IsLoading());
-    html_interface_->SetFullscreen(main_contents_->IsFullscreen());
+    ui_->SetURL(web_contents_->GetVisibleURL());
+    ui_->SetLoading(web_contents_->IsLoading());
+    ui_->SetFullscreen(web_contents_->IsFullscreen());
   }
 }
 
-void VrShell::LoadUIContent(JNIEnv* env, const JavaParamRef<jobject>& obj) {
-  GURL url(kVrShellUIURL);
-  ui_contents_->GetController().LoadURL(
-      url, content::Referrer(),
-      ui::PageTransition::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string(""));
-}
-
 bool RegisterVrShell(JNIEnv* env) {
   return RegisterNativesImpl(env);
 }
@@ -256,7 +238,7 @@
   // exit vr session
   if (metrics_helper_)
     metrics_helper_->SetVRActive(false);
-  SetIsInVR(main_contents_, false);
+  SetIsInVR(web_contents_, false);
 }
 
 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) {
@@ -265,7 +247,7 @@
 
   if (metrics_helper_)
     metrics_helper_->SetVRActive(true);
-  SetIsInVR(main_contents_, true);
+  SetIsInVR(web_contents_, true);
 }
 
 void VrShell::SetSurface(JNIEnv* env,
@@ -279,20 +261,6 @@
                                      base::Unretained(window)));
 }
 
-base::WeakPtr<VrShell> VrShell::GetWeakPtr(
-    const content::WebContents* web_contents) {
-  // Ensure that the WebContents requesting the VrShell instance is the one
-  // we created.
-  if (g_instance != nullptr && g_instance->ui_contents_ == web_contents)
-    return g_instance->weak_ptr_factory_.GetWeakPtr();
-  return base::WeakPtr<VrShell>(nullptr);
-}
-
-void VrShell::OnDomContentsLoaded() {
-  SetUiState();
-  html_interface_->OnDomContentsLoaded();
-}
-
 void VrShell::SetWebVrMode(JNIEnv* env,
                            const base::android::JavaParamRef<jobject>& obj,
                            bool enabled) {
@@ -302,8 +270,8 @@
   PostToGlThreadWhenReady(base::Bind(&VrShellGl::SetWebVrMode,
                                      gl_thread_->GetVrShellGl(), enabled));
 
-  html_interface_->SetMode(enabled ? UiInterface::Mode::WEB_VR
-                                   : UiInterface::Mode::STANDARD);
+  ui_->SetMode(enabled ? UiInterface::Mode::WEB_VR
+                       : UiInterface::Mode::STANDARD);
   PostToGlThreadWhenReady(base::Bind(&UiSceneManager::SetWebVRMode,
                                      gl_thread_->GetSceneManager(), enabled));
 }
@@ -311,17 +279,17 @@
 void VrShell::OnLoadProgressChanged(JNIEnv* env,
                                     const JavaParamRef<jobject>& obj,
                                     double progress) {
-  html_interface_->SetLoadProgress(progress);
+  ui_->SetLoadProgress(progress);
 }
 
 void VrShell::OnTabListCreated(JNIEnv* env,
                                const JavaParamRef<jobject>& obj,
                                jobjectArray tabs,
                                jobjectArray incognito_tabs) {
-  html_interface_->InitTabList();
+  ui_->InitTabList();
   ProcessTabArray(env, tabs, false);
   ProcessTabArray(env, incognito_tabs, true);
-  html_interface_->FlushTabList();
+  ui_->FlushTabList();
 }
 
 void VrShell::ProcessTabArray(JNIEnv* env, jobjectArray tabs, bool incognito) {
@@ -330,8 +298,7 @@
     jobject jtab = env->GetObjectArrayElement(tabs, i);
     TabAndroid* tab =
         TabAndroid::GetNativeTab(env, JavaParamRef<jobject>(env, jtab));
-    html_interface_->AppendToTabList(incognito, tab->GetAndroidId(),
-                                     tab->GetTitle());
+    ui_->AppendToTabList(incognito, tab->GetAndroidId(), tab->GetTitle());
   }
 }
 
@@ -342,19 +309,17 @@
                            jstring jtitle) {
   std::string title;
   base::android::ConvertJavaStringToUTF8(env, jtitle, &title);
-  html_interface_->UpdateTab(incognito, id, title);
+  ui_->UpdateTab(incognito, id, title);
 }
 
 void VrShell::OnTabRemoved(JNIEnv* env,
                            const JavaParamRef<jobject>& obj,
                            jboolean incognito,
                            jint id) {
-  html_interface_->RemoveTab(incognito, id);
+  ui_->RemoveTab(incognito, id);
 }
 
 void VrShell::SetWebVRSecureOrigin(bool secure_origin) {
-  // TODO(cjgrant): Align this state with the logic that drives the omnibox.
-  html_interface_->SetWebVRSecureOrigin(secure_origin);
   PostToGlThreadWhenReady(base::Bind(&UiSceneManager::SetWebVRSecureOrigin,
                                      gl_thread_->GetSceneManager(),
                                      secure_origin));
@@ -402,7 +367,7 @@
 base::android::ScopedJavaGlobalRef<jobject> VrShell::TakeContentSurface(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj) {
-  content_compositor_->SurfaceChanged(nullptr);
+  compositor_->SurfaceChanged(nullptr);
   base::android::ScopedJavaGlobalRef<jobject> surface(env, content_surface_);
   content_surface_ = nullptr;
   return surface;
@@ -418,16 +383,12 @@
                                        const JavaParamRef<jobject>& obj,
                                        jboolean can_go_back,
                                        jboolean can_go_forward) {
-  html_interface_->SetHistoryButtonsEnabled(can_go_back, can_go_forward);
-}
-
-void VrShell::UiSurfaceChanged(jobject surface) {
-  ui_compositor_->SurfaceChanged(surface);
+  ui_->SetHistoryButtonsEnabled(can_go_back, can_go_forward);
 }
 
 void VrShell::ContentSurfaceChanged(jobject surface) {
   content_surface_ = surface;
-  content_compositor_->SurfaceChanged(surface);
+  compositor_->SurfaceChanged(surface);
   JNIEnv* env = base::android::AttachCurrentThread();
   Java_VrShellImpl_contentSurfaceChanged(env, j_vr_shell_.obj());
 }
@@ -438,12 +399,12 @@
 
 void VrShell::AppButtonGesturePerformed(UiInterface::Direction direction) {
   if (vr_shell_enabled_)
-    html_interface_->HandleAppButtonGesturePerformed(direction);
+    ui_->HandleAppButtonGesturePerformed(direction);
 }
 
 void VrShell::AppButtonPressed() {
   if (vr_shell_enabled_)
-    html_interface_->HandleAppButtonClicked();
+    ui_->HandleAppButtonClicked();
 }
 
 void VrShell::ContentPhysicalBoundsChanged(JNIEnv* env,
@@ -455,37 +416,13 @@
   PostToGlThreadWhenReady(base::Bind(&VrShellGl::ContentPhysicalBoundsChanged,
                                      gl_thread_->GetVrShellGl(), width,
                                      height));
-  content_compositor_->SetWindowBounds(gfx::Size(width, height));
-}
-
-void VrShell::UIPhysicalBoundsChanged(JNIEnv* env,
-                                      const JavaParamRef<jobject>& object,
-                                      jint width,
-                                      jint height,
-                                      jfloat dpr) {
-  PostToGlThreadWhenReady(base::Bind(&VrShellGl::UIPhysicalBoundsChanged,
-                                     gl_thread_->GetVrShellGl(), width,
-                                     height));
-  ui_compositor_->SetWindowBounds(gfx::Size(width, height));
-}
-
-UiInterface* VrShell::GetUiInterface() {
-  return html_interface_.get();
-}
-
-void VrShell::UpdateScene(const base::ListValue* args) {
-  PostToGlThreadWhenReady(base::Bind(&UiSceneManager::UpdateScene,
-                                     gl_thread_->GetSceneManager(),
-                                     base::Passed(args->CreateDeepCopy())));
+  compositor_->SetWindowBounds(gfx::Size(width, height));
 }
 
 void VrShell::DoUiAction(const UiAction action,
                          const base::DictionaryValue* arguments) {
   // Actions that can be handled natively.
   switch (action) {
-    case OMNIBOX_CONTENT:
-      html_interface_->HandleOmniboxInput(*arguments);
-      return;
     case SET_CONTENT_PAUSED: {
       bool paused;
       CHECK(arguments->GetBoolean("paused", &paused));
@@ -493,34 +430,15 @@
       return;
     }
     case HISTORY_BACK:
-      if (main_contents_ && main_contents_->IsFullscreen()) {
-        main_contents_->ExitFullscreen(false);
+      if (web_contents_ && web_contents_->IsFullscreen()) {
+        web_contents_->ExitFullscreen(false);
         return;
       }
       // Otherwise handle in java.
       break;
-    case ZOOM_OUT:  // Not handled yet.
-    case ZOOM_IN:   // Not handled yet.
-      return;
-    case KEY_EVENT: {
-      int char_value;
-      int modifiers = 0;
-      arguments->GetInteger("modifiers", &modifiers);
-      CHECK(arguments->GetInteger("charValue", &char_value));
-      ui_input_manager_->GenerateKeyboardEvent(char_value, modifiers);
-      return;
-    }
     case EXIT_PRESENT:
       delegate_provider_->ExitWebVRPresent();
       return;
-#if defined(ENABLE_VR_SHELL_UI_DEV)
-    case RELOAD_UI:
-      ui_contents_->GetController().Reload(content::ReloadType::NORMAL, false);
-      html_interface_.reset(new UiInterface(UiInterface::Mode::STANDARD));
-      SetUiState();
-      vr_web_contents_observer_->SetUiInterface(html_interface_.get());
-      return;
-#endif
     default:
       break;
   }
@@ -548,66 +466,34 @@
     case RELOAD:
       Java_VrShellImpl_reload(env, j_vr_shell_.obj());
       break;
-    case LOAD_URL: {
-      base::string16 url_string;
-      CHECK(arguments->GetString("url", &url_string));
-      base::android::ScopedJavaLocalRef<jstring> string =
-          base::android::ConvertUTF16ToJavaString(env, url_string);
-      Java_VrShellImpl_loadURL(env, j_vr_shell_.obj(), string,
-                               ui::PageTransition::PAGE_TRANSITION_TYPED);
-      break;
-    }
     default:
       NOTREACHED();
   }
 }
 
-void VrShell::RenderViewHostChanged(content::RenderViewHost* old_host,
-                                    content::RenderViewHost* new_host) {
-  content::RenderWidgetHostView* view = new_host->GetWidget()->GetView();
-  view->SetBackgroundColor(SK_ColorTRANSPARENT);
-  view->SetIsInVR(true);
-}
-
-void VrShell::MainFrameWasResized(bool width_changed) {
-  display::Display display =
-      display::Screen::GetScreen()->GetDisplayNearestView(
-          ui_contents_->GetNativeView());
-  PostToGlThreadWhenReady(
-      base::Bind(&VrShellGl::UIBoundsChanged, gl_thread_->GetVrShellGl(),
-                 display.size().width(), display.size().height()));
-}
-
 void VrShell::ContentFrameWasResized(bool width_changed) {
   display::Display display =
-      display::Screen::GetScreen()->GetDisplayNearestWindow(content_window_);
+      display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
   PostToGlThreadWhenReady(
       base::Bind(&VrShellGl::ContentBoundsChanged, gl_thread_->GetVrShellGl(),
                  display.size().width(), display.size().height()));
 }
 
-void VrShell::WebContentsDestroyed() {
-  ui_input_manager_.reset();
-  ui_contents_ = nullptr;
-  // TODO(mthiesse): Handle web contents being destroyed.
-  ForceExitVr();
-}
-
 void VrShell::ContentWebContentsDestroyed() {
-  content_input_manager_.reset();
-  main_contents_ = nullptr;
+  input_manager_.reset();
+  web_contents_ = nullptr;
   // TODO(mthiesse): Handle web contents being destroyed.
   ForceExitVr();
 }
 
 void VrShell::ContentWasHidden() {
   // Ensure we don't continue sending input to it.
-  content_input_manager_ = nullptr;
+  input_manager_ = nullptr;
 }
 
 void VrShell::ContentWasShown() {
-  if (main_contents_)
-    content_input_manager_ = base::MakeUnique<VrInputManager>(main_contents_);
+  if (web_contents_)
+    input_manager_ = base::MakeUnique<VrInputManager>(web_contents_);
 }
 
 void VrShell::ForceExitVr() {
@@ -635,21 +521,10 @@
                                      dpr);
 }
 
-void VrShell::SetUiCssSize(float width, float height, float dpr) {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  Java_VrShellImpl_setUiCssSize(env, j_vr_shell_.obj(), width, height, dpr);
-}
-
-void VrShell::ProcessUIGesture(std::unique_ptr<blink::WebInputEvent> event) {
-  if (ui_input_manager_) {
-    ui_input_manager_->ProcessUpdatedGesture(std::move(event));
-  }
-}
-
 void VrShell::ProcessContentGesture(
     std::unique_ptr<blink::WebInputEvent> event) {
-  if (content_input_manager_) {
-    content_input_manager_->ProcessUpdatedGesture(std::move(event));
+  if (input_manager_) {
+    input_manager_->ProcessUpdatedGesture(std::move(event));
   } else if (android_ui_gesture_target_) {
     android_ui_gesture_target_->DispatchWebInputEvent(std::move(event));
   }
@@ -683,18 +558,14 @@
 
 jlong Init(JNIEnv* env,
            const JavaParamRef<jobject>& obj,
-           const JavaParamRef<jobject>& ui_web_contents,
-           jlong content_window_android,
-           jlong ui_window_android,
-           jboolean for_web_vr,
            const base::android::JavaParamRef<jobject>& delegate,
+           jlong window_android,
+           jboolean for_web_vr,
            jlong gvr_api,
            jboolean reprojected_rendering) {
   return reinterpret_cast<intptr_t>(new VrShell(
-      env, obj, reinterpret_cast<ui::WindowAndroid*>(content_window_android),
-      content::WebContents::FromJavaWebContents(ui_web_contents),
-      reinterpret_cast<ui::WindowAndroid*>(ui_window_android), for_web_vr,
-      VrShellDelegate::GetNativeVrShellDelegate(env, delegate),
+      env, obj, reinterpret_cast<ui::WindowAndroid*>(window_android),
+      for_web_vr, VrShellDelegate::GetNativeVrShellDelegate(env, delegate),
       reinterpret_cast<gvr_context*>(gvr_api), reprojected_rendering));
 }
 
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h
index ae3d136..20572cc 100644
--- a/chrome/browser/android/vr_shell/vr_shell.h
+++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -23,10 +23,6 @@
 #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h"
 #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h"
 
-namespace base {
-class ListValue;
-}
-
 namespace blink {
 class WebInputEvent;
 }
@@ -58,15 +54,9 @@
   HISTORY_BACK = 0,
   HISTORY_FORWARD,
   RELOAD,
-  ZOOM_OUT,
-  ZOOM_IN,
-  RELOAD_UI,
-  LOAD_URL,
-  OMNIBOX_CONTENT,
   SET_CONTENT_PAUSED,
   SHOW_TAB,
   OPEN_NEW_TAB,
-  KEY_EVENT,
   EXIT_PRESENT,
 };
 
@@ -75,14 +65,11 @@
 // The native instance of the Java VrShell. This class is not threadsafe and
 // must only be used on the UI thread.
 class VrShell : public device::PresentingGvrDelegate,
-                content::WebContentsObserver,
                 device::GvrGamepadDataProvider {
  public:
   VrShell(JNIEnv* env,
           jobject obj,
-          ui::WindowAndroid* content_window,
-          content::WebContents* ui_contents,
-          ui::WindowAndroid* ui_window,
+          ui::WindowAndroid* window,
           bool for_web_vr,
           VrShellDelegate* delegate,
           gvr_context* gvr_api,
@@ -137,14 +124,6 @@
   void ContentWasHidden();
   void ContentWasShown();
 
-  // html/js UI hooks.
-  static base::WeakPtr<VrShell> GetWeakPtr(
-      const content::WebContents* web_contents);
-
-  UiInterface* GetUiInterface();
-  void OnDomContentsLoaded();
-
-  void UiSurfaceChanged(jobject surface);
   void ContentSurfaceChanged(jobject surface);
   void GvrDelegateReady();
   void AppButtonGesturePerformed(UiInterface::Direction direction);
@@ -157,27 +136,16 @@
       jint height,
       jfloat dpr);
 
-  void UIPhysicalBoundsChanged(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& object,
-      jint width,
-      jint height,
-      jfloat dpr);
-
-  void UpdateScene(const base::ListValue* args);
-
   // Perform a UI action triggered by the javascript API.
   void DoUiAction(const UiAction action,
                   const base::DictionaryValue* arguments);
 
   void SetContentCssSize(float width, float height, float dpr);
-  void SetUiCssSize(float width, float height, float dpr);
 
   void ContentFrameWasResized(bool width_changed);
 
   void ForceExitVr();
 
-  void ProcessUIGesture(std::unique_ptr<blink::WebInputEvent> event);
   void ProcessContentGesture(std::unique_ptr<blink::WebInputEvent> event);
   void SubmitControllerModel(std::unique_ptr<VrControllerModel> model);
 
@@ -191,12 +159,6 @@
   void SetContentPaused(bool paused);
   void SetUiState();
 
-  // content::WebContentsObserver implementation.
-  void RenderViewHostChanged(content::RenderViewHost* old_host,
-                             content::RenderViewHost* new_host) override;
-  void MainFrameWasResized(bool width_changed) override;
-  void WebContentsDestroyed() override;
-
   // device::GvrDelegate implementation.
   void SetWebVRSecureOrigin(bool secure_origin) override;
   void SubmitWebVRFrame(int16_t frame_index,
@@ -221,25 +183,22 @@
 
   bool vr_shell_enabled_;
 
-  std::unique_ptr<UiInterface> html_interface_;
+  std::unique_ptr<UiInterface> ui_;
   bool content_paused_ = false;
   bool webvr_mode_ = false;
 
-  content::WebContents* main_contents_ = nullptr;
+  content::WebContents* web_contents_ = nullptr;
   base::android::ScopedJavaGlobalRef<jobject> j_motion_event_synthesizer_;
-  ui::WindowAndroid* content_window_;
-  std::unique_ptr<VrCompositor> content_compositor_;
-  content::WebContents* ui_contents_;
-  std::unique_ptr<VrCompositor> ui_compositor_;
+  ui::WindowAndroid* window_;
+  std::unique_ptr<VrCompositor> compositor_;
 
   std::unique_ptr<VrWebContentsObserver> vr_web_contents_observer_;
 
   VrShellDelegate* delegate_provider_ = nullptr;
   base::android::ScopedJavaGlobalRef<jobject> j_vr_shell_;
 
-  std::unique_ptr<VrInputManager> content_input_manager_;
+  std::unique_ptr<VrInputManager> input_manager_;
   std::unique_ptr<AndroidUiGestureTarget> android_ui_gesture_target_;
-  std::unique_ptr<VrInputManager> ui_input_manager_;
   std::unique_ptr<VrMetricsHelper> metrics_helper_;
 
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc
index 81397edd8..05a6c98f 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/android/vr_shell/ui_element.h"
 #include "chrome/browser/android/vr_shell/ui_interface.h"
 #include "chrome/browser/android/vr_shell/ui_scene.h"
+#include "chrome/browser/android/vr_shell/ui_scene_manager.h"
 #include "chrome/browser/android/vr_shell/vr_controller.h"
 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
 #include "chrome/browser/android/vr_shell/vr_shell.h"
@@ -203,13 +204,13 @@
     bool initially_web_vr,
     bool reprojected_rendering,
     UiScene* scene)
-    : scene_(scene),
-      web_vr_mode_(initially_web_vr),
+    : web_vr_mode_(initially_web_vr),
       surfaceless_rendering_(reprojected_rendering),
       task_runner_(base::ThreadTaskRunnerHandle::Get()),
       binding_(this),
       weak_vr_shell_(weak_vr_shell),
       main_thread_task_runner_(std::move(main_thread_task_runner)),
+      scene_(scene),
 #if DCHECK_IS_ON()
       fps_meter_(new FPSMeter()),
 #endif
@@ -277,26 +278,20 @@
     return;
   }
 
-  unsigned int textures[3];
-  glGenTextures(3, textures);
-  ui_texture_id_ = textures[0];
-  content_texture_id_ = textures[1];
-  webvr_texture_id_ = textures[2];
-  ui_surface_texture_ = gl::SurfaceTexture::Create(ui_texture_id_);
+  unsigned int textures[2];
+  glGenTextures(2, textures);
+  content_texture_id_ = textures[0];
+  webvr_texture_id_ = textures[1];
   content_surface_texture_ = gl::SurfaceTexture::Create(content_texture_id_);
   webvr_surface_texture_ = gl::SurfaceTexture::Create(webvr_texture_id_);
-  CreateUiSurface();
   CreateContentSurface();
-  ui_surface_texture_->SetFrameAvailableCallback(base::Bind(
-      &VrShellGl::OnUIFrameAvailable, weak_ptr_factory_.GetWeakPtr()));
   content_surface_texture_->SetFrameAvailableCallback(base::Bind(
       &VrShellGl::OnContentFrameAvailable, weak_ptr_factory_.GetWeakPtr()));
   webvr_surface_texture_->SetFrameAvailableCallback(base::Bind(
       &VrShellGl::OnWebVRFrameAvailable, weak_ptr_factory_.GetWeakPtr()));
-  ui_surface_texture_->SetDefaultBufferSize(ui_tex_physical_size_.width(),
-                                            ui_tex_physical_size_.height());
   content_surface_texture_->SetDefaultBufferSize(
       content_tex_physical_size_.width(), content_tex_physical_size_.height());
+
   InitializeRenderer();
 
   gfx::Size webvr_size =
@@ -320,14 +315,6 @@
                             content_surface_->j_surface().obj()));
 }
 
-void VrShellGl::CreateUiSurface() {
-  ui_surface_ =
-      base::MakeUnique<gl::ScopedJavaSurface>(ui_surface_texture_.get());
-  main_thread_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&VrShell::UiSurfaceChanged, weak_vr_shell_,
-                            ui_surface_->j_surface().obj()));
-}
-
 void VrShellGl::CreateOrResizeWebVRSurface(const gfx::Size& size) {
   if (!webvr_surface_texture_) {
     DLOG(ERROR) << "No WebVR surface texture available";
@@ -395,10 +382,6 @@
   submit_client_.Bind(std::move(submit_client_info));
 }
 
-void VrShellGl::OnUIFrameAvailable() {
-  ui_surface_texture_->UpdateTexImage();
-}
-
 void VrShellGl::OnContentFrameAvailable() {
   content_surface_texture_->UpdateTexImage();
   received_frame_ = true;
@@ -639,29 +622,12 @@
   int pixel_x = 0;
   int pixel_y = 0;
 
-  if (target_element_ != nullptr) {
-    gfx::RectF pixel_rect;
-    if (target_element_->fill == Fill::CONTENT) {
-      pixel_rect.SetRect(0, 0, content_tex_css_width_, content_tex_css_height_);
-    } else {
-      pixel_rect.SetRect(target_element_->copy_rect.x(),
-                         target_element_->copy_rect.y(),
-                         target_element_->copy_rect.width(),
-                         target_element_->copy_rect.height());
-    }
+  if (target_element_ != nullptr && target_element_->fill == Fill::CONTENT) {
+    input_target = InputTarget::CONTENT;
+    gfx::RectF pixel_rect(0, 0, content_tex_css_width_,
+                          content_tex_css_height_);
     pixel_x = pixel_rect.x() + pixel_rect.width() * target_x;
     pixel_y = pixel_rect.y() + pixel_rect.height() * target_y;
-
-    switch (target_element_->fill) {
-      case Fill::CONTENT:
-        input_target = InputTarget::CONTENT;
-        break;
-      case Fill::SPRITE:
-        input_target = InputTarget::UI;
-        break;
-      default:
-        break;
-    }
   }
   SendEventsToTarget(input_target, pixel_x, pixel_y);
 }
@@ -788,12 +754,9 @@
 void VrShellGl::SendGesture(InputTarget input_target,
                             std::unique_ptr<blink::WebInputEvent> event) {
   DCHECK(input_target != InputTarget::NONE);
-  auto&& target = input_target == InputTarget::CONTENT
-                      ? &VrShell::ProcessContentGesture
-                      : &VrShell::ProcessUIGesture;
   main_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(target, weak_vr_shell_, base::Passed(std::move(event))));
+      FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_,
+                            base::Passed(std::move(event))));
 }
 
 void VrShellGl::DrawFrame(int16_t frame_index) {
@@ -1031,15 +994,7 @@
     vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform);
 
     switch (rect->fill) {
-      case Fill::SPRITE: {
-        gfx::RectF copy_rect(
-            static_cast<float>(rect->copy_rect.x()) / ui_tex_css_width_,
-            static_cast<float>(rect->copy_rect.y()) / ui_tex_css_height_,
-            static_cast<float>(rect->copy_rect.width()) / ui_tex_css_width_,
-            static_cast<float>(rect->copy_rect.height()) / ui_tex_css_height_);
-        jint texture_handle = ui_texture_id_;
-        vr_shell_renderer_->GetTexturedQuadRenderer()->AddQuad(
-            texture_handle, transform, copy_rect, rect->computed_opacity);
+      case Fill::SKIA: {
         break;
       }
       case Fill::OPAQUE_GRADIENT: {
@@ -1057,10 +1012,9 @@
         break;
       }
       case Fill::CONTENT: {
-        gfx::RectF copy_rect = {0, 0, 1, 1};
-        jint texture_handle = content_texture_id_;
+        gfx::RectF copy_rect(0, 0, 1, 1);
         vr_shell_renderer_->GetTexturedQuadRenderer()->AddQuad(
-            texture_handle, transform, copy_rect, rect->computed_opacity);
+            content_texture_id_, transform, copy_rect, rect->computed_opacity);
         break;
       }
       default:
@@ -1274,18 +1228,6 @@
   content_tex_physical_size_.set_height(height);
 }
 
-void VrShellGl::UIBoundsChanged(int width, int height) {
-  ui_tex_css_width_ = width;
-  ui_tex_css_height_ = height;
-}
-
-void VrShellGl::UIPhysicalBoundsChanged(int width, int height) {
-  if (ui_surface_texture_.get())
-    ui_surface_texture_->SetDefaultBufferSize(width, height);
-  ui_tex_physical_size_.set_width(width);
-  ui_tex_physical_size_.set_height(height);
-}
-
 base::WeakPtr<VrShellGl> VrShellGl::GetWeakPtr() {
   return weak_ptr_factory_.GetWeakPtr();
 }
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h
index 2d14b66..8d3d2fcf 100644
--- a/chrome/browser/android/vr_shell/vr_shell_gl.h
+++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -65,7 +65,6 @@
   enum class InputTarget {
     NONE = 0,
     CONTENT,
-    UI,
   };
 
   VrShellGl(const base::WeakPtr<VrShell>& weak_vr_shell,
@@ -153,22 +152,16 @@
 
   void SendVSync(base::TimeDelta time, const GetVSyncCallback& callback);
 
-  // samplerExternalOES texture data for UI content image.
-  int ui_texture_id_ = 0;
   // samplerExternalOES texture data for main content image.
   int content_texture_id_ = 0;
   // samplerExternalOES texture data for WebVR content image.
   int webvr_texture_id_ = 0;
 
-  UiScene* scene_;
-
   scoped_refptr<gl::GLSurface> surface_;
   scoped_refptr<gl::GLContext> context_;
-  scoped_refptr<gl::SurfaceTexture> ui_surface_texture_;
   scoped_refptr<gl::SurfaceTexture> content_surface_texture_;
   scoped_refptr<gl::SurfaceTexture> webvr_surface_texture_;
 
-  std::unique_ptr<gl::ScopedJavaSurface> ui_surface_;
   std::unique_ptr<gl::ScopedJavaSurface> content_surface_;
 
   std::unique_ptr<gvr::GvrApi> gvr_api_;
@@ -202,13 +195,10 @@
   InputTarget current_input_target_ = InputTarget::NONE;
   InputTarget current_scroll_target_ = InputTarget::NONE;
   InputTarget current_fling_target_ = InputTarget::NONE;
-  int ui_tex_css_width_ = 0;
-  int ui_tex_css_height_ = 0;
   int content_tex_css_width_ = 0;
   int content_tex_css_height_ = 0;
   gfx::Size content_tex_physical_size_ = {0, 0};
   gfx::Size webvr_surface_size_ = {0, 0};
-  gfx::Size ui_tex_physical_size_ = {0, 0};
 
   std::vector<vr::Mat4f> webvr_head_pose_;
   bool web_vr_mode_;
@@ -232,6 +222,8 @@
   base::WeakPtr<VrShell> weak_vr_shell_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
 
+  UiScene* scene_ = nullptr;
+
   uint8_t frame_index_ = 0;
   // Larger than frame_index_ so it can be initialized out-of-band.
   uint16_t last_frame_index_ = -1;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 23b1f50..65959b76 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -235,15 +235,6 @@
         <include name="IDR_SNIPPETS_INTERNALS_HTML" file="resources\snippets_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" />
         <include name="IDR_SNIPPETS_INTERNALS_CSS" file="resources\snippets_internals.css" compress="gzip" type="BINDATA" />
         <include name="IDR_SNIPPETS_INTERNALS_JS" file="resources\snippets_internals.js" compress="gzip" type="BINDATA" />
-        <if expr="enable_vr">
-          <include name="IDR_VR_SHELL_UI_HTML" file="resources\vr_shell\vr_shell_ui.html" allowexternalscript="true" flattenhtml="true" compress="gzip" type="BINDATA" />
-          <include name="IDR_VR_SHELL_UI_CSS" file="resources\vr_shell\vr_shell_ui.css" compress="gzip" type="BINDATA" />
-          <include name="IDR_VR_SHELL_UI_JS" file="resources\vr_shell\vr_shell_ui.js" compress="gzip" type="BINDATA" />
-          <include name="IDR_VR_SHELL_UI_API_JS" file="resources\vr_shell\vr_shell_ui_api.js" compress="gzip" type="BINDATA" />
-          <include name="IDR_VR_SHELL_UI_SCENE_JS" file="resources\vr_shell\vr_shell_ui_scene.js" compress="gzip" type="BINDATA" />
-          <include name="IDR_VR_SHELL_UI_VK_CSS" file="resources\vr_shell\vk.css" compress="gzip" type="BINDATA" />
-          <include name="IDR_VR_SHELL_UI_VK_JS" file="resources\vr_shell\vk.js" compress="gzip" type="BINDATA" />
-        </if>
       </if>
       <include name="IDR_SUPERVISED_USER_INTERNALS_HTML" file="resources\supervised_user_internals.html" allowexternalscript="true" compress="gzip" type="BINDATA" />
       <include name="IDR_SUPERVISED_USER_INTERNALS_CSS" file="resources\supervised_user_internals.css" compress="gzip" type="BINDATA" />
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index 3a82ed5..1cf0597 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -573,10 +573,9 @@
       new display::ManagedDisplayMode(gfx::Size(400, 300)));
   scoped_refptr<display::ManagedDisplayMode> new_mode(
       new display::ManagedDisplayMode(gfx::Size(500, 400)));
-  if (shell->display_manager()->SetDisplayMode(id, new_mode)) {
-    shell->resolution_notification_controller()->PrepareNotification(
-        id, old_mode, new_mode, base::Closure());
-  }
+  EXPECT_TRUE(shell->resolution_notification_controller()
+                  ->PrepareNotificationAndSetDisplayMode(id, old_mode, new_mode,
+                                                         base::Closure()));
   UpdateDisplay("500x400#500x400|400x300|300x200");
 
   const base::DictionaryValue* properties =
diff --git a/chrome/browser/chromeos/printing/cups_print_job_notification.cc b/chrome/browser/chromeos/printing/cups_print_job_notification.cc
index f4908eff..8dee4784 100644
--- a/chrome/browser/chromeos/printing/cups_print_job_notification.cc
+++ b/chrome/browser/chromeos/printing/cups_print_job_notification.cc
@@ -149,10 +149,12 @@
   UpdateNotificationType();
   UpdateNotificationButtons();
 
-  // |STATE_PAGE_DONE| is special since if the user closes the notification in
-  // the middle, which means they're not interested in the printing progress, we
-  // should prevent showing the following printing progress.
-  if (print_job_->state() == CupsPrintJob::State::STATE_PAGE_DONE) {
+  // |STATE_STARTED| and |STATE_PAGE_DONE| are special since if the user closes
+  // the notification in the middle, which means they're not interested in the
+  // printing progress, we should prevent showing the following printing
+  // progress to the user.
+  if (print_job_->state() == CupsPrintJob::State::STATE_STARTED ||
+      print_job_->state() == CupsPrintJob::State::STATE_PAGE_DONE) {
     if (closed_in_middle_) {
       // If the notification was closed during the printing, prevent showing the
       // following printing progress.
@@ -186,9 +188,6 @@
   ResourceBundle& bundle = ResourceBundle::GetSharedInstance();
   switch (print_job_->state()) {
     case CupsPrintJob::State::STATE_WAITING:
-      notification_->set_icon(
-          bundle.GetImageNamed(IDR_PRINT_NOTIFICATION_WAITING));
-      break;
     case CupsPrintJob::State::STATE_STARTED:
     case CupsPrintJob::State::STATE_PAGE_DONE:
     case CupsPrintJob::State::STATE_SUSPENDED:
@@ -215,11 +214,6 @@
     case CupsPrintJob::State::STATE_NONE:
       break;
     case CupsPrintJob::State::STATE_WAITING:
-      message = l10n_util::GetStringFUTF16(
-          IDS_PRINT_JOB_WAITING_NOTIFICATION_MESSAGE,
-          base::IntToString16(print_job_->total_page_number()),
-          base::UTF8ToUTF16(print_job_->printer().display_name()));
-      break;
     case CupsPrintJob::State::STATE_STARTED:
     case CupsPrintJob::State::STATE_PAGE_DONE:
     case CupsPrintJob::State::STATE_SUSPENDED:
@@ -251,6 +245,7 @@
 
 void CupsPrintJobNotification::UpdateNotificationType() {
   switch (print_job_->state()) {
+    case CupsPrintJob::State::STATE_WAITING:
     case CupsPrintJob::State::STATE_STARTED:
     case CupsPrintJob::State::STATE_PAGE_DONE:
     case CupsPrintJob::State::STATE_SUSPENDED:
@@ -260,7 +255,6 @@
                                   print_job_->total_page_number());
       break;
     case CupsPrintJob::State::STATE_NONE:
-    case CupsPrintJob::State::STATE_WAITING:
     case CupsPrintJob::State::STATE_DOCUMENT_DONE:
     case CupsPrintJob::State::STATE_ERROR:
     case CupsPrintJob::State::STATE_CANCELLED:
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc
index c8f65ab9..3a0a01a 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc
@@ -269,7 +269,8 @@
   base::Closure task = base::Bind(
       &EPKPChallengeMachineKey::Run, base::Unretained(impl_),
       scoped_refptr<UIThreadExtensionFunction>(AsUIThreadExtensionFunction()),
-      callback, StringFromVector(params->challenge));
+      callback, StringFromVector(params->challenge),
+      params->register_key ? *params->register_key : false);
   content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, task);
   return RespondLater();
 }
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
index e48d908..29bda41 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
@@ -262,8 +262,24 @@
   }
 
   std::unique_ptr<base::ListValue> CreateArgs() {
+    return CreateArgsInternal(nullptr);
+  }
+
+  std::unique_ptr<base::ListValue> CreateArgsNoRegister() {
+    return CreateArgsInternal(base::MakeUnique<bool>(false));
+  }
+
+  std::unique_ptr<base::ListValue> CreateArgsRegister() {
+    return CreateArgsInternal(base::MakeUnique<bool>(true));
+  }
+
+  std::unique_ptr<base::ListValue> CreateArgsInternal(
+      std::unique_ptr<bool> register_key) {
     std::unique_ptr<base::ListValue> args(new base::ListValue);
     args->Append(base::Value::CreateWithCopiedBuffer("challenge", 9));
+    if (register_key) {
+      args->AppendBoolean(*register_key);
+    }
     return args;
   }
 
@@ -320,6 +336,15 @@
             RunFunctionAndReturnError(func_.get(), CreateArgs(), browser()));
 }
 
+TEST_F(EPKChallengeMachineKeyTest, KeyRegistrationFailed) {
+  EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
+      .WillRepeatedly(Invoke(RegisterKeyCallbackFalse));
+
+  EXPECT_EQ(
+      EPKPChallengeMachineKey::kKeyRegistrationFailedError,
+      RunFunctionAndReturnError(func_.get(), CreateArgsRegister(), browser()));
+}
+
 TEST_F(EPKChallengeMachineKeyTest, KeyExists) {
   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationDoesKeyExist(_, _, _, _))
       .WillRepeatedly(WithArgs<3>(Invoke(
@@ -331,6 +356,22 @@
       utils::RunFunction(func_.get(), CreateArgs(), browser(), utils::NONE));
 }
 
+TEST_F(EPKChallengeMachineKeyTest, KeyNotRegisteredByDefault) {
+  EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
+      .Times(0);
+
+  EXPECT_TRUE(
+      utils::RunFunction(func_.get(), CreateArgs(), browser(), utils::NONE));
+}
+
+TEST_F(EPKChallengeMachineKeyTest, KeyNotRegistered) {
+  EXPECT_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
+      .Times(0);
+
+  EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgsNoRegister(), browser(),
+                                 utils::NONE));
+}
+
 TEST_F(EPKChallengeMachineKeyTest, Success) {
   // GetCertificate must be called exactly once.
   EXPECT_CALL(mock_attestation_flow_,
@@ -355,6 +396,36 @@
             std::string(response->GetBuffer(), response->GetSize()));
 }
 
+TEST_F(EPKChallengeMachineKeyTest, KeyRegisteredSuccess) {
+  // GetCertificate must be called exactly once.
+  EXPECT_CALL(mock_attestation_flow_,
+              GetCertificate(
+                  chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
+                  _, _, _, _))
+      .Times(1);
+  // TpmAttestationRegisterKey must be called exactly once.
+  EXPECT_CALL(mock_async_method_caller_,
+              TpmAttestationRegisterKey(chromeos::attestation::KEY_DEVICE,
+                                        _ /* Unused by the API. */,
+                                        "attest-ent-machine", _))
+      .Times(1);
+  // SignEnterpriseChallenge must be called exactly once.
+  EXPECT_CALL(
+      mock_async_method_caller_,
+      TpmAttestationSignEnterpriseChallenge(
+          chromeos::attestation::KEY_DEVICE, cryptohome::Identification(),
+          "attest-ent-machine", "google.com", "device_id", _, "challenge", _))
+      .Times(1);
+
+  std::unique_ptr<base::Value> value(RunFunctionAndReturnSingleResult(
+      func_.get(), CreateArgsRegister(), browser()));
+
+  const base::Value* response;
+  ASSERT_TRUE(value->GetAsBinary(&response));
+  EXPECT_EQ("response",
+            std::string(response->GetBuffer(), response->GetSize()));
+}
+
 TEST_F(EPKChallengeMachineKeyTest, AttestationNotPrepared) {
   EXPECT_CALL(mock_cryptohome_client_, TpmAttestationIsPrepared(_))
       .WillRepeatedly(Invoke(
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
index 972e8ff..4b69f12d 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
@@ -287,6 +287,8 @@
 
 const char EPKPChallengeMachineKey::kGetCertificateFailedError[] =
     "Failed to get Enterprise machine certificate. Error code = %d";
+const char EPKPChallengeMachineKey::kKeyRegistrationFailedError[] =
+    "Machine key registration failed.";
 const char EPKPChallengeMachineKey::kNonEnterpriseDeviceError[] =
     "The device is not enterprise enrolled.";
 
@@ -312,7 +314,8 @@
 void EPKPChallengeMachineKey::Run(
     scoped_refptr<UIThreadExtensionFunction> caller,
     const ChallengeKeyCallback& callback,
-    const std::string& challenge) {
+    const std::string& challenge,
+    bool register_key) {
   callback_ = callback;
   profile_ = ChromeExtensionFunctionDetails(caller.get()).GetProfile();
   extension_id_ = caller->extension_id();
@@ -337,23 +340,26 @@
   // Check if RA is enabled in the device policy.
   GetDeviceAttestationEnabled(
       base::Bind(&EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback,
-                 base::Unretained(this), challenge));
+                 base::Unretained(this), challenge, register_key));
 }
 
 void EPKPChallengeMachineKey::DecodeAndRun(
     scoped_refptr<UIThreadExtensionFunction> caller,
     const ChallengeKeyCallback& callback,
-    const std::string& encoded_challenge) {
+    const std::string& encoded_challenge,
+    bool register_key) {
   std::string challenge;
   if (!base::Base64Decode(encoded_challenge, &challenge)) {
     callback.Run(false, kChallengeBadBase64Error);
     return;
   }
-  Run(caller, callback, challenge);
+  Run(caller, callback, challenge, register_key);
 }
 
 void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback(
-    const std::string& challenge, bool enabled) {
+    const std::string& challenge,
+    bool register_key,
+    bool enabled) {
   if (!enabled) {
     callback_.Run(false, kDevicePolicyDisabledError);
     return;
@@ -365,11 +371,12 @@
              chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
              false,  // user consent is not required.
              base::Bind(&EPKPChallengeMachineKey::PrepareKeyCallback,
-                        base::Unretained(this), challenge));
+                        base::Unretained(this), challenge, register_key));
 }
 
-void EPKPChallengeMachineKey::PrepareKeyCallback(
-    const std::string& challenge, PrepareKeyResult result) {
+void EPKPChallengeMachineKey::PrepareKeyCallback(const std::string& challenge,
+                                                 bool register_key,
+                                                 PrepareKeyResult result) {
   if (result != PREPARE_KEY_OK) {
     callback_.Run(false,
                   base::StringPrintf(kGetCertificateFailedError, result));
@@ -381,17 +388,41 @@
       chromeos::attestation::KEY_DEVICE,
       cryptohome::Identification(),  // Not used.
       kKeyName, GetEnterpriseDomain(), GetDeviceId(),
-      chromeos::attestation::CHALLENGE_OPTION_NONE, challenge,
+      register_key ? chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY
+                   : chromeos::attestation::CHALLENGE_OPTION_NONE,
+      challenge,
       base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback,
-                 base::Unretained(this)));
+                 base::Unretained(this), register_key));
 }
 
 void EPKPChallengeMachineKey::SignChallengeCallback(
-    bool success, const std::string& response) {
+    bool register_key,
+    bool success,
+    const std::string& response) {
   if (!success) {
     callback_.Run(false, kSignChallengeFailedError);
     return;
   }
+  if (register_key) {
+    async_caller_->TpmAttestationRegisterKey(
+        chromeos::attestation::KEY_DEVICE,
+        cryptohome::Identification(),  // Not used.
+        kKeyName,
+        base::Bind(&EPKPChallengeMachineKey::RegisterKeyCallback,
+                   base::Unretained(this), response));
+  } else {
+    RegisterKeyCallback(response, true, cryptohome::MOUNT_ERROR_NONE);
+  }
+}
+
+void EPKPChallengeMachineKey::RegisterKeyCallback(
+    const std::string& response,
+    bool success,
+    cryptohome::MountError return_code) {
+  if (!success || return_code != cryptohome::MOUNT_ERROR_NONE) {
+    callback_.Run(false, kKeyRegistrationFailedError);
+    return;
+  }
   callback_.Run(true, response);
 }
 
@@ -579,7 +610,7 @@
   base::Closure task = base::Bind(
       &EPKPChallengeMachineKey::DecodeAndRun, base::Unretained(impl_),
       scoped_refptr<UIThreadExtensionFunction>(AsUIThreadExtensionFunction()),
-      callback, params->challenge);
+      callback, params->challenge, false);
   content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, task);
   return RespondLater();
 }
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
index 2923b34..99e0b998 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h
@@ -163,6 +163,7 @@
 class EPKPChallengeMachineKey : public EPKPChallengeKeyBase {
  public:
   static const char kGetCertificateFailedError[];
+  static const char kKeyRegistrationFailedError[];
   static const char kNonEnterpriseDeviceError[];
 
   EPKPChallengeMachineKey();
@@ -177,21 +178,30 @@
   // context.
   void Run(scoped_refptr<UIThreadExtensionFunction> caller,
            const ChallengeKeyCallback& callback,
-           const std::string& encoded_challenge);
+           const std::string& encoded_challenge,
+           bool register_key);
 
   // Like |Run| but expects a Base64 |encoded_challenge|.
   void DecodeAndRun(scoped_refptr<UIThreadExtensionFunction> caller,
                     const ChallengeKeyCallback& callback,
-                    const std::string& encoded_challenge);
+                    const std::string& encoded_challenge,
+                    bool register_key);
 
  private:
   static const char kKeyName[];
 
   void GetDeviceAttestationEnabledCallback(const std::string& challenge,
+                                           bool register_key,
                                            bool enabled);
   void PrepareKeyCallback(const std::string& challenge,
+                          bool register_key,
                           PrepareKeyResult result);
-  void SignChallengeCallback(bool success, const std::string& response);
+  void SignChallengeCallback(bool register_key,
+                             bool success,
+                             const std::string& response);
+  void RegisterKeyCallback(const std::string& response,
+                           bool success,
+                           cryptohome::MountError return_code);
 };
 
 class EPKPChallengeUserKey : public EPKPChallengeKeyBase {
diff --git a/chrome/browser/extensions/display_info_provider_chromeos.cc b/chrome/browser/extensions/display_info_provider_chromeos.cc
index d981386..a7dc13e 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos.cc
@@ -352,19 +352,19 @@
       return false;
     }
 
-    if (!display_manager->SetDisplayMode(id, new_mode)) {
+    // If it's the internal display, the display mode will be applied directly,
+    // otherwise a confirm/revert notification will be prepared first, and the
+    // display mode will be applied. If the user accepts the mode change by
+    // dismissing the notification, StoreDisplayPrefs() will be called back to
+    // persist the new preferences.
+    if (!ash::Shell::Get()
+             ->resolution_notification_controller()
+             ->PrepareNotificationAndSetDisplayMode(
+                 id, current_mode, new_mode,
+                 base::Bind(&chromeos::StoreDisplayPrefs))) {
       *error = "Unable to set the display mode.";
       return false;
     }
-
-    if (!display::Display::IsInternalDisplayId(id)) {
-      // For external displays, show a notification confirming the resolution
-      // change.
-      ash::Shell::Get()
-          ->resolution_notification_controller()
-          ->PrepareNotification(id, current_mode, new_mode,
-                                base::Bind(&chromeos::StoreDisplayPrefs));
-    }
   }
   return true;
 }
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 7ebc199..9c75bce 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2453,6 +2453,13 @@
 const char kEnableAutofillCreditCardLastUsedDateDisplayDescription[] =
     "If enabled, display the last used date of a credit card in autofill.";
 
+const char kEnableAutofillCreditCardUploadCvcPrompt[] =
+    "Enable requesting missing CVC during Autofill credit card upload";
+
+const char kEnableAutofillCreditCardUploadCvcPromptDescription[] =
+    "If enabled, requests missing CVC when offering to upload credit cards to "
+    "Google Payments.";
+
 #if !defined(OS_ANDROID) && defined(GOOGLE_CHROME_BUILD)
 
 const char kGoogleBrandedContextMenuName[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a09ecf6..0c08081 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2664,6 +2664,14 @@
 // card in autofill.
 extern const char kEnableAutofillCreditCardLastUsedDateDisplayDescription[];
 
+// Name for the flag to enable requesting CVC in the credit card upload "offer
+// to save" bubble if it was not already detected in the submitted form.
+extern const char kEnableAutofillCreditCardUploadCvcPrompt[];
+
+// Description for the flag to enable requesting CVC in the credit card upload
+// offer to save bubble if it was not detected during the checkout flow.
+extern const char kEnableAutofillCreditCardUploadCvcPromptDescription[];
+
 #if !defined(OS_ANDROID) && defined(GOOGLE_CHROME_BUILD)
 
 // Name for the flag to enable Google branding in the context menu.
diff --git a/chrome/browser/resources/chromeos/login/encryption_migration.css b/chrome/browser/resources/chromeos/login/encryption_migration.css
index 41bd2f87..7b948b0d 100644
--- a/chrome/browser/resources/chromeos/login/encryption_migration.css
+++ b/chrome/browser/resources/chromeos/login/encryption_migration.css
@@ -2,13 +2,48 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
+oobe-dialog {
+  max-width: 768px;
+}
+
+oobe-dialog div {
+  line-height: 1.54;  /* 20px height for 13px font. */
+}
+
 paper-progress {
   --paper-progress-active-color: var(--google-blue-500);
-  bottom: 0;
   height: 3px;
+  margin-bottom: 28px;
   width: 100%;
 }
 
 .bottom-buttons {
   -webkit-padding-end: 16px;
 }
+
+oobe-text-button {
+  color: rgb(90, 90, 90);
+}
+
+oobe-dialog > iron-icon {
+  height: 32px;
+  width: 32px;
+}
+
+oobe-dialog > iron-icon.warning {
+  --iron-icon-fill-color: rgb(219, 68, 55);
+}
+
+.chrome-logo {
+  background: url(chrome://oobe/product-logo.png) center/100% no-repeat;
+}
+
+.footer div {
+  color: rgb(51, 51, 51);
+  font-size: 13px;
+}
+
+.footer div.warning {
+  color: rgb(197, 57, 41);
+  font-weight: 500;
+}
diff --git a/chrome/browser/resources/chromeos/login/encryption_migration.html b/chrome/browser/resources/chromeos/login/encryption_migration.html
index 24b4951..95ab26e9 100644
--- a/chrome/browser/resources/chromeos/login/encryption_migration.html
+++ b/chrome/browser/resources/chromeos/login/encryption_migration.html
@@ -2,6 +2,8 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
+<link rel="import" href="chrome://resources/cr_elements/icons.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
@@ -12,95 +14,106 @@
     <link rel="stylesheet" href="encryption_migration.css">
     <link rel="stylesheet" href="oobe_dialog_parameters.css">
     <template is="dom-if" if="[[isInitial_(uiState)]]">
-      <oobe-dialog tabindex="0" has-buttons>
-        <p>Checking the system...</p>
-      </oobe-dialog>
+      <oobe-dialog tabindex="0" has-buttons></oobe-dialog>
     </template>
     <template is="dom-if" if="[[isReady_(uiState)]]">
       <oobe-dialog tabindex="0" has-buttons>
+        <iron-icon class="oobe-icon chrome-logo"></iron-icon>
         <div class="header">
-          <h1 class="title">Your file system needs upgrade</h1>
-          <div class="subtitle">
-            Your file system needs to be upgraded to use Android applications.
-            String TBD.
-          </div>
+          <h1 class="title">$i18n{migrationReadyTitle}</h1>
+          <div class="subtitle">$i18n{migrationReadyDescription}</div>
         </div>
-        <template is="dom-if" if="[[!isEnoughBattery]]">
-          <div class="footer flex layout vertical">
-            <div>Battery too low for update. <span>[[batteryPercent]]</span>%
-            </div>
-            <div>Please plug your Chromebook into a power source.</div>
+        <template is="dom-if" if="[[isEnoughBattery]]">
+          <div class="footer layout vertical center">
+            <img srcset="images/security_update_1x.png 1x,
+                         images/security_update_2x.png 2x">
           </div>
         </template>
+        <template is="dom-if" if="[[!isEnoughBattery]]">
+          <div class="footer layout vertical">
+            <div class="warning">
+              [[computeBatteryWarningLabel_(batteryPercent)]]
+            </div>
+            <template is="dom-if" if="[[isCharging]]">
+              <div>$i18n{migrationChargingLabel}</div>
+            </template>
+            <template is="dom-if" if="[[!isCharging]]">
+              <div>$i18n{migrationAskChargeMessage}</div>
+            </template>
+            <div>[[computeNecessaryBatteryLevelLabel_()]]</div>
+          </div>
+        </template>
+        </div>
         <template is="dom-if" if="[[!isResuming]]">
           <div class="bottom-buttons flex layout horizontal">
             <div class="flex"></div>
-            <oobe-text-button on-tap="onSkip_">Skip</oobe-text-button>
+            <oobe-text-button border on-tap="onSkip_">
+              <div>$i18n{migrationButtonSkip}</div>
+            </oobe-text-button>
             <oobe-text-button inverse on-tap="onUpgrade_"
-                disabled="[[isMigrationAccepted]]">Upgrade</oobe-text-button>
+                disabled="[[isMigrationAccepted]]">
+              <div>$i18n{migrationButtonUpdate}</div>
+            </oobe-text-button>
           </div>
         </template>
       </oobe-dialog>
     </template>
     <template is="dom-if" if="[[isMigrating_(uiState)]]">
       <oobe-dialog tabindex="0">
+        <iron-icon class="oobe-icon chrome-logo"></iron-icon>
         <div class="header">
-          <h1 class="title">Upgrading...</h1>
-          <div class="subtitle">Please do not shutdown. String TBD.</div>
+          <h1 class="title">$i18n{migrationMigratingTitle}</h1>
+          <div class="subtitle">$i18n{migrationMigratingDescription}</div>
         </div>
         <div class="footer flex layout vertical">
           <paper-progress value="[[progress]]" max="1" step="0.001"
               indeterminate="[[isProgressIndeterminate_(progress)]]">
           </paper-progress>
-        </div>
-      </oobe-dialog>
-    </template>
-    <template is="dom-if" if="[[isMigrationSucceeded_(uiState)]]">
-      <oobe-dialog tabindex="0" has-buttons>
-        <div class="header">
-          <h1 class="title">Upgrade successfully finished</h1>
-          <div class="subtitle">
-            The system will restart automatically. String TBD.
-          </div>
-        </div>
-        <div class="bottom-buttons flex layout horizontal">
-          <div class="flex"></div>
-          <oobe-text-button inverse on-tap="onRestart_">Restart Now
-          </oobe-text-button>
+          <template is="dom-if" if="[[!isProgressIndeterminate_(progress)]]">
+            <div>[[computeProgressLabel_(progress)]]</div>
+          </template>
         </div>
       </oobe-dialog>
     </template>
     <template is="dom-if" if="[[isMigrationFailed_(uiState)]]">
       <oobe-dialog tabindex="0" has-buttons>
+        <iron-icon icon="cr:warning" class="oobe-icon warning"></iron-icon>
         <div class="header">
-          <h1 class="title">Upgrade failed</h1>
-          <div class="subtitle">
-            The system encountered a problem during migration. String TBD.
-          </div>
+          <h1 class="title">$i18n{migrationFailedTitle}</h1>
+          <div class="subtitle">$i18n{migrationFailedSubtitle}</div>
         </div>
+        <div class="footer"><div>$i18n{migrationFailedMessage}</div></div>
         <div class="bottom-buttons flex layout horizontal">
           <div class="flex"></div>
-          <oobe-text-button inverse on-tap="onRestart_">Restart
+          <oobe-text-button inverse on-tap="onRestart_">
+            <div>$i18n{migrationButtonRestart}</div>
           </oobe-text-button>
         </div>
       </oobe-dialog>
     </template>
     <template is="dom-if" if="[[isNotEnoughSpace_(uiState)]]">
       <oobe-dialog tabindex="0" has-buttons>
+        <iron-icon class="oobe-icon chrome-logo"></iron-icon>
         <div class="header">
-          <h1 class="title">Not enough storage for update</h1>
-          <div class="subtitle">
-            Please free up some space on your device and sign in again.
-          </div>
+          <h1 class="title">$i18n{migrationReadyTitle}</h1>
+          <div class="subtitle">$i18n{migrationReadyDescription}</div>
+        </div>
+        <div class="footer layout vertical">
+          <div class="warning">$i18n{migrationNospaceWarningLabel}</div>
+          <div>$i18n{migrationAskFreeSpaceMessage}</div>
+          <div>[[computeAvailableSpaceLabel_(availableSpaceInString)]]</div>
+          <div>[[computeNecessarySpaceLabel_(necessarySpaceInString)]]</div>
         </div>
         <div class="bottom-buttons flex layout horizontal">
           <div class="flex"></div>
           <template is="dom-if" if="[[!isResuming]]">
-            <oobe-text-button inverse on-tap="onSkip_">Continue
+            <oobe-text-button inverse on-tap="onSkip_">
+              <div>$i18n{migrationButtonContinue}</div>
             </oobe-text-button>
           </template>
           <template is="dom-if" if="[[isResuming]]">
-            <oobe-text-button inverse on-tap="onRestart_">Restart
+            <oobe-text-button inverse on-tap="onRestart_">
+              <div>$i18n{migrationButtonRestart}</div>
             </oobe-text-button>
           </template>
         </div>
diff --git a/chrome/browser/resources/chromeos/login/encryption_migration.js b/chrome/browser/resources/chromeos/login/encryption_migration.js
index 494176a..1ca09d2 100644
--- a/chrome/browser/resources/chromeos/login/encryption_migration.js
+++ b/chrome/browser/resources/chromeos/login/encryption_migration.js
@@ -16,14 +16,15 @@
   INITIAL: 0,
   READY: 1,
   MIGRATING: 2,
-  MIGRATION_SUCCEEDED: 3,
-  MIGRATION_FAILED: 4,
-  NOT_ENOUGH_SPACE: 5
+  MIGRATION_FAILED: 3,
+  NOT_ENOUGH_SPACE: 4
 };
 
 Polymer({
   is: 'encryption-migration',
 
+  behaviors: [I18nBehavior],
+
   properties: {
     /**
      * Current UI state which corresponds to a sub step in migration process.
@@ -68,12 +69,36 @@
     },
 
     /**
+     * True if the device is charging.
+     */
+    isCharging: {
+      type: Boolean,
+      value: false
+    },
+
+    /**
      * True if the user already accepted the migration.
      */
     isMigrationAccepted: {
       type: Boolean,
       value: false
     },
+
+    /**
+     * Formatted string of the current available space size.
+     */
+    availableSpaceInString: {
+      type: String,
+      value: ''
+    },
+
+    /**
+     * Formatted string of the necessary space size for migration.
+     */
+    necessarySpaceInString: {
+      type: String,
+      value: ''
+    },
   },
 
   /**
@@ -104,15 +129,6 @@
   },
 
   /**
-   * Returns true if the migration is finished successfully.
-   * @param {EncryptionMigrationUIState} state Current UI state
-   * @private
-   */
-  isMigrationSucceeded_: function(state) {
-    return state == EncryptionMigrationUIState.MIGRATION_SUCCEEDED;
-  },
-
-  /**
    * Returns true if the migration failed.
    * @param {EncryptionMigrationUIState} state Current UI state
    * @private
@@ -140,6 +156,55 @@
   },
 
   /**
+   * Computes the label shown under progress bar.
+   * @param {number} progress
+   * @return {string}
+   * @private
+   */
+  computeProgressLabel_: function(progress) {
+    return this.i18n('migrationProgressLabel', Math.floor(progress * 100));
+  },
+
+  /**
+   * Computes the warning label when battery level is not enough.
+   * @param {number} batteryPercent
+   * @return {string}
+   * @private
+   */
+  computeBatteryWarningLabel_: function(batteryPercent) {
+    return this.i18n('migrationBatteryWarningLabel', batteryPercent);
+  },
+
+  /**
+   * Computes the label to show the necessary battery level for migration.
+   * @return {string}
+   * @private
+   */
+  computeNecessaryBatteryLevelLabel_: function() {
+    return this.i18n('migrationNecessaryBatteryLevelLabel', 30);
+  },
+
+  /**
+   * Computes the label to show the current available space.
+   * @param {string} availableSpaceInString
+   * @return {string}
+   * @private
+   */
+  computeAvailableSpaceLabel_: function(availableSpaceInString) {
+    return this.i18n('migrationAvailableSpaceLabel', availableSpaceInString);
+  },
+
+  /**
+   * Computes the label to show the necessary space to start migration.
+   * @param {string} necessarySpaceInString
+   * @return {string}
+   * @private
+   */
+  computeNecessarySpaceLabel_: function(necessarySpaceInString) {
+    return this.i18n('migrationNecessarySpaceLabel', necessarySpaceInString);
+  },
+
+  /**
    * Handles tap on UPGRADE button.
    * @private
    */
diff --git a/chrome/browser/resources/chromeos/login/images/security_update_1x.png b/chrome/browser/resources/chromeos/login/images/security_update_1x.png
new file mode 100644
index 0000000..ce542da
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/images/security_update_1x.png
Binary files differ
diff --git a/chrome/browser/resources/chromeos/login/images/security_update_2x.png b/chrome/browser/resources/chromeos/login/images/security_update_2x.png
new file mode 100644
index 0000000..56b01d4
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/images/security_update_2x.png
Binary files differ
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.js b/chrome/browser/resources/chromeos/login/oobe_dialog.js
index fc5ad21..7dc9d22 100644
--- a/chrome/browser/resources/chromeos/login/oobe_dialog.js
+++ b/chrome/browser/resources/chromeos/login/oobe_dialog.js
@@ -39,7 +39,7 @@
     */
   show: function() {
     var focusedElements = this.getElementsByClassName('focus-on-show');
-    if (focusedElements)
+    if (focusedElements.length > 0)
       focusedElements[0].focus();
 
     this.fire('show-dialog');
diff --git a/chrome/browser/resources/chromeos/login/screen_encryption_migration.js b/chrome/browser/resources/chromeos/login/screen_encryption_migration.js
index 200ede4..70740d3 100644
--- a/chrome/browser/resources/chromeos/login/screen_encryption_migration.js
+++ b/chrome/browser/resources/chromeos/login/screen_encryption_migration.js
@@ -9,7 +9,9 @@
       'setUIState',
       'setMigrationProgress',
       'setIsResuming',
-      'setBatteryPercent',
+      'setBatteryState',
+      'setAvailableSpaceInString',
+      'setNecessarySpaceInString',
     ],
 
     /**
@@ -73,11 +75,29 @@
      * Updates battery level of the device.
      * @param {number} batteryPercent Battery level in percent.
      * @param {boolean} isEnoughBattery True if the battery is enough.
+     * @param {boolena} isCharging True if the device is connected to power.
      */
-    setBatteryPercent: function(batteryPercent, isEnoughBattery) {
-      $('encryption-migration-element').batteryPercent =
-          Math.floor(batteryPercent);
-      $('encryption-migration-element').isEnoughBattery = isEnoughBattery;
+    setBatteryState: function(batteryPercent, isEnoughBattery, isCharging) {
+      var element = $('encryption-migration-element');
+      element.batteryPercent = Math.floor(batteryPercent);
+      element.isEnoughBattery = isEnoughBattery;
+      element.isCharging = isCharging;
+    },
+
+    /**
+     * Updates the string representation of available space size.
+     * @param {string} space
+     */
+    setAvailableSpaceInString: function(space) {
+      $('encryption-migration-element').availableSpaceInString = space;
+    },
+
+    /**
+     * Updates the string representation of necessary space size.
+     * @param {string} space
+     */
+    setNecessarySpaceInString: function(space) {
+      $('encryption-migration-element').necessarySpaceInString = space;
     },
   };
 });
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html
index 2b8a0168..93497c7 100644
--- a/chrome/browser/resources/settings/icons.html
+++ b/chrome/browser/resources/settings/icons.html
@@ -69,7 +69,6 @@
 </if>
       <g id="help-outline"><path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"></path></g>
       <g id="info"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"></path></g>
-      <g id="input"><path d="M21 3.01H3c-1.1 0-2 .9-2 2V9h2V4.99h18v14.03H3V15H1v4.01c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98v-14c0-1.11-.9-2-2-2zM11 16l4-4-4-4v3H1v2h10v3z"></path></g>
 <if expr="chromeos">
       <g id="keyboard"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"></path></g>
 </if>
@@ -83,6 +82,7 @@
       <g id="lock"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"></path></g>
 </if>
       <g id="mic"><path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"></path></g>
+      <g id="midi"><path d="M21,19.1H3V5h18V19.1z M21,3H3C1.9,3,1,3.9,1,5v14c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"></path><path fill="none" d="M21,19.1H3V5h18V19.1z M21,3H3C1.9,3,1,3.9,1,5v14c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"></path><path d="M14,5h3v8h-3V5z"></path><path d="M15,12h1v8h-1V12z"></path><path fill="none" d="M0,0h24v24H0V0z"></path><rect x="7" y="5" width="3" height="8"></rect><rect x="8" y="12" width="1" height="8"></rect></g>
 <if expr="chromeos">
       <g id="mouse"><path d="M13 1.07V9h7c0-4.08-3.05-7.44-7-7.93zM4 15c0 4.42 3.58 8 8 8s8-3.58 8-8v-4H4v4zm7-13.93C7.05 1.56 4 4.92 4 9h7V1.07z"></path></g>
 </if>
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.js b/chrome/browser/resources/settings/internet_page/network_summary_item.js
index 23f7b60c..377c807 100644
--- a/chrome/browser/resources/settings/internet_page/network_summary_item.js
+++ b/chrome/browser/resources/settings/internet_page/network_summary_item.js
@@ -159,12 +159,17 @@
    * @private
    */
   onShowDetailsTap_: function(event) {
-    if (this.shouldShowList_())
+    if (!this.deviceIsEnabled_(this.deviceState)) {
+      this.fire(
+          'device-enabled-toggled',
+          {enabled: true, type: this.deviceState.Type});
+    } else if (this.shouldShowList_()) {
       this.fire('show-networks', this.deviceState);
-    else if (this.activeNetworkState.GUID)
+    } else if (this.activeNetworkState.GUID) {
       this.fire('show-detail', this.activeNetworkState);
-    else if (this.networkStateList.length > 0)
+    } else if (this.networkStateList.length > 0) {
       this.fire('show-detail', this.networkStateList[0]);
+    }
     event.stopPropagation();
   },
 
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 7b23e1a..b6e0dce6 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -287,7 +287,7 @@
           <category-setting-exceptions
               category="{{ContentSettingsTypes.COOKIES}}">
           </category-setting-exceptions>
-          <site-data></site-data>
+          <site-data focus-config="[[focusConfig_]]"></site-data>
         </settings-subpage>
       </template>
       <template is="dom-if" route-path="/content/images" no-search>
diff --git a/chrome/browser/resources/settings/settings_page/settings_animated_pages.js b/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
index 5e71132e..3da7e7a 100644
--- a/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
+++ b/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
@@ -59,10 +59,18 @@
     if (!this.focusConfig || !this.previousRoute_)
       return;
 
+    // Don't attempt to focus any anchor element, unless last navigation was a
+    // 'pop' (backwards) navigation.
+    if (!settings.lastRouteChangeWasPopstate())
+      return;
+
     // Only handle iron-select events from neon-animatable elements and the
-    // SITE_SETTINGS subpage only.
+    // given whitelist of settings-subpage instances.
     if (!e.detail.item.matches(
-        'neon-animatable, settings-subpage#site-settings')) {
+        'neon-animatable, ' +
+        'settings-subpage#site-settings, ' +
+        'settings-subpage[route-path=\"' +
+            settings.Route.SITE_SETTINGS_COOKIES.path + '\"]')) {
       return;
     }
 
diff --git a/chrome/browser/resources/settings/site_settings/site_data.js b/chrome/browser/resources/settings/site_settings/site_data.js
index 83e9ac0..d7dca1a 100644
--- a/chrome/browser/resources/settings/site_settings/site_data.js
+++ b/chrome/browser/resources/settings/site_settings/site_data.js
@@ -34,6 +34,30 @@
 
     /** @private */
     confirmationDeleteMsg_: String,
+
+    /** @type {!Map<string, string>} */
+    focusConfig: {
+      type: Object,
+      observer: 'focusConfigChanged_',
+    },
+  },
+
+  /**
+   * @param {!Map<string, string>} newConfig
+   * @param {?Map<string, string>} oldConfig
+   * @private
+   */
+  focusConfigChanged_: function(newConfig, oldConfig) {
+    // focusConfig is set only once on the parent, so this observer should only
+    // fire once.
+    assert(!oldConfig);
+
+    // Populate the |focusConfig| map of the parent <settings-animated-pages>
+    // element, with additional entries that correspond to subpage trigger
+    // elements residing in this element's Shadow DOM.
+    this.focusConfig.set(
+        settings.Route.SITE_SETTINGS_DATA_DETAILS.path,
+        '* /deep/ #filter /deep/ #searchInput');
   },
 
   /** @override */
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index 029e887b..d65bdd6 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -83,7 +83,7 @@
           label="$i18n{siteSettingsNotifications}" site="[[site]]">
       </site-details-permission>
       <site-details-permission category="{{ContentSettingsTypes.JAVASCRIPT}}"
-          icon="settings:input" id="javascript"
+          icon="settings:code" id="javascript"
           label="$i18n{siteSettingsJavascript}" site="[[site]]">
       </site-details-permission>
       <site-details-permission category="{{ContentSettingsTypes.PLUGINS}}"
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
index 8451c84..17cfd6e 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
@@ -119,7 +119,7 @@
         category$="[[ContentSettingsTypes.JAVASCRIPT]]"
         data-route="SITE_SETTINGS_JAVASCRIPT" on-tap="onTapNavigate_"
         actionable>
-      <iron-icon icon="settings:input"></iron-icon>
+      <iron-icon icon="settings:code"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsJavascript}
         <div class="secondary" id="javascriptSecondary">
@@ -283,7 +283,7 @@
         category$="[[ContentSettingsTypes.MIDI_DEVICES]]"
         data-route="SITE_SETTINGS_MIDI_DEVICES"
         on-tap="onTapNavigate_" actionable>
-      <iron-icon icon="settings:music-note"></iron-icon>
+      <iron-icon icon="settings:midi"></iron-icon>
       <div class="middle">
         $i18n{siteSettingsMidiDevices}
         <div class="secondary" id="midiDevicesSecondary">
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
index 5c489d72..a3d54f2 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -49,7 +49,6 @@
       }
     },
 
-
     /** @type {!Map<string, string>} */
     focusConfig: {
       type: Object,
diff --git a/chrome/browser/resources/vr_shell/OWNERS b/chrome/browser/resources/vr_shell/OWNERS
deleted file mode 100644
index f104584a8..0000000
--- a/chrome/browser/resources/vr_shell/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-bshe@chromium.org
-girard@chromium.org
-mthiesse@chromium.org
-cjgrant@chromium.org
-
-# COMPONENT: UI>Browser>VR
diff --git a/chrome/browser/resources/vr_shell/compiled_resources2.gyp b/chrome/browser/resources/vr_shell/compiled_resources2.gyp
deleted file mode 100644
index 3c01fc12dc..0000000
--- a/chrome/browser/resources/vr_shell/compiled_resources2.gyp
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'targets': [
-    {
-      'target_name': 'vr_shell_ui_api',
-      'dependencies': [
-        '<(EXTERNS_GYP):chrome_send',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-    {
-      'target_name': 'vr_shell_ui_scene',
-      'dependencies': [
-        'vr_shell_ui_api',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-    {
-      'target_name': 'vk',
-      'dependencies': [
-        'vr_shell_ui_api',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-    {
-      'target_name': 'vr_shell_ui',
-      'dependencies': [
-        'vr_shell_ui_api',
-        'vr_shell_ui_scene',
-        'vk',
-      ],
-      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
-    },
-  ],
-}
diff --git a/chrome/browser/resources/vr_shell/vk.css b/chrome/browser/resources/vr_shell/vk.css
deleted file mode 100644
index 4604f4d0..0000000
--- a/chrome/browser/resources/vr_shell/vk.css
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-.inputview-container {
-  float: left;
-  font-family: Roboto2, Roboto, 'Noto Sans', sans-serif;
-  height: 340px;
-  user-select: none;
-  width: 1228px;
-}
-
-.inputview-spacerview {
-  display: inline-block;
-  float: left;
-  overflow: hidden;
-  padding: 32px;
-  position: relative;
-}
-
-.inputview-layoutview {
-  background-color: rgb(71, 71, 71);
-  border: 2px solid rgb(128, 128, 128);
-  border-radius: 10px;
-  display: inline-block;
-  float: left;
-  overflow: hidden;
-  padding: 32px;
-  position: relative;
-}
-
-.inputview-softkey-view {
-  box-sizing: border-box;
-  display: inline-block;
-  overflow: hidden;
-  padding: 3px 2px;
-}
-
-.inputview-softkey {
-  background-color: rgb(71, 71, 71);
-  border-radius: 5px;
-  display: block;
-  height: 100%;
-  position: relative;
-  width: 100%;
-}
-
-.inputview-softkey:hover {
-  background-color: rgb(110, 112, 114);
-}
-
-.inputview-softkey:active {
-  background-color: rgb(90, 93, 95);
-}
-
-.inputview-softkey-spacer:hover {
-  background-color: inherit;
-}
-
-.inputview-ch {
-  color: rgba(236, 236, 236, 0.8);
-  display: inline-block;
-  font-size: 30px;
-  position: absolute;
-  text-align: center;
-  top: 15%;
-  width: 100%;
-}
-
-.inputview-ch {
-  display: block;
-}
-
-.inputview-level {
-  display: none;
-}
-
-.inputview-active-level-0 .inputview-level-0,
-.inputview-active-level-1 .inputview-level-1,
-.inputview-active-level-2 .inputview-level-2,
-.inputview-active-level-3 .inputview-level-3 {
-  display: block;
-}
-
-.vk-icon {
-  display: block;
-  left: 50%;
-  position: absolute;
-  top: 50%;
-}
-
-.vk-escape-icon {
-  background: url(../../../../ui/webui/resources/images/hidekeyboard.svg)
-      transparent no-repeat 0 0/32px 32px;
-  height: 32px;
-  margin: -16px 0 0 -16px;
-  width: 32px;
-}
-
-.vk-backspace-icon {
-  background: url(../../../../ui/webui/resources/images/backspace.svg)
-      transparent no-repeat 0 0/24px 24px;
-  height: 24px;
-  margin: -12px 0 0 -12px;
-  width: 24px;
-}
-
-.vk-space-icon {
-  background-color: rgba(165, 161, 169, 0.35);
-  border-radius: 40px;
-  height: 100%;
-  left: 0;
-  top: 0;
-  width: 100%;
-}
-
-.inputview-code-space:hover {
-  background-color: rgba(165, 161, 169, 0.35);
-  border-radius: 40px;
-}
-.inputview-code-space:active {
-  background-color: rgb(90, 93, 95);
-}
-
diff --git a/chrome/browser/resources/vr_shell/vk.js b/chrome/browser/resources/vr_shell/vk.js
deleted file mode 100644
index 6a47eed..0000000
--- a/chrome/browser/resources/vr_shell/vk.js
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var vrShellVK = (function() {
-  /** @const */ var VK_L_PANEL_LAYOUT = [
-    [
-      {'code': 'Key1', 'key': '1'},
-      {'code': 'Key2', 'key': '2'},
-      {'code': 'Key3', 'key': '3'},
-    ],
-    [
-      {'code': 'Key4', 'key': '4'},
-      {'code': 'Key5', 'key': '5'},
-      {'code': 'Key6', 'key': '6'},
-    ],
-    [
-      {'code': 'Key7', 'key': '7'},
-      {'code': 'Key8', 'key': '8'},
-      {'code': 'Key9', 'key': '9'},
-    ],
-    [
-      {'code': 'KeyNegative', 'key': '-'},
-      {'code': 'Key0', 'key': '0'},
-      {'code': 'KeyPoint', 'key': '.'},
-    ]
-  ];
-
-  /** @const */ var VK_R_PANEL_LAYOUT = [
-    [
-      {
-        'code': 'Backspace',
-        'key': 'Backspace',
-        'image-class': 'vk-backspace-icon'
-      },
-    ],
-    [
-      {
-        'code': 'Enter',
-        'key': 'Enter',
-        'height': 2.0,
-        'text' : '\u{021B2}',
-      },
-    ],
-    [
-      {
-        'code': 'Abort',
-        'key': 'Escape',
-        'image-class': 'vk-escape-icon',
-        'action': vkHide
-      },
-    ],
-  ];
-
-  /** @const */ var VK_LAYOUTS = {
-    'en-us-compact': {
-      'levels': [
-        [
-          // Level 0: Unshifted.
-          [
-            {'code': 'KeyQ', 'key': 'q'},
-            {'code': 'KeyW', 'key': 'w'},
-            {'code': 'KeyE', 'key': 'e'},
-            {'code': 'KeyR', 'key': 'r'},
-            {'code': 'KeyT', 'key': 't'},
-            {'code': 'KeyY', 'key': 'y'},
-            {'code': 'KeyU', 'key': 'u'},
-            {'code': 'KeyI', 'key': 'i'},
-            {'code': 'KeyO', 'key': 'o'},
-            {'code': 'KeyP', 'key': 'p'},
-          ],
-          [
-            {'width': 0.5, 'display': 'spacer'},
-            {'code': 'KeyA', 'key': 'a'},
-            {'code': 'KeyS', 'key': 's'},
-            {'code': 'KeyD', 'key': 'd'},
-            {'code': 'KeyF', 'key': 'f'},
-            {'code': 'KeyG', 'key': 'g'},
-            {'code': 'KeyH', 'key': 'h'},
-            {'code': 'KeyJ', 'key': 'j'},
-            {'code': 'KeyK', 'key': 'k'},
-            {'code': 'KeyL', 'key': 'l'},
-          ],
-          [
-            {
-              'code': 'ShiftLeft',
-              'key': 'Shift',
-              'text' : '\u{021E7}',
-              'action': vkLevel,
-              'level': 1
-            },
-            {'code': 'KeyZ', 'key': 'z'},
-            {'code': 'KeyX', 'key': 'x'},
-            {'code': 'KeyC', 'key': 'c'},
-            {'code': 'KeyV', 'key': 'v'},
-            {'code': 'KeyB', 'key': 'b'},
-            {'code': 'KeyN', 'key': 'n'},
-            {'code': 'KeyM', 'key': 'm'},
-            {'code': '', 'key': '!'},
-            {'code': '', 'key': '?'},
-          ],
-          [
-            {
-              'code': 'AltRight',
-              'key': 'AltGraph',
-              'text': '=\\<',
-              'action': vkLevel,
-              'level': 2
-            },
-            {'code': 'Slash', 'key': '/'},
-            {
-              'code': 'space',
-              'key': ' ',
-              'width': 6.00,
-              'image-class': 'vk-space-icon'
-            },
-            {'code': 'Comma', 'key': ','},
-            {'code': 'Period', 'key': '.'},
-          ]
-        ],
-        [
-          // Level 1: Shifted.
-          [
-            {'code': 'KeyQ', 'key': 'Q'},
-            {'code': 'KeyW', 'key': 'W'},
-            {'code': 'KeyE', 'key': 'E'},
-            {'code': 'KeyR', 'key': 'R'},
-            {'code': 'KeyT', 'key': 'T'},
-            {'code': 'KeyY', 'key': 'Y'},
-            {'code': 'KeyU', 'key': 'U'},
-            {'code': 'KeyI', 'key': 'I'},
-            {'code': 'KeyO', 'key': 'O'},
-            {'code': 'KeyP', 'key': 'P'},
-          ],
-          [
-            {'width': 0.5, 'display': 'spacer'},
-            {'code': 'KeyA', 'key': 'A'},
-            {'code': 'KeyS', 'key': 'S'},
-            {'code': 'KeyD', 'key': 'D'},
-            {'code': 'KeyF', 'key': 'F'},
-            {'code': 'KeyG', 'key': 'G'},
-            {'code': 'KeyH', 'key': 'H'},
-            {'code': 'KeyJ', 'key': 'J'},
-            {'code': 'KeyK', 'key': 'K'},
-            {'code': 'KeyL', 'key': 'L'},
-          ],
-          [
-            {
-              'code': 'ShiftLeft',
-              'key': 'Shift',
-              'text' : '\u{021E7}',
-              'action': vkLevel,
-              'level': 0,
-            },
-            {'code': 'KeyZ', 'key': 'Z'},
-            {'code': 'KeyX', 'key': 'X'},
-            {'code': 'KeyC', 'key': 'C'},
-            {'code': 'KeyV', 'key': 'V'},
-            {'code': 'KeyB', 'key': 'B'},
-            {'code': 'KeyN', 'key': 'N'},
-            {'code': 'KeyM', 'key': 'M'},
-            {'code': '', 'key': '!'},
-            {'code': '', 'key': '?'},
-          ],
-          [
-            {
-              'code': 'AltRight',
-              'key': 'AltGraph',
-              'text': '=\\<',
-              'action': vkLevel,
-              'level': 2
-            },
-            {'code': 'Slash', 'key': '/'},
-            {
-              'code': 'space',
-              'key': ' ',
-              'width': 6.00,
-              'image-class': 'vk-space-icon'
-            },
-            {'code': 'Comma', 'key': ','},
-            {'code': 'Period', 'key': '.'},
-          ]
-        ],
-        [
-          // Level 2: Symbols.
-          [
-            {'code': 'KeyQ', 'key': '!'},
-            {'code': 'KeyW', 'key': '@'},
-            {'code': 'KeyE', 'key': '#'},
-            {'code': 'KeyR', 'key': '$'},
-            {'code': 'KeyT', 'key': '%'},
-            {'code': 'KeyY', 'key': '^'},
-            {'code': 'KeyU', 'key': '&'},
-            {'code': 'KeyI', 'key': '*'},
-            {'code': 'KeyO', 'key': '('},
-            {'code': 'KeyP', 'key': ')'},
-          ],
-          [
-            {'width': 0.5, 'display': 'spacer'},
-            {'code': 'KeyA', 'key': '~'},
-            {'code': 'KeyS', 'key': '`'},
-            {'code': 'KeyD', 'key': '|'},
-            {'code': 'KeyF', 'key': '{'},
-            {'code': 'KeyG', 'key': '}'},
-            {'code': 'KeyH', 'key': '['},
-            {'code': 'KeyJ', 'key': ']'},
-            {'code': 'KeyK', 'key': '-'},
-            {'code': 'KeyL', 'key': '_'},
-          ],
-          [
-            {'code': 'ShiftLeft', 'key': '/'},
-            {'code': 'KeyZ', 'key': '\\'},
-            {'code': 'KeyX', 'key': '+'},
-            {'code': 'KeyC', 'key': '='},
-            {'code': 'KeyV', 'key': ':'},
-            {'code': 'KeyB', 'key': ';'},
-            {'code': 'KeyN', 'key': '\''},
-            {'code': 'KeyM', 'key': '<'},
-            {'key': '>'},
-            {'key': '"'},
-          ],
-          [
-            {
-              'code': 'AltRight',
-              'key': 'AltGraph',
-              'text': 'ABC',
-              'action': vkLevel,
-              'level': 0,
-            },
-            {'code': 'Slash', 'key': '/'},
-            {
-              'code': 'space',
-              'key': ' ',
-              'width': 6.00,
-              'image-class': 'vk-space-icon'
-            },
-            {'code': 'Comma', 'key': ','},
-            {'code': 'Period', 'key': '.'},
-          ]
-        ]
-      ]
-    }
-  };
-
-  /** @const */ var VK_BUTTON_SIZE = [64, 64, 'px'];
-
-  var vkState = {'query': {'language': 'en-us', 'layout': 'compact'}};
-
-  function vkHide(button) {
-    // TODO(asimjour): Send a key event to support vkHide.
-  }
-
-  function vkLevel(button) {
-    vkCh(button);
-    vkActivateLevel(button.level);
-  }
-
-  function vkLevel0(button) {
-    vkCh(button);
-    vkActivateLevel(0);
-  }
-
-  function vkCh(button) {
-    if (button.key || button.code) {
-      // This code limits use of the HTML keyboard to the omnibox.
-      document.querySelector("#omnibox-input-field").focus();
-
-      if (button.code != 'AltRight')
-        sendKey('key', button.code, button.key);
-      if (vkState.level == 1)
-        vkActivateLevel(0);
-    }
-  }
-
-  function vkOnClick(e) {
-    var button = e.vkButtonData;
-    button.action(button);
-  }
-
-  function vkActivateLevel(n) {
-    vkState.view.classList.remove('inputview-active-level-' + vkState.level);
-    vkState.level = n;
-    vkState.view.classList.add('inputview-active-level-' + vkState.level);
-  }
-
-  function vkNormalizeButtonData(buttonData) {
-    if (!buttonData.text) {
-      if (buttonData.key && !buttonData['image-class'])
-        buttonData.text = buttonData.key;
-      else
-        buttonData.text = null;
-    }
-    buttonData.action = buttonData.action || vkCh;
-    buttonData.width = buttonData.width || 1.00;
-    buttonData.height = buttonData.height || 1.00;
-
-    if (buttonData.display)
-      buttonData.display = 'inputview-softkey-' + buttonData.display;
-    else if (buttonData['image-class'])
-      buttonData.display = 'inputview-softkey-0';
-    else if (buttonData.text)
-      buttonData.display = 'inputview-softkey-1';
-    else
-      buttonData.display = 'inputview-softkey-none';
-
-    buttonData.styleWidth =
-        (buttonData.width * VK_BUTTON_SIZE[0]) + VK_BUTTON_SIZE[2];
-    buttonData.styleHeight =
-        (buttonData.height * VK_BUTTON_SIZE[1]) + VK_BUTTON_SIZE[2];
-    return buttonData;
-  }
-
-  function vkMkButton(index, buttonData) {
-    var button = document.createElement('div');
-
-    buttonData = vkNormalizeButtonData(buttonData);
-    button.vkButtonData = buttonData
-    button.classList.add('inputview-softkey-view');
-    button.style.width = buttonData.styleWidth;
-    button.style.height = buttonData.styleHeight;
-    button.onclick = function() {
-      vkOnClick(button);
-    };
-
-    var key = document.createElement('div');
-    key.classList.add('inputview-softkey', buttonData.display);
-    if (button.vkButtonData.code)
-      key.classList.add('inputview-code-' + buttonData.code);
-    var keyContent = key;
-    if (button.vkButtonData['image-class']) {
-      keyContent = document.createElement('div');
-      keyContent.classList.add(button.vkButtonData['image-class'], 'vk-icon');
-      key.appendChild(keyContent);
-    }
-    if (button.vkButtonData.class)
-      keyContent.classList.add(button.vkButtonData.class);
-
-    if (buttonData.text) {
-      var charKey = document.createElement('div');
-      charKey.classList.add('inputview-ch');
-      charKey.textContent = buttonData.text;
-      keyContent.appendChild(charKey);
-    }
-
-    button.appendChild(key);
-    return button;
-  }
-
-  function vkMkRow(index, rowData) {
-    var row = document.createElement('div');
-    row.id = 'row' + index;
-    row.classList.add('inputview-row');
-    for (var c = 0; c < rowData.length; ++c)
-      row.appendChild(vkMkButton(c, rowData[c]));
-    return row;
-  }
-
-  function vkMkLevel(index, levelData) {
-    var level = document.createElement('div');
-    level.id = 'level' + index;
-    level.classList.add('inputview-level', 'inputview-level-' + index);
-    for (var r = 0; r < levelData.length; ++r)
-      level.appendChild(vkMkRow(r, levelData[r]));
-    return level;
-  }
-
-  function vkMkKb(view, layout) {
-    vkState.view = view;
-    vkState.layout = layout;
-    vkState.levels = layout.levels.length;
-    for (var key = 0; key < layout.levels.length; ++key)
-      view.appendChild(vkMkLevel(key, vkState.layout.levels[key]));
-  }
-
-  function vkMkPanel(view, lPanelData) {
-    for (var r = 0; r < lPanelData.length; ++r)
-      view.appendChild(vkMkRow(r, lPanelData[r]));
-  }
-
-  function vkOnLoad() {
-    // Build keyboard.
-    vkState.layoutName = vkState.query.language + '-' + vkState.query.layout;
-    vkMkKb(
-        document.querySelector('#keyboardView'),
-        VK_LAYOUTS[vkState.layoutName]);
-    vkMkPanel(document.querySelector('#numberView'), VK_L_PANEL_LAYOUT);
-    vkMkPanel(document.querySelector('#specialkeyView'), VK_R_PANEL_LAYOUT);
-
-    vkActivateLevel(0);
-  }
-
-  // Flag values for ctrl, alt and shift as defined by EventFlags
-  // in "event_constants.h".
-  // @enum {number}
-  var Modifier = {NONE: 0, ALT: 8, CONTROL: 4, SHIFT: 2};
-
-  /** @const */ var DOM_KEYS = {
-    'Backspace': 0x08,
-    'Enter': 0x0D,
-    'Escape': 0x1B,
-    'AltGraph': 0x200103,
-  };
-
-  function domKeyValue(key) {
-    if (key) {
-      if (typeof key == 'number')
-        return key;
-      if (key.length == 1)
-        return key.charCodeAt(0);
-      if (DOM_KEYS.hasOwnProperty(key))
-        return DOM_KEYS[key];
-    }
-    return 0;
-  }
-
-  /**
-    * Dispatches a virtual key event. The system VK does not use the IME
-    * API as its primary role is to work in conjunction with a non-VK aware
-    * IME.
-    */
-  function sendKeyEvent(type, ch, code, name, modifiers) {
-    var event = {
-      type: type,
-      charValue: ch,
-      keyCode: code,
-      keyName: name,
-      modifiers: modifiers
-    };
-    api.doAction(api.Action.KEY_EVENT, event);
-  }
-
-  function sendKey(type, codeName, key) {
-    sendKeyEvent(type, domKeyValue(key), 0, codeName, 0);
-  }
-
-  return {vkOnLoad: vkOnLoad};
-})();
-
-document.addEventListener('DOMContentLoaded', vrShellVK.vkOnLoad);
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.css b/chrome/browser/resources/vr_shell/vr_shell_ui.css
deleted file mode 100644
index 025a3bc3..0000000
--- a/chrome/browser/resources/vr_shell/vr_shell_ui.css
+++ /dev/null
@@ -1,350 +0,0 @@
-/* Copyright 2016 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-html {
-  background-color: rgba(255, 255, 255, 0);
-}
-
-#ui {
-  left: 0;
-  position: absolute;
-  top: 0;
-  transform-origin: left top;
-  width: 1920px;
-}
-
-/* This class manages the position of elements on the texture page.
- * Each UI element should have a bounding div of this class. */
-.ui-element {
-  float: left;
-  margin: 2px;
-}
-
-.webvr-message-box {
-  align-items: center;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-}
-
-#webvr-not-secure-permanent .webvr-not-secure-icon {
-  display: inline-block;
-  margin: 20px 0;
-  vertical-align: middle;
-}
-
-#webvr-not-secure-permanent .webvr-string {
-  display: inline-block;
-  margin: 20px 10.5px;
-  vertical-align: middle;
-}
-
-/* This is a single-line (nowrap) short message. The width is elastic for
- * translations, and the underlying string had a request to translators
- * to keep it short. */
-#webvr-not-secure-permanent .webvr-box {
-  background-color: white;
-  border-radius: 6px;
-  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
-  box-sizing: border-box;
-  color: #444;
-  font-size: 26px;
-  height: 78px;
-  min-width: 226px;
-  overflow: hidden;
-  padding: 0 20px;
-  white-space: nowrap;
-}
-
-/* This uses fixed width but the height is elastic for translations. */
-#webvr-not-secure-transient > div {
-  background-color: rgba(26, 26, 26, 0.8);
-  border-radius: 6px;
-  box-sizing: border-box;
-  color: white;
-  display: flex;
-  flex-direction: column;
-  font-size: 26px;
-  justify-content: center;
-  line-height: 1.4;
-  min-height: 160px;
-  overflow: hidden;
-  padding: 20px;
-  text-align: center;
-  width: 512px;
-}
-
-.gesture-indicator {
-  background-color: rgba(0, 0, 0, 0);
-  background-position: center;
-  background-repeat: no-repeat;
-  background-size: contain;
-  height: 192px;
-  margin: auto auto;
-  width: 192px;
-}
-
-.round-button {
-  background-color: #fbfbfb;
-  background-position: center;
-  background-repeat: no-repeat;
-  background-size: 70px;
-  border-radius: 6px;
-  height: 112px;
-  margin: auto auto;
-  opacity: 0.8;
-  transition: opacity 50ms ease-in-out;
-  width: 112px;
-}
-
-.button-caption {
-  color: white;
-  font-size: 24px;
-  max-width: 192px;
-  opacity: 0;
-  overflow: hidden;
-  text-align: center;
-  transition: opacity 50ms ease-in-out;
-  white-space: nowrap;
-}
-
-.rect-button {
-  background-color: #eee;
-  border-radius: 6px;
-  color: black;
-  font-size: 20px;
-  line-height: 96px;
-  opacity: 0.8;
-  overflow: hidden;
-  text-align: center;
-  text-transform: uppercase;
-  vertical-align: middle;
-  white-space: nowrap;
-  width: 300px;
-}
-
-.rect-button:hover {
-  opacity: 1;
-}
-
-.disabled-button {
-  background-color: #bbb;
-}
-
-#back-button,
-#forward-button,
-#exit-present-button,
-#back-indicator,
-#forward-indicator {
-  background-image: url(../../../../ui/webui/resources/images/vr_back.svg);
-}
-
-#reload-button {
-  background-image: url(../../../../ui/webui/resources/images/vr_reload.svg);
-}
-
-#forward-button,
-#forward-indicator {
-  transform: scaleX(-1);
-}
-
-#reload-ui-button {
-  --rotX: -0.2;
-  --rotY: 0;
-  --rotZ: 0;
-  --scale: 1;
-  --tranX: 0;
-  --tranY: -0.7;
-  --tranZ: -0.4;
-  background-color: rgba(255,255,255,0.25);
-  color: white;
-  font-size: 24px;
-  padding: 12px;
-}
-
-#reload-ui-button:hover {
-  background-color: turquoise;
-}
-
-#content-interceptor {
-  height: 1px;
-  opacity: 0;
-  width: 1px;
-}
-
-.tab {
-  background-color: #eee;
-  border-radius: 6px;
-  color: black;
-  display: inline-block;
-  font-size: 20px;
-  height: 30px;
-  line-height: 30px;
-  margin: 0 15px 0 15px;
-  overflow: hidden;
-  padding: 12px;
-  vertical-align: middle;
-  white-space: nowrap;
-  width: 300px;
-}
-
-.tab-incognito {
-  background-color: #525252;
-  color: white;
-}
-
-/* The tab container element behaves like a scroll view (in conjunction with the
- * clip view). */
-#tab-container {
-  height: 54px;
-  overflow-x: scroll;
-  overflow-y: hidden;
-  white-space: nowrap;
-  width: 1000px;
-}
-
-/* The tab clip element's width will be programmatically set to the total width
- * of all it's children (the tabs). By doing so, the tabs can be scrolled
- * horizontally in the tab container element. */
-#tab-clip {
-  margin: 0 auto;
-  overflow: hidden;
-}
-
-#url-indicator-container {
-  --scale: 1.2;
-  --tranX: 0;
-  --tranY: -0.75;
-  --tranZ: -1.8;
-}
-
-#url-indicator-border {
-  --fadeTimeMs: 200;
-  --fadeYOffset: -0.05;
-  --opacity: 0.9;
-  --statusBarColor: rgb(66, 133, 244);
-  background-color: #ececec;
-  border-radius: 6px;
-  padding: 6px;
-}
-
-#url-indicator {
-  align-items: center;
-  background-color: #ececec;
-  border-radius: 6px;
-  box-sizing: border-box;
-  display: flex;
-  height: 104px;
-  justify-content: center;
-  overflow: hidden;
-  white-space: nowrap;
-  width: 512px;
-}
-
-#url-indicator-content {
-  align-items: center;
-  display: flex;
-  max-width: 448px;
-}
-
-.url-indicator-icon {
-  -webkit-mask-size: 50px;
-  display: none;
-  flex: none;
-  height: 50px;
-  margin-right: 10px;
-  width: 50px;
-}
-
-#url-indicator-info-icon {
-  -webkit-mask-image: url(../../../../ui/webui/resources/images/i_circle.svg);
-  background-color: rgb(90, 90, 90);
-}
-
-#url-indicator-lock-icon {
-  -webkit-mask-image: url(../../../../ui/webui/resources/images/lock.svg);
-  background-color: rgb(11, 128, 67);
-}
-
-#url-indicator-warning-icon {
-  -webkit-mask-image: url(../../../../ui/webui/resources/images/warning.svg);
-  background-color: rgb(199, 56, 33);
-}
-
-#url-indicator #url {
-  color: #252525;
-  font-size: 48px;
-  overflow: hidden;
-  white-space: nowrap;
-  width: 100%;
-}
-
-#url-indicator #path {
-  color: #868686;
-}
-
-#omnibox-ui-element {
-  background-color: transparent;
-  box-sizing: border-box;
-  font-size: 16px;
-  width: 368px;
-}
-
-#suggestions {
-  border: 1px solid transparent;
-  box-sizing: border-box;
-}
-
-.suggestion {
-  align-items: center; /* Vertically center text in div. */
-  background-color: white;
-  /* Use a transparent border to hide text overflow, but allow background to
-   * color show through. */
-  border-left: 5px solid transparent;
-  border-right: 5px solid transparent;
-  box-sizing: border-box;
-  display: flex;
-  height: 24px;
-  overflow: hidden;
-  white-space: nowrap;
-}
-
-.suggestion:hover {
-  background-color: orange;
-}
-
-#omnibox-border {
-  --statusBarColor: rgb(66, 133, 244);
-  background-color: white;
-  border-radius: 8px;
-  padding: 3px;
-}
-
-#omnibox-contents {
-  background-color: white;
-  border-radius: 6px;
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: row-reverse; /* Right-justify for convienence. */
-  height: 64px;
-  margin-top: 2px;
-  padding: 8px;
-  transition: background-color 50ms ease-in-out;
-}
-
-#omnibox-input-field {
-  background-color: transparent;
-  border: none;
-  font-size: 27px;
-  outline: none; /* Do not show an outline when focused. */
-  overflow: hidden;
-  text-align: center;
-  white-space: nowrap;
-  width: 100%;
-}
-
-#omnibox-clear-button {
-  background: url(../../../../ui/webui/resources/images/x-hover.png) no-repeat center center;
-  width: 18px;
-}
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.html b/chrome/browser/resources/vr_shell/vr_shell_ui.html
deleted file mode 100644
index 8d65649..0000000
--- a/chrome/browser/resources/vr_shell/vr_shell_ui.html
+++ /dev/null
@@ -1,118 +0,0 @@
-<!--
-Copyright 2016 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<if expr="is_android or is_ios">
-<meta name="viewport" content="width=device-width, initial-scale=1.0,
-    maximum-scale=1.0, user-scalable=no">
-<meta http-equiv="cache-control" content="no-cache">
-<meta http-equiv="pragma" content="no-cache">
-</if>
-<title>Vr Shell UIs</title>
-<link rel="stylesheet" href="vr_shell_ui.css">
-<link rel="stylesheet" href="vk.css">
-<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
-</head>
-<body>
-  <div id="ui">
-    <div id="webvr-not-secure-permanent" class="webvr-message-box ui-element">
-      <div class="webvr-box">
-        <img class="webvr-not-secure-icon" width="36" height="36"
-             src="../../../../ui/webui/resources/images/i_circle.svg">
-        <div class="webvr-string">$i18n{insecureWebVrContentPermanent}</div>
-      </div>
-    </div>
-    <div id="webvr-not-secure-transient" class="webvr-message-box ui-element">
-      <div>
-        <div>$i18n{insecureWebVrContentTransient}</div>
-      </div>
-    </div>
-    <div id="url-indicator-container" class="ui-element">
-      <div id="url-indicator-border">
-        <div id="url-indicator">
-          <div id="url-indicator-content">
-            <div id="url-indicator-info-icon" class="url-indicator-icon"></div>
-            <div id="url-indicator-lock-icon" class="url-indicator-icon"></div>
-            <div id="url-indicator-warning-icon" class="url-indicator-icon">
-            </div>
-            <div id="url">
-              <span id="domain"></span><span id="path"></span>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div id="omnibox-ui-element" class="ui-element">
-      <div id="suggestions">
-        <div id="suggestion-4" class="suggestion"></div>
-        <div id="suggestion-3" class="suggestion"></div>
-        <div id="suggestion-2" class="suggestion"></div>
-        <div id="suggestion-1" class="suggestion"></div>
-        <div id="suggestion-0" class="suggestion"></div>
-      </div>
-      <div id="omnibox-border">
-        <div id="omnibox-contents">
-          <div id="omnibox-clear-button"></div>
-          <input id="omnibox-input-field" type="url"></input>
-        </div>
-      </div>
-    </div>
-    <div id="back-indicator" class="gesture-indicator ui-element"></div>
-    <div id="forward-indicator" class="gesture-indicator ui-element"></div>
-    <div id="back-button" class="round-button ui-element"></div>
-    <div id="reload-button" class="round-button ui-element"></div>
-    <div id="forward-button" class="round-button ui-element"></div>
-    <div id="exit-present-button" class="round-button ui-element"></div>
-    <div id="back-button-caption" class="button-caption ui-element">
-      $i18n{back}
-    </div>
-    <div id="reload-button-caption" class="button-caption ui-element">
-      $i18n{reload}
-    </div>
-    <div id="forward-button-caption" class="button-caption ui-element">
-      $i18n{forward}
-    </div>
-    <div id="exit-present-button-caption" class="button-caption ui-element">
-      $i18n{exitPresent}
-    </div>
-    <div id="reload-ui-button" class="ui-element">Reload UI</div>
-    <div id="content-interceptor" class="ui-element"></div>
-    <div id="tab-template" class="tab"></div>
-    <!--The tab container element behaves like a scroll view (in conjunction
-        with the clip view). -->
-    <div id="tab-container" class="ui-element">
-      <!--The tab clip element's width will be programmatically set to the total
-          width of all it's children (the tabs). By doing so, the tabs can be
-          scrolled horizontally in the tab container element.-->
-      <div id="tab-clip">
-      </div>
-    </div>
-    <div id="new-tab" class="ui-element rect-button">
-      $i18n{newTab}
-    </div>
-    <div id="new-incognito-tab" class="ui-element rect-button">
-      $i18n{newIncognitoTab}
-    </div>
-    <div id="vkb-ui-element" class="ui-element" lang="en" dir="ltr">
-      <div id="vkb" class="inputview-container">
-        <div id="numberView" class="inputview-layoutview"></div>
-        <div class="inputview-spacerview"></div>
-        <div class="inputview-layoutview" id="keyboardView"></div>
-        <div class="inputview-spacerview"></div>
-        <div id="specialkeyView" class="inputview-layoutview"></div>
-      </div>
-    </div>
-  </div>
-</body>
-
-<!-- Run script after creating body, to let it add its own elements. -->
-<script src="vr_shell_ui_api.js"></script>
-<script src="vr_shell_ui_scene.js"></script>
-<script src="vr_shell_ui.js"></script>
-<script src="vk.js"></script>
-</html>
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js
deleted file mode 100644
index 214da76..0000000
--- a/chrome/browser/resources/vr_shell/vr_shell_ui.js
+++ /dev/null
@@ -1,1380 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var vrShellUi = (function() {
-  'use strict';
-
-  let ui = new scene.Scene();
-  let uiManager;
-  let nativeCommandHandler;
-
-  let uiRootElement = document.querySelector('#ui');
-  let uiStyle = window.getComputedStyle(uiRootElement);
-  /** @const */ var ANIM_DURATION = 150;
-
-  // This value should match the one in VrShellImpl.java
-  /** @const */ var UI_DPR = 1.2;
-
-  function getStyleFloat(style, property, defaultValue) {
-    let value = parseFloat(style.getPropertyValue(property));
-    return isNaN(value) ? defaultValue : value;
-  }
-
-  function getStyleString(style, property) {
-    let str = style.getPropertyValue(property);
-    return !str || 0 === str.length ? '' : str;
-  }
-
-  // Generate a two-color progress bar style background using a gradient.
-  function makeProgressBackground(loading, percentage, color, background) {
-    if (!loading) {
-      return background;
-    }
-    return 'linear-gradient(to right, ' + color + ' 0%, ' + color + ' ' +
-        percentage * 100.0 + '%, ' + background + ' ' + percentage * 100 +
-        '%, ' + background + ' 100%)';
-  }
-
-  class ContentQuad {
-    constructor() {
-      /** @const */ this.SCREEN_HEIGHT = 1.375;
-      /** @const */ this.SCREEN_RATIO = 9.6 / 6.4;
-      /** @const */ this.BROWSING_SCREEN_ELEVATION = -0.15;
-      /** @const */ this.BROWSING_SCREEN_DISTANCE = 2.0;
-      /** @const */ this.FULLSCREEN_DISTANCE = 3.0;
-      /** @const */ this.CSS_WIDTH_PIXELS = 960.0;
-      /** @const */ this.CSS_HEIGHT_PIXELS = 640.0;
-      /** @const */ this.DPR = 1.2;
-      /** @const */ this.MENU_MODE_SCREEN_DISTANCE = 2.0;
-      /** @const */ this.MENU_MODE_SCREEN_HEIGHT = 0.48;
-      /** @const */ this.MENU_MODE_SCREEN_ELEVATION = -0.125;
-      /** @const */ this.BACKGROUND_DISTANCE_MULTIPLIER = 1.414;
-      /** @const */ this.DOM_INTERCEPTOR_SELECTOR = '#content-interceptor';
-      /** @const */ this.DOM_INTERCEPTOR_ELEVATION = 0.01;
-
-      this.menuMode = false;
-      this.fullscreen = false;
-
-      let element = new api.UiElement(0, 0, 0, 0);
-      element.setName('Content');
-      element.setFill(new api.Content());
-      element.setVisible(false);
-      element.setSize(
-          this.SCREEN_HEIGHT * this.SCREEN_RATIO, this.SCREEN_HEIGHT);
-      element.setTranslation(
-          0, this.BROWSING_SCREEN_ELEVATION, -this.BROWSING_SCREEN_DISTANCE);
-      this.elementId = ui.addElement(element);
-
-      // Place an invisible (fill none) but hittable plane behind the content
-      // quad, to keep the reticle roughly planar with the content if near
-      // content.
-      let backPlane = new api.UiElement(0, 0, 0, 0);
-      backPlane.setName('Content backing');
-      backPlane.setSize(1000, 1000);
-      backPlane.setTranslation(0, 0, -0.01);
-      backPlane.setParentId(this.elementId);
-      backPlane.setFill(new api.NoFill());
-      ui.addElement(backPlane);
-
-      // Place invisible plane on top of content quad, to intercept the clicks
-      // while on menu mode.
-      this.interceptor = new DomUiElement(this.DOM_INTERCEPTOR_SELECTOR);
-      let update = new api.UiElementUpdate();
-      update.setTranslation(0, 0, this.DOM_INTERCEPTOR_ELEVATION);
-      update.setVisible(false);
-      update.setParentId(this.elementId);
-      update.setSize(
-          this.MENU_MODE_SCREEN_HEIGHT * this.SCREEN_RATIO,
-          this.MENU_MODE_SCREEN_HEIGHT);
-      ui.updateElement(this.interceptor.id, update);
-      let interceptorButton =
-          document.querySelector(this.DOM_INTERCEPTOR_SELECTOR);
-      interceptorButton.addEventListener('click', function() {
-        uiManager.exitMenuMode();
-        ui.flush();
-      });
-
-      this.updateState();
-    }
-
-    setEnabled(enabled) {
-      let update = new api.UiElementUpdate();
-      update.setVisible(enabled);
-      ui.updateElement(this.elementId, update);
-      if (enabled) {
-        api.setContentCssSize(
-            this.CSS_WIDTH_PIXELS, this.CSS_HEIGHT_PIXELS, this.DPR);
-      } else {
-        // TODO(mthiesse): Restore the webVR resolution (which matches native
-        // display resolution).
-      }
-    }
-
-    setMenuMode(enabled) {
-      if (this.menuMode == enabled)
-        return;
-      this.menuMode = enabled;
-      this.updateState();
-    }
-
-    setFullscreen(enabled) {
-      if (this.fullscreen == enabled)
-        return;
-      this.fullscreen = enabled;
-      this.updateState();
-    }
-
-    updateState() {
-      // Defaults content quad parameters.
-      let y = this.BROWSING_SCREEN_ELEVATION;
-      let distance = this.BROWSING_SCREEN_DISTANCE;
-      let height = this.SCREEN_HEIGHT;
-
-      // Mode-specific overrides.
-      if (this.menuMode) {
-        y = this.MENU_MODE_SCREEN_ELEVATION;
-        distance = this.MENU_MODE_SCREEN_DISTANCE;
-        height = this.MENU_MODE_SCREEN_HEIGHT;
-      } else if (this.fullscreen) {
-        distance = this.FULLSCREEN_DISTANCE;
-      }
-
-      let update = new api.UiElementUpdate();
-      update.setVisible(this.menuMode);
-      ui.updateElement(this.interceptor.id, update);
-
-      let anim;
-      anim = new api.Animation(this.elementId, ANIM_DURATION);
-      anim.setTranslation(0, y, -distance);
-      anim.setEasing(new api.InOutEasing());
-      ui.addAnimation(anim);
-      anim = new api.Animation(this.elementId, ANIM_DURATION);
-      anim.setSize(height * this.SCREEN_RATIO, height);
-      anim.setEasing(new api.InOutEasing());
-      ui.addAnimation(anim);
-
-      ui.setBackgroundDistance(distance * this.BACKGROUND_DISTANCE_MULTIPLIER);
-    }
-
-    // TODO(crbug/643815): Add a method setting aspect ratio (and possible
-    // animation of changing it).
-
-    getElementId() {
-      return this.elementId;
-    }
-  };
-
-  class DomUiElement {
-    constructor(domId) {
-      let domElement = document.querySelector(domId);
-
-      // Pull copy rectangle from the position of the element.
-      let rect = domElement.getBoundingClientRect();
-      let pixelX = Math.floor(rect.left);
-      let pixelY = Math.floor(rect.top);
-      let pixelWidth = Math.ceil(rect.right) - pixelX;
-      let pixelHeight = Math.ceil(rect.bottom) - pixelY;
-
-      let element = new api.UiElement(pixelX, pixelY, pixelWidth, pixelHeight);
-      this.sizeX = pixelWidth / 1000;
-      this.sizeY = pixelHeight / 1000;
-      element.setSize(this.sizeX, this.sizeY);
-
-      // Parse element CSS properties.
-      let style = window.getComputedStyle(domElement);
-
-      this.translationX = getStyleFloat(style, '--tranX', 0);
-      this.translationY = getStyleFloat(style, '--tranY', 0);
-      this.translationZ = getStyleFloat(style, '--tranZ', 0);
-      if (this.translationX != 0 || this.translationY != 0 ||
-          this.translationZ != 0) {
-        element.setTranslation(
-            this.translationX, this.translationY, this.translationZ);
-      }
-
-      this.scale = getStyleFloat(style, '--scale', 1);
-      if (this.scale != 1) {
-        element.setScale(this.scale, this.scale, this.scale);
-      }
-
-      this.rotationX = getStyleFloat(style, '--rotX', 0);
-      this.rotationY = getStyleFloat(style, '--rotY', 0);
-      this.rotationZ = getStyleFloat(style, '--rotZ', 0);
-      if (this.rotationX != 0 || this.rotationY != 0 || this.rotationZ != 0) {
-        element.setRotation(
-            this.rotationX, this.rotationY, this.rotationZ, 2 * Math.PI);
-      }
-
-      element.setName(domId);
-      this.id = ui.addElement(element);
-      this.domElement = domElement;
-    }
-  };
-
-  class Button {
-    constructor(domId, callback, parentId) {
-      let captionId = domId + '-caption';
-      this.button = document.querySelector(domId);
-      this.caption = document.querySelector(captionId);
-      this.callback = callback;
-      this.enabled = true;
-
-      // Create an invisible parent, from which the button will hover.
-      let backing = new api.UiElement(0, 0, 0, 0);
-      backing.setName(domId + '-backing');
-      backing.setParentId(parentId);
-      backing.setVisible(false);
-      this.backingElementId = ui.addElement(backing);
-
-      this.buttonElement = new DomUiElement(domId);
-      let update = new api.UiElementUpdate();
-      update.setParentId(this.backingElementId);
-      ui.updateElement(this.buttonElement.id, update);
-
-      this.captionElement = new DomUiElement(captionId);
-      update = new api.UiElementUpdate();
-      update.setParentId(this.buttonElement.id);
-      update.setTranslation(0, -this.captionElement.sizeY / 2, 0);
-      update.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YBOTTOM);
-      ui.updateElement(this.captionElement.id, update);
-
-      this.button.addEventListener('mouseenter', this.onMouseEnter.bind(this));
-      this.button.addEventListener('mouseleave', this.onMouseLeave.bind(this));
-      this.button.addEventListener('click', this.callback);
-    }
-
-    setTranslation(x, y, z) {
-      let update = new api.UiElementUpdate();
-      update.setTranslation(x, y, z);
-      ui.updateElement(this.backingElementId, update);
-    }
-
-    setVisible(visible) {
-      let update = new api.UiElementUpdate();
-      update.setVisible(visible);
-      ui.updateElement(this.buttonElement.id, update);
-      update = new api.UiElementUpdate();
-      update.setVisible(visible);
-      ui.updateElement(this.captionElement.id, update);
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-      if (enabled) {
-        this.button.classList.remove('disabled-button');
-        this.button.addEventListener('click', this.callback);
-      } else {
-        this.button.classList.add('disabled-button');
-        this.button.removeEventListener('click', this.callback);
-      }
-    }
-
-    configure(buttonOpacity, captionOpacity, distanceForward) {
-      this.button.style.opacity = buttonOpacity;
-      this.caption.style.opacity = captionOpacity;
-
-      let anim = new api.Animation(this.buttonElement.id, ANIM_DURATION);
-      anim.setTranslation(0, 0, distanceForward);
-      ui.addAnimation(anim);
-      ui.flush();
-    }
-
-    onMouseEnter() {
-      if (this.enabled) {
-        this.configure(1, 1, 0.015);
-      }
-    }
-
-    onMouseLeave() {
-      this.configure(0.8, 0, 0);
-    }
-  };
-
-  class GestureHandlers {
-    constructor() {
-      /** @const */ var BACKING_DISTANCE = 0.8;
-      /** @const */ var INDICATOR_DISTANCE = 0.15;
-      this.enabled = false;
-
-      let backing = new api.UiElement(0, 0, 0, 0);
-      backing.setName('Navigation indicator backing');
-      backing.setVisible(false);
-      backing.setTranslation(0, 0, -BACKING_DISTANCE);
-      backing.setLockToFieldOfView(true);
-      this.backingElementId = ui.addElement(backing);
-
-      this.indicators = {};
-      this.indicators[api.Direction.LEFT] =
-          new GestureHandler(
-              '#back-indicator',
-              function() {
-                api.doAction(api.Action.HISTORY_BACK, {});
-              },
-              this.backingElementId,
-              [-INDICATOR_DISTANCE, 0]);
-      this.indicators[api.Direction.RIGHT] =
-          new GestureHandler(
-              '#forward-indicator',
-              function() {
-                api.doAction(api.Action.HISTORY_FORWARD, {});
-              },
-              this.backingElementId,
-              [INDICATOR_DISTANCE, 0]);
-    }
-
-    setEnabled(enabledIndicators) {
-      for (let key in enabledIndicators) {
-        if (key in this.indicators) {
-          this.indicators[key].setEnabled(enabledIndicators[key]);
-        }
-      }
-    }
-
-    run(direction) {
-      if (direction in this.indicators) {
-        this.indicators[direction].run();
-      }
-    }
-  }
-
-  class GestureHandler {
-    constructor(selector, callback, parentId, position) {
-      /** @const */ this.ANIM_DURATION = 250;
-      this.enabled = false;
-
-      this.element = new DomUiElement(selector);
-      this.callback = callback;
-
-      let update = new api.UiElementUpdate();
-      update.setParentId(parentId);
-      update.setVisible(true);
-      update.setOpacity(0);
-      update.setScale(0, 0, 0);
-      update.setTranslation(position[0], position[1], 0);
-      ui.updateElement(this.element.id, update);
-    }
-
-    setTranslation(x, y, z) {
-      let update = new api.UiElementUpdate();
-      update.setTranslation(x, y, z);
-      ui.updateElement(this.element.id, update);
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-    }
-
-    run() {
-      if (!this.enabled) {
-        return;
-      }
-      this.callback();
-
-      let update = new api.UiElementUpdate();
-      update.setScale(0.5, 0.5, 0.5);
-      update.setOpacity(0.5);
-      ui.updateElement(this.element.id, update);
-      let anim = new api.Animation(this.element.id, this.ANIM_DURATION);
-      anim.setOpacity(1);
-      ui.addAnimation(anim);
-      anim = new api.Animation(this.element.id, this.ANIM_DURATION);
-      anim.setOpacity(0);
-      anim.setDelayedStart(this.ANIM_DURATION);
-      ui.addAnimation(anim);
-      anim = new api.Animation(this.element.id, this.ANIM_DURATION * 2);
-      anim.setScale(1, 1, 1);
-      ui.addAnimation(anim);
-    }
-  }
-
-  class Controls {
-    constructor(contentQuadId) {
-      this.enabled = false;
-      this.exitPresentButtonVisible = false;
-
-      this.buttons = {
-        backButton: null,
-        reloadButton: null,
-        forwardButton: null
-      };
-      let descriptors = [
-        [
-          0, 'backButton', '#back-button',
-          function() {
-            api.doAction(api.Action.HISTORY_BACK, {});
-          }
-        ],
-        [
-          1, 'reloadButton', '#reload-button',
-          function() {
-            api.doAction(api.Action.RELOAD, {});
-          }
-        ],
-        [
-          2, 'forwardButton', '#forward-button',
-          function() {
-            api.doAction(api.Action.HISTORY_FORWARD, {});
-          }
-        ],
-        [
-          0, 'exitPresentButton', '#exit-present-button',
-          function() {
-            api.doAction(api.Action.EXIT_PRESENT, {});
-          }
-        ],
-      ];
-
-      /** @const */ var BUTTON_Y = -0.53;
-      /** @const */ var BUTTON_Z = -2;
-      /** @const */ var BUTTON_SPACING = 0.14;
-
-      let controls = new api.UiElement(0, 0, 0, 0);
-      controls.setName('Controls');
-      controls.setVisible(false);
-      controls.setTranslation(0, BUTTON_Y, BUTTON_Z);
-      this.controlsId = ui.addElement(controls);
-
-      let slotCount = 0;
-      descriptors.forEach(function(descriptor) {
-        slotCount = Math.max(descriptor[0] + 1, slotCount);
-      });
-      let startPosition = -BUTTON_SPACING * (slotCount / 2.0 - 0.5);
-
-      for (let i = 0; i < descriptors.length; i++) {
-        let slot = descriptors[i][0];
-        let name = descriptors[i][1];
-        let domId = descriptors[i][2];
-        let callback = descriptors[i][3];
-        let button = new Button(domId, callback, this.controlsId);
-        button.setTranslation(startPosition + slot * BUTTON_SPACING, 0, 0);
-        this.buttons[name] = button;
-      }
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-      this.configure();
-    }
-
-    configure() {
-      for (let key in this.buttons) {
-        this.buttons[key].setVisible(this.enabled);
-      }
-      if (this.enabled) {
-        this.buttons['exitPresentButton'].setVisible(
-            this.exitPresentButtonVisible);
-        this.buttons['backButton'].setVisible(!this.exitPresentButtonVisible);
-      }
-    }
-
-    setBackButtonEnabled(enabled) {
-      this.buttons.backButton.setEnabled(enabled);
-    }
-
-    setForwardButtonEnabled(enabled) {
-      this.buttons.forwardButton.setEnabled(enabled);
-    }
-
-    /** If true shows the exit present button instead of the back button. */
-    setExitPresentButtonVisible(visible) {
-      this.exitPresentButtonVisible = visible;
-      this.configure();
-    }
-  };
-
-  /**
-   * A button to trigger a reload of the HTML UI for development purposes.
-   */
-  class ReloadUiButton {
-    constructor() {
-      this.enabled = false;
-      this.devMode = false;
-
-      this.uiElement = new DomUiElement('#reload-ui-button');
-      this.uiElement.domElement.addEventListener('click', function() {
-        ui.purge();
-        api.doAction(api.Action.RELOAD_UI, {});
-      });
-
-      let update = new api.UiElementUpdate();
-      update.setVisible(false);
-      ui.updateElement(this.uiElement.id, update);
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-      this.updateState();
-    }
-
-    setDevMode(enabled) {
-      this.devMode = enabled;
-      this.updateState();
-    }
-
-    updateState() {
-      let update = new api.UiElementUpdate();
-      update.setVisible(this.enabled && this.devMode);
-      ui.updateElement(this.uiElement.id, update);
-    }
-  };
-
-  class SecureOriginWarnings {
-    constructor() {
-      /** @const */ var DISTANCE = 0.7;
-      /** @const */ var ANGLE_UP = 16.3 * Math.PI / 180.0;
-
-      this.enabled = false;
-      this.secure = false;
-      this.secureOriginTimer = null;
-
-      // Permanent WebVR security warning. This warning is shown near the top of
-      // the field of view.
-      this.webVrSecureWarning = new DomUiElement('#webvr-not-secure-permanent');
-      let update = new api.UiElementUpdate();
-      update.setScale(DISTANCE, DISTANCE, 1);
-      update.setTranslation(
-          0, DISTANCE * Math.sin(ANGLE_UP), -DISTANCE * Math.cos(ANGLE_UP));
-      update.setRotation(1.0, 0.0, 0.0, ANGLE_UP);
-      update.setHitTestable(false);
-      update.setVisible(false);
-      update.setLockToFieldOfView(true);
-      ui.updateElement(this.webVrSecureWarning.id, update);
-
-      // Temporary WebVR security warning. This warning is shown in the center
-      // of the field of view, for a limited period of time.
-      this.transientWarning = new DomUiElement('#webvr-not-secure-transient');
-      update = new api.UiElementUpdate();
-      update.setScale(DISTANCE, DISTANCE, 1);
-      update.setTranslation(0, 0, -DISTANCE);
-      update.setHitTestable(false);
-      update.setVisible(false);
-      update.setLockToFieldOfView(true);
-      ui.updateElement(this.transientWarning.id, update);
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-      this.updateState();
-    }
-
-    setSecure(secure) {
-      this.secure = secure;
-      this.updateState();
-    }
-
-    updateState() {
-      /** @const */ var TRANSIENT_TIMEOUT_MS = 30000;
-
-      let visible = (this.enabled && !this.secure);
-      if (this.secureOriginTimer) {
-        clearInterval(this.secureOriginTimer);
-        this.secureOriginTimer = null;
-      }
-      if (visible) {
-        this.secureOriginTimer =
-            setTimeout(this.onTransientTimer.bind(this), TRANSIENT_TIMEOUT_MS);
-      }
-      this.showOrHideWarnings(visible);
-    }
-
-    showOrHideWarnings(visible) {
-      let update = new api.UiElementUpdate();
-      update.setVisible(visible);
-      ui.updateElement(this.webVrSecureWarning.id, update);
-      update = new api.UiElementUpdate();
-      update.setVisible(visible);
-      ui.updateElement(this.transientWarning.id, update);
-    }
-
-    onTransientTimer() {
-      let update = new api.UiElementUpdate();
-      update.setVisible(false);
-      ui.updateElement(this.transientWarning.id, update);
-      this.secureOriginTimer = null;
-      ui.flush();
-    }
-  };
-
-  class UrlIndicator {
-    constructor() {
-      this.domUiElement = new DomUiElement('#url-indicator-container');
-      this.enabled = false;
-      this.hidden = false;
-      this.loading = false;
-      this.loadProgress = 0;
-      this.level = 0;
-      this.visibilityTimeout = 0;
-      this.visibilityTimer = null;
-      this.nativeState = {};
-
-      // Initially invisible.
-      let update = new api.UiElementUpdate();
-      update.setVisible(false);
-      ui.updateElement(this.domUiElement.id, update);
-      this.nativeState.visible = false;
-
-      // Pull some CSS properties so that Javascript can reconfigure the
-      // indicator programmatically.
-      let border =
-          this.domUiElement.domElement.querySelector('#url-indicator-border');
-      let style = window.getComputedStyle(border);
-      this.statusBarColor = getStyleString(style, '--statusBarColor');
-      this.backgroundColor = style.backgroundColor;
-      this.fadeTimeMs = getStyleFloat(style, '--fadeTimeMs', 0);
-      this.fadeYOffset = getStyleFloat(style, '--fadeYOffset', 0);
-      this.opacity = getStyleFloat(style, '--opacity', 1);
-    }
-
-    getSecurityIconElementId(level) {
-      // See security_state.h and getSecurityIconResource() for this mapping.
-      switch (level) {
-        case 0:  // NONE
-        case 1:  // HTTP_SHOW_WARNING
-        case 4:  // SECURITY_WARNING
-          return '#url-indicator-info-icon';
-        case 2:  // SECURE:
-        case 3:  // EV_SECURE:
-          return '#url-indicator-lock-icon';
-        case 5:  // SECURE_WITH_POLICY_INSTALLED_CERT (ChromeOS only)
-        case 6:  // DANGEROUS
-        default:
-          return '#url-indicator-warning-icon';
-      }
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-      this.resetVisibilityTimer();
-      this.updateState();
-    }
-
-    setLoading(loading) {
-      this.loading = loading;
-      this.loadProgress = 0;
-      this.resetVisibilityTimer();
-      this.updateState();
-    }
-
-    setLoadProgress(progress) {
-      this.loadProgress = progress;
-      this.updateState();
-    }
-
-    setURL(host, path) {
-      let indicator = this.domUiElement.domElement;
-      indicator.querySelector('#domain').textContent = host;
-      indicator.querySelector('#path').textContent = path;
-      this.resetVisibilityTimer();
-      this.updateState();
-    }
-
-    setSecurityLevel(level) {
-      document.querySelector('#url-indicator-warning-icon').style.display =
-          'none';
-      document.querySelector('#url-indicator-info-icon').style.display = 'none';
-      document.querySelector('#url-indicator-lock-icon').style.display = 'none';
-      let icon = this.getSecurityIconElementId(level);
-      document.querySelector(icon).style.display = 'block';
-
-      this.resetVisibilityTimer();
-      this.updateState();
-    }
-
-    setVisibilityTimeout(milliseconds) {
-      this.visibilityTimeout = milliseconds;
-      this.resetVisibilityTimer();
-      this.updateState();
-    }
-
-    resetVisibilityTimer() {
-      if (this.visibilityTimer) {
-        clearInterval(this.visibilityTimer);
-        this.visibilityTimer = null;
-      }
-      if (this.enabled && this.visibilityTimeout > 0 && !this.loading) {
-        this.visibilityTimer = setTimeout(
-            this.onVisibilityTimer.bind(this), this.visibilityTimeout);
-      }
-    }
-
-    onVisibilityTimer() {
-      this.visibilityTimer = null;
-      this.updateState();
-    }
-
-    updateState() {
-      this.setNativeVisibility(this.enabled);
-
-      if (!this.enabled) {
-        return;
-      }
-
-      let indicator = document.querySelector('#url-indicator-border');
-      indicator.style.background = makeProgressBackground(
-          this.loading, this.loadProgress, this.statusBarColor,
-          this.backgroundColor);
-
-      let shouldBeHidden =
-          !this.loading && this.visibilityTimeout > 0 && !this.visibilityTimer;
-      if (shouldBeHidden != this.hidden) {
-        // Make the box fade away if it's disappearing.
-        this.hidden = shouldBeHidden;
-
-        // Fade-out or fade-in the box.
-        let opacityAnimation =
-            new api.Animation(this.domUiElement.id, this.fadeTimeMs);
-        opacityAnimation.setOpacity(this.hidden ? 0.0 : this.opacity);
-        ui.addAnimation(opacityAnimation);
-
-        // Drop the position as it fades, or raise the position if appearing.
-        let yOffset = this.hidden ? this.fadeYOffset : 0;
-        let positionAnimation =
-            new api.Animation(this.domUiElement.id, this.fadeTimeMs);
-        positionAnimation.setTranslation(
-            this.domUiElement.translationX,
-            this.domUiElement.translationY + yOffset,
-            this.domUiElement.translationZ);
-        ui.addAnimation(positionAnimation);
-      }
-
-      ui.flush();
-    }
-
-    setNativeVisibility(visible) {
-      if (visible == this.nativeState.visible) {
-        return;
-      }
-      this.nativeState.visible = visible;
-      let update = new api.UiElementUpdate();
-      update.setVisible(visible);
-      ui.updateElement(this.domUiElement.id, update);
-      ui.flush();
-    }
-  };
-
-  class Background {
-    constructor() {
-      /** @const */ this.SCENE_GROUND_SIZE = 25.0;
-      /** @const */ this.SCENE_HEIGHT = 4.0;
-      /** @const */ this.GRIDLINE_COUNT = 40;
-      /** @const */ this.HORIZON_COLOR = {r: 0.57, g: 0.57, b: 0.57, a: 1.0};
-      /** @const */ this.CENTER_COLOR = {r: 0.48, g: 0.48, b: 0.48, a: 1.0};
-      /** @const */ this.FULLSCREEN_BACKGROUND_COLOR =
-          {r: 0.1, g: 0.1, b: 0.1, a: 1.0};
-
-      // Make ground plane.
-      let groundPlane = new api.UiElementUpdate();
-      groundPlane.setName('Ground plane');
-      groundPlane.setVisible(true);
-      groundPlane.setSize(this.SCENE_GROUND_SIZE, this.SCENE_GROUND_SIZE);
-      groundPlane.setFill(
-          new api.OpaqueGradient(this.HORIZON_COLOR, this.CENTER_COLOR));
-      groundPlane.setTranslation(0, -this.SCENE_HEIGHT / 2, 0);
-      groundPlane.setRotation(1.0, 0.0, 0.0, -Math.PI / 2);
-      groundPlane.setDrawPhase(0);
-      this.groundPlaneId = ui.addElement(groundPlane);
-
-      // Make ceiling plane.
-      let ceilingPlane = new api.UiElementUpdate();
-      ceilingPlane.setName('Ceiling');
-      ceilingPlane.setVisible(true);
-      ceilingPlane.setSize(this.SCENE_GROUND_SIZE, this.SCENE_GROUND_SIZE);
-      ceilingPlane.setFill(
-          new api.OpaqueGradient(this.HORIZON_COLOR, this.CENTER_COLOR));
-      ceilingPlane.setTranslation(0, this.SCENE_HEIGHT * 2, 0);
-      ceilingPlane.setRotation(1.0, 0.0, 0.0, Math.PI / 2);
-      ceilingPlane.setDrawPhase(0);
-      this.ceilingPlaneId = ui.addElement(ceilingPlane);
-
-      // Ground grid.
-      let groundGrid = new api.UiElementUpdate();
-      groundGrid.setName('Ground grid');
-      groundGrid.setVisible(true);
-      groundGrid.setSize(this.SCENE_GROUND_SIZE, this.SCENE_GROUND_SIZE);
-      let transparentHorizonColor = {
-        r: this.HORIZON_COLOR.r,
-        g: this.HORIZON_COLOR.g,
-        b: this.HORIZON_COLOR.b,
-        a: 0
-      };
-      groundGrid.setFill(new api.GridGradient(
-          transparentHorizonColor, this.HORIZON_COLOR, this.GRIDLINE_COUNT));
-      groundGrid.setTranslation(0, -this.SCENE_HEIGHT / 2 + 0.01, 0);
-      groundGrid.setRotation(1.0, 0.0, 0.0, -Math.PI / 2);
-      groundGrid.setDrawPhase(0);
-      this.groundGridId = ui.addElement(groundGrid);
-
-      this.setHiddenBackground();
-    }
-
-    setElementVisible(elementId, visible) {
-      let update = new api.UiElementUpdate();
-      update.setVisible(visible);
-      ui.updateElement(elementId, update);
-    }
-
-    setLightBackground() {
-      this.setElementVisible(this.groundPlaneId, true);
-      this.setElementVisible(this.ceilingPlaneId, true);
-      this.setElementVisible(this.groundGridId, true);
-      ui.setBackgroundColor(this.HORIZON_COLOR);
-    }
-
-    setDarkBackground() {
-      this.setElementVisible(this.groundPlaneId, false);
-      this.setElementVisible(this.ceilingPlaneId, false);
-      this.setElementVisible(this.groundGridId, true);
-      ui.setBackgroundColor(this.FULLSCREEN_BACKGROUND_COLOR);
-    }
-
-    setHiddenBackground() {
-      this.setElementVisible(this.groundPlaneId, false);
-      this.setElementVisible(this.ceilingPlaneId, false);
-      this.setElementVisible(this.groundGridId, false);
-      ui.setBackgroundColor(this.FULLSCREEN_BACKGROUND_COLOR);
-    }
-
-    setState(mode, menuMode, fullscreen) {
-      switch (mode) {
-        case api.Mode.STANDARD:
-          if (fullscreen) {
-            this.setDarkBackground();
-          } else {
-            this.setLightBackground();
-          }
-          break;
-        case api.Mode.WEB_VR:
-          if (menuMode) {
-            this.setLightBackground();
-          } else {
-            this.setHiddenBackground();
-          }
-          break;
-      }
-    }
-  };
-
-  class Omnibox {
-    constructor() {
-      /** @const */ this.ELEVATION = -0.7;
-      /** @const */ this.DISTANCE = -1.99;
-      /** @const */ this.SCALE = -this.DISTANCE;
-
-      this.enabled = false;
-
-      let root = document.querySelector('#omnibox-ui-element');
-      this.domUiElement = new DomUiElement('#omnibox-border');
-      this.inputField = root.querySelector('#omnibox-input-field');
-
-      let style = window.getComputedStyle(this.domUiElement.domElement);
-      this.statusBarColor = getStyleString(style, '--statusBarColor');
-      this.backgroundColor = style.backgroundColor;
-      this.loading = false;
-      this.loadProgress = 0;
-      this.updateLoadingState();
-
-      // Initially invisible.
-      let update = new api.UiElementUpdate();
-      update.setVisible(false);
-      update.setTranslation(0, this.ELEVATION, this.DISTANCE);
-      update.setScale(this.SCALE, this.SCALE, this.SCALE);
-      ui.updateElement(this.domUiElement.id, update);
-
-      // Field-clearing button.
-      let clearButton = root.querySelector('#omnibox-clear-button');
-      clearButton.addEventListener('click', function() {
-        this.inputField.value = '';
-        api.doAction(api.Action.OMNIBOX_CONTENT, {'text': ''});
-      }.bind(this));
-
-      // Watch for the enter key to trigger navigation.
-      this.inputField.addEventListener('keypress', function(e) {
-        if (e.keyCode == 13) {
-          this.setSuggestions([]);
-          api.doAction(
-              // TODO(crbug.com/683344): Properly choose prefix.
-              api.Action.LOAD_URL, {'url': 'http://' + e.target.value});
-        }
-      });
-
-      // Watch for field input to generate suggestions.
-      this.inputField.addEventListener('input', function(e) {
-        api.doAction(api.Action.OMNIBOX_CONTENT, {'text': e.target.value});
-      });
-
-      // Clicking on suggestions triggers navigation.
-      let elements = root.querySelectorAll('.suggestion');
-      this.maxSuggestions = elements.length;
-      this.suggestions = [];
-      this.suggestionUiElements = [];
-      for (var i = 0; i < elements.length; i++) {
-        elements[i].addEventListener('click', function(index, e) {
-          if (e.target.url) {
-            api.doAction(api.Action.LOAD_URL, {'url': e.target.url});
-            this.setSuggestions([]);
-          }
-        }.bind(this, i));
-
-        let elem = new DomUiElement('#suggestion-' + i);
-        this.suggestionUiElements.push(elem);
-        let update = new api.UiElementUpdate();
-        update.setVisible(false);
-        update.setParentId(this.domUiElement.id);
-        update.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YTOP);
-        // Vertically offset suggestions to stack on top of the omnibox. The 0.5
-        // offset moves each anchor point from center to edge.
-        update.setTranslation(0, elem.sizeY * (i + 0.5), 0);
-        ui.updateElement(elem.id, update);
-      }
-      this.setSuggestions([]);
-    }
-
-    setEnabled(enabled) {
-      this.enabled = enabled;
-      let update = new api.UiElementUpdate();
-      update.setVisible(enabled);
-      ui.updateElement(this.domUiElement.id, update);
-      this.updateSuggestions();
-    }
-
-    setURL(url) {
-      this.inputField.value = url;
-    }
-
-    setSuggestions(suggestions) {
-      this.suggestions = suggestions;
-      this.updateSuggestions();
-    }
-
-    setLoading(loading) {
-      this.loading = loading;
-      this.loadProgress = 0;
-      this.updateLoadingState();
-    }
-
-    setLoadProgress(progress) {
-      this.loadProgress = progress;
-      this.updateLoadingState();
-    }
-
-    updateLoadingState() {
-      let indicator = document.querySelector('#omnibox-border');
-      indicator.style.background = makeProgressBackground(
-          this.loading, this.loadProgress, this.statusBarColor,
-          this.backgroundColor);
-    }
-
-    updateSuggestions() {
-      for (var i = 0; i < this.maxSuggestions; i++) {
-        let element = document.querySelector('#suggestion-' + i);
-        let update = new api.UiElementUpdate();
-        if (this.enabled && i < this.suggestions.length) {
-          element.textContent = this.suggestions[i].description;
-          element.url = this.suggestions[i].url;
-          update.setVisible(true);
-        } else {
-          element.textContent = '';
-          element.url = null;
-          update.setVisible(false);
-        }
-        ui.updateElement(this.suggestionUiElements[i].id, update);
-      }
-    }
-  };
-
-  // Shows the open tabs.
-  //
-  // The tab container is made of three <div> nesting levels. The first is the
-  // tab container element, which acts like a scroll view. It has a fixed size
-  // and corresponds to a UI element in the scene. The second level is the clip
-  // element, which is programmatically set to the total width of all it's
-  // children (the third nesting level). The clip element is needed to enable
-  // horizontal scrolling and prevent the children from breaking to a new line.
-  // The third nesting level comprises the actual tabs.
-  //
-  // TODO(crbug/641487): currently, tabs cannot be scrolled because the
-  // scrolling event is not sent to UI elements.
-  class TabContainer {
-    constructor(contentQuadId) {
-      /** @const */ var DOM_TAB_TEMPLATE_SELECTOR = '#tab-template';
-      /** @const */ var DOM_TAB_CONTAINER_SELECTOR = '#tab-container';
-      /** @const */ var DOM_TAB_CLIP_SELECTOR = '#tab-clip';
-      /** @const */ var DOM_NEW_TAB_BUTTON_SELECTOR = '#new-tab';
-      /** @const */ var DOM_NEW_INCOGNITO_TAB_BUTTON_SELECTOR =
-          '#new-incognito-tab';
-      /** @const */ var TAB_CONTAINER_Y_OFFSET = 0.3;
-      /** @const */ var TAB_CONTAINER_Z_OFFSET = -2;
-
-      this.domTabs = {};
-      this.contentQuadId = contentQuadId;
-      this.domTabTemplate = document.querySelector(DOM_TAB_TEMPLATE_SELECTOR);
-      this.domTabContainer = document.querySelector(DOM_TAB_CONTAINER_SELECTOR);
-      this.domTabClip = document.querySelector(DOM_TAB_CLIP_SELECTOR);
-
-      // Add tab container to native scene.
-      this.tabContainerElement = new DomUiElement(DOM_TAB_CONTAINER_SELECTOR);
-      let positionUpdate = new api.UiElementUpdate();
-      positionUpdate.setTranslation(
-          0, TAB_CONTAINER_Y_OFFSET, TAB_CONTAINER_Z_OFFSET);
-      positionUpdate.setVisible(false);
-      ui.updateElement(this.tabContainerElement.id, positionUpdate);
-
-      // Add the new tab buttons to the native scene.
-      let buttonConfigs = [
-        {
-          selector: DOM_NEW_TAB_BUTTON_SELECTOR, x: -0.2, incognito: false
-        }, {
-          selector: DOM_NEW_INCOGNITO_TAB_BUTTON_SELECTOR,
-          x: 0.2,
-          incognito: true
-        }
-      ];
-      this.buttonElements = [];
-      buttonConfigs.forEach(function(buttonConfig) {
-        let buttonElement = new DomUiElement(buttonConfig.selector);
-        let update = new api.UiElementUpdate();
-        update.setTranslation(buttonConfig.x, 0.1, 0);
-        update.setVisible(false);
-        update.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YTOP);
-        update.setParentId(this.tabContainerElement.id);
-        ui.updateElement(buttonElement.id, update);
-        buttonElement.domElement.addEventListener('click', function() {
-          api.doAction(
-              api.Action.OPEN_NEW_TAB, {'incognito': buttonConfig.incognito});
-        });
-        this.buttonElements.push(buttonElement);
-      }, this);
-
-      // Calculate the width of one tab so that we can properly set the clip
-      // element's width.
-      this.domTabWidth = this.domTabTemplate.offsetWidth;
-      var domTabStyle = window.getComputedStyle(this.domTabTemplate);
-      this.domTabWidth += parseInt(domTabStyle.marginLeft, 10) +
-          parseInt(domTabStyle.marginRight, 10);
-    }
-
-    makeDomTab(tab) {
-      // Make a copy of the template tab and add this copy to the tab container
-      // view.
-      let domTab = this.domTabTemplate.cloneNode(true);
-      domTab.removeAttribute('id');
-      domTab.addEventListener('click', function() {
-        api.doAction(api.Action.SHOW_TAB, {'id': domTab.tab.id});
-      });
-      domTab.tab = tab;
-      this.domTabClip.appendChild(domTab);
-      this.domTabs[tab.id] = domTab;
-      return domTab;
-    }
-
-    resizeClipElement() {
-      // Resize clip element so that scrolling works.
-      this.domTabClip.style.width =
-          (Object.keys(this.domTabs).length * this.domTabWidth) + 'px';
-    }
-
-    setTabs(tabs) {
-      // Remove all current tabs.
-      while (this.domTabClip.firstChild) {
-        this.domTabClip.removeChild(this.domTabClip.firstChild);
-      }
-      this.domTabs = {};
-
-      // Add new tabs.
-      for (let i = 0; i < tabs.length; i++) {
-        this.addTab(tabs[i]);
-      }
-    }
-
-    hasTab(tab) {
-      return tab.id in this.domTabs;
-    }
-
-    addTab(tab) {
-      this.makeDomTab(tab);
-      this.updateTab(tab);
-      this.resizeClipElement();
-    }
-
-    updateTab(tab) {
-      let domTab = this.domTabs[tab.id];
-      domTab.textContent = tab.title;
-      domTab.classList.remove('tab-incognito');
-      if (tab.incognito) {
-        domTab.classList.add('tab-incognito');
-      }
-    }
-
-    removeTab(tab) {
-      let qualifiedTabId = tab.id;
-      let domTab = this.domTabs[qualifiedTabId];
-      delete this.domTabs[qualifiedTabId];
-      this.domTabClip.removeChild(domTab);
-      this.resizeClipElement();
-    }
-
-    setEnabled(enabled) {
-      let update = new api.UiElementUpdate();
-      update.setVisible(enabled);
-      ui.updateElement(this.tabContainerElement.id, update);
-      this.buttonElements.forEach(function(buttonElement) {
-        let update = new api.UiElementUpdate();
-        update.setVisible(enabled);
-        ui.updateElement(buttonElement.id, update);
-      }, this);
-    }
-  };
-
-  class VirtualKeyboard {
-    constructor(contentQuadId) {
-      /** @const */ this.SCALE = 1.4;
-      /** @const */ this.ANGLE_UP = Math.PI / 8;
-      /** @const */ this.Y_OFFSET = -1.0;
-      /** @const */ this.Z_OFFSET = -1.8;
-
-      this.element = new DomUiElement('#vkb');
-      let update = new api.UiElementUpdate();
-      update.setVisible(true);
-      update.setOpacity(0);
-      update.setRotation(1, 0, 0, -this.ANGLE_UP);
-      update.setScale(this.SCALE, this.SCALE, this.SCALE);
-      update.setTranslation(0, this.Y_OFFSET, this.Z_OFFSET);
-      ui.updateElement(this.element.id, update);
-    }
-
-    setEnabled(enabled) {
-      let anim = new api.Animation(this.element.id, ANIM_DURATION);
-      anim.setOpacity(enabled ? 1 : 0);
-      ui.addAnimation(anim);
-      anim = new api.Animation(this.element.id, ANIM_DURATION);
-      let scale = enabled ? this.SCALE : 0;
-      anim.setScale(scale, scale, scale);
-      ui.addAnimation(anim);
-    }
-  };
-
-  class UiManager {
-    constructor() {
-      this.mode = api.Mode.UNKNOWN;
-      this.menuMode = false;
-      this.fullscreen = false;
-      this.canGoBack = false;
-      this.canGoForward = false;
-
-      this.background = new Background();
-      this.contentQuad = new ContentQuad();
-      let contentId = this.contentQuad.getElementId();
-
-      this.gestureHandlers = new GestureHandlers();
-      this.controls = new Controls(contentId);
-      this.secureOriginWarnings = new SecureOriginWarnings();
-      this.urlIndicator = new UrlIndicator();
-      this.omnibox = new Omnibox();
-      this.reloadUiButton = new ReloadUiButton();
-      this.tabContainer = new TabContainer(contentId);
-      this.keyboard = new VirtualKeyboard(contentId);
-    }
-
-    setMode(mode) {
-      this.mode = mode;
-      this.updateState();
-    }
-
-    setFullscreen(fullscreen) {
-      this.fullscreen = fullscreen;
-      this.updateState();
-    }
-
-    handleAppButtonGesturePerformed(direction) {
-      this.gestureHandlers.run(direction);
-    }
-
-    handleAppButtonClicked() {
-      this.menuMode = !this.menuMode;
-      this.updateState();
-    }
-
-    setHistoryButtonsEnabled(canGoBack, canGoForward) {
-      this.canGoBack = canGoBack;
-      this.canGoForward = canGoForward;
-
-      canGoBack = canGoBack || this.fullscreen;
-
-      /** No need to call updateState to adjust button properties. */
-      this.controls.setBackButtonEnabled(canGoBack);
-      this.controls.setForwardButtonEnabled(canGoForward);
-      let enabledIndicators = {}
-      enabledIndicators[api.Direction.LEFT] = canGoBack;
-      enabledIndicators[api.Direction.RIGHT] = canGoForward;
-      this.gestureHandlers.setEnabled(enabledIndicators);
-    }
-
-    exitMenuMode() {
-      if (this.menuMode) {
-        this.menuMode = false;
-        this.updateState();
-      }
-    }
-
-    updateState() {
-      /** @const */ var URL_INDICATOR_VISIBILITY_TIMEOUT_MS = 5000;
-
-      let mode = this.mode;
-      let menuMode = this.menuMode;
-      let fullscreen = this.fullscreen;
-
-      api.doAction(api.Action.SET_CONTENT_PAUSED, {'paused': menuMode});
-      ui.setWebVrRenderingModeEnabled(mode == api.Mode.WEB_VR && !menuMode);
-
-      this.contentQuad.setEnabled(mode == api.Mode.STANDARD || menuMode);
-      this.contentQuad.setFullscreen(fullscreen);
-      this.contentQuad.setMenuMode(menuMode);
-      // TODO(crbug/643815): Set aspect ratio on content quad when available.
-      this.controls.setEnabled(menuMode);
-      this.controls.setBackButtonEnabled(this.canGoBack || this.fullscreen);
-      // TODO(crbug/689139): Don't show exit present button if the page
-      // autopresented.
-      this.controls.setExitPresentButtonVisible(mode == api.Mode.WEB_VR);
-      let enabledIndicators = {}
-      enabledIndicators[api.Direction.LEFT] = this.canGoBack || this.fullscreen;
-      this.gestureHandlers.setEnabled(enabledIndicators);
-      this.omnibox.setEnabled(menuMode);
-      this.urlIndicator.setEnabled(mode == api.Mode.STANDARD && !menuMode);
-      this.urlIndicator.setVisibilityTimeout(
-          URL_INDICATOR_VISIBILITY_TIMEOUT_MS);
-      this.secureOriginWarnings.setEnabled(
-          mode == api.Mode.WEB_VR && !menuMode);
-      this.background.setState(mode, menuMode, fullscreen);
-      this.tabContainer.setEnabled(menuMode);
-
-      this.reloadUiButton.setEnabled(mode == api.Mode.STANDARD);
-      this.keyboard.setEnabled(mode == api.Mode.STANDARD && menuMode);
-
-
-      api.setUiCssSize(
-          uiRootElement.clientWidth, uiRootElement.clientHeight, UI_DPR);
-    }
-
-    setSecurityLevel(level) {
-      this.urlIndicator.setSecurityLevel(level);
-    }
-
-    setWebVRSecureOrigin(secure) {
-      this.secureOriginWarnings.setSecure(secure);
-    }
-  };
-
-  function initialize() {
-    uiManager = new UiManager();
-    nativeCommandHandler = new UiCommandHandler(uiManager);
-    ui.flush();
-
-    api.domLoaded();
-  }
-
-  class UiCommandHandler extends api.NativeCommandHandler {
-    constructor(uiManager) {
-      super();
-      this.manager = uiManager;
-    }
-
-    /** @override */
-    onSetMode(mode) {
-      this.manager.setMode(mode);
-    }
-
-    /** @override */
-    onSetFullscreen(fullscreen) {
-      this.manager.setFullscreen(fullscreen);
-    }
-
-    /** @override */
-    onAppButtonGesturePerformed(direction) {
-      this.manager.handleAppButtonGesturePerformed(direction);
-    }
-
-    /** @override */
-    onAppButtonClicked() {
-      this.manager.handleAppButtonClicked();
-    }
-
-    /** @override */
-    onSetSecurityLevel(level) {
-      this.manager.setSecurityLevel(level);
-    }
-
-    /** @override */
-    onSetWebVRSecureOrigin(secure) {
-      this.manager.setWebVRSecureOrigin(secure);
-    }
-
-    /** @override */
-    onSetReloadUiCapabilityEnabled(enabled) {
-      this.manager.reloadUiButton.setDevMode(enabled);
-    }
-
-    /** @override */
-    onSetUrl(host, path) {
-      this.manager.urlIndicator.setURL(host, path);
-      this.manager.omnibox.setURL(host, path);
-    }
-
-    /** @override */
-    onSetLoading(loading) {
-      this.manager.urlIndicator.setLoading(loading);
-      this.manager.omnibox.setLoading(loading);
-    }
-
-    /** @override */
-    onSetLoadingProgress(progress) {
-      this.manager.urlIndicator.setLoadProgress(progress);
-      this.manager.omnibox.setLoadProgress(progress);
-    }
-
-    /** @override */
-    onSetOmniboxSuggestions(suggestions) {
-      this.manager.omnibox.setSuggestions(suggestions);
-    }
-
-    /** @override */
-    onSetTabs(tabs) {
-      uiManager.tabContainer.setTabs(tabs);
-    }
-
-    /** @override */
-    onUpdateTab(tab) {
-      if (uiManager.tabContainer.hasTab(tab)) {
-        uiManager.tabContainer.updateTab(tab);
-      } else {
-        uiManager.tabContainer.addTab(tab);
-      }
-    }
-
-    /** @override */
-    onRemoveTab(tab) {
-      uiManager.tabContainer.removeTab(tab);
-    }
-
-    /** @override */
-    onSetHistoryButtonsEnabled(canGoBack, canGoForward) {
-      uiManager.setHistoryButtonsEnabled(canGoBack, canGoForward);
-    }
-
-    /** @override */
-    onCommandHandlerFinished() {
-      ui.flush();
-    }
-  }
-
-  function command(dict) {
-    nativeCommandHandler.handleCommand(dict);
-  }
-
-  return {
-    initialize: initialize,
-    command: command,
-  };
-})();
-
-window.addEventListener('load', vrShellUi.initialize);
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui_api.js b/chrome/browser/resources/vr_shell/vr_shell_ui_api.js
deleted file mode 100644
index a21bedaf..0000000
--- a/chrome/browser/resources/vr_shell/vr_shell_ui_api.js
+++ /dev/null
@@ -1,770 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var api = {};
-
-/**
- * Enumeration of scene update commands.
- * @enum {number}
- * @const
- */
-api.Command = {
-  'ADD_ELEMENT': 0,
-  'UPDATE_ELEMENT': 1,
-  'REMOVE_ELEMENT': 2,
-  'ADD_ANIMATION': 3,
-  'REMOVE_ANIMATION': 4,
-  'CONFIGURE_SCENE': 5
-};
-
-/**
- * Sends one or more commands to native scene management. Commands are used
- * to add, modify or remove elements and animations. For examples of how to
- * format command parameters, refer to examples in scene.js.
- * @param {Array<Object>} commands
- */
-api.sendCommands = function(commands) {
-  if (commands.length > 0) {
-    chrome.send('updateScene', commands);
-  }
-};
-
-/**
- * Enumeration of valid Anchroing for X axis.
- * An element can either be anchored to the left, right, or center of the main
- * content rect (or it can be absolutely positioned using NONE). Any
- * translations applied will be relative to this anchoring.
- * @enum {number}
- * @const
- */
-api.XAnchoring = {
-  'XNONE': 0,
-  'XLEFT': 1,
-  'XRIGHT': 2
-};
-
-/**
- * Enumeration of valid Anchroing for Y axis.
- * @enum {number}
- * @const
- */
-api.YAnchoring = {
-  'YNONE': 0,
-  'YTOP': 1,
-  'YBOTTOM': 2
-};
-
-/**
- * Enumeration of actions that can be triggered by the HTML UI.
- * @enum {number}
- * @const
- */
-api.Action = {
-  'HISTORY_BACK': 0,
-  'HISTORY_FORWARD': 1,
-  'RELOAD': 2,
-  'ZOOM_OUT': 3,
-  'ZOOM_IN': 4,
-  'RELOAD_UI': 5,
-  'LOAD_URL': 6,
-  'OMNIBOX_CONTENT': 7,
-  'SET_CONTENT_PAUSED': 8,
-  'SHOW_TAB': 9,
-  'OPEN_NEW_TAB': 10,
-  'KEY_EVENT': 11,
-  'EXIT_PRESENT': 12
-};
-
-/**
- * Enumeration of modes that can be specified by the native side.
- * @enum {number}
- * @const
- */
-api.Mode = {
-  'UNKNOWN': -1,
-  'STANDARD': 0,
-  'WEB_VR': 1,
-};
-
-/**
- * Enumeration of gesture directions
- * @enum {number}
- * @const
- */
-api.Direction = {
-  'LEFT': 1,
-  'RIGHT': 2,
-  'UP': 3,
-  'DOWN': 4
-};
-
-/**
- * Triggers an Action.
- * @param {api.Action} action
- * @param {Object} parameters
- */
-api.doAction = function(action, parameters) {
-  chrome.send('doAction', [action, parameters]);
-};
-
-/**
- * Notify native scene management that DOM loading has completed, at the
- * specified page size.
- */
-api.domLoaded = function() {
-  chrome.send('domLoaded');
-};
-
-/**
- * Sets the CSS size for the content window.
- * @param {number} width
- * @param {number} height
- * @param {number} dpr
- */
-api.setContentCssSize = function(width, height, dpr) {
-  chrome.send('setContentCssSize', [width, height, dpr]);
-};
-
-/**
- * Sets the CSS size for this page.
- * @param {number} width
- * @param {number} height
- * @param {number} dpr
- */
-api.setUiCssSize = function(width, height, dpr) {
-  chrome.send('setUiCssSize', [width, height, dpr]);
-};
-
-api.FillType = {
-  'NONE': 0,
-  'SPRITE': 1,
-  'OPAQUE_GRADIENT': 2,
-  'GRID_GRADIENT': 3,
-  'CONTENT': 4
-};
-
-/**
- * Abstract fill base class.
- * @abstract
- */
-api.Fill = class {
-  constructor(type) {
-    this.properties = {};
-    this.properties['fillType'] = type;
-  }
-};
-
-api.NoFill = class extends api.Fill {
-  constructor() {
-    super(api.FillType.NONE);
-  }
-}
-
-api.Sprite = class extends api.Fill {
-  constructor(pixelX, pixelY, pixelWidth, pixelHeight) {
-    super(api.FillType.SPRITE);
-    this.properties['copyRectX'] = pixelX;
-    this.properties['copyRectY'] = pixelY;
-    this.properties['copyRectWidth'] = pixelWidth;
-    this.properties['copyRectHeight'] = pixelHeight;
-  }
-};
-
-api.OpaqueGradient = class extends api.Fill {
-  constructor(edgeColor, centerColor) {
-    super(api.FillType.OPAQUE_GRADIENT);
-    this.properties.edgeColor = edgeColor;
-    this.properties.centerColor = centerColor;
-  }
-};
-
-api.GridGradient = class extends api.Fill {
-  constructor(edgeColor, centerColor, gridlineCount) {
-    super(api.FillType.GRID_GRADIENT);
-    this.properties.edgeColor = edgeColor;
-    this.properties.centerColor = centerColor;
-    this.properties.gridlineCount = gridlineCount;
-  }
-};
-
-api.Content = class extends api.Fill {
-  constructor() {
-    super(api.FillType.CONTENT);
-  }
-};
-
-/**
- * Represents updates to UI element properties. Any properties set on this
- * object are relayed to an underlying native element via scene command.
- * Properties that are not set on this object are left unchanged.
- * @struct
- */
-api.UiElementUpdate = class {
-  constructor() {
-    /** @private {!Object} */
-    this.properties = {'id': -1};
-  }
-
-  /**
-   * Set the id of the element to update.
-   * @param {number} id
-   */
-  setId(id) {
-    this.properties['id'] = id;
-  }
-
-  /**
-   * Set the name of the element. This name is used for debug and testing.
-   * @param {string} name
-   */
-  setName(name) {
-    this.properties['name'] = name;
-  }
-
-  /**
-   * Specify a parent for this element. If set, this element is positioned
-   * relative to its parent element, rather than absolutely. This allows
-   * elements to automatically move with a parent.
-   * @param {number} id
-   */
-  setParentId(id) {
-    this.properties['parentId'] = id;
-  }
-
-  /**
-   * Specify the width and height (in meters) of an element.
-   * @param {number} x
-   * @param {number} y
-   */
-  setSize(x, y) {
-    this.properties['sizeX'] = x;
-    this.properties['sizeY'] = y;
-  }
-
-  /**
-   * Specify optional scaling of the element, and any children.
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   */
-  setScale(x, y, z) {
-    this.properties['scaleX'] = x;
-    this.properties['scaleY'] = y;
-    this.properties['scaleZ'] = z;
-  }
-
-  /**
-   * Specify rotation for the element. The rotation is specified in axis-angle
-   * representation (rotate around unit vector [x, y, z] by 'a' radians).
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   * @param {number} a
-   */
-  setRotation(x, y, z, a) {
-    this.properties['rotationX'] = x;
-    this.properties['rotationY'] = y;
-    this.properties['rotationZ'] = z;
-    this.properties['rotationAngle'] = a;
-  }
-
-  /**
-   * Specify the translation of the element. If anchoring is specified, the
-   * offset is applied to the anchoring position rather than the origin.
-   * Translation is applied after scaling and rotation.
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   */
-  setTranslation(x, y, z) {
-    this.properties['translationX'] = x;
-    this.properties['translationY'] = y;
-    this.properties['translationZ'] = z;
-  }
-
-  /**
-   * Anchoring allows a rectangle to be positioned relative to the edge of
-   * its parent, without being concerned about the size of the parent.
-   * Values should be XAnchoring and YAnchoring elements.
-   * Example: element.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM);
-   * @param {number} x
-   * @param {number} y
-   */
-  setAnchoring(x, y) {
-    this.properties['xAnchoring'] = x;
-    this.properties['yAnchoring'] = y;
-  }
-
-  /**
-   * Visibility controls whether the element is rendered.
-   * @param {boolean} visible
-   */
-  setVisible(visible) {
-    this.properties['visible'] = !!visible;
-  }
-
-  /**
-   * Hit-testable implies that the reticle will hit the element, if visible.
-   * @param {boolean} testable
-   */
-  setHitTestable(testable) {
-    this.properties['hitTestable'] = !!testable;
-  }
-
-  /**
-   * Causes an element to be rendered relative to the field of view, rather
-   * than the scene. Elements locked in this way should not have a parent.
-   * @param {boolean} locked
-   */
-  setLockToFieldOfView(locked) {
-    this.properties['lockToFov'] = !!locked;
-  }
-
-  /**
-   * Causes an element to be rendered with a specified opacity, between 0.0 and
-   * 1.0. Opacity is inherited by children.
-   * @param {number} opacity
-   */
-  setOpacity(opacity) {
-    this.properties['opacity'] = opacity;
-  }
-
-  setFill(fill) {
-    Object.assign(this.properties, fill.properties);
-  }
-
-  /**
-   * Sets the draw phase. Elements with a lower draw phase are rendered before
-   * elements with a higher draw phase. If elements have an equal draw phase
-   * the element with the larger distance is drawn first. The default draw phase
-   * is 1.
-   * @param {number} drawPhase
-   */
-  setDrawPhase(drawPhase) {
-    this.properties['drawPhase'] = drawPhase;
-  }
-};
-
-/**
- * Represents a new UI element. This object builds on UiElementUpdate,
- * forcing the underlying texture coordinates to be specified.
- * @struct
- */
-api.UiElement = class extends api.UiElementUpdate {
-  /**
-   * Constructor of UiElement.
-   * pixelX and pixelY values indicate the left upper corner; pixelWidth and
-   * pixelHeight is width and height of the texture to be copied from the web
-   * contents.
-   * @param {number} pixelX
-   * @param {number} pixelY
-   * @param {number} pixelWidth
-   * @param {number} pixelHeight
-   */
-  constructor(pixelX, pixelY, pixelWidth, pixelHeight) {
-    super();
-
-    // Apply defaults to new elements.
-    this.setVisible(true);
-    this.setHitTestable(true);
-    this.setFill(new api.Sprite(pixelX, pixelY, pixelWidth, pixelHeight));
-  }
-};
-
-/**
- * Enumeration of animatable properties.
- * @enum {number}
- * @const
- */
-api.Property = {
-  'COPYRECT': 0,
-  'SIZE': 1,
-  'TRANSLATION': 2,
-  'SCALE': 3,
-  'ROTATION': 4,
-  'OPACITY': 5
-};
-
-/**
- * Enumeration of easing type.
- * @enum {number}
- * @const
- */
-api.EasingType = {
-  'LINEAR': 0,
-  'CUBICBEZIER': 1,
-  'EASEIN': 2,
-  'EASEOUT': 3,
-  'EASEINOUT': 4
-};
-
-/** @const */ var DEFAULT_EASING_POW = 2;
-/** @const */ var DEFAULT_CUBIC_BEZIER_P1X = 0.25;
-/** @const */ var DEFAULT_CUBIC_BEZIER_P1Y = 0;
-/** @const */ var DEFAULT_CUBIC_BEZIER_P2X = 0.75;
-/** @const */ var DEFAULT_CUBIC_BEZIER_P2Y = 1;
-
-/**
- * Abstract easing base class.
- * @abstract
- */
-api.Easing = class {
-  constructor(type) {
-    this.type = type;
-  }
-};
-
-api.LinearEasing = class extends api.Easing {
-  constructor() {
-    super(api.EasingType.LINEAR);
-  }
-};
-
-api.CubicBezierEasing = class extends api.Easing {
-  constructor(
-      p1x = DEFAULT_CUBIC_BEZIER_P1X,
-      p1y = DEFAULT_CUBIC_BEZIER_P1Y,
-      p2x = DEFAULT_CUBIC_BEZIER_P2X,
-      p2y = DEFAULT_CUBIC_BEZIER_P2Y) {
-    super(api.EasingType.CUBICBEZIER);
-    this.p1x = p1x;
-    this.p1y = p1y;
-    this.p2x = p2x;
-    this.p2y = p2y;
-  }
-};
-
-api.InEasing = class extends api.Easing {
-  constructor(pow = DEFAULT_EASING_POW) {
-    super(api.EasingType.EASEIN);
-    this.pow = pow;
-  }
-};
-
-api.OutEasing = class extends api.Easing {
-  constructor(pow = DEFAULT_EASING_POW) {
-    super(api.EasingType.EASEOUT);
-    this.pow = pow;
-  }
-};
-
-api.InOutEasing = class extends api.Easing {
-  constructor(pow = DEFAULT_EASING_POW) {
-    super(api.EasingType.EASEINOUT);
-    this.pow = pow;
-  }
-}
-
-/**
- * Base animation class. An animation can vary only one object property.
- * @struct
- */
-api.Animation = class {
-  constructor(elementId, durationMs) {
-    /** @private {number} */
-    this.id = -1;
-    /** @private {number} */
-    this.meshId = elementId;
-    /** @private {number} */
-    this.property = -1;
-    /** @private {Object} */
-    this.to = {};
-    /** @private {Object} */
-    this.easing = new api.LinearEasing();
-
-    // How many milliseconds in the future to start the animation.
-    /** @private {number} */
-    this.startInMillis = 0.0;
-
-    // Duration of the animation (milliseconds).
-    /** @private {number} */
-    this.durationMillis = durationMs;
-  }
-
-  /**
-   * Set the id of the animation.
-   * @param {number} id
-   */
-  setId(id) {
-    this.id = id;
-  }
-
-  /**
-   * Set the delay for starting the animation.
-   * @param {number} millis
-   */
-  setDelayedStart(millis) {
-    this.startInMillis = millis;
-  }
-
-  /**
-   * Set the animation's final element size.
-   * @param {number} width
-   * @param {number} height
-   */
-  setSize(width, height) {
-    this.property = api.Property.SIZE;
-    this.to.x = width;
-    this.to.y = height;
-  }
-
-  /**
-   * Set the animation's final element scale.
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   */
-  setScale(x, y, z) {
-    this.property = api.Property.SCALE;
-    this.to.x = x;
-    this.to.y = y;
-    this.to.z = z;
-  }
-
-  /**
-   * Set the animation's final element rotation.
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   * @param {number} a
-   */
-  setRotation(x, y, z, a) {
-    this.property = api.Property.ROTATION;
-    this.to.x = x;
-    this.to.y = y;
-    this.to.z = z;
-    this.to.a = a;
-  }
-
-  /**
-   * Set the animation's final element translation.
-   * @param {number} x
-   * @param {number} y
-   * @param {number} z
-   */
-  setTranslation(x, y, z) {
-    this.property = api.Property.TRANSLATION;
-    this.to.x = x;
-    this.to.y = y;
-    this.to.z = z;
-  }
-
-  /**
-   * Set the animation's final element opacity.
-   * @param {number} opacity
-   */
-  setOpacity(opacity) {
-    this.property = api.Property.OPACITY;
-    this.to.x = opacity;
-  }
-
-  /**
-   * Set the animation's easing.
-   * @param {api.Easing} easing
-   */
-  setEasing(easing) {
-    this.easing = easing;
-  }
-};
-
-/**
- * Scene configuration class. Use this object to generate the payload of a
- * CONFIGURE_SCENE command.
- * @struct
- */
-api.SceneConfiguration = class {
-  constructor() {
-    /** @private {!Object} */
-    this.properties = {};
-  }
-
-  getCommandPayload() {
-    return this.properties;
-  }
-
-  /**
-   * Set the background color of the scene.
-   * @param {{r: number, b: number, g: number, a: number}} color
-   */
-  setBackgroundColor(color) {
-    this.properties.backgroundColor = color;
-  }
-
-  /**
-   * Set the radius of the background-bounding sphere.
-   * @param {number} distance
-   */
-  setBackgroundDistance(distance) {
-    this.properties.backgroundDistance = distance;
-  }
-
-  /**
-   * Enable or disable rendering of WebVR content in the foreground. Rendering
-   * defaults to enabled when on a WebVR page. This property allows rendering to
-   * be disabled, for purposes of showing an alternate UI (such as a menu). When
-   * disabled, the cursor is rendered.
-   * @param {boolean} enabled
-   */
-  setWebVrRenderingModeEnabled(enabled) {
-    this.properties.drawWebVr = enabled;
-  }
-};
-
-/**
- * Abstract class handling webui command calls from native.  The UI must
- * subclass this and override the handlers.
- * @abstract
- */
-api.NativeCommandHandler = class {
-  /**
-   * @param {api.Mode} mode
-   */
-  onSetMode(mode) {}
-
-  /**
-   * Handles entering or exiting full-screen mode.
-   * @param {boolean} fullscreen
-   */
-  onSetFullscreen(fullscreen) {}
-
-  /**
-   * A controller app button gesture has happened.
-   */
-  onAppButtonGesturePerformed(direction) {}
-
-  /**
-   * A controller app button click has happened.
-   */
-  onAppButtonClicked() {}
-
-  /**
-   * Handles a change in the visible page's security level.
-   * @param {number} level
-   */
-  onSetSecurityLevel(level) {}
-
-  /**
-   * Handles a change in the WebVR-specific secure-origin state. If |secure| is
-   * false, the UI must convey appropriate security warnings.
-   * @param {boolean} secure
-   */
-  onSetWebVRSecureOrigin(secure) {}
-
-  /**
-   * Handles enabling of a development-oriented control to reload the UI.
-   * @param {boolean} enabled
-   */
-  onSetReloadUiCapabilityEnabled(enabled) {}
-
-  /**
-   * Handles a new URL, specifying the host and path compoments.
-   * @param {string} host
-   * @param {string} path
-   */
-  onSetUrl(host, path) {}
-
-  /**
-   * Handle a change in loading state (used to show a spinner or other loading
-   * indicator).
-   * @param {boolean} loading
-   */
-  onSetLoading(loading) {}
-
-  /**
-   * Handle a change in loading progress. Progress is supplied as a number
-   * between 0.0 and 1.0.
-   * @param {boolean} progress
-   */
-  onSetLoadingProgress(progress) {}
-
-  /**
-   * Handle a change in the set of omnibox suggestions.
-   * @param {Array<Object>} suggestions Array of suggestions with string members
-   * |description| and |url|.
-   */
-  onSetOmniboxSuggestions(suggestions) {}
-
-  /**
-   * Handle a new set of tabs, overwriting the previous state.
-   * @param {Array<Object>} tabs Array of tab states.
-   */
-  onSetTabs(tabs) {}
-
-  /**
-   * Update (or add if not present) a tab.
-   * @param {Object} tab
-   */
-  onUpdateTab(tab) {}
-
-  /**
-   * Remove a tab.
-   * @param {Object} tab
-   */
-  onRemoveTab(tab) {}
-
-  /**
-   * Set back/forward history buttons to enabled/disabled.
-   * @param {boolean} canGoBack
-   * @param {boolean} canGoForward
-   */
-  onSetHistoryButtonsEnabled(canGoBack, canGoForward) {}
-
-  /**
-   * This function is executed after command parsing completes.
-   */
-  onCommandHandlerFinished() {}
-
-  /** @final */
-  handleCommand(dict) {
-    if ('mode' in dict) {
-      this.onSetMode(dict['mode']);
-    }
-    if ('fullscreen' in dict) {
-      this.onSetFullscreen(dict['fullscreen'])
-    }
-    if ('appButtonGesturePerformed' in dict) {
-      let direction = dict['appButtonGesturePerformed'];
-      this.onAppButtonGesturePerformed(direction);
-    }
-    if ('appButtonClicked' in dict) {
-      this.onAppButtonClicked();
-    }
-    if ('securityLevel' in dict) {
-      this.onSetSecurityLevel(dict['securityLevel']);
-    }
-    if ('webVRSecureOrigin' in dict) {
-      this.onSetWebVRSecureOrigin(dict['webVRSecureOrigin']);
-    }
-    if ('enableReloadUi' in dict) {
-      this.onSetReloadUiCapabilityEnabled(dict['enableReloadUi']);
-    }
-    if ('url' in dict) {
-      let url = dict['url'];
-      this.onSetUrl(url['host'], url['path']);
-    }
-    if ('loading' in dict) {
-      this.onSetLoading(dict['loading']);
-    }
-    if ('loadProgress' in dict) {
-      this.onSetLoadingProgress(dict['loadProgress']);
-    }
-    if ('suggestions' in dict) {
-      this.onSetOmniboxSuggestions(dict['suggestions']);
-    }
-    if ('setTabs' in dict) {
-      this.onSetTabs(dict['setTabs']);
-    }
-    if ('updateTab' in dict) {
-      this.onUpdateTab(dict['updateTab']);
-    }
-    if ('removeTab' in dict) {
-      this.onRemoveTab(dict['removeTab']);
-    }
-    if ('canGoBack' in dict) {
-      this.onSetHistoryButtonsEnabled(dict['canGoBack'], dict['canGoForward']);
-    }
-
-    this.onCommandHandlerFinished()
-  }
-};
diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui_scene.js b/chrome/browser/resources/vr_shell/vr_shell_ui_scene.js
deleted file mode 100644
index 1040382..0000000
--- a/chrome/browser/resources/vr_shell/vr_shell_ui_scene.js
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var scene = {};
-
-/**
- * The scene class assists in managing element and animations in the UI.  It
- * allows UI update API commands to be queued in batches, and manages allocation
- * of element and animation IDs.
- *
- * Examples:
- *
- * var ui = new scene.Scene();
- *
- * // Add an element.
- * var el = new api.UiElement(100, 200, 50, 50);
- * el.setSize(buttonWidth, buttonHeight);
- *
- * // Anchor it to the bottom of the content quad.
- * el.setParentId(contentQuadId);
- * el.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YBOTTOM);
- *
- * // Place it just below the content quad edge.
- * el.setTranslation(0, -0.2, 0.0);
- *
- * // Add it to the ui.
- * var buttonId = ui.addElement(el);
- * ui.flush();
- *
- * // Make the button twice as big.
- * var update = new api.UiElementUpdate();
- * update.setSize(bunttonWidth * 2, buttonHeight * 2);
- * ui.updateElement(buttonId, update);
- * ui.flush();
- *
- * // Animate the button size back to its original size, over 250 ms.
- * var resize = new api.Animation(buttonId, 250);
- * resize.setSize(buttonWidth, buttonHeight);
- * ui.addAnimation(resize);
- * ui.flush();
- *
- * @struct
- */
-scene.Scene = class {
-  constructor() {
-    /** @private {number} */
-    this.idIndex = 1;
-    /** @private {Array<Object>} */
-    this.commands = [];
-    /** @private {!Set<number>} */
-    this.elements = new Set();
-    /** @private {!Object} */
-    this.animations = [];
-  }
-
-  /**
-   * Flush all queued commands to native.
-   */
-  flush() {
-    api.sendCommands(this.commands);
-    this.commands = [];
-  }
-
-  /**
-   * Add a new UiElementUpdate to the scene, returning the ID assigned.
-   * @param {api.UiElementUpdate} element
-   */
-  addElement(element) {
-    var id = this.idIndex++;
-    element.setId(id);
-    this.commands.push(
-        {'type': api.Command.ADD_ELEMENT, 'data': element.properties});
-    this.elements.add(id);
-    return id;
-  }
-
-  /**
-   * Update an existing element, according to a UiElementUpdate object.
-   * @param {number} id
-   * @param {api.UiElementUpdate} update
-   */
-  updateElement(id, update) {
-    // To-do:  Make sure ID exists.
-    update.setId(id);
-    this.commands.push(
-        {'type': api.Command.UPDATE_ELEMENT, 'data': update.properties});
-  }
-
-  /**
-   * Remove an element from the scene.
-   * @param {number} id
-   */
-  removeElement(id) {
-    // To-do: Make sure ID exists.
-    this.commands.push(
-        {'type': api.Command.REMOVE_ELEMENT, 'data': {'id': id}});
-    this.elements.delete(id);
-  }
-
-  /**
-   * Add a new Animation to the scene, returning the ID assigned.
-   * @param {api.Animation} animation
-   */
-  addAnimation(animation) {
-    var id = this.idIndex++;
-    animation.setId(id);
-    this.commands.push({'type': api.Command.ADD_ANIMATION, 'data': animation});
-    this.animations[id] = animation.meshId;
-    return id;
-  }
-
-  /**
-   * Remove an animation from the scene.
-   *
-   * Note that animations are flushed when they complete and are not required
-   * to be removed. Also new animations of the same type will effectively
-   * override the original so there is no need to remove in that scenario
-   * either.
-   *
-   * @param {number} id
-   */
-  removeAnimation(id) {
-    // To-do: Make sure ID exists.
-    this.commands.push({
-      'type': api.Command.REMOVE_ANIMATION,
-      'data': {'id': id, 'meshId': this.animations[id]}
-    });
-    delete this.animations[id];
-  }
-
-  /**
-   * Configure scene parameters.
-   * @param {api.SceneConfiguration} configuration
-   */
-  configureScene(configuration) {
-    this.commands.push({
-      'type': api.Command.CONFIGURE_SCENE,
-      'data': configuration.getCommandPayload(),
-    });
-  }
-
-  /**
-   * @param {{r: number, b: number, g: number, a: number}} color
-   */
-  setBackgroundColor(color) {
-    let configuration = new api.SceneConfiguration();
-    configuration.setBackgroundColor(color);
-    this.configureScene(configuration);
-  }
-
-  /**
-   * @param {number} distance
-   */
-  setBackgroundDistance(distance) {
-    let configuration = new api.SceneConfiguration();
-    configuration.setBackgroundDistance(distance);
-    this.configureScene(configuration);
-  }
-
-  /**
-   * @param {boolean} enabled
-   */
-  setWebVrRenderingModeEnabled(enabled) {
-    let configuration = new api.SceneConfiguration();
-    configuration.setWebVrRenderingModeEnabled(enabled);
-    this.configureScene(configuration);
-  }
-
-  /**
-   * Purge all elements in the scene.
-   */
-  purge() {
-    var ids = Object.keys(this.animations);
-    for (let id_key of ids) {
-      var id = parseInt(id_key, 10);
-      this.removeAnimation(id);
-    }
-    var ids = this.elements.values();
-    for (let id of ids) {
-      this.removeElement(id);
-    }
-    this.flush();
-  }
-};
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 0a43bf42..530dc71 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -8,7 +8,6 @@
 import("//build/config/ui.gni")
 import("//build/split_static_library.gni")
 import("//chrome/common/features.gni")
-import("//device/vr/features.gni")
 import("//extensions/features/features.gni")
 import("//media/media_options.gni")
 import("//ppapi/features/features.gni")
@@ -589,7 +588,6 @@
     "//device/base",
     "//device/bluetooth/public/interfaces:experimental_interfaces",
     "//device/usb",
-    "//device/vr:features",
     "//extensions/features",
     "//media",
     "//net:net",
@@ -1438,7 +1436,6 @@
   }
   if (toolkit_views) {
     sources += [
-      "autofill/save_card_bubble_controller.h",
       "autofill/save_card_bubble_controller_impl.cc",
       "autofill/save_card_bubble_controller_impl.h",
       "autofill/save_card_bubble_view.h",
@@ -1466,6 +1463,8 @@
       "views/apps/native_app_window_frame_view_mac.mm",
       "views/autofill/card_unmask_prompt_views.cc",
       "views/autofill/card_unmask_prompt_views.h",
+      "views/autofill/view_util.cc",
+      "views/autofill/view_util.h",
       "views/bookmarks/bookmark_bubble_view.cc",
       "views/bookmarks/bookmark_bubble_view.h",
       "views/bookmarks/bookmark_editor_view.cc",
@@ -2321,20 +2320,6 @@
       "webui/webapks_ui.cc",
       "webui/webapks_ui.h",
     ]
-    if (enable_vr) {
-      sources += [
-        "webui/vr_shell/vr_shell_ui_message_handler.cc",
-        "webui/vr_shell/vr_shell_ui_message_handler.h",
-        "webui/vr_shell/vr_shell_ui_ui.cc",
-        "webui/vr_shell/vr_shell_ui_ui.h",
-      ]
-      configs += [ "//third_party/gvr-android-sdk:libgvr_config" ]
-      deps += [ "//chrome/browser/android/vr_shell:vr_common" ]
-    }
-    if (enable_vr_shell_ui_dev) {
-      assert(enable_vr)
-      defines += [ "ENABLE_VR_SHELL_UI_DEV" ]
-    }
     deps += [
       "//chrome/browser:jni_headers",
       "//components/web_contents_delegate_android",
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 436b8d6..a3da1293 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -24,7 +24,6 @@
 #include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
 #include "chrome/browser/ui/autofill/create_card_unmask_prompt_view.h"
 #include "chrome/browser/ui/autofill/credit_card_scanner_controller.h"
-#include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
@@ -60,6 +59,7 @@
 #include "components/infobars/core/infobar.h"
 #include "content/public/browser/android/content_view_core.h"
 #else  // !OS_ANDROID
+#include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
@@ -152,6 +152,14 @@
   return g_browser_process->ukm_service();
 }
 
+SaveCardBubbleController* ChromeAutofillClient::GetSaveCardBubbleController() {
+#if defined(OS_ANDROID)
+  return nullptr;
+#else
+  return SaveCardBubbleControllerImpl::FromWebContents(web_contents());
+#endif
+}
+
 void ChromeAutofillClient::ShowAutofillSettings() {
 #if defined(OS_ANDROID)
   chrome::android::PreferencesLauncher::ShowAutofillSettings();
@@ -198,6 +206,7 @@
 void ChromeAutofillClient::ConfirmSaveCreditCardToCloud(
     const CreditCard& card,
     std::unique_ptr<base::DictionaryValue> legal_message,
+    bool should_cvc_be_requested,
     const base::Closure& callback) {
 #if defined(OS_ANDROID)
   InfoBarService::FromWebContents(web_contents())
@@ -209,7 +218,8 @@
   autofill::SaveCardBubbleControllerImpl::CreateForWebContents(web_contents());
   autofill::SaveCardBubbleControllerImpl* controller =
       autofill::SaveCardBubbleControllerImpl::FromWebContents(web_contents());
-  controller->ShowBubbleForUpload(card, std::move(legal_message), callback);
+  controller->ShowBubbleForUpload(card, std::move(legal_message),
+                                  should_cvc_be_requested, callback);
 #endif
 }
 
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h
index ea70532..0ca505f 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.h
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -45,6 +45,7 @@
   IdentityProvider* GetIdentityProvider() override;
   rappor::RapporServiceImpl* GetRapporServiceImpl() override;
   ukm::UkmService* GetUkmService() override;
+  SaveCardBubbleController* GetSaveCardBubbleController() override;
   void ShowAutofillSettings() override;
   void ShowUnmaskPrompt(const CreditCard& card,
                         UnmaskCardReason reason,
@@ -55,6 +56,7 @@
   void ConfirmSaveCreditCardToCloud(
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
+      bool should_cvc_be_requested,
       const base::Closure& callback) override;
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    const base::Closure& callback) override;
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
index 4165569..78ad6a8 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -12,7 +12,9 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/location_bar/location_bar.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/validation.h"
 #include "components/autofill/core/common/autofill_constants.h"
+#include "components/grit/components_scaled_resources.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/navigation_handle.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -47,6 +49,7 @@
     const base::Closure& save_card_callback) {
   is_uploading_ = false;
   is_reshow_ = false;
+  should_cvc_be_requested_ = false;
   legal_message_lines_.clear();
 
   AutofillMetrics::LogSaveCardPromptMetric(
@@ -61,9 +64,11 @@
 void SaveCardBubbleControllerImpl::ShowBubbleForUpload(
     const CreditCard& card,
     std::unique_ptr<base::DictionaryValue> legal_message,
+    bool should_cvc_be_requested,
     const base::Closure& save_card_callback) {
   is_uploading_ = true;
   is_reshow_ = false;
+  should_cvc_be_requested_ = should_cvc_be_requested;
   AutofillMetrics::LogSaveCardPromptMetric(
       AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_,
       is_reshow_);
@@ -121,7 +126,28 @@
   return card_;
 }
 
-void SaveCardBubbleControllerImpl::OnSaveButton() {
+int SaveCardBubbleControllerImpl::GetCvcImageResourceId() const {
+  return card_.type() == kAmericanExpressCard ? IDR_CREDIT_CARD_CVC_HINT_AMEX
+                                              : IDR_CREDIT_CARD_CVC_HINT;
+}
+
+bool SaveCardBubbleControllerImpl::ShouldRequestCvcFromUser() const {
+  return should_cvc_be_requested_;
+}
+
+base::string16 SaveCardBubbleControllerImpl::GetCvcEnteredByUser() const {
+  DCHECK(!cvc_entered_by_user_.empty());
+  return cvc_entered_by_user_;
+}
+
+void SaveCardBubbleControllerImpl::OnSaveButton(const base::string16& cvc) {
+  if (!cvc.empty()) {
+    // Record the CVC entered by the user so it can be sent in the final
+    // request.
+    DCHECK(ShouldRequestCvcFromUser());
+    DCHECK(InputCvcIsValid(cvc));
+    base::TrimWhitespace(cvc, base::TRIM_ALL, &cvc_entered_by_user_);
+  }
   save_card_callback_.Run();
   save_card_callback_.Reset();
   AutofillMetrics::LogSaveCardPromptMetric(
@@ -159,6 +185,13 @@
   return legal_message_lines_;
 }
 
+bool SaveCardBubbleControllerImpl::InputCvcIsValid(
+    const base::string16& input_text) const {
+  base::string16 trimmed_text;
+  base::TrimWhitespace(input_text, base::TRIM_ALL, &trimmed_text);
+  return IsValidCreditCardSecurityCode(trimmed_text, card_.type());
+}
+
 base::TimeDelta SaveCardBubbleControllerImpl::Elapsed() const {
   return timer_->Elapsed();
 }
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h
index d5268d0..1f5382f 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h
@@ -9,8 +9,8 @@
 
 #include "base/macros.h"
 #include "base/timer/elapsed_timer.h"
-#include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -32,8 +32,11 @@
   // Sets up the controller for upload and shows the bubble.
   // |save_card_callback| will be invoked if and when the Save button is
   // pressed. The contents of |legal_message| will be displayed in the bubble.
+  // A field requesting CVC will appear in the bubble if
+  // |should_cvc_be_requested| is true.
   void ShowBubbleForUpload(const CreditCard& card,
                            std::unique_ptr<base::DictionaryValue> legal_message,
+                           bool should_cvc_be_requested,
                            const base::Closure& save_card_callback);
 
   void HideBubble();
@@ -49,7 +52,10 @@
   base::string16 GetWindowTitle() const override;
   base::string16 GetExplanatoryMessage() const override;
   const CreditCard GetCard() const override;
-  void OnSaveButton() override;
+  int GetCvcImageResourceId() const override;
+  bool ShouldRequestCvcFromUser() const override;
+  base::string16 GetCvcEnteredByUser() const override;
+  void OnSaveButton(const base::string16& cvc = base::string16()) override;
   void OnCancelButton() override;
   void OnLearnMoreClicked() override;
   void OnLegalMessageLinkClicked(const GURL& url) override;
@@ -57,6 +63,11 @@
 
   const LegalMessageLines& GetLegalMessageLines() const override;
 
+  // Used to check if an entered CVC value is a valid CVC for the current card.
+  // Valid CVCs are a certain length for their card type (4 for AMEX, 3
+  // otherwise) and are comprised only of numbers.
+  bool InputCvcIsValid(const base::string16& input_text) const override;
+
  protected:
   explicit SaveCardBubbleControllerImpl(content::WebContents* web_contents);
   ~SaveCardBubbleControllerImpl() override;
@@ -88,10 +99,16 @@
   base::Closure save_card_callback_;
 
   // Governs whether the upload or local save version of the UI should be shown.
-  bool is_uploading_;
+  bool is_uploading_{false};
 
   // Whether ReshowBubble() has been called since ShowBubbleFor*() was called.
-  bool is_reshow_;
+  bool is_reshow_{false};
+
+  // Whether the upload save version of the UI should ask the user for CVC.
+  bool should_cvc_be_requested_{false};
+
+  // The value of the CVC entered by the user (if it was requested).
+  base::string16 cvc_entered_by_user_;
 
   // Contains the details of the card that will be saved if the user accepts.
   CreditCard card_;
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
index 96893557..a1121ec0e 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl_unittest.cc
@@ -69,7 +69,8 @@
     return new SaveCardBubbleTestBrowserWindow();
   }
 
-  void SetLegalMessage(const std::string& message_json) {
+  void SetLegalMessage(const std::string& message_json,
+                       bool should_cvc_be_requested = false) {
     std::unique_ptr<base::Value> value(base::JSONReader::Read(message_json));
     ASSERT_TRUE(value);
     base::DictionaryValue* dictionary;
@@ -77,6 +78,7 @@
     std::unique_ptr<base::DictionaryValue> legal_message =
         dictionary->CreateDeepCopy();
     controller()->ShowBubbleForUpload(CreditCard(), std::move(legal_message),
+                                      should_cvc_be_requested,
                                       base::Bind(&SaveCardCallback));
   }
 
@@ -85,13 +87,14 @@
                                          base::Bind(&SaveCardCallback));
   }
 
-  void ShowUploadBubble() {
+  void ShowUploadBubble(bool should_cvc_be_requested = false) {
     SetLegalMessage(
         "{"
         "  \"line\" : [ {"
         "     \"template\": \"This is the entire message.\""
         "  } ]"
-        "}");
+        "}",
+        should_cvc_be_requested);
   }
 
   void CloseAndReshowBubble() {
@@ -140,6 +143,18 @@
   EXPECT_TRUE(controller()->GetLegalMessageLines().empty());
 }
 
+TEST_F(SaveCardBubbleControllerImplTest,
+       PropagateShouldRequestCvcFromUserWhenFalse) {
+  ShowUploadBubble();
+  EXPECT_FALSE(controller()->ShouldRequestCvcFromUser());
+}
+
+TEST_F(SaveCardBubbleControllerImplTest,
+       PropagateShouldRequestCvcFromUserWhenTrue) {
+  ShowUploadBubble(true /* should_cvc_be_requested */);
+  EXPECT_TRUE(controller()->ShouldRequestCvcFromUser());
+}
+
 TEST_F(SaveCardBubbleControllerImplTest, Metrics_Local_FirstShow_ShowBubble) {
   base::HistogramTester histogram_tester;
   ShowLocalBubble();
@@ -164,7 +179,8 @@
                   Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1)));
 }
 
-TEST_F(SaveCardBubbleControllerImplTest, Metrics_Upload_FirstShow_ShowBubble) {
+TEST_F(SaveCardBubbleControllerImplTest,
+       Metrics_Upload_FirstShow_ShowBubble_NotRequestCvc) {
   base::HistogramTester histogram_tester;
   ShowUploadBubble();
 
@@ -175,6 +191,18 @@
                   Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1)));
 }
 
+TEST_F(SaveCardBubbleControllerImplTest,
+       Metrics_Upload_FirstShow_ShowBubble_RequestCvc) {
+  base::HistogramTester histogram_tester;
+  ShowUploadBubble(true /* should_cvc_be_requested */);
+
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(
+          "Autofill.SaveCreditCardPrompt.Upload.FirstShow"),
+      ElementsAre(Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, 1),
+                  Bucket(AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1)));
+}
+
 TEST_F(SaveCardBubbleControllerImplTest, Metrics_Upload_Reshows_ShowBubble) {
   ShowUploadBubble();
 
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
index 2ff18c8..7b0ca85 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
@@ -6,12 +6,12 @@
 
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/browser/ui/cocoa/chrome_style.h"
 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
 #include "components/strings/grit/components_strings.h"
 #include "skia/ext/skia_utils_mac.h"
 #include "ui/base/cocoa/cocoa_base_utils.h"
@@ -71,7 +71,7 @@
 
 void SaveCardBubbleViewBridge::OnSaveButton() {
   if (controller_)
-    controller_->OnSaveButton();
+    controller_->OnSaveButton(base::string16());
   Hide();
 }
 
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
index ef04955..e8e200c 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
@@ -8,11 +8,12 @@
 
 #include "base/json/json_reader.h"
 #include "base/values.h"
-#include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.h"
 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
 #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
 #include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "ui/events/test/cocoa_test_event_utils.h"
 
@@ -33,17 +34,16 @@
   }
 
   // SaveCardBubbleController:
-  base::string16 GetWindowTitle() const override { return base::string16(); }
+  MOCK_CONST_METHOD0(GetWindowTitle, base::string16());
+  MOCK_CONST_METHOD0(GetExplanatoryMessage, base::string16());
+  MOCK_CONST_METHOD0(GetCard, const CreditCard());
+  MOCK_CONST_METHOD0(GetCvcImageResourceId, int());
+  MOCK_CONST_METHOD0(ShouldRequestCvcFromUser, bool());
+  MOCK_CONST_METHOD0(GetCvcEnteredByUser, base::string16());
 
-  base::string16 GetExplanatoryMessage() const override {
-    return base::string16();
+  void OnSaveButton(const base::string16& cvc) override {
+    on_save_button_was_called_ = true;
   }
-
-  const CreditCard GetCard() const override {
-    return CreditCard();
-  }
-
-  void OnSaveButton() override { on_save_button_was_called_ = true; }
   void OnCancelButton() override { on_cancel_button_was_called_ = true; }
   void OnLearnMoreClicked() override { on_learn_more_was_called_ = true; }
   void OnLegalMessageLinkClicked(const GURL& url) override {
@@ -56,6 +56,8 @@
     return lines_;
   }
 
+  MOCK_CONST_METHOD1(InputCvcIsValid, bool(const base::string16& input_text));
+
   // Testing state.
   bool on_save_button_was_called() { return on_save_button_was_called_; }
   bool on_cancel_button_was_called() { return on_cancel_button_was_called_; }
diff --git a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
index 2d35985..10d7e221 100644
--- a/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
+++ b/chrome/browser/ui/views/autofill/card_unmask_prompt_views.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/ui/autofill/create_card_unmask_prompt_view.h"
+#include "chrome/browser/ui/views/autofill/view_util.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
 #include "components/autofill/core/browser/ui/card_unmask_prompt_controller.h"
@@ -436,12 +437,8 @@
       input_row_->child_at(i)->SetVisible(false);
   }
 
-  cvc_input_ = new views::Textfield();
-  cvc_input_->set_placeholder_text(
-      l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC));
+  cvc_input_ = CreateCvcTextfield();
   cvc_input_->set_controller(this);
-  cvc_input_->set_default_width_in_chars(8);
-  cvc_input_->SetTextInputType(ui::TextInputType::TEXT_INPUT_TYPE_NUMBER);
   input_row_->AddChildView(cvc_input_);
 
   views::ImageView* cvc_image = new views::ImageView();
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
index 2549a175..ecddc83 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -8,9 +8,10 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
-#include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
+#include "chrome/browser/ui/views/autofill/view_util.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/legal_message_line.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -21,14 +22,16 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/link.h"
 #include "ui/views/controls/styled_label.h"
+#include "ui/views/controls/textfield/textfield.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/layout_constants.h"
+#include "ui/views/window/dialog_client_view.h"
 
 namespace autofill {
 
 namespace {
 
-// Fixed width of the bubble.
+// Fixed width of the bubble, in dip.
 const int kBubbleWidth = 395;
 
 std::unique_ptr<views::StyledLabel> CreateLegalMessageLineLabel(
@@ -50,6 +53,7 @@
                                          SaveCardBubbleController* controller)
     : LocationBarBubbleDelegateView(anchor_view, web_contents),
       controller_(controller),
+      cvc_textfield_(nullptr),
       learn_more_link_(nullptr) {
   DCHECK(controller);
   views::BubbleDialogDelegateView::CreateBubble(this);
@@ -92,7 +96,8 @@
 
 bool SaveCardBubbleViews::Accept() {
   if (controller_)
-    controller_->OnSaveButton();
+    controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text()
+                                             : base::string16());
   return true;
 }
 
@@ -200,6 +205,10 @@
   description_view->AddChildView(
       new views::Label(card.AbbreviatedExpirationDateForDisplay()));
 
+  // Optionally add CVC request field if CVC was missing.
+  if (controller_->ShouldRequestCvcFromUser())
+    view->AddChildView(CreateRequestCvcView().release());
+
   // Optionally add label that will contain an explanation for upload.
   base::string16 explanation = controller_->GetExplanatoryMessage();
   if (!explanation.empty()) {
@@ -212,6 +221,42 @@
   return view;
 }
 
+std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() {
+  std::unique_ptr<View> request_cvc_view = base::MakeUnique<views::View>();
+  request_cvc_view->SetLayoutManager(new views::BoxLayout(
+      views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing));
+
+  DCHECK(!cvc_textfield_);
+  cvc_textfield_ = CreateCvcTextfield();
+  cvc_textfield_->set_controller(this);
+  request_cvc_view->AddChildView(cvc_textfield_);
+
+  views::ImageView* cvc_image = new views::ImageView();
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  cvc_image->SetImage(
+      rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId()));
+  request_cvc_view->AddChildView(cvc_image);
+
+  request_cvc_view->AddChildView(new views::Label(
+      l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC)));
+  return request_cvc_view;
+}
+
+bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const {
+  if (button == ui::DIALOG_BUTTON_CANCEL)
+    return true;
+
+  DCHECK_EQ(ui::DIALOG_BUTTON_OK, button);
+  return !cvc_textfield_ ||
+         controller_->InputCvcIsValid(cvc_textfield_->text());
+}
+
+void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender,
+                                          const base::string16& new_contents) {
+  DCHECK_EQ(cvc_textfield_, sender);
+  GetDialogClientView()->UpdateDialogButtons();
+}
+
 void SaveCardBubbleViews::Init() {
   SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
   AddChildView(CreateMainContentView().release());
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.h b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
index a7390a2..ca03dfc 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.h
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.h
@@ -6,11 +6,12 @@
 #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_CARD_BUBBLE_VIEWS_H_
 
 #include "base/macros.h"
-#include "chrome/browser/ui/autofill/save_card_bubble_controller.h"
 #include "chrome/browser/ui/autofill/save_card_bubble_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
 #include "ui/views/controls/link_listener.h"
 #include "ui/views/controls/styled_label_listener.h"
+#include "ui/views/controls/textfield/textfield_controller.h"
 
 namespace content {
 class WebContents;
@@ -19,6 +20,7 @@
 namespace views {
 class Link;
 class StyledLabel;
+class Textfield;
 }
 
 namespace autofill {
@@ -29,7 +31,8 @@
 class SaveCardBubbleViews : public SaveCardBubbleView,
                             public LocationBarBubbleDelegateView,
                             public views::LinkListener,
-                            public views::StyledLabelListener {
+                            public views::StyledLabelListener,
+                            public views::TextfieldController {
  public:
   // Bubble will be anchored to |anchor_view|.
   SaveCardBubbleViews(views::View* anchor_view,
@@ -49,6 +52,7 @@
   bool Close() override;
   int GetDialogButtons() const override;
   base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
+  bool IsDialogButtonEnabled(ui::DialogButton button) const override;
   bool ShouldDefaultButtonBeBlue() const override;
 
   // views::View
@@ -66,16 +70,23 @@
                               const gfx::Range& range,
                               int event_flags) override;
 
+  // views::TextfieldController
+  void ContentsChanged(views::Textfield* sender,
+                       const base::string16& new_contents) override;
+
  private:
   ~SaveCardBubbleViews() override;
 
   std::unique_ptr<views::View> CreateMainContentView();
+  std::unique_ptr<views::View> CreateRequestCvcView();
 
   // views::BubbleDialogDelegateView
   void Init() override;
 
   SaveCardBubbleController* controller_;  // Weak reference.
 
+  views::Textfield* cvc_textfield_;
+
   views::Link* learn_more_link_;
 
   DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleViews);
diff --git a/chrome/browser/ui/views/autofill/view_util.cc b/chrome/browser/ui/views/autofill/view_util.cc
new file mode 100644
index 0000000..9e3a1ba
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/view_util.cc
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/autofill/view_util.h"
+
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/controls/textfield/textfield.h"
+
+namespace autofill {
+
+views::Textfield* CreateCvcTextfield() {
+  views::Textfield* textfield = new views::Textfield();
+  textfield->set_placeholder_text(
+      l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC));
+  textfield->set_default_width_in_chars(8);
+  textfield->SetTextInputType(ui::TextInputType::TEXT_INPUT_TYPE_NUMBER);
+  return textfield;
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/view_util.h b/chrome/browser/ui/views/autofill/view_util.h
new file mode 100644
index 0000000..64c7abb
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/view_util.h
@@ -0,0 +1,17 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_
+#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_
+
+#include "ui/views/controls/textfield/textfield.h"
+
+namespace autofill {
+
+// Creates and returns a small Textfield intended to be used for CVC entry.
+views::Textfield* CreateCvcTextfield();
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index c7706ff..ef5295b 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -186,6 +186,40 @@
   return layout;
 }
 
+std::unique_ptr<views::View> CreateCheckingSpinnerView() {
+  std::unique_ptr<views::View> container = base::MakeUnique<views::View>();
+
+  std::unique_ptr<views::Throbber> throbber =
+      base::MakeUnique<views::Throbber>();
+  throbber->Start();
+  std::unique_ptr<views::GridLayout> layout =
+      base::MakeUnique<views::GridLayout>(container.get());
+  views::ColumnSet* throbber_columns = layout->AddColumnSet(0);
+  throbber_columns->AddPaddingColumn(0.5, 0);
+  throbber_columns->AddColumn(views::GridLayout::Alignment::CENTER,
+                              views::GridLayout::Alignment::TRAILING, 0,
+                              views::GridLayout::SizeType::USE_PREF, 0, 0);
+  throbber_columns->AddPaddingColumn(0.5, 0);
+
+  views::ColumnSet* label_columns = layout->AddColumnSet(1);
+  label_columns->AddPaddingColumn(0.5, 0);
+  label_columns->AddColumn(views::GridLayout::Alignment::CENTER,
+                           views::GridLayout::Alignment::LEADING, 0,
+                           views::GridLayout::SizeType::USE_PREF, 0, 0);
+  label_columns->AddPaddingColumn(0.5, 0);
+
+  layout->StartRow(0.5, 0);
+  layout->AddView(throbber.release());
+
+  layout->StartRow(0.5, 1);
+  layout->AddView(new views::Label(
+      l10n_util::GetStringUTF16(IDS_PAYMENTS_CHECKING_OPTION)));
+
+  container->SetLayoutManager(layout.release());
+
+  return container;
+}
+
 }  // namespace
 
 PaymentSheetViewController::PaymentSheetViewController(
@@ -194,7 +228,8 @@
     PaymentRequestDialogView* dialog)
     : PaymentRequestSheetController(spec, state, dialog),
       pay_button_(nullptr),
-      widest_name_column_view_width_(ComputeWidestNameColumnViewWidth()) {
+      widest_name_column_view_width_(ComputeWidestNameColumnViewWidth()),
+      current_update_reason_(PaymentRequestSpec::UpdateReason::NONE) {
   spec->AddObserver(this);
   state->AddObserver(this);
 }
@@ -204,7 +239,14 @@
   state()->RemoveObserver(this);
 }
 
+void PaymentSheetViewController::OnStartUpdating(
+    PaymentRequestSpec::UpdateReason reason) {
+  current_update_reason_ = reason;
+  UpdateContentView();
+}
+
 void PaymentSheetViewController::OnSpecUpdated() {
+  current_update_reason_ = PaymentRequestSpec::UpdateReason::NONE;
   UpdateContentView();
 }
 
@@ -394,12 +436,17 @@
 
 std::unique_ptr<views::View>
 PaymentSheetViewController::CreateShippingSectionContent() {
-  auto* profile = state()->selected_shipping_profile();
+  if (current_update_reason_ ==
+      PaymentRequestSpec::UpdateReason::SHIPPING_ADDRESS) {
+    return CreateCheckingSpinnerView();
+  } else {
+    auto* profile = state()->selected_shipping_profile();
 
-  return profile ? GetShippingAddressLabel(AddressStyleType::SUMMARY,
-                                           state()->GetApplicationLocale(),
-                                           *profile)
-                 : base::MakeUnique<views::Label>(base::string16());
+    return profile ? GetShippingAddressLabel(AddressStyleType::SUMMARY,
+                                             state()->GetApplicationLocale(),
+                                             *profile)
+                   : base::MakeUnique<views::Label>(base::string16());
+  }
 }
 
 // Creates the Shipping row, which contains a "Shipping address" label, the
@@ -501,16 +548,25 @@
 PaymentSheetViewController::CreateShippingOptionRow() {
   mojom::PaymentShippingOption* selected_option =
       spec()->selected_shipping_option();
-  if (!selected_option)
+  if (!selected_option &&
+      current_update_reason_ !=
+          PaymentRequestSpec::UpdateReason::SHIPPING_OPTION) {
     return nullptr;
+  }
 
-  std::unique_ptr<views::View> option_label = CreateShippingOptionLabel(
-      selected_option, selected_option ? spec()->GetFormattedCurrencyAmount(
-                                             selected_option->amount->value)
-                                       : base::ASCIIToUTF16(""));
+  std::unique_ptr<views::View> option_row_content =
+      current_update_reason_ ==
+              PaymentRequestSpec::UpdateReason::SHIPPING_OPTION
+          ? CreateCheckingSpinnerView()
+          : CreateShippingOptionLabel(selected_option,
+                                      selected_option
+                                          ? spec()->GetFormattedCurrencyAmount(
+                                                selected_option->amount->value)
+                                          : base::ASCIIToUTF16(""));
+
   std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this, GetShippingOptionSectionString(spec()->shipping_type()),
-      std::move(option_label), std::unique_ptr<views::View>(nullptr),
+      std::move(option_row_content), std::unique_ptr<views::View>(nullptr),
       widest_name_column_view_width_);
   section->set_tag(static_cast<int>(
       PaymentSheetViewControllerTags::SHOW_SHIPPING_OPTION_BUTTON));
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.h b/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
index 430b04c..bf202f2 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
@@ -30,6 +30,7 @@
 
   // PaymentRequestSpec::Observer:
   void OnInvalidSpecProvided() override {}
+  void OnStartUpdating(PaymentRequestSpec::UpdateReason reason) override;
   void OnSpecUpdated() override;
 
   // PaymentRequestState::Observer:
@@ -57,6 +58,7 @@
   views::Button* pay_button_;
 
   const int widest_name_column_view_width_;
+  PaymentRequestSpec::UpdateReason current_update_reason_;
 
   DISALLOW_COPY_AND_ASSIGN(PaymentSheetViewController);
 };
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 53e6ac0..03fb00a 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -81,7 +81,6 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_utils.h"
-#include "device/vr/features.h"
 #include "extensions/features/features.h"
 #include "media/media_features.h"
 #include "ppapi/features/features.h"
@@ -117,9 +116,6 @@
 #include "chrome/browser/ui/webui/popular_sites_internals_ui.h"
 #include "chrome/browser/ui/webui/snippets_internals_ui.h"
 #include "chrome/browser/ui/webui/webapks_ui.h"
-#if BUILDFLAG(ENABLE_VR)
-#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.h"
-#endif
 #else
 #include "chrome/browser/signin/easy_unlock_service.h"
 #include "chrome/browser/signin/easy_unlock_service_factory.h"
@@ -530,10 +526,6 @@
     return &NewWebUI<SnippetsInternalsUI>;
   if (url.host_piece() == chrome::kChromeUIWebApksHost)
     return &NewWebUI<WebApksUI>;
-#if BUILDFLAG(ENABLE_VR)
-  if (url.host_piece() == chrome::kChromeUIVrShellUIHost)
-    return &NewWebUI<VrShellUIUI>;
-#endif
 #else
   if (url.SchemeIs(content::kChromeDevToolsScheme)) {
     if (!DevToolsUIBindings::IsValidFrontendURL(url))
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
index 729ff1a2..bfd56ed 100644
--- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
@@ -7,17 +7,21 @@
 #include <string>
 #include <utility>
 
+#include "ash/system/devicetype_utils.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/sys_info.h"
 #include "base/task_scheduler/post_task.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/grit/generated_resources.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/cryptohome/homedir_methods.h"
 #include "chromeos/dbus/cryptohome_client.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
 #include "chromeos/dbus/power_manager_client.h"
+#include "components/login/localized_values_builder.h"
+#include "ui/base/text/bytes_formatting.h"
 
 namespace {
 
@@ -95,7 +99,49 @@
 }
 
 void EncryptionMigrationScreenHandler::DeclareLocalizedValues(
-    ::login::LocalizedValuesBuilder* builder) {}
+    ::login::LocalizedValuesBuilder* builder) {
+  builder->Add("migrationReadyTitle", IDS_ENCRYPTION_MIGRATION_READY_TITLE);
+  builder->Add("migrationReadyDescription",
+               ash::SubstituteChromeOSDeviceType(
+                   IDS_ENCRYPTION_MIGRATION_READY_DESCRIPTION));
+  builder->Add("migrationMigratingTitle",
+               IDS_ENCRYPTION_MIGRATION_MIGRATING_TITLE);
+  builder->Add("migrationMigratingDescription",
+               ash::SubstituteChromeOSDeviceType(
+                   IDS_ENCRYPTION_MIGRATION_MIGRATING_DESCRIPTION));
+  builder->Add("migrationProgressLabel",
+               IDS_ENCRYPTION_MIGRATION_PROGRESS_LABEL);
+  builder->Add("migrationBatteryWarningLabel",
+               IDS_ENCRYPTION_MIGRATION_BATTERY_WARNING_LABEL);
+  builder->Add("migrationAskChargeMessage",
+               ash::SubstituteChromeOSDeviceType(
+                   IDS_ENCRYPTION_MIGRATION_ASK_CHARGE_MESSAGE));
+  builder->Add("migrationNecessaryBatteryLevelLabel",
+               IDS_ENCRYPTION_MIGRATION_NECESSARY_BATTERY_LEVEL_MESSAGE);
+  builder->Add("migrationChargingLabel",
+               IDS_ENCRYPTION_MIGRATION_CHARGING_LABEL);
+  builder->Add("migrationFailedTitle", IDS_ENCRYPTION_MIGRATION_FAILED_TITLE);
+  builder->Add("migrationFailedSubtitle",
+               IDS_ENCRYPTION_MIGRATION_FAILED_SUBTITLE);
+  builder->Add("migrationFailedMessage",
+               ash::SubstituteChromeOSDeviceType(
+                   IDS_ENCRYPTION_MIGRATION_FAILED_MESSAGE));
+  builder->Add("migrationNospaceWarningLabel",
+               IDS_ENCRYPTION_MIGRATION_NOSPACE_WARNING_LABEL);
+  builder->Add("migrationAskFreeSpaceMessage",
+               IDS_ENCRYPTION_MIGRATION_ASK_FREE_SPACE_MESSAGE);
+  builder->Add("migrationAvailableSpaceLabel",
+               IDS_ENCRYPTION_MIGRATION_AVAILABLE_SPACE_LABEL);
+  builder->Add("migrationNecessarySpaceLabel",
+               IDS_ENCRYPTION_MIGRATION_NECESSARY_SPACE_LABEL);
+  builder->Add("migrationButtonUpdate", IDS_ENCRYPTION_MIGRATION_BUTTON_UPDATE);
+  builder->Add("migrationButtonSkip", IDS_ENCRYPTION_MIGRATION_BUTTON_SKIP);
+  builder->Add("migrationButtonRestart",
+               IDS_ENCRYPTION_MIGRATION_BUTTON_RESTART);
+  builder->Add("migrationButtonContinue",
+               IDS_ENCRYPTION_MIGRATION_BUTTON_CONTINUE);
+  builder->Add("migrationButtonSignIn", IDS_ENCRYPTION_MIGRATION_BUTTON_SIGNIN);
+}
 
 void EncryptionMigrationScreenHandler::Initialize() {
   if (!page_is_ready() || !delegate_)
@@ -121,8 +167,10 @@
 void EncryptionMigrationScreenHandler::PowerChanged(
     const power_manager::PowerSupplyProperties& proto) {
   current_battery_percent_ = proto.battery_percent();
-  CallJS("setBatteryPercent", current_battery_percent_,
-         current_battery_percent_ >= kMinimumBatteryPercent);
+  CallJS("setBatteryState", current_battery_percent_,
+         current_battery_percent_ >= kMinimumBatteryPercent,
+         proto.battery_state() ==
+             power_manager::PowerSupplyProperties_BatteryState_CHARGING);
 
   // If the migration was already requested and the bettery level is enough now,
   // The migration should start immediately.
@@ -150,9 +198,6 @@
 }
 
 void EncryptionMigrationScreenHandler::HandleRequestRestart() {
-  // TODO(fukino): If the migration finished successfully, we don't need to
-  // restart the device. Let's sign in to the desktop using the already-provided
-  // user credential.
   chrome::AttemptRestart();
 }
 
@@ -188,6 +233,9 @@
       UpdateUIState(UIState::READY);
     }
   } else {
+    CallJS("setAvailableSpaceInString", ui::FormatBytes(size));
+    CallJS("setNecessarySpaceInString",
+           ui::FormatBytes(kMinimumAvailableStorage));
     UpdateUIState(UIState::NOT_ENOUGH_STORAGE);
   }
 }
@@ -244,10 +292,11 @@
       CallJS("setMigrationProgress", static_cast<double>(current) / total);
       break;
     case cryptohome::DIRCRYPTO_MIGRATION_SUCCESS:
+      // Restart immediately after successful migration.
+      chrome::AttemptRestart();
+      break;
     case cryptohome::DIRCRYPTO_MIGRATION_FAILED:
-      UpdateUIState(status == cryptohome::DIRCRYPTO_MIGRATION_SUCCESS
-                        ? UIState::MIGRATION_SUCCEEDED
-                        : UIState::MIGRATION_FAILED);
+      UpdateUIState(UIState::MIGRATION_FAILED);
       // Stop listening to the progress updates.
       DBusThreadManager::Get()
           ->GetCryptohomeClient()
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
index b4e9cd6..de278cd6 100644
--- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.h
@@ -43,9 +43,8 @@
     INITIAL = 0,
     READY = 1,
     MIGRATING = 2,
-    MIGRATION_SUCCEEDED = 3,
-    MIGRATION_FAILED = 4,
-    NOT_ENOUGH_STORAGE = 5,
+    MIGRATION_FAILED = 3,
+    NOT_ENOUGH_STORAGE = 4,
   };
 
   // WebUIMessageHandler implementation:
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 3b6cbfd..c7941c628 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -118,6 +118,7 @@
 const char kArcPlaystoreCSSPath[] = "playstore.css";
 const char kArcPlaystoreJSPath[] = "playstore.js";
 const char kArcPlaystoreLogoPath[] = "playstore.svg";
+const char kProductLogoPath[] = "product-logo.png";
 
 // Creates a WebUIDataSource for chrome://oobe
 content::WebUIDataSource* CreateOobeUIDataSource(
@@ -163,6 +164,9 @@
   source->AddResourcePath(kArcPlaystoreLogoPath,
       IDR_ARC_SUPPORT_PLAYSTORE_LOGO);
 
+  // Required in encryption migration screen.
+  source->AddResourcePath(kProductLogoPath, IDR_PRODUCT_LOGO_64);
+
   source->AddResourcePath(kKeyboardUtilsJSPath, IDR_KEYBOARD_UTILS_JS);
   source->OverrideContentSecurityPolicyChildSrc(
       base::StringPrintf(
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
index 4ea500a5..fc794b79 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
@@ -491,17 +491,20 @@
   display::DisplayManager* display_manager = GetDisplayManager();
   scoped_refptr<display::ManagedDisplayMode> current_mode =
       display_manager->GetActiveModeForDisplayId(display_id);
-  if (!display_manager->SetDisplayMode(display_id, mode)) {
-    LOG(ERROR) << "Unable to set display mode for: " << display_id
-               << " Mode: " << *mode_data;
+
+  if (mode->IsEquivalent(current_mode)) {
+    LOG(ERROR) << "New display mode matches current mode.";
     return;
   }
-  if (display::Display::IsInternalDisplayId(display_id))
-    return;
-  // For external displays, show a notification confirming the resolution
-  // change.
-  ash::Shell::Get()->resolution_notification_controller()->PrepareNotification(
-      display_id, current_mode, mode, base::Bind(&chromeos::StoreDisplayPrefs));
+
+  if (!ash::Shell::Get()
+           ->resolution_notification_controller()
+           ->PrepareNotificationAndSetDisplayMode(
+               display_id, current_mode, mode,
+               base::Bind(&chromeos::StoreDisplayPrefs))) {
+    LOG(ERROR) << "Unable to set display mode for: " << display_id
+               << " Mode: " << *mode_data;
+  }
 }
 
 void DisplayOptionsHandler::HandleSetRotation(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/vr_shell/OWNERS b/chrome/browser/ui/webui/vr_shell/OWNERS
deleted file mode 100644
index f104584a8..0000000
--- a/chrome/browser/ui/webui/vr_shell/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-bshe@chromium.org
-girard@chromium.org
-mthiesse@chromium.org
-cjgrant@chromium.org
-
-# COMPONENT: UI>Browser>VR
diff --git a/chrome/browser/ui/webui/vr_shell/PRESUBMIT.py b/chrome/browser/ui/webui/vr_shell/PRESUBMIT.py
deleted file mode 100644
index e24a7c0..0000000
--- a/chrome/browser/ui/webui/vr_shell/PRESUBMIT.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for changes affecting chrome/browser/ui/webui/vr_shell
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into depot_tools.
-"""
-
-import re
-
-# chrome/PRESUBMIT.py blocks several linters due to the infeasibility of
-# enforcing them on a large codebase. Here we'll start by enforcing all
-# linters, and add exclusions if necessary.
-#
-# Note that this list must be non-empty, or cpplint will use its default set of
-# filters. Therefore, explicitly enable a single dummy linter.
-LINT_FILTERS = [
-  '+build/include',
-]
-
-VERBOSITY_LEVEL = 4
-
-INCLUDE_CPP_FILES_ONLY = (r'.*\.(cc|h)$',)
-
-def _CheckChangeLintsClean(input_api, output_api):
-  sources = lambda x: input_api.FilterSourceFile(
-      x, white_list=INCLUDE_CPP_FILES_ONLY)
-  return input_api.canned_checks.CheckChangeLintsClean(
-      input_api, output_api, sources, LINT_FILTERS, VERBOSITY_LEVEL)
-
-def CheckChangeOnUpload(input_api, output_api):
-  results = []
-  results.extend(_CheckChangeLintsClean(input_api, output_api))
-  return results
-
-def CheckChangeOnCommit(input_api, output_api):
-  results = []
-  results.extend(_CheckChangeLintsClean(input_api, output_api))
-  return results
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc
deleted file mode 100644
index db9b4f1..0000000
--- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/values.h"
-#include "chrome/browser/android/vr_shell/ui_interface.h"
-#include "chrome/browser/android/vr_shell/ui_scene.h"
-#include "chrome/browser/android/vr_shell/vr_shell.h"
-#include "content/public/browser/web_ui.h"
-
-VrShellUIMessageHandler::VrShellUIMessageHandler() = default;
-
-VrShellUIMessageHandler::~VrShellUIMessageHandler() {
-  if (vr_shell_) {
-    vr_shell_->GetUiInterface()->SetUiCommandHandler(nullptr);
-  }
-}
-
-void VrShellUIMessageHandler::RegisterMessages() {
-  vr_shell_ = vr_shell::VrShell::GetWeakPtr(web_ui()->GetWebContents());
-
-  web_ui()->RegisterMessageCallback(
-      "domLoaded", base::Bind(&VrShellUIMessageHandler::HandleDomLoaded,
-                              base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
-      "updateScene",
-      base::Bind(&VrShellUIMessageHandler::HandleUpdateScene,
-                 base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
-      "doAction", base::Bind(&VrShellUIMessageHandler::HandleDoAction,
-                             base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
-      "setContentCssSize",
-      base::Bind(&VrShellUIMessageHandler::HandleSetContentCssSize,
-                 base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
-      "setUiCssSize", base::Bind(&VrShellUIMessageHandler::HandleSetUiCssSize,
-                                 base::Unretained(this)));
-}
-
-void VrShellUIMessageHandler::HandleDomLoaded(const base::ListValue* args) {
-  AllowJavascript();
-}
-
-void VrShellUIMessageHandler::OnJavascriptAllowed() {
-  // If we don't have a VR Shell here, it means either the user manually loaded
-  // this webui page and we want to silently fail to connect to native vr shell,
-  // or VR Shell was deleted, and this webui content is also about to be
-  // deleted.
-  if (!vr_shell_)
-    return;
-  vr_shell_->GetUiInterface()->SetUiCommandHandler(this);
-  vr_shell_->OnDomContentsLoaded();
-}
-
-void VrShellUIMessageHandler::HandleUpdateScene(const base::ListValue* args) {
-  if (!vr_shell_)
-    return;
-  vr_shell_->UpdateScene(args);
-}
-
-void VrShellUIMessageHandler::HandleDoAction(const base::ListValue* args) {
-  int action;
-  const base::DictionaryValue* arguments = nullptr;
-  CHECK(args->GetInteger(0, &action));
-  CHECK(args->GetDictionary(1, &arguments));
-  if (vr_shell_)
-    vr_shell_->DoUiAction(static_cast<vr_shell::UiAction>(action), arguments);
-}
-
-void VrShellUIMessageHandler::HandleSetContentCssSize(
-    const base::ListValue* args) {
-  if (!vr_shell_)
-    return;
-  SetSize(args, false);
-}
-
-void VrShellUIMessageHandler::HandleSetUiCssSize(const base::ListValue* args) {
-  if (!vr_shell_)
-    return;
-  SetSize(args, true);
-}
-
-void VrShellUIMessageHandler::SetSize(const base::ListValue* args,
-                                      bool for_ui) {
-  CHECK(args->GetSize() == 3);
-  double width, height, dpr;
-  CHECK(args->GetDouble(0, &width));
-  CHECK(args->GetDouble(1, &height));
-  CHECK(args->GetDouble(2, &dpr));
-  if (for_ui) {
-    vr_shell_->SetUiCssSize(width, height, dpr);
-  } else {
-    vr_shell_->SetContentCssSize(width, height, dpr);
-  }
-}
-
-void VrShellUIMessageHandler::SendCommandToUi(const base::Value& value) {
-  CallJavascriptFunction("vrShellUi.command", value);
-}
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h
deleted file mode 100644
index be0825e..0000000
--- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_MESSAGE_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_MESSAGE_HANDLER_H_
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/android/vr_shell/ui_interface.h"
-#include "content/public/browser/web_ui_message_handler.h"
-
-namespace base {
-class ListValue;
-}
-
-namespace vr_shell {
-class VrShell;
-}
-
-class VrShellUIMessageHandler : public content::WebUIMessageHandler,
-                                public vr_shell::UiCommandHandler {
- public:
-  VrShellUIMessageHandler();
-  ~VrShellUIMessageHandler() override;
-
-  void SendCommandToUi(const base::Value& value) override;
-
- private:
-  // content::WebUIMessageHandler:
-  void RegisterMessages() override;
-  void OnJavascriptAllowed() override;
-
-  void HandleDomLoaded(const base::ListValue* args);
-  void HandleUpdateScene(const base::ListValue* args);
-  void HandleDoAction(const base::ListValue* args);
-  void HandleSetContentCssSize(const base::ListValue* args);
-  void HandleSetUiCssSize(const base::ListValue* args);
-  void SetSize(const base::ListValue* args, bool for_ui);
-
-  base::WeakPtr<vr_shell::VrShell> vr_shell_;
-
-  DISALLOW_COPY_AND_ASSIGN(VrShellUIMessageHandler);
-};
-
-#endif  // CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_MESSAGE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc
deleted file mode 100644
index 08fc70fd..0000000
--- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.h"
-
-#include <string>
-#include <unordered_set>
-
-#include "base/memory/ptr_util.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/vr_shell/vr_shell_ui_message_handler.h"
-#include "chrome/common/url_constants.h"
-#include "content/public/browser/web_ui.h"
-
-#if !defined(ENABLE_VR_SHELL_UI_DEV)
-#include "chrome/browser/browser_process.h"
-#include "chrome/grit/browser_resources.h"
-#include "chrome/grit/generated_resources.h"
-#include "content/public/browser/web_ui_data_source.h"
-#else
-#include <map>
-#include "base/macros.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/string_util.h"
-#include "content/public/browser/url_data_source.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_request_context_getter.h"
-#endif
-
-namespace {
-
-#if defined(ENABLE_VR_SHELL_UI_DEV)
-std::string PathWithoutParams(const std::string& path) {
-  return GURL(std::string("chrome://vr-shell-ui/") + path).path().substr(1);
-}
-
-const char kRemoteBase[] = "http://localhost:8080/";
-const char kRemoteDefaultPath[] = "vr_shell_ui.html";
-const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n";
-
-// RemoteDataSource ---------------------------------------------------------
-
-std::string GetMimeTypeForPath(const std::string& path) {
-  std::string filename = PathWithoutParams(path);
-  if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) {
-    return "text/html";
-  } else if (base::EndsWith(filename, ".css",
-                            base::CompareCase::INSENSITIVE_ASCII)) {
-    return "text/css";
-  } else if (base::EndsWith(filename, ".js",
-                            base::CompareCase::INSENSITIVE_ASCII)) {
-    return "application/javascript";
-  } else if (base::EndsWith(filename, ".png",
-                            base::CompareCase::INSENSITIVE_ASCII)) {
-    return "image/png";
-  } else if (base::EndsWith(filename, ".gif",
-                            base::CompareCase::INSENSITIVE_ASCII)) {
-    return "image/gif";
-  } else if (base::EndsWith(filename, ".svg",
-                            base::CompareCase::INSENSITIVE_ASCII)) {
-    return "image/svg+xml";
-  } else if (base::EndsWith(filename, ".manifest",
-                            base::CompareCase::INSENSITIVE_ASCII)) {
-    return "text/cache-manifest";
-  }
-  return "text/html";
-}
-
-class RemoteDataSource : public content::URLDataSource,
-                         public net::URLFetcherDelegate {
- public:
-  using GotDataCallback = content::URLDataSource::GotDataCallback;
-
-  explicit RemoteDataSource(net::URLRequestContextGetter* request_context);
-
-  // content::URLDataSource implementation.
-  std::string GetSource() const override;
-  void StartDataRequest(
-      const std::string& path,
-      const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
-      const GotDataCallback& callback) override;
-
-  bool AllowCaching() const override { return false; }
-
- private:
-  // content::URLDataSource overrides.
-  std::string GetMimeType(const std::string& path) const override;
-  bool ShouldAddContentSecurityPolicy() const override;
-  bool ShouldDenyXFrameOptions() const override;
-  bool ShouldServeMimeTypeAsContentTypeHeader() const override;
-
-  // net::URLFetcherDelegate overrides.
-  void OnURLFetchComplete(const net::URLFetcher* source) override;
-
-  ~RemoteDataSource() override;
-
-  scoped_refptr<net::URLRequestContextGetter> request_context_;
-
-  using PendingRequestsMap = std::map<const net::URLFetcher*, GotDataCallback>;
-  PendingRequestsMap pending_;
-
-  DISALLOW_COPY_AND_ASSIGN(RemoteDataSource);
-};
-
-RemoteDataSource::RemoteDataSource(
-    net::URLRequestContextGetter* request_context)
-    : request_context_(request_context) {}
-
-RemoteDataSource::~RemoteDataSource() {
-  for (const auto& pair : pending_) {
-    delete pair.first;
-    pair.second.Run(
-        new base::RefCountedStaticMemory(kHttpNotFound, strlen(kHttpNotFound)));
-  }
-}
-
-std::string RemoteDataSource::GetSource() const {
-  return chrome::kChromeUIVrShellUIHost;
-}
-
-void RemoteDataSource::StartDataRequest(
-    const std::string& path,
-    const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
-    const content::URLDataSource::GotDataCallback& callback) {
-  GURL url = GURL(kRemoteBase +
-                  (path.empty() ? std::string(kRemoteDefaultPath) : path));
-  if (!url.is_valid()) {
-    callback.Run(
-        new base::RefCountedStaticMemory(kHttpNotFound, strlen(kHttpNotFound)));
-    return;
-  }
-  net::URLFetcher* fetcher =
-      net::URLFetcher::Create(url, net::URLFetcher::GET, this).release();
-
-  fetcher->AddExtraRequestHeader("Cache-Control: no-cache");
-
-  pending_[fetcher] = callback;
-  fetcher->SetRequestContext(request_context_.get());
-  fetcher->Start();
-}
-
-std::string RemoteDataSource::GetMimeType(const std::string& path) const {
-  return GetMimeTypeForPath(path);
-}
-
-bool RemoteDataSource::ShouldAddContentSecurityPolicy() const {
-  return false;
-}
-
-bool RemoteDataSource::ShouldDenyXFrameOptions() const {
-  return false;
-}
-
-bool RemoteDataSource::ShouldServeMimeTypeAsContentTypeHeader() const {
-  return true;
-}
-
-void RemoteDataSource::OnURLFetchComplete(const net::URLFetcher* source) {
-  DCHECK(source);
-  PendingRequestsMap::iterator it = pending_.find(source);
-  DCHECK(it != pending_.end());
-  std::string response;
-  source->GetResponseAsString(&response);
-  delete source;
-  it->second.Run(base::RefCountedString::TakeString(&response));
-  pending_.erase(it);
-}
-#else
-content::WebUIDataSource* CreateVrShellUIHTMLSource() {
-  content::WebUIDataSource* source =
-      content::WebUIDataSource::Create(chrome::kChromeUIVrShellUIHost);
-  source->UseGzip(std::unordered_set<std::string>() /* excluded_paths */);
-  source->AddResourcePath("vr_shell_ui.css", IDR_VR_SHELL_UI_CSS);
-  source->AddResourcePath("vr_shell_ui.js", IDR_VR_SHELL_UI_JS);
-  source->AddResourcePath("vr_shell_ui_api.js", IDR_VR_SHELL_UI_API_JS);
-  source->AddResourcePath("vr_shell_ui_scene.js", IDR_VR_SHELL_UI_SCENE_JS);
-  source->AddResourcePath("vk.css", IDR_VR_SHELL_UI_VK_CSS);
-  source->AddResourcePath("vk.js", IDR_VR_SHELL_UI_VK_JS);
-  source->SetDefaultResource(IDR_VR_SHELL_UI_HTML);
-  source->AddLocalizedString("insecureWebVrContentPermanent",
-                             IDS_PAGE_INFO_INSECURE_WEBVR_CONTENT_PERMANENT);
-  source->AddLocalizedString("insecureWebVrContentTransient",
-                             IDS_PAGE_INFO_INSECURE_WEBVR_CONTENT_TRANSIENT);
-  source->AddLocalizedString("back", IDS_VR_SHELL_UI_BACK_BUTTON);
-  source->AddLocalizedString("forward", IDS_VR_SHELL_UI_FORWARD_BUTTON);
-  source->AddLocalizedString("reload", IDS_VR_SHELL_UI_RELOAD_BUTTON);
-  source->AddLocalizedString("exitPresent",
-                             IDS_VR_SHELL_UI_EXIT_PRESENT_BUTTON);
-  source->AddLocalizedString("newTab", IDS_VR_SHELL_NEW_TAB_BUTTON);
-  source->AddLocalizedString("newIncognitoTab",
-                             IDS_VR_SHELL_NEW_INCOGNITO_TAB_BUTTON);
-
-  return source;
-}
-#endif
-
-}  // namespace
-
-VrShellUIUI::VrShellUIUI(content::WebUI* web_ui) : WebUIController(web_ui) {
-  Profile* profile = Profile::FromWebUI(web_ui);
-#if !defined(ENABLE_VR_SHELL_UI_DEV)
-  content::WebUIDataSource::Add(profile, CreateVrShellUIHTMLSource());
-#else
-  content::URLDataSource::Add(
-      profile, new RemoteDataSource(profile->GetRequestContext()));
-#endif
-  web_ui->AddMessageHandler(base::MakeUnique<VrShellUIMessageHandler>());
-}
-
-VrShellUIUI::~VrShellUIUI() {}
diff --git a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.h b/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.h
deleted file mode 100644
index a2ca1c7..0000000
--- a/chrome/browser/ui/webui/vr_shell/vr_shell_ui_ui.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_UI_H_
-#define CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_UI_H_
-
-#include "base/macros.h"
-#include "content/public/browser/web_ui_controller.h"
-
-// The implementation for the chrome://vr-shell-ui page.
-class VrShellUIUI : public content::WebUIController {
- public:
-  explicit VrShellUIUI(content::WebUI* web_ui);
-  ~VrShellUIUI() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(VrShellUIUI);
-};
-
-#endif  // CHROME_BROWSER_UI_WEBUI_VR_SHELL_VR_SHELL_UI_UI_H_
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index bbf02bf2..624c08c 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -206,7 +206,6 @@
     "//components/visitedlink/common",
     "//content/public/common",
     "//crypto",
-    "//device/vr:features",
     "//extensions/common:common_constants",
     "//extensions/features",
     "//google_apis",
diff --git a/chrome/common/extensions/api/enterprise_platform_keys.idl b/chrome/common/extensions/api/enterprise_platform_keys.idl
index bb5cfb1..ecaf839b 100644
--- a/chrome/common/extensions/api/enterprise_platform_keys.idl
+++ b/chrome/common/extensions/api/enterprise_platform_keys.idl
@@ -111,8 +111,16 @@
     // policy. The Enterprise Machine Key does not reside in the
     // <code>"system"</code> token and is not accessible by any other API.
     // |challenge|: A challenge as emitted by the Verified Access Web API.
+    // |registerKey|: If set, the current Enterprise Machine Key is registered
+    //                with the <code>"system"</code> token and relinquishes the
+    //                Enterprise Machine Key role. The key can then be
+    //                associated with a certificate and used like any other
+    //                signing key. This key is 2048-bit RSA. Subsequent calls
+    //                to this function will then generate a new Enterprise
+    //                Machine Key.
     // |callback|: Called back with the challenge response.
     static void challengeMachineKey(ArrayBuffer challenge,
+                                    optional boolean registerKey,
                                     ChallengeCallback callback);
 
     // Challenges a hardware-backed Enterprise User Key and emits the response
diff --git a/chrome/common/extensions/docs/templates/public/apps/networking_onc.html b/chrome/common/extensions/docs/templates/public/apps/networking_onc.html
new file mode 100644
index 0000000..cbb7d16
--- /dev/null
+++ b/chrome/common/extensions/docs/templates/public/apps/networking_onc.html
@@ -0,0 +1 @@
+{{+partials.standard_apps_api api:apis.apps.networking_onc/}}
diff --git a/chrome/common/features.gni b/chrome/common/features.gni
index d585b94..9364bd9 100644
--- a/chrome/common/features.gni
+++ b/chrome/common/features.gni
@@ -61,9 +61,6 @@
 
   enable_supervised_users = !is_chromecast
 
-  # Enables vr shell UI development on local or remote page.
-  enable_vr_shell_ui_dev = false
-
   # Indicates if Wayland display server support is enabled.
   enable_wayland_server = is_chromeos
 
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 12829d3..47a6e73b 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -296,10 +296,6 @@
 const char kChromeUIWebApksHost[] = "webapks";
 #endif
 
-#if BUILDFLAG(ENABLE_VR)
-const char kChromeUIVrShellUIHost[] = "vr-shell-ui";
-#endif
-
 #if defined(OS_CHROMEOS)
 const char kChromeUIActivationMessageHost[] = "activationmessage";
 const char kChromeUIAppLaunchHost[] = "app-launch";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 320a624f..97971dcc3 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -15,7 +15,6 @@
 #include "build/build_config.h"
 #include "chrome/common/features.h"
 #include "content/public/common/url_constants.h"
-#include "device/vr/features.h"
 #include "media/media_features.h"
 #include "ppapi/features/features.h"
 #include "printing/features/features.h"
@@ -277,10 +276,6 @@
 extern const char kChromeUIWebApksHost[];
 #endif
 
-#if BUILDFLAG(ENABLE_VR)
-extern const char kChromeUIVrShellUIHost[];
-#endif
-
 #if defined(OS_CHROMEOS)
 extern const char kChromeUIActivationMessageHost[];
 extern const char kChromeUIAppLaunchHost[];
diff --git a/chrome/test/data/payments/metrics.js b/chrome/test/data/payments/metrics.js
index f9d0db0..b280f15 100644
--- a/chrome/test/data/payments/metrics.js
+++ b/chrome/test/data/payments/metrics.js
@@ -82,6 +82,29 @@
 }
 
 /**
+ * Launches the PaymentRequest UI which accepts only Android Pay and does not
+ * require any other information.
+ */
+function androidPaySkipUiBuy() {  // eslint-disable-line no-unused-vars
+  try {
+    request = new PaymentRequest(
+        [{supportedMethods: ['https://android.com/pay']}], {
+          total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}},
+        });
+    request.show()
+        .then(function(resp) {
+          return resp.complete('success');
+        }).then(function() {
+          print(JSON.stringify(resp, undefined, 2));
+        }).catch(function(error) {
+          print(error);
+        });
+  } catch (error) {
+    print(error.message);
+  }
+}
+
+/**
  * Launches the PaymentRequest UI which accepts only an unsupported payment
  * method.
  */
diff --git a/chrome/test/data/payments/payment_request_metrics_test.html b/chrome/test/data/payments/payment_request_metrics_test.html
index d2eab70c..d567b4a 100644
--- a/chrome/test/data/payments/payment_request_metrics_test.html
+++ b/chrome/test/data/payments/payment_request_metrics_test.html
@@ -13,6 +13,7 @@
 <body>
 <button onclick="ccBuy()" id="ccBuy">CC Buy Test</button><br>
 <button onclick="androidPayBuy()" id="androidPayBuy">Android Pay Buy Test</button><br>
+<button onclick="androidPaySkipUiBuy()" id="androidPaySkipUiBuy">Android Pay Skip UI Buy Test</button><br>
 <button onclick="noSupported()" id="noSupported">No Supported Method Test</button><br>
 <button onclick="abort()" id="abort">Abort</button>
 <pre id="result"></pre>
diff --git a/chrome/test/data/webapks/bad-sig.apk b/chrome/test/data/webapks/bad-sig.apk
new file mode 100644
index 0000000..8d65a109
--- /dev/null
+++ b/chrome/test/data/webapks/bad-sig.apk
Binary files differ
diff --git a/chrome/test/data/webapks/bad-utf8-fname.apk b/chrome/test/data/webapks/bad-utf8-fname.apk
new file mode 100644
index 0000000..4d563ff
--- /dev/null
+++ b/chrome/test/data/webapks/bad-utf8-fname.apk
Binary files differ
diff --git a/chrome/test/data/webapks/empty.apk b/chrome/test/data/webapks/empty.apk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/test/data/webapks/empty.apk
diff --git a/chrome/test/data/webapks/example.apk b/chrome/test/data/webapks/example.apk
new file mode 100644
index 0000000..af6d81a1
--- /dev/null
+++ b/chrome/test/data/webapks/example.apk
Binary files differ
diff --git a/chrome/test/data/webapks/extra-len-too-large.apk b/chrome/test/data/webapks/extra-len-too-large.apk
new file mode 100644
index 0000000..920fae4
--- /dev/null
+++ b/chrome/test/data/webapks/extra-len-too-large.apk
Binary files differ
diff --git a/chrome/test/data/webapks/fcomment-too-large.apk b/chrome/test/data/webapks/fcomment-too-large.apk
new file mode 100644
index 0000000..327aca0
--- /dev/null
+++ b/chrome/test/data/webapks/fcomment-too-large.apk
Binary files differ
diff --git a/chrome/test/data/webapks/java-example.apk b/chrome/test/data/webapks/java-example.apk
new file mode 100644
index 0000000..ae6ec021
--- /dev/null
+++ b/chrome/test/data/webapks/java-example.apk
Binary files differ
diff --git a/chrome/test/data/webapks/no-cd.apk b/chrome/test/data/webapks/no-cd.apk
new file mode 100644
index 0000000..f4b4bec
--- /dev/null
+++ b/chrome/test/data/webapks/no-cd.apk
Binary files differ
diff --git a/chrome/test/data/webapks/no-comment.apk b/chrome/test/data/webapks/no-comment.apk
new file mode 100644
index 0000000..7e28604
--- /dev/null
+++ b/chrome/test/data/webapks/no-comment.apk
Binary files differ
diff --git a/chrome/test/data/webapks/no-eocd.apk b/chrome/test/data/webapks/no-eocd.apk
new file mode 100644
index 0000000..24b84ba
--- /dev/null
+++ b/chrome/test/data/webapks/no-eocd.apk
Binary files differ
diff --git a/chrome/test/data/webapks/no-lfh.apk b/chrome/test/data/webapks/no-lfh.apk
new file mode 100644
index 0000000..4e0e72a
--- /dev/null
+++ b/chrome/test/data/webapks/no-lfh.apk
Binary files differ
diff --git a/chrome/test/data/webapks/not-an.apk b/chrome/test/data/webapks/not-an.apk
new file mode 100644
index 0000000..2a54d36
--- /dev/null
+++ b/chrome/test/data/webapks/not-an.apk
@@ -0,0 +1 @@
+Not an APK
diff --git a/chrome/test/data/webapks/public.der b/chrome/test/data/webapks/public.der
new file mode 100644
index 0000000..8ee4259a
--- /dev/null
+++ b/chrome/test/data/webapks/public.der
Binary files differ
diff --git a/chrome/test/data/webapks/too-many-metainf.apk b/chrome/test/data/webapks/too-many-metainf.apk
new file mode 100644
index 0000000..18e6f131
--- /dev/null
+++ b/chrome/test/data/webapks/too-many-metainf.apk
Binary files differ
diff --git a/chrome/test/data/webapks/truncated.apk b/chrome/test/data/webapks/truncated.apk
new file mode 100644
index 0000000..7c77a57
--- /dev/null
+++ b/chrome/test/data/webapks/truncated.apk
@@ -0,0 +1 @@
+PK
\ No newline at end of file
diff --git a/chrome/test/data/webapks/zeros-at-end.apk b/chrome/test/data/webapks/zeros-at-end.apk
new file mode 100644
index 0000000..7ff1191
--- /dev/null
+++ b/chrome/test/data/webapks/zeros-at-end.apk
Binary files differ
diff --git a/chrome/test/data/webapks/zeros.apk b/chrome/test/data/webapks/zeros.apk
new file mode 100644
index 0000000..d8141761
--- /dev/null
+++ b/chrome/test/data/webapks/zeros.apk
Binary files differ
diff --git a/chrome/test/data/webui/cr_elements/cr_dialog_test.js b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
index c61de46..41987dd 100644
--- a/chrome/test/data/webui/cr_elements/cr_dialog_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
@@ -145,6 +145,29 @@
     expectEquals(button, document.activeElement);
   });
 
+  // Ensuring that intersectionObserver does not fire any callbacks before the
+  // dialog has been opened.
+  test('body scrollable border not added before modal shown', function(done) {
+    document.body.innerHTML = `
+      <dialog is="cr-dialog" show-scroll-borders>
+        <div class="title">title</div>
+        <div class="body">body</div>
+      </dialog>`;
+
+    var dialog = document.body.querySelector('dialog');
+    assertFalse(dialog.open);
+    var bodyContainer = dialog.$$('.body-container');
+    assertTrue(!!bodyContainer);
+
+    // Waiting for 1ms because IntersectionObserver fires one message loop after
+    // dialog.attached.
+    setTimeout(function() {
+      assertFalse(bodyContainer.classList.contains('top-scrollable'));
+      assertFalse(bodyContainer.classList.contains('bottom-scrollable'));
+      done();
+    }, 1);
+  });
+
   test('dialog body scrollable border when appropriate', function(done) {
     document.body.innerHTML = `
       <dialog is="cr-dialog" show-scroll-borders>
diff --git a/chrome/test/data/webui/settings/settings_animated_pages_test.js b/chrome/test/data/webui/settings/settings_animated_pages_test.js
index fd47f641..1b2052e 100644
--- a/chrome/test/data/webui/settings/settings_animated_pages_test.js
+++ b/chrome/test/data/webui/settings/settings_animated_pages_test.js
@@ -5,7 +5,8 @@
 suite('settings-animated-pages', function() {
   test('focuses subpage trigger when exiting subpage', function(done) {
     document.body.innerHTML = `
-      <settings-animated-pages section="test-section">
+      <settings-animated-pages
+          section="${settings.Route.SEARCH_ENGINES.section}">
         <neon-animatable route-path="default">
           <button id="subpage-trigger"></button>
         </neon-animatable>
@@ -19,14 +20,13 @@
     animatedPages.focusConfig.set(
         settings.Route.SEARCH_ENGINES.path, '#subpage-trigger');
 
-    animatedPages.$.animatedPages.selected = settings.Route.SEARCH_ENGINES.path;
-
     var trigger = document.body.querySelector('#subpage-trigger');
     assertTrue(!!trigger);
     trigger.addEventListener('focus', function() { done(); });
 
-    // Trigger subpage exit.
-    animatedPages.currentRouteChanged(
-        settings.Route.BASIC, settings.Route.SEARCH_ENGINES);
+    // Trigger subpage exit navigation.
+    settings.navigateTo(settings.Route.BASIC);
+    settings.navigateTo(settings.Route.SEARCH_ENGINES);
+    settings.navigateToPreviousRoute();
   });
 });
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
index 69caebf..5d57cd6 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -56,6 +56,7 @@
     private WindowAndroid mWindow;
     private ContentViewCore mContentViewCore;
     private ContentView mContentView;
+    private boolean mReceivedUserLeave = false;
 
     private static final int TEARDOWN_GRACE_PERIOD_TIMEOUT_MILLIS = 300;
     public static final String ACTION_DATA_SCHEME = "cast";
@@ -72,6 +73,17 @@
     public static final String ACTION_ACTIVITY_STOPPED =
             "com.google.android.apps.castshell.intent.action.ACTIVITY_STOPPED";
 
+    /*
+     * Intended to be called from "onStop" to determine if this is a "legitimate" stop or not.
+     * When starting CastShellActivity from the TV in sleep mode, an extra onPause/onStop will be
+     * fired.
+     * Details: http://stackoverflow.com/questions/25369909/
+     * We use onUserLeaveHint to determine if the onPause/onStop called because of user intent.
+     */
+    private boolean isStopping() {
+        return mReceivedUserLeave;
+    }
+
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
         if (DEBUG) Log.d(TAG, "onCreate");
@@ -191,9 +203,10 @@
     @Override
     protected void onStop() {
         if (DEBUG) Log.d(TAG, "onStop");
-
-        detachWebContentsIfAny();
-        releaseStreamMuteIfNecessary();
+        if (isStopping()) {
+            detachWebContentsIfAny();
+            releaseStreamMuteIfNecessary();
+        }
         super.onStop();
     }
 
@@ -221,6 +234,12 @@
     }
 
     @Override
+    protected void onUserLeaveHint() {
+        if (DEBUG) Log.d(TAG, "onUserLeaveHint");
+        mReceivedUserLeave = true;
+    }
+
+    @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (DEBUG) Log.d(TAG, "dispatchKeyEvent");
         int keyCode = event.getKeyCode();
@@ -249,6 +268,7 @@
         }
 
         if (keyCode == KeyEvent.KEYCODE_BACK) {
+            mReceivedUserLeave = true;
             return super.dispatchKeyEvent(event);
         }
         return false;
diff --git a/chromecast/media/cma/backend/media_sink_default.cc b/chromecast/media/cma/backend/media_sink_default.cc
index 61d58c6..1ab07d72 100644
--- a/chromecast/media/cma/backend/media_sink_default.cc
+++ b/chromecast/media/cma/backend/media_sink_default.cc
@@ -64,8 +64,11 @@
   //    Those tests are wrong should be fixed.
   // TODO(alokp): Fix these issues when the next version of CMA backend is
   // scheduled to roll out. crbug.com/678394
-  last_frame_pts_ = base::TimeDelta::FromMicroseconds(buffer->timestamp());
-  time_interpolator_.SetUpperBound(last_frame_pts_);
+  auto timestamp = base::TimeDelta::FromMicroseconds(buffer->timestamp());
+  if (timestamp != ::media::kNoTimestamp) {
+    last_frame_pts_ = timestamp;
+    time_interpolator_.SetUpperBound(last_frame_pts_);
+  }
   return MediaPipelineBackend::kBufferSuccess;
 }
 
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 5293b93c..87a22f6e 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -183,6 +183,12 @@
     ]
   }
 
+  if (!is_android) {
+    sources += [
+      "ui/save_card_bubble_controller.h",
+    ]
+  }
+
   configs += [ "//build/config:precompiled_headers" ]
 
   public_deps = [
@@ -252,6 +258,13 @@
     "test_personal_data_manager.h",
   ]
 
+  if (!is_android) {
+    sources += [
+      "ui/mock_save_card_bubble_controller.cc",
+      "ui/mock_save_card_bubble_controller.h",
+    ]
+  }
+
   public_deps = [
     ":browser",
   ]
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h
index 1533f15..f6ff075 100644
--- a/components/autofill/core/browser/autofill_client.h
+++ b/components/autofill/core/browser/autofill_client.h
@@ -49,6 +49,7 @@
 class CreditCard;
 class FormStructure;
 class PersonalDataManager;
+class SaveCardBubbleController;
 struct Suggestion;
 
 // A client interface that needs to be supplied to the Autofill component by the
@@ -110,9 +111,13 @@
   // Gets the RapporServiceImpl associated with the client (for metrics).
   virtual rappor::RapporServiceImpl* GetRapporServiceImpl() = 0;
 
-  // Gets the UKM service assiciated with this client (for metrics).
+  // Gets the UKM service associated with this client (for metrics).
   virtual ukm::UkmService* GetUkmService() = 0;
 
+  // Gets the SaveCardBubbleController instance associated with the client.
+  // May return nullptr if the save card bubble has not been shown yet.
+  virtual SaveCardBubbleController* GetSaveCardBubbleController() = 0;
+
   // Causes the Autofill settings UI to be shown.
   virtual void ShowAutofillSettings() = 0;
 
@@ -129,10 +134,12 @@
                                             const base::Closure& callback) = 0;
 
   // Runs |callback| if the |card| should be uploaded to Payments. Displays the
-  // contents of |legal_message| to the user.
+  // contents of |legal_message| to the user. Display a CVC field in the bubble
+  // if |should_cvc_be_requested| is true.
   virtual void ConfirmSaveCreditCardToCloud(
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
+      bool should_cvc_be_requested,
       const base::Closure& callback) = 0;
 
   // Will show an infobar to get user consent for Credit Card assistive filling.
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc
index 8d5704d..ef37213e 100644
--- a/components/autofill/core/browser/autofill_experiments.cc
+++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -34,6 +34,8 @@
     "AutofillCreditCardLastUsedDateDisplay", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kAutofillUkmLogging{"AutofillUkmLogging",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kAutofillUpstreamRequestCvcIfMissing{
+    "AutofillUpstreamRequestCvcIfMissing", base::FEATURE_DISABLED_BY_DEFAULT};
 const char kCreditCardSigninPromoImpressionLimitParamKey[] = "impression_limit";
 const char kAutofillCreditCardPopupBackgroundColorKey[] = "background_color";
 const char kAutofillCreditCardPopupDividerColorKey[] = "dropdown_divider_color";
@@ -229,4 +231,12 @@
   return base::FeatureList::IsEnabled(kAutofillUkmLogging);
 }
 
+bool IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled() {
+#if defined(OS_ANDROID)
+  return false;
+#else
+  return base::FeatureList::IsEnabled(kAutofillUpstreamRequestCvcIfMissing);
+#endif
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h
index 70c3f41..ba03ac2 100644
--- a/components/autofill/core/browser/autofill_experiments.h
+++ b/components/autofill/core/browser/autofill_experiments.h
@@ -29,6 +29,7 @@
 extern const base::Feature kAutofillCreditCardPopupLayout;
 extern const base::Feature kAutofillCreditCardLastUsedDateDisplay;
 extern const base::Feature kAutofillUkmLogging;
+extern const base::Feature kAutofillUpstreamRequestCvcIfMissing;
 extern const char kCreditCardSigninPromoImpressionLimitParamKey[];
 extern const char kAutofillCreditCardPopupSettingsSuggestionValueKey[];
 extern const char kAutofillCreditCardLastUsedDateShowExpirationDateKey[];
@@ -104,6 +105,10 @@
 // Returns whether the feature to log UKMs is enabled.
 bool IsUkmLoggingEnabled();
 
+// Returns whether the experiment is enabled where Chrome Upstream requests CVC
+// in the offer to save bubble if it was not detected during the checkout flow.
+bool IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled();
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index a137044..933b7c5 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -51,6 +51,7 @@
 #include "components/autofill/core/browser/phone_number.h"
 #include "components/autofill/core/browser/phone_number_i18n.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
 #include "components/autofill/core/browser/validation.h"
 #include "components/autofill/core/common/autofill_clock.h"
 #include "components/autofill/core/common/autofill_constants.h"
@@ -217,16 +218,24 @@
     AutofillDownloadManagerState enable_download_manager)
     : driver_(driver),
       client_(client),
-      payments_client_(
-          new payments::PaymentsClient(driver->GetURLRequestContext(), this)),
+      payments_client_(base::MakeUnique<payments::PaymentsClient>(
+          driver->GetURLRequestContext(),
+          this)),
       app_locale_(app_locale),
       personal_data_(client->GetPersonalDataManager()),
       autocomplete_history_manager_(
-          new AutocompleteHistoryManager(driver, client)),
+          base::MakeUnique<AutocompleteHistoryManager>(driver, client)),
+      form_interactions_ukm_logger_(
+          base::MakeUnique<AutofillMetrics::FormInteractionsUkmLogger>(
+              client->GetUkmService())),
       address_form_event_logger_(
-          new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)),
+          base::MakeUnique<AutofillMetrics::FormEventLogger>(
+              false /* is_for_credit_card */,
+              form_interactions_ukm_logger_.get())),
       credit_card_form_event_logger_(
-          new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)),
+          base::MakeUnique<AutofillMetrics::FormEventLogger>(
+              true /* is_for_credit_card */,
+              form_interactions_ukm_logger_.get())),
       has_logged_autofill_enabled_(false),
       has_logged_address_suggestions_count_(false),
       did_show_suggestions_(false),
@@ -234,6 +243,7 @@
       user_did_autofill_(false),
       user_did_edit_autofilled_field_(false),
       user_did_accept_upload_prompt_(false),
+      should_cvc_be_requested_(false),
       external_delegate_(NULL),
       test_delegate_(NULL),
 #if defined(OS_ANDROID) || defined(OS_IOS)
@@ -493,7 +503,7 @@
   if (!upload_form)
     return;
 
-  StartUploadProcess(std::move(upload_form), base::TimeTicks::Now(), false);
+  StartUploadProcess(std::move(upload_form), TimeTicks::Now(), false);
 }
 
 void AutofillManager::OnTextFieldDidChange(const FormData& form,
@@ -512,6 +522,9 @@
 
   UpdatePendingForm(form);
 
+  if (!user_did_type_ || autofill_field->is_autofilled)
+    form_interactions_ukm_logger_->LogTextFieldDidChange(*autofill_field);
+
   if (!user_did_type_) {
     user_did_type_ = true;
     AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE);
@@ -1033,13 +1046,16 @@
     user_did_accept_upload_prompt_ = false;
     client_->ConfirmSaveCreditCardToCloud(
         upload_request_.card, std::move(legal_message),
+        should_cvc_be_requested_,
         base::Bind(&AutofillManager::OnUserDidAcceptUpload,
                    weak_ptr_factory_.GetWeakPtr()));
     client_->LoadRiskData(base::Bind(&AutofillManager::OnDidGetUploadRiskData,
                                      weak_ptr_factory_.GetWeakPtr()));
-    AutofillMetrics::LogCardUploadDecisionMetric(
-        AutofillMetrics::UPLOAD_OFFERED);
-    LogCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED);
+    AutofillMetrics::CardUploadDecisionMetric card_upload_decision_metric =
+        should_cvc_be_requested_ ? AutofillMetrics::UPLOAD_OFFERED_NO_CVC
+                                 : AutofillMetrics::UPLOAD_OFFERED;
+    AutofillMetrics::LogCardUploadDecisionMetric(card_upload_decision_metric);
+    LogCardUploadDecisionUkm(card_upload_decision_metric);
   } else {
     // If the upload details request failed, fall back to a local save. The
     // reasoning here is as follows:
@@ -1099,6 +1115,13 @@
   user_did_accept_upload_prompt_ = true;
   if (!upload_request_.risk_data.empty()) {
     upload_request_.app_locale = app_locale_;
+    // If the upload request does not have card CVC, populate it with the
+    // value provided by the user:
+    if (upload_request_.cvc.empty()) {
+      DCHECK(client_->GetSaveCardBubbleController());
+      upload_request_.cvc =
+          client_->GetSaveCardBubbleController()->GetCvcEnteredByUser();
+    }
     payments_client_->UploadCard(upload_request_);
   }
 }
@@ -1107,6 +1130,13 @@
   upload_request_.risk_data = risk_data;
   if (user_did_accept_upload_prompt_) {
     upload_request_.app_locale = app_locale_;
+    // If the upload request does not have card CVC, populate it with the
+    // value provided by the user:
+    if (upload_request_.cvc.empty()) {
+      DCHECK(client_->GetSaveCardBubbleController());
+      upload_request_.cvc =
+          client_->GetSaveCardBubbleController()->GetCvcEnteredByUser();
+    }
     payments_client_->UploadCard(upload_request_);
   }
 }
@@ -1199,9 +1229,11 @@
     // because if only one of the two is missing, it may be fixable.
 
     // Check for a CVC to determine whether we can prompt the user to upload
-    // their card. If no CVC is present, do nothing. We could fall back to a
-    // local save but we believe that sometimes offering upload and sometimes
-    // offering local save is a confusing user experience.
+    // their card. If no CVC is present and the experiment is off, do nothing.
+    // We could fall back to a local save but we believe that sometimes offering
+    // upload and sometimes offering local save is a confusing user experience.
+    // If no CVC and the experiment is on, request CVC from the user in the
+    // bubble and save using the provided value.
     for (const auto& field : submitted_form) {
       if (field->Type().GetStorableType() == CREDIT_CARD_VERIFICATION_CODE &&
           IsValidCreditCardSecurityCode(field->value,
@@ -1226,14 +1258,19 @@
 
     // Both the CVC and address checks are done.  Conform to the legacy order of
     // reporting on CVC then address.
+    should_cvc_be_requested_ = false;
     if (upload_request_.cvc.empty()) {
-      AutofillMetrics::LogCardUploadDecisionMetric(
-          AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
-      LogCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
-      pending_upload_request_url_ = GURL();
-      CollectRapportSample(submitted_form.source_url(),
-                           "Autofill.CardUploadNotOfferedNoCvc");
-      return;
+      if (IsAutofillUpstreamRequestCvcIfMissingExperimentEnabled()) {
+        should_cvc_be_requested_ = true;
+      } else {
+        AutofillMetrics::LogCardUploadDecisionMetric(
+            AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+        LogCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+        pending_upload_request_url_ = GURL();
+        CollectRapportSample(submitted_form.source_url(),
+                             "Autofill.CardUploadNotOfferedNoCvc");
+        return;
+      }
     }
     if (!get_profiles_succeeded) {
       DCHECK(get_profiles_decision_metric != AutofillMetrics::UPLOAD_OFFERED);
@@ -1378,11 +1415,10 @@
     const TimeTicks& interaction_time,
     const TimeTicks& submission_time,
     bool observed_submission) {
-  submitted_form->LogQualityMetrics(load_time, interaction_time,
-                                    submission_time,
-                                    client_->GetRapporServiceImpl(),
-                                    did_show_suggestions_, observed_submission);
-
+  submitted_form->LogQualityMetrics(
+      load_time, interaction_time, submission_time,
+      client_->GetRapporServiceImpl(), form_interactions_ukm_logger_.get(),
+      did_show_suggestions_, observed_submission);
   if (submitted_form->ShouldBeCrowdsourced())
     UploadFormData(*submitted_form, observed_submission);
 }
@@ -1416,10 +1452,12 @@
   ProcessPendingFormForUpload();
   DCHECK(!pending_form_data_);
   form_structures_.clear();
-  address_form_event_logger_.reset(
-      new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */));
-  credit_card_form_event_logger_.reset(
-      new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */));
+  form_interactions_ukm_logger_.reset(
+      new AutofillMetrics::FormInteractionsUkmLogger(client_->GetUkmService()));
+  address_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
+      false /* is_for_credit_card */, form_interactions_ukm_logger_.get()));
+  credit_card_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
+      true /* is_for_credit_card */, form_interactions_ukm_logger_.get()));
 #if defined(OS_ANDROID) || defined(OS_IOS)
   autofill_assistant_.Reset();
 #endif
@@ -1443,16 +1481,24 @@
                                  PersonalDataManager* personal_data)
     : driver_(driver),
       client_(client),
-      payments_client_(
-          new payments::PaymentsClient(driver->GetURLRequestContext(), this)),
+      payments_client_(base::MakeUnique<payments::PaymentsClient>(
+          driver->GetURLRequestContext(),
+          this)),
       app_locale_("en-US"),
       personal_data_(personal_data),
       autocomplete_history_manager_(
-          new AutocompleteHistoryManager(driver, client)),
+          base::MakeUnique<AutocompleteHistoryManager>(driver, client)),
+      form_interactions_ukm_logger_(
+          base::MakeUnique<AutofillMetrics::FormInteractionsUkmLogger>(
+              client->GetUkmService())),
       address_form_event_logger_(
-          new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)),
+          base::MakeUnique<AutofillMetrics::FormEventLogger>(
+              false /* is_for_credit_card */,
+              form_interactions_ukm_logger_.get())),
       credit_card_form_event_logger_(
-          new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)),
+          base::MakeUnique<AutofillMetrics::FormEventLogger>(
+              true /* is_for_credit_card */,
+              form_interactions_ukm_logger_.get())),
       has_logged_autofill_enabled_(false),
       has_logged_address_suggestions_count_(false),
       did_show_suggestions_(false),
@@ -1483,34 +1529,34 @@
 
   // Updating the FormEventLoggers for addresses and credit cards.
   {
-    bool is_server_data_available = false;
-    bool is_local_data_available = false;
+    size_t server_record_type_count = 0;
+    size_t local_record_type_count = 0;
     for (CreditCard* credit_card : credit_cards) {
       if (credit_card->record_type() == CreditCard::LOCAL_CARD)
-        is_local_data_available = true;
+        local_record_type_count++;
       else
-        is_server_data_available = true;
+        server_record_type_count++;
     }
-    credit_card_form_event_logger_->set_is_server_data_available(
-        is_server_data_available);
-    credit_card_form_event_logger_->set_is_local_data_available(
-        is_local_data_available);
+    credit_card_form_event_logger_->set_server_record_type_count(
+        server_record_type_count);
+    credit_card_form_event_logger_->set_local_record_type_count(
+        local_record_type_count);
     credit_card_form_event_logger_->set_is_context_secure(
         client_->IsContextSecure());
   }
   {
-    bool is_server_data_available = false;
-    bool is_local_data_available = false;
+    size_t server_record_type_count = 0;
+    size_t local_record_type_count = 0;
     for (AutofillProfile* profile : profiles) {
       if (profile->record_type() == AutofillProfile::LOCAL_PROFILE)
-        is_local_data_available = true;
+        local_record_type_count++;
       else if (profile->record_type() == AutofillProfile::SERVER_PROFILE)
-        is_server_data_available = true;
+        server_record_type_count++;
     }
-    address_form_event_logger_->set_is_server_data_available(
-        is_server_data_available);
-    address_form_event_logger_->set_is_local_data_available(
-        is_local_data_available);
+    address_form_event_logger_->set_server_record_type_count(
+        server_record_type_count);
+    address_form_event_logger_->set_local_record_type_count(
+        local_record_type_count);
   }
 
   if (profiles.empty() && credit_cards.empty())
@@ -1679,7 +1725,8 @@
 
 std::unique_ptr<FormStructure> AutofillManager::ValidateSubmittedForm(
     const FormData& form) {
-  std::unique_ptr<FormStructure> submitted_form(new FormStructure(form));
+  std::unique_ptr<FormStructure> submitted_form(
+      base::MakeUnique<FormStructure>(form));
   if (!ShouldUploadForm(*submitted_form))
     return std::unique_ptr<FormStructure>();
 
@@ -1855,7 +1902,7 @@
   std::vector<FormStructure*> non_queryable_forms;
   std::vector<FormStructure*> queryable_forms;
   for (const FormData& form : forms) {
-    const auto parse_form_start_time = base::TimeTicks::Now();
+    const auto parse_form_start_time = TimeTicks::Now();
 
     FormStructure* form_structure = nullptr;
     if (!ParseForm(form, &form_structure))
@@ -1869,7 +1916,7 @@
     else
       non_queryable_forms.push_back(form_structure);
 
-    AutofillMetrics::LogParseFormTiming(base::TimeTicks::Now() -
+    AutofillMetrics::LogParseFormTiming(TimeTicks::Now() -
                                         parse_form_start_time);
   }
 
@@ -1880,6 +1927,9 @@
 
   if (!queryable_forms.empty() || !non_queryable_forms.empty()) {
     AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED);
+    // Setup the url for metrics that we will collect for this form.
+    form_interactions_ukm_logger_->OnFormsLoaded(forms[0].origin);
+
 #if defined(OS_IOS)
     // Log this from same location as AutofillMetrics::FORMS_LOADED to ensure
     // that KeyboardAccessoryButtonsIOS and UserHappiness UMA metrics will be
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 90e7ecd..c8597275 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -43,8 +43,6 @@
 #define ENABLE_FORM_DEBUG_DUMP
 #endif
 
-class GURL;
-
 namespace gfx {
 class RectF;
 }
@@ -270,6 +268,10 @@
     return &form_structures_;
   }
 
+  AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger() {
+    return form_interactions_ukm_logger_.get();
+  }
+
   // Exposed for testing.
   AutofillExternalDelegate* external_delegate() {
     return external_delegate_;
@@ -510,6 +512,10 @@
   // Handles single-field autocomplete form data.
   std::unique_ptr<AutocompleteHistoryManager> autocomplete_history_manager_;
 
+  // Utility for logging URL keyed metrics.
+  std::unique_ptr<AutofillMetrics::FormInteractionsUkmLogger>
+      form_interactions_ukm_logger_;
+
   // Utilities for logging form events.
   std::unique_ptr<AutofillMetrics::FormEventLogger> address_form_event_logger_;
   std::unique_ptr<AutofillMetrics::FormEventLogger>
@@ -555,6 +561,7 @@
   payments::PaymentsClient::UploadRequestDetails upload_request_;
   bool user_did_accept_upload_prompt_;
   GURL pending_upload_request_url_;
+  bool should_cvc_be_requested_;
 
 #ifdef ENABLE_FORM_DEBUG_DUMP
   // The last few autofilled forms (key/value pairs) submitted, for debugging.
@@ -595,6 +602,7 @@
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressSubmittedFormEvents);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressWillSubmitFormEvents);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressSuggestionsCount);
+  FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutofillFormSubmittedState);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutofillIsEnabledAtPageLoad);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardSelectedFormEvents);
   FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardFilledFormEvents);
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 34bdd02..e9d94a4 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -1032,6 +1032,11 @@
     scoped_feature_list_.InitAndEnableFeature(kAutofillUkmLogging);
   }
 
+  void EnableAutofillUpstreamRequestCvcIfMissingExperimentAndUkmLogging() {
+    scoped_feature_list_.InitWithFeatures(
+        {kAutofillUpstreamRequestCvcIfMissing, kAutofillUkmLogging}, {});
+  }
+
   void ExpectUniqueFillableFormParsedUkm() {
     ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
 
@@ -4842,6 +4847,145 @@
 
 // TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
 #if defined(OS_ANDROID)
+#define MAYBE_UploadCreditCard_NoCvcFieldOnForm \
+  DISABLED_UploadCreditCard_NoCvcFieldOnForm
+#else
+#define MAYBE_UploadCreditCard_NoCvcFieldOnForm \
+  UploadCreditCard_NoCvcFieldOnForm
+#endif
+TEST_F(AutofillManagerTest, MAYBE_UploadCreditCard_NoCvcFieldOnForm) {
+  EnableAutofillUpstreamRequestCvcIfMissingExperimentAndUkmLogging();
+  autofill_manager_->set_credit_card_upload_enabled(true);
+
+  // Remove the profiles that were created in the TestPersonalDataManager
+  // constructor because they would result in conflicting names that would
+  // prevent the upload.
+  personal_data_.ClearAutofillProfiles();
+
+  // Create, fill and submit an address form in order to establish a recent
+  // profile which can be selected for the upload request.
+  FormData address_form;
+  test::CreateTestAddressFormData(&address_form);
+  FormsSeen(std::vector<FormData>(1, address_form));
+  ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+  FormSubmitted(address_form);
+
+  // Set up our credit card form data.  Note that CVC field is missing.
+  FormData credit_card_form;
+  credit_card_form.name = ASCIIToUTF16("MyForm");
+  credit_card_form.origin = GURL("https://myform.com/form.html");
+  credit_card_form.action = GURL("https://myform.com/submit.html");
+
+  FormFieldData field;
+  test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+
+  FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+  // Edit the data, and submit.
+  credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16("11");
+  credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+
+  base::HistogramTester histogram_tester;
+
+  // Upload should still happen as long as the user provides CVC in the bubble.
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+  FormSubmitted(credit_card_form);
+  EXPECT_TRUE(autofill_manager_->credit_card_was_uploaded());
+
+  // Verify that the correct histogram entry (and only that) was logged.
+  histogram_tester.ExpectUniqueSample("Autofill.CardUploadDecisionExpanded",
+                                      AutofillMetrics::UPLOAD_OFFERED_NO_CVC,
+                                      1);
+  // Verify that the correct UKM was logged.
+  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_OFFERED_NO_CVC);
+}
+
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
+#if defined(OS_ANDROID)
+#define MAYBE_UploadCreditCard_NoCvcFieldOnFormExperimentOff \
+  DISABLED_UploadCreditCard_NoCvcFieldOnFormExperimentOff
+#else
+#define MAYBE_UploadCreditCard_NoCvcFieldOnFormExperimentOff \
+  UploadCreditCard_NoCvcFieldOnFormExperimentOff
+#endif
+TEST_F(AutofillManagerTest,
+       MAYBE_UploadCreditCard_NoCvcFieldOnFormExperimentOff) {
+  EnableUkmLogging();
+  autofill_manager_->set_credit_card_upload_enabled(true);
+
+  // Remove the profiles that were created in the TestPersonalDataManager
+  // constructor because they would result in conflicting names that would
+  // prevent the upload.
+  personal_data_.ClearAutofillProfiles();
+
+  // Create, fill and submit an address form in order to establish a recent
+  // profile which can be selected for the upload request.
+  FormData address_form;
+  test::CreateTestAddressFormData(&address_form);
+  FormsSeen(std::vector<FormData>(1, address_form));
+  ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+  FormSubmitted(address_form);
+
+  // Set up our credit card form data.  Note that CVC field is missing.
+  FormData credit_card_form;
+  credit_card_form.name = ASCIIToUTF16("MyForm");
+  credit_card_form.origin = GURL("https://myform.com/form.html");
+  credit_card_form.action = GURL("https://myform.com/submit.html");
+
+  FormFieldData field;
+  test::CreateTestFormField("Card Name", "cardname", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Expiration Month", "ccmonth", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+  test::CreateTestFormField("Expiration Year", "ccyear", "", "text", &field);
+  credit_card_form.fields.push_back(field);
+
+  FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+  // Edit the data, and submit.
+  credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+  credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+  credit_card_form.fields[2].value = ASCIIToUTF16("11");
+  credit_card_form.fields[3].value = ASCIIToUTF16("2017");
+
+  base::HistogramTester histogram_tester;
+
+  // Neither a local save nor an upload should happen in this case.
+  EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
+  FormSubmitted(credit_card_form);
+  EXPECT_FALSE(autofill_manager_->credit_card_was_uploaded());
+
+  // Verify that the correct histogram entry (and only that) was logged.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.CardUploadDecisionExpanded",
+      AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC, 1);
+  // Verify that the correct UKM was logged.
+  ExpectCardUploadDecisionUkm(AutofillMetrics::UPLOAD_NOT_OFFERED_NO_CVC);
+
+  rappor::TestRapporServiceImpl* rappor_service =
+      autofill_client_.test_rappor_service();
+  EXPECT_EQ(1, rappor_service->GetReportsCount());
+  std::string sample;
+  rappor::RapporType type;
+  EXPECT_TRUE(rappor_service->GetRecordedSampleForMetric(
+      "Autofill.CardUploadNotOfferedNoCvc", &sample, &type));
+  EXPECT_EQ("myform.com", sample);
+  EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type);
+}
+
+// TODO(crbug.com/666704): Flaky on android_n5x_swarming_rel bot.
+#if defined(OS_ANDROID)
 #define MAYBE_UploadCreditCard_NoProfileAvailable DISABLED_UploadCreditCard_NoProfileAvailable
 #else
 #define MAYBE_UploadCreditCard_NoProfileAvailable UploadCreditCard_NoProfileAvailable
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc
index e813b183..7744239 100644
--- a/components/autofill/core/browser/autofill_metrics.cc
+++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -5,6 +5,8 @@
 #include "components/autofill/core/browser/autofill_metrics.h"
 
 #include <algorithm>
+#include <utility>
+#include <vector>
 
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
@@ -12,6 +14,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_experiments.h"
+#include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/common/form_data.h"
@@ -22,6 +25,28 @@
 const char kUKMCardUploadDecisionMetricName[] = "UploadDecision";
 const char kUKMDeveloperEngagementEntryName[] = "Autofill.DeveloperEngagement";
 const char kUKMDeveloperEngagementMetricName[] = "DeveloperEngagement";
+const char kUKMMillisecondsSinceFormLoadedMetricName[] =
+    "MillisecondsSinceFormLoaded";
+const char kUKMInteractedWithFormEntryName[] = "Autofill.InteractedWithForm";
+const char kUKMIsForCreditCardMetricName[] = "IsForCreditCard";
+const char kUKMLocalRecordTypeCountMetricName[] = "LocalRecordTypeCount";
+const char kUKMServerRecordTypeCountMetricName[] = "ServerRecordTypeCount";
+const char kUKMSuggestionsShownEntryName[] = "Autofill.SuggestionsShown";
+const char kUKMSelectedMaskedServerCardEntryName[] =
+    "Autofill.SelectedMaskedServerCard";
+const char kUKMSuggestionFilledEntryName[] = "Autofill.SuggestionFilled";
+const char kUKMRecordTypeMetricName[] = "RecordType";
+const char kUKMTextFieldDidChangeEntryName[] = "Autofill.TextFieldDidChange";
+const char kUKMFieldTypeGroupMetricName[] = "FieldTypeGroup";
+const char kUKMHeuristicTypeMetricName[] = "HeuristicType";
+const char kUKMServerTypeMetricName[] = "ServerType";
+const char kUKMHtmlFieldTypeMetricName[] = "HtmlFieldType";
+const char kUKMHtmlFieldModeMetricName[] = "HtmlFieldMode";
+const char kUKMIsAutofilledMetricName[] = "IsAutofilled";
+const char kUKMIsEmptyMetricName[] = "IsEmpty";
+const char kUKMFormSubmittedEntryName[] = "Autofill.AutofillFormSubmitted";
+const char kUKMAutofillFormSubmittedStateMetricName[] =
+    "AutofillFormSubmittedState";
 }  // namespace internal
 
 namespace autofill {
@@ -616,7 +641,8 @@
 
 // static
 void AutofillMetrics::LogAutofillFormSubmittedState(
-    AutofillFormSubmittedState state) {
+    AutofillFormSubmittedState state,
+    AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) {
   UMA_HISTOGRAM_ENUMERATION("Autofill.FormSubmittedState", state,
                             AUTOFILL_FORM_SUBMITTED_STATE_ENUM_SIZE);
 
@@ -650,6 +676,7 @@
       NOTREACHED();
       break;
   }
+  form_interactions_ukm_logger->LogFormSubmitted(state);
 }
 
 // static
@@ -706,7 +733,7 @@
   if (upload_decision >= AutofillMetrics::NUM_CARD_UPLOAD_DECISION_METRICS)
     return;
 
-  const std::map<std::string, int> metrics = {
+  const std::vector<std::pair<const char*, int>> metrics = {
       {internal::kUKMCardUploadDecisionMetricName,
        static_cast<int>(upload_decision)}};
   LogUkm(ukm_service, url, internal::kUKMCardUploadDecisionEntryName, metrics);
@@ -716,18 +743,22 @@
 void AutofillMetrics::LogDeveloperEngagementUkm(
     ukm::UkmService* ukm_service,
     const GURL& url,
-    AutofillMetrics::DeveloperEngagementMetric metric) {
-  const std::map<std::string, int> form_structure_metrics = {
-      {internal::kUKMDeveloperEngagementMetricName, static_cast<int>(metric)}};
+    std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics) {
+  std::vector<std::pair<const char*, int>> form_structure_metrics;
+  for (const auto it : metrics)
+    form_structure_metrics.push_back(
+        {internal::kUKMDeveloperEngagementMetricName, static_cast<int>(it)});
+
   LogUkm(ukm_service, url, internal::kUKMDeveloperEngagementEntryName,
          form_structure_metrics);
 }
 
 // static
-bool AutofillMetrics::LogUkm(ukm::UkmService* ukm_service,
-                             const GURL& url,
-                             const std::string& ukm_entry_name,
-                             const std::map<std::string, int>& metrics) {
+bool AutofillMetrics::LogUkm(
+    ukm::UkmService* ukm_service,
+    const GURL& url,
+    const std::string& ukm_entry_name,
+    const std::vector<std::pair<const char*, int>>& metrics) {
   if (!IsUkmLoggingEnabled() || !ukm_service || !url.is_valid() ||
       metrics.empty()) {
     return false;
@@ -739,16 +770,18 @@
       ukm_service->GetEntryBuilder(source_id, ukm_entry_name.c_str());
 
   for (auto it = metrics.begin(); it != metrics.end(); ++it) {
-    builder->AddMetric(it->first.c_str(), it->second);
+    builder->AddMetric(it->first, it->second);
   }
 
   return true;
 }
 
-AutofillMetrics::FormEventLogger::FormEventLogger(bool is_for_credit_card)
+AutofillMetrics::FormEventLogger::FormEventLogger(
+    bool is_for_credit_card,
+    AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
     : is_for_credit_card_(is_for_credit_card),
-      is_server_data_available_(false),
-      is_local_data_available_(false),
+      server_record_type_count_(0),
+      local_record_type_count_(0),
       is_context_secure_(false),
       has_logged_interacted_(false),
       has_logged_suggestions_shown_(false),
@@ -757,11 +790,15 @@
       has_logged_will_submit_(false),
       has_logged_submitted_(false),
       logged_suggestion_filled_was_server_data_(false),
-      logged_suggestion_filled_was_masked_server_card_(false) {}
+      logged_suggestion_filled_was_masked_server_card_(false),
+      form_interactions_ukm_logger_(form_interactions_ukm_logger) {}
 
 void AutofillMetrics::FormEventLogger::OnDidInteractWithAutofillableForm() {
   if (!has_logged_interacted_) {
     has_logged_interacted_ = true;
+    form_interactions_ukm_logger_->LogInteractedWithForm(
+        is_for_credit_card_, local_record_type_count_,
+        server_record_type_count_);
     Log(AutofillMetrics::FORM_EVENT_INTERACTED_ONCE);
   }
 }
@@ -786,6 +823,8 @@
 }
 
 void AutofillMetrics::FormEventLogger::OnDidShowSuggestions() {
+  form_interactions_ukm_logger_->LogSuggestionsShown();
+
   Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN);
   if (!has_logged_suggestions_shown_) {
     has_logged_suggestions_shown_ = true;
@@ -803,17 +842,22 @@
 
 void AutofillMetrics::FormEventLogger::OnDidSelectMaskedServerCardSuggestion() {
   DCHECK(is_for_credit_card_);
+  form_interactions_ukm_logger_->LogSelectedMaskedServerCard();
+
   Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED);
   if (!has_logged_masked_server_card_suggestion_selected_) {
     has_logged_masked_server_card_suggestion_selected_ = true;
-    Log(AutofillMetrics
-            ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
+    Log(AutofillMetrics::
+            FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
   }
 }
 
 void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
     const CreditCard& credit_card) {
   DCHECK(is_for_credit_card_);
+  form_interactions_ukm_logger_->LogDidFillSuggestion(
+      static_cast<int>(credit_card.record_type()));
+
   if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD)
     Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED);
   else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD)
@@ -829,8 +873,8 @@
     logged_suggestion_filled_was_masked_server_card_ =
         credit_card.record_type() == CreditCard::MASKED_SERVER_CARD;
     if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD) {
-      Log(AutofillMetrics
-              ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
+      Log(AutofillMetrics::
+              FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
     } else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD) {
       Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE);
     } else {
@@ -845,6 +889,9 @@
 void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
     const AutofillProfile& profile) {
   DCHECK(!is_for_credit_card_);
+  form_interactions_ukm_logger_->LogDidFillSuggestion(
+      static_cast<int>(profile.record_type()));
+
   if (profile.record_type() == AutofillProfile::SERVER_PROFILE)
     Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
   else
@@ -855,8 +902,8 @@
     logged_suggestion_filled_was_server_data_ =
         profile.record_type() == AutofillProfile::SERVER_PROFILE;
     Log(profile.record_type() == AutofillProfile::SERVER_PROFILE
-        ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
-        : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
+            ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
+            : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
   }
 
   base::RecordAction(
@@ -904,8 +951,8 @@
   if (!has_logged_suggestion_filled_) {
     Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE);
   } else if (logged_suggestion_filled_was_masked_server_card_) {
-    Log(AutofillMetrics
-            ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
+    Log(AutofillMetrics::
+            FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
   } else if (logged_suggestion_filled_was_server_data_) {
     Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE);
   } else {
@@ -937,15 +984,154 @@
   // Logging again in a different histogram for segmentation purposes.
   // TODO(waltercacau): Re-evaluate if we still need such fine grained
   // segmentation. http://crbug.com/454018
-  if (!is_server_data_available_ && !is_local_data_available_)
+  if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
     name += ".WithNoData";
-  else if (is_server_data_available_ && !is_local_data_available_)
+  else if (server_record_type_count_ > 0 && local_record_type_count_ == 0)
     name += ".WithOnlyServerData";
-  else if (!is_server_data_available_ && is_local_data_available_)
+  else if (server_record_type_count_ == 0 && local_record_type_count_ > 0)
     name += ".WithOnlyLocalData";
   else
     name += ".WithBothServerAndLocalData";
   LogUMAHistogramEnumeration(name, event, NUM_FORM_EVENTS);
 }
 
+AutofillMetrics::FormInteractionsUkmLogger::FormInteractionsUkmLogger(
+    ukm::UkmService* ukm_service)
+    : ukm_service_(ukm_service) {}
+
+void AutofillMetrics::FormInteractionsUkmLogger::OnFormsLoaded(
+    const GURL& url) {
+  if (!IsUkmLoggingEnabled() || ukm_service_ == nullptr)
+    return;
+
+  url_ = url;
+  form_loaded_timestamp_ = base::TimeTicks::Now();
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::LogInteractedWithForm(
+    bool is_for_credit_card,
+    size_t local_record_type_count,
+    size_t server_record_type_count) {
+  if (!CanLog())
+    return;
+
+  if (source_id_ == -1)
+    GetNewSourceID();
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
+      source_id_, internal::kUKMInteractedWithFormEntryName);
+  builder->AddMetric(internal::kUKMIsForCreditCardMetricName,
+                     is_for_credit_card);
+  builder->AddMetric(internal::kUKMLocalRecordTypeCountMetricName,
+                     local_record_type_count);
+  builder->AddMetric(internal::kUKMServerRecordTypeCountMetricName,
+                     server_record_type_count);
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown() {
+  if (!CanLog())
+    return;
+
+  if (source_id_ == -1)
+    GetNewSourceID();
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
+      source_id_, internal::kUKMSuggestionsShownEntryName);
+  builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
+                     MillisecondsSinceFormLoaded());
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::LogSelectedMaskedServerCard() {
+  if (!CanLog())
+    return;
+
+  if (source_id_ == -1)
+    GetNewSourceID();
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
+      source_id_, internal::kUKMSelectedMaskedServerCardEntryName);
+  builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
+                     MillisecondsSinceFormLoaded());
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
+    int record_type) {
+  if (!CanLog())
+    return;
+
+  if (source_id_ == -1)
+    GetNewSourceID();
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
+      source_id_, internal::kUKMSuggestionFilledEntryName);
+  builder->AddMetric(internal::kUKMRecordTypeMetricName, record_type);
+  builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
+                     MillisecondsSinceFormLoaded());
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
+    const AutofillField& field) {
+  if (!CanLog())
+    return;
+
+  if (source_id_ == -1)
+    GetNewSourceID();
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
+      source_id_, internal::kUKMTextFieldDidChangeEntryName);
+  builder->AddMetric(internal::kUKMFieldTypeGroupMetricName,
+                     static_cast<int>(field.Type().group()));
+  builder->AddMetric(internal::kUKMHeuristicTypeMetricName,
+                     static_cast<int>(field.heuristic_type()));
+  builder->AddMetric(internal::kUKMServerTypeMetricName,
+                     static_cast<int>(field.server_type()));
+  builder->AddMetric(internal::kUKMHtmlFieldTypeMetricName,
+                     static_cast<int>(field.html_type()));
+  builder->AddMetric(internal::kUKMHtmlFieldModeMetricName,
+                     static_cast<int>(field.html_mode()));
+  builder->AddMetric(internal::kUKMIsAutofilledMetricName, field.is_autofilled);
+  builder->AddMetric(internal::kUKMIsEmptyMetricName, field.IsEmpty());
+  builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
+                     MillisecondsSinceFormLoaded());
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
+    AutofillFormSubmittedState state) {
+  if (!CanLog())
+    return;
+
+  if (source_id_ == -1)
+    GetNewSourceID();
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
+      source_id_, internal::kUKMFormSubmittedEntryName);
+  builder->AddMetric(internal::kUKMAutofillFormSubmittedStateMetricName,
+                     static_cast<int>(state));
+  builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
+                     MillisecondsSinceFormLoaded());
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::UpdateSourceURL(
+    const GURL& url) {
+  url_ = url;
+  if (CanLog())
+    ukm_service_->UpdateSourceURL(source_id_, url_);
+}
+
+bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
+  return IsUkmLoggingEnabled() && ukm_service_ && url_.is_valid();
+}
+
+int64_t
+AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormLoaded()
+    const {
+  DCHECK(!form_loaded_timestamp_.is_null());
+  return (base::TimeTicks::Now() - form_loaded_timestamp_).InMilliseconds();
+}
+
+void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() {
+  source_id_ = ukm_service_->GetNewSourceID();
+  ukm_service_->UpdateSourceURL(source_id_, url_);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index ace3362..58ab8d2 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -7,18 +7,17 @@
 
 #include <stddef.h>
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "base/macros.h"
+#include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_client.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/common/form_field_data.h"
 
-namespace base {
-class TimeDelta;
-}  // namespace base
-
 namespace ukm {
 class UkmService;
 }  // namespace ukm
@@ -29,10 +28,53 @@
 extern const char kUKMCardUploadDecisionMetricName[];
 extern const char kUKMDeveloperEngagementEntryName[];
 extern const char kUKMDeveloperEngagementMetricName[];
+
+// Each form interaction event has a separate |UkmEntry|.
+
+// The first form event |UkmEntry| contains metrics for metadata that apply
+// to all subsequent events.
+extern const char kUKMInteractedWithFormEntryName[];
+extern const char kUKMIsForCreditCardMetricName[];
+extern const char kUKMLocalRecordTypeCountMetricName[];
+extern const char kUKMServerRecordTypeCountMetricName[];
+
+// |UkmEntry| when we show suggestions.
+extern const char kUKMSuggestionsShownEntryName[];
+
+// |UkmEntry| when user selects a masked server credit card.
+extern const char kUKMSelectedMaskedServerCardEntryName[];
+
+// Each |UkmEntry|, except the first interaction with the form, has a metric for
+// time elapsed, in milliseconds, since we loaded the form.
+extern const char kUKMMillisecondsSinceFormLoadedMetricName[];
+
+// |FormEvent| for FORM_EVENT_*_SUGGESTION_FILLED in credit card forms include a
+// |CreditCard| |record_type()| to indicate if the suggestion was for a local
+// card, masked server card or full server card. Similarly, address/profile
+// forms include a |AutofillProfile| |record_type()| to indicate if the
+// profile was a local profile or server profile.
+extern const char kUKMSuggestionFilledEntryName[];
+extern const char kUKMRecordTypeMetricName[];
+
+// |UkmEntry| for user editing text field. Metrics contain field's attributes.
+extern const char kUKMTextFieldDidChangeEntryName[];
+extern const char kUKMFieldTypeGroupMetricName[];
+extern const char kUKMHeuristicTypeMetricName[];
+extern const char kUKMServerTypeMetricName[];
+extern const char kUKMHtmlFieldTypeMetricName[];
+extern const char kUKMHtmlFieldModeMetricName[];
+extern const char kUKMIsAutofilledMetricName[];
+extern const char kUKMIsEmptyMetricName[];
+
+// |UkmEntry| for |AutofillFormSubmittedState|.
+extern const char kUKMFormSubmittedEntryName[];
+extern const char kUKMAutofillFormSubmittedStateMetricName[];
 }  // namespace internal
 
 namespace autofill {
 
+class AutofillField;
+
 class AutofillMetrics {
  public:
   enum AutofillProfileAction {
@@ -82,6 +124,9 @@
     // were otherwise valid nor whether we would have been able to get upload
     // details.
     UPLOAD_NOT_OFFERED_CONFLICTING_NAMES,
+    // No CVC was detected, but valid addresses and names were.  Upload is still
+    // possible if the user manually enters CVC, so upload was offered.
+    UPLOAD_OFFERED_NO_CVC,
     NUM_CARD_UPLOAD_DECISION_METRICS,
   };
 
@@ -566,6 +611,39 @@
     NUM_CONVERTED_ADDRESS_CONVERSION_TYPES
   };
 
+  // Utility to log URL keyed form interaction events.
+  class FormInteractionsUkmLogger {
+   public:
+    explicit FormInteractionsUkmLogger(ukm::UkmService* ukm_service);
+
+    const GURL& url() const { return url_; }
+
+    void OnFormsLoaded(const GURL& url);
+    void LogInteractedWithForm(bool is_for_credit_card,
+                               size_t local_record_type_count,
+                               size_t server_record_type_count);
+    void LogSuggestionsShown();
+    void LogSelectedMaskedServerCard();
+    void LogDidFillSuggestion(int record_type);
+    void LogTextFieldDidChange(const AutofillField& field);
+    void LogFormSubmitted(AutofillFormSubmittedState state);
+
+    // We initialize |url_| with the form's URL when we log the first form
+    // interaction. Later, we may update |url_| with the |source_url()| for the
+    // submitted form.
+    void UpdateSourceURL(const GURL& url);
+
+   private:
+    bool CanLog() const;
+    int64_t MillisecondsSinceFormLoaded() const;
+    void GetNewSourceID();
+
+    ukm::UkmService* ukm_service_;  // Weak reference.
+    int32_t source_id_ = -1;
+    GURL url_;
+    base::TimeTicks form_loaded_timestamp_;
+  };
+
   static void LogCardUploadDecisionMetric(CardUploadDecisionMetric metric);
   static void LogCreditCardInfoBarMetric(InfoBarMetric metric,
                                          bool is_uploading);
@@ -692,7 +770,9 @@
 
   // This should be called at each form submission to indicate the autofilled
   // state of the form.
-  static void LogAutofillFormSubmittedState(AutofillFormSubmittedState state);
+  static void LogAutofillFormSubmittedState(
+      AutofillFormSubmittedState state,
+      FormInteractionsUkmLogger* form_interactions_ukm_logger);
 
   // This should be called when determining the heuristic types for a form's
   // fields.
@@ -731,27 +811,28 @@
   static void LogDeveloperEngagementUkm(
       ukm::UkmService* ukm_service,
       const GURL& url,
-      AutofillMetrics::DeveloperEngagementMetric metric);
+      std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics);
 
   // Logs the the |ukm_entry_name| with the specified |url| and the specified
   // |metrics|. Returns whether the ukm was sucessfully logged.
   static bool LogUkm(ukm::UkmService* ukm_service,
                      const GURL& url,
                      const std::string& ukm_entry_name,
-                     const std::map<std::string, int>& metrics);
+                     const std::vector<std::pair<const char*, int>>& metrics);
 
-  // Utility to autofill form events in the relevant histograms depending on
+  // Utility to log autofill form events in the relevant histograms depending on
   // the presence of server and/or local data.
   class FormEventLogger {
    public:
-    FormEventLogger(bool is_for_credit_card);
+    FormEventLogger(bool is_for_credit_card,
+                    FormInteractionsUkmLogger* form_interactions_ukm_logger);
 
-    inline void set_is_server_data_available(bool is_server_data_available) {
-      is_server_data_available_ = is_server_data_available;
+    inline void set_server_record_type_count(size_t server_record_type_count) {
+      server_record_type_count_ = server_record_type_count;
     }
 
-    inline void set_is_local_data_available(bool is_local_data_available) {
-      is_local_data_available_ = is_local_data_available;
+    inline void set_local_record_type_count(size_t local_record_type_count) {
+      local_record_type_count_ = local_record_type_count;
     }
 
     inline void set_is_context_secure(bool is_context_secure) {
@@ -780,8 +861,8 @@
     void Log(FormEvent event) const;
 
     bool is_for_credit_card_;
-    bool is_server_data_available_;
-    bool is_local_data_available_;
+    size_t server_record_type_count_;
+    size_t local_record_type_count_;
     bool is_context_secure_;
     bool has_logged_interacted_;
     bool has_logged_suggestions_shown_;
@@ -794,6 +875,9 @@
 
     // The last field that was polled for suggestions.
     FormFieldData last_polled_field_;
+
+    FormInteractionsUkmLogger*
+        form_interactions_ukm_logger_;  // Weak reference.
   };
 
  private:
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 56b76bc..3372ee3 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "base/feature_list.h"
@@ -54,7 +55,8 @@
 using base::TimeTicks;
 using rappor::TestRapporServiceImpl;
 using ::testing::ElementsAre;
-using ::testing::UnorderedElementsAre;
+using ::testing::Matcher;
+using ::testing::UnorderedPointwise;
 
 namespace autofill {
 namespace {
@@ -264,6 +266,8 @@
         base::MakeUnique<TestFormStructure>(empty_form);
     form_structure->SetFieldTypes(heuristic_types, server_types);
     form_structures()->push_back(std::move(form_structure));
+
+    form_interactions_ukm_logger()->OnFormsLoaded(form.origin);
   }
 
   // Calls AutofillManager::OnWillSubmitForm and waits for it to complete.
@@ -288,9 +292,9 @@
   void RunRunLoop() { run_loop_->Run(); }
 
   void UploadFormDataAsyncCallback(const FormStructure* submitted_form,
-                                   const base::TimeTicks& load_time,
-                                   const base::TimeTicks& interaction_time,
-                                   const base::TimeTicks& submission_time,
+                                   const TimeTicks& load_time,
+                                   const TimeTicks& interaction_time,
+                                   const TimeTicks& submission_time,
                                    bool observed_submission) override {
     run_loop_->Quit();
 
@@ -317,6 +321,83 @@
   return nullptr;
 }
 
+MATCHER(CompareMetrics, "") {
+  const ukm::Entry_Metric& lhs = ::testing::get<0>(arg);
+  const std::pair<const char*, int64_t>& rhs = ::testing::get<1>(arg);
+  return lhs.metric_hash() == base::HashMetricName(rhs.first) &&
+         lhs.value() == rhs.second;
+}
+
+void VerifyDeveloperEngagementUkm(
+    const FormData& form,
+    const ukm::TestUkmService* ukm_service,
+    const std::vector<int64_t>& expected_metric_values) {
+  const ukm::UkmEntry* entry = ukm_service->GetEntryForEntryName(
+      internal::kUKMDeveloperEngagementEntryName);
+  ASSERT_NE(nullptr, entry);
+  ukm::Entry entry_proto;
+  entry->PopulateProto(&entry_proto);
+
+  const ukm::UkmSource* source =
+      ukm_service->GetSourceForSourceId(entry_proto.source_id());
+  ASSERT_NE(nullptr, source);
+  EXPECT_EQ(form.origin, source->url());
+
+  std::vector<std::pair<const char*, int64_t>> expected_metrics;
+  for (const auto it : expected_metric_values)
+    expected_metrics.push_back(
+        {internal::kUKMDeveloperEngagementMetricName, it});
+
+  EXPECT_THAT(entry_proto.metrics(),
+              UnorderedPointwise(CompareMetrics(), expected_metrics));
+}
+
+MATCHER(CompareMetricsIgnoringMillisecondsSinceFormLoaded, "") {
+  const ukm::Entry_Metric& lhs = ::testing::get<0>(arg);
+  const std::pair<const char*, int64_t>& rhs = ::testing::get<1>(arg);
+  return lhs.metric_hash() == base::HashMetricName(rhs.first) &&
+         (lhs.value() == rhs.second ||
+          (lhs.value() > 0 &&
+           rhs.first == internal::kUKMMillisecondsSinceFormLoadedMetricName));
+}
+
+void VerifyFormInteractionUkm(
+    const FormData& form,
+    const ukm::TestUkmService* ukm_service,
+    const char* event_name,
+    const std::vector<std::vector<std::pair<const char*, int64_t>>>&
+        expected_metrics) {
+  size_t expected_metrics_index = 0;
+  for (size_t i = 0; i < ukm_service->entries_count(); ++i) {
+    const ukm::UkmEntry* entry = ukm_service->GetEntry(i);
+    if (entry->event_hash() != base::HashMetricName(event_name))
+      continue;
+
+    ukm::Entry entry_proto;
+    entry->PopulateProto(&entry_proto);
+
+    const ukm::UkmSource* source =
+        ukm_service->GetSourceForSourceId(entry_proto.source_id());
+    ASSERT_NE(nullptr, source);
+    EXPECT_EQ(form.origin, source->url());
+
+    ASSERT_LT(expected_metrics_index, expected_metrics.size());
+    EXPECT_THAT(
+        entry_proto.metrics(),
+        UnorderedPointwise(CompareMetricsIgnoringMillisecondsSinceFormLoaded(),
+                           expected_metrics[expected_metrics_index++]));
+  }
+}
+
+void VerifySubmitFormUkm(const FormData& form,
+                         const ukm::TestUkmService* ukm_service,
+                         AutofillMetrics::AutofillFormSubmittedState state) {
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMFormSubmittedEntryName,
+      {{{internal::kUKMAutofillFormSubmittedStateMetricName, state},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+}
+
 }  // namespace
 
 // This is defined in the autofill_metrics.cc implementation file.
@@ -394,6 +475,7 @@
   account_tracker_.reset();
   signin_client_.reset();
   test::ReenableSystemServices();
+  autofill_client_.GetTestUkmService()->Purge();
 }
 
 void AutofillMetricsTest::EnableWalletSync() {
@@ -694,7 +776,7 @@
   // Simulate a OnFormsSeen() call that should trigger the recording.
   std::vector<FormData> forms;
   forms.push_back(form);
-  autofill_manager_->OnFormsSeen(forms, base::TimeTicks::Now());
+  autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
 
   // Because these metrics are related to timing, it is not possible to know in
   // advance which bucket the sample will fall into, so we just need to make
@@ -1545,6 +1627,11 @@
   // fields is logged.
   histogram_tester.ExpectUniqueSample(
       "Autofill.NumberOfEditedAutofilledFieldsAtSubmission", 2, 1);
+
+  // UKM must not be logged unless enabled.
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+  EXPECT_EQ(0U, ukm_service->sources_count());
+  EXPECT_EQ(0U, ukm_service->entries_count());
 }
 
 // Verify that when resetting the autofill manager (such as during a
@@ -1721,7 +1808,7 @@
 
   // Ensure no metrics are logged when loading a non-fillable form.
   {
-    autofill_manager_->OnFormsSeen(forms, TimeTicks());
+    autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
     autofill_manager_->Reset();
 
     EXPECT_EQ(0U, ukm_service->sources_count());
@@ -1732,30 +1819,17 @@
   test::CreateTestFormField("Phone", "phone", "", "text", &field);
   forms.back().fields.push_back(field);
 
-  // Expect the "form parsed without field type hints" metric to be logged.
+  // Expect the "form parsed without field type hints" metric and the
+  // "form loaded" form interaction event to be logged.
   {
-    autofill_manager_->OnFormsSeen(forms, TimeTicks());
+    autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
     autofill_manager_->Reset();
 
-    ASSERT_EQ(1U, ukm_service->sources_count());
-    const ukm::UkmSource* source =
-        ukm_service->GetSourceForUrl(form.origin.spec().c_str());
-    ASSERT_NE(nullptr, source);
-
     ASSERT_EQ(1U, ukm_service->entries_count());
-    const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
-    EXPECT_EQ(source->id(), entry->source_id());
-
-    ukm::Entry entry_proto;
-    entry->PopulateProto(&entry_proto);
-    EXPECT_EQ(source->id(), entry_proto.source_id());
-    EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
-              entry_proto.event_hash());
-    const ukm::Entry_Metric* metric = FindMetric(
-        internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics());
-    ASSERT_NE(nullptr, metric);
-    EXPECT_EQ(AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS,
-              metric->value());
+    ASSERT_EQ(1U, ukm_service->sources_count());
+    VerifyDeveloperEngagementUkm(
+        form, ukm_service,
+        {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS});
   }
 }
 
@@ -1798,30 +1872,17 @@
   field.autocomplete_attribute = "address-line1";
   forms.back().fields.push_back(field);
 
-  // Expect the "form parsed with field type hints" metric to be logged.
+  // Expect the "form parsed without field type hints" metric and the
+  // "form loaded" form interaction event to be logged.
   {
-    autofill_manager_->OnFormsSeen(forms, TimeTicks());
+    autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
     autofill_manager_->Reset();
 
-    ASSERT_EQ(1U, ukm_service->sources_count());
-    const ukm::UkmSource* source =
-        ukm_service->GetSourceForUrl(form.origin.spec().c_str());
-    ASSERT_NE(nullptr, source);
-
     ASSERT_EQ(1U, ukm_service->entries_count());
-    const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
-    EXPECT_EQ(source->id(), entry->source_id());
-
-    ukm::Entry entry_proto;
-    entry->PopulateProto(&entry_proto);
-    EXPECT_EQ(source->id(), entry_proto.source_id());
-    EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
-              entry_proto.event_hash());
-    const ukm::Entry_Metric* metric = FindMetric(
-        internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics());
-    ASSERT_NE(nullptr, metric);
-    EXPECT_EQ(AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS,
-              metric->value());
+    ASSERT_EQ(1U, ukm_service->sources_count());
+    VerifyDeveloperEngagementUkm(
+        form, ukm_service,
+        {AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS});
   }
 }
 
@@ -1847,29 +1908,32 @@
 
   std::vector<FormData> forms(1, form);
 
-  // Expect the "upi-vpa hint" metric to be logged.
+  // Expect the "upi-vpa hint" metric to be logged and the "form loaded" form
+  // interaction event to be logged.
   {
-    autofill_manager_->OnFormsSeen(forms, TimeTicks());
+    autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
     autofill_manager_->Reset();
 
-    ASSERT_EQ(1U, ukm_service->sources_count());
-    const ukm::UkmSource* source =
-        ukm_service->GetSourceForUrl(form.origin.spec().c_str());
-    ASSERT_NE(nullptr, source);
-
     ASSERT_EQ(1U, ukm_service->entries_count());
-    const ukm::UkmEntry* entry = ukm_service->GetEntry(0);
-    EXPECT_EQ(source->id(), entry->source_id());
+    ASSERT_EQ(1U, ukm_service->sources_count());
+    VerifyDeveloperEngagementUkm(form, ukm_service,
+                                 {AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT});
+    ukm_service->Purge();
+  }
 
-    ukm::Entry entry_proto;
-    entry->PopulateProto(&entry_proto);
-    EXPECT_EQ(source->id(), entry_proto.source_id());
-    EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName),
-              entry_proto.event_hash());
-    const ukm::Entry_Metric* metric = FindMetric(
-        internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics());
-    ASSERT_NE(nullptr, metric);
-    EXPECT_EQ(AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT, metric->value());
+  // Add another field with an author-specified field type to the form.
+  test::CreateTestFormField("", "", "", "text", &field);
+  field.autocomplete_attribute = "address-line1";
+  forms.back().fields.push_back(field);
+
+  {
+    autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
+    autofill_manager_->Reset();
+
+    VerifyDeveloperEngagementUkm(
+        form, ukm_service,
+        {AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS,
+         AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT});
   }
 }
 
@@ -2052,6 +2116,9 @@
 
 // Test that the credit card checkout flow user actions are correctly logged.
 TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
+  EnableUkmLogging();
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+
   personal_data_->RecreateCreditCards(
       true /* include_local_credit_card */,
       false /* include_masked_server_credit_card */,
@@ -2127,10 +2194,30 @@
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_NonFillable"));
   }
+
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMSuggestionsShownEntryName,
+      {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+  // Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
+  // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
+  // |autofill_manager_->FillOrPreviewForm|.
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+      {{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+       {{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+  // Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
+  // because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
+  VerifySubmitFormUkm(form, ukm_service,
+                      AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
 }
 
 // Test that the profile checkout flow user actions are correctly logged.
 TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
+  EnableUkmLogging();
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+
   // Create a profile.
   personal_data_->RecreateProfile();
 
@@ -2178,7 +2265,7 @@
     std::string guid("00000000-0000-0000-0000-000000000001");  // local profile.
     external_delegate_->DidAcceptSuggestion(
         ASCIIToUTF16("Test"),
-        autofill_manager_->MakeFrontendID(guid, std::string()), 0);
+        autofill_manager_->MakeFrontendID(std::string(), guid), 0);
     EXPECT_EQ(1,
               user_action_tester.GetActionCount("Autofill_SelectedSuggestion"));
   }
@@ -2204,6 +2291,23 @@
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_NonFillable"));
   }
+
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMSuggestionsShownEntryName,
+      {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+  // Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
+  // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
+  // |autofill_manager_->FillOrPreviewForm|.
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+      {{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+       {{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+  // Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
+  // because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
+  VerifySubmitFormUkm(form, ukm_service,
+                      AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
 }
 
 // Tests that the Autofill_PolledCreditCardSuggestions user action is only
@@ -2493,6 +2597,11 @@
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
   }
+
+  // UKM must not be logged unless enabled.
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+  EXPECT_EQ(0U, ukm_service->sources_count());
+  EXPECT_EQ(0U, ukm_service->entries_count());
 }
 
 // Test that we log selected form event for credit cards.
@@ -2625,6 +2734,7 @@
         autofill_manager_->MakeFrontendID(guid, std::string()));
     autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS,
                                        "6011000990139424");
+    autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
@@ -2758,6 +2868,9 @@
 
 // Test that we log submitted form events for credit cards.
 TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) {
+  EnableUkmLogging();
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+
   EnableWalletSync();
   // Creating all kinds of cards.
   personal_data_->RecreateCreditCards(
@@ -2797,10 +2910,15 @@
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 
-  // Reset the autofill manager state.
+  // Reset the autofill manager state and purge UKM logs.
   autofill_manager_->Reset();
+  ukm_service->Purge();
+
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
@@ -2815,10 +2933,18 @@
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSuggestionsShownEntryName,
+        {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 
-  // Reset the autofill manager state.
+  // Reset the autofill manager state and purge UKM logs.
   autofill_manager_->Reset();
+  ukm_service->Purge();
+
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
@@ -2836,10 +2962,19 @@
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+        {{{internal::kUKMRecordTypeMetricName, CreditCard::LOCAL_CARD},
+          {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 
-  // Reset the autofill manager state.
+  // Reset the autofill manager state and purge UKM logs.
   autofill_manager_->Reset();
+  ukm_service->Purge();
+
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
@@ -2858,10 +2993,19 @@
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+        {{{internal::kUKMRecordTypeMetricName, CreditCard::FULL_SERVER_CARD},
+          {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 
-  // Reset the autofill manager state.
+  // Reset the autofill manager state and purge UKM logs.
   autofill_manager_->Reset();
+  ukm_service->Purge();
+
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
@@ -2874,6 +3018,7 @@
         autofill_manager_->MakeFrontendID(guid, std::string()));
     autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS,
                                        "6011000990139424");
+    autofill_manager_->SubmitForm(form, TimeTicks::Now());
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
@@ -2881,8 +3026,22 @@
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
         1);
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+        {{{internal::kUKMRecordTypeMetricName, CreditCard::MASKED_SERVER_CARD},
+          {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSelectedMaskedServerCardEntryName,
+        {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 
+  // Reset the autofill manager state and purge UKM logs.
+  autofill_manager_->Reset();
+  ukm_service->Purge();
+
   // Recreating cards as the previous test should have upgraded the masked
   // card to a full card.
   personal_data_->RecreateCreditCards(
@@ -2899,7 +3058,24 @@
     base::HistogramTester histogram_tester;
     autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF());
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMFormSubmittedEntryName,
+        {{{internal::kUKMAutofillFormSubmittedStateMetricName,
+           AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
+          {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMFormSubmittedEntryName,
+        {{{internal::kUKMAutofillFormSubmittedStateMetricName,
+           AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
+          {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+         {{internal::kUKMAutofillFormSubmittedStateMetricName,
+           AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
+          {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -2936,8 +3112,10 @@
         0);
   }
 
-  // Reset the autofill manager state.
+  // Reset the autofill manager state and purge UKM logs.
   autofill_manager_->Reset();
+  ukm_service->Purge();
+
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
@@ -2980,6 +3158,12 @@
         AutofillMetrics::
             FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
         0);
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSuggestionsShownEntryName,
+        {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 }
 
@@ -3401,6 +3585,9 @@
 
 // Test that we log submitted form events for address.
 TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
+  EnableUkmLogging();
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+
   EnableWalletSync();
   // Create a profile.
   personal_data_->RecreateProfile();
@@ -3437,10 +3624,15 @@
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+
+    VerifySubmitFormUkm(form, ukm_service,
+                        AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
   }
 
-  // Reset the autofill manager state.
+  // Reset the autofill manager state and purge UKM logs.
   autofill_manager_->Reset();
+  ukm_service->Purge();
+
   autofill_manager_->AddSeenForm(form, field_types, field_types);
 
   {
@@ -3488,6 +3680,7 @@
     autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF());
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
+
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -3524,6 +3717,7 @@
     base::HistogramTester histogram_tester;
     autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
     autofill_manager_->SubmitForm(form, TimeTicks::Now());
+
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
@@ -3894,7 +4088,6 @@
   }
 }
 
-
 // Test that we log that Autofill is enabled when filling a form.
 TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) {
   base::HistogramTester histogram_tester;
@@ -3933,6 +4126,9 @@
 
 // Verify that we correctly log the submitted form's state.
 TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
+  EnableUkmLogging();
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+
   // Start with a form with insufficiently many fields.
   FormData form;
   form.name = ASCIIToUTF16("TestForm");
@@ -3953,10 +4149,16 @@
   // Expect no notifications when the form is first seen.
   {
     base::HistogramTester histogram_tester;
-    autofill_manager_->OnFormsSeen(forms, TimeTicks());
+    autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
     histogram_tester.ExpectTotalCount("Autofill.FormSubmittedState", 0);
   }
 
+  std::vector<std::vector<std::pair<const char*, int64_t>>>
+      expected_form_submission_ukm_metrics = {
+          {{internal::kUKMAutofillFormSubmittedStateMetricName,
+            AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
+           {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}};
+
   // No data entered in the form.
   {
     base::HistogramTester histogram_tester;
@@ -3967,6 +4169,17 @@
         AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_NonFillable"));
+
+    // Expect an entry for |DeveloperEngagement| and an entry for form
+    // interactions. Both entries are for the same URL.
+    ASSERT_EQ(2U, ukm_service->entries_count());
+    ASSERT_EQ(2U, ukm_service->sources_count());
+    VerifyDeveloperEngagementUkm(
+        form, ukm_service,
+        {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 
   // Non fillable form.
@@ -3983,6 +4196,14 @@
         AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_NonFillable"));
+
+    expected_form_submission_ukm_metrics.push_back(
+        {{internal::kUKMAutofillFormSubmittedStateMetricName,
+          AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
+         {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 
   // Fill in the third field.
@@ -4000,6 +4221,15 @@
         1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_FilledNone_SuggestionsNotShown"));
+
+    expected_form_submission_ukm_metrics.push_back(
+        {{internal::kUKMAutofillFormSubmittedStateMetricName,
+          AutofillMetrics::
+              FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS},
+         {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 
   // Autofilled none with suggestions shown.
@@ -4013,6 +4243,17 @@
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS, 1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_FilledNone_SuggestionsShown"));
+
+    VerifyFormInteractionUkm(
+        form, ukm_service, internal::kUKMSuggestionsShownEntryName,
+        {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+    expected_form_submission_ukm_metrics.push_back(
+        {{internal::kUKMAutofillFormSubmittedStateMetricName,
+          AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS},
+         {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 
   // Mark one of the fields as autofilled.
@@ -4029,6 +4270,14 @@
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME, 1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_FilledSome"));
+
+    expected_form_submission_ukm_metrics.push_back(
+        {{internal::kUKMAutofillFormSubmittedStateMetricName,
+          AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME},
+         {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 
   // Mark all of the fillable fields as autofilled.
@@ -4046,6 +4295,14 @@
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL, 1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_FilledAll"));
+
+    expected_form_submission_ukm_metrics.push_back(
+        {{internal::kUKMAutofillFormSubmittedStateMetricName,
+          AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL},
+         {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 
   // Clear out the third field's value.
@@ -4062,12 +4319,23 @@
         AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FormSubmitted_NonFillable"));
+
+    expected_form_submission_ukm_metrics.push_back(
+        {{internal::kUKMAutofillFormSubmittedStateMetricName,
+          AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
+         {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}});
+    VerifyFormInteractionUkm(form, ukm_service,
+                             internal::kUKMFormSubmittedEntryName,
+                             expected_form_submission_ukm_metrics);
   }
 }
 
 // Verify that we correctly log user happiness metrics dealing with form
 // interaction.
 TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) {
+  EnableUkmLogging();
+  ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService();
+
   // Load a fillable form.
   FormData form;
   form.name = ASCIIToUTF16("TestForm");
@@ -4167,6 +4435,50 @@
         "Autofill.UserHappiness",
         AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD, 1);
   }
+
+  autofill_manager_->Reset();
+
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMInteractedWithFormEntryName,
+      {{{internal::kUKMIsForCreditCardMetricName, false},
+        {internal::kUKMLocalRecordTypeCountMetricName, 0},
+        {internal::kUKMServerRecordTypeCountMetricName, 0}}});
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMSuggestionsShownEntryName,
+      {{{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+       {{internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMSuggestionFilledEntryName,
+      {{{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+       {{internal::kUKMRecordTypeMetricName, AutofillProfile::LOCAL_PROFILE},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
+  VerifyFormInteractionUkm(
+      form, ukm_service, internal::kUKMTextFieldDidChangeEntryName,
+      {{{internal::kUKMFieldTypeGroupMetricName, NAME},
+        {internal::kUKMHeuristicTypeMetricName, NAME_FULL},
+        {internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
+        {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+        {internal::kUKMHtmlFieldModeMetricName, HTML_MODE_NONE},
+        {internal::kUKMIsAutofilledMetricName, false},
+        {internal::kUKMIsEmptyMetricName, true},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+       {{internal::kUKMFieldTypeGroupMetricName, NAME},
+        {internal::kUKMHeuristicTypeMetricName, NAME_FULL},
+        {internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
+        {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+        {internal::kUKMHtmlFieldModeMetricName, HTML_MODE_NONE},
+        {internal::kUKMIsAutofilledMetricName, true},
+        {internal::kUKMIsEmptyMetricName, true},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}},
+       {{internal::kUKMFieldTypeGroupMetricName, EMAIL},
+        {internal::kUKMHeuristicTypeMetricName, EMAIL_ADDRESS},
+        {internal::kUKMServerTypeMetricName, NO_SERVER_DATA},
+        {internal::kUKMHtmlFieldTypeMetricName, HTML_TYPE_UNSPECIFIED},
+        {internal::kUKMHtmlFieldModeMetricName, HTML_MODE_NONE},
+        {internal::kUKMIsAutofilledMetricName, true},
+        {internal::kUKMIsEmptyMetricName, true},
+        {internal::kUKMMillisecondsSinceFormLoadedMetricName, 0}}});
 }
 
 // Verify that we correctly log metrics tracking the duration of form fill.
@@ -4744,7 +5056,7 @@
   ukm::UkmServiceTestingHarness ukm_service_test_harness;
   GURL url("https://www.google.com");
   int upload_decision = 1;
-  std::map<std::string, int> metrics = {
+  std::vector<std::pair<const char*, int>> metrics = {
       {internal::kUKMCardUploadDecisionMetricName, upload_decision}};
 
   EXPECT_TRUE(AutofillMetrics::LogUkm(
@@ -4785,7 +5097,7 @@
   ukm::UkmServiceTestingHarness ukm_service_test_harness;
   GURL url("https://www.google.com");
   int form_structure_metric = 1;
-  std::map<std::string, int> metrics = {
+  std::vector<std::pair<const char*, int>> metrics = {
       {internal::kUKMDeveloperEngagementMetricName, form_structure_metric}};
 
   EXPECT_TRUE(AutofillMetrics::LogUkm(
@@ -4825,7 +5137,7 @@
   EnableUkmLogging();
   ukm::UkmServiceTestingHarness ukm_service_test_harness;
   GURL url("");
-  std::map<std::string, int> metrics = {{"metric", 1}};
+  std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
 
   EXPECT_FALSE(AutofillMetrics::LogUkm(
       ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
@@ -4837,7 +5149,7 @@
   EnableUkmLogging();
   ukm::UkmServiceTestingHarness ukm_service_test_harness;
   GURL url("https://www.google.com");
-  std::map<std::string, int> metrics;
+  std::vector<std::pair<const char*, int>> metrics;
 
   EXPECT_FALSE(AutofillMetrics::LogUkm(
       ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
@@ -4849,7 +5161,7 @@
   EnableUkmLogging();
   ukm::UkmServiceTestingHarness ukm_service_test_harness;
   GURL url("https://www.google.com");
-  std::map<std::string, int> metrics = {{"metric", 1}};
+  std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
 
   EXPECT_FALSE(AutofillMetrics::LogUkm(nullptr, url, "test_ukm", metrics));
   ASSERT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count());
@@ -4859,7 +5171,7 @@
 TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_FeatureDisabled) {
   ukm::UkmServiceTestingHarness ukm_service_test_harness;
   GURL url("https://www.google.com");
-  std::map<std::string, int> metrics = {{"metric", 1}};
+  std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}};
 
   EXPECT_FALSE(AutofillMetrics::LogUkm(
       ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics));
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index aaa1c82d..9bff7e2 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <map>
 #include <utility>
+#include <vector>
 
 #include "base/command_line.h"
 #include "base/i18n/case_conversion.h"
@@ -364,23 +365,25 @@
   UpdateAutofillCount();
   IdentifySections(has_author_specified_sections_);
 
+  std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics;
   if (IsAutofillable()) {
-    const auto metric =
+    AutofillMetrics::DeveloperEngagementMetric metric =
         has_author_specified_types_
             ? AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS
             : AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS;
+    metrics.push_back(metric);
     AutofillMetrics::LogDeveloperEngagementMetric(metric);
-    AutofillMetrics::LogDeveloperEngagementUkm(ukm_service, source_url(),
-                                               metric);
   }
 
   if (has_author_specified_upi_vpa_hint_) {
     AutofillMetrics::LogDeveloperEngagementMetric(
         AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT);
-    AutofillMetrics::LogDeveloperEngagementUkm(
-        ukm_service, source_url(), AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT);
+    metrics.push_back(AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT);
   }
 
+  AutofillMetrics::LogDeveloperEngagementUkm(ukm_service, source_url(),
+                                             metrics);
+
   AutofillMetrics::LogDetermineHeuristicTypesTiming(
       base::TimeTicks::Now() - determine_heuristic_types_start_time);
 }
@@ -682,12 +685,14 @@
   form_signature_ = cached_form.form_signature_;
 }
 
-void FormStructure::LogQualityMetrics(const base::TimeTicks& load_time,
-                                      const base::TimeTicks& interaction_time,
-                                      const base::TimeTicks& submission_time,
-                                      rappor::RapporServiceImpl* rappor_service,
-                                      bool did_show_suggestions,
-                                      bool observed_submission) const {
+void FormStructure::LogQualityMetrics(
+    const base::TimeTicks& load_time,
+    const base::TimeTicks& interaction_time,
+    const base::TimeTicks& submission_time,
+    rappor::RapporServiceImpl* rappor_service,
+    AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
+    bool did_show_suggestions,
+    bool observed_submission) const {
   size_t num_detected_field_types = 0;
   size_t num_server_mismatches = 0;
   size_t num_heuristic_mismatches = 0;
@@ -824,24 +829,20 @@
   // We log "submission" and duration metrics if we are here after observing a
   // submission event.
   if (observed_submission) {
+    AutofillMetrics::AutofillFormSubmittedState state;
     if (num_detected_field_types < kRequiredFieldsForPredictionRoutines) {
-      AutofillMetrics::LogAutofillFormSubmittedState(
-          AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA);
+      state = AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA;
     } else {
       if (did_autofill_all_possible_fields) {
-        AutofillMetrics::LogAutofillFormSubmittedState(
-            AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL);
+        state = AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL;
       } else if (did_autofill_some_possible_fields) {
-        AutofillMetrics::LogAutofillFormSubmittedState(
-            AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME);
+        state = AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME;
       } else if (!did_show_suggestions) {
-        AutofillMetrics::LogAutofillFormSubmittedState(
-            AutofillMetrics::
-                FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS);
+        state = AutofillMetrics::
+            FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS;
       } else {
-        AutofillMetrics::LogAutofillFormSubmittedState(
-            AutofillMetrics::
-                FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS);
+        state =
+            AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS;
       }
 
       // Log some RAPPOR metrics for problematic cases.
@@ -888,6 +889,10 @@
         }
       }
     }
+    if (form_interactions_ukm_logger->url() != source_url())
+      form_interactions_ukm_logger->UpdateSourceURL(source_url());
+    AutofillMetrics::LogAutofillFormSubmittedState(
+        state, form_interactions_ukm_logger);
   }
 }
 
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 2890f67..5365ec1 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -18,6 +18,7 @@
 #include "base/strings/string16.h"
 #include "base/strings/string_piece.h"
 #include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/proto/server.pb.h"
@@ -132,12 +133,16 @@
   // indicates whether this method is called as a result of observing a
   // submission event (otherwise, it may be that an upload was triggered after
   // a form was unfocused or a navigation occurred).
-  void LogQualityMetrics(const base::TimeTicks& load_time,
-                         const base::TimeTicks& interaction_time,
-                         const base::TimeTicks& submission_time,
-                         rappor::RapporServiceImpl* rappor_service,
-                         bool did_show_suggestions,
-                         bool observed_submission) const;
+  // TODO(sebsg): We log more than quality metrics. Maybe rename or split
+  // function?
+  void LogQualityMetrics(
+      const base::TimeTicks& load_time,
+      const base::TimeTicks& interaction_time,
+      const base::TimeTicks& submission_time,
+      rappor::RapporServiceImpl* rappor_service,
+      AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
+      bool did_show_suggestions,
+      bool observed_submission) const;
 
   // Log the quality of the heuristics and server predictions for this form
   // structure, if autocomplete attributes are present on the fields (they are
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc
index 753edd5..1c67ac6 100644
--- a/components/autofill/core/browser/test_autofill_client.cc
+++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "components/autofill/core/browser/test_autofill_client.h"
+#if !defined(OS_ANDROID)
+#include "components/autofill/core/browser/ui/mock_save_card_bubble_controller.h"
+#endif
 
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
 
@@ -12,6 +15,9 @@
     : token_service_(new FakeOAuth2TokenService()),
       identity_provider_(new FakeIdentityProvider(token_service_.get())),
       rappor_service_(new rappor::TestRapporServiceImpl()),
+#if !defined(OS_ANDROID)
+      save_card_bubble_controller_(new MockSaveCardBubbleController()),
+#endif
       form_origin_(GURL("https://example.test")) {}
 
 TestAutofillClient::~TestAutofillClient() {
@@ -45,6 +51,14 @@
   return ukm_service_test_harness_.test_ukm_service();
 }
 
+SaveCardBubbleController* TestAutofillClient::GetSaveCardBubbleController() {
+#if defined(OS_ANDROID)
+  return nullptr;
+#else
+  return save_card_bubble_controller_.get();
+#endif
+}
+
 void TestAutofillClient::ShowAutofillSettings() {
 }
 
@@ -65,6 +79,7 @@
 void TestAutofillClient::ConfirmSaveCreditCardToCloud(
     const CreditCard& card,
     std::unique_ptr<base::DictionaryValue> legal_message,
+    bool should_cvc_be_requested,
     const base::Closure& callback) {
   callback.Run();
 }
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h
index 7bd1c96..a140c772 100644
--- a/components/autofill/core/browser/test_autofill_client.h
+++ b/components/autofill/core/browser/test_autofill_client.h
@@ -36,6 +36,7 @@
   IdentityProvider* GetIdentityProvider() override;
   rappor::RapporServiceImpl* GetRapporServiceImpl() override;
   ukm::UkmService* GetUkmService() override;
+  SaveCardBubbleController* GetSaveCardBubbleController() override;
   void ShowAutofillSettings() override;
   void ShowUnmaskPrompt(const CreditCard& card,
                         UnmaskCardReason reason,
@@ -46,6 +47,7 @@
   void ConfirmSaveCreditCardToCloud(
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
+      bool should_cvc_be_requested,
       const base::Closure& callback) override;
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    const base::Closure& callback) override;
@@ -97,6 +99,9 @@
   std::unique_ptr<FakeIdentityProvider> identity_provider_;
   std::unique_ptr<rappor::TestRapporServiceImpl> rappor_service_;
   ukm::UkmServiceTestingHarness ukm_service_test_harness_;
+#if !defined(OS_ANDROID)
+  std::unique_ptr<SaveCardBubbleController> save_card_bubble_controller_;
+#endif
   GURL form_origin_;
 
   DISALLOW_COPY_AND_ASSIGN(TestAutofillClient);
diff --git a/components/autofill/core/browser/ui/mock_save_card_bubble_controller.cc b/components/autofill/core/browser/ui/mock_save_card_bubble_controller.cc
new file mode 100644
index 0000000..b0c8d787
--- /dev/null
+++ b/components/autofill/core/browser/ui/mock_save_card_bubble_controller.cc
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/ui/mock_save_card_bubble_controller.h"
+
+namespace autofill {
+
+MockSaveCardBubbleController::MockSaveCardBubbleController() {}
+
+MockSaveCardBubbleController::~MockSaveCardBubbleController() {}
+
+base::string16 MockSaveCardBubbleController::GetCvcEnteredByUser() const {
+  return cvc_entered_by_user_;
+}
+
+void MockSaveCardBubbleController::OnSaveButton(const base::string16& cvc) {
+  if (!cvc.empty())
+    cvc_entered_by_user_ = cvc;
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/ui/mock_save_card_bubble_controller.h b/components/autofill/core/browser/ui/mock_save_card_bubble_controller.h
new file mode 100644
index 0000000..ce040ae
--- /dev/null
+++ b/components/autofill/core/browser/ui/mock_save_card_bubble_controller.h
@@ -0,0 +1,42 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_MOCK_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_MOCK_SAVE_CARD_BUBBLE_CONTROLLER_H_
+
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill {
+
+class MockSaveCardBubbleController : public SaveCardBubbleController {
+ public:
+  MockSaveCardBubbleController();
+  ~MockSaveCardBubbleController() override;
+
+  MOCK_CONST_METHOD0(GetWindowTitle, base::string16());
+  MOCK_CONST_METHOD0(GetExplanatoryMessage, base::string16());
+  MOCK_CONST_METHOD0(GetCard, const CreditCard());
+  MOCK_CONST_METHOD0(GetCvcImageResourceId, int());
+  MOCK_CONST_METHOD0(ShouldRequestCvcFromUser, bool());
+  MOCK_METHOD0(OnCancelButton, void());
+  MOCK_METHOD0(OnLearnMoreClicked, void());
+  MOCK_METHOD1(OnLegalMessageLinkClicked, void(const GURL& url));
+  MOCK_METHOD0(OnBubbleClosed, void());
+  MOCK_CONST_METHOD0(GetLegalMessageLines, const LegalMessageLines&());
+  MOCK_CONST_METHOD1(InputCvcIsValid, bool(const base::string16& input_text));
+
+  base::string16 GetCvcEnteredByUser() const override;
+  void OnSaveButton(const base::string16& cvc = base::string16()) override;
+
+ private:
+  base::string16 cvc_entered_by_user_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockSaveCardBubbleController);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_MOCK_SAVE_CARD_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller.h b/components/autofill/core/browser/ui/save_card_bubble_controller.h
similarity index 61%
rename from chrome/browser/ui/autofill/save_card_bubble_controller.h
rename to components/autofill/core/browser/ui/save_card_bubble_controller.h
index 6f74eb3..f01cac3 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller.h
+++ b/components/autofill/core/browser/ui/save_card_bubble_controller.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_AUTOFILL_SAVE_CARD_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_UI_AUTOFILL_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SAVE_CARD_BUBBLE_CONTROLLER_H_
 
 #include <memory>
 #include <vector>
@@ -21,6 +21,9 @@
 // Interface that exposes controller functionality to SaveCardBubbleView.
 class SaveCardBubbleController {
  public:
+  SaveCardBubbleController() {}
+  virtual ~SaveCardBubbleController() {}
+
   // Returns the title that should be displayed in the bubble.
   virtual base::string16 GetWindowTitle() const = 0;
 
@@ -31,8 +34,20 @@
   // Returns the card that will be uploaded if the user accepts.
   virtual const CreditCard GetCard() const = 0;
 
+  // Returns the CVC image icon resource ID.
+  virtual int GetCvcImageResourceId() const = 0;
+
+  // Returns whether the dialog should include a field requesting the card's CVC
+  // from the user.
+  virtual bool ShouldRequestCvcFromUser() const = 0;
+
+  // Returns the CVC provided by the user in the save card bubble.
+  virtual base::string16 GetCvcEnteredByUser() const = 0;
+
   // Interaction.
-  virtual void OnSaveButton() = 0;
+  // OnSaveButton takes in a string value representing the CVC entered by the
+  // user if it was requested, or an empty string otherwise.
+  virtual void OnSaveButton(const base::string16& cvc) = 0;
   virtual void OnCancelButton() = 0;
   virtual void OnLearnMoreClicked() = 0;
   virtual void OnLegalMessageLinkClicked(const GURL& url) = 0;
@@ -43,13 +58,13 @@
   // Returns empty vector if no legal message should be shown.
   virtual const LegalMessageLines& GetLegalMessageLines() const = 0;
 
- protected:
-  SaveCardBubbleController() {}
-  virtual ~SaveCardBubbleController() {}
+  // Utilities.
+  virtual bool InputCvcIsValid(const base::string16& input_text) const = 0;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SaveCardBubbleController);
 };
 
 }  // namespace autofill
 
-#endif  // CHROME_BROWSER_UI_AUTOFILL_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SAVE_CARD_BUBBLE_CONTROLLER_H_
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp
index 73c48b7..2ab82162 100644
--- a/components/autofill_strings.grdp
+++ b/components/autofill_strings.grdp
@@ -210,6 +210,9 @@
   <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION" desc="Explanation of the effect of the Autofill save card prompt when the card is to be saved by uploading it to Google Payments. The prompt can be either a bubble or an infobar.">
     Pay quickly on sites and apps across devices using cards you have saved with Google.
   </message>
+  <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC" desc="Text displayed in the Autofill save credit card prompt explaining that the card needs additional CVC information in order to be saved to Google Payments.">
+    Please verify your CVC
+  </message>
 
   <!-- Autofill credit card suggestion popup -->
   <message name="IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_ABBR" desc="Abbreviated label for credit card expiration date. [CHAR-LIMIT=32]">
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index eb267fb1..f5a610b1 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -287,6 +287,12 @@
   return OK;
 }
 
+DataStore::Status TestDataStore::RecreateDB() {
+  map_.clear();
+
+  return OK;
+}
+
 DataReductionProxyTestContext::Builder::Builder()
     : params_flags_(DataReductionProxyParams::kPromoAllowed),
       params_definitions_(TestDataReductionProxyParams::HAS_EVERYTHING),
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
index e42557f3..a6eb403 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -261,6 +261,8 @@
 
   DataStore::Status Delete(base::StringPiece key) override;
 
+  DataStore::Status RecreateDB() override;
+
   std::map<std::string, std::string>* map() { return &map_; }
 
  private:
diff --git a/components/data_reduction_proxy/core/browser/data_store.cc b/components/data_reduction_proxy/core/browser/data_store.cc
index eacf50c..782a194 100644
--- a/components/data_reduction_proxy/core/browser/data_store.cc
+++ b/components/data_reduction_proxy/core/browser/data_store.cc
@@ -28,4 +28,8 @@
   return DataStore::Status::OK;
 }
 
+DataStore::Status DataStore::RecreateDB() {
+  return DataStore::Status::OK;
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_store.h b/components/data_reduction_proxy/core/browser/data_store.h
index 1c254c2..f275da7 100644
--- a/components/data_reduction_proxy/core/browser/data_store.h
+++ b/components/data_reduction_proxy/core/browser/data_store.h
@@ -36,6 +36,9 @@
 
   virtual Status Delete(base::StringPiece key);
 
+  // Deletes the LevelDB and recreates it.
+  virtual Status RecreateDB();
+
  private:
   DISALLOW_COPY_AND_ASSIGN(DataStore);
 };
diff --git a/components/data_reduction_proxy/core/browser/data_store_impl.cc b/components/data_reduction_proxy/core/browser/data_store_impl.cc
index 76903be..3c7c180f 100644
--- a/components/data_reduction_proxy/core/browser/data_store_impl.cc
+++ b/components/data_reduction_proxy/core/browser/data_store_impl.cc
@@ -117,7 +117,9 @@
   leveldb::Options options;
   options.create_if_missing = true;
   options.paranoid_checks = true;
-  options.reuse_logs = leveldb_env::kDefaultLogReuseOptionValue;
+  // Deletes to buckets not found are stored in the log. Use a new log so that
+  // these log entries are deleted.
+  options.reuse_logs = false;
   std::string db_name = profile_path_.Append(kDBName).AsUTF8Unsafe();
   leveldb::DB* dbptr = nullptr;
   Status status =
@@ -144,14 +146,13 @@
   return status;
 }
 
-void DataStoreImpl::RecreateDB() {
+DataStore::Status DataStoreImpl::RecreateDB() {
   DCHECK(sequence_checker_.CalledOnValidSequence());
 
-  LOG(WARNING) << "Deleting corrupt Data Reduction Proxy LevelDB";
   db_.reset(nullptr);
   base::DeleteFile(profile_path_.Append(kDBName), true);
 
-  OpenDB();
+  return OpenDB();
 }
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_store_impl.h b/components/data_reduction_proxy/core/browser/data_store_impl.h
index b7aeca2..950de079 100644
--- a/components/data_reduction_proxy/core/browser/data_store_impl.h
+++ b/components/data_reduction_proxy/core/browser/data_store_impl.h
@@ -36,14 +36,14 @@
 
   Status Delete(base::StringPiece key) override;
 
+  // Deletes the LevelDB and recreates it. This method is called if any DB call
+  // returns a |CORRUPTED| status or the database is cleared.
+  Status RecreateDB() override;
+
  private:
   // Opens the underlying LevelDB for read and write.
   Status OpenDB();
 
-  // Deletes the LevelDB and recreates it. This method is called if any DB call
-  // returns a |CORRUPTED| status.
-  void RecreateDB();
-
   // The underlying LevelDB used by this implementation.
   std::unique_ptr<leveldb::DB> db_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_usage_store.cc b/components/data_reduction_proxy/core/browser/data_usage_store.cc
index fb89dd0..41f5fb6 100644
--- a/components/data_reduction_proxy/core/browser/data_usage_store.cc
+++ b/components/data_reduction_proxy/core/browser/data_usage_store.cc
@@ -152,10 +152,16 @@
 }
 
 void DataUsageStore::DeleteHistoricalDataUsage() {
-  for (int i = 0; i < kNumDataUsageBuckets; ++i)
-    db_->Delete(DbKeyForBucketIndex(i));
+  std::string current_index_string;
+  DataStore::Status index_read_status =
+      db_->Get(kCurrentBucketIndexKey, &current_index_string);
 
-  db_->Delete(kCurrentBucketIndexKey);
+  // If the index doesn't exist, then no buckets have been written and the
+  // data usage doesn't need to be deleted.
+  if (index_read_status != DataStore::Status::OK)
+    return;
+
+  db_->RecreateDB();
 }
 
 void DataUsageStore::DeleteBrowsingHistory(const base::Time& start,
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn
index e60183b..b288937 100644
--- a/components/history/core/browser/BUILD.gn
+++ b/components/history/core/browser/BUILD.gn
@@ -192,7 +192,6 @@
     "history_backend_db_unittest.cc",
     "history_backend_unittest.cc",
     "history_database_unittest.cc",
-    "history_model_worker_unittest.cc",
     "history_querying_unittest.cc",
     "history_service_unittest.cc",
     "history_types_unittest.cc",
diff --git a/components/history/core/browser/history_model_worker.cc b/components/history/core/browser/history_model_worker.cc
index ad3f991..72b843d 100644
--- a/components/history/core/browser/history_model_worker.cc
+++ b/components/history/core/browser/history_model_worker.cc
@@ -6,19 +6,30 @@
 
 #include <utility>
 
-#include "base/memory/ptr_util.h"
+#include "base/synchronization/waitable_event.h"
 #include "components/history/core/browser/history_db_task.h"
 #include "components/history/core/browser/history_service.h"
+#include "components/sync/base/scoped_event_signal.h"
 
 namespace browser_sync {
 
 class WorkerTask : public history::HistoryDBTask {
  public:
-  WorkerTask(base::OnceClosure work) : work_(std::move(work)) {}
+  WorkerTask(const syncer::WorkCallback& work,
+             syncer::ScopedEventSignal scoped_event_signal,
+             syncer::SyncerError* error)
+      : work_(work),
+        scoped_event_signal_(std::move(scoped_event_signal)),
+        error_(error) {}
 
   bool RunOnDBThread(history::HistoryBackend* backend,
                      history::HistoryDatabase* db) override {
-    std::move(work_).Run();
+    // Signal the completion event at the end of this scope.
+    auto scoped_event_signal = std::move(scoped_event_signal_);
+
+    // Run the task.
+    *error_ = work_.Run();
+
     return true;
   }
 
@@ -26,12 +37,34 @@
   // any code asynchronously on the main thread after completion.
   void DoneRunOnMainThread() override {}
 
- private:
-  // A OnceClosure is deleted right after it runs. This is important to unblock
-  // DoWorkAndWaitUntilDone() right after the task runs.
-  base::OnceClosure work_;
+ protected:
+  ~WorkerTask() override {
+    // The event in |scoped_event_signal_| is signaled at the end of this
+    // scope if this is destroyed before RunOnDBThread runs.
+  }
 
-  DISALLOW_COPY_AND_ASSIGN(WorkerTask);
+  syncer::WorkCallback work_;
+  syncer::ScopedEventSignal scoped_event_signal_;
+  syncer::SyncerError* error_;
+};
+
+class AddDBThreadObserverTask : public history::HistoryDBTask {
+ public:
+  explicit AddDBThreadObserverTask(base::Closure register_callback)
+     : register_callback_(register_callback) {}
+
+  bool RunOnDBThread(history::HistoryBackend* backend,
+                     history::HistoryDatabase* db) override {
+    register_callback_.Run();
+    return true;
+  }
+
+  void DoneRunOnMainThread() override {}
+
+ private:
+  ~AddDBThreadObserverTask() override {}
+
+  base::Closure register_callback_;
 };
 
 namespace {
@@ -40,11 +73,18 @@
 // thread.
 void PostWorkerTask(
     const base::WeakPtr<history::HistoryService>& history_service,
-    base::OnceClosure work,
-    base::CancelableTaskTracker* cancelable_tracker) {
+    const syncer::WorkCallback& work,
+    syncer::ScopedEventSignal scoped_event_signal,
+    base::CancelableTaskTracker* cancelable_tracker,
+    syncer::SyncerError* error) {
   if (history_service.get()) {
-    history_service->ScheduleDBTask(
-        base::MakeUnique<WorkerTask>(std::move(work)), cancelable_tracker);
+    std::unique_ptr<history::HistoryDBTask> task(
+        new WorkerTask(work, std::move(scoped_event_signal), error));
+    history_service->ScheduleDBTask(std::move(task), cancelable_tracker);
+  } else {
+    *error = syncer::CANNOT_DO_WORK;
+    // The event in |scoped_event_signal| is signaled at the end of this
+    // scope.
   }
 }
 
@@ -59,6 +99,27 @@
   cancelable_tracker_.reset(new base::CancelableTaskTracker);
 }
 
+syncer::SyncerError HistoryModelWorker::DoWorkAndWaitUntilDoneImpl(
+    const syncer::WorkCallback& work) {
+  syncer::SyncerError error = syncer::UNSET;
+
+  // Signaled after the task runs or when it is abandoned.
+  base::WaitableEvent work_done_or_abandoned(
+      base::WaitableEvent::ResetPolicy::AUTOMATIC,
+      base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+  if (ui_thread_->PostTask(FROM_HERE,
+                           base::Bind(&PostWorkerTask, history_service_, work,
+                                      base::Passed(syncer::ScopedEventSignal(
+                                          &work_done_or_abandoned)),
+                                      cancelable_tracker_.get(), &error))) {
+    work_done_or_abandoned.Wait();
+  } else {
+    error = syncer::CANNOT_DO_WORK;
+  }
+  return error;
+}
+
 syncer::ModelSafeGroup HistoryModelWorker::GetModelSafeGroup() {
   return syncer::GROUP_HISTORY;
 }
@@ -77,10 +138,4 @@
   ui_thread_->DeleteSoon(FROM_HERE, cancelable_tracker_.release());
 }
 
-void HistoryModelWorker::ScheduleWork(base::OnceClosure work) {
-  ui_thread_->PostTask(FROM_HERE, base::Bind(&PostWorkerTask, history_service_,
-                                             base::Passed(std::move(work)),
-                                             cancelable_tracker_.get()));
-}
-
 }  // namespace browser_sync
diff --git a/components/history/core/browser/history_model_worker.h b/components/history/core/browser/history_model_worker.h
index f72b00af..6421c64 100644
--- a/components/history/core/browser/history_model_worker.h
+++ b/components/history/core/browser/history_model_worker.h
@@ -32,11 +32,13 @@
   syncer::ModelSafeGroup GetModelSafeGroup() override;
   bool IsOnModelThread() override;
 
+ protected:
+  syncer::SyncerError DoWorkAndWaitUntilDoneImpl(
+      const syncer::WorkCallback& work) override;
+
  private:
   ~HistoryModelWorker() override;
 
-  void ScheduleWork(base::OnceClosure work) override;
-
   const base::WeakPtr<history::HistoryService> history_service_;
 
   // A reference to the UI thread's task runner.
diff --git a/components/history/core/browser/history_model_worker_unittest.cc b/components/history/core/browser/history_model_worker_unittest.cc
deleted file mode 100644
index 1877558..0000000
--- a/components/history/core/browser/history_model_worker_unittest.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/history/core/browser/history_model_worker.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/atomic_flag.h"
-#include "base/test/test_simple_task_runner.h"
-#include "base/test/test_timeouts.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread.h"
-#include "components/history/core/browser/history_db_task.h"
-#include "components/history/core/browser/history_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace browser_sync {
-namespace {
-
-class HistoryServiceMock : public history::HistoryService {
- public:
-  HistoryServiceMock(scoped_refptr<base::SingleThreadTaskRunner> history_thread)
-      : history_thread_(std::move(history_thread)) {}
-
-  base::CancelableTaskTracker::TaskId ScheduleDBTask(
-      std::unique_ptr<history::HistoryDBTask> task,
-      base::CancelableTaskTracker* tracker) override {
-    history::HistoryDBTask* task_raw = task.get();
-    history_thread_->PostTaskAndReply(
-        FROM_HERE,
-        base::Bind(base::IgnoreResult(&history::HistoryDBTask::RunOnDBThread),
-                   base::Unretained(task_raw), nullptr, nullptr),
-        base::Bind(&history::HistoryDBTask::DoneRunOnMainThread,
-                   base::Passed(std::move(task))));
-    return base::CancelableTaskTracker::kBadTaskId;  // Unused.
-  }
-
- private:
-  const scoped_refptr<base::SingleThreadTaskRunner> history_thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistoryServiceMock);
-};
-
-syncer::WorkCallback ClosureToWorkCallback(base::Closure work) {
-  return base::Bind(
-      [](base::Closure work) {
-        work.Run();
-        return syncer::SYNCER_OK;
-      },
-      std::move(work));
-}
-
-class HistoryModelWorkerTest : public testing::Test {
- public:
-  HistoryModelWorkerTest()
-      : sync_thread_("SyncThreadForTest"),
-        history_service_(history_thread_),
-        history_service_factory_(&history_service_) {
-    sync_thread_.Start();
-    worker_ = new HistoryModelWorker(history_service_factory_.GetWeakPtr(),
-                                     ui_thread_);
-  }
-
-  ~HistoryModelWorkerTest() override {
-    // HistoryModelWorker posts a cleanup task to the UI thread in its
-    // destructor. Run it to prevent a leak.
-    worker_ = nullptr;
-    ui_thread_->RunUntilIdle();
-  }
-
- protected:
-  void DoWorkAndWaitUntilDoneOnSyncThread(base::Closure work) {
-    sync_thread_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(
-            base::IgnoreResult(&HistoryModelWorker::DoWorkAndWaitUntilDone),
-            worker_, base::Passed(ClosureToWorkCallback(work))));
-    sync_thread_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&base::AtomicFlag::Set,
-                              base::Unretained(&sync_thread_unblocked_)));
-  }
-
-  const scoped_refptr<base::TestSimpleTaskRunner> ui_thread_ =
-      new base::TestSimpleTaskRunner();
-  scoped_refptr<base::TestSimpleTaskRunner> history_thread_ =
-      new base::TestSimpleTaskRunner();
-  base::AtomicFlag sync_thread_unblocked_;
-  base::Thread sync_thread_;
-  HistoryServiceMock history_service_;
-  scoped_refptr<HistoryModelWorker> worker_;
-
- private:
-  base::WeakPtrFactory<HistoryServiceMock> history_service_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistoryModelWorkerTest);
-};
-
-}  // namespace
-
-TEST_F(HistoryModelWorkerTest, DoWorkAndWaitUntilDone) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to the UI thread and run it. Expect this task
-  // to post another task to the history DB thread and run it.
-  while (!ui_thread_->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  ui_thread_->RunUntilIdle();
-  EXPECT_TRUE(history_thread_->HasPendingTask());
-  history_thread_->RunUntilIdle();
-
-  EXPECT_TRUE(did_work);
-
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(HistoryModelWorkerTest, DoWorkAndWaitUntilDoneRequestStopBeforeRunWork) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to the UI thread and run it.
-  while (!ui_thread_->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  ui_thread_->RunUntilIdle();
-
-  // Stop the worker.
-  worker_->RequestStop();
-
-  // The WorkCallback should not run on the history DB thread.
-  EXPECT_TRUE(history_thread_->HasPendingTask());
-  history_thread_->RunUntilIdle();
-  EXPECT_FALSE(did_work);
-
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(HistoryModelWorkerTest,
-       DoWorkAndWaitUntilDoneRequestStopBeforeUITaskRun) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to the UI thread.
-  while (!ui_thread_->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-
-  // Stop the worker.
-  worker_->RequestStop();
-
-  // Stopping the worker should unblock the sync thread.
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(HistoryModelWorkerTest, DoWorkAndWaitUntilDoneDeleteWorkBeforeRun) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to the UI thread. Delete it before it can run.
-  while (!ui_thread_->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  ui_thread_->ClearPendingTasks();
-
-  EXPECT_FALSE(did_work);
-
-  // Deleting the task should have unblocked the sync thread.
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(HistoryModelWorkerTest, DoWorkAndWaitUntilDoneRequestStopDuringRunWork) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](scoped_refptr<HistoryModelWorker> worker,
-         base::AtomicFlag* sync_thread_unblocked, bool* did_work) {
-        worker->RequestStop();
-        base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
-
-        // The sync thread should not be unblocked while a WorkCallback is
-        // running.
-        EXPECT_FALSE(sync_thread_unblocked->IsSet());
-
-        *did_work = true;
-      },
-      worker_, base::Unretained(&sync_thread_unblocked_),
-      base::Unretained(&did_work)));
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to the UI thread and run it.
-  while (!ui_thread_->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  ui_thread_->RunUntilIdle();
-
-  // Expect a task to be posted to the history DB thread. Run it.
-  EXPECT_TRUE(history_thread_->HasPendingTask());
-  history_thread_->RunUntilIdle();
-  EXPECT_TRUE(did_work);
-
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-}  // namespace browser_sync
diff --git a/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc b/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
index 82af8ed..4b5a0e1 100644
--- a/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
+++ b/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.cc
@@ -145,6 +145,96 @@
   return base::TimeDelta::FromSecondsD(value_hours * 3600.0);
 }
 
+void ReportTimeUntilFirstSoftTrigger(UserClassifier::UserClass user_class,
+                                     base::TimeDelta time_until_first_trigger) {
+  switch (user_class) {
+    case UserClassifier::UserClass::RARE_NTP_USER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilFirstSoftTrigger.RareNTPUser",
+          time_until_first_trigger, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+    case UserClassifier::UserClass::ACTIVE_NTP_USER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilFirstSoftTrigger."
+          "ActiveNTPUser",
+          time_until_first_trigger, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+    case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilFirstSoftTrigger."
+          "ActiveSuggestionsConsumer",
+          time_until_first_trigger, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+  }
+}
+
+void ReportTimeUntilSoftFetch(UserClassifier::UserClass user_class,
+                              base::TimeDelta time_until_soft_fetch) {
+  switch (user_class) {
+    case UserClassifier::UserClass::RARE_NTP_USER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilSoftFetch."
+          "RareNTPUser",
+          time_until_soft_fetch, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+    case UserClassifier::UserClass::ACTIVE_NTP_USER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilSoftFetch."
+          "ActiveNTPUser",
+          time_until_soft_fetch, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+    case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilSoftFetch."
+          "ActiveSuggestionsConsumer",
+          time_until_soft_fetch, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+  }
+}
+
+void ReportTimeUntilPersistentFetch(
+    UserClassifier::UserClass user_class,
+    base::TimeDelta time_until_persistent_fetch) {
+  switch (user_class) {
+    case UserClassifier::UserClass::RARE_NTP_USER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilPersistentFetch."
+          "RareNTPUser",
+          time_until_persistent_fetch, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+    case UserClassifier::UserClass::ACTIVE_NTP_USER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilPersistentFetch."
+          "ActiveNTPUser",
+          time_until_persistent_fetch, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+    case UserClassifier::UserClass::ACTIVE_SUGGESTIONS_CONSUMER:
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "NewTabPage.ContentSuggestions.TimeUntilPersistentFetch."
+          "ActiveSuggestionsConsumer",
+          time_until_persistent_fetch, base::TimeDelta::FromSeconds(1),
+          base::TimeDelta::FromDays(7),
+          /*bucket_count=*/50);
+      break;
+  }
+}
+
 }  // namespace
 
 class EulaState : public web_resource::EulaAcceptedNotifier::Observer {
@@ -248,6 +338,7 @@
           profile_prefs,
           RequestThrottler::RequestType::
               CONTENT_SUGGESTION_FETCHER_ACTIVE_SUGGESTIONS_CONSUMER),
+      time_until_first_trigger_reported_(false),
       eula_state_(base::MakeUnique<EulaState>(local_state_prefs, this)),
       profile_prefs_(profile_prefs),
       clock_(std::move(clock)),
@@ -440,8 +531,17 @@
     return;
   }
 
-  if (trigger != TriggerType::PERSISTENT_SCHEDULER_WAKE_UP &&
-      !ShouldRefetchInTheBackgroundNow()) {
+  bool is_soft = trigger != TriggerType::PERSISTENT_SCHEDULER_WAKE_UP;
+  const base::Time last_fetch_attempt_time = base::Time::FromInternalValue(
+      profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt));
+
+  if (is_soft && !time_until_first_trigger_reported_) {
+    time_until_first_trigger_reported_ = true;
+    ReportTimeUntilFirstSoftTrigger(user_classifier_->GetUserClass(),
+                                    clock_->Now() - last_fetch_attempt_time);
+  }
+
+  if (is_soft && !ShouldRefetchInTheBackgroundNow(last_fetch_attempt_time)) {
     return;
   }
 
@@ -449,6 +549,14 @@
     return;
   }
 
+  if (is_soft) {
+    ReportTimeUntilSoftFetch(user_classifier_->GetUserClass(),
+                             clock_->Now() - last_fetch_attempt_time);
+  } else {
+    ReportTimeUntilPersistentFetch(user_classifier_->GetUserClass(),
+                                   clock_->Now() - last_fetch_attempt_time);
+  }
+
   UMA_HISTOGRAM_ENUMERATION(
       "NewTabPage.ContentSuggestions.BackgroundFetchTrigger",
       static_cast<int>(trigger), static_cast<int>(TriggerType::COUNT));
@@ -459,10 +567,8 @@
       base::Unretained(this)));
 }
 
-bool RemoteSuggestionsSchedulerImpl::ShouldRefetchInTheBackgroundNow() {
-  const base::Time last_fetch_attempt_time = base::Time::FromInternalValue(
-      profile_prefs_->GetInt64(prefs::kSnippetLastFetchAttempt));
-
+bool RemoteSuggestionsSchedulerImpl::ShouldRefetchInTheBackgroundNow(
+    base::Time last_fetch_attempt_time) {
   // If we have no persistent scheduler to ask, err on the side of caution.
   bool wifi = false;
   if (persistent_scheduler_) {
@@ -523,6 +629,7 @@
 void RemoteSuggestionsSchedulerImpl::OnFetchCompleted(Status fetch_status) {
   profile_prefs_->SetInt64(prefs::kSnippetLastFetchAttempt,
                            clock_->Now().ToInternalValue());
+  time_until_first_trigger_reported_ = false;
 
   // Reschedule after a fetch. The persistent schedule is applied only after a
   // successful fetch. After a failed fetch, we want to keep the previous
diff --git a/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h b/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h
index 7fe94d6..9921f51 100644
--- a/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h
+++ b/components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h
@@ -93,7 +93,7 @@
 
   // Checks whether it is time to perform a soft background fetch, according to
   // |schedule|.
-  bool ShouldRefetchInTheBackgroundNow();
+  bool ShouldRefetchInTheBackgroundNow(base::Time last_fetch_attempt_time);
 
   // Returns whether background fetching (for the given |trigger|) is disabled.
   bool BackgroundFetchesDisabled(TriggerType trigger) const;
@@ -144,6 +144,9 @@
   RequestThrottler request_throttler_active_ntp_user_;
   RequestThrottler request_throttler_active_suggestions_consumer_;
 
+  // To make sure we only report the first trigger to UMA.
+  bool time_until_first_trigger_reported_;
+
   // We should not fetch in background before EULA gets accepted.
   std::unique_ptr<EulaState> eula_state_;
 
diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.cc b/components/open_from_clipboard/clipboard_recent_content_generic.cc
index 87c6542..15ffa42 100644
--- a/components/open_from_clipboard/clipboard_recent_content_generic.cc
+++ b/components/open_from_clipboard/clipboard_recent_content_generic.cc
@@ -10,17 +10,12 @@
 ClipboardRecentContentGeneric::ClipboardRecentContentGeneric() {}
 
 bool ClipboardRecentContentGeneric::GetRecentURLFromClipboard(GURL* url) {
-  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
-  base::Time last_modified_time = clipboard->GetClipboardLastModifiedTime();
-  if (!last_modified_time_to_suppress_.is_null() &&
-      (last_modified_time == last_modified_time_to_suppress_))
-    return false;
-
   if (GetClipboardContentAge() > MaximumAgeOfClipboard())
     return false;
 
   // Get and clean up the clipboard before processing.
   std::string gurl_string;
+  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
   clipboard->ReadAsciiText(ui::CLIPBOARD_TYPE_COPY_PASTE, &gurl_string);
   base::TrimWhitespaceASCII(gurl_string, base::TrimPositions::TRIM_ALL,
                             &gurl_string);
@@ -53,7 +48,7 @@
 
 base::TimeDelta ClipboardRecentContentGeneric::GetClipboardContentAge() const {
   const base::Time last_modified_time =
-      ui::Clipboard::GetForCurrentThread()->GetClipboardLastModifiedTime();
+      ui::Clipboard::GetForCurrentThread()->GetLastModifiedTime();
   const base::Time now = base::Time::Now();
   // In case of system clock change, assume the last modified time is now.
   // (Don't return a negative age, i.e., a time in the future.)
@@ -64,9 +59,7 @@
 
 void ClipboardRecentContentGeneric::SuppressClipboardContent() {
   // User cleared the user data.  The pasteboard entry must be removed from the
-  // omnibox list.  Do this by suppressing all clipboard content with the
-  // current clipboard content's time.  Then we only suggest the clipboard
-  // content later if the time changed.
-  last_modified_time_to_suppress_ =
-      ui::Clipboard::GetForCurrentThread()->GetClipboardLastModifiedTime();
+  // omnibox list.  Do this by pretending the current clipboard is ancient,
+  // not recent.
+  ui::Clipboard::GetForCurrentThread()->ClearLastModifiedTime();
 }
diff --git a/components/open_from_clipboard/clipboard_recent_content_generic.h b/components/open_from_clipboard/clipboard_recent_content_generic.h
index 60024dc..c0b8704 100644
--- a/components/open_from_clipboard/clipboard_recent_content_generic.h
+++ b/components/open_from_clipboard/clipboard_recent_content_generic.h
@@ -27,11 +27,6 @@
   void SuppressClipboardContent() override;
 
  private:
-  // When told to suppress clipboard content, store the time of the last
-  // modified clipboard and suppress suggestions that correspond to that time.
-  // Set to base::Time() if not suppressing clipboard content.
-  base::Time last_modified_time_to_suppress_;
-
   DISALLOW_COPY_AND_ASSIGN(ClipboardRecentContentGeneric);
 };
 
diff --git a/components/open_from_clipboard/clipboard_recent_content_generic_unittest.cc b/components/open_from_clipboard/clipboard_recent_content_generic_unittest.cc
index 1101c5e..83b9ac9 100644
--- a/components/open_from_clipboard/clipboard_recent_content_generic_unittest.cc
+++ b/components/open_from_clipboard/clipboard_recent_content_generic_unittest.cc
@@ -65,8 +65,8 @@
   for (size_t i = 0; i < arraysize(test_data); ++i) {
     test_clipboard_->WriteText(test_data[i].clipboard.data(),
                                test_data[i].clipboard.length());
-    test_clipboard_->SetClipboardLastModifiedTime(
-        now - base::TimeDelta::FromSeconds(10));
+    test_clipboard_->SetLastModifiedTime(now -
+                                         base::TimeDelta::FromSeconds(10));
     GURL url;
     EXPECT_EQ(test_data[i].expected_get_recent_url_value,
               recent_content.GetRecentURLFromClipboard(&url))
@@ -79,13 +79,11 @@
   base::Time now = base::Time::Now();
   std::string text = "http://example.com/";
   test_clipboard_->WriteText(text.data(), text.length());
-  test_clipboard_->SetClipboardLastModifiedTime(
-      now - base::TimeDelta::FromSeconds(10));
+  test_clipboard_->SetLastModifiedTime(now - base::TimeDelta::FromSeconds(10));
   GURL url;
   EXPECT_TRUE(recent_content.GetRecentURLFromClipboard(&url));
   // If the last modified time is days ago, the URL shouldn't be suggested.
-  test_clipboard_->SetClipboardLastModifiedTime(now -
-                                                base::TimeDelta::FromDays(2));
+  test_clipboard_->SetLastModifiedTime(now - base::TimeDelta::FromDays(2));
   EXPECT_FALSE(recent_content.GetRecentURLFromClipboard(&url));
 }
 
@@ -94,8 +92,7 @@
   base::Time now = base::Time::Now();
   std::string text = " whether URL or not should not matter here.";
   test_clipboard_->WriteText(text.data(), text.length());
-  test_clipboard_->SetClipboardLastModifiedTime(
-      now - base::TimeDelta::FromSeconds(32));
+  test_clipboard_->SetLastModifiedTime(now - base::TimeDelta::FromSeconds(32));
   base::TimeDelta age = recent_content.GetClipboardContentAge();
   // It's possible the GetClipboardContentAge() took some time, so allow a
   // little slop (5 seconds) in this comparison; don't check for equality.
@@ -109,8 +106,7 @@
   base::Time now = base::Time::Now();
   std::string text = "http://example.com/";
   test_clipboard_->WriteText(text.data(), text.length());
-  test_clipboard_->SetClipboardLastModifiedTime(
-      now - base::TimeDelta::FromSeconds(10));
+  test_clipboard_->SetLastModifiedTime(now - base::TimeDelta::FromSeconds(10));
   GURL url;
   EXPECT_TRUE(recent_content.GetRecentURLFromClipboard(&url));
 
@@ -121,6 +117,6 @@
   // If the clipboard changes, even if to the same thing again, the content
   // should be suggested again.
   test_clipboard_->WriteText(text.data(), text.length());
-  test_clipboard_->SetClipboardLastModifiedTime(now);
+  test_clipboard_->SetLastModifiedTime(now);
   EXPECT_TRUE(recent_content.GetRecentURLFromClipboard(&url));
 }
diff --git a/components/password_manager/sync/browser/password_model_worker.cc b/components/password_manager/sync/browser/password_model_worker.cc
index 997a0b1c..81fb889b 100644
--- a/components/password_manager/sync/browser/password_model_worker.cc
+++ b/components/password_manager/sync/browser/password_model_worker.cc
@@ -4,18 +4,60 @@
 
 #include "components/password_manager/sync/browser/password_model_worker.h"
 
-#include <utility>
-
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/synchronization/waitable_event.h"
 #include "components/password_manager/core/browser/password_store.h"
+#include "components/sync/base/scoped_event_signal.h"
 
 namespace browser_sync {
 
+namespace {
+
+void CallDoWorkAndSignalEvent(const syncer::WorkCallback& work,
+                              syncer::ScopedEventSignal scoped_event_signal,
+                              syncer::SyncerError* error_info) {
+  *error_info = work.Run();
+  // The event in |scoped_event_signal| is signaled at the end of this scope.
+}
+
+}  // namespace
+
 PasswordModelWorker::PasswordModelWorker(
     const scoped_refptr<password_manager::PasswordStore>& password_store)
     : password_store_(password_store) {
   DCHECK(password_store.get());
 }
 
+syncer::SyncerError PasswordModelWorker::DoWorkAndWaitUntilDoneImpl(
+    const syncer::WorkCallback& work) {
+  syncer::SyncerError error = syncer::UNSET;
+
+  // Signaled when the task is deleted, i.e. after it runs or when it is
+  // abandoned.
+  base::WaitableEvent work_done_or_abandoned(
+      base::WaitableEvent::ResetPolicy::AUTOMATIC,
+      base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+  bool scheduled = false;
+  {
+    base::AutoLock lock(password_store_lock_);
+    if (!password_store_.get())
+      return syncer::CANNOT_DO_WORK;
+
+    scheduled = password_store_->ScheduleTask(base::Bind(
+        &CallDoWorkAndSignalEvent, work,
+        base::Passed(syncer::ScopedEventSignal(&work_done_or_abandoned)),
+        &error));
+  }
+
+  if (scheduled)
+    work_done_or_abandoned.Wait();
+  else
+    error = syncer::CANNOT_DO_WORK;
+  return error;
+}
+
 syncer::ModelSafeGroup PasswordModelWorker::GetModelSafeGroup() {
   return syncer::GROUP_PASSWORD;
 }
@@ -29,15 +71,6 @@
 
 PasswordModelWorker::~PasswordModelWorker() {}
 
-void PasswordModelWorker::ScheduleWork(base::OnceClosure work) {
-  base::AutoLock lock(password_store_lock_);
-  if (password_store_) {
-    password_store_->ScheduleTask(
-        base::Bind([](base::OnceClosure work) { std::move(work).Run(); },
-                   base::Passed(std::move(work))));
-  }
-}
-
 void PasswordModelWorker::RequestStop() {
   ModelSafeWorker::RequestStop();
 
diff --git a/components/password_manager/sync/browser/password_model_worker.h b/components/password_manager/sync/browser/password_model_worker.h
index 08405739..eb45efc 100644
--- a/components/password_manager/sync/browser/password_model_worker.h
+++ b/components/password_manager/sync/browser/password_model_worker.h
@@ -28,11 +28,13 @@
   bool IsOnModelThread() override;
   void RequestStop() override;
 
+ protected:
+  syncer::SyncerError DoWorkAndWaitUntilDoneImpl(
+      const syncer::WorkCallback& work) override;
+
  private:
   ~PasswordModelWorker() override;
 
-  void ScheduleWork(base::OnceClosure work) override;
-
   // |password_store_| is used on password thread but released on UI thread.
   // Protected by |password_store_lock_|.
   base::Lock password_store_lock_;
diff --git a/components/payments/content/payment_request_spec.cc b/components/payments/content/payment_request_spec.cc
index bec17e2..6fbfc5f6 100644
--- a/components/payments/content/payment_request_spec.cc
+++ b/components/payments/content/payment_request_spec.cc
@@ -127,6 +127,13 @@
   return formatter->formatted_currency_code();
 }
 
+void PaymentRequestSpec::StartWaitingForUpdateWith(
+    PaymentRequestSpec::UpdateReason reason) {
+  for (auto& observer : observers_) {
+    observer.OnStartUpdating(reason);
+  }
+}
+
 void PaymentRequestSpec::PopulateValidatedMethodData(
     const std::vector<mojom::PaymentMethodDataPtr>& method_data_mojom) {
   if (method_data_mojom.empty()) {
diff --git a/components/payments/content/payment_request_spec.h b/components/payments/content/payment_request_spec.h
index 39bbda8..de0187a 100644
--- a/components/payments/content/payment_request_spec.h
+++ b/components/payments/content/payment_request_spec.h
@@ -25,6 +25,14 @@
 // certain occasions by the merchant (see API).
 class PaymentRequestSpec : public PaymentOptionsProvider {
  public:
+  // This enum represents which bit of information was changed to trigger an
+  // update roundtrip with the website.
+  enum class UpdateReason {
+    NONE,
+    SHIPPING_OPTION,
+    SHIPPING_ADDRESS,
+  };
+
   // Any class call add itself as Observer via AddObserver() and receive
   // notification about spec events.
   class Observer {
@@ -32,6 +40,11 @@
     // Called when the provided spec (details, options, method_data) is invalid.
     virtual void OnInvalidSpecProvided() = 0;
 
+    // Called when the website is notified that the user selected shipping
+    // options or a shipping address. This will be followed by a call to
+    // OnSpecUpdated or the PaymentRequest being aborted due to a timeout.
+    virtual void OnStartUpdating(UpdateReason reason) {}
+
     // Called when the provided spec has changed.
     virtual void OnSpecUpdated() = 0;
 
@@ -87,6 +100,8 @@
 
   const mojom::PaymentDetails& details() const { return *details_.get(); }
 
+  void StartWaitingForUpdateWith(UpdateReason reason);
+
  private:
   friend class PaymentRequestDialogView;
   void add_observer_for_testing(Observer* observer_for_testing) {
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc
index 9f009bf..c3f1526 100644
--- a/components/payments/content/payment_request_state.cc
+++ b/components/payments/content/payment_request_state.cc
@@ -100,6 +100,8 @@
 
 void PaymentRequestState::SetSelectedShippingOption(
     const std::string& shipping_option_id) {
+  spec_->StartWaitingForUpdateWith(
+      PaymentRequestSpec::UpdateReason::SHIPPING_OPTION);
   // This will inform the merchant and will lead to them calling updateWith with
   // new PaymentDetails.
   delegate_->OnShippingOptionIdSelected(shipping_option_id);
@@ -107,6 +109,8 @@
 
 void PaymentRequestState::SetSelectedShippingProfile(
     autofill::AutofillProfile* profile) {
+  spec_->StartWaitingForUpdateWith(
+      PaymentRequestSpec::UpdateReason::SHIPPING_ADDRESS);
   selected_shipping_profile_ = profile;
   UpdateIsReadyToPayAndNotifyObservers();
   delegate_->OnShippingAddressSelected(
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h
index 85c850e..c3330eb 100644
--- a/components/payments/core/journey_logger.h
+++ b/components/payments/core/journey_logger.h
@@ -65,7 +65,8 @@
     EVENT_SHOWN = 1 << 0,
     EVENT_PAY_CLICKED = 1 << 1,
     EVENT_RECEIVED_INSTRUMENT_DETAILS = 1 << 2,
-    EVENT_MAX = 8,
+    EVENT_SKIPPED_SHOW = 1 << 3,
+    EVENT_MAX = 16,
   };
 
   // Used to mesure the impact of the CanMakePayment return value on whether the
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index ab0ba57..a4db5e1 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -367,12 +367,12 @@
 }
 
 bool TemplateURLService::IsPrepopulatedOrCreatedByPolicy(
-    const TemplateURL* t_url) {
+    const TemplateURL* t_url) const {
   return (t_url->prepopulate_id() > 0 || t_url->created_by_policy()) &&
       t_url->SupportsReplacement(search_terms_data());
 }
 
-bool TemplateURLService::ShowInDefaultList(const TemplateURL* t_url) {
+bool TemplateURLService::ShowInDefaultList(const TemplateURL* t_url) const {
   return t_url == default_search_provider_ ||
       IsPrepopulatedOrCreatedByPolicy(t_url);
 }
@@ -570,7 +570,7 @@
     NotifyObservers();
 }
 
-bool TemplateURLService::CanMakeDefault(const TemplateURL* url) {
+bool TemplateURLService::CanMakeDefault(const TemplateURL* url) const {
   return
       ((default_search_provider_source_ == DefaultSearchManager::FROM_USER) ||
        (default_search_provider_source_ ==
@@ -621,7 +621,7 @@
       default_provider->IsSearchURL(url, search_terms_data());
 }
 
-bool TemplateURLService::IsExtensionControlledDefaultSearch() {
+bool TemplateURLService::IsExtensionControlledDefaultSearch() const {
   return default_search_provider_source_ ==
       DefaultSearchManager::FROM_EXTENSION;
 }
@@ -850,8 +850,11 @@
 
 base::string16 TemplateURLService::GetKeywordShortName(
     const base::string16& keyword,
-    bool* is_omnibox_api_extension_keyword) {
-  const TemplateURL* template_url = GetTemplateURLForKeyword(keyword);
+    bool* is_omnibox_api_extension_keyword) const {
+  // TODO(jeffschiller): Make GetTemplateURLForKeyword const and remove the
+  // const_cast.
+  const TemplateURL* template_url =
+      const_cast<TemplateURLService*>(this)->GetTemplateURLForKeyword(keyword);
 
   // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService
   // to track changes to the model, this should become a DCHECK.
@@ -1629,7 +1632,7 @@
 }
 
 bool TemplateURLService::CanAddAutogeneratedKeywordForHost(
-    const std::string& host) {
+    const std::string& host) const {
   const TemplateURLSet* urls = provider_map_->GetURLsForHost(host);
   if (!urls)
     return true;
@@ -1640,7 +1643,7 @@
   return true;
 }
 
-bool TemplateURLService::CanReplace(const TemplateURL* t_url) {
+bool TemplateURLService::CanReplace(const TemplateURL* t_url) const {
   return !ShowInDefaultList(t_url) && t_url->safe_for_autoreplace();
 }
 
@@ -2230,10 +2233,14 @@
   return keyword_candidate;
 }
 
-bool TemplateURLService::IsLocalTemplateURLBetter(const TemplateURL* local_turl,
-                                                  const TemplateURL* sync_turl,
-                                                  bool prefer_local_default) {
-  DCHECK(GetTemplateURLForGUID(local_turl->sync_guid()));
+bool TemplateURLService::IsLocalTemplateURLBetter(
+    const TemplateURL* local_turl,
+    const TemplateURL* sync_turl,
+    bool prefer_local_default) const {
+  // TODO(jeffschiller): Make GetTemplateURLForKeyword const and remove the
+  // const_cast.
+  DCHECK(const_cast<TemplateURLService*>(this)->GetTemplateURLForGUID(
+          local_turl->sync_guid()));
   return local_turl->last_modified() > sync_turl->last_modified() ||
          local_turl->created_by_policy() ||
          (prefer_local_default && local_turl == GetDefaultSearchProvider());
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h
index b6bb73ba7..4187327 100644
--- a/components/search_engines/template_url_service.h
+++ b/components/search_engines/template_url_service.h
@@ -135,14 +135,14 @@
 
   // Returns whether the engine is a "pre-existing" engine, either from the
   // prepopulate list or created by policy.
-  bool IsPrepopulatedOrCreatedByPolicy(const TemplateURL* template_url);
+  bool IsPrepopulatedOrCreatedByPolicy(const TemplateURL* template_url) const;
 
   // Returns whether |template_url| should be shown in the list of engines
   // most likely to be selected as a default engine. This is meant to highlight
   // the current default, as well as the other most likely choices of default
   // engine, separately from a full list of all TemplateURLs (which might be
   // very long).
-  bool ShowInDefaultList(const TemplateURL* template_url);
+  bool ShowInDefaultList(const TemplateURL* template_url) const;
 
   // Adds to |matches| all TemplateURLs whose keywords begin with |prefix|,
   // sorted shortest-keyword-first. If |supports_replacement_only| is true, only
@@ -248,7 +248,7 @@
   // Return true if the given |url| can be made the default. This returns false
   // regardless of |url| if the default search provider is managed by policy or
   // controlled by an extension.
-  bool CanMakeDefault(const TemplateURL* url);
+  bool CanMakeDefault(const TemplateURL* url) const;
 
   // Set the default search provider.  |url| may be null.
   // This will assert if the default search is managed; the UI should not be
@@ -274,7 +274,7 @@
   }
 
   // Returns true if the default search provider is controlled by an extension.
-  bool IsExtensionControlledDefaultSearch();
+  bool IsExtensionControlledDefaultSearch() const;
 
   // Returns the default search specified in the prepopulated data, if it
   // exists.  If not, returns first URL in |template_urls_|, or NULL if that's
@@ -330,8 +330,9 @@
   // Returns the locale-direction-adjusted short name for the given keyword.
   // Also sets the out param to indicate whether the keyword belongs to an
   // Omnibox extension.
-  base::string16 GetKeywordShortName(const base::string16& keyword,
-                                     bool* is_omnibox_api_extension_keyword);
+  base::string16 GetKeywordShortName(
+      const base::string16& keyword,
+      bool* is_omnibox_api_extension_keyword) const;
 
   // Called by the history service when a URL is visited.
   void OnHistoryURLVisited(const URLVisitedDetails& details);
@@ -543,13 +544,13 @@
 
   // Returns false if there is a TemplateURL that has a search url with the
   // specified host and that TemplateURL has been manually modified.
-  bool CanAddAutogeneratedKeywordForHost(const std::string& host);
+  bool CanAddAutogeneratedKeywordForHost(const std::string& host) const;
 
   // Returns true if the TemplateURL is replaceable. This doesn't look at the
   // uniqueness of the keyword or host and is intended to be called after those
   // checks have been done. This returns true if the TemplateURL doesn't appear
   // in the default list and is marked as safe_for_autoreplace.
-  bool CanReplace(const TemplateURL* t_url);
+  bool CanReplace(const TemplateURL* t_url) const;
 
   // Like GetTemplateURLForKeyword(), but ignores extension-provided keywords.
   TemplateURL* FindNonExtensionTemplateURLForKeyword(
@@ -661,7 +662,7 @@
   //    search provider
   bool IsLocalTemplateURLBetter(const TemplateURL* local_turl,
                                 const TemplateURL* sync_turl,
-                                bool prefer_local_default = true);
+                                bool prefer_local_default = true) const;
 
   // Given two synced TemplateURLs with a conflicting keyword, one of which
   // needs to be added to or updated in the local model (|unapplied_sync_turl|)
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index 3967025..1f81eb0 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -61,6 +61,8 @@
     "base/proto_value_ptr.h",
     "base/report_unrecoverable_error.cc",
     "base/report_unrecoverable_error.h",
+    "base/scoped_event_signal.cc",
+    "base/scoped_event_signal.h",
     "base/stop_source.h",
     "base/sync_features.cc",
     "base/sync_features.h",
@@ -842,6 +844,7 @@
     "base/ordinal_unittest.cc",
     "base/proto_value_ptr_unittest.cc",
     "base/protobuf_unittest.cc",
+    "base/scoped_event_signal_unittest.cc",
     "base/sync_prefs_unittest.cc",
     "base/system_encryptor_unittest.cc",
     "base/unique_position_unittest.cc",
@@ -933,6 +936,7 @@
     "syncable/model_type_unittest.cc",
     "syncable/nigori_util_unittest.cc",
     "syncable/parent_child_index_unittest.cc",
+    "syncable/syncable_delete_journal_unittest.cc",
     "syncable/syncable_enum_conversions_unittest.cc",
     "syncable/syncable_id_unittest.cc",
     "syncable/syncable_unittest.cc",
diff --git a/components/sync/base/scoped_event_signal.cc b/components/sync/base/scoped_event_signal.cc
new file mode 100644
index 0000000..daaaa1d
--- /dev/null
+++ b/components/sync/base/scoped_event_signal.cc
@@ -0,0 +1,34 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/base/scoped_event_signal.h"
+
+#include "base/logging.h"
+#include "base/synchronization/waitable_event.h"
+
+namespace syncer {
+
+ScopedEventSignal::ScopedEventSignal(base::WaitableEvent* event)
+    : event_(event) {
+  DCHECK(event_);
+}
+
+ScopedEventSignal::ScopedEventSignal(ScopedEventSignal&& other)
+    : event_(other.event_) {
+  other.event_ = nullptr;
+}
+
+ScopedEventSignal& ScopedEventSignal::operator=(ScopedEventSignal&& other) {
+  DCHECK(!event_);
+  event_ = other.event_;
+  other.event_ = nullptr;
+  return *this;
+}
+
+ScopedEventSignal::~ScopedEventSignal() {
+  if (event_)
+    event_->Signal();
+}
+
+}  // namespace syncer
diff --git a/components/sync/base/scoped_event_signal.h b/components/sync/base/scoped_event_signal.h
new file mode 100644
index 0000000..d8df104
--- /dev/null
+++ b/components/sync/base/scoped_event_signal.h
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SYNC_BASE_SCOPED_EVENT_SIGNAL_H_
+#define COMPONENTS_SYNC_BASE_SCOPED_EVENT_SIGNAL_H_
+
+#include "base/macros.h"
+
+namespace base {
+class WaitableEvent;
+}
+
+namespace syncer {
+
+// An object which signals a WaitableEvent when it is deleted. Used to wait for
+// a task to run or be abandoned.
+class ScopedEventSignal {
+ public:
+  // |event| will be signaled in the destructor.
+  explicit ScopedEventSignal(base::WaitableEvent* event);
+
+  // This ScopedEventSignal will signal |other|'s WaitableEvent in its
+  // destructor. |other| will not signal anything in its destructor. The
+  // assignment operator cannot be used if this ScopedEventSignal's
+  // WaitableEvent hasn't been moved to another ScopedEventSignal.
+  ScopedEventSignal(ScopedEventSignal&& other);
+  ScopedEventSignal& operator=(ScopedEventSignal&& other);
+
+  ~ScopedEventSignal();
+
+ private:
+  base::WaitableEvent* event_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedEventSignal);
+};
+
+}  // namespace syncer
+
+#endif  // COMPONENTS_SYNC_BASE_SCOPED_EVENT_SIGNAL_H_
diff --git a/components/sync/base/scoped_event_signal_unittest.cc b/components/sync/base/scoped_event_signal_unittest.cc
new file mode 100644
index 0000000..fe65b4b9
--- /dev/null
+++ b/components/sync/base/scoped_event_signal_unittest.cc
@@ -0,0 +1,84 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/base/scoped_event_signal.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/synchronization/waitable_event.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace syncer {
+
+TEST(ScopedEventSignalTest, SignalAtEndOfScope) {
+  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
+                            base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+  {
+    ScopedEventSignal scoped_event_signal(&event);
+    EXPECT_FALSE(event.IsSignaled());
+  }
+
+  EXPECT_TRUE(event.IsSignaled());
+}
+
+TEST(ScopedEventSignalTest, MoveConstructor) {
+  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
+                            base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+  {
+    ScopedEventSignal scoped_event_signal(&event);
+    EXPECT_FALSE(event.IsSignaled());
+
+    {
+      ScopedEventSignal other_scoped_event_signal(
+          std::move(scoped_event_signal));
+      EXPECT_FALSE(event.IsSignaled());
+    }
+
+    // |event| is signaled when |other_scoped_event_signal| is destroyed.
+    EXPECT_TRUE(event.IsSignaled());
+
+    event.Reset();
+  }
+
+  // |event| is not signaled when |scoped_signal_event| is destroyed.
+  EXPECT_FALSE(event.IsSignaled());
+}
+
+TEST(ScopedEventSignalTest, MoveAssignOperator) {
+  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
+                            base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+  {
+    ScopedEventSignal scoped_event_signal_a(&event);
+    EXPECT_FALSE(event.IsSignaled());
+
+    {
+      base::WaitableEvent other_event(
+          base::WaitableEvent::ResetPolicy::MANUAL,
+          base::WaitableEvent::InitialState::NOT_SIGNALED);
+      ScopedEventSignal scoped_event_signal_b(&other_event);
+
+      // Move |scoped_event_signal_b| to |scoped_event_signal_c| because the
+      // assignment operator cannot be used on a ScopedEventSignal which is
+      // already associated with an event.
+      ScopedEventSignal scoped_event_signal_c(std::move(scoped_event_signal_b));
+
+      scoped_event_signal_b = std::move(scoped_event_signal_a);
+      EXPECT_FALSE(event.IsSignaled());
+    }
+
+    // |event| is signaled when |scoped_event_signal_b| is destroyed.
+    EXPECT_TRUE(event.IsSignaled());
+
+    event.Reset();
+  }
+
+  // |event| is not signaled when |scoped_signal_event_a| is destroyed.
+  EXPECT_FALSE(event.IsSignaled());
+}
+
+}  // namespace syncer
diff --git a/components/sync/engine/browser_thread_model_worker.cc b/components/sync/engine/browser_thread_model_worker.cc
index a6d92c5..3b29d85 100644
--- a/components/sync/engine/browser_thread_model_worker.cc
+++ b/components/sync/engine/browser_thread_model_worker.cc
@@ -4,22 +4,45 @@
 
 #include "components/sync/engine/browser_thread_model_worker.h"
 
-#include <utility>
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/synchronization/waitable_event.h"
+
+using base::SingleThreadTaskRunner;
 
 namespace syncer {
 
 BrowserThreadModelWorker::BrowserThreadModelWorker(
-    const scoped_refptr<base::SingleThreadTaskRunner>& runner,
+    const scoped_refptr<SingleThreadTaskRunner>& runner,
     ModelSafeGroup group)
     : runner_(runner), group_(group) {}
 
-void BrowserThreadModelWorker::ScheduleWork(base::OnceClosure work) {
+SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDoneImpl(
+    const WorkCallback& work) {
+  SyncerError error = UNSET;
   if (runner_->BelongsToCurrentThread()) {
     DLOG(WARNING) << "Already on thread " << runner_;
-    std::move(work).Run();
-  } else {
-    runner_->PostTask(FROM_HERE, std::move(work));
+    return work.Run();
   }
+
+  // Signaled when the task is deleted, i.e. after it runs or when it is
+  // abandoned.
+  base::WaitableEvent work_done_or_abandoned(
+      base::WaitableEvent::ResetPolicy::AUTOMATIC,
+      base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+  if (!runner_->PostTask(
+          FROM_HERE,
+          base::Bind(
+              &BrowserThreadModelWorker::CallDoWorkAndSignalTask, this, work,
+              base::Passed(syncer::ScopedEventSignal(&work_done_or_abandoned)),
+              &error))) {
+    DLOG(WARNING) << "Failed to post task to runner " << runner_;
+    error = CANNOT_DO_WORK;
+    return error;
+  }
+  work_done_or_abandoned.Wait();
+  return error;
 }
 
 ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() {
@@ -32,4 +55,14 @@
 
 BrowserThreadModelWorker::~BrowserThreadModelWorker() {}
 
+void BrowserThreadModelWorker::CallDoWorkAndSignalTask(
+    const WorkCallback& work,
+    syncer::ScopedEventSignal scoped_event_signal,
+    SyncerError* error) {
+  DCHECK(runner_->BelongsToCurrentThread());
+  if (!IsStopped())
+    *error = work.Run();
+  // The event in |scoped_event_signal| is signaled at the end of this scope.
+}
+
 }  // namespace syncer
diff --git a/components/sync/engine/browser_thread_model_worker.h b/components/sync/engine/browser_thread_model_worker.h
index 32e63b28..3a121f66 100644
--- a/components/sync/engine/browser_thread_model_worker.h
+++ b/components/sync/engine/browser_thread_model_worker.h
@@ -8,6 +8,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
+#include "components/sync/base/scoped_event_signal.h"
+#include "components/sync/base/syncer_error.h"
 #include "components/sync/engine/model_safe_worker.h"
 
 namespace syncer {
@@ -26,11 +28,16 @@
   ModelSafeGroup GetModelSafeGroup() override;
   bool IsOnModelThread() override;
 
- private:
+ protected:
   ~BrowserThreadModelWorker() override;
 
-  void ScheduleWork(base::OnceClosure work) override;
+  SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) override;
 
+  void CallDoWorkAndSignalTask(const WorkCallback& work,
+                               syncer::ScopedEventSignal scoped_event_signal,
+                               SyncerError* error);
+
+ private:
   scoped_refptr<base::SingleThreadTaskRunner> runner_;
   ModelSafeGroup group_;
 
diff --git a/components/sync/engine/browser_thread_model_worker_unittest.cc b/components/sync/engine/browser_thread_model_worker_unittest.cc
index 98900e6..f4417e9 100644
--- a/components/sync/engine/browser_thread_model_worker_unittest.cc
+++ b/components/sync/engine/browser_thread_model_worker_unittest.cc
@@ -39,10 +39,11 @@
   // DoWork hasn't executed within action_timeout().
   void ScheduleWork() {
     // We wait until the callback is done. So it is safe to use unretained.
+    WorkCallback c = base::Bind(&SyncBrowserThreadModelWorkerTest::DoWork,
+                                base::Unretained(this));
     timer()->Start(FROM_HERE, TestTimeouts::action_timeout(), this,
                    &SyncBrowserThreadModelWorkerTest::Timeout);
-    worker()->DoWorkAndWaitUntilDone(base::BindOnce(
-        &SyncBrowserThreadModelWorkerTest::DoWork, base::Unretained(this)));
+    worker()->DoWorkAndWaitUntilDone(c);
   }
 
   // This is the work that will be scheduled to be done on the DB thread.
diff --git a/components/sync/engine/model_safe_worker.cc b/components/sync/engine/model_safe_worker.cc
index 7735716..530f2065 100644
--- a/components/sync/engine/model_safe_worker.cc
+++ b/components/sync/engine/model_safe_worker.cc
@@ -4,9 +4,6 @@
 
 #include "components/sync/engine/model_safe_worker.h"
 
-#include <utility>
-
-#include "base/bind.h"
 #include "base/json/json_writer.h"
 #include "base/values.h"
 
@@ -72,86 +69,24 @@
   }
 }
 
-ModelSafeWorker::ModelSafeWorker()
-    : work_done_or_abandoned_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
-                              base::WaitableEvent::InitialState::NOT_SIGNALED) {
-}
+ModelSafeWorker::ModelSafeWorker() {}
 ModelSafeWorker::~ModelSafeWorker() {}
 
 void ModelSafeWorker::RequestStop() {
-  base::AutoLock auto_lock(lock_);
-
-  // Set stop flag to prevent any *further* WorkCallback from starting to run
-  // (note that one may alreay be running).
-  stopped_ = true;
-
-  // If no work is running, unblock DoWorkAndWaitUntilDone(). If work is
-  // running, it is unsafe to return from DoWorkAndWaitUntilDone().
-  // ScopedSignalWorkDoneOrAbandoned will take care of signaling the event when
-  // the work is done.
-  if (!is_work_running_)
-    work_done_or_abandoned_.Signal();
+  // Set stop flag. This prevents any *further* tasks from being posted to
+  // worker threads (see DoWorkAndWaitUntilDone below), but note that one may
+  // already be posted.
+  stopped_.Set();
 }
 
-SyncerError ModelSafeWorker::DoWorkAndWaitUntilDone(WorkCallback work) {
-  {
-    // It is important to check |stopped_| and reset |work_done_or_abandoned_|
-    // atomically to prevent this race:
-    //
-    // Thread  Action
-    // Sync    Sees that |stopped_| is false.
-    // UI      Calls RequestStop(). Signals |work_done_or_abandoned_|.
-    // Sync    Resets |work_done_or_abandoned_|.
-    //         Waits on |work_done_or_abandoned_| forever since the task may not
-    //         run after RequestStop() is called.
-    base::AutoLock auto_lock(lock_);
-    if (stopped_)
-      return CANNOT_DO_WORK;
-    DCHECK(!is_work_running_);
-    work_done_or_abandoned_.Reset();
-  }
-
-  SyncerError error = UNSET;
-  bool did_run = false;
-  ScheduleWork(base::BindOnce(
-      &ModelSafeWorker::DoWork, this, base::Passed(std::move(work)),
-      base::Passed(base::ScopedClosureRunner(base::Bind(
-          [](scoped_refptr<ModelSafeWorker> worker) {
-            worker->work_done_or_abandoned_.Signal();
-          },
-          make_scoped_refptr(this)))),
-      base::Unretained(&error), base::Unretained(&did_run)));
-
-  // Unblocked when the task runs or is deleted or when RequestStop() is called
-  // before the task starts running.
-  work_done_or_abandoned_.Wait();
-
-  return did_run ? error : CANNOT_DO_WORK;
+SyncerError ModelSafeWorker::DoWorkAndWaitUntilDone(const WorkCallback& work) {
+  if (stopped_.IsSet())
+    return CANNOT_DO_WORK;
+  return DoWorkAndWaitUntilDoneImpl(work);
 }
 
-void ModelSafeWorker::DoWork(WorkCallback work,
-                             base::ScopedClosureRunner scoped_closure_runner,
-                             SyncerError* error,
-                             bool* did_run) {
-  {
-    base::AutoLock auto_lock(lock_);
-    if (stopped_)
-      return;
-
-    // Set |is_work_running_| to make sure that DoWorkAndWaitUntilDone() doesn't
-    // return while |work| is running.
-    DCHECK(!is_work_running_);
-    is_work_running_ = true;
-  }
-
-  *error = std::move(work).Run();
-  *did_run = true;
-
-  {
-    base::AutoLock auto_lock(lock_);
-    DCHECK(is_work_running_);
-    is_work_running_ = false;
-  }
+bool ModelSafeWorker::IsStopped() {
+  return stopped_.IsSet();
 }
 
 }  // namespace syncer
diff --git a/components/sync/engine/model_safe_worker.h b/components/sync/engine/model_safe_worker.h
index 620297fb..1565aa2 100644
--- a/components/sync/engine/model_safe_worker.h
+++ b/components/sync/engine/model_safe_worker.h
@@ -9,12 +9,10 @@
 #include <memory>
 #include <string>
 
-#include "base/callback.h"
-#include "base/callback_helpers.h"
+#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
+#include "base/synchronization/atomic_flag.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/syncer_error.h"
 
@@ -24,7 +22,7 @@
 
 namespace syncer {
 
-using WorkCallback = base::OnceCallback<enum SyncerError(void)>;
+using WorkCallback = base::Callback<enum SyncerError(void)>;
 
 enum ModelSafeGroup {
   GROUP_PASSIVE = 0,   // Models that are just "passively" being synced; e.g.
@@ -56,14 +54,17 @@
 // a thread and does actual work on that thread.
 class ModelSafeWorker : public base::RefCountedThreadSafe<ModelSafeWorker> {
  public:
-  // If not stopped, calls ScheduleWork() to schedule |work| and waits until it
-  // is done or abandoned. Otherwise, returns CANNOT_DO_WORK.
-  SyncerError DoWorkAndWaitUntilDone(WorkCallback work);
+  // If not stopped, call DoWorkAndWaitUntilDoneImpl() to do work. Otherwise
+  // return CANNOT_DO_WORK.
+  SyncerError DoWorkAndWaitUntilDone(const WorkCallback& work);
 
   // Soft stop worker by setting stopped_ flag. Called when sync is disabled
   // or browser is shutting down. Called on UI loop.
   virtual void RequestStop();
 
+  // Return true if the worker was stopped. Thread safe.
+  bool IsStopped();
+
   virtual ModelSafeGroup GetModelSafeGroup() = 0;
 
   // Returns true if called on the thread this worker works on.
@@ -73,31 +74,16 @@
   ModelSafeWorker();
   virtual ~ModelSafeWorker();
 
+  // Any time the Syncer performs model modifications (e.g employing a
+  // WriteTransaction), it should be done by this method to ensure it is done
+  // from a model-safe thread.
+  virtual SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) = 0;
+
  private:
   friend class base::RefCountedThreadSafe<ModelSafeWorker>;
 
-  // Schedules |work| on the appropriate thread.
-  virtual void ScheduleWork(base::OnceClosure work) = 0;
-
-  void DoWork(WorkCallback work,
-              base::ScopedClosureRunner scoped_closure_runner,
-              SyncerError* error,
-              bool* did_run);
-
-  // Synchronizes access to all members.
-  base::Lock lock_;
-
-  // Signaled when DoWorkAndWaitUntilDone() can return, either because the work
-  // is done, the work has been abandoned or RequestStop() was called while no
-  // work was running. Reset at the beginning of DoWorkAndWaitUntilDone().
-  base::WaitableEvent work_done_or_abandoned_;
-
-  // Whether a WorkCallback is currently running.
-  bool is_work_running_ = false;
-
-  // Whether the worker was stopped. No WorkCallback can start running when this
-  // is true.
-  bool stopped_ = false;
+  // Whether the worker should do more work. Set when sync is disabled.
+  base::AtomicFlag stopped_;
 
   DISALLOW_COPY_AND_ASSIGN(ModelSafeWorker);
 };
diff --git a/components/sync/engine/model_safe_worker_unittest.cc b/components/sync/engine/model_safe_worker_unittest.cc
index cb6cedd..6340dca 100644
--- a/components/sync/engine/model_safe_worker_unittest.cc
+++ b/components/sync/engine/model_safe_worker_unittest.cc
@@ -4,84 +4,13 @@
 
 #include "components/sync/engine/model_safe_worker.h"
 
-#include <utility>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/synchronization/atomic_flag.h"
-#include "base/test/test_simple_task_runner.h"
-#include "base/test/test_timeouts.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace syncer {
 namespace {
 
-syncer::WorkCallback ClosureToWorkCallback(base::Closure work) {
-  return base::Bind(
-      [](base::Closure work) {
-        work.Run();
-        return syncer::SYNCER_OK;
-      },
-      std::move(work));
-}
-
-class MockModelSafeWorker : public ModelSafeWorker {
- public:
-  MockModelSafeWorker() = default;
-
-  void ScheduleWork(base::OnceClosure work) override {
-    task_runner_->PostTask(FROM_HERE, std::move(work));
-  }
-
-  ModelSafeGroup GetModelSafeGroup() override { return GROUP_PASSIVE; }
-
-  bool IsOnModelThread() override {
-    return task_runner_->BelongsToCurrentThread();
-  }
-
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner() const {
-    return task_runner_;
-  }
-
- private:
-  friend class base::RefCountedThreadSafe<MockModelSafeWorker>;
-
-  ~MockModelSafeWorker() override = default;
-
-  const scoped_refptr<base::TestSimpleTaskRunner> task_runner_ =
-      new base::TestSimpleTaskRunner();
-
-  DISALLOW_COPY_AND_ASSIGN(MockModelSafeWorker);
-};
-
-class ModelSafeWorkerTest : public ::testing::Test {
- protected:
-  ModelSafeWorkerTest() : sync_thread_("SyncThreadForTest") {
-    sync_thread_.Start();
-  }
-
-  void DoWorkAndWaitUntilDoneOnSyncThread(base::Closure work) {
-    sync_thread_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(base::IgnoreResult(&ModelSafeWorker::DoWorkAndWaitUntilDone),
-                   worker_, base::Passed(ClosureToWorkCallback(work))));
-    sync_thread_.task_runner()->PostTask(
-        FROM_HERE, base::Bind(&base::AtomicFlag::Set,
-                              base::Unretained(&sync_thread_unblocked_)));
-  }
-
-  base::AtomicFlag sync_thread_unblocked_;
-  base::Thread sync_thread_;
-  const scoped_refptr<MockModelSafeWorker> worker_ = new MockModelSafeWorker();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ModelSafeWorkerTest);
-};
-
-}  // namespace
+class ModelSafeWorkerTest : public ::testing::Test {};
 
 TEST_F(ModelSafeWorkerTest, ModelSafeRoutingInfoToValue) {
   ModelSafeRoutingInfo routing_info;
@@ -120,95 +49,5 @@
   EXPECT_EQ(expected_types, GetRoutingInfoTypes(routing_info));
 }
 
-TEST_F(ModelSafeWorkerTest, DoWorkAndWaitUntilDone) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to |worker_|'s TaskRunner and run it.
-  while (!worker_->task_runner()->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  worker_->task_runner()->RunUntilIdle();
-
-  EXPECT_TRUE(did_work);
-
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(ModelSafeWorkerTest, DoWorkAndWaitUntilDoneRequestStopBeforeRunWork) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to |worker_|'s TaskRunner.
-  while (!worker_->task_runner()->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-
-  // Stop the worker.
-  worker_->RequestStop();
-
-  // The WorkCallback should not run.
-  worker_->task_runner()->RunUntilIdle();
-  EXPECT_FALSE(did_work);
-
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(ModelSafeWorkerTest, DoWorkAndWaitUntilDoneDeleteWorkBeforeRun) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](bool* did_work) { *did_work = true; }, base::Unretained(&did_work)));
-
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to |worker_|'s TaskRunner and delete it.
-  while (!worker_->task_runner()->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  worker_->task_runner()->ClearPendingTasks();
-
-  EXPECT_FALSE(did_work);
-
-  // Deleting the task should have unblocked the sync thread.
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
-TEST_F(ModelSafeWorkerTest, DoWorkAndWaitUntilDoneRequestStopDuringRunWork) {
-  bool did_work = false;
-  DoWorkAndWaitUntilDoneOnSyncThread(base::Bind(
-      [](scoped_refptr<ModelSafeWorker> worker,
-         base::AtomicFlag* sync_thread_unblocked, bool* did_work) {
-        worker->RequestStop();
-        base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
-
-        // The sync thread should not be unblocked while a WorkCallback is
-        // running.
-        EXPECT_FALSE(sync_thread_unblocked->IsSet());
-
-        *did_work = true;
-      },
-      worker_, base::Unretained(&sync_thread_unblocked_),
-      base::Unretained(&did_work)));
-  EXPECT_FALSE(did_work);
-  EXPECT_FALSE(sync_thread_unblocked_.IsSet());
-
-  // Wait for a task to be posted to |worker_|'s TaskRunner and run it.
-  while (!worker_->task_runner()->HasPendingTask())
-    base::PlatformThread::YieldCurrentThread();
-  worker_->task_runner()->RunUntilIdle();
-
-  EXPECT_TRUE(did_work);
-  sync_thread_.Stop();
-  EXPECT_TRUE(sync_thread_unblocked_.IsSet());
-}
-
+}  // namespace
 }  // namespace syncer
diff --git a/components/sync/engine/passive_model_worker.cc b/components/sync/engine/passive_model_worker.cc
index f8ba2d0..6a4f766 100644
--- a/components/sync/engine/passive_model_worker.cc
+++ b/components/sync/engine/passive_model_worker.cc
@@ -4,7 +4,7 @@
 
 #include "components/sync/engine/passive_model_worker.h"
 
-#include <utility>
+#include "base/callback.h"
 
 namespace syncer {
 
@@ -12,8 +12,10 @@
 
 PassiveModelWorker::~PassiveModelWorker() {}
 
-void PassiveModelWorker::ScheduleWork(base::OnceClosure work) {
-  std::move(work).Run();
+SyncerError PassiveModelWorker::DoWorkAndWaitUntilDoneImpl(
+    const WorkCallback& work) {
+  // Simply do the work on the current thread.
+  return work.Run();
 }
 
 ModelSafeGroup PassiveModelWorker::GetModelSafeGroup() {
diff --git a/components/sync/engine/passive_model_worker.h b/components/sync/engine/passive_model_worker.h
index 11725df7..ac744de 100644
--- a/components/sync/engine/passive_model_worker.h
+++ b/components/sync/engine/passive_model_worker.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_SYNC_ENGINE_PASSIVE_MODEL_WORKER_H_
 
 #include "base/macros.h"
+#include "components/sync/base/syncer_error.h"
 #include "components/sync/engine/model_safe_worker.h"
 
 namespace syncer {
@@ -21,11 +22,12 @@
   ModelSafeGroup GetModelSafeGroup() override;
   bool IsOnModelThread() override;
 
+ protected:
+  SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) override;
+
  private:
   ~PassiveModelWorker() override;
 
-  void ScheduleWork(base::OnceClosure work) override;
-
   DISALLOW_COPY_AND_ASSIGN(PassiveModelWorker);
 };
 
diff --git a/components/sync/engine/ui_model_worker.cc b/components/sync/engine/ui_model_worker.cc
index 08cc1a25..77fe9c77 100644
--- a/components/sync/engine/ui_model_worker.cc
+++ b/components/sync/engine/ui_model_worker.cc
@@ -6,11 +6,90 @@
 
 #include <utility>
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "components/sync/base/scoped_event_signal.h"
+
 namespace syncer {
 
+namespace {
+
+class ScopedEventSignalWithWorker {
+ public:
+  ScopedEventSignalWithWorker(scoped_refptr<UIModelWorker> ui_model_worker,
+                              base::WaitableEvent* event)
+      : ui_model_worker_(std::move(ui_model_worker)),
+        scoped_event_signal_(event) {}
+
+  ScopedEventSignalWithWorker(ScopedEventSignalWithWorker&&) = default;
+  ScopedEventSignalWithWorker& operator=(ScopedEventSignalWithWorker&&) =
+      default;
+
+  bool IsStopped() const { return ui_model_worker_->IsStopped(); }
+
+ private:
+  // This reference prevents the event in |scoped_event_signal_| from being
+  // signaled after being deleted.
+  scoped_refptr<UIModelWorker> ui_model_worker_;
+
+  ScopedEventSignal scoped_event_signal_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedEventSignalWithWorker);
+};
+
+void CallDoWorkAndSignalEvent(
+    const WorkCallback& work,
+    ScopedEventSignalWithWorker scoped_event_signal_with_worker,
+    SyncerError* error_info) {
+  if (!scoped_event_signal_with_worker.IsStopped())
+    *error_info = work.Run();
+  // The event in |scoped_event_signal_with_worker| is signaled at the end of
+  // this scope.
+}
+
+}  // namespace
+
 UIModelWorker::UIModelWorker(
     scoped_refptr<base::SingleThreadTaskRunner> ui_thread)
-    : ui_thread_(std::move(ui_thread)) {}
+    : ui_thread_(std::move(ui_thread)),
+      work_done_or_abandoned_(base::WaitableEvent::ResetPolicy::MANUAL,
+                              base::WaitableEvent::InitialState::NOT_SIGNALED),
+      stop_requested_(base::WaitableEvent::ResetPolicy::MANUAL,
+                      base::WaitableEvent::InitialState::NOT_SIGNALED) {
+  sequence_checker_.DetachFromSequence();
+}
+
+SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl(
+    const WorkCallback& work) {
+  DCHECK(sequence_checker_.CalledOnValidSequence());
+  DCHECK(!ui_thread_->BelongsToCurrentThread());
+
+  SyncerError error_info;
+  work_done_or_abandoned_.Reset();
+
+  if (!ui_thread_->PostTask(
+          FROM_HERE,
+          base::Bind(&CallDoWorkAndSignalEvent, work,
+                     base::Passed(syncer::ScopedEventSignalWithWorker(
+                         this, &work_done_or_abandoned_)),
+                     &error_info))) {
+    DLOG(WARNING) << "Could not post work to UI loop.";
+    error_info = CANNOT_DO_WORK;
+    return error_info;
+  }
+
+  base::WaitableEvent* events[] = {&work_done_or_abandoned_, &stop_requested_};
+  base::WaitableEvent::WaitMany(events, arraysize(events));
+
+  return error_info;
+}
+
+void UIModelWorker::RequestStop() {
+  DCHECK(ui_thread_->BelongsToCurrentThread());
+  ModelSafeWorker::RequestStop();
+  stop_requested_.Signal();
+}
 
 ModelSafeGroup UIModelWorker::GetModelSafeGroup() {
   return GROUP_UI;
@@ -22,8 +101,4 @@
 
 UIModelWorker::~UIModelWorker() {}
 
-void UIModelWorker::ScheduleWork(base::OnceClosure work) {
-  ui_thread_->PostTask(FROM_HERE, std::move(work));
-}
-
 }  // namespace syncer
diff --git a/components/sync/engine/ui_model_worker.h b/components/sync/engine/ui_model_worker.h
index bff75a8..2306a39c 100644
--- a/components/sync/engine/ui_model_worker.h
+++ b/components/sync/engine/ui_model_worker.h
@@ -7,7 +7,9 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
 #include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
 #include "components/sync/engine/model_safe_worker.h"
 
 namespace syncer {
@@ -20,17 +22,33 @@
   explicit UIModelWorker(scoped_refptr<base::SingleThreadTaskRunner> ui_thread);
 
   // ModelSafeWorker implementation.
+  void RequestStop() override;
   ModelSafeGroup GetModelSafeGroup() override;
   bool IsOnModelThread() override;
 
+ protected:
+  SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) override;
+
  private:
   ~UIModelWorker() override;
 
-  void ScheduleWork(base::OnceClosure work) override;
-
   // A reference to the UI thread's task runner.
   const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
 
+  // Signaled when a task posted by DoWorkAndWaitUntilDoneImpl() is deleted,
+  // i.e. after it runs or when it is abandoned. Reset at the beginning of every
+  // DoWorkAndWaitUntilDoneImpl() call.
+  base::WaitableEvent work_done_or_abandoned_;
+
+  // Signaled from RequestStop(). When this is signaled,
+  // DoWorkAndWaitUntilDoneImpl() returns immediately. This is needed to prevent
+  // the UI thread from joining the sync thread while it is waiting for a
+  // WorkCallback to run on the UI thread. See crbug.com/663600.
+  base::WaitableEvent stop_requested_;
+
+  // Verifies that calls to DoWorkAndWaitUntilDoneImpl() are sequenced.
+  base::SequenceChecker sequence_checker_;
+
   DISALLOW_COPY_AND_ASSIGN(UIModelWorker);
 };
 
diff --git a/components/sync/engine/ui_model_worker_unittest.cc b/components/sync/engine/ui_model_worker_unittest.cc
index ab27452..9411a67a 100644
--- a/components/sync/engine/ui_model_worker_unittest.cc
+++ b/components/sync/engine/ui_model_worker_unittest.cc
@@ -52,7 +52,7 @@
     sync_thread_.task_runner()->PostTask(
         FROM_HERE,
         base::Bind(base::IgnoreResult(&UIModelWorker::DoWorkAndWaitUntilDone),
-                   worker_, base::Passed(ClosureToWorkCallback(work))));
+                   worker_, ClosureToWorkCallback(work)));
   }
 
  protected:
diff --git a/components/sync/engine_impl/directory_update_handler.cc b/components/sync/engine_impl/directory_update_handler.cc
index 7b71cf6..495346c 100644
--- a/components/sync/engine_impl/directory_update_handler.cc
+++ b/components/sync/engine_impl/directory_update_handler.cc
@@ -6,7 +6,6 @@
 
 #include <stdint.h>
 
-#include <utility>
 #include <vector>
 
 #include "base/memory/ptr_util.h"
@@ -128,7 +127,7 @@
                    // We wait until the callback is executed.  We can safely use
                    // Unretained.
                    base::Unretained(this), base::Unretained(status));
-    worker_->DoWorkAndWaitUntilDone(std::move(c));
+    worker_->DoWorkAndWaitUntilDone(c);
 
     debug_info_emitter_->EmitUpdateCountersUpdate();
     debug_info_emitter_->EmitStatusCountersUpdate();
diff --git a/components/sync/syncable/directory_backing_store.cc b/components/sync/syncable/directory_backing_store.cc
index d2e3246..3714cd90 100644
--- a/components/sync/syncable/directory_backing_store.cc
+++ b/components/sync/syncable/directory_backing_store.cc
@@ -717,13 +717,11 @@
 
   while (s.Step()) {
     int total_entry_copies;
-    std::unique_ptr<EntryKernel> kernel_ptr =
-        UnpackEntry(&s, &total_entry_copies);
+    std::unique_ptr<EntryKernel> kernel = UnpackEntry(&s, &total_entry_copies);
     // A null kernel is evidence of external data corruption.
-    if (!kernel_ptr)
+    if (!kernel)
       return false;
-    EntryKernel* kernel = kernel_ptr.get();
-    (*delete_journals)[kernel] = std::move(kernel_ptr);
+    DeleteJournal::AddEntryToJournalIndex(delete_journals, std::move(kernel));
   }
   return s.Succeeded();
 }
diff --git a/components/sync/syncable/syncable_delete_journal.cc b/components/sync/syncable/syncable_delete_journal.cc
index a5b426a..e43f695c 100644
--- a/components/sync/syncable/syncable_delete_journal.cc
+++ b/components/sync/syncable/syncable_delete_journal.cc
@@ -45,10 +45,9 @@
   if (entry.ref(SERVER_IS_DEL)) {
     if (it == delete_journals_.end()) {
       // New delete.
-      std::unique_ptr<EntryKernel> t_ptr = base::MakeUnique<EntryKernel>(entry);
-      EntryKernel* t = t_ptr.get();
-      delete_journals_to_purge_.erase(t->ref(META_HANDLE));
-      delete_journals_[t] = std::move(t_ptr);
+      auto entry_copy = base::MakeUnique<EntryKernel>(entry);
+      delete_journals_to_purge_.erase(entry_copy->ref(META_HANDLE));
+      AddEntryToJournalIndex(&delete_journals_, std::move(entry_copy));
     }
   } else {
     // Undelete. This could happen in two cases:
@@ -124,10 +123,8 @@
   for (auto& entry : entries) {
     needle.put(ID, entry->ref(ID));
     if (delete_journals_.find(&needle) == delete_journals_.end()) {
-      std::unique_ptr<EntryKernel> t_ptr =
-          base::MakeUnique<EntryKernel>(*entry);
-      EntryKernel* t = t_ptr.get();
-      delete_journals_[t] = std::move(t_ptr);
+      auto entry_copy = base::MakeUnique<EntryKernel>(*entry);
+      AddEntryToJournalIndex(&delete_journals_, std::move(entry_copy));
     }
     delete_journals_to_purge_.erase(entry->ref(META_HANDLE));
   }
@@ -143,5 +140,13 @@
   }
 }
 
+// static
+void DeleteJournal::AddEntryToJournalIndex(JournalIndex* journal_index,
+                                           std::unique_ptr<EntryKernel> entry) {
+  EntryKernel* key = entry.get();
+  if (journal_index->find(key) == journal_index->end())
+    (*journal_index)[key] = std::move(entry);
+}
+
 }  // namespace syncable
 }  // namespace syncer
diff --git a/components/sync/syncable/syncable_delete_journal.h b/components/sync/syncable/syncable_delete_journal.h
index da2b4c1..6d907d8 100644
--- a/components/sync/syncable/syncable_delete_journal.h
+++ b/components/sync/syncable/syncable_delete_journal.h
@@ -92,6 +92,10 @@
   // Return true if delete journals of |type| are maintained.
   static bool IsDeleteJournalEnabled(ModelType type);
 
+  // Adds entry to JournalIndex if it doesn't already exist.
+  static void AddEntryToJournalIndex(JournalIndex* journal_index,
+                                     std::unique_ptr<EntryKernel> entry);
+
  private:
   FRIEND_TEST_ALL_PREFIXES(SyncableDirectoryTest, ManageDeleteJournals);
 
diff --git a/components/sync/syncable/syncable_delete_journal_unittest.cc b/components/sync/syncable/syncable_delete_journal_unittest.cc
new file mode 100644
index 0000000..e7ad444
--- /dev/null
+++ b/components/sync/syncable/syncable_delete_journal_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync/syncable/syncable_delete_journal.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "components/sync/syncable/entry_kernel.h"
+#include "components/sync/syncable/syncable_id.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace syncer {
+namespace syncable {
+
+// Tests that when adding entries to JournalIndex key pointer always matches
+// value object.
+TEST(SyncableDeleteJournal, AddEntryToJournalIndex_KeyMatchesValue) {
+  JournalIndex journal_index;
+  std::unique_ptr<EntryKernel> entry;
+
+  // Add two entries with the same id. Verify that only one entry is stored in
+  // JournalIndex and that entry's key matches the value object.
+  entry = base::MakeUnique<EntryKernel>();
+  entry->put(ID, Id::CreateFromServerId("id1"));
+  DeleteJournal::AddEntryToJournalIndex(&journal_index, std::move(entry));
+  EXPECT_EQ(1U, journal_index.size());
+
+  entry = base::MakeUnique<EntryKernel>();
+  entry->put(ID, Id::CreateFromServerId("id1"));
+  DeleteJournal::AddEntryToJournalIndex(&journal_index, std::move(entry));
+  EXPECT_EQ(1U, journal_index.size());
+
+  for (auto it = journal_index.begin(); it != journal_index.end(); ++it) {
+    EXPECT_TRUE(it->first == it->second.get());
+  }
+}
+
+}  // namespace syncable
+}  // namespace syncer
diff --git a/components/sync/test/engine/fake_model_worker.cc b/components/sync/test/engine/fake_model_worker.cc
index 966e0a4..c696005 100644
--- a/components/sync/test/engine/fake_model_worker.cc
+++ b/components/sync/test/engine/fake_model_worker.cc
@@ -4,7 +4,7 @@
 
 #include "components/sync/test/engine/fake_model_worker.h"
 
-#include <utility>
+#include "base/callback.h"
 
 namespace syncer {
 
@@ -18,10 +18,11 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 }
 
-void FakeModelWorker::ScheduleWork(base::OnceClosure work) {
+SyncerError FakeModelWorker::DoWorkAndWaitUntilDoneImpl(
+    const WorkCallback& work) {
   DCHECK(thread_checker_.CalledOnValidThread());
   // Simply do the work on the current thread.
-  std::move(work).Run();
+  return work.Run();
 }
 
 ModelSafeGroup FakeModelWorker::GetModelSafeGroup() {
diff --git a/components/sync/test/engine/fake_model_worker.h b/components/sync/test/engine/fake_model_worker.h
index ccc922d..55ab4a9 100644
--- a/components/sync/test/engine/fake_model_worker.h
+++ b/components/sync/test/engine/fake_model_worker.h
@@ -22,11 +22,12 @@
   ModelSafeGroup GetModelSafeGroup() override;
   bool IsOnModelThread() override;
 
+ protected:
+  SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) override;
+
  private:
   ~FakeModelWorker() override;
 
-  void ScheduleWork(base::OnceClosure work) override;
-
   const ModelSafeGroup group_;
   base::ThreadChecker thread_checker_;
 
diff --git a/components/ukm/test_ukm_service.cc b/components/ukm/test_ukm_service.cc
index e3fcef86..824fa25 100644
--- a/components/ukm/test_ukm_service.cc
+++ b/components/ukm/test_ukm_service.cc
@@ -4,6 +4,9 @@
 
 #include "components/ukm/test_ukm_service.h"
 
+#include "base/logging.h"
+#include "base/metrics/metrics_hashes.h"
+#include "components/ukm/ukm_entry.h"
 #include "components/ukm/ukm_source.h"
 
 namespace ukm {
@@ -33,15 +36,38 @@
 }
 
 const UkmSource* TestUkmService::GetSourceForUrl(const char* url) const {
+  const UkmSource* source = nullptr;
   for (const auto& kv : sources_for_testing()) {
-    if (kv.second->url() == url)
-      return kv.second.get();
+    if (kv.second->url() == url) {
+      DCHECK_EQ(nullptr, source);
+      source = kv.second.get();
+    }
   }
-  return nullptr;
+  return source;
+}
+
+const UkmSource* TestUkmService::GetSourceForSourceId(int32_t source_id) const {
+  const UkmSource* source = nullptr;
+  for (const auto& kv : sources_for_testing()) {
+    if (kv.second->id() == source_id) {
+      DCHECK_EQ(nullptr, source);
+      source = kv.second.get();
+    }
+  }
+  return source;
 }
 
 const UkmEntry* TestUkmService::GetEntry(size_t entry_num) const {
   return entries_for_testing()[entry_num].get();
 }
 
+const UkmEntry* TestUkmService::GetEntryForEntryName(
+    const char* entry_name) const {
+  for (const auto& it : entries_for_testing()) {
+    if (it->event_hash() == base::HashMetricName(entry_name))
+      return it.get();
+  }
+  return nullptr;
+}
+
 }  // namespace ukm
diff --git a/components/ukm/test_ukm_service.h b/components/ukm/test_ukm_service.h
index e3ffbf9..55d5920 100644
--- a/components/ukm/test_ukm_service.h
+++ b/components/ukm/test_ukm_service.h
@@ -24,9 +24,11 @@
   size_t sources_count() const { return sources_for_testing().size(); }
   const std::map<int32_t, std::unique_ptr<UkmSource>>& GetSources() const;
   const UkmSource* GetSourceForUrl(const char* url) const;
+  const UkmSource* GetSourceForSourceId(int32_t source_id) const;
 
   size_t entries_count() const { return entries_for_testing().size(); }
   const UkmEntry* GetEntry(size_t entry_num) const;
+  const UkmEntry* GetEntryForEntryName(const char* entry_name) const;
 
  private:
   metrics::TestMetricsServiceClient test_metrics_service_client_;
diff --git a/content/app/strings/content_strings.grd b/content/app/strings/content_strings.grd
index 6596fd3e..8b521fc 100644
--- a/content/app/strings/content_strings.grd
+++ b/content/app/strings/content_strings.grd
@@ -517,7 +517,7 @@
           tree item
         </message>
       </if>
-      
+
       <message name="IDS_AX_AM_PM_FIELD_TEXT" desc="Accessible description of the AM/PM field in a date/time control">
         AM/PM
       </message>
@@ -872,6 +872,12 @@
       <message name="IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD" desc="Media controls overflow menu item label for a download button.">
        Download
       </message>
+      <message name="IDS_MEDIA_REMOTING_DISABLE_TEXT" desc="Media remoting disable button label.">
+       Play on both screens
+      </message>
+      <message name="IDS_MEDIA_REMOTING_CAST_TEXT" desc="Media remoting cast video text message.">
+       Now casting to your TV
+      </message>
       <message name="IDS_MEDIA_TRACKS_NO_LABEL" desc="Menu item label for a text track that has no name specified. The number represents the track number in the list of tracks.">
         Track <ph name="NUMBER">$1<ex>1</ex></ph>
       </message>
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index 94eb1e88..700f10f 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -696,9 +696,11 @@
     return;
   if (completion_status.error_code != net::OK) {
     frontend_->LoadingFailed(
-        request_id, base::TimeTicks::Now().ToInternalValue() /
-                        static_cast<double>(base::Time::kMicrosecondsPerSecond),
-        Page::ResourceTypeEnum::Other, "Navigation Preload Error",
+        request_id,
+        base::TimeTicks::Now().ToInternalValue() /
+            static_cast<double>(base::Time::kMicrosecondsPerSecond),
+        Page::ResourceTypeEnum::Other,
+        net::ErrorToString(completion_status.error_code),
         completion_status.error_code == net::Error::ERR_ABORTED);
   }
   frontend_->LoadingFinished(
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index c503716..2ebed65 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -41,6 +41,7 @@
   auto new_request = base::MakeUnique<ResourceRequest>();
   new_request->method = "GET";
   new_request->url = request_info->common_params.url;
+  new_request->first_party_for_cookies = request_info->first_party_for_cookies;
   new_request->priority = net::HIGHEST;
 
   mojom::URLLoaderClientPtr url_loader_client_ptr;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 2e5c40c..1de98c2 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -548,15 +548,6 @@
   prefs.background_video_track_optimization_enabled =
       base::FeatureList::IsEnabled(media::kBackgroundVideoTrackOptimization);
 
-  // TODO(avayvod, asvitkine): Query the value directly when it is available in
-  // the renderer process. See https://crbug.com/681160.
-  prefs.max_keyframe_distance_to_disable_background_video =
-      base::TimeDelta::FromMilliseconds(
-          variations::GetVariationParamByFeatureAsInt(
-              media::kBackgroundVideoTrackOptimization,
-              "max_keyframe_distance_ms",
-              base::TimeDelta::FromSeconds(10).InMilliseconds()));
-
   // TODO(servolk, asvitkine): Query the value directly when it is available in
   // the renderer process. See https://crbug.com/681160.
   prefs.enable_instant_source_buffer_gc =
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc
index 0787909..74044ea 100644
--- a/content/child/blink_platform_impl.cc
+++ b/content/child/blink_platform_impl.cc
@@ -212,6 +212,10 @@
       return IDS_FORM_INPUT_ALT;
     case WebLocalizedString::kMissingPluginText:
       return IDS_PLUGIN_INITIALIZATION_ERROR;
+    case WebLocalizedString::kMediaRemotingDisableText:
+      return IDS_MEDIA_REMOTING_DISABLE_TEXT;
+    case WebLocalizedString::kMediaRemotingCastText:
+      return IDS_MEDIA_REMOTING_CAST_TEXT;
     case WebLocalizedString::kMultipleFileUploadText:
       return IDS_FORM_FILE_MULTIPLE_UPLOAD;
     case WebLocalizedString::kOtherColorLabel:
@@ -523,6 +527,8 @@
      ui::SCALE_FACTOR_100P, false},
     {"mediaplayerOverlayPlay", IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON,
      ui::SCALE_FACTOR_100P, false},
+    {"mediaRemotingCastIcon", IDR_MEDIA_REMOTING_CAST_ICON,
+     ui::SCALE_FACTOR_100P, false},
     {"mediaplayerTrackSelectionCheckmark",
      IDR_MEDIAPLAYER_TRACKSELECTION_CHECKMARK, ui::SCALE_FACTOR_100P, false},
     {"mediaplayerClosedCaptionsIcon", IDR_MEDIAPLAYER_CLOSEDCAPTIONS_ICON,
diff --git a/content/network/network_context.cc b/content/network/network_context.cc
index 5637a659..fcca28c 100644
--- a/content/network/network_context.cc
+++ b/content/network/network_context.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "content/network/url_loader_impl.h"
 #include "content/public/common/content_client.h"
 #include "net/dns/host_resolver.h"
@@ -13,6 +14,7 @@
 #include "net/log/net_log_util.h"
 #include "net/log/write_to_file_net_log_observer.h"
 #include "net/proxy/proxy_service.h"
+#include "net/url_request/data_protocol_handler.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
 
@@ -58,6 +60,10 @@
 
   builder.EnableHttpCache(cache_params);
   builder.set_file_enabled(true);
+
+  builder.SetProtocolHandler(url::kDataScheme,
+                             base::MakeUnique<net::DataProtocolHandler>());
+
   return builder.Build();
 }
 
diff --git a/content/network/url_loader_impl.cc b/content/network/url_loader_impl.cc
index a29cec4..b2fd442 100644
--- a/content/network/url_loader_impl.cc
+++ b/content/network/url_loader_impl.cc
@@ -6,6 +6,7 @@
 
 #include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
 #include "content/network/net_adapters.h"
 #include "content/network/network_context.h"
 #include "content/public/common/referrer.h"
@@ -63,6 +64,11 @@
 
   response->head.effective_connection_type =
       net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
+
+  request->GetLoadTimingInfo(&response->head.load_timing);
+
+  response->head.request_start = request->creation_time();
+  response->head.response_start = base::TimeTicks::Now();
 }
 
 // A subclass of net::UploadBytesElementReader which owns
@@ -226,6 +232,7 @@
 
   scoped_refptr<ResourceResponse> response = new ResourceResponse();
   PopulateResourceResponse(url_request_.get(), response.get());
+  response->head.encoded_data_length = url_request_->GetTotalReceivedBytes();
 
   url_loader_client_->OnReceiveRedirect(redirect_info, response->head);
 }
@@ -237,6 +244,7 @@
 
   scoped_refptr<ResourceResponse> response = new ResourceResponse();
   PopulateResourceResponse(url_request_.get(), response.get());
+  response->head.encoded_data_length = url_request_->raw_header_size();
 
   mojom::DownloadedTempFilePtr downloaded_file_ptr;
   url_loader_client_->OnReceiveResponse(response->head,
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java b/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java
index 63d5a616..6a8bcea1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContextSelectionClient.java
@@ -137,11 +137,11 @@
 
         switch (callbackData) {
             case SUGGEST_AND_CLASSIFY:
-                mProvider.sendSuggestAndClassifyRequest(text, start, end);
+                mProvider.sendSuggestAndClassifyRequest(text, start, end, null);
                 break;
 
             case CLASSIFY:
-                mProvider.sendClassifyRequest(text, start, end);
+                mProvider.sendClassifyRequest(text, start, end, null);
                 break;
 
             default:
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContextSelectionProvider.java b/content/public/android/java/src/org/chromium/content/browser/ContextSelectionProvider.java
index 50890fe..0f6dc07 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContextSelectionProvider.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContextSelectionProvider.java
@@ -10,6 +10,8 @@
 
 import org.chromium.base.annotations.SuppressFBWarnings;
 
+import java.util.Locale;
+
 /**
  * The interface that controls contextual text selection.
  */
@@ -78,7 +80,8 @@
      * @param end   The index pointing to the first character that comes after
      *              the selected text inside the textual context.
      */
-    public void sendSuggestAndClassifyRequest(CharSequence text, int start, int end);
+    public void sendSuggestAndClassifyRequest(
+            CharSequence text, int start, int end, Locale[] locales);
 
     /**
      * Sends asynchronous request to obtain the selection and analyze its type.
@@ -87,7 +90,7 @@
      * @param end   The index pointing to the first character that comes after
      *              the selected text inside the textual context.
      */
-    public void sendClassifyRequest(CharSequence text, int start, int end);
+    public void sendClassifyRequest(CharSequence text, int start, int end, Locale[] locales);
 
     /**
      * Cancel all asynchronous requests.
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h
index cb9519dd..3dd2e75 100644
--- a/content/public/common/common_param_traits_macros.h
+++ b/content/public/common/common_param_traits_macros.h
@@ -248,7 +248,6 @@
   IPC_STRUCT_TRAITS_MEMBER(default_maximum_page_scale_factor)
   IPC_STRUCT_TRAITS_MEMBER(hide_download_ui)
   IPC_STRUCT_TRAITS_MEMBER(background_video_track_optimization_enabled)
-  IPC_STRUCT_TRAITS_MEMBER(max_keyframe_distance_to_disable_background_video)
   IPC_STRUCT_TRAITS_MEMBER(enable_instant_source_buffer_gc)
   IPC_STRUCT_TRAITS_MEMBER(presentation_receiver)
   IPC_STRUCT_TRAITS_MEMBER(media_controls_enabled)
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc
index 78312c4..72f7bd8 100644
--- a/content/public/common/web_preferences.cc
+++ b/content/public/common/web_preferences.cc
@@ -225,8 +225,6 @@
 #endif
       hide_download_ui(false),
       background_video_track_optimization_enabled(false),
-      max_keyframe_distance_to_disable_background_video(
-          base::TimeDelta::FromSeconds(10)),
       enable_instant_source_buffer_gc(false),
       presentation_receiver(false),
       media_controls_enabled(true),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h
index e2e6c5f0..ae9756c 100644
--- a/content/public/common/web_preferences.h
+++ b/content/public/common/web_preferences.h
@@ -266,13 +266,6 @@
   // If enabled, disabled video track when the video is in the background.
   bool background_video_track_optimization_enabled;
 
-  // If background video track optimization is enabled, don't disable video
-  // track for videos with the average keyframe distance greater than this
-  // value.
-  // TODO(avayvod, asvitkine): Query the value directly when it is available in
-  // the renderer process. See https://crbug.com/681160.
-  base::TimeDelta max_keyframe_distance_to_disable_background_video;
-
   // When memory pressure based garbage collection is enabled for MSE, the
   // |enable_instant_source_buffer_gc| flag controls whether the GC is done
   // immediately on memory pressure notification or during the next SourceBuffer
diff --git a/content/renderer/mojo/blink_connector_js_wrapper.cc b/content/renderer/mojo/blink_connector_js_wrapper.cc
index e7fb6f51..abf402c 100644
--- a/content/renderer/mojo/blink_connector_js_wrapper.cc
+++ b/content/renderer/mojo/blink_connector_js_wrapper.cc
@@ -24,7 +24,7 @@
 // static
 gin::Handle<BlinkConnectorJsWrapper> BlinkConnectorJsWrapper::Create(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     service_manager::Connector* connector) {
   return gin::CreateHandle(
       isolate,
@@ -73,7 +73,7 @@
 
 BlinkConnectorJsWrapper::BlinkConnectorJsWrapper(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     base::WeakPtr<service_manager::Connector> connector)
     : isolate_(isolate),
       context_(isolate, context),
@@ -90,7 +90,7 @@
     return;
 
   v8::HandleScope handle_scope(isolate_);
-  v8::Handle<v8::Context> context = context_.Get(isolate_);
+  v8::Local<v8::Context> context = context_.Get(isolate_);
   v8::Context::Scope context_scope(context);
   v8::Local<v8::Value> argv[] = {
       gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))};
diff --git a/content/renderer/mojo/blink_connector_js_wrapper.h b/content/renderer/mojo/blink_connector_js_wrapper.h
index 54f53c2..34fe942e6 100644
--- a/content/renderer/mojo/blink_connector_js_wrapper.h
+++ b/content/renderer/mojo/blink_connector_js_wrapper.h
@@ -29,7 +29,7 @@
   ~BlinkConnectorJsWrapper() override;
   static gin::Handle<BlinkConnectorJsWrapper> Create(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       service_manager::Connector* remote_interfaces);
 
   // gin::Wrappable<BlinkConnectorJsWrapper> overrides.
@@ -52,7 +52,7 @@
       v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>>;
 
   BlinkConnectorJsWrapper(v8::Isolate* isolate,
-                          v8::Handle<v8::Context> context,
+                          v8::Local<v8::Context> context,
                           base::WeakPtr<service_manager::Connector> connector);
 
   void CallJsFactory(const ScopedJsFactory& factory,
diff --git a/content/renderer/mojo/interface_provider_js_wrapper.cc b/content/renderer/mojo/interface_provider_js_wrapper.cc
index 03c3dfd..352ee01 100644
--- a/content/renderer/mojo/interface_provider_js_wrapper.cc
+++ b/content/renderer/mojo/interface_provider_js_wrapper.cc
@@ -28,7 +28,7 @@
 // static
 gin::Handle<InterfaceProviderJsWrapper> InterfaceProviderJsWrapper::Create(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     service_manager::Connector* connector) {
   return gin::CreateHandle(
       isolate, new InterfaceProviderJsWrapper(isolate, context,
@@ -38,7 +38,7 @@
 // static
 gin::Handle<InterfaceProviderJsWrapper> InterfaceProviderJsWrapper::Create(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     service_manager::InterfaceProvider* remote_interfaces) {
   return gin::CreateHandle(
       isolate,
@@ -104,7 +104,7 @@
 
 InterfaceProviderJsWrapper::InterfaceProviderJsWrapper(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     base::WeakPtr<service_manager::Connector> connector)
     : isolate_(isolate),
       context_(isolate, context),
@@ -116,7 +116,7 @@
 
 InterfaceProviderJsWrapper::InterfaceProviderJsWrapper(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     base::WeakPtr<service_manager::InterfaceProvider> remote_interfaces)
     : isolate_(isolate),
       context_(isolate, context),
@@ -133,7 +133,7 @@
     return;
 
   v8::HandleScope handle_scope(isolate_);
-  v8::Handle<v8::Context> context = context_.Get(isolate_);
+  v8::Local<v8::Context> context = context_.Get(isolate_);
   v8::Context::Scope context_scope(context);
   v8::Local<v8::Value> argv[] = {
       gin::ConvertToV8(isolate_, mojo::Handle(pipe.release().value()))};
diff --git a/content/renderer/mojo/interface_provider_js_wrapper.h b/content/renderer/mojo/interface_provider_js_wrapper.h
index ec18bfc1..b6dd37a 100644
--- a/content/renderer/mojo/interface_provider_js_wrapper.h
+++ b/content/renderer/mojo/interface_provider_js_wrapper.h
@@ -30,11 +30,11 @@
   ~InterfaceProviderJsWrapper() override;
   static gin::Handle<InterfaceProviderJsWrapper> Create(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       service_manager::Connector* connector);
   static gin::Handle<InterfaceProviderJsWrapper> Create(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       service_manager::InterfaceProvider* remote_interfaces);
 
   // gin::Wrappable<InterfaceProviderJsWrapper> overrides.
@@ -58,11 +58,11 @@
 
   InterfaceProviderJsWrapper(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       base::WeakPtr<service_manager::Connector> connector);
   InterfaceProviderJsWrapper(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       base::WeakPtr<service_manager::InterfaceProvider> remote_interfaces);
 
   void CallJsFactory(const ScopedJsFactory& factory,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 676a081..6922b94 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -24,6 +24,7 @@
 #include "base/memory/shared_memory.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/process/process.h"
 #include "base/stl_util.h"
@@ -2875,6 +2876,16 @@
   base::WeakPtr<media::MediaObserver> media_observer = nullptr;
 #endif
 
+  base::TimeDelta max_keyframe_distance_to_disable_background_video =
+      base::TimeDelta::FromMilliseconds(base::GetFieldTrialParamByFeatureAsInt(
+          media::kBackgroundVideoTrackOptimization, "max_keyframe_distance_ms",
+          base::TimeDelta::FromSeconds(10).InMilliseconds()));
+  base::TimeDelta max_keyframe_distance_to_disable_background_video_mse =
+      base::TimeDelta::FromMilliseconds(base::GetFieldTrialParamByFeatureAsInt(
+          media::kBackgroundVideoTrackOptimization,
+          "max_keyframe_distance_media_source_ms",
+          base::TimeDelta::FromSeconds(10).InMilliseconds()));
+
   media::WebMediaPlayerParams params(
       base::Bind(&ContentRendererClient::DeferMediaLoad,
                  base::Unretained(GetContentClient()->renderer()),
@@ -2887,9 +2898,8 @@
       base::Bind(&v8::Isolate::AdjustAmountOfExternalAllocatedMemory,
                  base::Unretained(blink::MainThreadIsolate())),
       initial_cdm, media_surface_manager_, media_observer,
-      // TODO(avayvod, asvitkine): Query the value directly when it is available
-      // in the renderer process. See https://crbug.com/681160.
-      GetWebkitPreferences().max_keyframe_distance_to_disable_background_video,
+      max_keyframe_distance_to_disable_background_video,
+      max_keyframe_distance_to_disable_background_video_mse,
       GetWebkitPreferences().enable_instant_source_buffer_gc,
       GetContentClient()->renderer()->AllowMediaSuspend(),
       embedded_media_experience_enabled);
diff --git a/content/shell/renderer/layout_test/interface_registry_js_wrapper.cc b/content/shell/renderer/layout_test/interface_registry_js_wrapper.cc
index 7f2a054..3a1458f 100644
--- a/content/shell/renderer/layout_test/interface_registry_js_wrapper.cc
+++ b/content/shell/renderer/layout_test/interface_registry_js_wrapper.cc
@@ -24,7 +24,7 @@
 // static
 gin::Handle<InterfaceRegistryJsWrapper> InterfaceRegistryJsWrapper::Create(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     service_manager::InterfaceRegistry* interface_registry) {
   return gin::CreateHandle(
       isolate, new InterfaceRegistryJsWrapper(
@@ -52,7 +52,7 @@
 
 InterfaceRegistryJsWrapper::InterfaceRegistryJsWrapper(
     v8::Isolate* isolate,
-    v8::Handle<v8::Context> context,
+    v8::Local<v8::Context> context,
     base::WeakPtr<service_manager::InterfaceRegistry> interface_registry)
     : isolate_(isolate),
       context_(isolate, context),
diff --git a/content/shell/renderer/layout_test/interface_registry_js_wrapper.h b/content/shell/renderer/layout_test/interface_registry_js_wrapper.h
index 1330d56..e562316c 100644
--- a/content/shell/renderer/layout_test/interface_registry_js_wrapper.h
+++ b/content/shell/renderer/layout_test/interface_registry_js_wrapper.h
@@ -28,7 +28,7 @@
  public:
   static gin::Handle<InterfaceRegistryJsWrapper> Create(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       service_manager::InterfaceRegistry* interface_registry);
 
   // gin::Wrappable<InterfaceRegistryJsWrapper> overrides.
@@ -48,7 +48,7 @@
 
   InterfaceRegistryJsWrapper(
       v8::Isolate* isolate,
-      v8::Handle<v8::Context> context,
+      v8::Local<v8::Context> context,
       base::WeakPtr<service_manager::InterfaceRegistry> interface_registry);
   ~InterfaceRegistryJsWrapper() override;
 
diff --git a/device/vr/vr_display_impl.cc b/device/vr/vr_display_impl.cc
index ddbdbb5..46542389 100644
--- a/device/vr/vr_display_impl.cc
+++ b/device/vr/vr_display_impl.cc
@@ -59,7 +59,9 @@
 void VRDisplayImpl::RequestPresent(bool secure_origin,
                                    mojom::VRSubmitFrameClientPtr submit_client,
                                    const RequestPresentCallback& callback) {
-  if (!device_->IsAccessAllowed(this)) {
+  // TODO(mthiesse): Re-enable insecure origin support once webVR content
+  // warnings are fixed. crbug.com/704937
+  if (!device_->IsAccessAllowed(this) || !secure_origin) {
     callback.Run(false);
     return;
   }
diff --git a/docs/README.md b/docs/README.md
index c203f4ed..b0d26a2 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,17 +1,22 @@
 # Chromium docs
 
 This directory contains chromium project documentation in
-[Gitiles-flavored Markdown].
+[Gitiles-flavored Markdown](https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md).
 It is automatically
 [rendered by Gitiles](https://chromium.googlesource.com/chromium/src/+/master/docs/).
 
+If you add new documents, please also add a link to them in the Document Index
+below.
+
+[TOC]
+
 ## Style guide
 
-Markdown documents must follow the [style guide].
+Markdown documents must follow the [style guide](https://github.com/google/styleguide/tree/gh-pages/docguide).
 
 ## Previewing changes
 
-You can preview your local changes using [md_browser]:
+You can preview your local changes using [md_browser](../tools/md_browser/):
 
 ```bash
 # in chromium checkout
@@ -26,6 +31,280 @@
 ./tools/md_browser/md_browser.py
 ```
 
-[Gitiles-flavored Markdown]: https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md
-[style guide]: https://github.com/google/styleguide/tree/gh-pages/docguide
-[md_browser]: ../tools/md_browser/
+## Document Index
+
+### Checking Out and Building
+*   [Linux Build Instructions](linux_build_instructions.md) - Linux
+*   [Mac Build Instructions](mac_build_instructions.md) - MacOS
+*   [Windows Build Instructions](windows_build_instructions.md) - Windows
+*   [Android Build Instructions](android_build_instructions.md) - Android target
+    (on a Linux host)
+*   [Cast Build Instructions](linux_cast_build_instructions.md) - Cast target
+    (on a Linux host)
+*   [Cast for Android Build Instructions](android_cast_build_instructions.md) -
+    Cast for Android (on a Linux host)
+*   [iOS Build Instructions](ios/build_instructions.md) - iOS target (on a MacOS
+    host)
+*   [Linux Chromium ARM Recipes](linux_chromium_arm.md) - Recipes for building
+    Chromium for ARM on Linux.
+*   [Common Build Tasks](common_build_tasks.md) - Recipes for slightly more
+    advanced build tasks
+*   [Chrome Component Build](component_build.md) - Faster builds using more
+    libraries
+*   [Using the BuildRunner](using_build_runner.md) - Scripts that extract build
+    stops from builders and runs them locally on a slave
+*   [Cr User Manual](cr_user_manual.md) - Manual for `cr`, a tool that tries to
+    hide some of the tools used for working on Chromium behind an abstraction
+    layer
+
+### Integrated Development Environment (IDE) Set Up Guides
+*   [Android Studio](android_studio.md) - Android Studio for Android builds
+*   [Eclipse for Android](eclipse.md) - Eclipse for Android
+*   [Eclipse for Linux](linux_eclipse_dev.md) - Eclipse for other platforms
+    (This guide was written for Linux, but is probably usable on Windows/MacOS
+    as well)
+*   [Qt Creator](qtcreator.md) - Using Qt Creator as an IDE or GUI debugger
+*   [Setting up Visual Studio Code](vscode.md) - Visual Studio Code
+*   [EMACS Notes](emacs.md) - EMACS commands/styles/tool integrations
+*   [Atom](atom.md) - Atom multi-platform code editor
+
+### Git
+*   [Git Cookbook](git_cookbook.md) - A collection of git recipes for common
+    tasks
+*   [Git Tips](git_tips.md) - More git tips
+
+### Clang
+*   [Clang Compiler](clang.md) - General information on the clang compiler, used
+    by default on Mac and Linux
+*   [Clang Tool Refactoring](clang_tool_refactoring.md) - Leveraging clang tools
+    to perform refactorings that are AST-aware
+*   [The Clang Static Analyzer](clang_static_analyzer.md) - How to enable static
+    analysis at build time
+*   [Writing Clang Plugins](writing_clang_plugins.md) - Don't write a clang
+    plugin, but if you do, read this
+*   [Updating Clang](updating_clang.md) - Updating the version of Clang used to
+    build
+*   [Using clang-format on Chromium C++ Code](clang_format.md) - Various ways to
+    invoke clang-format on C++ code
+*   [Clang Tidy](clang_tidy.md) - Support for the `clang-tidy` tool in Chromium
+*   [Updating Clang Format Binaries](updating_clang_format_binaries.md) - How up
+    update the clang-format binaries that come with a checkout of Chromium
+
+### General Development
+*   [Code Reviews](code_reviews.md) - Code review requirements and guidelines
+*   [Closure Compilation](closure_compilation.md) - The _Closure_ JavaScript
+    compiler
+*   [Callback<> and Bind()](callback.md) - All about Callbacks, Closures, and
+    Bind().
+*   [Views Platform Styling](ui/views/platform_style.md) - How views are styled
+    to fit in different native platforms
+*   [Tab Helpers](tab_helpers.md) - Using WebContents/WebContentsObserver to add
+    features to browser tabs.
+*   [Adding third_party Libraries](adding_to_third_party.md) - How to get code
+    into third_party/
+*   [Graphical Debugging Aid for Chromium Views](graphical_debugging_aid_chromium_views.md) -
+    Visualizing view trees during debugging
+*   [Bitmap Pipeline](bitmap_pipeline.md) - How bitmaps are moved from the
+    renderer to the screen.
+*   [base::Optional](optional.md) - How to use `base::Optional` in C++ code.
+*   [Using the Origin Trials Framework](origin_trials_integration.md) - A
+    framework for conditionally enabling experimental APIs for testing.
+*   [`SharedModelTypeProcessor` in Unified Sync and Storage](sync/uss/shared_model_type_processor.md) -
+    Notes on the central data structure used in Chrome Sync.
+*   [Chrome Sync's Model API](sync/model_api.md) - Data models used for syncing
+    information across devices using Chrome Sync.
+*   [Ozone Overview](ozone_overview.md) - Ozone is an abstraction layer between
+    the window system and low level input and graphics.
+*   [Optimizing Chrome Web UIs](optimizing_web_uis.md) - Notes on making webuis
+    more performant
+*   [ES6 Support in Chromium](es6_chromium.md) - Implementation of ECMAScript6
+    features in Chromium
+
+### Testing
+*   [Running and Debugging Layout Tests](testing/layout_tests.md)
+*   [Writing Layout Tests](testing/writing_layout_tests.md) - Layout Tests using
+    `content_shell`
+*   [Layout Test Expectations and Baselines](testing/layout_test_expectations.md) -
+    Setting expected results of layout tests.
+*   [Layout Tests Tips](testing/layout_tests_tips.md) - Best practices for Layout
+    Tests
+*   [Layout Tests with Manual Fallback](testing/layout_tests_with_manual_fallback.md) -
+    Writing tests that simulate manual interventions
+*   [Extending the Layout Test Framework](how_to_extend_layout_test_framework.md)
+*   [Fixing Layout Test Flakiness](testing/identifying_tests_that_depend_on_order.md) -
+    Diagnosing and fixing layout test flakiness due to ordering dependencies.
+*   [Running Layout Tests using `content_shell`](testing/layout_tests_in_content_shell.md) -
+    Running layout tests by hand.
+*   [Testing Browser Dialogs](testing/test_browser_dialog.md) - Using
+    TestBrowserDialog
+*   [Web Platform Tests](testing/web_platform_tests.md) - Shared tests across
+    browser vendors
+*   [Using Breakpad with `content_shell`](testing/using_breakpad_with_content_shell.md) -
+    Capture stack traces on layout test crashes without an attached debugger
+*   [Test Descriptions](test_descriptions.md) - Unit test targets that can be
+    built, with associated desciptions.
+*   [IPC Fuzzer](ipc_fuzzer.md) - Fuzz testing of Chromium IPC interfaces.
+
+### Misc Linux-Specific Docs
+*   [Linux Proxy Config](linux_proxy_config.md) - Network proxy sources on Linux
+*   [Debugging SSL on Linux](linux_debugging_ssl.md) - Tips on debugging SSL
+    code in Linux
+*   [Linux Cert Managment](linux_cert_management.md) - Managing X.509
+    Certificates in Linux
+*   [Tips for Debugging on Linux](linux_debugging.md)
+*   [Linux GTK Theme Integration](linux_gtk_theme_integration.md) - Having
+    Chrome match the GTK+ theme.
+*   [Gtk vs ViewsGtk](gtk_vs_views_gtk.md) - Notes on when to use Gtk vs
+    ViewsGtk
+*   [Browser Plugins on Linux](linux_plugins.md) - A collection of links to
+    information on how browser plugins work on Linux
+*   [Linux Crash Dumping](linux_crash_dumping.md) - How Breakpad uploads crash
+    reports to Google crash servers.
+*   [Linux Minidump to Core](linux_minidump_to_core.md) - How to convert a
+    Breakpad-generated minidump files to a core file readable by most debuggersx
+*   [Linux Sandbox IPC](linux_sandbox_ipc.md) - The lower level UPC system used
+    to route requests from the bottom of the call stack up into the browser.
+*   [Linux Dev Build as Default Browser](linux_dev_build_as_default_browser.md) -
+    How to configure a Dev build of Chrome as the default browser in Linux.
+*   [Linux Chromium Packages](linux_chromium_packages.md) - Packages of Chromium
+    browser (not Chrome) provided by some Linux distributions.
+*   [`seccomp` Sandbox Crash Dumping](seccomp_sandbox_crash_dumping.md) - Notes
+    on crash dumping a process running in a seccomp sandbox.
+*   [Linux Password Storage](linux_password_storage.md) - Keychain integrations
+    between Chromium and Linux.
+*   [Linux Sublime Development](linux_sublime_dev.md) - Using Sublime as an IDE
+    for Chromium development on Linux.
+*   [Building and Debugging GTK](linux_building_debug_gtk.md) - Building
+    Chromium against GTK using lower optimization levels and/or more debugging
+    symbols.
+*   [Debugging GTK](linux_debugging_gtk.md) - Using the GTK Debug packages and
+    related tools.
+*   [Chroot Notes](using_a_linux_chroot.md) - Setting up a chroot to work around
+    libfreetype differences in some versions of Linux.
+*   [Linux Sandboxing](linux_sandboxing.md) - The Linux multi-process model to
+    isolate browser components with different privileges.
+*   [Zygote Process](linux_zygote.md) - How the Linux Zygote process, used to
+    spawn new processes, works.
+*   [Running Layout Tests on Linux](layout_tests_linux.md) - Linux-specific
+    instructions for running layout tests.
+*   [Linux Sysroot Images](linux_sysroot.md) - How builds use libraries on Linux
+*   [`msttcorefonts` on Mandriva](mandriva_msttcorefonts.md) - Getting fonts
+    needed to build Chrome that are not available for Mandriva
+*   [Linux Hardware Video Decoding](linux_hw_video_decode.md) - Enabling
+    hardware video decode codepaths on Linux
+
+### Misc MacOS-Specific Docs
+*   [Using CCache on Mac](ccache_mac.md) - Speed up builds on Mac using ccache
+    with clang/ninja
+*   [Cocoa tips and tricks](cocoa_tips_and_tricks.md) - A collection of idioms
+    used when writing Cocoa views and controllers
+*   [MacViews Release Plan](ui/views/macviews_release.md)
+
+### Misc Windows-Specific Docs
+*   [Handling cygwin rebaseall failures](cygwin_dll_remapping_failure.md)
+*   [Hacking on ANGLE in Chromium](angle_in_chromium.md) - OpenGL ES 2.0 built
+    on top of DirectX
+*   [Retrieveing Code Analysis Warnings](retrieving_code_analysis_warnings.md) -
+    How to retrieve and summarize the warnings generated by Microsoft VC++'s
+    `/analyze` compile option.
+*   [Windows Split DLLs](windows_split_dll.md) - Splitting `chrome.dll` into
+    multiple dlls to work around toolchain limitations on Windows.
+
+### Misc Android-Specific Docs
+*   [Google Play Services in Chrome for Android](google_play_services.md)
+*   [Accessing C++ Enums in Java](android_accessing_cpp_enums_in_java.md) - How
+    to use C++-defined enums in Java code
+*   [Profiling Content Shell on Android](profiling_content_shell_on_android.md) -
+    Setting up profiling for `content_shell` on Android
+*   [Working Remotely with Android](working_remotely_with_android.md) - Building
+    on a remote machine for an Android device connected to your local machine
+*   [Using FindBugs for Android](use_find_bugs_for_android.md) - Using the open
+    source static analysis tool findbugs on the Java code.
+*   [Android Test Instructions](android_test_instructions.md) - Running a build
+    on an Android device or emulator.
+*   [Android Debugging](android_debugging_instructions.md) - Tools and tips for
+    how to debug Java and/or C/C++ code running on Android.
+*   [Android Logging](android_logging.md) - How Chrome's logging API works with
+    `android.util.Log` on Android, and usage guidelines.
+*   [Chromoting Android Hacking](chromoting_android_hacking.md) - Viewing the
+    logs and debugging the Chrome Remote Desktop Android client.
+
+### Misc iOS-Specific Docs
+*   [Continuous Build and Test Infrastructure for Chromium for iOS](ios/infra.md)
+*   [Opening links in Chrome for iOS](ios/opening_links.md) - How to have your
+    iOS app open links in Chrome.
+*   [User Agent in Chrome for iOS](ios/user_agent.md) - Notes on User Agent
+    strings using Chrome for iOS.
+
+### Media
+*   [Audio Focus Handling](media/audio_focus.md) - How multiple MediaSession
+    audio streams interact
+*   [Autoplay of HTMLMediaElements](media/autoplay.md) - How HTMLMediaElements
+    are autoplayed.
+*   [Piranha Plant](piranha_plant.md) - Future architecture of MediaStreams
+
+### Accessibility
+*   [Accessibility Overview](accessibility/overview.md) - Overview of
+    accessibility concerns and approaches in Chromium.
+*   [Accessibility Tests](accessibility/tests.md) - Where to find
+    accessibility-related tests in the codebase.
+*   [ChromeVox on Chrome OS](accessibility/chromevox.md) - Enabling spoken
+    feedback (ChromeVox) on Chrome OS.
+*   [ChromeVox on Desktop Linux](accessibility/chromevox_on_desktop_linux.md) -
+    Enabling spoken feedback (ChromeVox) on desktop Linux.
+*   [BRLTTY in Chrome OS](accessibility/brltty.md) - Chrome OS integration with
+    BRLTTY to support refreshable braille displays
+*   [PATTS on Chrome OS](accessibility/patts.md) - Notes on the PATTS speech
+    sythesis engine used on Chrome OS
+*   [VoiceOver](ios/voiceover.md) - Using Apple's VoiceOver feature with
+    Chromium on iOS.
+
+### Memory Infrastructure Timeline Profiling (MemoryInfra)
+*   [Overview](memory-infra/README.md)
+*   [GPU Profiling](memory-infra/probe-gpu.md)
+*   [Adding Tracing to a Component](memory-infra/adding_memory_infra_tracing.md)
+*   [Enabling Startup Tracing](memory-infra/memory_infra_startup_tracing.md)
+*   [Memory Usage in CC](memory-infra/probe-cc.md)
+*   [Memory Benchmarks](memory-infra/memory_benchmarks.md)
+*   [Heap Profiling](memory-infra/heap_profiler.md)
+*   [Heap Profiling Internals](memory-infra/heap_profiler_internals.md)
+
+### Misc
+*   [Useful URLs](useful_urls.md) - A collection of links to various tools and
+    dashboards
+*   [ERC IRC](erc_irc.md) - Using ERC in EMACS to access IRC
+*   [Kiosk Mode](kiosk_mode.md) - Simulating kiosk mode.
+*   [User Handle Mapping](user_handle_mapping.md) - Names of developers across
+    Chromium/IRC/Google
+*   [Documentation Best Practices](documentation_best_practices.md)
+*   [Documentation Guidelines](documentation_guidelines.md)
+*   [Shift-Based Development](shift_based_development.md) - An experiment in
+    handing off development of coordinated work between developers in different
+    time zones.
+*   [Chromium Browser vs Google Chrome](chromium_browser_vs_google_chrome.md) -
+    What's the difference between _Chromium Browser_ and _Google Chrome_?
+*   [Proxy Auto Config using WPAD](proxy_auto_config.md) - How WPAD servers are
+    used to automatically set proxy settings.
+*   [Installing Chromium OS on VMWare](installation_at_vmware.md) - How to
+    install Chromium OS on VMWare.
+
+### Probably Obsolete
+*   [Old ChromeOS build instructions](old_chromeos_build_instructions.md)
+*   [TPM Quick Reference](tpm_quick_ref.md) - Trusted Platform Module notes.
+*   [System Hardening Features](system_hardening_features.md) - A list of
+    current and planned Chrome OS security features.
+*   [Browser View Resizer](browser_view_resizer.md) - Design doc for making
+    browser window resizing easier on Windows.
+*   [WebView Policies](webview_policies.md)
+*   [Linux Profiling](linux_profiling.md) - How to profile Chromium on Linux
+*   [Linux Graphics Pipeline](linux_graphics_pipeline.md)
+*   [Linux `SUID` Sandbox](linux_suid_sandbox.md) - Sandboxing renderers using a
+    SUID binary on Linux
+*   [Linux `SUID` Sandbox Development](linux_suid_sandbox_development.md) -
+    Development on the above system.
+*   [Linux PID Namespace Support](linux_pid_namespace_support.md)
+*   [Vanilla msysgit workflow](vanilla_msysgit_workflow.md) - A workflow for
+    using mostly vanilla git on Windows.
+*   [Old Chromoting Build Instructions](old_chromoting_build_instructions.md)
+*   [Old Options](chrome_settings.md) - Pre-Material Design chrome://settings
+    notes.
diff --git a/extensions/browser/api/networking_private/networking_private_api.cc b/extensions/browser/api/networking_private/networking_private_api.cc
index e99b5fb..eee7356 100644
--- a/extensions/browser/api/networking_private/networking_private_api.cc
+++ b/extensions/browser/api/networking_private/networking_private_api.cc
@@ -656,6 +656,11 @@
 
 ExtensionFunction::ResponseAction
 NetworkingPrivateStartActivateFunction::Run() {
+  if (!HasPrivateNetworkingAccess(extension(), source_context_type(),
+                                  source_url())) {
+    return RespondNow(Error(kPrivateOnlyError));
+  }
+
   std::unique_ptr<private_api::StartActivate::Params> params =
       private_api::StartActivate::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -958,6 +963,11 @@
 
 ExtensionFunction::ResponseAction
 NetworkingPrivateUnlockCellularSimFunction::Run() {
+  if (!HasPrivateNetworkingAccess(extension(), source_context_type(),
+                                  source_url())) {
+    return RespondNow(Error(kPrivateOnlyError));
+  }
+
   std::unique_ptr<private_api::UnlockCellularSim::Params> params =
       private_api::UnlockCellularSim::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
@@ -992,6 +1002,11 @@
 
 ExtensionFunction::ResponseAction
 NetworkingPrivateSetCellularSimStateFunction::Run() {
+  if (!HasPrivateNetworkingAccess(extension(), source_context_type(),
+                                  source_url())) {
+    return RespondNow(Error(kPrivateOnlyError));
+  }
+
   std::unique_ptr<private_api::SetCellularSimState::Params> params =
       private_api::SetCellularSimState::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json
index 411f8cd..80c5489a 100644
--- a/extensions/common/api/_permission_features.json
+++ b/extensions/common/api/_permission_features.json
@@ -300,7 +300,7 @@
     "extension_types": ["extension", "platform_app"]
   },
   "networking.onc": [{
-    "channel": "dev",
+    "channel": "stable",
     "extension_types": ["platform_app"],
     "platforms": ["chromeos"],
     "session_types": ["kiosk.autolaunched"]
diff --git a/extensions/common/api/networking_onc.idl b/extensions/common/api/networking_onc.idl
new file mode 100644
index 0000000..6e37363
--- /dev/null
+++ b/extensions/common/api/networking_onc.idl
@@ -0,0 +1,1014 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// <p>
+//   The <code>chrome.networking.onc</code> API is used for configuring
+//   network connections (Cellular, Ethernet, VPN, WiFi or WiMAX).
+//   This API is available in Chrome OS kiosk sessions.
+// </p>
+// <p>
+//   Network connection configurations are specified following
+//   <a href="https://chromium.googlesource.com/chromium/src/+/master/components/onc/docs/onc_spec.md">
+//   Open Network Configuration (ONC)</a> specification.
+// </p>
+// <p>
+//   <b>NOTE</b>: Most dictionary properties and enum values use UpperCamelCase
+//   to match the ONC specification instead of the JavaScript lowerCamelCase
+//   convention.
+// </p>
+namespace networking.onc {
+  enum ActivationStateType {
+    Activated, Activating, NotActivated, PartiallyActivated
+  };
+
+  enum CaptivePortalStatus {
+    Unknown, Offline, Online, Portal, ProxyAuthRequired
+  };
+
+  enum ConnectionStateType {
+    Connected, Connecting, NotConnected
+  };
+
+  enum DeviceStateType {
+    // Device is available but not initialized.
+    Uninitialized,
+    // Device is initialized but not enabled.
+    Disabled,
+    // Enabled state has been requested but has not completed.
+    Enabling,
+    // Device is enabled.
+    Enabled,
+    // Device is prohibited.
+    Prohibited
+  };
+
+  enum IPConfigType {
+    DHCP, Static
+  };
+
+  enum NetworkType {
+    All, Cellular, Ethernet, VPN, Wireless, WiFi, WiMAX
+  };
+
+  enum ProxySettingsType {
+    Direct, Manual, PAC, WPAD
+  };
+
+  enum ClientCertificateType {
+    Ref, Pattern
+  };
+
+  dictionary ManagedBoolean {
+    // The active value currently used by the network configuration manager
+    // (e.g. Shill).
+    boolean? Active;
+    // The source from which the effective property value was determined.
+    DOMString? Effective;
+    // The property value provided by the user policy.
+    boolean? UserPolicy;
+    // The property value provided by the device policy.
+    boolean? DevicePolicy;
+    // The property value set by the logged in user. Only provided if
+    // |UserEditable| is <code>true</code>.
+    boolean? UserSetting;
+    // The value set for all users of the device. Only provided if
+    // |DeviceEditiable| is <code>true</code>.
+    boolean? SharedSetting;
+    // Whether a UserPolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? UserEditable;
+    // Whether a DevicePolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? DeviceEditable;
+  };
+
+  dictionary ManagedLong {
+    // The active value currently used by the network configuration manager
+    // (e.g. Shill).
+    long? Active;
+    // The source from which the effective property value was determined.
+    DOMString? Effective;
+    // The property value provided by the user policy.
+    long? UserPolicy;
+    // The property value provided by the device policy.
+    long? DevicePolicy;
+    // The property value set by the logged in user. Only provided if
+    // |UserEditable| is <code>true</code>.
+    long? UserSetting;
+    // The value set for all users of the device. Only provided if
+    // |DeviceEditiable| is <code>true</code>.
+    long? SharedSetting;
+    // Whether a UserPolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? UserEditable;
+    // Whether a DevicePolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? DeviceEditable;
+  };
+
+  dictionary ManagedDOMString {
+    // The active value currently used by the network configuration manager
+    // (e.g. Shill).
+    DOMString? Active;
+    // The source from which the effective property value was determined.
+    DOMString? Effective;
+    // The property value provided by the user policy.
+    DOMString? UserPolicy;
+    // The property value provided by the device policy.
+    DOMString? DevicePolicy;
+    // The property value set by the logged in user. Only provided if
+    // |UserEditable| is <code>true</code>.
+    DOMString? UserSetting;
+    // The value set for all users of the device. Only provided if
+    // |DeviceEditiable| is <code>true</code>.
+    DOMString? SharedSetting;
+    // Whether a UserPolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? UserEditable;
+    // Whether a DevicePolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? DeviceEditable;
+  };
+
+  dictionary ManagedDOMStringList {
+    // The active value currently used by the network configuration manager
+    // (e.g. Shill).
+    DOMString[]? Active;
+    // The source from which the effective property value was determined.
+    DOMString? Effective;
+    // The property value provided by the user policy.
+    DOMString[]? UserPolicy;
+    // The property value provided by the device policy.
+    DOMString[]? DevicePolicy;
+    // The property value set by the logged in user. Only provided if
+    // |UserEditable| is <code>true</code>.
+    DOMString[]? UserSetting;
+    // The value set for all users of the device. Only provided if
+    // |DeviceEditiable| is <code>true</code>.
+    DOMString[]? SharedSetting;
+    // Whether a UserPolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? UserEditable;
+    // Whether a DevicePolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? DeviceEditable;
+  };
+
+  dictionary ManagedIPConfigType {
+    // The active value currently used by the network configuration manager
+    // (e.g. Shill).
+    IPConfigType? Active;
+    // The source from which the effective property value was determined.
+    DOMString? Effective;
+    // The property value provided by the user policy.
+    IPConfigType? UserPolicy;
+    // The property value provided by the device policy.
+    IPConfigType? DevicePolicy;
+    // The property value set by the logged in user. Only provided if
+    // |UserEditable| is <code>true</code>.
+    IPConfigType? UserSetting;
+    // The value set for all users of the device. Only provided if
+    // |DeviceEditiable| is <code>true</code>.
+    IPConfigType? SharedSetting;
+    // Whether a UserPolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? UserEditable;
+    // Whether a DevicePolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? DeviceEditable;
+  };
+
+  dictionary ManagedProxySettingsType {
+    // The active value currently used by the network configuration manager
+    // (e.g. Shill).
+    ProxySettingsType? Active;
+    // The source from which the effective property value was determined.
+    DOMString? Effective;
+    // The property value provided by the user policy.
+    ProxySettingsType? UserPolicy;
+    // The property value provided by the device policy.
+    ProxySettingsType? DevicePolicy;
+    // The property value set by the logged in user. Only provided if
+    // |UserEditable| is <code>true</code>.
+    ProxySettingsType? UserSetting;
+    // The value set for all users of the device. Only provided if
+    // |DeviceEditiable| is <code>true</code>.
+    ProxySettingsType? SharedSetting;
+    // Whether a UserPolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? UserEditable;
+    // Whether a DevicePolicy for the property exists and allows the property to
+    // be edited (i.e. the policy set recommended property value).
+    // Defaults to <code>false</code>.
+    boolean? DeviceEditable;
+  };
+
+  // Sub-dictionary types.
+
+  dictionary CellularProviderProperties {
+    // The operator name.
+    DOMString Name;
+    // Cellular network ID as a simple concatenation of the network's
+    // MCC (Mobile Country Code) and MNC (Mobile Network Code).
+    DOMString Code;
+    // The two-letter country code.
+    DOMString? Country;
+  };
+
+  dictionary IssuerSubjectPattern {
+    // If set, the value against which to match the certificate subject's
+    // common name.
+    DOMString? CommonName;
+    // If set, the value against which to match the certificate subject's
+    // common location.
+    DOMString? Locality;
+    // If set, the value against which to match the certificate subject's
+    // organizations. At least one organization should match the value.
+    DOMString? Organization;
+    // If set, the value against which to match the certificate subject's
+    // organizational units. At least one organizational unit should match the
+    // value.
+    DOMString? OrganizationalUnit;    
+  };
+
+  dictionary CertificatePattern {
+    // List of URIs to which the user can be directed in case no certificates
+    // that match this pattern are found.
+    DOMString[]? EnrollmentURI;
+    // If set, pattern against which X.509 issuer settings should be matched.
+    IssuerSubjectPattern? Issuer;
+    // List of certificate issuer CA certificates. A certificate must be signed
+    // by one of them in order to match this pattern.
+    DOMString[]? IssuerCARef;
+    // If set, pattern against which X.509 subject settings should be matched.
+    IssuerSubjectPattern? Subject;
+  };
+
+  dictionary EAPProperties {
+    DOMString? AnonymousIdentity;
+    CertificatePattern? ClientCertPattern;
+    DOMString? ClientCertRef;
+    ClientCertificateType ClientCertType;
+    DOMString? Identity;
+    DOMString? Inner;
+    DOMString Outer;
+    DOMString? Password;
+    boolean? SaveCredentials;
+    DOMString[]? ServerCARefs;
+    boolean? UseProactiveKeyCaching;
+    boolean? UseSystemCAs;
+  };
+
+  dictionary FoundNetworkProperties {
+    // Network availability.
+    DOMString Status;
+    // Network ID.
+    DOMString NetworkId;
+    // Access technology used by the network.
+    DOMString Technology;
+    // The network operator's short-format name.
+    DOMString? ShortName;
+    // The network operator's long-format name.
+    DOMString? LongName;
+  };
+
+  dictionary IPConfigProperties {
+    // Gateway address used for the IP configuration.
+    DOMString? Gateway;
+    // The IP address for a connection. Can be IPv4 or IPv6 address, depending
+    // on value of <code>Type</code>.
+    DOMString? IPAddress;
+    // Array of addresses used for name servers.
+    DOMString[]? NameServers;
+    // The routing prefix.
+    long? RoutingPrefix;
+    // The IP configuration type. Can be <code>IPv4</code> or <code>IPv6</code>.
+    DOMString? Type;
+    // The URL for WEb Proxy Auto-Discovery, as reported over DHCP.
+    DOMString? WebProxyAutoDiscoveryUrl;
+  };
+
+  dictionary ManagedIPConfigProperties {
+    // See $(ref:IPConfigProperties.Gateway).
+    ManagedDOMString? Gateway;
+    // See $(ref:IPConfigProperties.IPAddress).
+    ManagedDOMString? IPAddress;
+    // See $(ref:IPConfigProperties.NameServers).
+    ManagedDOMStringList? NameServers;
+    // See $(ref:IPConfigProperties.RoutingPrefix).
+    ManagedLong? RoutingPrefix;
+    // See $(ref:IPConfigProperties.Type).
+    ManagedDOMString? Type;
+    // See $(ref:IPConfigProperties.WebProxyAutoDiscoveryUrl).
+    ManagedDOMString? WebProxyAutoDiscoveryUrl;
+  };
+
+  dictionary PaymentPortal {
+    // The HTTP method to use for the payment portal.
+    DOMString Method;
+    // The post data to send to the payment portal. Ignored unless
+    // <code>Method</code> is <code>POST</code>.
+    DOMString? PostData;
+    // The payment portal URL.
+    DOMString? Url;
+  };
+
+  dictionary ProxyLocation {
+    // The proxy IP address host.
+    DOMString Host;
+    // The port to use for the proxy.
+    long Port;
+  };
+
+  dictionary ManagedProxyLocation {
+    // See $(ref:ProxyLocation.Host).
+    ManagedDOMString Host;
+    // See $(ref:ProxyLocation.Port).
+    ManagedLong Port;
+  };
+
+  [noinline_doc] dictionary ManualProxySettings {
+    // Settings for HTTP proxy.
+    ProxyLocation? HTTPProxy;
+    // Settings for secure HTTP proxy.
+    ProxyLocation? SecureHTTPProxy;
+    // Settings for FTP proxy.
+    ProxyLocation? FTPProxy;
+    // Settings for SOCKS proxy.
+    ProxyLocation? SOCKS;
+  };
+
+  dictionary ManagedManualProxySettings {
+    // See $(ref:ManualProxySettings.HTTPProxy).
+    ManagedProxyLocation? HTTPProxy;
+    // See $(ref:ManualProxySettings.SecureHTTPProxy).
+    ManagedProxyLocation? SecureHTTPProxy;
+    // See $(ref:ManualProxySettings.FTPProxy).
+    ManagedProxyLocation? FTPProxy;
+    // See $(ref:ManualProxySettings.SOCKS).
+    ManagedProxyLocation? SOCKS;
+  };
+
+  [noinline_doc] dictionary ProxySettings {
+    // The type of proxy settings.
+    ProxySettingsType Type;
+    // Manual proxy settings - used only for <code>Manual</code> proxy settings.
+    ManualProxySettings? Manual;
+    // Domains and hosts for which manual proxy settings are excluded.
+    DOMString[]? ExcludeDomains;
+    // URL for proxy auto-configuration file.
+    DOMString? PAC;
+  };
+
+  dictionary ManagedProxySettings {
+    // See $(ref:ProxySettings.Type).
+    ManagedProxySettingsType Type;
+    // See $(ref:ProxySettings.Manual).
+    ManagedManualProxySettings? Manual;
+    // See $(ref:ProxySettings.ExcludeDomains).
+    ManagedDOMStringList? ExcludeDomains;
+    // See $(ref:ProxySettings.PAC).
+    ManagedDOMString? PAC;
+  };
+
+  dictionary SIMLockStatus {
+    // The status of SIM lock - possible values are <code>'sim-pin'</code>,
+    // <code>'sim-puk'</code> and <code>''</code>.
+    DOMString LockType;
+    // Whether SIM lock is enabled.
+    boolean LockEnabled;
+    // Number of PIN lock tries allowed before PUK is required to unlock the
+    // SIM.
+    long? RetriesLeft;
+  };
+
+  dictionary ThirdPartyVPNProperties {
+    // ID of the third-party VPN provider extension.
+    DOMString ExtensionID;
+    // The VPN provider name.
+    DOMString? ProviderName;
+  };
+
+  dictionary ManagedThirdPartyVPNProperties {
+    // See $(ref:ThirdPartyVPNProperties.ExtensionID).
+    ManagedDOMString ExtensionID;
+    // See $(ref:ThirdPartyVPNProperties.ProviderName).
+    DOMString? ProviderName;
+  };
+
+  // Network type dictionary types.
+
+  [noinline_doc] dictionary CellularProperties {
+    // Whether the cellular network should be connected automatically (when
+    // in range). 
+    boolean? AutoConnect;
+    // The cellular network activation type.
+    DOMString? ActivationType;
+    // Carrier account activation state.
+    ActivationStateType? ActivationState;
+    // Whether roaming is allowed for the network.
+    boolean? AllowRoaming;
+    // The name of the carrier for which the cellular device is configured.
+    DOMString? Carrier;
+    // Cellular device technology family - <code>CDMA</code> or
+    // <code>GSM</code>.
+    DOMString? Family;
+    // The firmware revision loaded in the cellular modem.
+    DOMString? FirmwareRevision;
+    // The list of networks found during the most recent network scan.
+    FoundNetworkProperties[]? FoundNetworks;
+    // The cellular modem hardware revision.
+    DOMString? HardwareRevision;
+    // Information about the operator that issued the SIM card currently
+    // installed in the modem.
+    CellularProviderProperties? HomeProvider;
+    // The cellular modem manufacturer.
+    DOMString? Manufacturer;
+    // The cellular modem model ID.
+    DOMString? ModelID;
+    // If the modem is registered on a network, the network technology
+    // currently in use.
+    DOMString? NetworkTechnology;
+    // Online payment portal a user can use to sign-up for or modify a mobile
+    // data plan.
+    PaymentPortal? PaymentPortal;
+    // The revision of the Preferred Roaming List loaded in the modem.
+    long? PRLVersion;
+    // The roaming state of the cellular modem on the current network.
+    DOMString? RoamingState;
+    // Information about the operator on whose network the modem is currently
+    // registered.
+    CellularProviderProperties? ServingOperator;
+    // The state of SIM lock for GSM family networks.
+    SIMLockStatus? SIMLockStatus;
+    // Whether a SIM card is present.
+    boolean? SIMPresent;
+     // The current network signal strength.
+    long? SignalStrength;
+    // Whether the cellular network supports scanning.
+    boolean? SupportNetworkScan;
+    // A list of supported carriers.
+    DOMString[]? SupportedCarriers;
+  };
+
+  dictionary ManagedCellularProperties {
+    // See $(ref:CellularProperties.AutoConnect).
+    ManagedBoolean? AutoConnect;
+    // See $(ref:CellularProperties.ActivationType).
+    DOMString? ActivationType;
+    // See $(ref:CellularProperties.ActivationState).
+    ActivationStateType? ActivationState;
+    // See $(ref:CellularProperties.AllowRoaming).
+    boolean? AllowRoaming;
+    // See $(ref:CellularProperties.Carrier).
+    ManagedDOMString? Carrier;
+    // See $(ref:CellularProperties.Family).
+    DOMString? Family;
+    // See $(ref:CellularProperties.FirmwareRevision).
+    DOMString? FirmwareRevision;
+    // See $(ref:CellularProperties.FoundNetworks).
+    FoundNetworkProperties[]? FoundNetworks;
+    // See $(ref:CellularProperties.HardwareRevision).
+    DOMString? HardwareRevision;
+    // See $(ref:CellularProperties.HomeProvider).
+    CellularProviderProperties[]? HomeProvider;
+    // See $(ref:CellularProperties.Manufacturer).
+    DOMString? Manufacturer;
+    // See $(ref:CellularProperties.ModelID).
+    DOMString? ModelID;
+    // See $(ref:CellularProperties.NetworkTechnology).
+    DOMString? NetworkTechnology;
+    // See $(ref:CellularProperties.PaymentPortal).
+    PaymentPortal? PaymentPortal;
+    // See $(ref:CellularProperties.PRLVersion).
+    long? PRLVersion;
+    // See $(ref:CellularProperties.RoamingState).
+    DOMString? RoamingState;
+    // See $(ref:CellularProperties.ServingOperator).
+    CellularProviderProperties? ServingOperator;
+    // See $(ref:CellularProperties.SIMLockStatus).
+    SIMLockStatus? SIMLockStatus;
+    // See $(ref:CellularProperties.SIMPresent).
+    boolean? SIMPresent;
+    // See $(ref:CellularProperties.SignalStrength).
+    long? SignalStrength;
+    // See $(ref:CellularProperties.SupportNetworkScan).
+    boolean? SupportNetworkScan;
+    // See $(ref:CellularProperties.SupportedCarriers).
+    DOMString[]? SupportedCarriers;
+  };
+
+  dictionary CellularStateProperties {
+    // See $(ref:CellularProperties.ActivationState).
+    ActivationStateType? ActivationState;
+    // See $(ref:CellularProperties.NetworkTechnology).
+    DOMString? NetworkTechnology;
+    // See $(ref:CellularProperties.RoamingState).
+    DOMString? RoamingState;
+    // See $(ref:CellularProperties.SIMPresent).
+    boolean? SIMPresent;
+    // See $(ref:CellularProperties.SignalStrength).
+    long? SignalStrength;
+  };
+
+  dictionary EthernetProperties {
+    // Whether the Ethernet network should be connected automatically. 
+    boolean? AutoConnect;
+    // The authentication used by the Ethernet network. Possible values are
+    // <code>None</code> and <code>8021X</code>.
+    DOMString? Authentication;
+    // Network's EAP settings. Required for 8021X authentication.
+    EAPProperties? EAP;
+  };
+
+  dictionary ManagedEthernetProperties {
+    // See $(ref:EthernetProperties.AutoConnect).
+    ManagedBoolean? AutoConnect;
+    // See $(ref:EthernetProperties.Authentication).
+    ManagedDOMString? Authentication;
+  };
+
+  dictionary EthernetStateProperties {
+    // See $(ref:EthernetProperties.Authentication).
+    DOMString Authentication;
+  };
+
+  dictionary VPNProperties {
+    // Whether the VPN network should be connected automatically.
+    boolean? AutoConnect;
+    // The VPN host.
+    DOMString? Host;
+    // The VPN type.
+    DOMString? Type;
+  };
+
+  dictionary ManagedVPNProperties {
+    // See $(ref:VPNProperties.AutoConnect).
+    ManagedBoolean? AutoConnect;
+    // See $(ref:VPNProperties.Host).
+    ManagedDOMString? Host;
+    // See $(ref:VPNProperties.Type).
+    ManagedDOMString Type;
+  };
+
+  dictionary VPNStateProperties {
+    // See $(ref:VPNProperties.Type).
+    DOMString Type;
+  };
+
+  [noinline_doc] dictionary WiFiProperties {
+    // Whether ARP polling of default gateway is allowed. Defaults to true.
+    boolean? AllowGatewayARPPolling;
+    // Whether the WiFi network should be connected automatically when in range.
+    boolean? AutoConnect;
+    // The BSSID of the associated access point..
+    DOMString? BSSID;
+    // The network EAP properties. Required for <code>WEP-8021X</code> and
+    // <code>WPA-EAP</code> networks.
+    EAPProperties? EAP;
+    // The WiFi service operating frequency in MHz. For connected networks, the
+    // current frequency on which the network is connected. Otherwise, the
+    // frequency of the best available BSS.
+    long? Frequency;
+    // Contains all operating frequency recently seen for the WiFi network.
+    long[]? FrequencyList;
+    // HEX-encoded copy of the network SSID.
+    DOMString? HexSSID;
+    // Whether the network SSID will be broadcast.
+    boolean? HiddenSSID;
+    // Signal-to-noise value (in dB) below which roaming to a new network
+    // should be attempted.
+    long? RoamThreshold;
+    // The network SSID.
+    DOMString? SSID;
+    // The network security type.
+    DOMString? Security;
+    // The network signal strength.
+    long? SignalStrength;
+  };
+
+  dictionary ManagedWiFiProperties {
+    // See $(ref:WiFiProperties.AllowGatewayARPPolling).
+    ManagedBoolean? AllowGatewayARPPolling;
+    // See $(ref:WiFiProperties.AutoConnect).
+    ManagedBoolean? AutoConnect;
+    // See $(ref:WiFiProperties.BSSID).
+    DOMString? BSSID;
+    // See $(ref:WiFiProperties.Frequency).
+    long? Frequency;
+    // See $(ref:WiFiProperties.FrequencyList).
+    long[]? FrequencyList;
+    // See $(ref:WiFiProperties.HexSSID).
+    ManagedDOMString? HexSSID;
+    // See $(ref:WiFiProperties.HiddenSSID).
+    ManagedBoolean? HiddenSSID;
+    // See $(ref:WiFiProperties.RoamThreshold).
+    ManagedLong? RoamThreshold;
+    // See $(ref:WiFiProperties.SSID).
+    ManagedDOMString? SSID;
+    // See $(ref:WiFiProperties.Security).
+    ManagedDOMString Security;
+    // See $(ref:WiFiProperties.SignalStrength).
+    long? SignalStrength;
+  };
+
+  dictionary WiFiStateProperties {
+    // See $(ref:WiFiProperties.BSSID).
+    DOMString? BSSID;
+    // See $(ref:WiFiProperties.Frequency).
+    long? Frequency;
+    // See $(ref:WiFiProperties.Security).
+    DOMString Security;
+    // See $(ref:WiFiProperties.SignalStrength).
+    long? SignalStrength;
+  };
+
+  dictionary WiMAXProperties {
+    // Whether the network should be connected automatically.
+    boolean? AutoConnect;
+    // The network EAP properties.
+    EAPProperties? EAP;
+    // The network signal strength.
+    long? SignalStrength;
+  };
+
+  dictionary ManagedWiMAXProperties {
+    // See $(ref:WiMAXProperties.AutoConnect).
+    ManagedBoolean? AutoConnect;
+    // See $(ref:WiMAXProperties.SignalStrength).
+    long? SignalStrength;
+  };
+
+  dictionary WiMAXStateProperties {
+    // See $(ref:WiMAXProperties.SignalStrength).
+    long? SignalStrength;
+  };
+
+  dictionary NetworkConfigProperties {
+    // See $(ref:NetworkProperties.Cellular).
+    CellularProperties? Cellular;
+    // See $(ref:NetworkProperties.Ethernet).
+    EthernetProperties? Ethernet;
+    // See $(ref:NetworkProperties.GUID).
+    DOMString? GUID;
+    // See $(ref:NetworkProperties.IPAddressConfigType).
+    IPConfigType? IPAddressConfigType;
+    // See $(ref:NetworkProperties.Name).
+    DOMString? Name;
+    // See $(ref:NetworkProperties.NameServersConfigType).
+    IPConfigType? NameServersConfigType;
+    // See $(ref:NetworkProperties.Priority).
+    long? Priority;
+    // See $(ref:NetworkProperties.Type).
+    NetworkType? Type;
+    // See $(ref:NetworkProperties.VPN).
+    VPNProperties? VPN;
+    // See $(ref:NetworkProperties.WiFi).
+    WiFiProperties? WiFi;
+    // See $(ref:NetworkProperties.WiMAX).
+    WiMAXProperties? WiMAX;
+  };
+
+  [noinline_doc]
+  dictionary NetworkProperties {
+    // For cellular networks, cellular network properties.
+    CellularProperties? Cellular;
+    // Whether the network is connectable.
+    boolean? Connectable;
+    // The network's current connection state.
+    ConnectionStateType? ConnectionState;
+    // The last recorded network error state.
+    DOMString? ErrorState;
+    // For Ethernet networks, the Ethernet network properties.
+    EthernetProperties? Ethernet;
+    // The network GUID.
+    DOMString GUID;
+    // The network's IP address configuration type.
+    IPConfigType? IPAddressConfigType;
+    // The network's IP configuration.
+    IPConfigProperties[]? IPConfigs;
+    // The network's MAC address.
+    DOMString? MacAddress;
+    // A user friendly network name.
+    DOMString? Name;
+    // The IP configuration type for the name servers used by the network.
+    IPConfigType? NameServersConfigType;
+    // The network priority.
+    long? Priority;
+    // The network's proxy settings.
+    ProxySettings? ProxySettings;
+    // For a connected network, whether the network connectivity to the
+    // Internet is limited, e.g. if the network is behind a portal, or a
+    // cellular network is not activated.
+    boolean? RestrictedConnectivity;
+    // The network's static IP configuration.
+    IPConfigProperties? StaticIPConfig;
+    // IP configuration that was received from the DHCP server before applying
+    // static IP configuration.
+    IPConfigProperties? SavedIPConfig;
+    // Indicates whether and how the network is configured.
+    DOMString? Source;
+    // The network type.
+    NetworkType Type;
+    // For VPN networks, the network VPN properties.
+    VPNProperties? VPN;
+    // For WiFi networks, the network WiFi properties.
+    WiFiProperties? WiFi;
+    // For WiMAX networks, the network WiMAX properties.
+    WiMAXProperties? WiMAX;
+  };
+
+  [noinline_doc]
+  dictionary ManagedProperties {
+    // See $(ref:NetworkProperties.Cellular).
+    ManagedCellularProperties? Cellular;
+    // See $(ref:NetworkProperties.Connectable).
+    boolean? Connectable;
+    // See $(ref:NetworkProperties.ConnectionState).
+    ConnectionStateType? ConnectionState;
+    // See $(ref:NetworkProperties.ErrorState).
+    DOMString? ErrorState;
+    // See $(ref:NetworkProperties.Ethernet).
+    ManagedEthernetProperties? Ethernet;
+    // See $(ref:NetworkProperties.GUID).
+    DOMString GUID;
+    // See $(ref:NetworkProperties.IPAddressConfigType).
+    ManagedIPConfigType? IPAddressConfigType;
+    // See $(ref:NetworkProperties.IPConfigs).
+    IPConfigProperties[]? IPConfigs;
+    // See $(ref:NetworkProperties.MacAddress).
+    DOMString? MacAddress;
+    // See $(ref:NetworkProperties.Name).
+    ManagedDOMString? Name;
+    // See $(ref:NetworkProperties.NameServersConfigType).
+    ManagedIPConfigType? NameServersConfigType;
+    // See $(ref:NetworkProperties.Priority).
+    ManagedLong? Priority;
+    // See $(ref:NetworkProperties.ProxySettings).
+    ManagedProxySettings? ProxySettings;
+    // See $(ref:NetworkProperties.RestrictedConnectivity).
+    boolean? RestrictedConnectivity;
+    // See $(ref:NetworkProperties.StaticIPConfig).
+    ManagedIPConfigProperties? StaticIPConfig;
+    // See $(ref:NetworkProperties.SavedIPConfig).
+    IPConfigProperties? SavedIPConfig;
+    // See $(ref:NetworkProperties.Source).
+    DOMString? Source;
+    // See $(ref:NetworkProperties.Type).
+    NetworkType Type;
+    // See $(ref:NetworkProperties.VPN).
+    ManagedVPNProperties? VPN;
+    // See $(ref:NetworkProperties.WiFi).
+    ManagedWiFiProperties? WiFi;
+    // See $(ref:NetworkProperties.WiMAX).
+    ManagedWiMAXProperties? WiMAX;
+  };
+
+  dictionary NetworkStateProperties {
+    // See $(ref:NetworkProperties.Cellular).
+    CellularStateProperties? Cellular;
+    // See $(ref:NetworkProperties.Connectable).
+    boolean? Connectable;
+    // See $(ref:NetworkProperties.ConnectionState).
+    ConnectionStateType? ConnectionState;
+    // See $(ref:NetworkProperties.Ethernet).
+    EthernetStateProperties? Ethernet;
+    // See $(ref:NetworkProperties.ErrorState).
+    DOMString? ErrorState;
+    // See $(ref:NetworkProperties.GUID).
+    DOMString GUID;
+    // See $(ref:NetworkProperties.Name).
+    DOMString? Name;
+    // See $(ref:NetworkProperties.Priority).
+    long? Priority;
+    // See $(ref:NetworkProperties.Source).
+    DOMString? Source;
+    // See $(ref:NetworkProperties.Type).
+    NetworkType Type;
+    // See $(ref:NetworkProperties.VPN).
+    VPNStateProperties? VPN;
+    // See $(ref:NetworkProperties.WiFi).
+    WiFiStateProperties? WiFi;
+    // See $(ref:NetworkProperties.WiMAX).
+    WiMAXStateProperties? WiMAX;
+  };
+
+  dictionary DeviceStateProperties {
+    // Set if the device is enabled. True if the device is currently scanning.
+    boolean? Scanning;
+
+    // Set to the SIM lock type if the device type is Cellular and the device
+    // is locked.
+    DOMString? SimLockType;
+
+    // Set to the SIM present state if the device type is Cellular.
+    boolean? SimPresent;
+
+    // The current state of the device.
+    DeviceStateType State;
+
+    // The network type associated with the device (Cellular, Ethernet, WiFi, or
+    // WiMAX).
+    NetworkType Type;
+  };
+
+  dictionary NetworkFilter {
+    // The type of networks to return.
+    NetworkType networkType;
+
+    // If true, only include visible (physically connected or in-range)
+    // networks. Defaults to 'false'.
+    boolean? visible;
+
+    // If true, only include configured (saved) networks. Defaults to 'false'.
+    boolean? configured;
+
+    // Maximum number of networks to return. Defaults to 1000 if unspecified.
+    // Use 0 for no limit.
+    long? limit;
+  };
+
+  dictionary GlobalPolicy {
+    // If true, only policy networks may auto connect. Defaults to false.
+    boolean? AllowOnlyPolicyNetworksToAutoconnect;
+
+    // If true, only policy networks may be connected to and no new networks may
+    // be added or configured. Defaults to false.
+    boolean? AllowOnlyPolicyNetworksToConnect;
+  };
+
+  callback VoidCallback = void();
+  callback BooleanCallback = void(boolean result);
+  callback StringCallback = void(DOMString result);
+  callback GetPropertiesCallback = void(NetworkProperties result);
+  callback GetManagedPropertiesCallback = void(ManagedProperties result);
+  callback GetStatePropertiesCallback = void(NetworkStateProperties result);
+  callback GetNetworksCallback = void(NetworkStateProperties[] result);
+  callback GetDeviceStatesCallback = void(DeviceStateProperties[] result);
+  callback GetEnabledNetworkTypesCallback = void(NetworkType[] result);
+  callback CaptivePortalStatusCallback = void(CaptivePortalStatus result);
+  callback GetGlobalPolicyCallback = void(GlobalPolicy result);
+
+  interface Functions {
+    // Gets all the properties of the network with id networkGuid. Includes all
+    // properties of the network (read-only and read/write values).
+    // |networkGuid|: The GUID of the network to get properties for.
+    // |callback|: Called with the network properties when received.
+    static void getProperties(DOMString networkGuid,
+                              GetPropertiesCallback callback);
+
+    // Gets the merged properties of the network with id networkGuid from the
+    // sources: User settings, shared settings, user policy, device policy and
+    // the currently active settings.
+    // |networkGuid|: The GUID of the network to get properties for.
+    // |callback|: Called with the managed network properties when received.
+    static void getManagedProperties(DOMString networkGuid,
+                                     GetManagedPropertiesCallback callback);
+
+    // Gets the cached read-only properties of the network with id networkGuid.
+    // This is meant to be a higher performance function than
+    // $(ref:getProperties), which requires a round trip to query the networking
+    // subsystem. The following properties are returned for all networks: GUID,
+    // Type, Name, WiFi.Security. Additional properties are provided for visible
+    // networks: ConnectionState, ErrorState, WiFi.SignalStrength,
+    // Cellular.NetworkTechnology, Cellular.ActivationState,
+    // Cellular.RoamingState.
+    // |networkGuid|: The GUID of the network to get properties for.
+    // |callback|: Called immediately with the network state properties.
+    static void getState(DOMString networkGuid,
+                         GetStatePropertiesCallback callback);
+
+    // Sets the properties of the network with id networkGuid.
+    // <b>
+    //   In kiosk sessions, calling this method on a shared network will fail.
+    // </b>
+    // |networkGuid|: The GUID of the network to set properties for.
+    // |properties|: The properties to set.
+    // |callback|: Called when the operation has completed.
+    static void setProperties(DOMString networkGuid,
+                              NetworkConfigProperties properties,
+                              optional VoidCallback callback);
+
+    // Creates a new network configuration from properties. If a matching
+    // configured network already exists, this will fail. Otherwise returns the
+    // GUID of the new network.
+    // |shared|: <p>
+    //     If <code>true</code>, share this network configuration with
+    //     other users.
+    //     </p>
+    //     <p>
+    //       <b>This option is exposed only to Chrome's Web UI.</b>
+    //       When called by apps, <code>false</code> is the only allowed value.
+    //     </p>
+    // |properties|: The properties to configure the new network with.
+    // |callback|: Called with the GUID for the new network configuration once
+    //     the network has been created.
+    static void createNetwork(boolean shared,
+                              NetworkConfigProperties properties,
+                              optional StringCallback callback);
+
+    // <p>
+    //   Forgets a network configuration by clearing any configured properties
+    //   for the network with GUID <code>networkGuid</code>. This may also
+    //   include any other networks with matching identifiers (e.g. WiFi SSID
+    //   and Security). If no such configuration exists, an error will be set
+    //   and the operation will fail.
+    // </p>
+    // <p>
+    //   <b>In kiosk sessions, this method will not be able to forget shared
+    //      network configurations.</b>
+    // </p>
+    // |networkGuid|: The GUID of the network to forget.
+    // |callback|: Called when the operation has completed.
+    static void forgetNetwork(DOMString networkGuid,
+                              optional VoidCallback callback);
+
+    // Returns a list of network objects with the same properties provided by
+    // $(ref:getState). A filter is provided to specify the
+    // type of networks returned and to limit the number of networks. Networks
+    // are ordered by the system based on their priority, with connected or
+    // connecting networks listed first.
+    // |filter|: Describes which networks to return.
+    // |callback|: Called with a dictionary of networks and their state
+    //     properties when received.
+    static void getNetworks(NetworkFilter filter,
+                            GetNetworksCallback callback);
+
+    // Returns states of available networking devices.
+    // |callback|: Called with a list of devices and their state.
+    static void getDeviceStates(GetDeviceStatesCallback callback);
+
+    // Enables any devices matching the specified network type. Note, the type
+    // might represent multiple network types (e.g. 'Wireless').
+    // |networkType|: The type of network to enable.
+    static void enableNetworkType(NetworkType networkType);
+
+    // Disables any devices matching the specified network type. See note for
+    // $(ref:enableNetworkType).
+    // |networkType|: The type of network to disable.
+    static void disableNetworkType(NetworkType networkType);
+
+    // Requests that the networking subsystem scan for new networks and
+    // update the list returned by $(ref:getNetworks). This is only a
+    // request: the network subsystem can choose to ignore it.  If the list
+    // is updated, then the $(ref:onNetworkListChanged) event will be fired.
+    static void requestNetworkScan();
+
+    // Starts a connection to the network with networkGuid.
+    // |networkGuid|: The GUID of the network to connect to.
+    // |callback|: Called when the connect request has been sent. Note: the
+    //     connection may not have completed. Observe $(ref:onNetworksChanged)
+    //     to be notified when a network state changes.
+    static void startConnect(DOMString networkGuid,
+                             optional VoidCallback callback);
+
+    // Starts a disconnect from the network with networkGuid.
+    // |networkGuid|: The GUID of the network to disconnect from.
+    // |callback|: Called when the disconnect request has been sent. See note
+    //     for $(ref:startConnect).
+    static void startDisconnect(DOMString networkGuid,
+                                optional VoidCallback callback);
+
+    // Returns captive portal status for the network matching 'networkGuid'.
+    // |networkGuid|: The GUID of the network to get captive portal status for.
+    // |callback|: A callback function that returns the results of the query for
+    //     network captive portal status.
+    static void getCaptivePortalStatus(DOMString networkGuid,
+                                       CaptivePortalStatusCallback callback);
+
+    // Gets the global policy properties. These properties are not expected to
+    // change during a session.
+    static void getGlobalPolicy(GetGlobalPolicyCallback callback);
+  };
+
+  interface Events {
+    // Fired when the properties change on any of the networks.  Sends a list of
+    // GUIDs for networks whose properties have changed.
+    static void onNetworksChanged(DOMString[] changes);
+
+    // Fired when the list of networks has changed.  Sends a complete list of
+    // GUIDs for all the current networks.
+    static void onNetworkListChanged(DOMString[] changes);
+
+    // Fired when the list of devices has changed or any device state properties
+    // have changed.
+    static void onDeviceStateListChanged();
+
+    // Fired when a portal detection for a network completes. Sends the GUID of
+    // the network and the corresponding captive portal status.
+    static void onPortalDetectionCompleted(DOMString networkGuid,
+                                           CaptivePortalStatus status);
+  };
+};
diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
index 080019e..77440ee 100644
--- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
+++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
@@ -48,7 +48,7 @@
 
 namespace {
 
-content::RenderFrame* GetRenderFrame(v8::Handle<v8::Value> value) {
+content::RenderFrame* GetRenderFrame(v8::Local<v8::Value> value) {
   v8::Local<v8::Context> context =
       v8::Local<v8::Object>::Cast(value)->CreationContext();
   if (context.IsEmpty())
@@ -368,8 +368,8 @@
   if (map_entry == view_map.end())
     return;
 
-  auto return_object = v8::Handle<v8::Object>::New(args.GetIsolate(),
-                                                   *map_entry->second);
+  auto return_object =
+      v8::Local<v8::Object>::New(args.GetIsolate(), *map_entry->second);
   args.GetReturnValue().Set(return_object);
 }
 
diff --git a/extensions/renderer/wake_event_page.cc b/extensions/renderer/wake_event_page.cc
index 2118929..a33f45a 100644
--- a/extensions/renderer/wake_event_page.cc
+++ b/extensions/renderer/wake_event_page.cc
@@ -115,7 +115,7 @@
 
   v8::Isolate* isolate = context->isolate();
   v8::EscapableHandleScope handle_scope(isolate);
-  v8::Handle<v8::Context> v8_context = context->v8_context();
+  v8::Local<v8::Context> v8_context = context->v8_context();
   v8::Context::Scope context_scope(v8_context);
 
   // Cache the imported function as a hidden property on the global object of
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h
index 29d025f7..41ab8ef 100644
--- a/gpu/command_buffer/common/capabilities.h
+++ b/gpu/command_buffer/common/capabilities.h
@@ -168,6 +168,10 @@
   // work around this. See https://crbug.com/449150 for an example.
   bool emulate_rgb_buffer_with_rgba = false;
 
+  // When true, is safe to convert a canvas from software to accelerated.
+  // See https://crbug.com/710029.
+  bool software_to_accelerated_canvas_upgrade = true;
+
   int major_version = 2;
   int minor_version = 0;
 };
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index cc1c913..b34e690 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3812,6 +3812,8 @@
       kGpuFeatureStatusEnabled;
   caps.disable_webgl_rgb_multisampling_usage =
       workarounds().disable_webgl_rgb_multisampling_usage;
+  caps.software_to_accelerated_canvas_upgrade =
+      !workarounds().disable_software_to_accelerated_canvas_upgrade;
   caps.emulate_rgb_buffer_with_rgba =
       workarounds().disable_gl_rgb_format;
 
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 16c85a86..fe5d306c0b 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -1,6 +1,6 @@
 {
   "name": "gpu driver bug list",
-  "version": "10.2",
+  "version": "10.3",
   "entries": [
     {
       "id": 1,
@@ -2350,6 +2350,18 @@
       "features": [
         "disallow_large_instanced_draw"
       ]
+    },
+    {
+      "id": 222,
+      "description": "Software to Accelerated canvas update breaks Linux AMD",
+      "cr_bugs": [710029],
+      "os": {
+        "type": "linux"
+      },
+      "vendor_id": "0x1002",
+      "features": [
+        "disable_software_to_accelerated_canvas_upgrade"
+      ]
     }
   ],
   "comment": [
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h
index 043acc33..2fb5625 100644
--- a/gpu/config/gpu_driver_bug_workaround_type.h
+++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -209,6 +209,8 @@
          use_gpu_driver_workaround_for_testing)              \
   GPU_OP(DISALLOW_LARGE_INSTANCED_DRAW,                      \
          disallow_large_instanced_draw)                      \
+  GPU_OP(DISABLE_SOFTWARE_TO_ACCELERATED_CANVAS_UPGRADE,     \
+         disable_software_to_accelerated_canvas_upgrade)     \
 // clang-format on
 
 namespace gpu {
diff --git a/gpu/ipc/common/gpu_command_buffer_traits_multi.h b/gpu/ipc/common/gpu_command_buffer_traits_multi.h
index 87a3eb1..fe721e65 100644
--- a/gpu/ipc/common/gpu_command_buffer_traits_multi.h
+++ b/gpu/ipc/common/gpu_command_buffer_traits_multi.h
@@ -127,6 +127,7 @@
   IPC_STRUCT_TRAITS_MEMBER(gpu_rasterization)
   IPC_STRUCT_TRAITS_MEMBER(chromium_image_rgb_emulation)
   IPC_STRUCT_TRAITS_MEMBER(emulate_rgb_buffer_with_rgba)
+  IPC_STRUCT_TRAITS_MEMBER(software_to_accelerated_canvas_upgrade)
   IPC_STRUCT_TRAITS_MEMBER(dc_layers)
 
   IPC_STRUCT_TRAITS_MEMBER(major_version)
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc
index f67183c..0f4e40e5 100644
--- a/gpu/ipc/service/direct_composition_surface_win.cc
+++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -473,7 +473,28 @@
   swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width();
   swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height();
 
-  swap_chain_->Present(first_present ? 0 : 1, 0);
+  if (first_present) {
+    swap_chain_->Present(0, 0);
+
+    // DirectComposition can display black for a swapchain between the first
+    // and second time it's presented to - maybe the first Present can get
+    // lost somehow and it shows the wrong buffer. In that case copy the
+    // buffers so both have the correct contents, which seems to help. The
+    // first Present() after this needs to have SyncInterval > 0, or else the
+    // workaround doesn't help.
+    base::win::ScopedComPtr<ID3D11Texture2D> dest_texture;
+    HRESULT hr =
+        swap_chain_->GetBuffer(0, IID_PPV_ARGS(dest_texture.Receive()));
+    DCHECK(SUCCEEDED(hr));
+    base::win::ScopedComPtr<ID3D11Texture2D> src_texture;
+    hr = swap_chain_->GetBuffer(1, IID_PPV_ARGS(src_texture.Receive()));
+    DCHECK(SUCCEEDED(hr));
+    base::win::ScopedComPtr<ID3D11DeviceContext> context;
+    d3d11_device_->GetImmediateContext(context.Receive());
+    context->CopyResource(dest_texture.get(), src_texture.get());
+  }
+
+  swap_chain_->Present(1, 0);
 
   frames_since_color_space_change_++;
 
diff --git a/gpu/ipc/service/direct_composition_surface_win_unittest.cc b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
index fcc34d8..8e6485b 100644
--- a/gpu/ipc/service/direct_composition_surface_win_unittest.cc
+++ b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
@@ -326,7 +326,10 @@
 
   UINT last_present_count = 0;
   EXPECT_TRUE(SUCCEEDED(swap_chain->GetLastPresentCount(&last_present_count)));
-  EXPECT_EQ(1u, last_present_count);
+
+  // One present is normal, and a second present because it's the first frame
+  // and the other buffer needs to be drawn to.
+  EXPECT_EQ(2u, last_present_count);
 
   surface->ScheduleDCLayer(params);
   EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
@@ -337,7 +340,7 @@
 
   // It's the same image, so it should have the same swapchain.
   EXPECT_TRUE(SUCCEEDED(swap_chain->GetLastPresentCount(&last_present_count)));
-  EXPECT_EQ(1u, last_present_count);
+  EXPECT_EQ(2u, last_present_count);
 
   // The size of the swapchain changed, so it should be recreated.
   ui::DCRendererLayerParams params2(false, gfx::Rect(), 1, gfx::Transform(),
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index b715db6..b53e4328f 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -629,6 +629,9 @@
       <message name="IDS_IOS_FACETIME_BUTTON" desc="Text in the confirmation dialog button that will initiate a FaceTime call for the presented number. [Length: 10em] [iOS only]">
         FaceTime
       </message>
+      <message name="IDS_IOS_PHONE_CALL_BUTTON" desc="Text in the confirmation dialog button that will initiate a phone call for the presented number. [Length: 10em] [iOS only]">
+        Call
+      </message>
       <message name="IDS_IOS_FIRSTRUN_ACCOUNT_CONSISTENCY_SKIP_BUTTON" desc="Title of the button to skip the selection of an account on First Run when account consistency is enabled. [Length: 10em] [iOS only]">
         No thanks
       </message>
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.h b/ios/chrome/browser/ui/autofill/autofill_client_ios.h
index 410cc187..458a95d 100644
--- a/ios/chrome/browser/ui/autofill/autofill_client_ios.h
+++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.h
@@ -60,6 +60,7 @@
   IdentityProvider* GetIdentityProvider() override;
   rappor::RapporServiceImpl* GetRapporServiceImpl() override;
   ukm::UkmService* GetUkmService() override;
+  SaveCardBubbleController* GetSaveCardBubbleController() override;
   void ShowAutofillSettings() override;
   void ShowUnmaskPrompt(const CreditCard& card,
                         UnmaskCardReason reason,
@@ -70,6 +71,7 @@
   void ConfirmSaveCreditCardToCloud(
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
+      bool should_cvc_be_requested,
       const base::Closure& callback) override;
   void ConfirmCreditCardFillAssist(const CreditCard& card,
                                    const base::Closure& callback) override;
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
index 7ffcb0fa..377e7e74f 100644
--- a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
@@ -84,6 +84,10 @@
   return GetApplicationContext()->GetUkmService();
 }
 
+SaveCardBubbleController* AutofillClientIOS::GetSaveCardBubbleController() {
+  return nullptr;
+}
+
 void AutofillClientIOS::ShowAutofillSettings() {
   NOTREACHED();
 }
@@ -120,6 +124,7 @@
 void AutofillClientIOS::ConfirmSaveCreditCardToCloud(
     const CreditCard& card,
     std::unique_ptr<base::DictionaryValue> legal_message,
+    bool should_cvc_be_requested,
     const base::Closure& callback) {
   infobar_manager_->AddInfoBar(CreateSaveCardInfoBarMobile(
       base::MakeUnique<AutofillSaveCardInfoBarDelegateMobile>(
diff --git a/media/base/media_observer.h b/media/base/media_observer.h
index f5b1fb6..0181b1d 100644
--- a/media/base/media_observer.h
+++ b/media/base/media_observer.h
@@ -16,9 +16,10 @@
   virtual ~MediaObserverClient() {}
 
   // Requests to restart the media pipeline and create a new renderer as soon as
-  // possible. |disable_pipeline_auto_suspend| indicates whether to disable
-  // any optimizations that might suspend the media pipeline.
-  virtual void SwitchRenderer(bool disable_pipeline_auto_suspend) = 0;
+  // possible. |is_rendered_remotely| indicates whether the media is rendered
+  // remotely. When it is true, all the optimizations that might suspend the
+  // media pipeline should be disabled.
+  virtual void SwitchRenderer(bool is_rendered_remotely) = 0;
 
   // Requests to activate monitoring changes on viewport intersection.
   virtual void ActivateViewportIntersectionMonitoring(bool activate) = 0;
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 28e749dc..03b4c76 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -173,6 +173,10 @@
 const base::Feature kBackgroundVideoTrackOptimization{
     "BackgroundVideoTrackOptimization", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Let video without audio be paused when it is playing in the background.
+const base::Feature kBackgroundVideoPauseOptimization{
+    "BackgroundVideoPauseOptimization", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Make MSE garbage collection algorithm more aggressive when we are under
 // moderate or critical memory pressure. This will relieve memory pressure by
 // releasing stale data from MSE buffers.
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 89b4a03a..b2234d1a 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -95,6 +95,7 @@
 MEDIA_EXPORT extern const base::Feature kVideoBlitColorAccuracy;
 MEDIA_EXPORT extern const base::Feature kExternalClearKeyForTesting;
 MEDIA_EXPORT extern const base::Feature kBackgroundVideoTrackOptimization;
+MEDIA_EXPORT extern const base::Feature kBackgroundVideoPauseOptimization;
 MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC;
 
 #if defined(OS_ANDROID)
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 7c10f9f..309441e 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -130,6 +130,10 @@
   return base::FeatureList::IsEnabled(kBackgroundVideoTrackOptimization);
 }
 
+bool IsBackgroundVideoPauseOptimizationEnabled() {
+  return base::FeatureList::IsEnabled(kBackgroundVideoPauseOptimization);
+}
+
 bool IsNetworkStateError(blink::WebMediaPlayer::NetworkState state) {
   bool result = state == blink::WebMediaPlayer::kNetworkStateFormatError ||
                 state == blink::WebMediaPlayer::kNetworkStateNetworkError ||
@@ -237,6 +241,8 @@
       observer_(params.media_observer()),
       max_keyframe_distance_to_disable_background_video_(
           params.max_keyframe_distance_to_disable_background_video()),
+      max_keyframe_distance_to_disable_background_video_mse_(
+          params.max_keyframe_distance_to_disable_background_video_mse()),
       enable_instant_source_buffer_gc_(
           params.enable_instant_source_buffer_gc()),
       embedded_media_experience_enabled_(
@@ -2199,7 +2205,7 @@
 
   // Otherwise only pause if the optimization is on and it's a video-only
   // optimization candidate.
-  return IsBackgroundVideoTrackOptimizationEnabled() && !HasAudio() &&
+  return IsBackgroundVideoPauseOptimizationEnabled() && !HasAudio() &&
          IsBackgroundOptimizationCandidate();
 }
 
@@ -2233,13 +2239,16 @@
 
   // Videos shorter than the maximum allowed keyframe distance can be optimized.
   base::TimeDelta duration = GetPipelineMediaDuration();
-  if (duration < max_keyframe_distance_to_disable_background_video_)
+  base::TimeDelta max_keyframe_distance =
+      (load_type_ == kLoadTypeMediaSource)
+          ? max_keyframe_distance_to_disable_background_video_mse_
+          : max_keyframe_distance_to_disable_background_video_;
+  if (duration < max_keyframe_distance)
     return true;
 
   // Otherwise, only optimize videos with shorter average keyframe distance.
   PipelineStatistics stats = GetPipelineStatistics();
-  return stats.video_keyframe_distance_average <
-         max_keyframe_distance_to_disable_background_video_;
+  return stats.video_keyframe_distance_average < max_keyframe_distance;
 }
 
 void WebMediaPlayerImpl::UpdateBackgroundVideoOptimizationState() {
@@ -2334,10 +2343,16 @@
                         time_to_first_frame);
   }
 }
-void WebMediaPlayerImpl::SwitchRenderer(bool disable_pipeline_auto_suspend) {
+void WebMediaPlayerImpl::SwitchRenderer(bool is_rendered_remotely) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  disable_pipeline_auto_suspend_ = disable_pipeline_auto_suspend;
+  disable_pipeline_auto_suspend_ = is_rendered_remotely;
   ScheduleRestart();
+  if (client_) {
+    if (is_rendered_remotely)
+      client_->MediaRemotingStarted();
+    else
+      client_->MediaRemotingStopped();
+  }
 }
 
 void WebMediaPlayerImpl::RecordUnderflowDuration(base::TimeDelta duration) {
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index 8e1a16b5..5be40d1fd 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -223,7 +223,7 @@
 #endif
 
   // MediaObserverClient implementation.
-  void SwitchRenderer(bool disable_pipeline_auto_suspend) override;
+  void SwitchRenderer(bool is_rendered_remotely) override;
   void ActivateViewportIntersectionMonitoring(bool activate) override;
 
   // Called from WebMediaPlayerCast.
@@ -681,9 +681,13 @@
   base::WeakPtr<MediaObserver> observer_;
 
   // The maximum video keyframe distance that allows triggering background
-  // playback optimizations.
+  // playback optimizations (non-MSE).
   base::TimeDelta max_keyframe_distance_to_disable_background_video_;
 
+  // The maximum video keyframe distance that allows triggering background
+  // playback optimizations (MSE).
+  base::TimeDelta max_keyframe_distance_to_disable_background_video_mse_;
+
   // When MSE memory pressure based garbage collection is enabled, the
   // |enable_instant_source_buffer_gc| controls whether the GC is done
   // immediately on memory pressure notification or during the next SourceBuffer
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc
index 493dfb8..0d4e6f8 100644
--- a/media/blink/webmediaplayer_impl_unittest.cc
+++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -28,6 +28,7 @@
 #include "media/renderers/default_renderer_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
@@ -44,6 +45,12 @@
 
 namespace media {
 
+// Specify different values for testing.
+const base::TimeDelta kMaxKeyframeDistanceToDisableBackgroundVideo =
+    base::TimeDelta::FromSeconds(5);
+const base::TimeDelta kMaxKeyframeDistanceToDisableBackgroundVideoMSE =
+    base::TimeDelta::FromSeconds(10);
+
 int64_t OnAdjustAllocatedMemory(int64_t delta) {
   return 0;
 }
@@ -215,7 +222,9 @@
             media_thread_.task_runner(), message_loop_.task_runner(),
             message_loop_.task_runner(), WebMediaPlayerParams::Context3DCB(),
             base::Bind(&OnAdjustAllocatedMemory), nullptr, nullptr, nullptr,
-            base::TimeDelta::FromSeconds(10), false, allow_suspend, false));
+            kMaxKeyframeDistanceToDisableBackgroundVideo,
+            kMaxKeyframeDistanceToDisableBackgroundVideoMSE, false,
+            allow_suspend, false));
   }
 
   ~WebMediaPlayerImplTest() override {
@@ -331,6 +340,10 @@
     wmpi_->SetSuspendState(is_suspended);
   }
 
+  void SetLoadType(blink::WebMediaPlayer::LoadType load_type) {
+    wmpi_->load_type_ = load_type;
+  }
+
   // "Renderer" thread.
   base::MessageLoop message_loop_;
 
@@ -796,7 +809,7 @@
 class WebMediaPlayerImplBackgroundBehaviorTest
     : public WebMediaPlayerImplTest,
       public ::testing::WithParamInterface<
-          std::tuple<bool, bool, int, int, bool>> {
+          std::tuple<bool, bool, int, int, bool, bool, bool>> {
  public:
   // Indices of the tuple parameters.
   static const int kIsMediaSuspendEnabled = 0;
@@ -804,6 +817,8 @@
   static const int kDurationSec = 2;
   static const int kAverageKeyframeDistanceSec = 3;
   static const int kIsResumeBackgroundVideoEnabled = 4;
+  static const int kIsMediaSource = 5;
+  static const int kIsBackgroundPauseEnabled = 6;
 
   void SetUp() override {
     WebMediaPlayerImplTest::SetUp();
@@ -818,6 +833,16 @@
       disabled_features += kBackgroundVideoTrackOptimization.name;
     }
 
+    if (IsBackgroundPauseOn()) {
+      if (!enabled_features.empty())
+        enabled_features += ",";
+      enabled_features += kBackgroundVideoPauseOptimization.name;
+    } else {
+      if (!disabled_features.empty())
+        disabled_features += ",";
+      disabled_features += kBackgroundVideoPauseOptimization.name;
+    }
+
     if (IsResumeBackgroundVideoEnabled()) {
       if (!enabled_features.empty())
         enabled_features += ",";
@@ -831,6 +856,9 @@
     feature_list_.InitFromCommandLine(enabled_features, disabled_features);
 
     InitializeWebMediaPlayerImpl(true);
+    bool is_media_source = std::get<kIsMediaSource>(GetParam());
+    SetLoadType(is_media_source ? blink::WebMediaPlayer::kLoadTypeMediaSource
+                                : blink::WebMediaPlayer::kLoadTypeURL);
     SetVideoKeyframeDistanceAverage(
         base::TimeDelta::FromSeconds(GetAverageKeyframeDistanceSec()));
     SetDuration(base::TimeDelta::FromSeconds(GetDurationSec()));
@@ -859,12 +887,24 @@
     return std::get<kIsResumeBackgroundVideoEnabled>(GetParam());
   }
 
+  bool IsBackgroundPauseOn() {
+    return std::get<kIsBackgroundPauseEnabled>(GetParam());
+  }
+
   int GetDurationSec() const { return std::get<kDurationSec>(GetParam()); }
 
   int GetAverageKeyframeDistanceSec() const {
     return std::get<kAverageKeyframeDistanceSec>(GetParam());
   }
 
+  int GetMaxKeyframeDistanceSec() const {
+    base::TimeDelta max_keyframe_distance =
+        std::get<kIsMediaSource>(GetParam())
+            ? kMaxKeyframeDistanceToDisableBackgroundVideoMSE
+            : kMaxKeyframeDistanceToDisableBackgroundVideo;
+    return max_keyframe_distance.InSeconds();
+  }
+
   bool IsAndroid() {
 #if defined(OS_ANDROID)
     return true;
@@ -907,14 +947,14 @@
   // There's no optimization criteria for video only on Android.
   bool matches_requirements =
       IsAndroid() ||
-      ((GetDurationSec() < GetAverageKeyframeDistanceSec()) ||
-       (GetAverageKeyframeDistanceSec() < 10));
+      ((GetDurationSec() < GetMaxKeyframeDistanceSec()) ||
+       (GetAverageKeyframeDistanceSec() < GetMaxKeyframeDistanceSec()));
   EXPECT_EQ(matches_requirements, IsBackgroundOptimizationCandidate());
 
   // Video is always paused when suspension is on and only if matches the
   // optimization criteria if the optimization is on.
-  bool should_pause = IsMediaSuspendOn() ||
-                      (IsBackgroundOptimizationOn() && matches_requirements);
+  bool should_pause =
+      IsMediaSuspendOn() || (IsBackgroundPauseOn() && matches_requirements);
   EXPECT_EQ(should_pause, ShouldPauseVideoWhenHidden());
 }
 
@@ -923,15 +963,15 @@
 
   // Optimization requirements are the same for all platforms.
   bool matches_requirements =
-      (GetDurationSec() < GetAverageKeyframeDistanceSec()) ||
-      (GetAverageKeyframeDistanceSec() < 10);
+      (GetDurationSec() < GetMaxKeyframeDistanceSec()) ||
+      (GetAverageKeyframeDistanceSec() < GetMaxKeyframeDistanceSec());
 
   EXPECT_EQ(matches_requirements, IsBackgroundOptimizationCandidate());
   EXPECT_EQ(IsBackgroundOptimizationOn() && matches_requirements,
             ShouldDisableVideoWhenHidden());
 
-  // Only pause audible videos on Android if both media suspend and resume
-  // background videos is on. On Desktop
+  // Only pause audible videos if both media suspend and resume background
+  // videos is on. Both are on by default on Android and off on desktop.
   EXPECT_EQ(IsMediaSuspendOn() && IsResumeBackgroundVideoEnabled(),
             ShouldPauseVideoWhenHidden());
 }
@@ -942,6 +982,8 @@
                                            ::testing::Bool(),
                                            ::testing::Values(5, 300),
                                            ::testing::Values(5, 100),
+                                           ::testing::Bool(),
+                                           ::testing::Bool(),
                                            ::testing::Bool()));
 
 }  // namespace media
diff --git a/media/blink/webmediaplayer_params.cc b/media/blink/webmediaplayer_params.cc
index a89f693..ce635b6 100644
--- a/media/blink/webmediaplayer_params.cc
+++ b/media/blink/webmediaplayer_params.cc
@@ -24,6 +24,7 @@
     SurfaceManager* surface_manager,
     base::WeakPtr<MediaObserver> media_observer,
     base::TimeDelta max_keyframe_distance_to_disable_background_video,
+    base::TimeDelta max_keyframe_distance_to_disable_background_video_mse,
     bool enable_instant_source_buffer_gc,
     bool allow_suspend,
     bool embedded_media_experience_enabled)
@@ -40,6 +41,8 @@
       media_observer_(media_observer),
       max_keyframe_distance_to_disable_background_video_(
           max_keyframe_distance_to_disable_background_video),
+      max_keyframe_distance_to_disable_background_video_mse_(
+          max_keyframe_distance_to_disable_background_video_mse),
       enable_instant_source_buffer_gc_(enable_instant_source_buffer_gc),
       allow_suspend_(allow_suspend),
       embedded_media_experience_enabled_(embedded_media_experience_enabled) {}
diff --git a/media/blink/webmediaplayer_params.h b/media/blink/webmediaplayer_params.h
index b16ee3a..2da0d23 100644
--- a/media/blink/webmediaplayer_params.h
+++ b/media/blink/webmediaplayer_params.h
@@ -60,6 +60,7 @@
       SurfaceManager* surface_manager,
       base::WeakPtr<MediaObserver> media_observer,
       base::TimeDelta max_keyframe_distance_to_disable_background_video,
+      base::TimeDelta max_keyframe_distance_to_disable_background_video_mse,
       bool enable_instant_source_buffer_gc,
       bool allow_suspend,
       bool embedded_media_experience_enabled);
@@ -110,6 +111,11 @@
     return max_keyframe_distance_to_disable_background_video_;
   }
 
+  base::TimeDelta max_keyframe_distance_to_disable_background_video_mse()
+      const {
+    return max_keyframe_distance_to_disable_background_video_mse_;
+  }
+
   bool enable_instant_source_buffer_gc() const {
     return enable_instant_source_buffer_gc_;
   }
@@ -134,6 +140,7 @@
   SurfaceManager* surface_manager_;
   base::WeakPtr<MediaObserver> media_observer_;
   base::TimeDelta max_keyframe_distance_to_disable_background_video_;
+  base::TimeDelta max_keyframe_distance_to_disable_background_video_mse_;
   bool enable_instant_source_buffer_gc_;
   const bool allow_suspend_;
   const bool embedded_media_experience_enabled_;
diff --git a/mojo/edk/js/core.cc b/mojo/edk/js/core.cc
index baccc4c..4b557db 100644
--- a/mojo/edk/js/core.cc
+++ b/mojo/edk/js/core.cc
@@ -81,7 +81,7 @@
   MojoHandle handle1 = MOJO_HANDLE_INVALID;
   MojoResult result = MOJO_RESULT_OK;
 
-  v8::Handle<v8::Value> options_value = args.PeekNext();
+  v8::Local<v8::Value> options_value = args.PeekNext();
   if (options_value.IsEmpty() || options_value->IsNull() ||
       options_value->IsUndefined()) {
     result = MojoCreateMessagePipe(NULL, &handle0, &handle1);
@@ -144,7 +144,7 @@
     return dictionary;
   }
 
-  v8::Handle<v8::ArrayBuffer> array_buffer =
+  v8::Local<v8::ArrayBuffer> array_buffer =
       v8::ArrayBuffer::New(args.isolate(), num_bytes);
   std::vector<mojo::Handle> handles(num_handles);
 
@@ -178,7 +178,7 @@
   MojoHandle consumer_handle = MOJO_HANDLE_INVALID;
   MojoResult result = MOJO_RESULT_OK;
 
-  v8::Handle<v8::Value> options_value = args.PeekNext();
+  v8::Local<v8::Value> options_value = args.PeekNext();
   if (options_value.IsEmpty() || options_value->IsNull() ||
       options_value->IsUndefined()) {
     result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle);
@@ -234,7 +234,7 @@
     return dictionary;
   }
 
-  v8::Handle<v8::ArrayBuffer> array_buffer =
+  v8::Local<v8::ArrayBuffer> array_buffer =
       v8::ArrayBuffer::New(args.isolate(), num_bytes);
   gin::ArrayBuffer buffer;
   ConvertFromV8(args.isolate(), array_buffer, &buffer);
@@ -257,12 +257,12 @@
 // and the buffer will contain whatever was read before the error occurred.
 // The drainData data pipe handle argument is closed automatically.
 
-v8::Handle<v8::Value> DoDrainData(gin::Arguments* args,
-                                  gin::Handle<HandleWrapper> handle) {
+v8::Local<v8::Value> DoDrainData(gin::Arguments* args,
+                                 gin::Handle<HandleWrapper> handle) {
   return (new DrainData(args->isolate(), handle->release()))->GetPromise();
 }
 
-bool IsHandle(gin::Arguments* args, v8::Handle<v8::Value> val) {
+bool IsHandle(gin::Arguments* args, v8::Local<v8::Value> val) {
   gin::Handle<mojo::edk::js::HandleWrapper> ignore_handle;
   return gin::Converter<gin::Handle<mojo::edk::js::HandleWrapper>>::FromV8(
       args->isolate(), val, &ignore_handle);
@@ -332,7 +332,7 @@
     return dictionary;
   }
 
-  v8::Handle<v8::ArrayBuffer> array_buffer =
+  v8::Local<v8::ArrayBuffer> array_buffer =
       v8::ArrayBuffer::New(args.isolate(), data, num_bytes);
 
   dictionary.Set("result", result);
@@ -342,7 +342,7 @@
 }
 
 MojoResult UnmapBuffer(const gin::Arguments& args,
-                       const v8::Handle<v8::ArrayBuffer>& buffer) {
+                       const v8::Local<v8::ArrayBuffer>& buffer) {
   // Buffer must be external, created by MapBuffer
   if (!buffer->IsExternal())
     return MOJO_RESULT_INVALID_ARGUMENT;
diff --git a/mojo/edk/js/drain_data.cc b/mojo/edk/js/drain_data.cc
index 334ced32..00c10a4 100644
--- a/mojo/edk/js/drain_data.cc
+++ b/mojo/edk/js/drain_data.cc
@@ -24,15 +24,15 @@
     : isolate_(isolate),
       handle_(DataPipeConsumerHandle(handle.value())),
       handle_watcher_(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC) {
-  v8::Handle<v8::Context> context(isolate_->GetCurrentContext());
+  v8::Local<v8::Context> context(isolate_->GetCurrentContext());
   runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
 
   WaitForData();
 }
 
-v8::Handle<v8::Value> DrainData::GetPromise() {
+v8::Local<v8::Value> DrainData::GetPromise() {
   CHECK(resolver_.IsEmpty());
-  v8::Handle<v8::Promise::Resolver> resolver(
+  v8::Local<v8::Promise::Resolver> resolver(
       v8::Promise::Resolver::New(isolate_));
   resolver_.Reset(isolate_, resolver);
   return resolver->GetPromise();
@@ -86,7 +86,7 @@
 
   // Create a total_bytes length ArrayBuffer return value.
   gin::Runner::Scope scope(runner_.get());
-  v8::Handle<v8::ArrayBuffer> array_buffer =
+  v8::Local<v8::ArrayBuffer> array_buffer =
       v8::ArrayBuffer::New(isolate_, total_bytes);
   gin::ArrayBuffer buffer;
   ConvertFromV8(isolate_, array_buffer, &buffer);
@@ -108,13 +108,13 @@
   // that was read before either an error occurred or the remote pipe handle
   // was closed. The latter is indicated by MOJO_RESULT_FAILED_PRECONDITION.
 
-  v8::Handle<v8::Promise::Resolver> resolver(
+  v8::Local<v8::Promise::Resolver> resolver(
       v8::Local<v8::Promise::Resolver>::New(isolate_, resolver_));
 
   gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(isolate_);
   dictionary.Set("result", result);
   dictionary.Set("buffer", array_buffer);
-  v8::Handle<v8::Value> settled_value(ConvertToV8(isolate_, dictionary));
+  v8::Local<v8::Value> settled_value(ConvertToV8(isolate_, dictionary));
 
   if (result == MOJO_RESULT_FAILED_PRECONDITION)
     resolver->Resolve(settled_value);
diff --git a/mojo/edk/js/drain_data.h b/mojo/edk/js/drain_data.h
index 42da90f..42734893d 100644
--- a/mojo/edk/js/drain_data.h
+++ b/mojo/edk/js/drain_data.h
@@ -31,7 +31,7 @@
 
   // Returns a Promise that will be settled when no more data can be read.
   // Should be called just once on a newly allocated DrainData object.
-  v8::Handle<v8::Value> GetPromise();
+  v8::Local<v8::Value> GetPromise();
 
  private:
   ~DrainData();
diff --git a/mojo/edk/js/handle.cc b/mojo/edk/js/handle.cc
index 7da8e9f..b120f96 100644
--- a/mojo/edk/js/handle.cc
+++ b/mojo/edk/js/handle.cc
@@ -47,15 +47,15 @@
 
 namespace gin {
 
-v8::Handle<v8::Value> Converter<mojo::Handle>::ToV8(v8::Isolate* isolate,
-                                                    const mojo::Handle& val) {
+v8::Local<v8::Value> Converter<mojo::Handle>::ToV8(v8::Isolate* isolate,
+                                                   const mojo::Handle& val) {
   if (!val.is_valid())
     return v8::Null(isolate);
   return mojo::edk::js::HandleWrapper::Create(isolate, val.value()).ToV8();
 }
 
 bool Converter<mojo::Handle>::FromV8(v8::Isolate* isolate,
-                                     v8::Handle<v8::Value> val,
+                                     v8::Local<v8::Value> val,
                                      mojo::Handle* out) {
   if (val->IsNull()) {
     *out = mojo::Handle();
@@ -71,13 +71,14 @@
   return true;
 }
 
-v8::Handle<v8::Value> Converter<mojo::MessagePipeHandle>::ToV8(
-    v8::Isolate* isolate, mojo::MessagePipeHandle val) {
+v8::Local<v8::Value> Converter<mojo::MessagePipeHandle>::ToV8(
+    v8::Isolate* isolate,
+    mojo::MessagePipeHandle val) {
   return Converter<mojo::Handle>::ToV8(isolate, val);
 }
 
 bool Converter<mojo::MessagePipeHandle>::FromV8(v8::Isolate* isolate,
-                                                v8::Handle<v8::Value> val,
+                                                v8::Local<v8::Value> val,
                                                 mojo::MessagePipeHandle* out) {
   return Converter<mojo::Handle>::FromV8(isolate, val, out);
 }
diff --git a/mojo/edk/js/handle.h b/mojo/edk/js/handle.h
index 60652ed..af5cc1a 100644
--- a/mojo/edk/js/handle.h
+++ b/mojo/edk/js/handle.h
@@ -59,18 +59,19 @@
 // TODO(mpcomplete): define converters for all Handle subtypes.
 template <>
 struct MOJO_JS_EXPORT Converter<mojo::Handle> {
-  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
-                                    const mojo::Handle& val);
-  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
+  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
+                                   const mojo::Handle& val);
+  static bool FromV8(v8::Isolate* isolate,
+                     v8::Local<v8::Value> val,
                      mojo::Handle* out);
 };
 
 template <>
 struct MOJO_JS_EXPORT Converter<mojo::MessagePipeHandle> {
-  static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
-                                    mojo::MessagePipeHandle val);
+  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
+                                   mojo::MessagePipeHandle val);
   static bool FromV8(v8::Isolate* isolate,
-                     v8::Handle<v8::Value> val,
+                     v8::Local<v8::Value> val,
                      mojo::MessagePipeHandle* out);
 };
 
@@ -78,14 +79,14 @@
 // converting |null| to a wrapper for an empty mojo::Handle.
 template <>
 struct MOJO_JS_EXPORT Converter<gin::Handle<mojo::edk::js::HandleWrapper>> {
-  static v8::Handle<v8::Value> ToV8(
+  static v8::Local<v8::Value> ToV8(
       v8::Isolate* isolate,
       const gin::Handle<mojo::edk::js::HandleWrapper>& val) {
     return val.ToV8();
   }
 
   static bool FromV8(v8::Isolate* isolate,
-                     v8::Handle<v8::Value> val,
+                     v8::Local<v8::Value> val,
                      gin::Handle<mojo::edk::js::HandleWrapper>* out) {
     if (val->IsNull()) {
       *out = mojo::edk::js::HandleWrapper::Create(isolate, MOJO_HANDLE_INVALID);
diff --git a/mojo/edk/js/mojo_runner_delegate.cc b/mojo/edk/js/mojo_runner_delegate.cc
index dda0b2c3..5d001f9 100644
--- a/mojo/edk/js/mojo_runner_delegate.cc
+++ b/mojo/edk/js/mojo_runner_delegate.cc
@@ -34,13 +34,12 @@
 
 void StartCallback(base::WeakPtr<gin::Runner> runner,
                    MojoHandle pipe,
-                   v8::Handle<v8::Value> module) {
+                   v8::Local<v8::Value> module) {
   v8::Isolate* isolate = runner->GetContextHolder()->isolate();
-  v8::Handle<v8::Function> start;
+  v8::Local<v8::Function> start;
   CHECK(gin::ConvertFromV8(isolate, module, &start));
 
-  v8::Handle<v8::Value> args[] = {
-      gin::ConvertToV8(isolate, Handle(pipe)) };
+  v8::Local<v8::Value> args[] = {gin::ConvertToV8(isolate, Handle(pipe))};
   runner->Call(start, runner->global(), 1, args);
 }
 
diff --git a/mojo/edk/js/support.cc b/mojo/edk/js/support.cc
index 404cb9b7..21ce0d0d 100644
--- a/mojo/edk/js/support.cc
+++ b/mojo/edk/js/support.cc
@@ -25,7 +25,7 @@
 WaitingCallback* AsyncWait(const gin::Arguments& args,
                            gin::Handle<HandleWrapper> handle,
                            MojoHandleSignals signals,
-                           v8::Handle<v8::Function> callback) {
+                           v8::Local<v8::Function> callback) {
   return WaitingCallback::Create(
       args.isolate(), callback, handle, signals, true /* one_shot */).get();
 }
@@ -37,7 +37,7 @@
 WaitingCallback* Watch(const gin::Arguments& args,
                        gin::Handle<HandleWrapper> handle,
                        MojoHandleSignals signals,
-                       v8::Handle<v8::Function> callback) {
+                       v8::Local<v8::Function> callback) {
   return WaitingCallback::Create(
       args.isolate(), callback, handle, signals, false /* one_shot */).get();
 }
diff --git a/mojo/edk/js/waiting_callback.cc b/mojo/edk/js/waiting_callback.cc
index 98501236..d9c920a 100644
--- a/mojo/edk/js/waiting_callback.cc
+++ b/mojo/edk/js/waiting_callback.cc
@@ -14,7 +14,7 @@
 
 namespace {
 
-v8::Handle<v8::Private> GetHiddenPropertyName(v8::Isolate* isolate) {
+v8::Local<v8::Private> GetHiddenPropertyName(v8::Isolate* isolate) {
   return v8::Private::ForApi(
       isolate, gin::StringToV8(isolate, "::mojo::js::WaitingCallback"));
 }
@@ -26,7 +26,7 @@
 // static
 gin::Handle<WaitingCallback> WaitingCallback::Create(
     v8::Isolate* isolate,
-    v8::Handle<v8::Function> callback,
+    v8::Local<v8::Function> callback,
     gin::Handle<HandleWrapper> handle_wrapper,
     MojoHandleSignals signals,
     bool one_shot) {
@@ -50,12 +50,12 @@
 }
 
 WaitingCallback::WaitingCallback(v8::Isolate* isolate,
-                                 v8::Handle<v8::Function> callback,
+                                 v8::Local<v8::Function> callback,
                                  bool one_shot)
     : one_shot_(one_shot),
       watcher_(FROM_HERE, SimpleWatcher::ArmingPolicy::AUTOMATIC),
       weak_factory_(this) {
-  v8::Handle<v8::Context> context = isolate->GetCurrentContext();
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
   runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
   v8::Maybe<bool> result = GetWrapper(isolate).ToLocalChecked()->SetPrivate(
       context, GetHiddenPropertyName(isolate), callback);
diff --git a/mojo/edk/js/waiting_callback.h b/mojo/edk/js/waiting_callback.h
index f97b389a..03518fe 100644
--- a/mojo/edk/js/waiting_callback.h
+++ b/mojo/edk/js/waiting_callback.h
@@ -29,7 +29,7 @@
   // WaitingCallback is explicitly cancelled.
   static gin::Handle<WaitingCallback> Create(
       v8::Isolate* isolate,
-      v8::Handle<v8::Function> callback,
+      v8::Local<v8::Function> callback,
       gin::Handle<HandleWrapper> handle_wrapper,
       MojoHandleSignals signals,
       bool one_shot);
@@ -41,7 +41,7 @@
 
  private:
   WaitingCallback(v8::Isolate* isolate,
-                  v8::Handle<v8::Function> callback,
+                  v8::Local<v8::Function> callback,
                   bool one_shot);
   ~WaitingCallback() override;
 
diff --git a/net/dns/host_resolver.cc b/net/dns/host_resolver.cc
index 656e7a8b..1f6dcf9 100644
--- a/net/dns/host_resolver.cc
+++ b/net/dns/host_resolver.cc
@@ -132,14 +132,6 @@
     const PersistCallback& persist_callback,
     std::unique_ptr<const base::Value> old_data) {}
 
-void HostResolver::SetDefaultAddressFamily(AddressFamily address_family) {
-  NOTREACHED();
-}
-
-AddressFamily HostResolver::GetDefaultAddressFamily() const {
-  return ADDRESS_FAMILY_UNSPECIFIED;
-}
-
 void HostResolver::SetNoIPv6OnWifi(bool no_ipv6_on_wifi) {
   NOTREACHED();
 }
diff --git a/net/dns/host_resolver.h b/net/dns/host_resolver.h
index ba507870..f909e7b0 100644
--- a/net/dns/host_resolver.h
+++ b/net/dns/host_resolver.h
@@ -213,14 +213,6 @@
       const PersistCallback& persist_callback,
       std::unique_ptr<const base::Value> old_data);
 
-  // Sets the default AddressFamily to use when requests have left it
-  // unspecified. For example, this could be used to restrict resolution
-  // results to AF_INET by passing in ADDRESS_FAMILY_IPV4, or to
-  // AF_INET6 by passing in ADDRESS_FAMILY_IPV6. See http://crbug.com/696569 for
-  // why this option is necessary.
-  virtual void SetDefaultAddressFamily(AddressFamily address_family);
-  virtual AddressFamily GetDefaultAddressFamily() const;
-
   // Sets the HostResolver to assume that IPv6 is unreachable when on a wifi
   // connection. See https://crbug.com/696569 for further context.
   virtual void SetNoIPv6OnWifi(bool no_ipv6_on_wifi);
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
index cb4d66f2..fd4c065 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_impl.cc
@@ -2046,7 +2046,6 @@
       net_log_(net_log),
       received_dns_config_(false),
       num_dns_failures_(0),
-      default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
       assume_ipv6_failure_on_wifi_(false),
       use_local_ipv6_(false),
       last_ipv6_probe_result_(true),
@@ -2223,15 +2222,6 @@
   return rv;
 }
 
-void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) {
-  DCHECK(CalledOnValidThread());
-  default_address_family_ = address_family;
-}
-
-AddressFamily HostResolverImpl::GetDefaultAddressFamily() const {
-  return default_address_family_;
-}
-
 void HostResolverImpl::SetNoIPv6OnWifi(bool no_ipv6_on_wifi) {
   DCHECK(CalledOnValidThread());
   assume_ipv6_failure_on_wifi_ = no_ipv6_on_wifi;
@@ -2253,11 +2243,6 @@
 
   *net_error = OK;
   AddressFamily family = GetAddressFamily(*ip_address);
-  if (family == ADDRESS_FAMILY_IPV6 &&
-      default_address_family_ == ADDRESS_FAMILY_IPV4) {
-    // Don't return IPv6 addresses if default address family is set to IPv4.
-    *net_error = ERR_NAME_NOT_RESOLVED;
-  }
   if (key.address_family != ADDRESS_FAMILY_UNSPECIFIED &&
       key.address_family != family) {
     // Don't return IPv6 addresses for IPv4 queries, and vice versa.
@@ -2400,9 +2385,6 @@
       info.host_resolver_flags() | additional_resolver_flags_;
   AddressFamily effective_address_family = info.address_family();
 
-  if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED)
-    effective_address_family = default_address_family_;
-
   if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED &&
       // When resolving IPv4 literals, there's no need to probe for IPv6.
       // When resolving IPv6 literals, there's no benefit to artificially
diff --git a/net/dns/host_resolver_impl.h b/net/dns/host_resolver_impl.h
index 65b5c0b..f78d39e 100644
--- a/net/dns/host_resolver_impl.h
+++ b/net/dns/host_resolver_impl.h
@@ -158,9 +158,6 @@
       const PersistCallback& persist_callback,
       std::unique_ptr<const base::Value> old_data) override;
 
-  void SetDefaultAddressFamily(AddressFamily address_family) override;
-  AddressFamily GetDefaultAddressFamily() const override;
-
   void SetNoIPv6OnWifi(bool no_ipv6_on_wifi) override;
   bool GetNoIPv6OnWifi() override;
 
@@ -356,10 +353,6 @@
   // Number of consecutive failures of DnsTask, counted when fallback succeeds.
   unsigned num_dns_failures_;
 
-  // Address family to use when the request doesn't specify one. See
-  // http://crbug.com/696569 for why the option is needed.
-  AddressFamily default_address_family_;
-
   // True if IPv6 should not be attempted when on a WiFi connection. See
   // https://crbug.com/696569 for further context.
   bool assume_ipv6_failure_on_wifi_;
diff --git a/net/dns/host_resolver_impl_unittest.cc b/net/dns/host_resolver_impl_unittest.cc
index c6a9426..c33515e 100644
--- a/net/dns/host_resolver_impl_unittest.cc
+++ b/net/dns/host_resolver_impl_unittest.cc
@@ -2606,98 +2606,4 @@
   EXPECT_EQ(1, count2);
 }
 
-// Tests that after changing the default AddressFamily to IPV4, requests
-// with UNSPECIFIED address family map to IPV4.
-TEST_F(HostResolverImplTest, SetDefaultAddressFamily_IPv4) {
-  CreateSerialResolver();  // To guarantee order of resolutions.
-
-  proc_->AddRule("h1", ADDRESS_FAMILY_IPV4, "1.0.0.1");
-  proc_->AddRule("h1", ADDRESS_FAMILY_IPV6, "::2");
-
-  resolver_->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV4);
-
-  CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_UNSPECIFIED);
-  CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV4);
-  CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV6);
-
-  // Start all of the requests.
-  for (size_t i = 0; i < requests_.size(); ++i) {
-    EXPECT_EQ(ERR_IO_PENDING, requests_[i]->Resolve()) << i;
-  }
-
-  proc_->SignalMultiple(requests_.size());
-
-  // Wait for all the requests to complete.
-  for (size_t i = 0u; i < requests_.size(); ++i) {
-    EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i;
-  }
-
-  // Since the requests all had the same priority and we limited the thread
-  // count to 1, they should have completed in the same order as they were
-  // requested. Moreover, request0 and request1 will have been serviced by
-  // the same job.
-
-  MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList();
-  ASSERT_EQ(2u, capture_list.size());
-
-  EXPECT_EQ("h1", capture_list[0].hostname);
-  EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[0].address_family);
-
-  EXPECT_EQ("h1", capture_list[1].hostname);
-  EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[1].address_family);
-
-  // Now check that the correct resolved IP addresses were returned.
-  EXPECT_TRUE(requests_[0]->HasOneAddress("1.0.0.1", 80));
-  EXPECT_TRUE(requests_[1]->HasOneAddress("1.0.0.1", 80));
-  EXPECT_TRUE(requests_[2]->HasOneAddress("::2", 80));
-}
-
-// This is the exact same test as SetDefaultAddressFamily_IPv4, except the
-// default family is set to IPv6 and the family of requests is flipped where
-// specified.
-TEST_F(HostResolverImplTest, SetDefaultAddressFamily_IPv6) {
-  CreateSerialResolver();  // To guarantee order of resolutions.
-
-  // Don't use IPv6 replacements here since some systems don't support it.
-  proc_->AddRule("h1", ADDRESS_FAMILY_IPV4, "1.0.0.1");
-  proc_->AddRule("h1", ADDRESS_FAMILY_IPV6, "::2");
-
-  resolver_->SetDefaultAddressFamily(ADDRESS_FAMILY_IPV6);
-
-  CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_UNSPECIFIED);
-  CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV6);
-  CreateRequest("h1", 80, MEDIUM, ADDRESS_FAMILY_IPV4);
-
-  // Start all of the requests.
-  for (size_t i = 0; i < requests_.size(); ++i) {
-    EXPECT_EQ(ERR_IO_PENDING, requests_[i]->Resolve()) << i;
-  }
-
-  proc_->SignalMultiple(requests_.size());
-
-  // Wait for all the requests to complete.
-  for (size_t i = 0u; i < requests_.size(); ++i) {
-    EXPECT_EQ(OK, requests_[i]->WaitForResult()) << i;
-  }
-
-  // Since the requests all had the same priority and we limited the thread
-  // count to 1, they should have completed in the same order as they were
-  // requested. Moreover, request0 and request1 will have been serviced by
-  // the same job.
-
-  MockHostResolverProc::CaptureList capture_list = proc_->GetCaptureList();
-  ASSERT_EQ(2u, capture_list.size());
-
-  EXPECT_EQ("h1", capture_list[0].hostname);
-  EXPECT_EQ(ADDRESS_FAMILY_IPV6, capture_list[0].address_family);
-
-  EXPECT_EQ("h1", capture_list[1].hostname);
-  EXPECT_EQ(ADDRESS_FAMILY_IPV4, capture_list[1].address_family);
-
-  // Now check that the correct resolved IP addresses were returned.
-  EXPECT_TRUE(requests_[0]->HasOneAddress("::2", 80));
-  EXPECT_TRUE(requests_[1]->HasOneAddress("::2", 80));
-  EXPECT_TRUE(requests_[2]->HasOneAddress("1.0.0.1", 80));
-}
-
 }  // namespace net
diff --git a/net/dns/mapped_host_resolver.cc b/net/dns/mapped_host_resolver.cc
index 0003fbb..dc14b650 100644
--- a/net/dns/mapped_host_resolver.cc
+++ b/net/dns/mapped_host_resolver.cc
@@ -56,14 +56,6 @@
   return impl_->GetDnsConfigAsValue();
 }
 
-void MappedHostResolver::SetDefaultAddressFamily(AddressFamily address_family) {
-  impl_->SetDefaultAddressFamily(address_family);
-}
-
-AddressFamily MappedHostResolver::GetDefaultAddressFamily() const {
-  return impl_->GetDefaultAddressFamily();
-}
-
 void MappedHostResolver::SetNoIPv6OnWifi(bool no_ipv6_on_wifi) {
   impl_->SetNoIPv6OnWifi(no_ipv6_on_wifi);
 }
diff --git a/net/dns/mapped_host_resolver.h b/net/dns/mapped_host_resolver.h
index 5c76ce9..5ae459c 100644
--- a/net/dns/mapped_host_resolver.h
+++ b/net/dns/mapped_host_resolver.h
@@ -57,8 +57,6 @@
   void SetDnsClientEnabled(bool enabled) override;
   HostCache* GetHostCache() override;
   std::unique_ptr<base::Value> GetDnsConfigAsValue() const override;
-  void SetDefaultAddressFamily(AddressFamily address_family) override;
-  AddressFamily GetDefaultAddressFamily() const override;
   void SetNoIPv6OnWifi(bool no_ipv6_on_wifi) override;
   bool GetNoIPv6OnWifi() override;
 
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
index 12b24ad..54c1cf35 100644
--- a/printing/pdf_metafile_skia.cc
+++ b/printing/pdf_metafile_skia.cc
@@ -12,9 +12,9 @@
 #include "base/files/file.h"
 #include "base/memory/ptr_util.h"
 #include "base/time/time.h"
+#include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_record.h"
 #include "cc/paint/paint_recorder.h"
-#include "cc/paint/skia_paint_canvas.h"
 #include "printing/print_settings.h"
 #include "third_party/skia/include/core/SkDocument.h"
 #include "third_party/skia/include/core/SkStream.h"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/idbobjectstore-index-finished.html b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/idbobjectstore-index-finished.html
new file mode 100644
index 0000000..75677cf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/idbobjectstore-index-finished.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>IndexedDB: IDBObjectStore index() when transaction is finished</title>
+<link rel="help" href="https://w3c.github.io/IndexedDB/#dom-idbobjectstore-index">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+<script>
+
+indexeddb_test(
+  (t, db) => {
+    const store = db.createObjectStore('store');
+    store.createIndex('index', 'key_path');
+  },
+  (t, db) => {
+    const tx = db.transaction('store');
+    const store = tx.objectStore('store');
+    tx.abort();
+    assert_throws('InvalidStateError', () => store.index('index'),
+                  'index() should throw if transaction is finished');
+    t.done();
+  },
+  'IDBObjectStore index() behavior when transaction is finished'
+);
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/idbtransaction-objectStore-finished.html b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/idbtransaction-objectStore-finished.html
new file mode 100644
index 0000000..5e363ea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/idbtransaction-objectStore-finished.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>IndexedDB: IDBTransaction objectStore() when transaction is finished</title>
+<link rel="help" href="https://w3c.github.io/IndexedDB/#dom-idbtransaction-objectstore">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support.js"></script>
+<script>
+
+indexeddb_test(
+  (t, db) => {
+    db.createObjectStore('store');
+  },
+  (t, db) => {
+    const tx = db.transaction('store');
+    tx.abort();
+    assert_throws('InvalidStateError', () => tx.objectStore('store'),
+                  'objectStore() should throw if transaction is finished');
+    t.done();
+  },
+  'IDBTransaction objectStore() behavior when transaction is finished'
+);
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-expected.txt
index 09b0bad..4fa88d53 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-expected.txt
@@ -5,10 +5,10 @@
 
 PASS Rejected as expected: undefined
 PASS reason instanceof Error is true
-TypeError: Failed to execute 'createImageBitmap' on 'Window': The provided value is not of type '(HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'
+TypeError: Failed to execute 'createImageBitmap' on 'Window': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'
 PASS Rejected as expected: null
 PASS reason instanceof Error is true
-TypeError: Failed to execute 'createImageBitmap' on 'Window': The provided value is not of type '(HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'
+TypeError: Failed to execute 'createImageBitmap' on 'Window': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'
 PASS Rejected as expected: empty image
 PASS reason instanceof Error is true
 InvalidStateError: Failed to execute 'createImageBitmap' on 'Window': No image can be retrieved from the provided element.
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-in-workers-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-in-workers-expected.txt
index dcf97bd7..eddad15 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-in-workers-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-invalid-args-in-workers-expected.txt
@@ -6,7 +6,7 @@
 Starting worker: ./resources/canvas-createImageBitmap-invalid-args-in-workers.js
 PASS [Worker] Rejected as expected: null
 PASS [Worker] reason instanceof Error is true
-[Worker] TypeError: Failed to execute 'createImageBitmap' on 'WorkerGlobalScope': The provided value is not of type '(HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'
+[Worker] TypeError: Failed to execute 'createImageBitmap' on 'WorkerGlobalScope': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or Blob or ImageData or ImageBitmap or OffscreenCanvas)'
 PASS [Worker] Rejected as expected: invalid area
 PASS [Worker] reason instanceof Error is true
 [Worker] IndexSizeError: Failed to execute 'createImageBitmap' on 'WorkerGlobalScope': The source height provided is 0.
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html
deleted file mode 100644
index a18476a..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-image-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html>
-<style>
-svg {
-  border: 1px solid black;
-}
-#img4 {
-  display: none;
-}
-</style>
-<svg id="s1" width="20px" height="20px">
-  <image id="img1" href="resources/pattern.png" x="0" y="0" width="20px" height="20px" />
-</svg>
-<svg id="s2" width="20px" height="20px">
-  <image id="img1" href="resources/pattern.png" x="10" y="10" width="20px" height="20px" />
-</svg>
-<svg id="s3" width="20px" height="20px">
-  <image id="img3" href="resources/pattern.png" x="0" y="0" width="20px" height="20px" />
-</svg>
-<svg id="s4" width="20px" height="20px">
-  <image id="img4" href="invalid" x="0" y="0" width="20px" height="20px" />
-</svg>
-<svg id="s5" width="20px" height="20px">
-</svg>
-<svg id="s6" width="20px" height="20px">
-  <image id="img1" href="resources/pattern.png" x="0" y="0" width="10px" height="10px" />
-</svg>
-</svg>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-image.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-image.html
deleted file mode 100644
index 6780ef2..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-image.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!doctype html>
-<style>
-svg {
-  display: none;
-}
-canvas {
-  border: 1px solid black;
-}
-</style>
-
-<svg id="s1" width="200px" height="20px">
-  <image id="img1" href="resources/pattern.png" x="0" y="0" width="20px" height="20px" />
-  <image id="img2" href="resources/pattern.png" x="20" y="0" width="40px" height="40px" />
-  <image id="img3" href="resources/pattern.png" x="40" y="0" width="40px" height="40px" />
-  <image id="img4" href="invalid" x="60" y="0" width="20px" height="20px" />
-  <image id="img5" href="resources/pattern.png" x="80" y="0" width="20px" height="20px" />
-</svg>
-
-<canvas id="c1" width="20" height="20"></canvas>
-<canvas id="c2" width="20" height="20"></canvas>
-<canvas id="c3" width="20" height="20"></canvas>
-<canvas id="c4" width="20" height="20"></canvas>
-<canvas id="c5" width="20" height="20"></canvas>
-<canvas id="c6" width="20" height="20"></canvas>
-
-<script>
-var draw = function(target, img, x, y, opts) {
-  document.getElementById(img).addEventListener("load", function() {
-    createImageBitmap(this, opts).then((ib) => {
-      document.getElementById(target).getContext("2d").drawImage(
-        ib, x || 0, y || 0);
-    });
-  });
-}
-
-draw("c1", "img1");
-draw("c2", "img2", 10, 10);
-draw("c3", "img3");
-draw("c4", "img4");
-document.getElementById("c5").getContext("2d").drawImage(
-  document.getElementById("img5"), 0, 0);
-draw("c6", "img2", 0, 0, {resizeWidth: 10, resizeHeight: 10});
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/layers-in-multicol-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/layers-in-multicol-expected.html
new file mode 100644
index 0000000..97d5761f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/layers-in-multicol-expected.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<style>
+    .multicol {
+        width: 300px;
+        height: 100px;
+        line-height: 20px;
+        border: 5px solid maroon;
+    }
+    .column {
+        width: 100px;
+        float: left;
+    }
+    .multicol[dir="rtl"] > .column {
+        float: right;
+    }
+    .block {
+        display: inline-block;
+        width: 1em;
+        height: 10px;
+        background-color: green;
+    }
+    .opacity {
+        opacity: 0.5;
+        color: green;
+    }
+    .relative {
+        position: relative;
+        top: -4px;
+        color: green;
+    }
+</style>
+<p>
+    Test layers which are fully contained within a single column.
+</p>
+LTR:
+<div class="multicol">
+    <div class="column">
+        line1<br>
+        line2<br>
+        line3<br>
+        line4<br>
+        line5<br>
+    </div>
+    <div class="column">
+        line6<br>
+        <div class="block"></div> line7<br>
+        line8<br>
+        <span class="relative">relative9</span><br>
+        line10<br>
+    </div>
+    <div class="column">
+        line11<br>
+        line12<br>
+        <!-- The extra inner span below forces the creation of a transparency layer in Skia to work
+             around optimizations that would cause blending differences between the test and the
+             expectation. -->
+        <span class="opacity">opacity<span>13</span></span><br>
+        line14
+    </div>
+</div>
+
+RTL:
+<div class="multicol" dir="rtl">
+    <div class="column">
+        line1<br>
+        line2<br>
+        line3<br>
+        line4<br>
+        line5<br>
+    </div>
+    <div class="column">
+        line6<br>
+        <div class="block"></div> line7<br>
+        line8<br>
+        <span class="relative">relative9</span><br>
+        line10<br>
+    </div>
+    <div class="column">
+        line11<br>
+        line12<br>
+        <!-- The extra inner span below forces the creation of a transparency layer in Skia to work
+             around optimizations that would cause blending differences between the test and the
+             expectation. -->
+        <span class="opacity">opacity<span>13</span></span><br>
+        line14
+    </div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/layers-split-across-columns-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/layers-split-across-columns-expected.html
new file mode 100644
index 0000000..8bbd920
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/layers-split-across-columns-expected.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<style>
+    .container {
+        margin-right: 4px;
+        position: absolute;
+    }
+    .multicol {
+        width: 110px;
+        height: 150px;
+        border: 5px solid black;
+    }
+    .multicol > div {
+        float: left;
+        width: 50px;
+        height: 50px;
+    }
+
+    .row1_left { background-color: black; }
+    .row1_right { background-color: #0000b0; }
+    .row2_left { background-color: #0000f0; }
+    .row2_right { background-color: #000090; }
+    .row3_left { background-color: #0000d0; }
+    .row3_right { background-color: black; }
+
+    .row1_right,
+    .row2_right,
+    .row3_right {
+        margin-left: 10px;
+    }
+
+    #opacity .row1_right,
+    #opacity .row2_left,
+    #opacity .row2_right,
+    #opacity .row3_left {
+        opacity: 0.99;
+    }
+
+    .pos1 { left: 10px; top: 10px; }
+    .pos2 { left: 150px; top: 10px; }
+    .pos3 { left: 10px; top: 200px; }
+    .pos4 { left: 150px; top: 200px; }
+
+</style>
+<div class="container pos1">
+    Overflow:
+    <div class="multicol">
+        <div class="row1_left"></div>
+        <div class="row1_right"></div>
+        <div class="row2_left"></div>
+        <div class="row2_right"></div>
+        <div class="row3_left"></div>
+        <div class="row3_right"></div>
+    </div>
+</div>
+<div class="container pos2">
+    Transforms:
+    <div class="multicol">
+        <div class="row1_left"></div>
+        <div class="row1_right"></div>
+        <div class="row2_left"></div>
+        <div class="row2_right"></div>
+        <div class="row3_left"></div>
+        <div class="row3_right"></div>
+    </div>
+</div>
+<div class="container pos3">
+    Relative Pos.:
+    <div class="multicol">
+        <div class="row1_left"></div>
+        <div class="row1_right"></div>
+        <div class="row2_left"></div>
+        <div class="row2_right"></div>
+        <div class="row3_left"></div>
+        <div class="row3_right"></div>
+    </div>
+</div>
+<div class="container pos4" id="opacity">
+    Opacity:
+    <div class="multicol">
+        <div class="row1_left"></div>
+        <!-- The extra &nbsp;s below force the creation of transparency layers in Skia to work
+             around optimizations that would cause blending differences between the test and the
+             expectation. -->
+        <div class="row1_right">&nbsp;</div>
+        <div class="row2_left">&nbsp;</div>
+        <div class="row2_right">&nbsp;</div>
+        <div class="row3_left">&nbsp;</div>
+        <div class="row3_right"></div>
+    </div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.html
new file mode 100644
index 0000000..0b67873
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.html
@@ -0,0 +1,6 @@
+<div style="position:relative; width:420px;border:2px solid black; height:200px">
+<!-- The extra &nbsp; below forces the creation of a transparency layer in Skia to work around
+     optimizations that would cause blending differences between the test and the expectation. -->
+<div style="opacity:0.5; position:absolute;width:200px;height:100px;background-color:green;right:0;top:0">&nbsp;</div>
+</div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.png b/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.png
deleted file mode 100644
index 1ebb6e8..0000000
--- a/third_party/WebKit/LayoutTests/fast/multicol/transform-inside-opacity-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt
index 16d3794c..2ee62a6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/service-workers/service-workers-navigation-preload-expected.txt
@@ -20,7 +20,7 @@
   timing available: true
   requestHeaders['Service-Worker-Navigation-Preload']: hello
 onRequestFinished:
-  localizedFailDescription: Navigation Preload Error
+  localizedFailDescription: net::ERR_INVALID_CHUNKED_ENCODING
 The iframe loaded.
 -----------------
 Loading another iframe.
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png
index c6cabcbb..a92e6a8 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/column-float-under-stacked-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-in-multicol-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-in-multicol-expected.png
deleted file mode 100644
index 44fc4a4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-in-multicol-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-split-across-columns-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-split-across-columns-expected.png
deleted file mode 100644
index 27fbf58..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/multicol/layers-split-across-columns-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 5e1fff8..b024e71 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png
index 6f98684..8d5f6fd3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 5e1fff8..b024e71 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png
index 0acea10..3a881330 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/transforms/2d/hindi-rotated-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 991aaf7a..07e019c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png
index 84b89da..11b5d71 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png
index 1693941..f409f9e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/transformed-focused-text-input-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 991aaf7a..07e019c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-in-multicol-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-in-multicol-expected.png
deleted file mode 100644
index 9243efa..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-in-multicol-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-split-across-columns-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-split-across-columns-expected.png
deleted file mode 100644
index 86cf379..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/multicol/layers-split-across-columns-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index af00c64c0..56d7e380c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
index 31dd704..ab426ac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-background-image/background-image-preserveaspectRatio-support-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png
index 98ce8c5..7e1243a1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-image/img-preserveAspectRatio-support-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
index 556507c..8938c8b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/zoom/page/zoom-img-preserveAspectRatio-support-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png
index 70f55312..497919fc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/hindi-rotated-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png
index c57f417b..38e6870 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-focused-text-input-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index af00c64c0..56d7e380c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-in-multicol-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-in-multicol-expected.png
deleted file mode 100644
index 62b98ea..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-in-multicol-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-split-across-columns-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-split-across-columns-expected.png
deleted file mode 100644
index 608b610..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/fast/multicol/layers-split-across-columns-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 6eb1bf6..8829276ef 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png
index 5b597ed..6837fed 100644
--- a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/hindi-rotated-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 6eb1bf6..8829276ef 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 27dad6f..bbb8278 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png
index 855bfdf8..7e9778db 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
index 27dad6f..bbb8278 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/disable-spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png
Binary files differ
diff --git a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
index 4aff4bd..986f8f2 100644
--- a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
+++ b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
@@ -811,12 +811,12 @@
 You can write custom bindings as V8XXX::namedPropertyQuery(...) and V8XXX::namedPropertyEnumerator(...) in Source/bindings/v8/custom/V8XXXCustom.cpp:
 
 ```c++
-v8::Handle<v8::Integer> V8XXX::namedPropertyQuery(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+v8::Local<v8::Integer> V8XXX::namedPropertyQuery(v8::Local<v8::String> name, const v8::AccessorInfo& info)
 {
     ...;
 }
 
-v8::Handle<v8::Array> V8XXX::namedPropertyEnumerator(const v8::AccessorInfo& info)
+v8::Local<v8::Array> V8XXX::namedPropertyEnumerator(const v8::AccessorInfo& info)
 {
     ...;
 }
@@ -841,7 +841,7 @@
 You can write custom `V8XXX::callAsFunctionCallback(...)` in Source/bindings/v8/custom/V8XXXCustom.cpp:
 
 ```c++
-v8::Handle<v8::Value> V8XXX::callAsFunctionCallback(const v8::Arguments& args)
+v8::Local<v8::Value> V8XXX::callAsFunctionCallback(const v8::Arguments& args)
 {
     ...;
 }
@@ -1411,7 +1411,7 @@
 Then you can write custom bindings in Source/bindings/v8/custom/V8XXXConstructorCustom.cpp:
 
 ```c++
-v8::Handle<v8::Value> V8XXX::constructorCallback(const v8::Arguments& args)
+v8::Local<v8::Value> V8XXX::constructorCallback(const v8::Arguments& args)
 {
    ...;
 }
diff --git a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
index 9686fc9..086d637 100644
--- a/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
+++ b/third_party/WebKit/Source/bindings/core/v8/BUILD.gn
@@ -204,8 +204,8 @@
   "$bindings_core_v8_output_dir/FloatOrStringElementRecord.h",
   "$bindings_core_v8_output_dir/HTMLElementOrLong.cpp",
   "$bindings_core_v8_output_dir/HTMLElementOrLong.h",
-  "$bindings_core_v8_output_dir/HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.cpp",
-  "$bindings_core_v8_output_dir/HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.h",
+  "$bindings_core_v8_output_dir/HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.cpp",
+  "$bindings_core_v8_output_dir/HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.h",
   "$bindings_core_v8_output_dir/HTMLOptionElementOrHTMLOptGroupElement.cpp",
   "$bindings_core_v8_output_dir/HTMLOptionElementOrHTMLOptGroupElement.h",
   "$bindings_core_v8_output_dir/HTMLScriptElementOrSVGScriptElement.cpp",
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScopedPersistent.h b/third_party/WebKit/Source/bindings/core/v8/ScopedPersistent.h
index 3d5872a..51ffd6e 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScopedPersistent.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScopedPersistent.h
@@ -85,7 +85,7 @@
     handle_.Reset(isolate, handle);
   }
 
-  // Note: This is clear in the std::unique_ptr sense, not the v8::Handle sense.
+  // Note: This is clear in the std::unique_ptr sense, not the v8::Local sense.
   void Clear() { handle_.Reset(); }
 
   bool operator==(const ScopedPersistent<T>& other) {
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 0594bc6..60b8cf6 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -475,6 +475,9 @@
     case kCapsLockIndicatorPart:
       value_id_ = CSSValueCapsLockIndicator;
       break;
+    case kMediaRemotingCastIconPart:
+      value_id_ = CSSValueInternalMediaRemotingCastIcon;
+      break;
   }
 }
 
diff --git a/third_party/WebKit/Source/core/css/CSSValueKeywords.json5 b/third_party/WebKit/Source/core/css/CSSValueKeywords.json5
index 6dfe0a6..e340a8fe 100644
--- a/third_party/WebKit/Source/core/css/CSSValueKeywords.json5
+++ b/third_party/WebKit/Source/core/css/CSSValueKeywords.json5
@@ -668,6 +668,7 @@
     "-internal-media-subtitles-icon",
     "-internal-media-overflow-button",
     "-internal-media-download-button",
+    "-internal-media-remoting-cast-icon",
     "menulist",
     "menulist-button",
     "menulist-text",
diff --git a/third_party/WebKit/Source/core/css/mediaControls.css b/third_party/WebKit/Source/core/css/mediaControls.css
index f13cb3d..dd4a094 100644
--- a/third_party/WebKit/Source/core/css/mediaControls.css
+++ b/third_party/WebKit/Source/core/css/mediaControls.css
@@ -145,6 +145,87 @@
     padding: 0;
 }
 
+/* TODO(xjz): Move media remoting elements to a separate css file. */
+video::-internal-media-remoting-interstitial {
+    width: inherit;
+    height: inherit;
+    position: relative;
+    direction: ltr;
+    display: flex;
+    flex-direction: column;
+    font-family: Segoe, "Helvetica Neue", Roboto, Arial, Helvetica, sans-serif;
+    justify-content: flex-end;
+    align-items: center;
+    font-size: 28px;
+    background-color: black;
+    transition: opacity .2s cubic-bezier (0.4, 0.0, 0.2, 1);
+}
+
+video::-internal-media-remoting-background-image {
+    display: flex;
+    position: absolute;
+    margin: 0;
+    top: 0px;
+    left: 0px;
+    width: 100%;
+    height: 100%;
+    border: none;
+    border-width: 0px;
+    background-color: transparent;
+    padding: 0;
+    filter: grayscale(100%) blur(5px);
+}
+
+video::-internal-media-remoting-cast-icon {
+    -webkit-appearance: -internal-media-remoting-cast-icon;
+    display: flex;
+    position: absolute;
+    margin: 0px;
+    border-width: 0px;
+    background-color: transparent;
+    height: 36px;
+    width: 44px;
+    padding: 0px;
+    left: calc(50% - 22px);
+    top: calc(50% - 60px);
+}
+
+video::-internal-media-remoting-cast-text-message {
+    display: inline;
+    position: absolute;
+    top: calc(50% - 10px);
+    border: none;
+    color: #FFFFFF;
+    opacity: 54%
+    width: 100%;
+    text-wrap: none;
+    text-align: center;
+    background-color: transparent;
+    font-size: 13pt;
+    font-face: Roboto-Regular, Sans-serif, Segoe, Serif, Helvetica;
+    padding: 0px;
+    margin: 0px;
+}
+
+video::-internal-media-remoting-disable-button {
+    display: flex;
+    position: absolute;
+    top: calc(50% + 55pt);
+    left: calc(50% - 102px);
+    height: 28pt;
+    border: 2pt solid rgba(255,255,255,.54);
+    border-radius: 2pt;
+    background-color: transparent;
+    color: #FFFFFF;
+    margin: 0px;
+    padding: 8pt 16pt 0pt 16pt;
+    text-wrap: none;
+    font-size: 13pt;
+    font-face: Roboto-Medium, Sans-serif, Segoe, Serif, Helvetica;
+    opacity: 54%
+    transition: border .5s ease-out;
+}
+
 video::-internal-media-controls-overlay-cast-button {
     -webkit-appearance: -internal-media-overlay-cast-off-button;
     display: flex;
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn
index 13a8eb86..c23c3a3d 100644
--- a/third_party/WebKit/Source/core/dom/BUILD.gn
+++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -197,6 +197,8 @@
     "Modulator.h",
     "ModuleMap.cpp",
     "ModuleMap.h",
+    "ModulePendingScript.cpp",
+    "ModulePendingScript.h",
     "ModuleScript.cpp",
     "ModuleScript.h",
     "MutationCallback.h",
diff --git a/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp b/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
index 2ff5068..047b3647 100644
--- a/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
+++ b/third_party/WebKit/Source/core/dom/ClassicPendingScript.cpp
@@ -229,7 +229,7 @@
   return GetResource()->WasCanceled();
 }
 
-KURL ClassicPendingScript::Url() const {
+KURL ClassicPendingScript::UrlForClassicScript() const {
   return GetResource()->Url();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/ClassicPendingScript.h b/third_party/WebKit/Source/core/dom/ClassicPendingScript.h
index 13a7519b..153eeb61 100644
--- a/third_party/WebKit/Source/core/dom/ClassicPendingScript.h
+++ b/third_party/WebKit/Source/core/dom/ClassicPendingScript.h
@@ -49,11 +49,11 @@
   ClassicScript* GetSource(const KURL& document_url,
                            bool& error_occurred) const override;
   bool IsReady() const override;
-  KURL Url() const override;
   bool IsExternal() const override { return GetResource(); }
   bool ErrorOccurred() const override;
   bool WasCanceled() const override;
   void StartStreamingIfPossible(Document*, ScriptStreamer::Type) override;
+  KURL UrlForClassicScript() const override;
   void RemoveFromMemoryCache() override;
   void DisposeInternal() override;
 
diff --git a/third_party/WebKit/Source/core/dom/ClassicScript.cpp b/third_party/WebKit/Source/core/dom/ClassicScript.cpp
index 9898325..a4b726bb 100644
--- a/third_party/WebKit/Source/core/dom/ClassicScript.cpp
+++ b/third_party/WebKit/Source/core/dom/ClassicScript.cpp
@@ -51,10 +51,6 @@
   visitor->Trace(script_source_code_);
 }
 
-DEFINE_TRACE_WRAPPERS(ClassicScript) {
-  Script::TraceWrappers(visitor);
-}
-
 bool ClassicScript::IsEmpty() const {
   return GetScriptSourceCode().IsEmpty();
 }
diff --git a/third_party/WebKit/Source/core/dom/ClassicScript.h b/third_party/WebKit/Source/core/dom/ClassicScript.h
index b8c36533..887214d 100644
--- a/third_party/WebKit/Source/core/dom/ClassicScript.h
+++ b/third_party/WebKit/Source/core/dom/ClassicScript.h
@@ -18,7 +18,6 @@
   }
 
   DECLARE_TRACE();
-  DECLARE_TRACE_WRAPPERS();
 
   const ScriptSourceCode& GetScriptSourceCode() const {
     return script_source_code_;
diff --git a/third_party/WebKit/Source/core/dom/ElementRareData.h b/third_party/WebKit/Source/core/dom/ElementRareData.h
index ee04b86..9422f5c8 100644
--- a/third_party/WebKit/Source/core/dom/ElementRareData.h
+++ b/third_party/WebKit/Source/core/dom/ElementRareData.h
@@ -44,15 +44,14 @@
 
 namespace blink {
 
-class LayoutObject;
 class CompositorProxiedPropertySet;
 class ResizeObservation;
 class ResizeObserver;
 
 class ElementRareData : public NodeRareData {
  public:
-  static ElementRareData* Create(LayoutObject* layout_object) {
-    return new ElementRareData(layout_object);
+  static ElementRareData* Create(NodeLayoutData* node_layout_data) {
+    return new ElementRareData(node_layout_data);
   }
 
   ~ElementRareData();
@@ -226,17 +225,16 @@
 
   Member<AccessibleNode> accessible_node_;
 
-  explicit ElementRareData(LayoutObject*);
+  explicit ElementRareData(NodeLayoutData*);
 };
-
 DEFINE_TRAIT_FOR_TRACE_WRAPPERS(ElementRareData);
 
 inline LayoutSize DefaultMinimumSizeForResizing() {
   return LayoutSize(LayoutUnit::Max(), LayoutUnit::Max());
 }
 
-inline ElementRareData::ElementRareData(LayoutObject* layout_object)
-    : NodeRareData(layout_object),
+inline ElementRareData::ElementRareData(NodeLayoutData* node_layout_data)
+    : NodeRareData(node_layout_data),
       minimum_size_for_resizing_(DefaultMinimumSizeForResizing()),
       class_list_(nullptr) {
   is_element_rare_data_ = true;
diff --git a/third_party/WebKit/Source/core/dom/Modulator.h b/third_party/WebKit/Source/core/dom/Modulator.h
index ef95e0b..ad1d582 100644
--- a/third_party/WebKit/Source/core/dom/Modulator.h
+++ b/third_party/WebKit/Source/core/dom/Modulator.h
@@ -34,6 +34,13 @@
   virtual void NotifyModuleLoadFinished(ModuleScript*) = 0;
 };
 
+// A ModuleTreeClient is notified when a module script and its whole descendent
+// tree load is complete.
+class ModuleTreeClient : public GarbageCollectedMixin {
+ public:
+  virtual void NotifyModuleTreeLoadFinished(ModuleScript*) = 0;
+};
+
 // spec: "top-level module fetch flag"
 // https://html.spec.whatwg.org/multipage/webappapis.html#fetching-scripts-is-top-level
 enum class ModuleGraphLevel { kTopLevelModuleFetch, kDependentModuleFetch };
diff --git a/third_party/WebKit/Source/core/dom/ModulePendingScript.cpp b/third_party/WebKit/Source/core/dom/ModulePendingScript.cpp
new file mode 100644
index 0000000..f0184b1
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/ModulePendingScript.cpp
@@ -0,0 +1,82 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/dom/ModulePendingScript.h"
+
+#include "core/dom/ScriptLoader.h"
+#include "core/frame/LocalFrame.h"
+
+namespace blink {
+
+ModulePendingScriptTreeClient::ModulePendingScriptTreeClient()
+    : module_script_(nullptr), pending_script_(nullptr) {}
+
+void ModulePendingScriptTreeClient::SetPendingScript(
+    ModulePendingScript* pending_script) {
+  DCHECK(!pending_script_);
+  pending_script_ = pending_script;
+
+  if (finished_) {
+    pending_script_->NotifyModuleTreeLoadFinished();
+  }
+}
+
+void ModulePendingScriptTreeClient::NotifyModuleTreeLoadFinished(
+    ModuleScript* module_script) {
+  DCHECK(!(module_script && module_script->InstantiationState() ==
+                                ModuleInstantiationState::kUninstantiated));
+  DCHECK(!finished_);
+  finished_ = true;
+  module_script_ = module_script;
+
+  if (pending_script_)
+    pending_script_->NotifyModuleTreeLoadFinished();
+}
+
+DEFINE_TRACE(ModulePendingScriptTreeClient) {
+  visitor->Trace(module_script_);
+  visitor->Trace(pending_script_);
+  ModuleTreeClient::Trace(visitor);
+}
+
+ModulePendingScript::ModulePendingScript(ScriptElementBase* element,
+                                         ModulePendingScriptTreeClient* client)
+    : PendingScript(element, TextPosition()), module_tree_client_(client) {
+  CHECK(this->GetElement());
+  DCHECK(module_tree_client_);
+  client->SetPendingScript(this);
+}
+
+ModulePendingScript::~ModulePendingScript() {}
+
+void ModulePendingScript::DisposeInternal() {
+  module_tree_client_ = nullptr;
+}
+
+DEFINE_TRACE(ModulePendingScript) {
+  visitor->Trace(module_tree_client_);
+  PendingScript::Trace(visitor);
+}
+
+void ModulePendingScript::NotifyModuleTreeLoadFinished() {
+  CHECK(!IsReady());
+  ready_ = true;
+
+  if (Client())
+    Client()->PendingScriptFinished(this);
+}
+
+Script* ModulePendingScript::GetSource(const KURL& document_url,
+                                       bool& error_occurred) const {
+  CHECK(IsReady());
+  error_occurred = ErrorOccurred();
+  return GetModuleScript();
+}
+
+bool ModulePendingScript::ErrorOccurred() const {
+  CHECK(IsReady());
+  return !GetModuleScript();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ModulePendingScript.h b/third_party/WebKit/Source/core/dom/ModulePendingScript.h
new file mode 100644
index 0000000..62ecccb
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/ModulePendingScript.h
@@ -0,0 +1,98 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ModulePendingScript_h
+#define ModulePendingScript_h
+
+#include "core/dom/Modulator.h"
+#include "core/dom/ModuleScript.h"
+#include "core/dom/PendingScript.h"
+
+namespace blink {
+
+class ModulePendingScript;
+
+// ModulePendingScriptTreeClient is used to connect from Modulator::FetchTree()
+// to ModulePendingScript. Because ModulePendingScript is created after
+// Modulator::FetchTree() is called, ModulePendingScriptTreeClient is
+// registered as ModuleTreeClient to FetchTree() first, and later
+// ModulePendingScript is supplied to ModulePendingScriptTreeClient via
+// SetPendingScript() and is notified of module tree load finish.
+class ModulePendingScriptTreeClient final
+    : public GarbageCollectedFinalized<ModulePendingScriptTreeClient>,
+      public ModuleTreeClient {
+  USING_GARBAGE_COLLECTED_MIXIN(ModulePendingScriptTreeClient);
+
+ public:
+  static ModulePendingScriptTreeClient* Create() {
+    return new ModulePendingScriptTreeClient();
+  }
+  virtual ~ModulePendingScriptTreeClient() = default;
+
+  void SetPendingScript(ModulePendingScript* client);
+
+  ModuleScript* GetModuleScript() const { return module_script_; }
+
+  DECLARE_TRACE();
+
+ private:
+  ModulePendingScriptTreeClient();
+
+  // Implements ModuleTreeClient
+  void NotifyModuleTreeLoadFinished(ModuleScript*) override;
+
+  bool finished_ = false;
+  Member<ModuleScript> module_script_;
+  Member<ModulePendingScript> pending_script_;
+};
+
+// PendingScript for a module script
+// https://html.spec.whatwg.org/#module-script.
+class CORE_EXPORT ModulePendingScript : public PendingScript {
+ public:
+  static ModulePendingScript* Create(ScriptElementBase* element,
+                                     ModulePendingScriptTreeClient* client) {
+    return new ModulePendingScript(element, client);
+  }
+
+  ~ModulePendingScript() override;
+
+  void NotifyModuleTreeLoadFinished();
+
+  ModuleScript* GetModuleScript() const {
+    return module_tree_client_->GetModuleScript();
+  }
+
+  DECLARE_TRACE();
+
+ private:
+  ModulePendingScript(ScriptElementBase*, ModulePendingScriptTreeClient*);
+
+  // PendingScript
+  ScriptType GetScriptType() const override { return ScriptType::kModule; }
+  Script* GetSource(const KURL& document_url,
+                    bool& error_occurred) const override;
+  bool IsReady() const override { return ready_; }
+  bool IsExternal() const override { return true; }
+  bool ErrorOccurred() const override;
+  bool WasCanceled() const override { return false; }
+
+  void StartStreamingIfPossible(Document*, ScriptStreamer::Type) override {}
+  KURL UrlForClassicScript() const override {
+    NOTREACHED();
+    return KURL();
+  }
+  void RemoveFromMemoryCache() override { NOTREACHED(); }
+
+  void DisposeInternal() override;
+
+  void CheckState() const override {}
+
+  Member<ModulePendingScriptTreeClient> module_tree_client_;
+  bool ready_ = false;
+};
+
+}  // namespace blink
+
+#endif  // ModulePendingScript_h
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.cpp b/third_party/WebKit/Source/core/dom/ModuleScript.cpp
index ced261f0..28fa847d 100644
--- a/third_party/WebKit/Source/core/dom/ModuleScript.cpp
+++ b/third_party/WebKit/Source/core/dom/ModuleScript.cpp
@@ -24,7 +24,6 @@
   Script::Trace(visitor);
 }
 DEFINE_TRACE_WRAPPERS(ModuleScript) {
-  Script::TraceWrappers(visitor);
   visitor->TraceWrappers(instantiation_error_);
 }
 
diff --git a/third_party/WebKit/Source/core/dom/ModuleScript.h b/third_party/WebKit/Source/core/dom/ModuleScript.h
index 6624f605..dbe6db9 100644
--- a/third_party/WebKit/Source/core/dom/ModuleScript.h
+++ b/third_party/WebKit/Source/core/dom/ModuleScript.h
@@ -27,7 +27,7 @@
 
 // ModuleScript is a model object for the "module script" spec concept.
 // https://html.spec.whatwg.org/multipage/webappapis.html#module-script
-class CORE_EXPORT ModuleScript final : public Script {
+class CORE_EXPORT ModuleScript final : public Script, public TraceWrapperBase {
  public:
   static ModuleScript* Create(
       ScriptModule record,
@@ -58,7 +58,7 @@
   const String& Nonce() const { return nonce_; }
 
   DECLARE_TRACE();
-  DECLARE_VIRTUAL_TRACE_WRAPPERS();
+  DECLARE_TRACE_WRAPPERS();
 
  private:
   ModuleScript(ScriptModule record,
@@ -96,6 +96,13 @@
       ModuleInstantiationState::kUninstantiated;
 
   // https://html.spec.whatwg.org/multipage/webappapis.html#concept-module-script-instantiation-error
+  //
+  // |instantiation_error_| is TraceWrappers()ed and kept alive via the path of
+  // v8::Context -> PerContextData -> Modulator/ModulatorImpl
+  // -> ModuleMap -> ModuleMap::Entry -> ModuleScript -> instantiation_error_.
+  // All the classes/references on the path above should be
+  // TraceWrapperBase/TraceWrapperMember<>/etc.,
+  // but other references to those classes can be normal Member<>.
   TraceWrapperV8Reference<v8::Value> instantiation_error_;
 
   // https://html.spec.whatwg.org/multipage/webappapis.html#concept-module-script-nonce
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index e7d6f09..a61464b 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -295,9 +295,8 @@
 }
 
 Node::~Node() {
-  // With Oilpan, the rare data finalizer also asserts for
-  // this condition (we cannot directly access it here.)
-  CHECK(HasRareData() || !GetLayoutObject());
+  if (!HasRareData() && !data_.node_layout_data_->IsSharedEmptyData())
+    delete data_.node_layout_data_;
   InstanceCounters::DecrementNodeCounter();
 }
 
@@ -311,9 +310,9 @@
     return *RareData();
 
   if (IsElementNode())
-    data_.rare_data_ = ElementRareData::Create(data_.layout_object_);
+    data_.rare_data_ = ElementRareData::Create(data_.node_layout_data_);
   else
-    data_.rare_data_ = NodeRareData::Create(data_.layout_object_);
+    data_.rare_data_ = NodeRareData::Create(data_.node_layout_data_);
 
   DCHECK(data_.rare_data_);
   SetFlag(kHasRareDataFlag);
@@ -589,6 +588,30 @@
                                                  : nullptr;
 }
 
+void Node::SetLayoutObject(LayoutObject* layout_object) {
+  NodeLayoutData* node_layout_data = HasRareData()
+                                         ? data_.rare_data_->GetNodeLayoutData()
+                                         : data_.node_layout_data_;
+
+  // Already pointing to a non empty NodeLayoutData so just set the pointer to
+  // the new LayoutObject.
+  if (!node_layout_data->IsSharedEmptyData()) {
+    node_layout_data->SetLayoutObject(layout_object);
+    return;
+  }
+
+  if (!layout_object)
+    return;
+
+  // Swap the NodeLayoutData to point to a new NodeLayoutData instead of the
+  // static SharedEmptyData instance.
+  node_layout_data = new NodeLayoutData(layout_object);
+  if (HasRareData())
+    data_.rare_data_->SetNodeLayoutData(node_layout_data);
+  else
+    data_.node_layout_data_ = node_layout_data;
+}
+
 LayoutBoxModelObject* Node::GetLayoutBoxModelObject() const {
   LayoutObject* layout_object = this->GetLayoutObject();
   return layout_object && layout_object->IsBoxModelObject()
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index c3f294d8..369b8c5 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -57,6 +57,7 @@
 class NodeList;
 class NodeListsNodeData;
 class NodeOrString;
+class NodeLayoutData;
 class NodeRareData;
 class QualifiedName;
 class RegisteredEventListener;
@@ -98,21 +99,45 @@
   kChained,
 };
 
-class NodeRareDataBase {
+class NodeLayoutData {
  public:
+  explicit NodeLayoutData(LayoutObject* layout_object)
+      : layout_object_(layout_object) {}
+  ~NodeLayoutData() { CHECK(!layout_object_); }
+
   LayoutObject* GetLayoutObject() const { return layout_object_; }
   void SetLayoutObject(LayoutObject* layout_object) {
+    DCHECK_NE(&SharedEmptyData(), this);
     layout_object_ = layout_object;
   }
+  static NodeLayoutData& SharedEmptyData() {
+    DEFINE_STATIC_LOCAL(NodeLayoutData, shared_empty_data, (nullptr));
+    return shared_empty_data;
+  }
+  bool IsSharedEmptyData() { return this == &SharedEmptyData(); }
+
+ private:
+  LayoutObject* layout_object_;
+};
+
+class NodeRareDataBase {
+ public:
+  NodeLayoutData* GetNodeLayoutData() const { return node_layout_data_; }
+  void SetNodeLayoutData(NodeLayoutData* node_layout_data) {
+    DCHECK(node_layout_data);
+    node_layout_data_ = node_layout_data;
+  }
 
  protected:
-  NodeRareDataBase(LayoutObject* layout_object)
-      : layout_object_(layout_object) {}
+  NodeRareDataBase(NodeLayoutData* node_layout_data)
+      : node_layout_data_(node_layout_data) {}
+  ~NodeRareDataBase() {
+    if (node_layout_data_ && !node_layout_data_->IsSharedEmptyData())
+      delete node_layout_data_;
+  }
 
  protected:
-  // LayoutObjects are fully owned by their DOM node. See LayoutObject's
-  // LIFETIME documentation section.
-  LayoutObject* layout_object_;
+  NodeLayoutData* node_layout_data_;
 };
 
 class Node;
@@ -287,6 +312,7 @@
   virtual bool IsAttributeNode() const { return false; }
   virtual bool IsCharacterDataNode() const { return false; }
   virtual bool IsFrameOwnerElement() const { return false; }
+  virtual bool IsMediaRemotingInterstitial() const { return false; }
 
   bool IsStyledElement() const;
 
@@ -568,16 +594,11 @@
   // Note that if a Node has a layoutObject, it's parentNode is guaranteed to
   // have one as well.
   LayoutObject* GetLayoutObject() const {
-    return HasRareData() ? data_.rare_data_->GetLayoutObject()
-                         : data_.layout_object_;
+    return HasRareData()
+               ? data_.rare_data_->GetNodeLayoutData()->GetLayoutObject()
+               : data_.node_layout_data_->GetLayoutObject();
   }
-  void SetLayoutObject(LayoutObject* layout_object) {
-    if (HasRareData())
-      data_.rare_data_->SetLayoutObject(layout_object);
-    else
-      data_.layout_object_ = layout_object;
-  }
-
+  void SetLayoutObject(LayoutObject*);
   // Use these two methods with caution.
   LayoutBox* GetLayoutBox() const;
   LayoutBoxModelObject* GetLayoutBoxModelObject() const;
@@ -930,10 +951,10 @@
   Member<Node> next_;
   // When a node has rare data we move the layoutObject into the rare data.
   union DataUnion {
-    DataUnion() : layout_object_(nullptr) {}
+    DataUnion() : node_layout_data_(&NodeLayoutData::SharedEmptyData()) {}
     // LayoutObjects are fully owned by their DOM node. See LayoutObject's
     // LIFETIME documentation section.
-    LayoutObject* layout_object_;
+    NodeLayoutData* node_layout_data_;
     NodeRareDataBase* rare_data_;
   } data_;
 };
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.cpp b/third_party/WebKit/Source/core/dom/NodeRareData.cpp
index 221b9ca..46b358d 100644
--- a/third_party/WebKit/Source/core/dom/NodeRareData.cpp
+++ b/third_party/WebKit/Source/core/dom/NodeRareData.cpp
@@ -77,7 +77,6 @@
 }
 
 void NodeRareData::FinalizeGarbageCollectedObject() {
-  CHECK(!GetLayoutObject());
   if (is_element_rare_data_)
     static_cast<ElementRareData*>(this)->~ElementRareData();
   else
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.h b/third_party/WebKit/Source/core/dom/NodeRareData.h
index f33fbe6..0e50069f 100644
--- a/third_party/WebKit/Source/core/dom/NodeRareData.h
+++ b/third_party/WebKit/Source/core/dom/NodeRareData.h
@@ -98,8 +98,8 @@
   WTF_MAKE_NONCOPYABLE(NodeRareData);
 
  public:
-  static NodeRareData* Create(LayoutObject* layout_object) {
-    return new NodeRareData(layout_object);
+  static NodeRareData* Create(NodeLayoutData* node_layout_data) {
+    return new NodeRareData(node_layout_data);
   }
 
   void ClearNodeLists() { node_lists_.Clear(); }
@@ -163,12 +163,14 @@
   DECLARE_TRACE_WRAPPERS_AFTER_DISPATCH();
 
  protected:
-  explicit NodeRareData(LayoutObject* layout_object)
-      : NodeRareDataBase(layout_object),
+  explicit NodeRareData(NodeLayoutData* node_layout_data)
+      : NodeRareDataBase(node_layout_data),
         connected_frame_count_(0),
         element_flags_(0),
         restyle_flags_(0),
-        is_element_rare_data_(false) {}
+        is_element_rare_data_(false) {
+    CHECK_NE(node_layout_data, nullptr);
+  }
 
  private:
   Member<NodeListsNodeData> node_lists_;
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.h b/third_party/WebKit/Source/core/dom/PendingScript.h
index f0175f5..6886b9bb 100644
--- a/third_party/WebKit/Source/core/dom/PendingScript.h
+++ b/third_party/WebKit/Source/core/dom/PendingScript.h
@@ -88,14 +88,14 @@
   // https://html.spec.whatwg.org/#the-script-is-ready
   virtual bool IsReady() const = 0;
 
-  virtual KURL Url() const = 0;
   virtual bool IsExternal() const = 0;
   virtual bool ErrorOccurred() const = 0;
   virtual bool WasCanceled() const = 0;
   virtual void StartStreamingIfPossible(Document*, ScriptStreamer::Type) = 0;
 
-  // Used for document.write() intervention.
-  // Has effects only for classic scripts.
+  // The following two methods are used for document.write() intervention and
+  // have effects only for classic scripts.
+  virtual KURL UrlForClassicScript() const = 0;
   virtual void RemoveFromMemoryCache() = 0;
 
   void Dispose();
diff --git a/third_party/WebKit/Source/core/dom/Script.h b/third_party/WebKit/Source/core/dom/Script.h
index b3e1be5..471751b 100644
--- a/third_party/WebKit/Source/core/dom/Script.h
+++ b/third_party/WebKit/Source/core/dom/Script.h
@@ -19,11 +19,9 @@
 enum class ScriptType { kClassic, kModule };
 
 // https://html.spec.whatwg.org/#concept-script
-class CORE_EXPORT Script : public GarbageCollectedFinalized<Script>,
-                           public TraceWrapperBase {
+class CORE_EXPORT Script : public GarbageCollectedFinalized<Script> {
  public:
   DEFINE_INLINE_VIRTUAL_TRACE() {}
-  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {}
 
   virtual ~Script() {}
 
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index abd2738..74e0cefd 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -554,7 +554,7 @@
   return StaticBitmapImage::Create(PremulSkImageToUnPremul(skia_image.get()));
 }
 
-ImageBitmap::ImageBitmap(ImageElementBase* image,
+ImageBitmap::ImageBitmap(HTMLImageElement* image,
                          Optional<IntRect> crop_rect,
                          Document* document,
                          const ImageBitmapOptions& options) {
@@ -996,7 +996,7 @@
 
 ImageBitmap::~ImageBitmap() {}
 
-ImageBitmap* ImageBitmap::Create(ImageElementBase* image,
+ImageBitmap* ImageBitmap::Create(HTMLImageElement* image,
                                  Optional<IntRect> crop_rect,
                                  Document* document,
                                  const ImageBitmapOptions& options) {
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.h b/third_party/WebKit/Source/core/frame/ImageBitmap.h
index 3684c0c3..db57545 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.h
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.h
@@ -8,8 +8,8 @@
 #include <memory>
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/CoreExport.h"
+#include "core/html/HTMLImageElement.h"
 #include "core/html/canvas/CanvasImageSource.h"
-#include "core/html/canvas/ImageElementBase.h"
 #include "core/imagebitmap/ImageBitmapOptions.h"
 #include "core/imagebitmap/ImageBitmapSource.h"
 #include "platform/geometry/IntRect.h"
@@ -21,7 +21,6 @@
 #include "third_party/skia/include/core/SkRefCnt.h"
 
 namespace blink {
-class Document;
 class HTMLCanvasElement;
 class HTMLVideoElement;
 class ImageData;
@@ -49,7 +48,7 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  static ImageBitmap* Create(ImageElementBase*,
+  static ImageBitmap* Create(HTMLImageElement*,
                              Optional<IntRect>,
                              Document*,
                              const ImageBitmapOptions& = ImageBitmapOptions());
@@ -139,7 +138,7 @@
   DECLARE_VIRTUAL_TRACE();
 
  private:
-  ImageBitmap(ImageElementBase*,
+  ImageBitmap(HTMLImageElement*,
               Optional<IntRect>,
               Document*,
               const ImageBitmapOptions&);
diff --git a/third_party/WebKit/Source/core/html/BUILD.gn b/third_party/WebKit/Source/core/html/BUILD.gn
index 865c8db2..66703ff 100644
--- a/third_party/WebKit/Source/core/html/BUILD.gn
+++ b/third_party/WebKit/Source/core/html/BUILD.gn
@@ -263,12 +263,12 @@
     "canvas/CanvasDrawListener.h",
     "canvas/CanvasFontCache.cpp",
     "canvas/CanvasFontCache.h",
+    "canvas/CanvasImageElementSource.cpp",
+    "canvas/CanvasImageElementSource.h",
     "canvas/CanvasImageSource.h",
     "canvas/CanvasRenderingContext.cpp",
     "canvas/CanvasRenderingContext.h",
     "canvas/CanvasRenderingContextFactory.h",
-    "canvas/ImageElementBase.cpp",
-    "canvas/ImageElementBase.h",
     "forms/BaseButtonInputType.cpp",
     "forms/BaseButtonInputType.h",
     "forms/BaseCheckableInputType.cpp",
@@ -485,6 +485,10 @@
     "shadow/MediaControlElements.h",
     "shadow/MediaControlTimelineMetrics.cpp",
     "shadow/MediaControlTimelineMetrics.h",
+    "shadow/MediaRemotingElements.cpp",
+    "shadow/MediaRemotingElements.h",
+    "shadow/MediaRemotingInterstitial.cpp",
+    "shadow/MediaRemotingInterstitial.h",
     "shadow/ProgressShadowElement.cpp",
     "shadow/ProgressShadowElement.h",
     "shadow/ShadowElementNames.cpp",
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 105b9f0..c16060d 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -74,6 +74,7 @@
 #include "platform/graphics/StaticBitmapImage.h"
 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
 #include "platform/graphics/gpu/AcceleratedImageBufferSurface.h"
+#include "platform/graphics/gpu/SharedGpuContext.h"
 #include "platform/graphics/paint/PaintCanvas.h"
 #include "platform/image-encoders/ImageEncoderUtils.h"
 #include "platform/transforms/AffineTransform.h"
@@ -276,13 +277,12 @@
 
   probe::didCreateCanvasContext(&GetDocument());
 
-  if (context_->Is3d()) {
+  if (Is3d()) {
     UpdateExternallyAllocatedMemory();
   }
 
   LayoutObject* layout_object = this->GetLayoutObject();
-  if (layout_object && context_->Is2d() &&
-      !context_->CreationAttributes().alpha()) {
+  if (layout_object && Is2d() && !context_->CreationAttributes().alpha()) {
     // In the alpha false case, canvas is initially opaque even though there is
     // no ImageBuffer, so we need to trigger an invalidation.
     DidDraw();
@@ -315,15 +315,15 @@
   ClearCopiedImage();
   if (GetLayoutObject())
     GetLayoutObject()->SetMayNeedPaintInvalidation();
-  if (context_ && context_->Is2d() && context_->ShouldAntialias() &&
-      GetPage() && GetPage()->DeviceScaleFactorDeprecated() > 1.0f) {
+  if (Is2d() && context_->ShouldAntialias() && GetPage() &&
+      GetPage()->DeviceScaleFactorDeprecated() > 1.0f) {
     FloatRect inflated_rect = rect;
     inflated_rect.Inflate(1);
     dirty_rect_.Unite(inflated_rect);
   } else {
     dirty_rect_.Unite(rect);
   }
-  if (context_ && context_->Is2d() && HasImageBuffer())
+  if (Is2d() && HasImageBuffer())
     Buffer()->DidDraw(rect);
 }
 
@@ -362,7 +362,7 @@
 
 void HTMLCanvasElement::DoDeferredPaintInvalidation() {
   DCHECK(!dirty_rect_.IsEmpty());
-  if (context_->Is2d()) {
+  if (Is2d()) {
     FloatRect src_rect(0, 0, size().Width(), size().Height());
     dirty_rect_.Intersect(src_rect);
     LayoutBox* lb = GetLayoutBox();
@@ -428,7 +428,7 @@
   if (RuntimeEnabledFeatures::
           enableCanvas2dDynamicRenderingModeSwitchingEnabled() &&
       !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled()) {
-    if (context_->Is2d() && HasImageBuffer() && Buffer()->IsAccelerated() &&
+    if (Is2d() && HasImageBuffer() && Buffer()->IsAccelerated() &&
         num_frames_since_last_rendering_mode_switch_ >=
             ExpensiveCanvasHeuristicParameters::kMinFramesBeforeSwitch &&
         !pending_rendering_mode_switch_) {
@@ -475,7 +475,7 @@
   if (!ok || h < 0)
     h = kDefaultHeight;
 
-  if (context_ && context_->Is2d())
+  if (Is2d())
     context_->Reset();
 
   IntSize old_size = size();
@@ -483,8 +483,8 @@
 
   // If the size of an existing buffer matches, we can just clear it instead of
   // reallocating.  This optimization is only done for 2D canvases for now.
-  if (had_image_buffer && old_size == new_size && context_ &&
-      context_->Is2d() && !Buffer()->IsRecording()) {
+  if (had_image_buffer && old_size == new_size && Is2d() &&
+      !Buffer()->IsRecording()) {
     if (!image_buffer_is_clear_) {
       image_buffer_is_clear_ = true;
       context_->clearRect(0, 0, width(), height());
@@ -494,7 +494,7 @@
 
   SetSurfaceSize(new_size);
 
-  if (context_ && context_->Is3d() && old_size != size())
+  if (Is3d() && old_size != size())
     context_->Reshape(width(), height());
 
   if (LayoutObject* layout_object = this->GetLayoutObject()) {
@@ -566,7 +566,7 @@
           ? kNone_SkFilterQuality
           : kLow_SkFilterQuality;
 
-  if (Is3D()) {
+  if (Is3d()) {
     context_->SetFilterQuality(filter_quality);
   } else if (HasImageBuffer()) {
     image_buffer_->SetFilterQuality(filter_quality);
@@ -605,17 +605,20 @@
       context.FillRect(FloatRect(r), Color(0, 0, 0));
   }
 
-  if (Is3D() && PaintsIntoCanvasBuffer())
+  if (Is3d() && PaintsIntoCanvasBuffer())
     context_->MarkLayerComposited();
 }
 
-bool HTMLCanvasElement::Is3D() const {
+bool HTMLCanvasElement::Is3d() const {
   return context_ && context_->Is3d();
 }
 
-bool HTMLCanvasElement::IsAnimated2D() const {
-  return context_ && context_->Is2d() && HasImageBuffer() &&
-         image_buffer_->WasDrawnToAfterSnapshot();
+bool HTMLCanvasElement::Is2d() const {
+  return context_ && context_->Is2d();
+}
+
+bool HTMLCanvasElement::IsAnimated2d() const {
+  return Is2d() && HasImageBuffer() && image_buffer_->WasDrawnToAfterSnapshot();
 }
 
 void HTMLCanvasElement::SetSurfaceSize(const IntSize& size) {
@@ -623,7 +626,7 @@
   did_fail_to_create_image_buffer_ = false;
   DiscardImageBuffer();
   ClearCopiedImage();
-  if (context_ && context_->Is2d() && context_->isContextLost()) {
+  if (Is2d() && context_->isContextLost()) {
     context_->DidSetSurfaceSize();
   }
 }
@@ -634,8 +637,7 @@
 }
 
 void HTMLCanvasElement::PrepareSurfaceForPaintingIfNeeded() const {
-  DCHECK(context_ &&
-         context_->Is2d());  // This function is called by the 2d context
+  DCHECK(Is2d());  // This function is called by the 2d context
   if (Buffer())
     image_buffer_->PrepareSurfaceForPaintingIfNeeded();
 }
@@ -643,7 +645,7 @@
 ImageData* HTMLCanvasElement::ToImageData(SourceDrawingBuffer source_buffer,
                                           SnapshotReason reason) const {
   ImageData* image_data;
-  if (Is3D()) {
+  if (Is3d()) {
     // Get non-premultiplied data because of inaccurate premultiplied alpha
     // conversion of buffer()->toDataURL().
     image_data = context_->PaintRenderingResultsToImageData(source_buffer);
@@ -670,7 +672,7 @@
   if ((!context_ || !image_data) && !PlaceholderFrame())
     return image_data;
 
-  DCHECK((context_ && context_->Is2d()) || PlaceholderFrame());
+  DCHECK(Is2d() || PlaceholderFrame());
   sk_sp<SkImage> snapshot;
   if (HasImageBuffer()) {
     snapshot = Buffer()->NewSkImageSnapshot(kPreferNoAcceleration, reason);
@@ -820,7 +822,7 @@
 }
 
 bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
-  if (context_ && !context_->Is2d())
+  if (context_ && !Is2d())
     return false;
 
   if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled())
@@ -916,7 +918,7 @@
 
 std::unique_ptr<ImageBufferSurface>
 HTMLCanvasElement::CreateWebGLImageBufferSurface(OpacityMode opacity_mode) {
-  DCHECK(Is3D());
+  DCHECK(Is3d());
   // If 3d, but the use of the canvas will be for non-accelerated content
   // then make a non-accelerated ImageBuffer. This means copying the internal
   // Image will require a pixel readback, but that is unavoidable in this case.
@@ -998,7 +1000,7 @@
 
 void HTMLCanvasElement::CreateImageBuffer() {
   CreateImageBufferInternal(nullptr);
-  if (did_fail_to_create_image_buffer_ && context_->Is2d() && !size().IsEmpty())
+  if (did_fail_to_create_image_buffer_ && Is2d() && !size().IsEmpty())
     context_->LoseContext(CanvasRenderingContext::kSyntheticLostContext);
 }
 
@@ -1020,7 +1022,7 @@
   if (external_surface) {
     if (external_surface->IsValid())
       surface = std::move(external_surface);
-  } else if (Is3D()) {
+  } else if (Is3d()) {
     surface = CreateWebGLImageBufferSurface(opacity_mode);
   } else {
     if (ShouldAccelerate(kNormalAccelerationCriteria)) {
@@ -1042,7 +1044,7 @@
 
   UpdateExternallyAllocatedMemory();
 
-  if (Is3D()) {
+  if (Is3d()) {
     // Early out for WebGL canvases
     return;
   }
@@ -1060,7 +1062,7 @@
 }
 
 void HTMLCanvasElement::NotifySurfaceInvalid() {
-  if (context_ && context_->Is2d())
+  if (Is2d())
     context_->LoseContext(CanvasRenderingContext::kRealLostContext);
 }
 
@@ -1095,7 +1097,7 @@
   // Four bytes per pixel per buffer.
   CheckedNumeric<intptr_t> checked_externally_allocated_memory =
       4 * buffer_count;
-  if (Is3D()) {
+  if (Is3d()) {
     checked_externally_allocated_memory +=
         context_->ExternallyAllocatedBytesPerPixel();
   }
@@ -1215,7 +1217,7 @@
   context_->SetIsHidden(hidden);
   if (hidden) {
     ClearCopiedImage();
-    if (Is3D()) {
+    if (Is3d()) {
       DiscardImageBuffer();
     }
   }
@@ -1240,6 +1242,7 @@
 
 void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) {
   if (ExpensiveCanvasHeuristicParameters::kEnableAccelerationToAvoidReadbacks &&
+      SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() &&
       source->IsAccelerated() && !Buffer()->IsAccelerated() &&
       ShouldAccelerate(kIgnoreResourceLimitCriteria)) {
     OpacityMode opacity_mode =
@@ -1289,7 +1292,7 @@
   sk_sp<SkImage> sk_image;
   // TODO(ccameron): Canvas should produce sRGB images.
   // https://crbug.com/672299
-  if (context_->Is3d()) {
+  if (Is3d()) {
     // Because WebGL sources always require making a copy of the back buffer, we
     // use paintRenderingResultsToCanvas instead of getImage in order to keep a
     // cached copy of the backing in the canvas's ImageBuffer.
@@ -1451,7 +1454,7 @@
 
 HitTestCanvasResult* HTMLCanvasElement::GetControlAndIdIfHitRegionExists(
     const LayoutPoint& location) {
-  if (context_ && context_->Is2d())
+  if (Is2d())
     return context_->GetControlAndIdIfHitRegionExists(location);
   return HitTestCanvasResult::Create(String(), nullptr);
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
index 5ca64bd..0ca28af7 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -157,8 +157,9 @@
 
   AffineTransform BaseTransform() const;
 
-  bool Is3D() const;
-  bool IsAnimated2D() const;
+  bool Is3d() const;
+  bool Is2d() const;
+  bool IsAnimated2d() const;
 
   bool HasImageBuffer() const { return image_buffer_.get(); }
   void DiscardImageBuffer();
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index 9a72937..54cb6398 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -688,6 +688,28 @@
                                      referrer_policy_);
 }
 
+ScriptPromise HTMLImageElement::CreateImageBitmap(
+    ScriptState* script_state,
+    EventTarget& event_target,
+    Optional<IntRect> crop_rect,
+    const ImageBitmapOptions& options,
+    ExceptionState& exception_state) {
+  DCHECK(event_target.ToLocalDOMWindow());
+  if ((crop_rect &&
+       !ImageBitmap::IsSourceSizeValid(crop_rect->Width(), crop_rect->Height(),
+                                       exception_state)) ||
+      !ImageBitmap::IsSourceSizeValid(BitmapSourceSize().Width(),
+                                      BitmapSourceSize().Height(),
+                                      exception_state))
+    return ScriptPromise();
+  if (!ImageBitmap::IsResizeOptionValid(options, exception_state))
+    return ScriptPromise();
+  return ImageBitmapSource::FulfillImageBitmap(
+      script_state, ImageBitmap::Create(
+                        this, crop_rect,
+                        event_target.ToLocalDOMWindow()->document(), options));
+}
+
 void HTMLImageElement::SelectSourceURL(
     ImageLoader::UpdateFromElementBehavior behavior) {
   if (!GetDocument().IsActive())
@@ -811,6 +833,16 @@
   }
 }
 
+IntSize HTMLImageElement::BitmapSourceSize() const {
+  ImageResourceContent* image = CachedImage();
+  if (!image)
+    return IntSize();
+  LayoutSize l_size = image->ImageSize(
+      LayoutObject::ShouldRespectImageOrientation(GetLayoutObject()), 1.0f);
+  DCHECK(l_size.Fraction().IsZero());
+  return IntSize(l_size.Width().ToInt(), l_size.Height().ToInt());
+}
+
 void HTMLImageElement::AssociateWith(HTMLFormElement* form) {
   if (form && form->isConnected()) {
     form_ = form;
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.h b/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 195cee7f..a85704f6 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -29,7 +29,8 @@
 #include "core/html/FormAssociated.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLImageLoader.h"
-#include "core/html/canvas/ImageElementBase.h"
+#include "core/html/canvas/CanvasImageElementSource.h"
+#include "core/imagebitmap/ImageBitmapSource.h"
 #include "platform/graphics/GraphicsTypes.h"
 #include "platform/loader/fetch/FetchParameters.h"
 #include "platform/loader/fetch/ResourceResponse.h"
@@ -39,10 +40,12 @@
 class HTMLFormElement;
 class ImageCandidate;
 class ShadowRoot;
+class ImageBitmapOptions;
 
 class CORE_EXPORT HTMLImageElement final
     : public HTMLElement,
-      public ImageElementBase,
+      public CanvasImageElementSource,
+      public ImageBitmapSource,
       public ActiveScriptWrappable<HTMLImageElement>,
       public FormAssociated {
   DEFINE_WRAPPERTYPEINFO();
@@ -130,6 +133,14 @@
 
   void ForceReload() const;
 
+  // ImageBitmapSource implementation
+  IntSize BitmapSourceSize() const override;
+  ScriptPromise CreateImageBitmap(ScriptState*,
+                                  EventTarget&,
+                                  Optional<IntRect> crop_rect,
+                                  const ImageBitmapOptions&,
+                                  ExceptionState&) override;
+
   FormAssociated* ToFormAssociatedOrNull() override { return this; };
   void AssociateWith(HTMLFormElement*) override;
 
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index d707de7..d3e0fc4 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -3637,20 +3637,32 @@
   return text_tracks_visible_;
 }
 
-static void AssertShadowRootChildren(ShadowRoot& shadow_root) {
+// static
+void HTMLMediaElement::AssertShadowRootChildren(ShadowRoot& shadow_root) {
 #if DCHECK_IS_ON()
-  // There can be up to two children, either or both of the text
-  // track container and media controls. If both are present, the
-  // text track container must be the first child.
+  // There can be up to three children: media remoting interstitial, text track
+  // container, and media controls. The media controls has to be the last child
+  // if presend, and has to be the next sibling of the text track container if
+  // both present. When present, media remoting interstitial has to be the first
+  // child.
   unsigned number_of_children = shadow_root.CountChildren();
-  DCHECK_LE(number_of_children, 2u);
+  DCHECK_LE(number_of_children, 3u);
   Node* first_child = shadow_root.FirstChild();
   Node* last_child = shadow_root.LastChild();
   if (number_of_children == 1) {
     DCHECK(first_child->IsTextTrackContainer() ||
-           first_child->IsMediaControls());
+           first_child->IsMediaControls() ||
+           first_child->IsMediaRemotingInterstitial());
   } else if (number_of_children == 2) {
-    DCHECK(first_child->IsTextTrackContainer());
+    DCHECK(first_child->IsTextTrackContainer() ||
+           first_child->IsMediaRemotingInterstitial());
+    DCHECK(last_child->IsTextTrackContainer() || last_child->IsMediaControls());
+    if (first_child->IsTextTrackContainer())
+      DCHECK(last_child->IsMediaControls());
+  } else if (number_of_children == 3) {
+    Node* second_child = first_child->nextSibling();
+    DCHECK(first_child->IsMediaRemotingInterstitial());
+    DCHECK(second_child->IsTextTrackContainer());
     DCHECK(last_child->IsMediaControls());
   }
 #endif
@@ -3663,12 +3675,20 @@
   Node* first_child = shadow_root.FirstChild();
   if (first_child && first_child->IsTextTrackContainer())
     return ToTextTrackContainer(*first_child);
+  Node* to_be_inserted = first_child;
+
+  if (first_child && first_child->IsMediaRemotingInterstitial()) {
+    Node* second_child = first_child->nextSibling();
+    if (second_child && second_child->IsTextTrackContainer())
+      return ToTextTrackContainer(*second_child);
+    to_be_inserted = second_child;
+  }
 
   TextTrackContainer* text_track_container = TextTrackContainer::Create(*this);
 
   // The text track container should be inserted before the media controls,
   // so that they are rendered behind them.
-  shadow_root.InsertBefore(text_track_container, first_child);
+  shadow_root.InsertBefore(text_track_container, to_be_inserted);
 
   AssertShadowRootChildren(shadow_root);
 
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index 85a51d2..c61d5df 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -350,6 +350,9 @@
   DisplayMode GetDisplayMode() const { return display_mode_; }
   virtual void SetDisplayMode(DisplayMode mode) { display_mode_ = mode; }
 
+  // Assert the correct order of the children in shadow dom when DCHECK is on.
+  static void AssertShadowRootChildren(ShadowRoot&);
+
  private:
   // Friend class for testing.
   friend class MediaElementFillingViewportTest;
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
index 2e741f235..c8fa9d8 100644
--- a/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
@@ -39,6 +39,7 @@
 #include "core/frame/Settings.h"
 #include "core/html/media/MediaCustomControlsFullscreenDetector.h"
 #include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/shadow/MediaRemotingInterstitial.h"
 #include "core/imagebitmap/ImageBitmapOptions.h"
 #include "core/layout/LayoutImage.h"
 #include "core/layout/LayoutVideo.h"
@@ -66,7 +67,9 @@
 }  // anonymous namespace
 
 inline HTMLVideoElement::HTMLVideoElement(Document& document)
-    : HTMLMediaElement(videoTag, document) {
+    : HTMLMediaElement(videoTag, document),
+      media_remoting_status_(MediaRemotingStatus::kNotStarted),
+      remoting_interstitial_(nullptr) {
   if (document.GetSettings()) {
     default_poster_url_ =
         AtomicString(document.GetSettings()->GetDefaultVideoPosterURL());
@@ -88,6 +91,7 @@
 DEFINE_TRACE(HTMLVideoElement) {
   visitor->Trace(image_loader_);
   visitor->Trace(custom_controls_fullscreen_detector_);
+  visitor->Trace(remoting_interstitial_);
   HTMLMediaElement::Trace(visitor);
 }
 
@@ -179,6 +183,10 @@
     // Notify the player when the poster image URL changes.
     if (GetWebMediaPlayer())
       GetWebMediaPlayer()->SetPoster(PosterImageURL());
+    // Media remoting doesn't show the original poster image, instead, it shows
+    // a grayscaled and blurred copy.
+    if (remoting_interstitial_)
+      remoting_interstitial_->OnPosterImageChanged();
   } else {
     HTMLMediaElement::ParseAttribute(params);
   }
@@ -483,4 +491,30 @@
                         event_target.ToLocalDOMWindow()->document(), options));
 }
 
+void HTMLVideoElement::MediaRemotingStarted() {
+  DCHECK_EQ(media_remoting_status_, MediaRemotingStatus::kNotStarted);
+  media_remoting_status_ = MediaRemotingStatus::kStarted;
+  if (!remoting_interstitial_) {
+    remoting_interstitial_ = new MediaRemotingInterstitial(*this);
+    ShadowRoot& shadow_root = EnsureUserAgentShadowRoot();
+    shadow_root.InsertBefore(remoting_interstitial_, shadow_root.FirstChild());
+    HTMLMediaElement::AssertShadowRootChildren(shadow_root);
+  }
+  remoting_interstitial_->Show();
+}
+
+void HTMLVideoElement::MediaRemotingStopped() {
+  if (media_remoting_status_ != MediaRemotingStatus::kDisabled)
+    media_remoting_status_ = MediaRemotingStatus::kNotStarted;
+  DCHECK(remoting_interstitial_);
+  remoting_interstitial_->Hide();
+}
+
+void HTMLVideoElement::DisableMediaRemoting() {
+  if (GetWebMediaPlayer())
+    GetWebMediaPlayer()->RequestRemotePlaybackDisabled(true);
+  media_remoting_status_ = MediaRemotingStatus::kDisabled;
+  MediaRemotingStopped();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLVideoElement.h b/third_party/WebKit/Source/core/html/HTMLVideoElement.h
index 6f14c678..cef9ba0 100644
--- a/third_party/WebKit/Source/core/html/HTMLVideoElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLVideoElement.h
@@ -43,6 +43,7 @@
 class ExceptionState;
 class ImageBitmapOptions;
 class MediaCustomControlsFullscreenDetector;
+class MediaRemotingInterstitial;
 
 class CORE_EXPORT HTMLVideoElement final : public HTMLMediaElement,
                                            public CanvasImageSource,
@@ -53,6 +54,8 @@
   static HTMLVideoElement* Create(Document&);
   DECLARE_VIRTUAL_TRACE();
 
+  enum class MediaRemotingStatus { kNotStarted, kStarted, kDisabled };
+
   // Node override.
   Node::InsertionNotificationRequest InsertedInto(ContainerNode*) override;
   void RemovedFrom(ContainerNode*) override;
@@ -132,6 +135,11 @@
 
   bool IsPersistent() const;
 
+  MediaRemotingStatus GetMediaRemotingStatus() const {
+    return media_remoting_status_;
+  }
+  void DisableMediaRemoting();
+
  private:
   friend class MediaCustomControlsFullscreenDetectorTest;
   friend class HTMLMediaElementEventListenersTest;
@@ -156,11 +164,17 @@
   void UpdateDisplayState() override;
   void DidMoveToNewDocument(Document& old_document) override;
   void SetDisplayMode(DisplayMode) override;
+  void MediaRemotingStarted() final;
+  void MediaRemotingStopped() final;
 
   Member<HTMLImageLoader> image_loader_;
   Member<MediaCustomControlsFullscreenDetector>
       custom_controls_fullscreen_detector_;
 
+  MediaRemotingStatus media_remoting_status_;
+
+  Member<MediaRemotingInterstitial> remoting_interstitial_;
+
   AtomicString default_poster_url_;
 
   bool is_persistent_ = false;
diff --git a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasImageElementSource.cpp
similarity index 62%
rename from third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp
rename to third_party/WebKit/Source/core/html/canvas/CanvasImageElementSource.cpp
index e41aa983..64277260 100644
--- a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasImageElementSource.cpp
@@ -2,29 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/html/canvas/ImageElementBase.h"
+#include "core/html/canvas/CanvasImageElementSource.h"
 
-#include "core/frame/ImageBitmap.h"
-#include "core/frame/LocalDOMWindow.h"
 #include "core/layout/LayoutObject.h"
 #include "core/loader/ImageLoader.h"
 #include "core/svg/graphics/SVGImageForContainer.h"
 
 namespace blink {
 
-ImageResourceContent* ImageElementBase::CachedImage() const {
+ImageResourceContent* CanvasImageElementSource::CachedImage() const {
   return GetImageLoader().GetImage();
 }
 
-const Element& ImageElementBase::GetElement() const {
+const Element& CanvasImageElementSource::GetElement() const {
   return *GetImageLoader().GetElement();
 }
 
-bool ImageElementBase::IsSVGSource() const {
+bool CanvasImageElementSource::IsSVGSource() const {
   return CachedImage() && CachedImage()->GetImage()->IsSVGImage();
 }
 
-PassRefPtr<Image> ImageElementBase::GetSourceImageForCanvas(
+PassRefPtr<Image> CanvasImageElementSource::GetSourceImageForCanvas(
     SourceImageStatus* status,
     AccelerationHint,
     SnapshotReason,
@@ -56,13 +54,13 @@
   return source_image->ImageForDefaultFrame();
 }
 
-bool ImageElementBase::WouldTaintOrigin(
+bool CanvasImageElementSource::WouldTaintOrigin(
     SecurityOrigin* destination_security_origin) const {
   return CachedImage() &&
          !CachedImage()->IsAccessAllowed(destination_security_origin);
 }
 
-FloatSize ImageElementBase::ElementSize(
+FloatSize CanvasImageElementSource::ElementSize(
     const FloatSize& default_object_size) const {
   ImageResourceContent* image = CachedImage();
   if (!image)
@@ -78,7 +76,7 @@
                                     1.0f));
 }
 
-FloatSize ImageElementBase::DefaultDestinationSize(
+FloatSize CanvasImageElementSource::DefaultDestinationSize(
     const FloatSize& default_object_size) const {
   ImageResourceContent* image = CachedImage();
   if (!image)
@@ -96,15 +94,15 @@
   return FloatSize(size);
 }
 
-bool ImageElementBase::IsAccelerated() const {
+bool CanvasImageElementSource::IsAccelerated() const {
   return false;
 }
 
-const KURL& ImageElementBase::SourceURL() const {
+const KURL& CanvasImageElementSource::SourceURL() const {
   return CachedImage()->GetResponse().Url();
 }
 
-int ImageElementBase::SourceWidth() {
+int CanvasImageElementSource::SourceWidth() {
   SourceImageStatus status;
   RefPtr<Image> image = GetSourceImageForCanvas(&status, kPreferNoAcceleration,
                                                 kSnapshotReasonUnknown,
@@ -112,7 +110,7 @@
   return image->width();
 }
 
-int ImageElementBase::SourceHeight() {
+int CanvasImageElementSource::SourceHeight() {
   SourceImageStatus status;
   RefPtr<Image> image = GetSourceImageForCanvas(&status, kPreferNoAcceleration,
                                                 kSnapshotReasonUnknown,
@@ -120,43 +118,9 @@
   return image->height();
 }
 
-bool ImageElementBase::IsOpaque() const {
+bool CanvasImageElementSource::IsOpaque() const {
   Image* image = const_cast<Element&>(GetElement()).ImageContents();
   return image && image->CurrentFrameKnownToBeOpaque();
 }
 
-IntSize ImageElementBase::BitmapSourceSize() const {
-  ImageResourceContent* image = CachedImage();
-  if (!image)
-    return IntSize();
-  LayoutSize lSize =
-      image->ImageSize(LayoutObject::ShouldRespectImageOrientation(
-                           GetElement().GetLayoutObject()),
-                       1.0f);
-  DCHECK(lSize.Fraction().IsZero());
-  return IntSize(lSize.Width().ToInt(), lSize.Height().ToInt());
-}
-
-ScriptPromise ImageElementBase::CreateImageBitmap(
-    ScriptState* script_state,
-    EventTarget& event_target,
-    Optional<IntRect> crop_rect,
-    const ImageBitmapOptions& options,
-    ExceptionState& exception_state) {
-  DCHECK(event_target.ToLocalDOMWindow());
-  if ((crop_rect &&
-       !ImageBitmap::IsSourceSizeValid(crop_rect->Width(), crop_rect->Height(),
-                                       exception_state)) ||
-      !ImageBitmap::IsSourceSizeValid(BitmapSourceSize().Width(),
-                                      BitmapSourceSize().Height(),
-                                      exception_state))
-    return ScriptPromise();
-  if (!ImageBitmap::IsResizeOptionValid(options, exception_state))
-    return ScriptPromise();
-  return ImageBitmapSource::FulfillImageBitmap(
-      script_state, ImageBitmap::Create(
-                        this, crop_rect,
-                        event_target.ToLocalDOMWindow()->document(), options));
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.h b/third_party/WebKit/Source/core/html/canvas/CanvasImageElementSource.h
similarity index 69%
rename from third_party/WebKit/Source/core/html/canvas/ImageElementBase.h
rename to third_party/WebKit/Source/core/html/canvas/CanvasImageElementSource.h
index d8060f49..4497a79 100644
--- a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasImageElementSource.h
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ImageElementBase_h
-#define ImageElementBase_h
+#ifndef CanvasImageElementSource_h
+#define CanvasImageElementSource_h
 
 #include "core/CoreExport.h"
 #include "core/html/canvas/CanvasImageSource.h"
-#include "core/imagebitmap/ImageBitmapSource.h"
 
 namespace blink {
 
@@ -15,19 +14,11 @@
 class ImageLoader;
 class ImageResourceContent;
 
-class CORE_EXPORT ImageElementBase : public CanvasImageSource,
-                                     public ImageBitmapSource {
+class CORE_EXPORT CanvasImageElementSource : public CanvasImageSource {
  public:
   virtual ImageLoader& GetImageLoader() const = 0;
   virtual FloatSize SourceDefaultObjectSize() = 0;
 
-  IntSize BitmapSourceSize() const override;
-  ScriptPromise CreateImageBitmap(ScriptState*,
-                                  EventTarget&,
-                                  Optional<IntRect>,
-                                  const ImageBitmapOptions&,
-                                  ExceptionState&) override;
-
   PassRefPtr<Image> GetSourceImageForCanvas(SourceImageStatus*,
                                             AccelerationHint,
                                             SnapshotReason,
@@ -51,12 +42,11 @@
 
   const KURL& SourceURL() const override;
 
-  ImageResourceContent* CachedImage() const;
-
  private:
+  ImageResourceContent* CachedImage() const;
   const Element& GetElement() const;
 };
 
 }  // namespace blink
 
-#endif  // ImageElementBase_h
+#endif  // CanvasImageElementSource_h
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
index 1b94d33a..5884247d 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp
@@ -339,8 +339,8 @@
   CHECK_EQ(pending_script->GetScriptType(), ScriptType::kClassic);
 
   if (!pending_script->ErrorOccurred()) {
-    EmitWarningForDocWriteScripts(pending_script->Url().GetString(),
-                                  *document_);
+    EmitWarningForDocWriteScripts(
+        pending_script->UrlForClassicScript().GetString(), *document_);
     return;
   }
 
@@ -348,7 +348,8 @@
   // ERR_CACHE_MISS but other errors are rare with
   // WebCachePolicy::ReturnCacheDataDontLoad.
 
-  EmitErrorForDocWriteScripts(pending_script->Url().GetString(), *document_);
+  EmitErrorForDocWriteScripts(pending_script->UrlForClassicScript().GetString(),
+                              *document_);
   TextPosition starting_position = ParserBlockingScript()->StartingPosition();
   bool is_parser_inserted = script_loader->IsParserInserted();
   // Remove this resource entry from memory cache as the new request
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaRemotingElements.cpp b/third_party/WebKit/Source/core/html/shadow/MediaRemotingElements.cpp
new file mode 100644
index 0000000..c53bc9d8
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/shadow/MediaRemotingElements.cpp
@@ -0,0 +1,103 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/html/shadow/MediaRemotingElements.h"
+
+#include "core/dom/ClientRect.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/MouseEvent.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/input/EventHandler.h"
+#include "platform/text/PlatformLocale.h"
+#include "public/platform/WebLocalizedString.h"
+
+namespace blink {
+
+using namespace HTMLNames;
+
+// ----------------------------
+
+class MediaRemotingExitButtonElement::MouseEventsListener final
+    : public EventListener {
+ public:
+  explicit MouseEventsListener(MediaRemotingExitButtonElement& element)
+      : EventListener(kCPPEventListenerType), element_(element) {}
+
+  bool operator==(const EventListener& other) const override {
+    return this == &other;
+  }
+
+  void Trace(blink::Visitor* visitor) {
+    visitor->Trace(element_);
+    EventListener::Trace(visitor);
+  }
+
+ private:
+  void handleEvent(ExecutionContext* context, Event* event) override {
+    DCHECK_EQ(event->type(), EventTypeNames::click);
+
+    MouseEvent* mouse_event = ToMouseEvent(event);
+    ClientRect* client_rect = element_->getBoundingClientRect();
+    const double x = mouse_event->x();
+    const double y = mouse_event->y();
+    if (x < client_rect->left() || x > client_rect->right() ||
+        y < client_rect->top() || y > client_rect->bottom())
+      return;
+
+    element_->GetVideoElement().DisableMediaRemoting();
+    event->SetDefaultHandled();
+    event->stopPropagation();
+  }
+
+  Member<MediaRemotingExitButtonElement> element_;
+};
+
+MediaRemotingExitButtonElement::MediaRemotingExitButtonElement(
+    MediaRemotingInterstitial& interstitial)
+    : HTMLDivElement(interstitial.GetDocument()), interstitial_(interstitial) {
+  listener_ = new MouseEventsListener(*this);
+  SetShadowPseudoId(AtomicString("-internal-media-remoting-disable-button"));
+  setInnerText(interstitial.GetVideoElement().GetLocale().QueryString(
+                   WebLocalizedString::kMediaRemotingDisableText),
+               ASSERT_NO_EXCEPTION);
+}
+
+void MediaRemotingExitButtonElement::OnShown() {
+  GetDocument().addEventListener(EventTypeNames::click, listener_, true);
+}
+
+void MediaRemotingExitButtonElement::OnHidden() {
+  GetDocument().removeEventListener(EventTypeNames::click, listener_, true);
+}
+
+HTMLVideoElement& MediaRemotingExitButtonElement::GetVideoElement() const {
+  return interstitial_->GetVideoElement();
+}
+
+DEFINE_TRACE(MediaRemotingExitButtonElement) {
+  visitor->Trace(interstitial_);
+  visitor->Trace(listener_);
+  HTMLDivElement::Trace(visitor);
+}
+
+// ----------------------------
+
+MediaRemotingCastMessageElement::MediaRemotingCastMessageElement(
+    MediaRemotingInterstitial& interstitial)
+    : HTMLDivElement(interstitial.GetDocument()) {
+  SetShadowPseudoId(AtomicString("-internal-media-remoting-cast-text-message"));
+  setInnerText(interstitial.GetVideoElement().GetLocale().QueryString(
+                   WebLocalizedString::kMediaRemotingCastText),
+               ASSERT_NO_EXCEPTION);
+}
+
+// ----------------------------
+
+MediaRemotingCastIconElement::MediaRemotingCastIconElement(
+    MediaRemotingInterstitial& interstitial)
+    : HTMLDivElement(interstitial.GetDocument()) {
+  SetShadowPseudoId(AtomicString("-internal-media-remoting-cast-icon"));
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaRemotingElements.h b/third_party/WebKit/Source/core/html/shadow/MediaRemotingElements.h
new file mode 100644
index 0000000..605678e
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/shadow/MediaRemotingElements.h
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaRemotingElements_h
+#define MediaRemotingElements_h
+
+#include "core/html/shadow/MediaRemotingInterstitial.h"
+
+namespace blink {
+
+// A button shown when media remoting starts. It allows user to click to exit
+// media remoting and back to traditional tab mirroring.
+class MediaRemotingExitButtonElement final : public HTMLDivElement {
+ public:
+  explicit MediaRemotingExitButtonElement(MediaRemotingInterstitial&);
+
+  void OnShown();
+  void OnHidden();
+  HTMLVideoElement& GetVideoElement() const;
+
+  DECLARE_VIRTUAL_TRACE();
+
+ private:
+  class MouseEventsListener;
+
+  Member<MediaRemotingInterstitial> interstitial_;
+  // A document event listener to listen to the mouse clicking events while
+  // media remoting is ongoing. This listener is used instead of the
+  // DefaultEventHandler() to avoid other web sites stopping propagating the
+  // events. It will be removed once media remoting stops.
+  Member<MouseEventsListener> listener_;
+};
+
+// A text message shown to indicate media remoting is ongoing.
+class MediaRemotingCastMessageElement final : public HTMLDivElement {
+ public:
+  explicit MediaRemotingCastMessageElement(MediaRemotingInterstitial&);
+};
+
+// An icon shown to indicate media remoting is ongoing.
+class MediaRemotingCastIconElement final : public HTMLDivElement {
+ public:
+  explicit MediaRemotingCastIconElement(MediaRemotingInterstitial&);
+};
+
+}  // namespace blink
+
+#endif  // MediaRemotingElements_h
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaRemotingInterstitial.cpp b/third_party/WebKit/Source/core/html/shadow/MediaRemotingInterstitial.cpp
new file mode 100644
index 0000000..e183d8e5
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/shadow/MediaRemotingInterstitial.cpp
@@ -0,0 +1,58 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/html/shadow/MediaRemotingInterstitial.h"
+
+#include "core/html/HTMLImageElement.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/html/shadow/MediaRemotingElements.h"
+
+namespace blink {
+
+MediaRemotingInterstitial::MediaRemotingInterstitial(
+    HTMLVideoElement& videoElement)
+    : HTMLDivElement(videoElement.GetDocument()),
+      video_element_(&videoElement) {
+  SetShadowPseudoId(AtomicString("-internal-media-remoting-interstitial"));
+  background_image_ = HTMLImageElement::Create(videoElement.GetDocument());
+  background_image_->SetShadowPseudoId(
+      AtomicString("-internal-media-remoting-background-image"));
+  background_image_->SetSrc(videoElement.getAttribute(HTMLNames::posterAttr));
+  AppendChild(background_image_);
+
+  cast_icon_ = new MediaRemotingCastIconElement(*this);
+  AppendChild(cast_icon_);
+
+  cast_text_message_ = new MediaRemotingCastMessageElement(*this);
+  AppendChild(cast_text_message_);
+
+  exit_button_ = new MediaRemotingExitButtonElement(*this);
+  AppendChild(exit_button_);
+}
+
+void MediaRemotingInterstitial::Show() {
+  RemoveInlineStyleProperty(CSSPropertyDisplay);
+  exit_button_->OnShown();
+}
+
+void MediaRemotingInterstitial::Hide() {
+  SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+  exit_button_->OnHidden();
+}
+
+void MediaRemotingInterstitial::OnPosterImageChanged() {
+  background_image_->SetSrc(
+      GetVideoElement().getAttribute(HTMLNames::posterAttr));
+}
+
+DEFINE_TRACE(MediaRemotingInterstitial) {
+  visitor->Trace(video_element_);
+  visitor->Trace(background_image_);
+  visitor->Trace(exit_button_);
+  visitor->Trace(cast_icon_);
+  visitor->Trace(cast_text_message_);
+  HTMLDivElement::Trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaRemotingInterstitial.h b/third_party/WebKit/Source/core/html/shadow/MediaRemotingInterstitial.h
new file mode 100644
index 0000000..0baaa2b
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/shadow/MediaRemotingInterstitial.h
@@ -0,0 +1,56 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaRemotingInterstitial_h
+#define MediaRemotingInterstitial_h
+
+#include "core/html/HTMLDivElement.h"
+
+namespace blink {
+
+class HTMLImageElement;
+class HTMLVideoElement;
+class MediaRemotingExitButtonElement;
+class MediaRemotingCastMessageElement;
+class MediaRemotingCastIconElement;
+
+// Media Remoting UI. DOM structure looks like:
+//
+// MediaRemotingInterstitial
+//     (-internal-media-remoting-interstitial)
+// +-HTMLImageElement
+// |    (-internal-media-remoting-background-image)
+// \-MediaRemotingCastIconElement
+// |    (-internal-media-remoting-cast-icon)
+// \-MediaRemotingCastMessageElement
+// |    (-internal-media-remoting-cast-text-message)
+// \-MediaRemotingExitButtonElement
+//      (-internal-media-remoting-disable-button)
+class MediaRemotingInterstitial final : public HTMLDivElement {
+ public:
+  explicit MediaRemotingInterstitial(HTMLVideoElement&);
+
+  // Show/Hide Media Remoting interstitial.
+  void Show();
+  void Hide();
+  void OnPosterImageChanged();
+
+  HTMLVideoElement& GetVideoElement() const { return *video_element_; }
+
+  DECLARE_VIRTUAL_TRACE();
+
+ private:
+  // Node override.
+  bool IsMediaRemotingInterstitial() const override { return true; }
+
+  Member<HTMLVideoElement> video_element_;
+  Member<HTMLImageElement> background_image_;
+  Member<MediaRemotingExitButtonElement> exit_button_;
+  Member<MediaRemotingCastIconElement> cast_icon_;
+  Member<MediaRemotingCastMessageElement> cast_text_message_;
+};
+
+}  // namespace
+
+#endif  // MediaRemotingInterstitial_h
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
index a3c4e95..f273bc8 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
@@ -45,7 +45,6 @@
 #include "core/html/ImageData.h"
 #include "core/imagebitmap/ImageBitmapOptions.h"
 #include "core/offscreencanvas/OffscreenCanvas.h"
-#include "core/svg/SVGImageElement.h"
 #include "core/svg/graphics/SVGImage.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "platform/CrossThreadFunctional.h"
@@ -64,16 +63,9 @@
     ExceptionState& exception_state,
     const ImageBitmapOptions& options,
     bool has_crop_rect) {
-  ImageElementBase* image_element = nullptr;
   if (value.isHTMLImageElement()) {
-    if (!(image_element = value.getAsHTMLImageElement()))
-      return nullptr;
-  } else if (value.isSVGImageElement()) {
-    if (!(image_element = value.getAsSVGImageElement()))
-      return nullptr;
-  }
-  if (image_element) {
-    if (!image_element->CachedImage()) {
+    HTMLImageElement* image_element = value.getAsHTMLImageElement();
+    if (!image_element || !image_element->CachedImage()) {
       exception_state.ThrowDOMException(
           kInvalidStateError,
           "No image can be retrieved from the provided element.");
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
index 009bcb1..71124ca 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
@@ -31,8 +31,7 @@
 #ifndef ImageBitmapFactories_h
 #define ImageBitmapFactories_h
 
-#include <memory>
-#include "bindings/core/v8/HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.h"
+#include "bindings/core/v8/HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas.h"
 #include "bindings/core/v8/ScriptPromise.h"
 #include "bindings/core/v8/ScriptPromiseResolver.h"
 #include "bindings/core/v8/ScriptState.h"
@@ -44,6 +43,7 @@
 #include "platform/Supplementable.h"
 #include "platform/geometry/IntRect.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
+#include <memory>
 
 class SkImage;
 
@@ -57,7 +57,7 @@
 class ImageBitmapOptions;
 class WebTaskRunner;
 
-typedef HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas
+typedef HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas
     ImageBitmapSourceUnion;
 
 class ImageBitmapFactories final
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl
index 8d64642..13ace66 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.idl
@@ -31,7 +31,6 @@
 // https://html.spec.whatwg.org/#imagebitmapfactories
 
 typedef (HTMLImageElement or
-         SVGImageElement or
          HTMLVideoElement or
          HTMLCanvasElement or
          Blob or
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 384b01b..9b41ff4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -1207,14 +1207,14 @@
     transform.Multiply(Layer()->CurrentTransform());
 
   // 2. Container offset.
-  transform.TranslateRight(container_offset.X().ToFloat(),
-                           container_offset.Y().ToFloat());
+  transform.PostTranslate(container_offset.X().ToFloat(),
+                          container_offset.Y().ToFloat());
 
   // 3. Container scroll offset.
   if (container_object->IsBox() && container_object != ancestor &&
       container_object->HasOverflowClip()) {
     IntSize offset = -ToLayoutBox(container_object)->ScrolledContentOffset();
-    transform.TranslateRight(offset.Width(), offset.Height());
+    transform.PostTranslate(offset.Width(), offset.Height());
   }
 
   // 4. Perspective applied by container.
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index 30426d7..562f5bb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -1383,8 +1383,8 @@
   if (ShouldUseTransformFromContainer(container)) {
     TransformationMatrix t;
     GetTransformFromContainer(container, container_offset, t);
-    t.TranslateRight(adjustment_for_skipped_ancestor.Width().ToFloat(),
-                     adjustment_for_skipped_ancestor.Height().ToFloat());
+    t.PostTranslate(adjustment_for_skipped_ancestor.Width().ToFloat(),
+                    adjustment_for_skipped_ancestor.Height().ToFloat());
     geometry_map.Push(this, t, flags, LayoutSize());
   } else {
     container_offset += adjustment_for_skipped_ancestor;
diff --git a/third_party/WebKit/Source/core/layout/LayoutMedia.cpp b/third_party/WebKit/Source/core/layout/LayoutMedia.cpp
index 50fd030e..e0dcf82 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMedia.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMedia.cpp
@@ -59,16 +59,22 @@
 // overlap checking, see LayoutVTTCue.
 #if DCHECK_IS_ON()
   bool seen_text_track_container = false;
+  bool seen_media_remoting_interstitial = false;
 #endif
   for (LayoutObject* child = children_.LastChild(); child;
        child = child->PreviousSibling()) {
 #if DCHECK_IS_ON()
-    if (child->GetNode()->IsMediaControls())
+    if (child->GetNode()->IsMediaControls()) {
       DCHECK(!seen_text_track_container);
-    else if (child->GetNode()->IsTextTrackContainer())
+      DCHECK(!seen_media_remoting_interstitial);
+    } else if (child->GetNode()->IsTextTrackContainer()) {
       seen_text_track_container = true;
-    else
+      DCHECK(!seen_media_remoting_interstitial);
+    } else if (child->GetNode()->IsMediaRemotingInterstitial()) {
+      seen_media_remoting_interstitial = true;
+    } else {
       NOTREACHED();
+    }
 #endif
 
     // TODO(mlamouri): we miss some layouts because needsLayout returns false in
@@ -115,7 +121,8 @@
   if (child->GetNode()->IsMediaControls())
     return child->IsFlexibleBox();
 
-  if (child->GetNode()->IsTextTrackContainer())
+  if (child->GetNode()->IsTextTrackContainer() ||
+      child->GetNode()->IsMediaRemotingInterstitial())
     return true;
 
   return false;
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index a40effc..d71a514 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -2306,8 +2306,8 @@
   if (layer && layer->Transform())
     transform.Multiply(layer->CurrentTransform());
 
-  transform.TranslateRight(offset_in_container.Width().ToFloat(),
-                           offset_in_container.Height().ToFloat());
+  transform.PostTranslate(offset_in_container.Width().ToFloat(),
+                          offset_in_container.Height().ToFloat());
 
   if (container_object && container_object->HasLayer() &&
       container_object->Style()->HasPerspective()) {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
index 119147a..4976df78 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc
@@ -131,7 +131,7 @@
 
   LayoutText* layout_text =
       ToLayoutText(GetLayoutObjectByElementId("text")->SlowFirstChild());
-  ASSERT(layout_text->HasTextBoxes());
+  DCHECK(layout_text->HasTextBoxes());
 
   ASSERT_EQ(4UL, text_fragments.size());
 
@@ -181,7 +181,7 @@
   )HTML");
   LayoutText* layout_text =
       ToLayoutText(GetLayoutObjectByElementId("text")->SlowFirstChild());
-  ASSERT(layout_text->HasTextBoxes());
+  DCHECK(layout_text->HasTextBoxes());
 
   InlineTextBox* inline_text_box1 = layout_text->FirstTextBox();
   // 30 == narrow-float's width.
@@ -219,7 +219,7 @@
   )HTML");
   LayoutText* layout_text =
       ToLayoutText(GetLayoutObjectByElementId("text")->SlowFirstChild());
-  ASSERT(layout_text->HasTextBoxes());
+  DCHECK(layout_text->HasTextBoxes());
 
   InlineTextBox* inline_text_box1 = layout_text->FirstTextBox();
   EXPECT_EQ(LayoutUnit(), inline_text_box1->X());
@@ -292,7 +292,7 @@
   )HTML");
   LayoutText* layout_text =
       ToLayoutText(GetLayoutObjectByElementId("text")->SlowFirstChild());
-  ASSERT(layout_text->HasTextBoxes());
+  DCHECK(layout_text->HasTextBoxes());
 
   InlineTextBox* inline_text_box1 = layout_text->FirstTextBox();
   // 45 = sum of left's inline margins: 40 + left's width: 5
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc
index 29142258..dbf73c81 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_space_utils.cc
@@ -88,7 +88,7 @@
     case EClear::kBoth:
       return OptionalMax<LayoutUnit>(left_offset, right_offset);
     default:
-      ASSERT_NOT_REACHED();
+      NOTREACHED();
   }
   return WTF::kNullopt;
 }
diff --git a/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp b/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp
index 48ec709..6504977 100644
--- a/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/MediaControlsPainter.cpp
@@ -217,6 +217,18 @@
                           slider_background_color);
 }
 
+bool MediaControlsPainter::PaintMediaRemotingCastIcon(
+    const LayoutObject& object,
+    const PaintInfo& paintInfo,
+    const IntRect& rect) {
+  const HTMLMediaElement* media_element = ToParentMediaElement(object);
+  if (!media_element)
+    return false;
+  static Image* cast_icon = PlatformResource("mediaRemotingCastIcon");
+
+  return PaintMediaButton(paintInfo.context, rect, cast_icon);
+}
+
 static void PaintSliderRangeHighlight(const IntRect& rect,
                                       const ComputedStyle& style,
                                       GraphicsContext& context,
diff --git a/third_party/WebKit/Source/core/paint/MediaControlsPainter.h b/third_party/WebKit/Source/core/paint/MediaControlsPainter.h
index 0e39d63..2784624 100644
--- a/third_party/WebKit/Source/core/paint/MediaControlsPainter.h
+++ b/third_party/WebKit/Source/core/paint/MediaControlsPainter.h
@@ -88,6 +88,9 @@
                                      const PaintInfo&,
                                      const IntRect&);
   static void AdjustMediaSliderThumbSize(ComputedStyle&);
+  static bool PaintMediaRemotingCastIcon(const LayoutObject&,
+                                         const PaintInfo&,
+                                         const IntRect&);
 
  private:
   static void AdjustMediaSliderThumbPaintSize(const IntRect&,
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 587c3631..df10d3c 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -815,7 +815,7 @@
   TransformationMatrix transform(
       paint_layer_.RenderableTransform(painting_info.GetGlobalPaintFlags()));
   IntPoint rounded_delta = RoundedIntPoint(delta);
-  transform.TranslateRight(rounded_delta.X(), rounded_delta.Y());
+  transform.PostTranslate(rounded_delta.X(), rounded_delta.Y());
   LayoutSize adjusted_sub_pixel_accumulation =
       painting_info.sub_pixel_accumulation + (delta - rounded_delta);
 
diff --git a/third_party/WebKit/Source/core/paint/ThemePainter.cpp b/third_party/WebKit/Source/core/paint/ThemePainter.cpp
index c39cdeb..f4a6cca 100644
--- a/third_party/WebKit/Source/core/paint/ThemePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ThemePainter.cpp
@@ -161,6 +161,8 @@
       return PaintSearchField(o, paint_info, r);
     case kSearchFieldCancelButtonPart:
       return PaintSearchFieldCancelButton(o, paint_info, r);
+    case kMediaRemotingCastIconPart:
+      return MediaControlsPainter::PaintMediaRemotingCastIcon(o, paint_info, r);
     default:
       break;
   }
diff --git a/third_party/WebKit/Source/core/svg/SVGImageElement.cpp b/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
index 19538f8..7b035be 100644
--- a/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
@@ -23,8 +23,6 @@
 
 #include "core/CSSPropertyNames.h"
 #include "core/dom/StyleChangeReason.h"
-#include "core/frame/ImageBitmap.h"
-#include "core/frame/LocalDOMWindow.h"
 #include "core/layout/LayoutImageResource.h"
 #include "core/layout/svg/LayoutSVGImage.h"
 
diff --git a/third_party/WebKit/Source/core/svg/SVGImageElement.h b/third_party/WebKit/Source/core/svg/SVGImageElement.h
index b7a2260..90fc988 100644
--- a/third_party/WebKit/Source/core/svg/SVGImageElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGImageElement.h
@@ -22,7 +22,7 @@
 #define SVGImageElement_h
 
 #include "core/SVGNames.h"
-#include "core/html/canvas/ImageElementBase.h"
+#include "core/html/canvas/CanvasImageElementSource.h"
 #include "core/svg/SVGAnimatedLength.h"
 #include "core/svg/SVGAnimatedPreserveAspectRatio.h"
 #include "core/svg/SVGGraphicsElement.h"
@@ -33,7 +33,7 @@
 namespace blink {
 
 class CORE_EXPORT SVGImageElement final : public SVGGraphicsElement,
-                                          public ImageElementBase,
+                                          public CanvasImageElementSource,
                                           public SVGURIReference {
   DEFINE_WRAPPERTYPEINFO();
   USING_GARBAGE_COLLECTED_MIXIN(SVGImageElement);
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index 39564a8..445cfe074 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -365,7 +365,7 @@
   FloatRect float_bounds(FloatPoint(), size);
   const SkRect bounds(float_bounds);
 
-  flags.setShader(MakePaintShaderRecord(
+  flags.setShader(SkShader::MakePictureShader(
       PaintRecordForCurrentFrame(float_bounds, url), SkShader::kRepeat_TileMode,
       SkShader::kRepeat_TileMode, &local_matrix, &bounds));
 
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png
index 9e40e19..be3d406 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png
+++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png
index 3d23b09..97ac39aa 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png
+++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png
Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
index 747c4f3b..2d58d84 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -4,7 +4,7 @@
     "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
     "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a",
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
-    "smallIcons.svg": "55c46735baa910dbe8f6b9602eb2f464",
+    "smallIcons.svg": "a612780441b0cc423900f6343ee572ab",
     "mediumIcons.svg": "e63ac6385b0a6efb783d9838517e5e44",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
     "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9",
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg
index ef36848..0b61ec60 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg
@@ -36,15 +36,15 @@
      guidetolerance="10"
      inkscape:pageopacity="0"
      inkscape:pageshadow="2"
-     inkscape:window-width="1986"
-     inkscape:window-height="1353"
+     inkscape:window-width="938"
+     inkscape:window-height="826"
      id="namedview4455"
      showgrid="true"
-     inkscape:zoom="10.488889"
-     inkscape:cx="52.875124"
-     inkscape:cy="43.09204"
-     inkscape:window-x="201"
-     inkscape:window-y="36"
+     inkscape:zoom="3.7083823"
+     inkscape:cx="22.472364"
+     inkscape:cy="66.155904"
+     inkscape:window-x="940"
+     inkscape:window-y="26"
      inkscape:window-maximized="0"
      inkscape:current-layer="svg4185">
     <inkscape:grid
@@ -755,4 +755,19 @@
        id="tspan5193-90"
        x="-7.1080513"
        y="8.0561762">5</tspan></text>
+  <g
+     transform="matrix(1.1320755,0,0,1.1320754,81.603774,82.603774)"
+     style="fill:#00bcd4;stroke:#000000;stroke-width:0.30000001"
+     id="g3669">
+    <circle
+       d="M 5.5,3 C 5.5,4.3807119 4.3807119,5.5 3,5.5 1.6192881,5.5 0.5,4.3807119 0.5,3 0.5,1.6192881 1.6192881,0.5 3,0.5 4.3807119,0.5 5.5,1.6192881 5.5,3 z"
+       sodipodi:ry="2.5"
+       sodipodi:rx="2.5"
+       sodipodi:cy="3"
+       sodipodi:cx="3"
+       cx="3"
+       cy="3"
+       r="2.5"
+       id="circle3671" />
+  </g>
 </svg>
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
index 747c4f3b..2d58d84 100644
--- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
+++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -4,7 +4,7 @@
     "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28",
     "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a",
     "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45",
-    "smallIcons.svg": "55c46735baa910dbe8f6b9602eb2f464",
+    "smallIcons.svg": "a612780441b0cc423900f6343ee572ab",
     "mediumIcons.svg": "e63ac6385b0a6efb783d9838517e5e44",
     "breakpoint.svg": "69cd92d807259c022791112809b97799",
     "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9",
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
index aafd190d..015fb7d 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkDataGridNode.js
@@ -44,6 +44,8 @@
     this._showingInitiatorChain = false;
     /** @type {?SDK.NetworkRequest} */
     this._requestOrFirstKnownChildRequest = null;
+    /** @type {!Map<string, !UI.Icon>} */
+    this._columnIcons = new Map();
   }
 
   /**
@@ -612,15 +614,25 @@
 
     element.classList.toggle('network-error-row', this._isFailed());
     element.classList.toggle('network-navigation-row', this._isNavigationRequest);
+    for (var rowDecorator of this._parentView.rowDecorators())
+      rowDecorator.decorate(this);
     super.createCells(element);
   }
 
   /**
+   * @param {string} columnId
+   * @param {!UI.Icon} icon
+   */
+  setIconForColumn(columnId, icon) {
+    this._columnIcons.set(columnId, icon);
+  }
+
+  /**
    * @param {!Element} element
    * @param {string} text
    */
   _setTextAndTitle(element, text) {
-    element.textContent = text;
+    element.createTextChild(text);
     element.title = text;
   }
 
@@ -631,6 +643,9 @@
    */
   createCell(columnIdentifier) {
     var cell = this.createTD(columnIdentifier);
+    var icon = this._columnIcons.get(columnIdentifier);
+    if (icon)
+      cell.appendChild(icon);
     // If the key exists but the value is null it means the extension instance has not resolved yet.
     // The view controller will force all rows to update when extension is resolved.
     if (this._columnExtensions.has(columnIdentifier)) {
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
index 5b19f71c6..7e8d4a0 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
@@ -76,6 +76,9 @@
     this._nodesByRequestId = new Map();
     /** @type {!Map<*, !Network.NetworkGroupNode>} */
     this._nodeGroups = new Map();
+    /** @type {!Set<!Network.NetworkRowDecorator>} */
+    this._rowDecorators = new Set();
+
     /** @type {!Object.<string, boolean>} */
     this._staleRequestIds = {};
     /** @type {number} */
@@ -358,6 +361,13 @@
   }
 
   /**
+   * @return {!Set<!Network.NetworkRowDecorator>}
+   */
+  rowDecorators() {
+    return this._rowDecorators;
+  }
+
+  /**
    * @param {!SDK.NetworkRequest} request
    * @return {?Network.NetworkRequestNode}
    */
@@ -488,6 +498,12 @@
     this.element.id = 'network-container';
     this._setupDataGrid();
 
+    self.runtime.allInstances(Network.NetworkRowDecorator).then(instances => {
+      for (var instance of instances)
+        this._rowDecorators.add(instance);
+      this._invalidateAllItems(true);
+    });
+
     this._columns.show(this.element);
 
     this._summaryBarElement = this.element.createChild('div', 'network-summary-bar');
@@ -1818,3 +1834,15 @@
    */
   groupName(key) {}
 };
+
+/**
+ * @interface
+ */
+Network.NetworkRowDecorator = function() {};
+
+Network.NetworkRowDecorator.prototype = {
+  /**
+   * @param {!Network.NetworkNode} node
+   */
+  decorate(node) {}
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/network_group_lookup/NetworkProductGroupLookup.js b/third_party/WebKit/Source/devtools/front_end/network_group_lookup/NetworkProductGroupLookup.js
index 356b4a1..cdee8495 100644
--- a/third_party/WebKit/Source/devtools/front_end/network_group_lookup/NetworkProductGroupLookup.js
+++ b/third_party/WebKit/Source/devtools/front_end/network_group_lookup/NetworkProductGroupLookup.js
@@ -113,4 +113,29 @@
   }
 };
 
+/**
+ * @implements {Network.NetworkRowDecorator}
+ */
+NetworkGroupLookup.NetworkProductTypeGroupLookup = class {
+  /**
+   * @override
+   * @param {!Network.NetworkNode} node
+   */
+  decorate(node) {
+    var request = node.request();
+    var element = node.existingElement();
+    if (!request || !element)
+      return;
+    var typeName = ProductRegistry.typeForUrl(request.parsedURL);
+    if (!typeName)
+      return;
+    var icon = UI.Icon.create('smallicon-network-product');
+    if (typeName === 'Tracking')
+      icon.style.filter = 'hue-rotate(220deg) brightness(1.5)';
+    if (typeName === 'CDN')
+      icon.style.filter = 'hue-rotate(-90deg) brightness(1.5)';
+    node.setIconForColumn('product-extension', icon);
+  }
+};
+
 NetworkGroupLookup.NetworkProductFrameGroupLookup._productFrameGroupNameSymbol = Symbol('ProductFrameGroupName');
diff --git a/third_party/WebKit/Source/devtools/front_end/network_group_lookup/module.json b/third_party/WebKit/Source/devtools/front_end/network_group_lookup/module.json
index f933c617..9753bb9 100644
--- a/third_party/WebKit/Source/devtools/front_end/network_group_lookup/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/network_group_lookup/module.json
@@ -16,6 +16,10 @@
           "type": "@Network.NetworkColumnExtensionInterface",
           "className": "NetworkGroupLookup.NetworkProductGroupLookup",
           "title": "Product"
+        },
+        {
+          "type": "@Network.NetworkRowDecorator",
+          "className": "NetworkGroupLookup.NetworkProductTypeGroupLookup"
         }
     ],
     "dependencies": [
diff --git a/third_party/WebKit/Source/devtools/front_end/product_registry/ProductNameForURL.js b/third_party/WebKit/Source/devtools/front_end/product_registry/ProductNameForURL.js
index 2a1f885b..29c6dcd1 100644
--- a/third_party/WebKit/Source/devtools/front_end/product_registry/ProductNameForURL.js
+++ b/third_party/WebKit/Source/devtools/front_end/product_registry/ProductNameForURL.js
@@ -6,6 +6,17 @@
  * @return {?string}
  */
 ProductRegistry.nameForUrl = function(parsedUrl) {
+  var entry = ProductRegistry.entryForUrl(parsedUrl);
+  if (entry)
+    return entry.name;
+  return null;
+};
+
+/**
+ * @param {!Common.ParsedURL} parsedUrl
+ * @return {?ProductRegistry.ProductEntry}
+ */
+ProductRegistry.entryForUrl = function(parsedUrl) {
   if (parsedUrl.isDataURL())
     return null;
   // TODO(allada) This should be expanded to allow paths as as well as domain to find a product.
@@ -42,6 +53,17 @@
 };
 
 /**
+ * @param {!Common.ParsedURL} parsedUrl
+ * @return {?string}
+ */
+ProductRegistry.typeForUrl = function(parsedUrl) {
+  var entry = ProductRegistry.entryForUrl(parsedUrl);
+  if (entry)
+    return entry.type;
+  return null;
+};
+
+/**
  * @param {string} domain
  * @return {string}
  */
@@ -50,20 +72,29 @@
 };
 
 /**
+ * @param {!Array<string>} productTypes
  * @param {!Array<string>} productNames
- * @param {!Array<!{hash: string, prefixes: !Object<string, number>}>} data
+ * @param {!Array<!{hash: string, prefixes: !Object<string, !{product: number, type: (number|undefined)}>}>} data
  */
-ProductRegistry.register = function(productNames, data) {
+ProductRegistry.register = function(productTypes, productNames, data) {
+  var typesMap = /** @type {!Map<number, string>} */ (new Map());
+  for (var i = 0; i < productTypes.length; i++)
+    typesMap.set(i, productTypes[i]);
+
   for (var i = 0; i < data.length; i++) {
     var entry = data[i];
     var prefixes = {};
     for (var prefix in entry.prefixes) {
-      var productNameIndex = entry.prefixes[prefix];
-      prefixes[prefix] = productNames[productNameIndex];
+      var prefixEntry = entry.prefixes[prefix];
+      var type = prefixEntry.type !== undefined ? (typesMap.get(prefixEntry.type) || null) : null;
+      prefixes[prefix] = {name: productNames[prefixEntry.product], type: type};
     }
     ProductRegistry._productsByDomainHash.set(entry.hash, prefixes);
   }
 };
 
-/** @type {!Map<string, !Object<string, string>>}} */
+/** @typedef {!{name: string, type: ?string}} */
+ProductRegistry.ProductEntry;
+
+/** @type {!Map<string, !Object<string, !ProductRegistry.ProductEntry>>}} */
 ProductRegistry._productsByDomainHash = new Map();
diff --git a/third_party/WebKit/Source/devtools/front_end/product_registry/ProductRegistryData.js b/third_party/WebKit/Source/devtools/front_end/product_registry/ProductRegistryData.js
index a81166545..fe780fa 100644
--- a/third_party/WebKit/Source/devtools/front_end/product_registry/ProductRegistryData.js
+++ b/third_party/WebKit/Source/devtools/front_end/product_registry/ProductRegistryData.js
@@ -4,6 +4,8 @@
 // clang-format off
 /* eslint-disable */
 ProductRegistry.register([
+],
+[
   "1&1 Internet AG",
   "A9",
   "AdGenie",
@@ -1499,5333 +1501,5333 @@
   "4Info, Inc."
 ],
 [
-  {"hash":"20d393bb0e5c4de5","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"583365b5f9d44cae","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"dcde9b6a7ed731d0","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"0b618d2d6d12ff65","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"5ca7dfe6f0741d1b","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"f10aac9be30b9153","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"a29e3fb3581debcc","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"586a404a027dd51d","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"b772cd4d229b926f","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"5f153f573d601ed5","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"d08d00723aa41a8b","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"154c00442038842c","prefixes":{"":1}}, // [A9]
-  {"hash":"bb5191c2744e5157","prefixes":{"":1}}, // [A9]
-  {"hash":"24f8ee8d41010340","prefixes":{"":1}}, // [A9]
-  {"hash":"dde97a25d741083b","prefixes":{"":1}}, // [A9]
-  {"hash":"c40e51f0d4308aef","prefixes":{"":1}}, // [A9]
-  {"hash":"dafae404fe4bf9e0","prefixes":{"":1}}, // [A9]
-  {"hash":"2965d60c41f24692","prefixes":{"*":2}}, // [AdGenie]
-  {"hash":"947df9bf1ccc5af0","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"5874ab2040fd92e5","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"12c9a3fc47eec655","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"ff950154b65538b5","prefixes":{"":5}}, // [Conversant Ad Server]
-  {"hash":"cca88c18c3a955c3","prefixes":{"*":6}}, // [Napster Luxemburg SARL]
-  {"hash":"cf583a4f1b85a63d","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"b1f24fb9f4e82bc4","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"7ed3ef3bd9b7964c","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"802185637db97f57","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"69ac52e6452dcdcc","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"99d6e276a9f3dce4","prefixes":{"*":10}}, // [eBay]
-  {"hash":"20cea422f633f132","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"abac0e92b7c09189","prefixes":{"":12}}, // [Madeleine Mode GmbH]
-  {"hash":"ab6d5bcfcb13c98c","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"17c760570121cb8e","prefixes":{"":14}}, // [Telefonica UK / O2 UK]
-  {"hash":"cca991b6ab7e6463","prefixes":{"":15}}, // [Tamome]
-  {"hash":"b24aab8ad8822e3b","prefixes":{"":15}}, // [Tamome]
-  {"hash":"e068190951dbb5ef","prefixes":{"":15}}, // [Tamome]
-  {"hash":"c5a5fd495c44b8e2","prefixes":{"":15}}, // [Tamome]
-  {"hash":"95305154969e81b9","prefixes":{"":15}}, // [Tamome]
-  {"hash":"f40a7549c998fd96","prefixes":{"":16}}, // [TUI UK Limited]
-  {"hash":"96eeaa2c9afb8955","prefixes":{"":16}}, // [TUI UK Limited]
-  {"hash":"bfeca1a08eac1f5e","prefixes":{"*":17}}, // [iJento]
-  {"hash":"cfbb894fdba5489a","prefixes":{"":18}}, // [McCann Erikson]
-  {"hash":"4ce21296b7adb20d","prefixes":{"":19}}, // [Tribes Research Limited]
-  {"hash":"72b12a834f93bbd1","prefixes":{"":20}}, // [On Device Research Ltd.]
-  {"hash":"5a885783941e6540","prefixes":{"*":21}}, // [SuperVista AG]
-  {"hash":"382734d54ddf7100","prefixes":{"":22}}, // [National Lottery]
-  {"hash":"397eccbf74cd0328","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"bf0f9d6566d29693","prefixes":{"*":0}}, // [1&1 Internet AG]
-  {"hash":"8fd259996da5f3d8","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"56837fe2597a4f9e","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"fb4ddfafadb387cf","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"07a11d9d007c60f8","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"9f36fc0bb2911046","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"57c7af60819b3f3e","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"c3363b1ccf0e2ab6","prefixes":{"":24}}, // [Interworks Media, Inc.]
-  {"hash":"9d16bd99e929eccd","prefixes":{"":24}}, // [Interworks Media, Inc.]
-  {"hash":"211d3b9ea9bf8f2e","prefixes":{"":25}}, // [Action Exchange, Inc.]
-  {"hash":"414adfe007d3587f","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"4486e584990f9603","prefixes":{"":26}}, // [FSN ASIA PRIVATE LIMITED]
-  {"hash":"8cfb66b1b7bbe43b","prefixes":{"":27}}, // [iPromote]
-  {"hash":"fba2a0cd626a5289","prefixes":{"":27}}, // [iPromote]
-  {"hash":"113620ff3bb3ea60","prefixes":{"":27}}, // [iPromote]
-  {"hash":"b5f6b4570a07977c","prefixes":{"*":28}}, // [33Across Inc.]
-  {"hash":"877f3b2ffe34bf4a","prefixes":{"*":29}}, // [8thBridge]
-  {"hash":"bc5882cc43d24a0b","prefixes":{"":1}}, // [A9]
-  {"hash":"5506a3935677620c","prefixes":{"":1}}, // [A9]
-  {"hash":"4a8f0380d8c0ee22","prefixes":{"":1}}, // [A9]
-  {"hash":"54e1d163948509ad","prefixes":{"":1}}, // [A9]
-  {"hash":"534e3733e4e5309d","prefixes":{"":1}}, // [A9]
-  {"hash":"c7db8e0e25c7df2d","prefixes":{"":1}}, // [A9]
-  {"hash":"222afdeb29be30ca","prefixes":{"":1}}, // [A9]
-  {"hash":"a082f434d9ec1f91","prefixes":{"":1}}, // [A9]
-  {"hash":"e00092cf7fb8c74a","prefixes":{"":1}}, // [A9]
-  {"hash":"6b3557e54073f90d","prefixes":{"":1}}, // [A9]
-  {"hash":"b825724682d4bd41","prefixes":{"":1}}, // [A9]
-  {"hash":"62a0c6b3cd3ed567","prefixes":{"":1}}, // [A9]
-  {"hash":"7e5f80275a654f93","prefixes":{"":1}}, // [A9]
-  {"hash":"426c5ded1145b847","prefixes":{"*":1}}, // [A9]
-  {"hash":"14f8bb92c4036403","prefixes":{"*":1}}, // [A9]
-  {"hash":"8aaada51ee8ebb86","prefixes":{"*":1}}, // [A9]
-  {"hash":"38eac8937b706b6f","prefixes":{"*":1}}, // [A9]
-  {"hash":"7e1d4edc3530e448","prefixes":{"":1}}, // [A9]
-  {"hash":"c0bf2b011199054e","prefixes":{"":1}}, // [A9]
-  {"hash":"b4dd68c5d9b68922","prefixes":{"":1}}, // [A9]
-  {"hash":"8d943586f8f86d04","prefixes":{"":1}}, // [A9]
-  {"hash":"f60b51325cdf4f80","prefixes":{"":1}}, // [A9]
-  {"hash":"080dea15fa602a8c","prefixes":{"":1}}, // [A9]
-  {"hash":"a01c9f1f745acb3b","prefixes":{"":1}}, // [A9]
-  {"hash":"eae49b84950db230","prefixes":{"":1}}, // [A9]
-  {"hash":"dabd2bc95093ab29","prefixes":{"":1}}, // [A9]
-  {"hash":"8912c7bdde481292","prefixes":{"":1}}, // [A9]
-  {"hash":"c735e4adfc754475","prefixes":{"":1}}, // [A9]
-  {"hash":"297bba8cd045b252","prefixes":{"":1}}, // [A9]
-  {"hash":"b4ee04e1cb1b0cb0","prefixes":{"":1}}, // [A9]
-  {"hash":"1f9925b611b3db5e","prefixes":{"":1}}, // [A9]
-  {"hash":"e63f21a01153ba8c","prefixes":{"":1}}, // [A9]
-  {"hash":"5df92c4776ddb318","prefixes":{"":1}}, // [A9]
-  {"hash":"995e4fe402d230d4","prefixes":{"":1}}, // [A9]
-  {"hash":"f27bb2795a31311c","prefixes":{"":1}}, // [A9]
-  {"hash":"7ef41a846501bb38","prefixes":{"":1}}, // [A9]
-  {"hash":"f69c9d0a6726d8a2","prefixes":{"":1}}, // [A9]
-  {"hash":"fbe82cac507c4685","prefixes":{"":1}}, // [A9]
-  {"hash":"b30108dc4fef7d3d","prefixes":{"":1}}, // [A9]
-  {"hash":"3db91f22497fff29","prefixes":{"":1}}, // [A9]
-  {"hash":"8c93f288d1c9adaa","prefixes":{"":1}}, // [A9]
-  {"hash":"dd3abfa7756f945e","prefixes":{"":1}}, // [A9]
-  {"hash":"562f4260ff4f65a6","prefixes":{"":1}}, // [A9]
-  {"hash":"94d8ddce749b5392","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"031269afdaee38ca","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"0c0ba1aaf374eac4","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"cb1dbab4bb9d139b","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"144dac73c5669441","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"b6b232e5fbf868f0","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"3c15562b6abc1319","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"722c811d70136506","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"78a792effa9e4967","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"a59637a7ca9dc579","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"6b3ce5ea793ecbbf","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"2b5bd0c505a178d0","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"c41cefa39852e538","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"e572b55cf0c6834b","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"80d0b8e46094b1c9","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"343036881041aa23","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"2559ed3163479794","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"95acf3d42f565375","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"a3fe80607786880e","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"b7629e7fab881e7a","prefixes":{"":31}}, // [Retailigence]
-  {"hash":"03ec1a841574bd4d","prefixes":{"":32}}, // [Logly DSP]
-  {"hash":"7ff5ce1768464e16","prefixes":{"":32}}, // [Logly DSP]
-  {"hash":"10fb9dcb49e1abe6","prefixes":{"":33}}, // [App-CM Inc.]
-  {"hash":"6d3713ad37a0966c","prefixes":{"":33}}, // [App-CM Inc.]
-  {"hash":"41670ff004a04f19","prefixes":{"":33}}, // [App-CM Inc.]
-  {"hash":"cd681b4891935464","prefixes":{"":34}}, // [Yahoo! Japan Corporation]
-  {"hash":"b97383320b594f18","prefixes":{"":34}}, // [Yahoo! Japan Corporation]
-  {"hash":"e2fff6e598b3035e","prefixes":{"":1}}, // [A9]
-  {"hash":"cb3ceda4f0c38995","prefixes":{"":1}}, // [A9]
-  {"hash":"a218e065250d793c","prefixes":{"":1}}, // [A9]
-  {"hash":"deb1ce911dfb392b","prefixes":{"":1}}, // [A9]
-  {"hash":"de5ead15f1d0f171","prefixes":{"":1}}, // [A9]
-  {"hash":"92615d394883ce3c","prefixes":{"":1}}, // [A9]
-  {"hash":"6cd842b12d20b208","prefixes":{"":1}}, // [A9]
-  {"hash":"dc6acfacad6c1026","prefixes":{"":1}}, // [A9]
-  {"hash":"81aa25ff76990996","prefixes":{"":1}}, // [A9]
-  {"hash":"1254067a80cf3d7b","prefixes":{"":1}}, // [A9]
-  {"hash":"31e2549e82b92770","prefixes":{"":1}}, // [A9]
-  {"hash":"be41bb940608434e","prefixes":{"":1}}, // [A9]
-  {"hash":"05a4ab4a11bd1fbf","prefixes":{"":1}}, // [A9]
-  {"hash":"05677aca712e9b65","prefixes":{"":1}}, // [A9]
-  {"hash":"00620801050945d1","prefixes":{"":35}}, // [Oggifinogi]
-  {"hash":"c0ceae7cfc4144c6","prefixes":{"":36}}, // [PaperG]
-  {"hash":"996c3990310cfc19","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"14210f0f0a8d71cb","prefixes":{"":38}}, // [The Trade Desk Inc.]
-  {"hash":"0f07ec261c73a8fb","prefixes":{"*":39,"":40}}, // [Amazon] [F# Inc.]
-  {"hash":"736b87f504b5e113","prefixes":{"":41}}, // [Airpush, Inc.]
-  {"hash":"0bcef81372eadfe9","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"9ea6769e672968e9","prefixes":{"":40}}, // [F# Inc.]
-  {"hash":"0fde612c20c42c6f","prefixes":{"":43}}, // [Transout Inc.]
-  {"hash":"5ed995763ce85029","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"497082972c1c0dfd","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"6d7e4a203b969d9e","prefixes":{"":46}}, // [Opera Mediaworks Inc.]
-  {"hash":"d3a9057528c14a56","prefixes":{"":47}}, // [DistroScale Inc.]
-  {"hash":"479d2f8d9b7a2efe","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"6f7f9fb0065f745f","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"893d967f4540bb44","prefixes":{"":49}}, // [Fluct Inc.]
-  {"hash":"3830f0b6ca460fe9","prefixes":{"*":50}}, // [Acuity Ads]
-  {"hash":"e917237ee7b0ad79","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"e0792ffd5eca94d8","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"29beee316a393584","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"ce9e7bf17bba4aae","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"fcf604f90166bb66","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"f11d9059950b4a07","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"7d142a85f84f3402","prefixes":{"":50}}, // [Acuity Ads]
-  {"hash":"83c0bb224cb5622f","prefixes":{"*":51}}, // [iLead]
-  {"hash":"27841e5ac1581a67","prefixes":{"":52}}, // [Canned Banners LLC]
-  {"hash":"83fbdce4f2519684","prefixes":{"":52}}, // [Canned Banners LLC]
-  {"hash":"db7bac94f2b2d2b7","prefixes":{"":53}}, // [AdBroker GmbH]
-  {"hash":"e0de5430253205fc","prefixes":{"":53}}, // [AdBroker GmbH]
-  {"hash":"bde57b6011499edf","prefixes":{"":53}}, // [AdBroker GmbH]
-  {"hash":"077ad042e29c79fb","prefixes":{"":53}}, // [AdBroker GmbH]
-  {"hash":"d3c6fc5ff77f0d5c","prefixes":{"":53}}, // [AdBroker GmbH]
-  {"hash":"b88fb01ba215894e","prefixes":{"*":54}}, // [InMind Opinion Media]
-  {"hash":"3d509f557aeca6de","prefixes":{"*":55}}, // [Adcentric]
-  {"hash":"3a9959c8cadd20af","prefixes":{"*":56}}, // [AdClear GmbH]
-  {"hash":"e8adb806a39f661d","prefixes":{"":57}}, // [DeinDeal AG]
-  {"hash":"da7343c16a51f1d4","prefixes":{"":58}}, // [Sixt Leasing SE]
-  {"hash":"5b4d4595453d5b23","prefixes":{"":59}}, // [Air Berlin]
-  {"hash":"b5085d3a3ede7503","prefixes":{"":60}}, // [Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper]
-  {"hash":"076e39b7aa354c83","prefixes":{"":56}}, // [AdClear GmbH]
-  {"hash":"61c6a6d15b340f45","prefixes":{"":61}}, // [Adform DSP]
-  {"hash":"36f5cb213a4d1469","prefixes":{"":61}}, // [Adform DSP]
-  {"hash":"95b61c012402be18","prefixes":{"":61}}, // [Adform DSP]
-  {"hash":"34e291794974e891","prefixes":{"":61}}, // [Adform DSP]
-  {"hash":"1d0d393655ae7ce4","prefixes":{"*":62}}, // [Adconion Media Group]
-  {"hash":"dbeb328acc5a5a14","prefixes":{"*":62}}, // [Adconion Media Group]
-  {"hash":"9e6e5f626bc3d43c","prefixes":{"":62}}, // [Adconion Media Group]
-  {"hash":"66659e79ff807f39","prefixes":{"":62}}, // [Adconion Media Group]
-  {"hash":"ce965bb06760436e","prefixes":{"":62}}, // [Adconion Media Group]
-  {"hash":"ca8e04a5cdd8fd1f","prefixes":{"":62}}, // [Adconion Media Group]
-  {"hash":"1084f1e2b04f5f93","prefixes":{"":62}}, // [Adconion Media Group]
-  {"hash":"04b3778457a3ba99","prefixes":{"*":62}}, // [Adconion Media Group]
-  {"hash":"1b843f2f1a39c98b","prefixes":{"":63}}, // [Adform]
-  {"hash":"8c7beead1ea37382","prefixes":{"":63}}, // [Adform]
-  {"hash":"2b59e3efe59d97d5","prefixes":{"":63}}, // [Adform]
-  {"hash":"518308907f5f69a2","prefixes":{"":63}}, // [Adform]
-  {"hash":"07d4474fae9c6b06","prefixes":{"":63}}, // [Adform]
-  {"hash":"47c590566f0c869a","prefixes":{"":63}}, // [Adform]
-  {"hash":"409240a38e5e72b9","prefixes":{"":63}}, // [Adform]
-  {"hash":"98421a6d07f5517b","prefixes":{"":63}}, // [Adform]
-  {"hash":"4f00fb001635132a","prefixes":{"":63}}, // [Adform]
-  {"hash":"c6ba94708f6d7d53","prefixes":{"":63}}, // [Adform]
-  {"hash":"caae109e8a3bec4f","prefixes":{"":63}}, // [Adform]
-  {"hash":"9137b5cdfcb54ca8","prefixes":{"":63}}, // [Adform]
-  {"hash":"ae96d818a0674db2","prefixes":{"":63}}, // [Adform]
-  {"hash":"f67fecc339ee273d","prefixes":{"":63}}, // [Adform]
-  {"hash":"763cc84e4a6c6fce","prefixes":{"":63}}, // [Adform]
-  {"hash":"170707627205d14d","prefixes":{"*":64}}, // [Adition]
-  {"hash":"4b3783127a962269","prefixes":{"":64}}, // [Adition]
-  {"hash":"457cb5e9c72500bd","prefixes":{"":64}}, // [Adition]
-  {"hash":"0f529dc32c1b9057","prefixes":{"":64}}, // [Adition]
-  {"hash":"e63845bad50263e0","prefixes":{"":65}}, // [Active Agent]
-  {"hash":"08b8d8e397848984","prefixes":{"":65}}, // [Active Agent]
-  {"hash":"146ac0ff21924e7d","prefixes":{"*":64}}, // [Adition]
-  {"hash":"a51da6855de3a256","prefixes":{"":66}}, // [mov.ad GmbH]
-  {"hash":"150498b9d10f053f","prefixes":{"*":64}}, // [Adition]
-  {"hash":"fa1803e00adafe6b","prefixes":{"":66}}, // [mov.ad GmbH]
-  {"hash":"ba820e9bd3ccd291","prefixes":{"":66}}, // [mov.ad GmbH]
-  {"hash":"73f70045beea25cc","prefixes":{"":66}}, // [mov.ad GmbH]
-  {"hash":"14725cb7b6e3ed94","prefixes":{"":66}}, // [mov.ad GmbH]
-  {"hash":"fd2740cbee10696e","prefixes":{"":66}}, // [mov.ad GmbH]
-  {"hash":"e150d6342c6a3952","prefixes":{"*":67}}, // [AdJug]
-  {"hash":"50b8b93a8b536983","prefixes":{"*":68}}, // [AdJuggler]
-  {"hash":"85335d83efc9839b","prefixes":{"*":68}}, // [AdJuggler]
-  {"hash":"08f0bb45326cffe3","prefixes":{"*":69}}, // [AdKeeper]
-  {"hash":"5e2b2393dad3f5eb","prefixes":{"*":69}}, // [AdKeeper]
-  {"hash":"da818bcf61df9002","prefixes":{"*":69}}, // [AdKeeper]
-  {"hash":"846fc96edd68e2f8","prefixes":{"*":70}}, // [AdKnife]
-  {"hash":"914d48df3d7aeaae","prefixes":{"*":71}}, // [Adku]
-  {"hash":"8a5b58174cc938bf","prefixes":{"*":72}}, // [AdLantic Online Advertising]
-  {"hash":"218eb49612488266","prefixes":{"":73}}, // [Adloox]
-  {"hash":"85c9a55ea5b2a32a","prefixes":{"data":73,"am":73}}, // [Adloox] [Adloox]
-  {"hash":"9827ba4725b53982","prefixes":{"":73}}, // [Adloox]
-  {"hash":"bfbbf6b81b109b36","prefixes":{"*":74}}, // [adMarketplace]
-  {"hash":"006d6718806b7562","prefixes":{"*":75}}, // [AdMotion]
-  {"hash":"43871f2ce46890ca","prefixes":{"":76}}, // [AdMotion USA Inc.]
-  {"hash":"2648f20c5fa7ee09","prefixes":{"":76}}, // [AdMotion USA Inc.]
-  {"hash":"63e0b0f085a8b214","prefixes":{"*":77}}, // [Digilant]
-  {"hash":"7288a07f340911e5","prefixes":{"":78}}, // [Adnologies GmbH]
-  {"hash":"a9fe843107d85e5c","prefixes":{"":78}}, // [Adnologies GmbH]
-  {"hash":"230c59512261d73d","prefixes":{"cdn-":78}}, // [Adnologies GmbH]
-  {"hash":"8ca4fb13619b77f1","prefixes":{"*":79}}, // [Adometry by Google]
-  {"hash":"18652cba5445b34f","prefixes":{"":80}}, // [Adperium BV]
-  {"hash":"6d09f83aefc4501e","prefixes":{"*":81}}, // [AdPredictive]
-  {"hash":"70732e61af9adb0a","prefixes":{"":82}}, // [Usemax]
-  {"hash":"b4ede094fe706ace","prefixes":{"*":83}}, // [Adrime]
-  {"hash":"b19cfc95f67d0fa7","prefixes":{"*":83}}, // [Adrime]
-  {"hash":"a6e49b6248014fa6","prefixes":{"*":84}}, // [AdRiver]
-  {"hash":"4a53a59490c4a38e","prefixes":{"*":85}}, // [Adroit Interactive]
-  {"hash":"683e22cafa5f3bd9","prefixes":{"":85}}, // [Adroit Interactive]
-  {"hash":"02e8a15ca61fbc33","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"a3c3a62c565da599","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"73e23ad84157f244","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"b8bd71aaaa715a18","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"34049e798c80bbab","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"838eef1c1fe8af0c","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"3a7e3dfea00e8162","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"0173cd7bab46f6fd","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"c14663d78cbafed8","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"308a1884ba632254","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"0e219f63d92e9f36","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"f01c179c5f1e71ec","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"37523eaeb9b1fe5b","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"65eb7e97acb7c098","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"3caa5b10b768447a","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"c8ca517332beacb1","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"8af902c81b793154","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"38ed924c01545a3b","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"5b57e356a62d6828","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"4281a0a413796f1b","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"66e356358c42a9dd","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"ebe26069a0940456","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"9d2283ab81bb7a35","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"d5e05919c2d72fad","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"519afd00add32a74","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"88d48f3ceb8d02bb","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"d93b7d2660301b12","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"6a71009da4358f28","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"71f627786ab80897","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"f1b3147102656b41","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"1a3040f79f3eda5d","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"1c81402568ca4c6f","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"5a0f681f5d3714ed","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"fb3d4d280f621627","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"6811c6e8c717b25b","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"2b559615c990392b","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"d8447dd40d9ce63f","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"98a32e82bd6110c6","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"e3ff44ab0bbc3669","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"d8a244effa85d1e6","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"fa65d62c20cc94bb","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"1d55dfbdf9f318d1","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"e06269227a02ae45","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"2d2bf9a9cb6e9f86","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"0adbf6085946bbf6","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"61d2d4f25972fccd","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"d9506dcf3ab8ec68","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"61448b088aea7146","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"12b1ed92371498e2","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"b8f763d46b3d230a","prefixes":{"":88}}, // [Integral Ad Science Firewall]
-  {"hash":"d4033ecbe069d318","prefixes":{"":87}}, // [Campaign Monitor]
-  {"hash":"b45ea1eb9c9290a1","prefixes":{"*":89}}, // [AdShuffle]
-  {"hash":"333bed71fe872c88","prefixes":{"":90}}, // [ADSOVO]
-  {"hash":"ad77e48d841a15a8","prefixes":{"":90}}, // [ADSOVO]
-  {"hash":"f822525b349866b4","prefixes":{"*":91}}, // [ADTECH GmbH]
-  {"hash":"6cda8dd1b92f6c35","prefixes":{"*":91}}, // [ADTECH GmbH]
-  {"hash":"4d592efbff40197f","prefixes":{"*":92}}, // [Adtelligence]
-  {"hash":"0f57dc611a2e469e","prefixes":{"":93}}, // [Adverline]
-  {"hash":"ef6cb8337223cbd6","prefixes":{"*":93}}, // [Adverline]
-  {"hash":"1902c407bbf1add8","prefixes":{"*":94}}, // [AOL Advertising.com]
-  {"hash":"c0956c63084023a8","prefixes":{"":95}}, // [Adap.tv Inc. (AdX)]
-  {"hash":"f029d231882ed252","prefixes":{"":95}}, // [Adap.tv Inc. (AdX)]
-  {"hash":"ee175aa478efb9b3","prefixes":{"*":94}}, // [AOL Advertising.com]
-  {"hash":"c0fff6b8232710c4","prefixes":{"*":94}}, // [AOL Advertising.com]
-  {"hash":"a846e3340ac27ada","prefixes":{"":96}}, // [Convertro Inc]
-  {"hash":"548e9e34dbc275b6","prefixes":{"":97}}, // [Tacoda]
-  {"hash":"e9695f56eaa054e2","prefixes":{"":94}}, // [AOL Advertising.com]
-  {"hash":"f7f6bc8c4345347a","prefixes":{"*":98}}, // [Digital Control GmbH (Advolution)]
-  {"hash":"484a656ace404140","prefixes":{"":98}}, // [Digital Control GmbH (Advolution)]
-  {"hash":"a224f896601ec717","prefixes":{"":98}}, // [Digital Control GmbH (Advolution)]
-  {"hash":"3a79a6d9af12ef9a","prefixes":{"*":99}}, // [AdXcel]
-  {"hash":"b3dec77d20a55dcb","prefixes":{"*":99}}, // [AdXcel]
-  {"hash":"1f25b55eca65221c","prefixes":{"":99}}, // [AdXcel]
-  {"hash":"f531a655b1982ee7","prefixes":{"":100}}, // [Alenty S.A.S]
-  {"hash":"b884f71dddd78a28","prefixes":{"":101}}, // [DoubleClick Bid Manager]
-  {"hash":"839eb75d0e9ef128","prefixes":{"":102}}, // [BigaBid Media Ltd.]
-  {"hash":"ad920773d5c3e050","prefixes":{"":103}}, // [Cogo Labs, Inc.]
-  {"hash":"6cbe6bc5d5fed35c","prefixes":{"":104}}, // [AudienceProject]
-  {"hash":"98bc51a23a37253c","prefixes":{"*":39}}, // [Amazon]
-  {"hash":"78cfcb50606e44f8","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"37f3aa55bd48760c","prefixes":{"":106}}, // [PocketMath]
-  {"hash":"fa92c520ca116999","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"26d760f54a265d93","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"c046bec428f602d5","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"7fbe2c9290629394","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"16d261a6c03c3de9","prefixes":{"":108}}, // [Immedium, Inc.]
-  {"hash":"1787c49522ce0278","prefixes":{"":109}}, // [Fractional Media, LLC]
-  {"hash":"45ccf99ac2ed3af1","prefixes":{"":109}}, // [Fractional Media, LLC]
-  {"hash":"8c431268cc5c116b","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"645dd2a279a77bf5","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"53aaf4b4f2f2cc8b","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"a6175c31fc587fa2","prefixes":{"":111}}, // [Epic Combo Malta Ltd.]
-  {"hash":"c0e7c2ad3d5d28a0","prefixes":{"":111}}, // [Epic Combo Malta Ltd.]
-  {"hash":"b6a3ce0dea65f762","prefixes":{"":112}}, // [Quixey]
-  {"hash":"29e07de898fa18f4","prefixes":{"":112}}, // [Quixey]
-  {"hash":"1959efaae117c9fa","prefixes":{"":113}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"0a59c33253f15970","prefixes":{"":114}}, // [TapTap Networks S.L.]
-  {"hash":"383161133467d12b","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"e2e18e4ba75c8e58","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"1f9da694ae6dd7cf","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"5038b4de783848d4","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"3542b95dcaa08c84","prefixes":{"":115}}, // [ComScore (AdXpose)]
-  {"hash":"7bbbdfeb3d7b8ad3","prefixes":{"*":116}}, // [AdYard]
-  {"hash":"2ff57c503c5f110d","prefixes":{"":117}}, // [Affectv]
-  {"hash":"7558d4293841e1f0","prefixes":{"":117}}, // [Affectv]
-  {"hash":"a8adad05a6ff5945","prefixes":{"":117}}, // [Affectv]
-  {"hash":"cd1a91dee22478d6","prefixes":{"":117}}, // [Affectv]
-  {"hash":"ebca243af085210f","prefixes":{"":117}}, // [Affectv]
-  {"hash":"bc7fe0dc5bf3e869","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"c894a0e3f6a6b627","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"bfdba513f8cb5b8b","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"1227c609f898a707","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"4f884065e1e88de2","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"93d5950ea0bfe437","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"560c5b8e23e29733","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"28d74bfc94c9635f","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"8f7f83e4f5f9e2c0","prefixes":{"":3}}, // [Affilinet GmbH]
-  {"hash":"fd2b5d860fd44749","prefixes":{"*":3}}, // [Affilinet GmbH]
-  {"hash":"1d0953961a14d2fc","prefixes":{"*":118}}, // [SET.tv]
-  {"hash":"5edf63353d8e0fcd","prefixes":{"":118}}, // [SET.tv]
-  {"hash":"e4e5eb11299f703e","prefixes":{"*":119}}, // [Adroit Digital Solutions (ADS)]
-  {"hash":"e5cf3445847fef93","prefixes":{"*":119}}, // [Adroit Digital Solutions (ADS)]
-  {"hash":"8441a2216167c3d4","prefixes":{"at":100}}, // [Alenty S.A.S]
-  {"hash":"b9dab57457cf6477","prefixes":{"":100}}, // [Alenty S.A.S]
-  {"hash":"94b55596aadb2893","prefixes":{"":100}}, // [Alenty S.A.S]
-  {"hash":"16b31027fd40c9ad","prefixes":{"":100}}, // [Alenty S.A.S]
-  {"hash":"bb4adabba7b0b6b8","prefixes":{"*":120}}, // [AppNexus Inc]
-  {"hash":"3b2105469f3563e3","prefixes":{"*":121}}, // [Adfusion]
-  {"hash":"2f29d38052b5a8a6","prefixes":{"":122}}, // [ARC Media Group]
-  {"hash":"c133787bd9e605a7","prefixes":{"":123}}, // [Semasio GmbH]
-  {"hash":"b9a83d8bd4f31543","prefixes":{"":124}}, // [Mojiva]
-  {"hash":"2a1b04ad13f24350","prefixes":{"":124}}, // [Mojiva]
-  {"hash":"a3c6b5ffd4fe1547","prefixes":{"":125}}, // [Mocean mobile, Inc.]
-  {"hash":"0d52aafa33281228","prefixes":{"":126}}, // [Phluant]
-  {"hash":"655e31ecb8719994","prefixes":{"":126}}, // [Phluant]
-  {"hash":"dca17bd2f3edb917","prefixes":{"":126}}, // [Phluant]
-  {"hash":"53de58004f88a1c2","prefixes":{"*":127}}, // [AdSpirit]
-  {"hash":"6a1ebf671194b458","prefixes":{"*":127}}, // [AdSpirit]
-  {"hash":"6ae5a4877aab564f","prefixes":{"":127}}, // [AdSpirit]
-  {"hash":"9dcf8d17ea42466e","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"32e0acbf3d2ecfcf","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"708d275466f5230b","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"7532d83428e05417","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"3258e49c5f504307","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"2c381faaa3144a37","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"776a64cc3a9c6f81","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"d38247a8e8d14a7c","prefixes":{"*":128}}, // [ConvertMedia Ltd.]
-  {"hash":"50e5ca70dbb69c03","prefixes":{"":128}}, // [ConvertMedia Ltd.]
-  {"hash":"c1dfde405c173e3b","prefixes":{"":128}}, // [ConvertMedia Ltd.]
-  {"hash":"5bce52b0f221aac2","prefixes":{"":128}}, // [ConvertMedia Ltd.]
-  {"hash":"5a0e5730145156e2","prefixes":{"":128}}, // [ConvertMedia Ltd.]
-  {"hash":"c081c626ad2c0f1f","prefixes":{"":128}}, // [ConvertMedia Ltd.]
-  {"hash":"a31f53c0c58e67c0","prefixes":{"":129}}, // [ATK Media GmbH]
-  {"hash":"514b4f19cbdabb49","prefixes":{"":129}}, // [ATK Media GmbH]
-  {"hash":"264493bb5046087f","prefixes":{"":129}}, // [ATK Media GmbH]
-  {"hash":"f4e40d6832493420","prefixes":{"":129}}, // [ATK Media GmbH]
-  {"hash":"126b6492c0b1b53a","prefixes":{"*":130}}, // [Atlas]
-  {"hash":"0493e6c92c59fd4d","prefixes":{"":130}}, // [Atlas]
-  {"hash":"d6d40b4417fefcf6","prefixes":{"":130}}, // [Atlas]
-  {"hash":"0b16a7cf8dcb70ee","prefixes":{"*":131}}, // [AudienceScience]
-  {"hash":"edbae80f2449aaee","prefixes":{"":132}}, // [BeWebMedia]
-  {"hash":"c1196b1418bf9de9","prefixes":{"*":133}}, // [Bidalpha Inc.]
-  {"hash":"87016c0f34162bc6","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"2db3b8adb9c37590","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"a10756ccfb034a50","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"1ea7188c5cc22ccf","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"c70dfe98c3735972","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"05aa49d024d6d67c","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"27c08401857f47aa","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"9a569266b426d074","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"5a764c1f870e4e38","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"64b993405c35034f","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"afe660eca2d01217","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"cd398b1d3fe6caf4","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"bb2cf5a27552ba10","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"b79ee8778f5b56d6","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"cae97638b357a30e","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"2c552297aa3abdf1","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"75bbf901ed30d891","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"365bc710167be24c","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"49849f3497cc7ff5","prefixes":{"":134}}, // [AdGear Technologies Inc.]
-  {"hash":"14bb8555907973f5","prefixes":{"":135}}, // [BlueKai]
-  {"hash":"db6cb381e20a210a","prefixes":{"":135}}, // [BlueKai]
-  {"hash":"8e4e07437ae4b61c","prefixes":{"*":136}}, // [Bluestreak]
-  {"hash":"4bb6a17c8b5ec2e7","prefixes":{"":137}}, // [blurbIQ]
-  {"hash":"4aefb106f857a0de","prefixes":{"":137}}, // [blurbIQ]
-  {"hash":"a7b4452428f93120","prefixes":{"":137}}, // [blurbIQ]
-  {"hash":"38f01d050feb50e8","prefixes":{"":137}}, // [blurbIQ]
-  {"hash":"d4ab70ba7caf1ed7","prefixes":{"":138}}, // [Brand.net]
-  {"hash":"94655d9cadd8e829","prefixes":{"":138}}, // [Brand.net]
-  {"hash":"f3347a75843fd9c6","prefixes":{"":138}}, // [Brand.net]
-  {"hash":"60e2856d32c1da23","prefixes":{"*":139}}, // [Brandscreen Inc.]
-  {"hash":"16460b1ac6e3b229","prefixes":{"*":140}}, // [BrightRoll Inc.]
-  {"hash":"814fef93d6498b58","prefixes":{"*":140}}, // [BrightRoll Inc.]
-  {"hash":"72fc1d7c40b9af03","prefixes":{"":141}}, // [Brightroll Inc.]
-  {"hash":"80f8944423cc936c","prefixes":{"*":142}}, // [Vindico]
-  {"hash":"bf2db20b09960c7b","prefixes":{"":142}}, // [Vindico]
-  {"hash":"e180a56826bf4ba6","prefixes":{"*":143}}, // [Edgesuite]
-  {"hash":"1e90c625da6683a5","prefixes":{"":144}}, // [Spark Flow S.A.]
-  {"hash":"d385e514fe92e6d9","prefixes":{"":145}}, // [Aarki, Inc.]
-  {"hash":"4646e46d55455ffe","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"a8c5f49831b36ab9","prefixes":{"*":147}}, // [Burst Media LLC d/b/a AdConductor]
-  {"hash":"f22276edaf005231","prefixes":{"*":148}}, // [Advertising.com Dynamic Retargeter]
-  {"hash":"220db526eb84992d","prefixes":{"*":149}}, // [NetAffiliation]
-  {"hash":"cda3d9612026866c","prefixes":{"*":149}}, // [NetAffiliation]
-  {"hash":"9f8018bcbf15a592","prefixes":{"*":150}}, // [C3 Metrics Inc.]
-  {"hash":"78ec342986654215","prefixes":{"":150}}, // [C3 Metrics Inc.]
-  {"hash":"e4ad94837095a9bc","prefixes":{"*":150}}, // [C3 Metrics Inc.]
-  {"hash":"32401b2118eff57a","prefixes":{"":151}}, // [CAPITALDATA (SARL)]
-  {"hash":"a5f9db92cb5aeb3e","prefixes":{"":151}}, // [CAPITALDATA (SARL)]
-  {"hash":"ae12db7e0621ec0b","prefixes":{"*":151}}, // [CAPITALDATA (SARL)]
-  {"hash":"d7c4970fde31fd62","prefixes":{"*":152}}, // [e-Planning]
-  {"hash":"20cadab7abdae752","prefixes":{"*":153}}, // [Chango Inc.]
-  {"hash":"38363f7ac872a916","prefixes":{"":154}}, // [Chango]
-  {"hash":"114215c6a5b66e37","prefixes":{"":154}}, // [Chango]
-  {"hash":"1ab7b29d135c11fc","prefixes":{"":155}}, // [Channel Intelligence]
-  {"hash":"6e8e21cf50387d5b","prefixes":{"":155}}, // [Channel Intelligence]
-  {"hash":"cbd8c46855691ac9","prefixes":{"*":155}}, // [Channel Intelligence]
-  {"hash":"8bde0d3ba731b24b","prefixes":{"":155}}, // [Channel Intelligence]
-  {"hash":"d415664f4794184e","prefixes":{"":155}}, // [Channel Intelligence]
-  {"hash":"bc8edad5208e36aa","prefixes":{"*":155}}, // [Channel Intelligence]
-  {"hash":"00900e4af3795b7d","prefixes":{"":156}}, // [Chartbeat Inc]
-  {"hash":"dddd416675de98d6","prefixes":{"":156}}, // [Chartbeat Inc]
-  {"hash":"085835cbbea3af5b","prefixes":{"":156}}, // [Chartbeat Inc]
-  {"hash":"0a5fd555ed989cf1","prefixes":{"":156}}, // [Chartbeat Inc]
-  {"hash":"38e6dfa04599d610","prefixes":{"":156}}, // [Chartbeat Inc]
-  {"hash":"282ab213b57d8196","prefixes":{"":156}}, // [Chartbeat Inc]
-  {"hash":"465922959fd197de","prefixes":{"*":157}}, // [Choicestream Inc.]
-  {"hash":"07b64c6d94aaeede","prefixes":{"*":158}}, // [AddThis, Inc]
-  {"hash":"8285ed75ebbab1bf","prefixes":{"*":158}}, // [AddThis, Inc]
-  {"hash":"397da235f9c6c4dc","prefixes":{"*":159}}, // [Platform 161]
-  {"hash":"3e4380669a97a9da","prefixes":{"":159}}, // [Platform 161]
-  {"hash":"0cf7c3db283e4fde","prefixes":{"":160}}, // [ClickPoint]
-  {"hash":"e3f610966ee4998e","prefixes":{"":161}}, // [Cobalt Group]
-  {"hash":"5458332ef0eff5a0","prefixes":{"":161}}, // [Cobalt Group]
-  {"hash":"755391831ca3c171","prefixes":{"*":161}}, // [Cobalt Group]
-  {"hash":"82d7785d13750576","prefixes":{"*":161}}, // [Cobalt Group]
-  {"hash":"f1b10b28e8a1e8a9","prefixes":{"*":161}}, // [Cobalt Group]
-  {"hash":"ca9dc80141cf19b5","prefixes":{"*":162}}, // [Cognitive Match Limited]
-  {"hash":"d02173b857f779a2","prefixes":{"*":162}}, // [Cognitive Match Limited]
-  {"hash":"987bec8a1c07a02f","prefixes":{"*":162}}, // [Cognitive Match Limited]
-  {"hash":"da18ae94f7dd99ab","prefixes":{"":163}}, // [Tagtoo Tech Limited]
-  {"hash":"5e1256c5e919daf9","prefixes":{"":164}}, // [wayStorm Co., Ltd.]
-  {"hash":"9e92efa06a26b83d","prefixes":{"*":162}}, // [Cognitive Match Limited]
-  {"hash":"cf3c8c24a0eb24a6","prefixes":{"*":162}}, // [Cognitive Match Limited]
-  {"hash":"eac24a30a92872f1","prefixes":{"":162}}, // [Cognitive Match Limited]
-  {"hash":"a508105d922876fe","prefixes":{"":162}}, // [Cognitive Match Limited]
-  {"hash":"b7f1551e6c1615df","prefixes":{"":162}}, // [Cognitive Match Limited]
-  {"hash":"e56a388aae6f063e","prefixes":{"*":165}}, // [Collective Media LLC]
-  {"hash":"adc75d0087df3e89","prefixes":{"":166}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"6f0ca09cdc147fb0","prefixes":{"":166}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"11f6ca20d229d8ad","prefixes":{"":166}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"e4d55634b8d3126d","prefixes":{"":166}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"6100cc0a622faa8e","prefixes":{"":167}}, // [ComScore Validated Campaign Essentials (vCE)]
-  {"hash":"a30e99f000f781c7","prefixes":{"":167}}, // [ComScore Validated Campaign Essentials (vCE)]
-  {"hash":"1ee7cb55ae2cb071","prefixes":{"":166}}, // [ComScore Campaign Essentials (CE)]
-  {"hash":"7dfd981d4c018953","prefixes":{"":167}}, // [ComScore Validated Campaign Essentials (vCE)]
-  {"hash":"5011cb94579baba5","prefixes":{"*":168}}, // [VoiceFive (ComScore)]
-  {"hash":"a0cff89b286fc309","prefixes":{"":168}}, // [VoiceFive (ComScore)]
-  {"hash":"4782e75d195d3144","prefixes":{"":168}}, // [VoiceFive (ComScore)]
-  {"hash":"e63472329b04aab9","prefixes":{"":168}}, // [VoiceFive (ComScore)]
-  {"hash":"5814e7da11d65131","prefixes":{"":168}}, // [VoiceFive (ComScore)]
-  {"hash":"26c9b653ef6bfb53","prefixes":{"*":169}}, // [Connexity LLC]
-  {"hash":"eb38b3659a232a56","prefixes":{"":169}}, // [Connexity LLC]
-  {"hash":"08abcdb9184877f9","prefixes":{"":169}}, // [Connexity LLC]
-  {"hash":"65a439ff09c9f7dc","prefixes":{"":169}}, // [Connexity LLC]
-  {"hash":"b3afc505f1f5487b","prefixes":{"":169}}, // [Connexity LLC]
-  {"hash":"b35a41328f2a6830","prefixes":{"*":170}}, // [Constant Contact]
-  {"hash":"e7a596af94ad559e","prefixes":{"":171}}, // [ContextWeb Inc.]
-  {"hash":"25ccc25c112607e9","prefixes":{"":171}}, // [ContextWeb Inc.]
-  {"hash":"44e652990824ddee","prefixes":{"":171}}, // [ContextWeb Inc.]
-  {"hash":"8eac48fda4ccaec8","prefixes":{"":171}}, // [ContextWeb Inc.]
-  {"hash":"0b4eee92ed72b991","prefixes":{"ant-":172}}, // [Conversive BV]
-  {"hash":"dae78afe5d5cc699","prefixes":{"":172}}, // [Conversive BV]
-  {"hash":"7729d423a7fc3adf","prefixes":{"*":96}}, // [Convertro Inc]
-  {"hash":"cdff1e442509fafe","prefixes":{"":173}}, // [IBM Digital Analytics]
-  {"hash":"a07829ef9a9d6762","prefixes":{"*":174}}, // [Crimtan]
-  {"hash":"43c19f0523939982","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"2c4f3b76ebfafe80","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"078603692b0949b1","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"aa8844a1d3e7c3aa","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"15ef2aafaa03e60b","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"5f1ef71046a359f7","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"2fb5d0d81abd43be","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"75ce1d1edaf8f426","prefixes":{"":174}}, // [Crimtan]
-  {"hash":"a7b80b09927034f7","prefixes":{"*":175}}, // [Criteo]
-  {"hash":"3a96f385ff402ab6","prefixes":{"*":175}}, // [Criteo]
-  {"hash":"189c3bab631d09cf","prefixes":{"":176}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"3d9109a2e81eee2d","prefixes":{"":176}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"e7170acff5d6fda1","prefixes":{"":176}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"e0496c88da22371f","prefixes":{"":176}}, // [D.A. Consortium Inc. (EffectiveOne)]
-  {"hash":"59ab4e7744543242","prefixes":{"":177}}, // [Platform One]
-  {"hash":"f6b2b21a0a0417b3","prefixes":{"":177}}, // [Platform One]
-  {"hash":"4384a84e6276861a","prefixes":{"*":178}}, // [Dapper Inc.]
-  {"hash":"1ccbc5b91f4c5fc9","prefixes":{"*":179}}, // [DataXu Inc.]
-  {"hash":"4840192a8cb4b1ca","prefixes":{"*":179}}, // [DataXu Inc.]
-  {"hash":"b50faf8c7e5fc38c","prefixes":{"":180}}, // [Aperture]
-  {"hash":"bdcf8ed53f1b3802","prefixes":{"*":181}}, // [Rakuten Attribution]
-  {"hash":"d31e7c4efd1a5191","prefixes":{"*":181}}, // [Rakuten Attribution]
-  {"hash":"68318c6d8f72133b","prefixes":{"*":181}}, // [Rakuten Attribution]
-  {"hash":"c0c4eb0ce58ef4b1","prefixes":{"*":181}}, // [Rakuten Attribution]
-  {"hash":"ae713ee10231204e","prefixes":{"*":182}}, // [AdAction]
-  {"hash":"e4282cef85ee5728","prefixes":{"":183}}, // [Demandbase Inc.]
-  {"hash":"79f6c3d16c278e94","prefixes":{"":183}}, // [Demandbase Inc.]
-  {"hash":"13e7a7b6c40ef05b","prefixes":{"":183}}, // [Demandbase Inc.]
-  {"hash":"57e736fc045f8fbd","prefixes":{"":183}}, // [Demandbase Inc.]
-  {"hash":"82137a4a2aa17f33","prefixes":{"*":184}}, // [Omniture]
-  {"hash":"ddc305710749f5b7","prefixes":{"*":184}}, // [Omniture]
-  {"hash":"3cd74441fc237226","prefixes":{"*":184}}, // [Omniture]
-  {"hash":"5b40000c858b730d","prefixes":{"":185}}, // [Rovion, Inc.]
-  {"hash":"47d66d29363322cd","prefixes":{"":186}}, // [AdHui.com LLC]
-  {"hash":"10a0efb999eedf90","prefixes":{"":186}}, // [AdHui.com LLC]
-  {"hash":"b1bf29ae383ea0cd","prefixes":{"":187}}, // [Bidlab sp. z o.o]
-  {"hash":"baa26df04dbce196","prefixes":{"":187}}, // [Bidlab sp. z o.o]
-  {"hash":"c3f807fb12d64ef3","prefixes":{"":188}}, // [CyberAgent Inc.]
-  {"hash":"8caed248711d066a","prefixes":{"":188}}, // [CyberAgent Inc.]
-  {"hash":"03524472b71baf6f","prefixes":{"":189}}, // [Relay42 Technology B.V.]
-  {"hash":"c26a754afcf8496d","prefixes":{"":189}}, // [Relay42 Technology B.V.]
-  {"hash":"fa7ea4c2400b9304","prefixes":{"":189}}, // [Relay42 Technology B.V.]
-  {"hash":"f91d12ea09409395","prefixes":{"":189}}, // [Relay42 Technology B.V.]
-  {"hash":"a3404139a451726c","prefixes":{"":190}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"072f7bf8cea1803c","prefixes":{"":190}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"8a6e324bbf4e02dc","prefixes":{"":190}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"e59faa8d364c3ad2","prefixes":{"":190}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"fe39de2cc1550ee8","prefixes":{"":190}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"41808f1a9bcd4cdf","prefixes":{"":190}}, // [Nielsen Digital Ad Ratings (JS)]
-  {"hash":"1774fa7feee9a3ba","prefixes":{"":191}}, // [Nielsen (Audience Measurement Platform)]
-  {"hash":"8bcfafa30bb9a496","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"04a15100eebd5238","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"37669b02a11574d6","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"b0e609cae76778ef","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"8602961190244c78","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"cf6160cc55083e3f","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"d8e0147c7067e033","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"fa4e638adbad854a","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"bfc104d8ae540578","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"a77b609ecb948524","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"5b2d6c6512b90826","prefixes":{"":193}}, // [Nielsen (Sales Effect)]
-  {"hash":"3f0eefad5865a4ed","prefixes":{"":194}}, // [Ohana Media India Private Limited]
-  {"hash":"ba149fc47bfe9e3c","prefixes":{"":194}}, // [Ohana Media India Private Limited]
-  {"hash":"cfe9fa124d3faa0b","prefixes":{"*":195}}, // [DisplayCDN]
-  {"hash":"3f8d8705aeaf2a69","prefixes":{"":196}}, // [Avail Intelligence]
-  {"hash":"3aa373d150e55bb8","prefixes":{"":196}}, // [Avail Intelligence]
-  {"hash":"01168e37c54407ec","prefixes":{"":196}}, // [Avail Intelligence]
-  {"hash":"9d0088e875d03291","prefixes":{"":197}}, // [Adobe Scene 7]
-  {"hash":"7892719f65634daf","prefixes":{"":198}}, // [Asda]
-  {"hash":"76913c314e7299f2","prefixes":{"":199}}, // [Adsfactor Limited]
-  {"hash":"ec3d301a1049a29c","prefixes":{"":200}}, // [Trademob GmbH]
-  {"hash":"0407237113d1e01a","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"3c2b08727db96f57","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"28d8cdf30ea5e75d","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"4ba6006c59a0afb3","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"34b0d82da56a6e14","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"c9293b8324f3a30f","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"78ad5395bf22ddd5","prefixes":{"":201}}, // [Zamplus Technology Co., Ltd.]
-  {"hash":"b0a5ecf647236d2a","prefixes":{"*":202}}, // [Telemetry Limited]
-  {"hash":"7d7cd86e56968411","prefixes":{"*":202}}, // [Telemetry Limited]
-  {"hash":"ccaf0946d1809711","prefixes":{"*":202}}, // [Telemetry Limited]
-  {"hash":"d08bcd58e153f333","prefixes":{"*":203}}, // [AdPilot]
-  {"hash":"c1ee73ca85937956","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"b3ee9fcc7f773476","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"0dededd99d2513e4","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"efd59a0198028c96","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"b43b6c20f3008842","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"5d96f09a039b26e6","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"039408a17f3d50d7","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"16d696fe52cae068","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"ebb9da6e533fc7e4","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"c8afb150eb1b6ac1","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"1e21c92ae4d08330","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"07ef420d707be72c","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"3d9fb95e3108b648","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"938e971e186be4f8","prefixes":{"":203}}, // [AdPilot]
-  {"hash":"94682de65e11f128","prefixes":{"":204}}, // [ebookers]
-  {"hash":"32548cc45dcf9e95","prefixes":{"":204}}, // [ebookers]
-  {"hash":"baa9bf6209e38821","prefixes":{"":204}}, // [ebookers]
-  {"hash":"25a263451425f7e3","prefixes":{"*":205}}, // [Mashero GmbH]
-  {"hash":"4871ba81fe73b693","prefixes":{"":206}}, // [4wMarketPlace Srl]
-  {"hash":"f95f038fea1148ab","prefixes":{"*":207}}, // [Meetic Partners]
-  {"hash":"8c555d8aa0a96ecc","prefixes":{"*":208}}, // [Adara Media]
-  {"hash":"a31f9bce31634750","prefixes":{"":209}}, // [Adledge]
-  {"hash":"bb0d6b4eac177896","prefixes":{"":209}}, // [Adledge]
-  {"hash":"02712dc83414bc52","prefixes":{"":209}}, // [Adledge]
-  {"hash":"03cfa92cdadd6c20","prefixes":{"":209}}, // [Adledge]
-  {"hash":"4d8640e955380082","prefixes":{"":209}}, // [Adledge]
-  {"hash":"42ab78ba8d28d0d9","prefixes":{"":209}}, // [Adledge]
-  {"hash":"113f35a595990303","prefixes":{"":209}}, // [Adledge]
-  {"hash":"9566d797c39bca8e","prefixes":{"":209}}, // [Adledge]
-  {"hash":"caab6878aaf1b900","prefixes":{"":209}}, // [Adledge]
-  {"hash":"13581af42d29c3fd","prefixes":{"":209}}, // [Adledge]
-  {"hash":"8ad4e9b59b6cfebf","prefixes":{"":209}}, // [Adledge]
-  {"hash":"025223bda779fb50","prefixes":{"":210}}, // [Adledge: Ad Swapping]
-  {"hash":"6c7970d8fe11d946","prefixes":{"":211}}, // [LifeStreet Corportation]
-  {"hash":"226c377d19c24dca","prefixes":{"":211}}, // [LifeStreet Corportation]
-  {"hash":"bc64475cc35aba69","prefixes":{"":211}}, // [LifeStreet Corportation]
-  {"hash":"8a184297457cd4e1","prefixes":{"":211}}, // [LifeStreet Corportation]
-  {"hash":"900f97a5320abcc7","prefixes":{"":212}}, // [AdCirrus]
-  {"hash":"39b102bb2f01d1b4","prefixes":{"":213}}, // [Dimestore]
-  {"hash":"a144c6442bbc8a0a","prefixes":{"":213}}, // [Dimestore]
-  {"hash":"8020cac4e8fee023","prefixes":{"":213}}, // [Dimestore]
-  {"hash":"2dcefe5fe106e478","prefixes":{"*":214}}, // [GfK SE]
-  {"hash":"d8f9a95c0ea00853","prefixes":{"*":213}}, // [Dimestore]
-  {"hash":"829fbeefc45bca87","prefixes":{"*":215}}, // [Conversant CRM]
-  {"hash":"357a04f93d25ae56","prefixes":{"cdn":216,"log":216,"tps":216,"rtb":217}}, // [DoubleVerify Inc.] [DoubleVerify Inc.] [DoubleVerify Inc.] [DoubleVerify Inc. (BrandShield): Ad Swapping]
-  {"hash":"e88f040d82035294","prefixes":{"":216}}, // [DoubleVerify Inc.]
-  {"hash":"a378f9f7b3d5241c","prefixes":{"*":218}}, // [Dynamic Video LLC]
-  {"hash":"665ab90fa95fb304","prefixes":{"":218}}, // [Dynamic Video LLC]
-  {"hash":"1358623e271c4d67","prefixes":{"":218}}, // [Dynamic Video LLC]
-  {"hash":"a11e7a579fa98970","prefixes":{"*":219}}, // [Think RealTime, LLC]
-  {"hash":"9225aaedf058b2a2","prefixes":{"":220}}, // [Effective Measure]
-  {"hash":"36703887ac49b84b","prefixes":{"":220}}, // [Effective Measure]
-  {"hash":"eabfdf13f38b7671","prefixes":{"*":221}}, // [Adobe Media Optimizer]
-  {"hash":"e6c60b5e8bab7589","prefixes":{"*":221}}, // [Adobe Media Optimizer]
-  {"hash":"d4ca4e6c8a0bedf0","prefixes":{"*":221}}, // [Adobe Media Optimizer]
-  {"hash":"2e2899c7688fb6b3","prefixes":{"":222}}, // [Effiliation]
-  {"hash":"3a8f463e807ab596","prefixes":{"":222}}, // [Effiliation]
-  {"hash":"4c49524999954857","prefixes":{"":222}}, // [Effiliation]
-  {"hash":"99a4dc2c14dac648","prefixes":{"*":223}}, // [EmediateAd]
-  {"hash":"eb4d633002c35102","prefixes":{"*":223}}, // [EmediateAd]
-  {"hash":"a4155988849d9899","prefixes":{"":223}}, // [EmediateAd]
-  {"hash":"a29dc15ab67e4109","prefixes":{"*":223}}, // [EmediateAd]
-  {"hash":"244ed2f383a41c11","prefixes":{"*":223}}, // [EmediateAd]
-  {"hash":"f1d41523d742a4c4","prefixes":{"*":224}}, // [engage:BDR Inc.]
-  {"hash":"0c985c5bee46dcca","prefixes":{"":224}}, // [engage:BDR Inc.]
-  {"hash":"6f92a4165360659f","prefixes":{"":224}}, // [engage:BDR Inc.]
-  {"hash":"e65b14b1de797d5e","prefixes":{"":224}}, // [engage:BDR Inc.]
-  {"hash":"8908058eec675b88","prefixes":{"*":4}}, // [Eulerian Technologies SARL]
-  {"hash":"dae357b5105fb541","prefixes":{"*":4}}, // [Eulerian Technologies SARL]
-  {"hash":"7e5c5286bc6286af","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"6459463a599e26cf","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"d49c14999963fa7c","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"f7508ecdfd1b76f8","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"747ac3c2114de916","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"5445e9650966f2c9","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"b701368b6964f28f","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"b8d4853208b3d665","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"a3c05ce1535a1bb0","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"4113e02fa7f80330","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"1ec6c8299f47c92d","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"6213db1c94ff78b4","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"afdce1f639f05293","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"c00800107f132ba6","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"f989cf5678a6cd73","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"7248d6bb2e2d2812","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"5decec320495d46c","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"ffffd176ae6095cd","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"a0ead46cc7797fc4","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"d1b36183709cf97c","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"f08e0f4d46762277","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"1082450fce471aec","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"0c44a72359ff962b","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"c6ced7239fa526b8","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"bcd4afcb16a1bf83","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"c4629483e0f61849","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"3a8a51dc5059eb82","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"10d4846e0b0f6213","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"8e03e96054cde307","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"d1c591453eeceb89","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"a9ee5e0b07924cbe","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"4909d0f68d7f7dd5","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"1954dcac7d36e9a9","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"855fab1b44b2cc38","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"9a977de69b69e767","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"32c7999b9a328d48","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"675aab76d51e4be4","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"454f35d478088b2f","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"af6f37ce228476e6","prefixes":{"*":4}}, // [Eulerian Technologies SARL]
-  {"hash":"dfa2565386557dbb","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"7bdee1b08b69b7fa","prefixes":{"*":4}}, // [Eulerian Technologies SARL]
-  {"hash":"259e3811976143d2","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"29633cedc9fc7e43","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"758fea4a1e3ad80f","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"cf9bd7435c526efc","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"913928e477b69d4d","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"391c770feaa49fc6","prefixes":{"":4}}, // [Eulerian Technologies SARL]
-  {"hash":"9aea11673c37df0c","prefixes":{"*":225}}, // [Ghostery Enterprise]
-  {"hash":"5efff70d6937c916","prefixes":{"*":226}}, // [Experteer GmbH]
-  {"hash":"070f9075bd0072ca","prefixes":{"":227}}, // [Action Allocator]
-  {"hash":"2a8c1779456949e3","prefixes":{"":228}}, // [AdTraxx]
-  {"hash":"0d3994abeed42b53","prefixes":{"*":229}}, // [eyeDemand]
-  {"hash":"f804a9a8eb6b2828","prefixes":{"*":230}}, // [EyeReturn Marketing]
-  {"hash":"e7b16a7fe9d18804","prefixes":{"*":230}}, // [EyeReturn Marketing]
-  {"hash":"9a826150ea3a7b3d","prefixes":{"*":231}}, // [EyeView Inc.]
-  {"hash":"00f40aaf7abec691","prefixes":{"":232}}, // [EyeView, Inc]
-  {"hash":"a47b1640e108c4e8","prefixes":{"":232}}, // [EyeView, Inc]
-  {"hash":"73c2e89f340530ca","prefixes":{"*":233}}, // [Eyewonder Inc.]
-  {"hash":"ab1869399e555ac8","prefixes":{"":234}}, // [MLB Advanced Media, L.P.]
-  {"hash":"6792c3d3132bf7d7","prefixes":{"":234}}, // [MLB Advanced Media, L.P.]
-  {"hash":"3d02d3a5042f5ad8","prefixes":{"":234}}, // [MLB Advanced Media, L.P.]
-  {"hash":"c75b8641d2e585d7","prefixes":{"*":235}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"535ecf05ae26ef66","prefixes":{"*":235}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"2393220aafcd7f07","prefixes":{"*":235}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"ead2626488917d96","prefixes":{"*":235}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"82402af773d46078","prefixes":{"*":235}}, // [Facilitate For Agencies (FFA)]
-  {"hash":"0afacf5097d4ca72","prefixes":{"*":236}}, // [Flashtalking]
-  {"hash":"5215ee9300af8125","prefixes":{"":237}}, // [Hostelworld.com Limited]
-  {"hash":"e8d6e54e3ce31711","prefixes":{"":238}}, // [Knorex Pte. Ltd.]
-  {"hash":"a8ac5a522ae936d9","prefixes":{"":238}}, // [Knorex Pte. Ltd.]
-  {"hash":"c88080a9090fa828","prefixes":{"":238}}, // [Knorex Pte. Ltd.]
-  {"hash":"90727ba23e427206","prefixes":{"":238}}, // [Knorex Pte. Ltd.]
-  {"hash":"d496e8a41b845c1e","prefixes":{"":238}}, // [Knorex Pte. Ltd.]
-  {"hash":"e3463a0b0d9d0b84","prefixes":{"*":239}}, // [Flite Inc.]
-  {"hash":"93eff417d773ad79","prefixes":{"*":239}}, // [Flite Inc.]
-  {"hash":"48c727cb39130203","prefixes":{"*":239}}, // [Flite Inc.]
-  {"hash":"1f8b889072fc177c","prefixes":{"*":240}}, // [Forbes Media LLC]
-  {"hash":"830e0f5dd1181234","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"daf4edc7545d5166","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"f786c1dcc4eb883e","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"82534a9af0bc48e0","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"091c6487b80c3425","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"5250da9f53cd928c","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"9a8514c0fd5d6754","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"ad91bc98d2a8be55","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"91e5780ca48d75cc","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"481acfc271cd8a12","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"ef2a23dc677d8426","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"c6c8ce28b06bbda5","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"2bb2e1ea24146c0b","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"a0f3f5041ae3893c","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"4d6c5ce49301c775","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"747c952599211285","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"59f1e6a6110f9a68","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"f76895f67d1585b2","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"a2e125e235d1ffd4","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"17cbbfe7617725b3","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"1c118cc87c632e94","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"a48217ad66a56eb4","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"949fd73ca6fcc6f5","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"7d647d3164d8e6e2","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"e6d9d61b6785d883","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"aad9a81ea12d3c42","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"f0d9b5588abc50f9","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"dcb3db79fcab6476","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"1985d21c9c0b8366","prefixes":{"":242}}, // [FreakOut Inc.]
-  {"hash":"a268d22dc85b4108","prefixes":{"*":243}}, // [FreeWheel]
-  {"hash":"a796f300b3d2c84e","prefixes":{"*":244}}, // [Fringe81 Inc.]
-  {"hash":"bb563c63d09f3d76","prefixes":{"":245}}, // [Fringe81 - IBV]
-  {"hash":"c6ac10cc9ddfb3e7","prefixes":{"":245}}, // [Fringe81 - IBV]
-  {"hash":"48983a0d5a27b120","prefixes":{"*":246}}, // [FuseBox Inc.]
-  {"hash":"6f59caebdaac019e","prefixes":{"":246}}, // [FuseBox Inc.]
-  {"hash":"8090c608651eca30","prefixes":{"*":247}}, // [gemiusDirectEffect+]
-  {"hash":"e7b75209bd73a1d9","prefixes":{"*":248}}, // [AdOcean Ltd]
-  {"hash":"24fb4ed27ae8cf88","prefixes":{"*":249}}, // [Intomart GfK (GfK Daphne)]
-  {"hash":"91571a34ff0fcf44","prefixes":{"*":250}}, // [Gigya]
-  {"hash":"bd66201f4f935a9d","prefixes":{"*":251}}, // [Global Market Insite Inc.]
-  {"hash":"c0854a371610fbf2","prefixes":{"*":251}}, // [Global Market Insite Inc.]
-  {"hash":"4a32fa997117f00d","prefixes":{"*":252,"":253}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"68d0356c33bd8ec4","prefixes":{"*":252,"":253}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"813ca9ac3483af55","prefixes":{"*":252,"":253}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"ee88383142da014d","prefixes":{"*":252,"":253}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
-  {"hash":"1332f3da43091ed3","prefixes":{"":252,"*":254}}, // [DoubleClick Campaign Manager] [DoubleClick for Publishers Premium]
-  {"hash":"f04082d14282d452","prefixes":{"":252}}, // [DoubleClick Campaign Manager]
-  {"hash":"c6ad6c580aef6ce5","prefixes":{"":252}}, // [DoubleClick Campaign Manager]
-  {"hash":"642706b0b0335500","prefixes":{"":252}}, // [DoubleClick Campaign Manager]
-  {"hash":"baea954b95731c68","prefixes":{"*":255}}, // [Google CDN]
-  {"hash":"8e23699963552b18","prefixes":{"*":252}}, // [DoubleClick Campaign Manager]
-  {"hash":"bafedfe69ed92305","prefixes":{"*":253}}, // [DoubleClick Bidder Pilot for Networks]
-  {"hash":"f2b999c597cd97af","prefixes":{"*":253}}, // [DoubleClick Bidder Pilot for Networks]
-  {"hash":"66399889a04f9513","prefixes":{"cdn":256,"ads":256,"db":256,"img":256,"ssl":256}}, // [GroovinAds] [GroovinAds] [GroovinAds] [GroovinAds] [GroovinAds]
-  {"hash":"ea8510cdf6991d43","prefixes":{"":256}}, // [GroovinAds]
-  {"hash":"fc2e03aac9426552","prefixes":{"":257}}, // [Reddion]
-  {"hash":"6db39bcc7e0f7fed","prefixes":{"":258}}, // [HQ GmbH]
-  {"hash":"4de0590ca954b13b","prefixes":{"*":259}}, // [Performance Display Advertising]
-  {"hash":"44f4a1b16ff856e5","prefixes":{"":5}}, // [Conversant Ad Server]
-  {"hash":"127f97cfaedd763a","prefixes":{"":5}}, // [Conversant Ad Server]
-  {"hash":"508035bfa2d95844","prefixes":{"*":5}}, // [Conversant Ad Server]
-  {"hash":"6ea225859ddfba18","prefixes":{"*":5}}, // [Conversant Ad Server]
-  {"hash":"600a5a5f53775d42","prefixes":{"*":216}}, // [DoubleVerify Inc.]
-  {"hash":"cabba15c5ee8f039","prefixes":{"*":260}}, // [Avazu Inc.]
-  {"hash":"ec98881ed60ffe62","prefixes":{"":91}}, // [ADTECH GmbH]
-  {"hash":"b1e5dca23b928251","prefixes":{"":91}}, // [ADTECH GmbH]
-  {"hash":"87e919d72e293303","prefixes":{"*":261}}, // [Aerify Media]
-  {"hash":"652d7fe0079512a8","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"8e1afef4fbf079f4","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"3f697fb2c06659ac","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"cb5ae4cc94e8cb57","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"3cd44a0f52d69fed","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"fd87dfe8678e2630","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"274e4476c8fbfe0c","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"e3f56a006c4f8fc8","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"11d582be18893073","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"54768ce9ed6664fc","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"6de580016869f523","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"7fc8a77e5f366b6d","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"06838afa0ce9cde5","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"d788f92161d75b72","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"bd27e9c073c7b133","prefixes":{"":262}}, // [IClick Interactive Ltd.]
-  {"hash":"71096991891dc36f","prefixes":{"*":263}}, // [iCrossing]
-  {"hash":"0a48c6448ca1af83","prefixes":{"":263}}, // [iCrossing]
-  {"hash":"23cce2ff5ce35111","prefixes":{"*":264}}, // [Impact Engine Inc.]
-  {"hash":"b63329d63303bcac","prefixes":{"*":265}}, // [Inadco Inc.]
-  {"hash":"9dab6f7b066953b6","prefixes":{"":265}}, // [Inadco Inc.]
-  {"hash":"83efdfb00e5e0bb5","prefixes":{"":266}}, // [Innity Singapore Pte Ltd.]
-  {"hash":"5cdf5c58d4a95757","prefixes":{"":266}}, // [Innity Singapore Pte Ltd.]
-  {"hash":"e84e4c75279b444c","prefixes":{"":266}}, // [Innity Singapore Pte Ltd.]
-  {"hash":"0ad278b0f1bf83c7","prefixes":{"":267}}, // [Insight Express (Cross Media - Ignite)]
-  {"hash":"75089fef153b99d9","prefixes":{"":267}}, // [Insight Express (Cross Media - Ignite)]
-  {"hash":"17e48170b29e8c55","prefixes":{"":268}}, // [intelliAd Media GmbH]
-  {"hash":"8ff3a159f3a3dd37","prefixes":{"":268}}, // [intelliAd Media GmbH]
-  {"hash":"d5ad6ce37d416c20","prefixes":{"":268}}, // [intelliAd Media GmbH]
-  {"hash":"829116e73bbd766e","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"58b6a73b811a6744","prefixes":{"":268}}, // [intelliAd Media GmbH]
-  {"hash":"1b02753d1ebc5935","prefixes":{"":270}}, // [Intelliad]
-  {"hash":"2d4767b28a0a3dc9","prefixes":{"":270}}, // [Intelliad]
-  {"hash":"04e4138ad91eba43","prefixes":{"*":271}}, // [Genome]
-  {"hash":"a80259001a08f5fe","prefixes":{"":271}}, // [Genome]
-  {"hash":"bccc7d85fcbd6406","prefixes":{"*":272}}, // [Intergi LLC dba PlaywireMedia]
-  {"hash":"c0e12f3f6483d539","prefixes":{"":273}}, // [Intermundo Media LLC]
-  {"hash":"aa0d2346396993dc","prefixes":{"*":274}}, // [Interpolls]
-  {"hash":"391f02c89579c41e","prefixes":{"*":275}}, // [Intelligent Reach (Intuitive Search Technologies)]
-  {"hash":"dd7ece8c8b4dd4db","prefixes":{"*":275}}, // [Intelligent Reach (Intuitive Search Technologies)]
-  {"hash":"51beebfd5a677c74","prefixes":{"":275}}, // [Intelligent Reach (Intuitive Search Technologies)]
-  {"hash":"15a557d1be0b55bc","prefixes":{"*":276}}, // [IPONWEB Limited]
-  {"hash":"ab800ebb45ab5e96","prefixes":{"":276}}, // [IPONWEB Limited]
-  {"hash":"cf6003cf8be11c49","prefixes":{"*":276}}, // [IPONWEB Limited]
-  {"hash":"bd97f2dac673ccef","prefixes":{"*":277}}, // [JasperLabs Inc.]
-  {"hash":"833a1bb3e47002bf","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"925afb63a81d22ae","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"e3546ee6177ce1af","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"a6e81a993b0dc090","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"57cf72a6bcc6ed09","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"aef508a87f7b9342","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"a1a0984cf6e12596","prefixes":{"":278}}, // [Jivox Corporation]
-  {"hash":"c1b82a9e7564881f","prefixes":{"*":279}}, // [Joinville AB]
-  {"hash":"e20dd6e83cbd14d9","prefixes":{"":280}}, // [KliKKicom Oy]
-  {"hash":"a1f03f455fc97850","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"fb87830648f1fe7c","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"93a6bcd7660ef88b","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"14fba951393c4cc1","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"96bf72901db53556","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"00ceea10fed6f827","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"5deb6288aeb4b20d","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"30a9e5cf761c2db9","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"b49fda322943ed64","prefixes":{"":281}}, // [Komli Media Inc.]
-  {"hash":"30067241c16c9f88","prefixes":{"*":282}}, // [Koninklijke Luchtvaart Maatschappij N.V.]
-  {"hash":"06076b672be3af43","prefixes":{"*":283}}, // [J.D. Power O2O]
-  {"hash":"1e23ff61443f919a","prefixes":{"*":284}}, // [Kwanzoo Inc.]
-  {"hash":"32327b1f6a21f5e3","prefixes":{"":285}}, // [Legolas Media Inc.]
-  {"hash":"0a98bd3ecf6d4f39","prefixes":{"":285}}, // [Legolas Media Inc.]
-  {"hash":"4141a8162aadd52a","prefixes":{"":285}}, // [Legolas Media Inc.]
-  {"hash":"9562185c6a06e194","prefixes":{"*":286}}, // [Undertone Ad System (UAS)]
-  {"hash":"d8be1c121ccbdb84","prefixes":{"":287}}, // [LEVEL Studios]
-  {"hash":"1b274516ac601c1d","prefixes":{"*":288}}, // [LinkedIn Corporation]
-  {"hash":"a9aceb9b28670518","prefixes":{"*":288}}, // [LinkedIn Corporation]
-  {"hash":"f202e32e7503e766","prefixes":{"":288}}, // [LinkedIn Corporation]
-  {"hash":"cf2094771b42b367","prefixes":{"*":288}}, // [LinkedIn Corporation]
-  {"hash":"ad94f98bfc0092ce","prefixes":{"*":289}}, // [Content Directions, Inc. dba Linkstorm]
-  {"hash":"2c97a2e1f7f59cde","prefixes":{"*":290}}, // [Liverail Inc.]
-  {"hash":"562dd0a17776cfc3","prefixes":{"*":291}}, // [Lotame Solutions Inc.]
-  {"hash":"85c409cdb78a6fec","prefixes":{"*":292}}, // [LucidMedia Networks Inc.]
-  {"hash":"25cdc372f14aa636","prefixes":{"":293}}, // [Magnetic Media Online Inc.]
-  {"hash":"490a692feb4f5f83","prefixes":{"":293}}, // [Magnetic Media Online Inc.]
-  {"hash":"8cd182ca413a6770","prefixes":{"":293}}, // [Magnetic Media Online Inc.]
-  {"hash":"891ff79862603ca1","prefixes":{"*":294}}, // [Mate1.com]
-  {"hash":"ae4598324ee10cb2","prefixes":{"":295}}, // [MaxPoint Interactive Inc.]
-  {"hash":"66eafecb064a6d3f","prefixes":{"*":296}}, // [Media Armor Inc.]
-  {"hash":"d9921090d75b28f3","prefixes":{"*":297}}, // [Xaxis, Inc]
-  {"hash":"4c897372b3205c67","prefixes":{"*":298}}, // [Dstillery]
-  {"hash":"78172051b147ff71","prefixes":{"*":298}}, // [Dstillery]
-  {"hash":"3e32e501635bb994","prefixes":{"*":299}}, // [Rakuten MediaForge]
-  {"hash":"ab3637f7ff19f3be","prefixes":{"*":86}}, // [MediaMath Inc.]
-  {"hash":"eacb348c2bfde7c6","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"6ec884dc33afd8e3","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"6a0b44c268e0ea34","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"5ec2ba6f16455240","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"f6a166105958340d","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"1bafa194e1b43948","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"c4c10492cf3f1e5c","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"fb29996f4dbe86a3","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"33cba419c0d99c36","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"1471e355753e333a","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"8445471e74aaf1ad","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"fe448fc8fa6792c7","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"7142d0f7c95e6c11","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"f71e7939a3a06b85","prefixes":{"":300}}, // [Sizmek]
-  {"hash":"25c9493f4ceef0b3","prefixes":{"*":300}}, // [Sizmek]
-  {"hash":"1c0486f5c9ddccc1","prefixes":{"":301}}, // [MediaMind]
-  {"hash":"511f53552d7c07f9","prefixes":{"*":302}}, // [Paypal]
-  {"hash":"c23b8169e8d6f935","prefixes":{"*":302}}, // [Paypal]
-  {"hash":"4cb72fa17c1e6b21","prefixes":{"*":303}}, // [ZEDO Inc.]
-  {"hash":"1f5866beb3a2da29","prefixes":{"":304}}, // [Contobox]
-  {"hash":"ab4011df7412e85a","prefixes":{"":304}}, // [Contobox]
-  {"hash":"4c55c99f7e731e4a","prefixes":{"":304}}, // [Contobox]
-  {"hash":"b32dad95de4864bb","prefixes":{"":304}}, // [Contobox]
-  {"hash":"e0636cdabf7592eb","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"9e011383339e65c3","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"c7f6b97c8a7defa6","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"ba29743e534631a5","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"df986bbd43ef130c","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"32e39349c0434e31","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"4b920fabf61fd6f3","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"068f3a0cd7e03112","prefixes":{"":305}}, // [Melt Tecnologia e Informatica S.A]
-  {"hash":"95cce4f80c49239f","prefixes":{"*":306}}, // [MeMo2 / Hottraffic]
-  {"hash":"7672c0e258e0a20b","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"065ac7f58737b759","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"f0c15855e3418345","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"45068fe6a5fe83c0","prefixes":{"*":308}}, // [Mercado Livre.com Atividades de Internet Ltda]
-  {"hash":"a3fbfa83663a40a6","prefixes":{"*":308}}, // [Mercado Livre.com Atividades de Internet Ltda]
-  {"hash":"5241d2ae86ff307f","prefixes":{"":309}}, // [Merchenta Limited]
-  {"hash":"7b92690c1232eb23","prefixes":{"":309}}, // [Merchenta Limited]
-  {"hash":"e5b1a15c3a7a1ee6","prefixes":{"":309}}, // [Merchenta Limited]
-  {"hash":"f0b40488d9ecd9a2","prefixes":{"":309}}, // [Merchenta Limited]
-  {"hash":"63600c9242f10b0d","prefixes":{"":309}}, // [Merchenta Limited]
-  {"hash":"e89e81c1ed314cc1","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"297f0571158ef576","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"2228e5ce36c007c1","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"798bcbf9415873df","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"ab03f3b496037843","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"eca01f0508fbf30b","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"0d839898fade319a","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"4fc010b1e52ce252","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"31e7fb81bf0ec52f","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"a6edfa074ceff9c5","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"289dc75a912dcc97","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"5a8de8926c410758","prefixes":{"":310}}, // [Metapeople GmbH]
-  {"hash":"79c798a9d8e32afc","prefixes":{"":311}}, // [MetrixLab B.V.]
-  {"hash":"61617058e6206283","prefixes":{"":311}}, // [MetrixLab B.V.]
-  {"hash":"cf945767a2fa79f3","prefixes":{"*":312}}, // [Mixpo Inc.]
-  {"hash":"541f85cbc710f2b3","prefixes":{"":313}}, // [Monsoon Ads Pvt. Ltd.]
-  {"hash":"c800e798e160fe89","prefixes":{"*":314}}, // [Monster]
-  {"hash":"775035c4c49057eb","prefixes":{"":314}}, // [Monster]
-  {"hash":"2a26221290e24a08","prefixes":{"":314}}, // [Monster]
-  {"hash":"fda966b5c6ec2b2f","prefixes":{"":314}}, // [Monster]
-  {"hash":"887d148a8ae98b2e","prefixes":{"*":315}}, // [neckermann.de GmbH]
-  {"hash":"35c76c9165e3349f","prefixes":{"*":316}}, // [Ad.agio]
-  {"hash":"d5c7d1240bf8989e","prefixes":{"":316}}, // [Ad.agio]
-  {"hash":"1e5ea56690a0716d","prefixes":{"*":316}}, // [Ad.agio]
-  {"hash":"a54661777ef51189","prefixes":{"*":317}}, // [Netmining LLC]
-  {"hash":"cc673c90c8abe830","prefixes":{"*":318}}, // [AdoTube]
-  {"hash":"5f4b0cbb95552b3f","prefixes":{"*":319}}, // [Next Audience GmbH]
-  {"hash":"a78e1096b3c03fbc","prefixes":{"":319}}, // [Next Audience GmbH]
-  {"hash":"582d973b69391ebe","prefixes":{"":319}}, // [Next Audience GmbH]
-  {"hash":"18585076a5b0c6dd","prefixes":{"":319}}, // [Next Audience GmbH]
-  {"hash":"1df4ee86fc680406","prefixes":{"":319}}, // [Next Audience GmbH]
-  {"hash":"ecd80a6a46f6a1ce","prefixes":{"":319}}, // [Next Audience GmbH]
-  {"hash":"8ee876aaaaf537e0","prefixes":{"":319}}, // [Next Audience GmbH]
-  {"hash":"92bc4f011133f05a","prefixes":{"*":320}}, // [Nextperf]
-  {"hash":"b10d35d6cde76082","prefixes":{"*":320}}, // [Nextperf]
-  {"hash":"8e6e5d6dc4720f98","prefixes":{"":320}}, // [Nextperf]
-  {"hash":"edc7f4e87a8ea4a3","prefixes":{"":320}}, // [Nextperf]
-  {"hash":"f0c76e07985c56c5","prefixes":{"":320}}, // [Nextperf]
-  {"hash":"cff1b3137482e5e3","prefixes":{"":320}}, // [Nextperf]
-  {"hash":"33f28c5ebbd4525e","prefixes":{"":320}}, // [Nextperf]
-  {"hash":"849c8324d4c32ea5","prefixes":{"*":321}}, // [Calibex]
-  {"hash":"0bbcc61ed60a63c7","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"7da7b69cf130f867","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"524bf7ee34882325","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"0fc0858e8d42a096","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"94d1d06666f458b2","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"9515f9226eae0ee6","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"c610850a50287c6c","prefixes":{"":322}}, // [ViziAds for Advertisers]
-  {"hash":"1324d12fd047205a","prefixes":{"":322}}, // [ViziAds for Advertisers]
-  {"hash":"922df75b11e4bdb8","prefixes":{"":322}}, // [ViziAds for Advertisers]
-  {"hash":"94be9a0ad636acc1","prefixes":{"":322}}, // [ViziAds for Advertisers]
-  {"hash":"921f858655989bdb","prefixes":{"":322}}, // [ViziAds for Advertisers]
-  {"hash":"0f44f6f2024007e3","prefixes":{"":323}}, // [FinanceGenerator]
-  {"hash":"c5d545736ea3f40c","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"c5190fb3c11efd5c","prefixes":{"":324}}, // [Telstra Corporation]
-  {"hash":"f8e19bba6ecb9d4d","prefixes":{"":324}}, // [Telstra Corporation]
-  {"hash":"78cb9e34e18a70c6","prefixes":{"":324}}, // [Telstra Corporation]
-  {"hash":"555b77a6dbc1077b","prefixes":{"":324}}, // [Telstra Corporation]
-  {"hash":"04cd318d8c9e0aa1","prefixes":{"":325}}, // [The Online Research Unit]
-  {"hash":"44b28a9d35489468","prefixes":{"":326}}, // [Webling Pty Ltd]
-  {"hash":"ce2a97a2bc3975b0","prefixes":{"*":327}}, // [Lasoo Pty Ltd]
-  {"hash":"70c03e717046730c","prefixes":{"":327}}, // [Lasoo Pty Ltd]
-  {"hash":"a1956c55f379362a","prefixes":{"":327}}, // [Lasoo Pty Ltd]
-  {"hash":"78761e0920b86d00","prefixes":{"":327}}, // [Lasoo Pty Ltd]
-  {"hash":"fb49a17ebf575b4b","prefixes":{"":327}}, // [Lasoo Pty Ltd]
-  {"hash":"3ba767e322876167","prefixes":{"":327}}, // [Lasoo Pty Ltd]
-  {"hash":"db60b4edeb07e6e0","prefixes":{"*":328}}, // [Salefinder Ltd.]
-  {"hash":"1a2b2619e15f81ed","prefixes":{"":329}}, // [The Monkeys Pty Ltd]
-  {"hash":"d33c5423234580d2","prefixes":{"":330}}, // [Louder Digital Pty Ltd]
-  {"hash":"35c305dfff8e956a","prefixes":{"":331}}, // [Publisher’s Internationale Pty Ltd]
-  {"hash":"ab95fd39f34e1919","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"e394eac0c09e952a","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"d754759cedf098a4","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"469abb509832dcba","prefixes":{"":7}}, // [Wize Commerce, Inc.]
-  {"hash":"089ade7154cdafd2","prefixes":{"":7}}, // [Wize Commerce, Inc.]
-  {"hash":"7c4e77c7146bc27c","prefixes":{"":7}}, // [Wize Commerce, Inc.]
-  {"hash":"27943a61af56578c","prefixes":{"":7}}, // [Wize Commerce, Inc.]
-  {"hash":"5b9d47d01e06e207","prefixes":{"":7}}, // [Wize Commerce, Inc.]
-  {"hash":"efae037999b8354a","prefixes":{"":7}}, // [Wize Commerce, Inc.]
-  {"hash":"64b1c22f19588e65","prefixes":{"*":7}}, // [Wize Commerce, Inc.]
-  {"hash":"1b500703c376dccf","prefixes":{"":332}}, // [NowSpots]
-  {"hash":"0b8a5111da2a18e6","prefixes":{"":332}}, // [NowSpots]
-  {"hash":"6cbd63b4b5a258e2","prefixes":{"":333}}, // [Ocapi]
-  {"hash":"2ecb3e4de562d83f","prefixes":{"*":334}}, // [Predicta]
-  {"hash":"b0032d1f28de6b8e","prefixes":{"*":334}}, // [Predicta]
-  {"hash":"495b10f97369710c","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"07b876ce04abdfc9","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"bd1d888d58054387","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"deb9a6a0e78770f8","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"3d9897472cebdff7","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"a036e7b2680b1720","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"ae8e27c2a1195c9d","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"685a4ece024544f3","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"d705e49e2ecfc500","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"4fd0a4a032a34191","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"2640f60d445d4d0d","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"0067af133fbf162f","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"62e23e8e0a53b097","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"57643f79e10fdc91","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"fe70aef371b87e0d","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"c80b88907c4da662","prefixes":{"":335}}, // [Comune SA]
-  {"hash":"3c027bef12167411","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"9e7ef06636d0b122","prefixes":{"":337}}, // [Hotwords Informação LTDA]
-  {"hash":"ac577d2ba001c2f9","prefixes":{"":337}}, // [Hotwords Informação LTDA]
-  {"hash":"8baa23f77cec98d3","prefixes":{"":337}}, // [Hotwords Informação LTDA]
-  {"hash":"86e7352358e7a0a1","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"461a9aacd5db8b62","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"4523c8dd39cb10d8","prefixes":{"":338}}, // [uMotion]
-  {"hash":"a7eaf4ae4152200d","prefixes":{"":338}}, // [uMotion]
-  {"hash":"1874ed5aa610db51","prefixes":{"*":339}}, // [Google Zoo]
-  {"hash":"0dc9eb6c8b1c77fa","prefixes":{"*":35}}, // [Oggifinogi]
-  {"hash":"60d67cd6819e7de4","prefixes":{"*":340}}, // [Audience Manager]
-  {"hash":"2ae524eac16b06f8","prefixes":{"":341}}, // [ONDCP]
-  {"hash":"8210c1a27bdc1916","prefixes":{"*":143}}, // [Edgesuite]
-  {"hash":"ca8cb9c623002dc9","prefixes":{"*":143}}, // [Edgesuite]
-  {"hash":"3ba6cc7216a7d5ae","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"24267a212835b827","prefixes":{"*":143}}, // [Edgesuite]
-  {"hash":"060ee4c312a8e977","prefixes":{"":342}}, // [LOKA Research inc.]
-  {"hash":"c7e974006ec125b7","prefixes":{"*":343}}, // [OpenX OnRamp]
-  {"hash":"a985fc121086ead8","prefixes":{"*":344}}, // [OpenX Ad Server]
-  {"hash":"402ca9fbb308a1c5","prefixes":{"*":36}}, // [PaperG]
-  {"hash":"53f1cd9b06aea643","prefixes":{"*":36}}, // [PaperG]
-  {"hash":"36b3ccfb92c2fb71","prefixes":{"*":345}}, // [Parship]
-  {"hash":"28832d626c0b0925","prefixes":{"*":346}}, // [pauldirekt GmbH]
-  {"hash":"1d474301c170499d","prefixes":{"*":347}}, // [Pictela Inc.]
-  {"hash":"fd1aa96507b2bf44","prefixes":{"":347}}, // [Pictela Inc.]
-  {"hash":"7f890c0fd0c6a4d9","prefixes":{"":348}}, // [Pilot 1/0 GmbH & Co KG]
-  {"hash":"549e294957d756d8","prefixes":{"":348}}, // [Pilot 1/0 GmbH & Co KG]
-  {"hash":"5dc046f77f32adf1","prefixes":{"*":349}}, // [Piximedia]
-  {"hash":"637b449ba51266a3","prefixes":{"*":349}}, // [Piximedia]
-  {"hash":"013ba3dd6b18ee4a","prefixes":{"*":350}}, // [Pointroll]
-  {"hash":"d96024cf9bafa9d0","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"4f0c9093d18b4ecd","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"d63f961e0c8cc056","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"1bcfb023adee2b08","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"6ed6fb838bd994d7","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"9fd07c030d45578d","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"5370f7b026779f44","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"c367910d58376fa0","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"670926f337b85492","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"77d7124c8aa87819","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"3726ef9236aeff59","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"84078980dc7d0310","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"496666ed92d32be6","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"3e8a19db4e7dd91a","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"33cfdc955bd4ab90","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"543046798ae8e38d","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"54537a7d4ce6fc35","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"242ab5d44fae500c","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"e81d4aa82d04d068","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"7c7f55d8a75cb9bc","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"e4a82caa59141478","prefixes":{"":351}}, // [Beijing PinYou Interactive Information Technology]
-  {"hash":"caf06dc269e4cbd7","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"70584cd7bcb88744","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"c9cabfef49bb4ec1","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"993089a2d306632e","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"cf04aaaa5ae5f383","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"a1cd6a668ae89bc8","prefixes":{"*":353}}, // [AdMaster]
-  {"hash":"f72dd5293eba3ca3","prefixes":{"":353}}, // [AdMaster]
-  {"hash":"e946e6b718e0e81a","prefixes":{"":353}}, // [AdMaster]
-  {"hash":"01b5e469f3b6d1d9","prefixes":{"":354}}, // [D.A.Consortium Beijing (Platform One China)]
-  {"hash":"f091b3175305cced","prefixes":{"":354}}, // [D.A.Consortium Beijing (Platform One China)]
-  {"hash":"1a095d1901f0940b","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"f66f99ee20105c2c","prefixes":{"*":356}}, // [PurposeLab]
-  {"hash":"86c250cf0da31481","prefixes":{"":356}}, // [PurposeLab]
-  {"hash":"8f204c79d6b23736","prefixes":{"*":334}}, // [Predicta]
-  {"hash":"43d06db6d6527876","prefixes":{"":357}}, // [Proclivity Systems]
-  {"hash":"5f76990173953807","prefixes":{"":357}}, // [Proclivity Systems]
-  {"hash":"7d3947ee9533bf30","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"fb241396adc3ebde","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"b8c5f46fb8945332","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"ade9cbc2becb390f","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"874cfa4e9fe27233","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"2cd6bee614e910f1","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"854f37cd1f444e62","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"19a83c7a2b673a6d","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"ca312e078723d178","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"4aa2d41fa2878d8f","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"8931cc3c2d6bbbff","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"e67e88dcc0afe050","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"3f6c08baf48fa0ae","prefixes":{"":37}}, // [Public-Idées]
-  {"hash":"6303a58061eaabd1","prefixes":{"*":358}}, // [Viewbix]
-  {"hash":"4fdc8f2ff122ce2e","prefixes":{"":358}}, // [Viewbix]
-  {"hash":"ba78a984ad7a8c06","prefixes":{"":358}}, // [Viewbix]
-  {"hash":"00885ce869b93eab","prefixes":{"":358}}, // [Viewbix]
-  {"hash":"eb59f3a64b415670","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"243c70f61da9731c","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"ed6b204d6b8f351e","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"e6888b5be4ecca23","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"8034327c12c77172","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"d48f950e0036e4ee","prefixes":{"*":360}}, // [QuinStreet]
-  {"hash":"6118e4e0e4001349","prefixes":{"*":361}}, // [Quisma GmbH]
-  {"hash":"1b2f3dadf0889c1c","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"491acc9692437dcc","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"95be38e789f1c074","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"7d13c9a93867cfd5","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"aee8b719a85b0392","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"03c0d3572439e910","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"42c10737e9d2eb44","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"1ece70926dbb1e9c","prefixes":{"*":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"15b1b56db686d6b8","prefixes":{"":362}}, // [Quismatch / Quisma Tracker]
-  {"hash":"6f2fb017c596785a","prefixes":{"*":363}}, // [Qwobl Inc.]
-  {"hash":"45bd1c4bac827eb4","prefixes":{"*":364}}, // [RadiumOne Inc.]
-  {"hash":"a4cc28a873663be4","prefixes":{"*":365}}, // [Core Audience, Inc]
-  {"hash":"b1b347108c9875ae","prefixes":{"*":366}}, // [The Reach Group]
-  {"hash":"9680c32132a31294","prefixes":{"":367}}, // [revenue cloud]
-  {"hash":"4654f1b3d29f0a2a","prefixes":{"":367}}, // [revenue cloud]
-  {"hash":"c8daf5a2befc762c","prefixes":{"":367}}, // [revenue cloud]
-  {"hash":"cd7c04dcaab54cf3","prefixes":{"":366}}, // [The Reach Group]
-  {"hash":"6a7ac3b20a8267da","prefixes":{"*":368}}, // [Register.it]
-  {"hash":"24064a7ef37c0464","prefixes":{"":369}}, // [ReleStar]
-  {"hash":"28a4e40561f9acae","prefixes":{"":369}}, // [ReleStar]
-  {"hash":"3de1987cea55e4a5","prefixes":{"":369}}, // [ReleStar]
-  {"hash":"827fd98c61df481c","prefixes":{"":369}}, // [ReleStar]
-  {"hash":"eec1a8a2a7fb129b","prefixes":{"":369}}, // [ReleStar]
-  {"hash":"6c1b7209cced7033","prefixes":{"*":370}}, // [Research Horizons LLC dba Phoenix Marketing]
-  {"hash":"c946c0fe5eecd55f","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"2feb43f5f97da585","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"4847977384b78f1d","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"308241d0fe4d6897","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"2cb30990aa0823eb","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"2c25ebde178886b1","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"d4eeb4a4736e8358","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"12498108d00bd104","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"c7437019688a5c87","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"ebc599442a1e60e0","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"ab9c2a8a5ed26375","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"c9473e1a1e9213bc","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"a15bca05fb29201f","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"8c2336c1a87e9c7e","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"67f7079b53ce160f","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"a07c7ea743bca71c","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"ce0849726cb792fb","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"6d2feeb6316bf983","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"056132328ebc8a3b","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"c0dd251eb151bbdd","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"02e6b230a73d95aa","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"62cef89124c9831e","prefixes":{"*":8}}, // [Research Now Limited]
-  {"hash":"1bb2fad94e9dfd9e","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"0bca341ab2881187","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"fb725c5783121bc4","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"6d442fcb13dbd9da","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"6020c585ae546ba6","prefixes":{"":8}}, // [Research Now Limited]
-  {"hash":"bf994d767fc23e27","prefixes":{"":371}}, // [Retention Media Inc.]
-  {"hash":"5c801bba74bf0884","prefixes":{"":372}}, // [Suite 66]
-  {"hash":"f727f4c8af36c75c","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"d0ffa461035bdf6a","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"f1381513cbb99bf4","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"2b675a4d048f6d58","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"ff9153951d29d7eb","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"9a2d88a64367054f","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"22fc5e00cc71b2ca","prefixes":{"":373}}, // [Dynamic Logic / Safecount (AdIndex)]
-  {"hash":"d680287680a3b47b","prefixes":{"*":374}}, // [BridgeTrack]
-  {"hash":"6659ffe0ec0db1a1","prefixes":{"*":375}}, // [adnanny.com GmbH]
-  {"hash":"cdef303f827a483a","prefixes":{"":375}}, // [adnanny.com GmbH]
-  {"hash":"d37d706078f5ef0e","prefixes":{"":375}}, // [adnanny.com GmbH]
-  {"hash":"cefa23f603f78274","prefixes":{"":375}}, // [adnanny.com GmbH]
-  {"hash":"9beed54a2448f091","prefixes":{"*":376}}, // [AdRoll]
-  {"hash":"131ff02cd8b2b585","prefixes":{"*":377}}, // [AdExtent]
-  {"hash":"7b03a999ce62649a","prefixes":{"*":377}}, // [AdExtent]
-  {"hash":"d888444955526bb9","prefixes":{"*":378}}, // [ShareThis Inc.]
-  {"hash":"24bedaecde8de52e","prefixes":{"*":379}}, // [Shirtinator]
-  {"hash":"b2227832d5aab97c","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"29d1a1af90fe4764","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"55d58888ac21e28e","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"15a0a565c098bb6c","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"c740f7042a936f94","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"83b6131729d98b9a","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"df61075a3761234c","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"31d664b6a0c86fc5","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"b3f1fda5ca08f66c","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"a505bd8c5fdbe348","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"ff4b6ade85c0fa47","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"55fbb05b573abfc0","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"7509d096b740a94e","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"3e05ad70e7b857f6","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"f3122b05b916b4d8","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"7df77439ca0af167","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"7b6f3b92d848f180","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"c50b3a11c75c1de2","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"42bd2bd016c36072","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"d964e110e03add5e","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"b2f31dc5aea81475","prefixes":{"":380}}, // [Simplifi Holdings Inc.]
-  {"hash":"fd3e5505c689b1bc","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"e21937d0011ae5da","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"0f5e4a0353dbf996","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"0ece74eb8682685e","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"3d8ea3f0d5d389d5","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"b5602307e99e9538","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"c13decc96884eb9a","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"b815964fd4b63ffe","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"a49f2db509757639","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"a3ff80b45a2b0087","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"b1b2c1399cbf19be","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"ba44917903f4a6c0","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"ad5130e5aa2d0bcd","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"ceb371583c3948ee","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"5d5d4fe496a7b543","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"30e80084c1e7285e","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"d1d0fc6a034973b5","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"e2814abcd5399a68","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"9d4acd34336a73d4","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"dcbf7d7841f88317","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"c19fe37a92d8a1f4","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"dd502cbc700beb03","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"a76947b64ea18232","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"75875c5fcc471f0e","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"5323dbf9f56befc9","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"fd3df839224700c5","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"dc544506e0acf31c","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"fbadeeb25ac766a9","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"f344fa72c3acea98","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"e0d1929f5490ba3c","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"150d5c444034d16f","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"63c9992c37df81e6","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"9a2f65999a2602e7","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"b13d21bc9d60e3cf","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"36778688c2c8550d","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"7764641665318d7a","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"137839bac6b52f11","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"75b17e7427d84ec0","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"f576b8f6b5698927","prefixes":{"":381}}, // [Centro DSP]
-  {"hash":"a0bef488713fd8ba","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"c4f4b5d7a3bc8772","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"652de2e0257cc6f9","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"e1eb84d2322dd53f","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"0759e6e60e23806b","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"b97f9d3a0092f5df","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"6f7d322aac5f6093","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"d6d2092af97f6672","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"700b4497422246d3","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"24758e00974c4842","prefixes":{"*":382}}, // [Smart Adserver]
-  {"hash":"229fb1e217ec3254","prefixes":{"*":382}}, // [Smart Adserver]
-  {"hash":"24f84ec66db45f3d","prefixes":{"":383}}, // [smartclip Holding AG]
-  {"hash":"7bce0d8d711753ea","prefixes":{"":383}}, // [smartclip Holding AG]
-  {"hash":"f748f5ce8e9c4b7d","prefixes":{"*":384}}, // [Snap Technologies Inc.]
-  {"hash":"c17d7dedc318749c","prefixes":{"":385}}, // [So-net Media Networks]
-  {"hash":"d3a65eea99debc9b","prefixes":{"":385}}, // [So-net Media Networks]
-  {"hash":"f28c7fc4a06bcfa7","prefixes":{"*":386}}, // [SocialMedia.com]
-  {"hash":"17591c31cbbe7cf8","prefixes":{"":387}}, // [Content to Emotion (CTE)]
-  {"hash":"7c350f8bcf5a54b9","prefixes":{"":387}}, // [Content to Emotion (CTE)]
-  {"hash":"e003938122f9ac4f","prefixes":{"":387}}, // [Content to Emotion (CTE)]
-  {"hash":"6deac101ca463319","prefixes":{"static":387}}, // [Content to Emotion (CTE)]
-  {"hash":"304e631663a87e67","prefixes":{"*":388}}, // [Sociomantic.com]
-  {"hash":"e86474f9c6ad794d","prefixes":{"":389}}, // [AdSpeed]
-  {"hash":"de0816aa39c8b153","prefixes":{"*":390}}, // [Sophus3]
-  {"hash":"df8355613a445a85","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"a72f2b989760c8dc","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"fbdc1704c28873c8","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"d4674ccaf8fb7e31","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"f184677fb7e2abca","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"e7d695bf507e45d5","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"ea3f746342f05dbf","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"96ce83a8f0d84d99","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"62c6410f3e4000d8","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"b5172a6eee01acbe","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"36f9ba3a735ea443","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"f4d96ab5c7d0f720","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"7c8204a143e83abb","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"cb5b72c4fdc90b38","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"01c1382916f7a580","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"49505fd99e787062","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"a931030a5dbd7346","prefixes":{"":9}}, // [Spartoo]
-  {"hash":"3a09b22266ba0b12","prefixes":{"*":391}}, // [Specific Media Inc.]
-  {"hash":"2136a3b6f6600ad0","prefixes":{"*":391}}, // [Specific Media Inc.]
-  {"hash":"600e429523014251","prefixes":{"*":391}}, // [Specific Media Inc.]
-  {"hash":"e8b1c9274a662ad3","prefixes":{"":392}}, // [Metrigo GmbH]
-  {"hash":"d0ffd80eda189780","prefixes":{"":392}}, // [Metrigo GmbH]
-  {"hash":"e4ab3c31faef2b98","prefixes":{"":392}}, // [Metrigo GmbH]
-  {"hash":"97db8dd1bcbc33b8","prefixes":{"*":393}}, // [SpongeCell]
-  {"hash":"363a0f26e680d077","prefixes":{"":394}}, // [SpngeCell LLC]
-  {"hash":"fbef9c1b28b0cb05","prefixes":{"*":393}}, // [SpongeCell]
-  {"hash":"2218b5ce1e656e21","prefixes":{"":395}}, // [SpotXchange]
-  {"hash":"a520f16cf6177ebd","prefixes":{"":395}}, // [SpotXchange]
-  {"hash":"cda310d3654d07a5","prefixes":{"":395}}, // [SpotXchange]
-  {"hash":"2fc5567578510af6","prefixes":{"":396}}, // [Spotxchange]
-  {"hash":"abab2d20e98c266d","prefixes":{"":395}}, // [SpotXchange]
-  {"hash":"0d78cf3b068120c3","prefixes":{"":395}}, // [SpotXchange]
-  {"hash":"6da7c1b25ca845b3","prefixes":{"":395}}, // [SpotXchange]
-  {"hash":"c824df0fb0fdf482","prefixes":{"":397}}, // [Encore Attribution Platform]
-  {"hash":"9796e014709ccbec","prefixes":{"":397}}, // [Encore Attribution Platform]
-  {"hash":"fced1a8e32fb989c","prefixes":{"*":398}}, // [Steelhouse]
-  {"hash":"314523d1c217734f","prefixes":{"*":399}}, // [Strike New Media Limited]
-  {"hash":"276a5e6003750c07","prefixes":{"*":400}}, // [Struq Limited]
-  {"hash":"e5652beb11c7fceb","prefixes":{"*":401}}, // [SundaySky Inc.]
-  {"hash":"173a426f6562928a","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"81a2745fc67a8ecf","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"0aea8cde58b4f14e","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"b73e77077b022d36","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"fcf0d2e1f5fa003b","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"361c645b41a96807","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"81df9375fed9172e","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"c1493a0cd3b358a5","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"bdedb9447527960a","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"1cb83aa94e1a92ed","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"2172731c879fab72","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"7dd683bf50ce5c95","prefixes":{"":402}}, // [Symphony Advanced Media]
-  {"hash":"aa47b70219d2ee5e","prefixes":{"*":403}}, // [TagMan Ltd.]
-  {"hash":"097edb88beda9a20","prefixes":{"":404}}, // [Taobao]
-  {"hash":"bc65fc5f46cd88c9","prefixes":{"":404}}, // [Taobao]
-  {"hash":"a4d1bf696dde4d0b","prefixes":{"":404}}, // [Taobao]
-  {"hash":"c94f9318ace953f1","prefixes":{"":404}}, // [Taobao]
-  {"hash":"9e2b38828859944c","prefixes":{"":404}}, // [Taobao]
-  {"hash":"02319fc6286418de","prefixes":{"":404}}, // [Taobao]
-  {"hash":"dacc570e07ffd91a","prefixes":{"img":404}}, // [Taobao]
-  {"hash":"e8ccbc8f652e85a2","prefixes":{"*":404}}, // [Taobao]
-  {"hash":"da1ba7cc516336c0","prefixes":{"":404}}, // [Taobao]
-  {"hash":"41035e7733acf867","prefixes":{"":405}}, // [Target.com]
-  {"hash":"0509bdf297db5010","prefixes":{"*":406}}, // [Teadma]
-  {"hash":"69925c7888575612","prefixes":{"":407}}, // [BannerConnect BV]
-  {"hash":"4d44c3cec23aea09","prefixes":{"":407}}, // [BannerConnect BV]
-  {"hash":"447ea46d0797b32f","prefixes":{"*":408}}, // [Teracent Corporation]
-  {"hash":"26ca7e33d194e46e","prefixes":{"":408}}, // [Teracent Corporation]
-  {"hash":"b49b79e2e870c3e9","prefixes":{"":408}}, // [Teracent Corporation]
-  {"hash":"3a555db76a46f881","prefixes":{"*":38}}, // [The Trade Desk Inc.]
-  {"hash":"c4684dd3ef28687a","prefixes":{"*":409}}, // [The Travelers Indemnity Company]
-  {"hash":"1c38e7ac2dcf5d58","prefixes":{"":410}}, // [Videology]
-  {"hash":"4872cdec0944a698","prefixes":{"":410}}, // [Videology]
-  {"hash":"d4e30248b2920988","prefixes":{"*":411}}, // [TNS Custom Research Inc.]
-  {"hash":"48a3c2e049507f03","prefixes":{"*":412}}, // [TrackingSoft LLC]
-  {"hash":"4c5b26902a10b85b","prefixes":{"*":412}}, // [TrackingSoft LLC]
-  {"hash":"51a48ea23568f817","prefixes":{"*":413}}, // [Tradedoubler]
-  {"hash":"14251708a577d8c0","prefixes":{"*":414}}, // [Epic Marketplace]
-  {"hash":"20f50db7213cc9ee","prefixes":{"*":415}}, // [Tribal Fusion]
-  {"hash":"37b92f46ce8d0fa5","prefixes":{"":415}}, // [Tribal Fusion]
-  {"hash":"218cac8e116dcf7a","prefixes":{"":416}}, // [Triggit]
-  {"hash":"135ee5dfe108d144","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"f6afa26369731900","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"600a58efa4b0a4fa","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"c274f6336d4a40c8","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"0476503f0fc5138a","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"f6364185e21bdfb4","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"3b746cbe2984928e","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"2966c06482ab340c","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"1320f91c88734ed7","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"49e73f2dfe503088","prefixes":{"":417}}, // [True Ultimate Standards Everywhere Inc.]
-  {"hash":"345de3574a5cef61","prefixes":{"":418}}, // [CarMax Business Services LLC]
-  {"hash":"8aba77355315b602","prefixes":{"":419}}, // [Charter Communications]
-  {"hash":"f7e3882cd37d1a5b","prefixes":{"":419}}, // [Charter Communications]
-  {"hash":"a62179d5dc8551f8","prefixes":{"":419}}, // [Charter Communications]
-  {"hash":"ac3760dc99259bf9","prefixes":{"":420}}, // [General Nutrition Centers Inc.]
-  {"hash":"e1c51fbf9b39950a","prefixes":{"":421}}, // [Hamilton Beach]
-  {"hash":"68a80c829eb9c95e","prefixes":{"":422}}, // [JacquieLawson.com]
-  {"hash":"a02b27c9af68c051","prefixes":{"":423}}, // [TruEffect]
-  {"hash":"76b54dcac102ae32","prefixes":{"":423}}, // [TruEffect]
-  {"hash":"f36743b8c729a3e5","prefixes":{"":424}}, // [American Greetings]
-  {"hash":"0d479c4b1d2026b9","prefixes":{"":425}}, // [BlueMountain]
-  {"hash":"c442eae221355ece","prefixes":{"":426}}, // [Cardstore]
-  {"hash":"1277d75c5bace94e","prefixes":{"":427}}, // [Chemistry.com]
-  {"hash":"2534adb635b0540f","prefixes":{"":428}}, // [Donald J Pliner]
-  {"hash":"6e81f110e25ceba1","prefixes":{"*":429}}, // [Gevalia]
-  {"hash":"58cb024039904795","prefixes":{"":430}}, // [GSI Media]
-  {"hash":"36b7a450ddb92a81","prefixes":{"":431}}, // [Match.com]
-  {"hash":"7f6a517c8eef7bf6","prefixes":{"":431}}, // [Match.com]
-  {"hash":"b5aa9057f4ab3a79","prefixes":{"":431}}, // [Match.com]
-  {"hash":"177eb410b9eee3c2","prefixes":{"":431}}, // [Match.com]
-  {"hash":"5a75e9cff48a157c","prefixes":{"":431}}, // [Match.com]
-  {"hash":"e561536f4b9b0f5e","prefixes":{"*":432}}, // [Optimum Response]
-  {"hash":"3aaed06dec8e119b","prefixes":{"":433}}, // [Oreck]
-  {"hash":"e7b19cb5471c10b3","prefixes":{"":434}}, // [Tassimo]
-  {"hash":"5eca8c8aa7c01b0e","prefixes":{"*":435}}, // [uSwitch]
-  {"hash":"974734b3e01eab8f","prefixes":{"*":436}}, // [TubeMogul Inc.]
-  {"hash":"9f562a308fffc5c4","prefixes":{"*":437}}, // [Tumri]
-  {"hash":"09845e50cbc70b8a","prefixes":{"*":182}}, // [AdAction]
-  {"hash":"82ae5c9a96804ec8","prefixes":{"":102}}, // [BigaBid Media Ltd.]
-  {"hash":"b91b0c7d1d3bb786","prefixes":{"":102}}, // [BigaBid Media Ltd.]
-  {"hash":"2804070c2606fca7","prefixes":{"":102}}, // [BigaBid Media Ltd.]
-  {"hash":"d601d362a989dcf9","prefixes":{"":438}}, // [iMarker]
-  {"hash":"0a0084b896887917","prefixes":{"":438}}, // [iMarker]
-  {"hash":"64596506e8398578","prefixes":{"":438}}, // [iMarker]
-  {"hash":"4af3f67573bdbad8","prefixes":{"":438}}, // [iMarker]
-  {"hash":"1348f7d07273dfcf","prefixes":{"":438}}, // [iMarker]
-  {"hash":"4329a4ad527e4779","prefixes":{"":438}}, // [iMarker]
-  {"hash":"5eca470b27725f28","prefixes":{"*":439}}, // [Turn Inc.]
-  {"hash":"83807aae08d0747f","prefixes":{"*":439}}, // [Turn Inc.]
-  {"hash":"a0542aaf969b6041","prefixes":{"*":440}}, // [Twelvefold Media]
-  {"hash":"7837c4e8623f0409","prefixes":{"":440}}, // [Twelvefold Media]
-  {"hash":"13c46ea92caeecf8","prefixes":{"":441}}, // [Tynt]
-  {"hash":"5f7c83b68361da73","prefixes":{"*":442}}, // [Unica an IBM Company]
-  {"hash":"bd242bcdc493f1d5","prefixes":{"*":443}}, // [Unicast]
-  {"hash":"58ad481190b46e2e","prefixes":{"":444}}, // [UniQlick]
-  {"hash":"7f5d2102ab11e53c","prefixes":{"":444}}, // [UniQlick]
-  {"hash":"c9dd94a27435350b","prefixes":{"":444}}, // [UniQlick]
-  {"hash":"4ba8d85cfc1bf5de","prefixes":{"*":445}}, // [United Virtualities]
-  {"hash":"0e4c474511c6dfff","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"875bbc4dbaee8734","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"58b08ddd9e3cccf9","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"356603d457828911","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"77c85cb3240da7c5","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"010912cf400592bc","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"28e6d587198883be","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"e64d00be64f97a79","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"fa0271d4d3cf41f2","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"a227d04cd3bf04f7","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"b69205c5372d2357","prefixes":{"":446}}, // [VideoHub]
-  {"hash":"da30259edef87286","prefixes":{"*":447}}, // [Visible Measures Corp.]
-  {"hash":"46ff1406588e7ceb","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"32ca2bff73328a83","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"3fc1dc351d4952c8","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"80d2379485452f29","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"35183abb3e2c864c","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"3b235045cc005d15","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"34e6561d9300f451","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"08980f63c2ca7971","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"327755ab5ee91d4e","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"c3d3383046b5690f","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"d196d3b7e439011e","prefixes":{"":192}}, // [Nielsen OBE (Vizu)]
-  {"hash":"09582bb8c4f0bdcd","prefixes":{"*":448}}, // [Vizury Interactive Solutions Pvt. Ltd.]
-  {"hash":"ccbe4ed34be8ea01","prefixes":{"":449}}, // [Markit On Demand (Adhesion)]
-  {"hash":"5c0c23d6d5b2aa7d","prefixes":{"":449}}, // [Markit On Demand (Adhesion)]
-  {"hash":"6fe5393d68aec474","prefixes":{"":449}}, // [Markit On Demand (Adhesion)]
-  {"hash":"24de99047e3e2592","prefixes":{"":449}}, // [Markit On Demand (Adhesion)]
-  {"hash":"a1d810c22ef4c8c1","prefixes":{"":449}}, // [Markit On Demand (Adhesion)]
-  {"hash":"a961c235191ccc5c","prefixes":{"":449}}, // [Markit On Demand (Adhesion)]
-  {"hash":"30327e228a69909d","prefixes":{"":450}}, // [WebMetro Inc]
-  {"hash":"1440114026d0b8a7","prefixes":{"*":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"178b8b7280deb93c","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"8398687ebe990cf1","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"5cad65c27ef8d2b4","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"f28574a110053221","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"64eae6bdfc8cc1be","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"36b0c30f5f967ffd","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"10c282544a39807b","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"ce2ed22191804ffa","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"bd56114f26a64020","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"54e283b8884709c3","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"313822ab7be9585a","prefixes":{"":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"d54943c8060334b5","prefixes":{"":452}}, // [Weborama Campaign Manager]
-  {"hash":"7928274bf854b28b","prefixes":{"*":451}}, // [Weborama Campaign Manager (former name AdPerf)]
-  {"hash":"80415fbb74db7704","prefixes":{"":453}}, // [Shopping Network]
-  {"hash":"0840f634995e25fb","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"5fd40859cc837b00","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"c58731043a973263","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"ee286fbf0440d595","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"660d555331a8be68","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"c412040c18d978ce","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"667b34ab71cb2381","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"b888d9e69003de82","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"38dafaa727179ef7","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"78da2db9d3a51f98","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"94a731a76dd26bfc","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"c4ca9b6aebf488dc","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"0a42e116235fec6e","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"ac4d0bcf3017cc3d","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"6653125411676c31","prefixes":{"":454}}, // [Shanghai WiseMedia Technology Co. Ltd.]
-  {"hash":"062b10abe02277c1","prefixes":{"":455}}, // [XA.net]
-  {"hash":"b0e3a57e8f415aec","prefixes":{"":455}}, // [XA.net]
-  {"hash":"6e1bb44d175a20af","prefixes":{"":455}}, // [XA.net]
-  {"hash":"34984bab025a1372","prefixes":{"":455}}, // [XA.net]
-  {"hash":"d9eb2f654e80ebc6","prefixes":{"*":456}}, // [Xaxis LLC]
-  {"hash":"b86d63843110e02a","prefixes":{"*":457}}, // [Net Edge]
-  {"hash":"8b526a29c7f2b3dc","prefixes":{"*":458}}, // [Xplusone Solutions Inc.]
-  {"hash":"fe0ea2a1c212cfde","prefixes":{"":459}}, // [Yahoo! Ad Exchange]
-  {"hash":"dc06a1403eb499df","prefixes":{"":459}}, // [Yahoo! Ad Exchange]
-  {"hash":"5a36dbbd382aa12c","prefixes":{"":459}}, // [Yahoo! Ad Exchange]
-  {"hash":"c8fd15f0a5fc19aa","prefixes":{"":459}}, // [Yahoo! Ad Exchange]
-  {"hash":"ce63a8ab511ec5bb","prefixes":{"":459}}, // [Yahoo! Ad Exchange]
-  {"hash":"a6d2abe55f73bc22","prefixes":{"":460}}, // [Yahoo Ad Manager Plus]
-  {"hash":"707a11e6dcfa57db","prefixes":{"":460}}, // [Yahoo Ad Manager Plus]
-  {"hash":"f75439bd7693fa84","prefixes":{"":460}}, // [Yahoo Ad Manager Plus]
-  {"hash":"2f7feb27a1b93524","prefixes":{"":460}}, // [Yahoo Ad Manager Plus]
-  {"hash":"f801c9750710d30a","prefixes":{"":460}}, // [Yahoo Ad Manager Plus]
-  {"hash":"9b96f7700d727da9","prefixes":{"":461}}, // [APT from Yahoo!]
-  {"hash":"e4de2f3b2c06e193","prefixes":{"":461}}, // [APT from Yahoo!]
-  {"hash":"21aa62a45ef75fb2","prefixes":{"*":462}}, // [Yieldr]
-  {"hash":"85bf1ed3ee6ee615","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"2cf45ce27d0b73c2","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"e8595ade1fd26e2f","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"5660279fe13cfe3b","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"ad26a995ee586915","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"23412da5a5a538cc","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"6b333dd78d119434","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"f3621ca5777d61d5","prefixes":{"":462}}, // [Yieldr]
-  {"hash":"cafa71178e1de4db","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"2ca490afaa90c2b3","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"8f0dd7539cf77aa5","prefixes":{"":352}}, // [YoYi Interactive]
-  {"hash":"005700973b435023","prefixes":{"":463}}, // [YuMe Inc.]
-  {"hash":"bd83427751c351a9","prefixes":{"":463}}, // [YuMe Inc.]
-  {"hash":"e504ebfcb6b2722e","prefixes":{"":463}}, // [YuMe Inc.]
-  {"hash":"8080438b5792b260","prefixes":{"":464}}, // [Ebuzzing]
-  {"hash":"274889e98fbfc776","prefixes":{"":464}}, // [Ebuzzing]
-  {"hash":"b62ee5e77fde7ec7","prefixes":{"":464}}, // [Ebuzzing]
-  {"hash":"cc6a7a565374c257","prefixes":{"":464}}, // [Ebuzzing]
-  {"hash":"e02936a6a6a2cb94","prefixes":{"":465}}, // [Ziff Davis]
-  {"hash":"223b94a95f6849cf","prefixes":{"":465}}, // [Ziff Davis]
-  {"hash":"a8742ddae80b031b","prefixes":{"":466}}, // [DataPoint Media Inc.]
-  {"hash":"fd4a16bf59718107","prefixes":{"":467}}, // [Simplytics Limited]
-  {"hash":"a3d523521bc4ba12","prefixes":{"":467}}, // [Simplytics Limited]
-  {"hash":"9da8a1153308d7f2","prefixes":{"":468}}, // [Makazi]
-  {"hash":"d9cc216c8d482336","prefixes":{"":468}}, // [Makazi]
-  {"hash":"166c65d7776be9f8","prefixes":{"":468}}, // [Makazi]
-  {"hash":"55f15e5b7746999f","prefixes":{"":468}}, // [Makazi]
-  {"hash":"213194bd445e551d","prefixes":{"":468}}, // [Makazi]
-  {"hash":"31406bff4dc35eea","prefixes":{"":468}}, // [Makazi]
-  {"hash":"ea9607b28f4238c2","prefixes":{"":468}}, // [Makazi]
-  {"hash":"707d5310f27d0dd2","prefixes":{"":469}}, // [Rich Relevance]
-  {"hash":"59fa19b8a48477fe","prefixes":{"":470}}, // [MainADV]
-  {"hash":"efb9b464f6ebaa1d","prefixes":{"":470}}, // [MainADV]
-  {"hash":"8848350bd85fffe4","prefixes":{"":470}}, // [MainADV]
-  {"hash":"519275c83a5a1c92","prefixes":{"":470}}, // [MainADV]
-  {"hash":"fc92bec8fbcb03ef","prefixes":{"":470}}, // [MainADV]
-  {"hash":"91fa39bc27e156b4","prefixes":{"":470}}, // [MainADV]
-  {"hash":"408d55e8995335ad","prefixes":{"":470}}, // [MainADV]
-  {"hash":"d0efa7323c77b1a5","prefixes":{"":470}}, // [MainADV]
-  {"hash":"baa5cf88a0176bc6","prefixes":{"":471}}, // [MediaV Advertising]
-  {"hash":"3ea0854e74c32c87","prefixes":{"":471}}, // [MediaV Advertising]
-  {"hash":"88a70c2ebfe38ffe","prefixes":{"":471}}, // [MediaV Advertising]
-  {"hash":"dc0b1dfe6de6a967","prefixes":{"":471}}, // [MediaV Advertising]
-  {"hash":"cb234228af27fa32","prefixes":{"":471}}, // [MediaV Advertising]
-  {"hash":"c7abee58863b27a4","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"7e34b0d37ded49ed","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"d7255d3135b0294d","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"e21264db24be060c","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"466676eb4c2066ac","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"2505a55ead3f2266","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"e97b9e2d31ac962d","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"906215055f6880fa","prefixes":{"":472}}, // [MicroAd Inc.]
-  {"hash":"df04046f11aea628","prefixes":{"*":473}}, // [Platform ID Inc.]
-  {"hash":"9fe8e93d55562003","prefixes":{"":474}}, // [Xrost]
-  {"hash":"6b29d401833f79d8","prefixes":{"":473}}, // [Platform ID Inc.]
-  {"hash":"00928c6f847a4785","prefixes":{"":475}}, // [Sociocast Networks LLC D/B/A Velos]
-  {"hash":"c3964f299adbe862","prefixes":{"":476}}, // [Trend Research]
-  {"hash":"76b5ddb10f769c6b","prefixes":{"*":248}}, // [AdOcean Ltd]
-  {"hash":"f52edd3926705507","prefixes":{"":477}}, // [Black Swan Verification]
-  {"hash":"d63e38f4eba51f77","prefixes":{"":478}}, // [Momentum K.K]
-  {"hash":"6c0f8db03b28099b","prefixes":{"":477}}, // [Black Swan Verification]
-  {"hash":"248772911542d550","prefixes":{"*":479}}, // [Betgenius Limited]
-  {"hash":"38a72a4924027d8f","prefixes":{"*":480}}, // [AT Internet]
-  {"hash":"255b63d169bd9d10","prefixes":{"*":480}}, // [AT Internet]
-  {"hash":"3a7fbbad166769ad","prefixes":{"":481}}, // [DataLab]
-  {"hash":"fe64230a84967d3c","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"a91296d609efe0b4","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"947fa5564eccc0b2","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"89a64fe46687237f","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"ce1cd4220063df2d","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"1c489f83a79301c6","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"9dc25ef9b3ed3e5d","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"9898ab0c57d683ae","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"0229fe19979f88b0","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"6dedd3fca4d243ac","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"cbc23a15e9f02987","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"95119cbc05f9e42a","prefixes":{"":482}}, // [Innovid Inc.]
-  {"hash":"784647d3eb0236dc","prefixes":{"*":483}}, // [Adacado]
-  {"hash":"4be5d3939998bc39","prefixes":{"":483}}, // [Adacado]
-  {"hash":"cec4d2059bbb1365","prefixes":{"*":484}}, // [NetDNA, LLC]
-  {"hash":"87a9bf2f660b2673","prefixes":{"":478}}, // [Momentum K.K]
-  {"hash":"33f6a4c9eb1313f6","prefixes":{"":478}}, // [Momentum K.K]
-  {"hash":"38afcf5464d4a46e","prefixes":{"":478}}, // [Momentum K.K]
-  {"hash":"4a13b10532de4033","prefixes":{"*":485}}, // [Pipewave Inc.]
-  {"hash":"a703750c918980b9","prefixes":{"":486}}, // [US Media Consulting]
-  {"hash":"77b351109047edb2","prefixes":{"":487}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"f9f554c96902397e","prefixes":{"":487}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"e8f2c7f5eb75983e","prefixes":{"":487}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"f8680fe819857e65","prefixes":{"image":487}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"fe12b35f78c433a6","prefixes":{"":487}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
-  {"hash":"531f5c369a189473","prefixes":{"":488}}, // [Hanesbrands Direct LLC]
-  {"hash":"4bfbc25da5ec8116","prefixes":{"":489}}, // [A1platform]
-  {"hash":"56cea5c2b408989a","prefixes":{"*":10}}, // [eBay]
-  {"hash":"2c24b521f38d28dd","prefixes":{"":10}}, // [eBay]
-  {"hash":"d6449351ee8e33eb","prefixes":{"*":490}}, // [Agency.com]
-  {"hash":"5e040f7b958d9ee5","prefixes":{"*":10}}, // [eBay]
-  {"hash":"379ed8ab1690a74c","prefixes":{"":10}}, // [eBay]
-  {"hash":"6ed4dac9c333ef4b","prefixes":{"*":10}}, // [eBay]
-  {"hash":"b4a9e54654a6de08","prefixes":{"*":10}}, // [eBay]
-  {"hash":"687aa30619ec8e7f","prefixes":{"*":10}}, // [eBay]
-  {"hash":"5ac823af612c4492","prefixes":{"*":10}}, // [eBay]
-  {"hash":"ce4e70466c43ade3","prefixes":{"*":10}}, // [eBay]
-  {"hash":"c865cf822ab64a71","prefixes":{"*":10}}, // [eBay]
-  {"hash":"083c339aac7e418c","prefixes":{"*":10}}, // [eBay]
-  {"hash":"8d689bf60029c98f","prefixes":{"*":10}}, // [eBay]
-  {"hash":"19d0e1eba389dfe1","prefixes":{"*":10}}, // [eBay]
-  {"hash":"b789395149868329","prefixes":{"*":10}}, // [eBay]
-  {"hash":"25e9f5191f3d2397","prefixes":{"*":10}}, // [eBay]
-  {"hash":"82a743999425aaad","prefixes":{"*":10}}, // [eBay]
-  {"hash":"97a729e5b41fd4ed","prefixes":{"*":10}}, // [eBay]
-  {"hash":"0db7dee9d3c756cc","prefixes":{"*":10}}, // [eBay]
-  {"hash":"10981271cb66af25","prefixes":{"*":10}}, // [eBay]
-  {"hash":"8c86bc9ba67482c6","prefixes":{"*":10}}, // [eBay]
-  {"hash":"d36efad270e3e7c6","prefixes":{"*":10}}, // [eBay]
-  {"hash":"b709ca3f38e77645","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"3cba207e4aa9d6c6","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"fd8da92d6de2518b","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"d9e4d4444ebd418f","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"4c1c4999d1501943","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"a635762b8125bba5","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"99818fe6fd4c4a9c","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"cae59de4e054a5a8","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"d1ec771fe9489a9f","prefixes":{"":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"d9effad74da2b097","prefixes":{"*":491}}, // [Adap.tv Inc. (AdWords/YouTube)]
-  {"hash":"46b1fc5fe9da3681","prefixes":{"*":492}}, // [Fjord Technologies S.A.S.]
-  {"hash":"e0b6d05a8e75e14a","prefixes":{"*":492}}, // [Fjord Technologies S.A.S.]
-  {"hash":"11a89bdf6bc5cf28","prefixes":{"":493}}, // [Refined Ads]
-  {"hash":"8e6414939f586d4c","prefixes":{"":493}}, // [Refined Ads]
-  {"hash":"6462a1b97a382278","prefixes":{"":493}}, // [Refined Ads]
-  {"hash":"9f99479854cea2e7","prefixes":{"":493}}, // [Refined Ads]
-  {"hash":"72b40aacd2b4e226","prefixes":{"":493}}, // [Refined Ads]
-  {"hash":"67401ef133d2ed76","prefixes":{"":494}}, // [nugg.ad AG]
-  {"hash":"696757eb9e07845f","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"c84660fcf8a4c99c","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"df10c5e0e18fda2b","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"c71dfe726124b24c","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"f603a3b56996fe4c","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"149593d24f74e3e1","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"a1b9a8ff7b829f8f","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"37cb27fb57319c52","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"16e50e7e7b499ab7","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"c10f5df1adb6160f","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"df3ea734f608dc0d","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"3014b8652e4fd340","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"68034e41a59505be","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"4ff550d2f5a384d7","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"266c6cb54cc8f810","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"c174c4c7c469cbb9","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"19b8f26cb5987d86","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"0301de7ebef3ded7","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"5f6ccacecc90b6ab","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"cee43a3e7001e664","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"27d64efa61e9fb8c","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"05eae7c7a976d6b2","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"da375ad9bc86ad05","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"1a62d22c13d4f003","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"65f8018fc9a58ba7","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"c790c87ca2abbb6c","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"5aefca188560242d","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"eaa7adee1317cb7d","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"db5afb1288bacbff","prefixes":{"*":496}}, // [Meetrics GmbH]
-  {"hash":"7d618e8de39f548c","prefixes":{"*":496}}, // [Meetrics GmbH]
-  {"hash":"b5c30978f10b1f56","prefixes":{"s":496,"":497}}, // [Meetrics GmbH] [Meetrics]
-  {"hash":"5c4a10a5bc0897c7","prefixes":{"":498}}, // [Digital Control GmbH & Co. KG]
-  {"hash":"38d57267aeada6cc","prefixes":{"":498}}, // [Digital Control GmbH & Co. KG]
-  {"hash":"7dc82de98d234295","prefixes":{"":499}}, // [Dedicated Media]
-  {"hash":"98cac3ed2db221c5","prefixes":{"":499}}, // [Dedicated Media]
-  {"hash":"74da617dd78c4c25","prefixes":{"":499}}, // [Dedicated Media]
-  {"hash":"ad829d4fccaec076","prefixes":{"":499}}, // [Dedicated Media]
-  {"hash":"93214296470961ea","prefixes":{"":500}}, // [Accuen]
-  {"hash":"fb8e16c2a3413e04","prefixes":{"*":501}}, // [Pulse 360, Inc.]
-  {"hash":"56de3497c2b187f9","prefixes":{"*":501}}, // [Pulse 360, Inc.]
-  {"hash":"1763cb8cd4ecb455","prefixes":{"*":502}}, // [ZANOX AG]
-  {"hash":"dd420134fd0b31f7","prefixes":{"*":502}}, // [ZANOX AG]
-  {"hash":"f942b375b4c9d301","prefixes":{"":503}}, // [Webgains Ltd]
-  {"hash":"03b41741559a5775","prefixes":{"":504}}, // [Virgin Media Limited]
-  {"hash":"e01702c3ace07a42","prefixes":{"*":505}}, // [MyBuys MyAds]
-  {"hash":"a09aa03b7ab4a6a0","prefixes":{"*":506}}, // [VCCP Search LTD]
-  {"hash":"8ae53030752d70fd","prefixes":{"":507}}, // [Conversant Media]
-  {"hash":"3f911ef887ffe5a7","prefixes":{"":507}}, // [Conversant Media]
-  {"hash":"dd0195d7ab665db3","prefixes":{"":507}}, // [Conversant Media]
-  {"hash":"6ac275e8e99e5fb3","prefixes":{"":507}}, // [Conversant Media]
-  {"hash":"5960f055d64bd6fb","prefixes":{"":507}}, // [Conversant Media]
-  {"hash":"d07a0c93a2f5da33","prefixes":{"":507}}, // [Conversant Media]
-  {"hash":"b7e7f7ab4a600ced","prefixes":{"":508}}, // [Up-Value GmbH & Co. KG]
-  {"hash":"e92a06c68de2a79d","prefixes":{"":509}}, // [Unruly Media]
-  {"hash":"789659215cb1620d","prefixes":{"":509}}, // [Unruly Media]
-  {"hash":"b61a48cd46cb7b06","prefixes":{"*":510}}, // [Underdog Media LLC]
-  {"hash":"eea5fa46bce35e24","prefixes":{"":511}}, // [SVG Media Pvt. Ltd.]
-  {"hash":"9b346c0d77f1fcf2","prefixes":{"*":512}}, // [TRAFFIQ LLC]
-  {"hash":"51324f52aa5eb734","prefixes":{"*":513}}, // [TellApart Inc.]
-  {"hash":"26e3ca8cc9a6afd8","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"2e9a57a3dcc61e3e","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"2e6202e113ae62e3","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"9a1d6d8445e2cce9","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"88015c5982735097","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"9cf10e72a2db48a9","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"cf5ba41c477d8aa5","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"fe50c8a7f665cf78","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"5c9fb160269ccb5c","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"366f4f435bfb9255","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"5dde0b5371aae6bb","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"ebd682e181b553a7","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"df61db1cec60b5a1","prefixes":{"":513}}, // [TellApart Inc.]
-  {"hash":"bdf8043c482f8afd","prefixes":{"*":514}}, // [Shopzilla Inc.]
-  {"hash":"83ce758172dc68fb","prefixes":{"*":514}}, // [Shopzilla Inc.]
-  {"hash":"45cc9e8ea0e405cc","prefixes":{"*":514}}, // [Shopzilla Inc.]
-  {"hash":"bc8d543772676fe4","prefixes":{"*":514}}, // [Shopzilla Inc.]
-  {"hash":"6a51a8a28265901e","prefixes":{"*":515}}, // [Reactivpub]
-  {"hash":"b03903f1abac9b82","prefixes":{"*":515}}, // [Reactivpub]
-  {"hash":"14281bd870fa9e85","prefixes":{"*":515}}, // [Reactivpub]
-  {"hash":"52c9dfb471edf4de","prefixes":{"*":515}}, // [Reactivpub]
-  {"hash":"b9cf807aee694b90","prefixes":{"*":516}}, // [Netseer Inc.]
-  {"hash":"720c7cdaeb3d3edf","prefixes":{"":516}}, // [Netseer Inc.]
-  {"hash":"a7e82477ddc48f23","prefixes":{"*":517}}, // [eBay Enterprise]
-  {"hash":"c35bcff10cd62a44","prefixes":{"":518}}, // [Goodway Group]
-  {"hash":"a45b6c7292b7b560","prefixes":{"":518}}, // [Goodway Group]
-  {"hash":"d76efc82324fb8d5","prefixes":{"":518}}, // [Goodway Group]
-  {"hash":"5eb742c77c59dd05","prefixes":{"":518}}, // [Goodway Group]
-  {"hash":"33f9a4e4a440eeda","prefixes":{"*":519}}, // [Double Positive Marketing Group Inc.]
-  {"hash":"285da2e20d7ae651","prefixes":{"*":520}}, // [Chitika Inc.]
-  {"hash":"9ac26bc76037dd72","prefixes":{"*":521}}, // [Scigineer Inc.]
-  {"hash":"11971f02aee2996f","prefixes":{"*":522}}, // [Sales Spider Inc.]
-  {"hash":"0dfb620c1f99f67a","prefixes":{"*":522}}, // [Sales Spider Inc.]
-  {"hash":"dee182aa38b90802","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"ee4bb512aa7bff3f","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"051b6a2f5170871a","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"ef2266eab416e344","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"40701593c87a2a6d","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"4dfd82e7fcbfe056","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"2848c783f1d69118","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"26fd0c0c1bbdf578","prefixes":{"":523}}, // [Rocket Fuel Inc.]
-  {"hash":"9362d437c6649ac0","prefixes":{"":524}}, // [RTBlab]
-  {"hash":"83cd554cdc78cc1c","prefixes":{"":524}}, // [RTBlab]
-  {"hash":"e4e3ec12949d311d","prefixes":{"":524}}, // [RTBlab]
-  {"hash":"9db675ca1ddbc25e","prefixes":{"":524}}, // [RTBlab]
-  {"hash":"c407f5eb4837736a","prefixes":{"":524}}, // [RTBlab]
-  {"hash":"27e52d41a00bf2fd","prefixes":{"":524}}, // [RTBlab]
-  {"hash":"efa545dd9d577a82","prefixes":{"":525}}, // [abilicom GmbH]
-  {"hash":"f690d50313c4d883","prefixes":{"":525}}, // [abilicom GmbH]
-  {"hash":"e59063ed858c1ac6","prefixes":{"":525}}, // [abilicom GmbH]
-  {"hash":"08ecd0f7d816b029","prefixes":{"":30}}, // [Rakuten Display]
-  {"hash":"6321d1d2e3ff13cf","prefixes":{"":526}}, // [Pulpo Media Inc]
-  {"hash":"68778ff49de5f6b7","prefixes":{"":526}}, // [Pulpo Media Inc]
-  {"hash":"4fe62a295bf7110a","prefixes":{"*":527}}, // [OneSpot]
-  {"hash":"0a03e9309eac6fef","prefixes":{"*":528}}, // [MyThings UK Ltd]
-  {"hash":"aefee6cf21fb21d0","prefixes":{"*":528}}, // [MyThings UK Ltd]
-  {"hash":"013cf49561a61d0a","prefixes":{"":529}}, // [Exactag]
-  {"hash":"a5db93b0474bf88a","prefixes":{"":529}}, // [Exactag]
-  {"hash":"8eaf146d58acaea3","prefixes":{"":353}}, // [AdMaster]
-  {"hash":"62f9a92e2fa55157","prefixes":{"":353}}, // [AdMaster]
-  {"hash":"2246fe417fb594d4","prefixes":{"":353}}, // [AdMaster]
-  {"hash":"46be6b3d05c938b5","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"b588a450d30940dc","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"9013d3536e80f01a","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"705829297e5108ae","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"bfd58f70292d02ab","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"ff5875b2546d8499","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"ccc16a9e8656612f","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"a764b52c155c440b","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"a8a184b600fd3af1","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"6c106d279e66ed61","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"7c8663ad744aeec9","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"c3860e5673290a36","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"485e37ef683e6da8","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"03c59eef464ffa9d","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"e8d28d6ae9ed1064","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"1fc896b89972c4a3","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"89d45cf6716d92c4","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"c374b8ef2cc0a6d3","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"e0a60df6ec972762","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"dfd819866072d81c","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"dbaab38c6254fc44","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"25e404b1d7cfa7b3","prefixes":{"":530}}, // [Kyocera Communication Systems Co. Ltd.]
-  {"hash":"f9b4a878a9f66629","prefixes":{"":531}}, // [Beijing LangTaoJin Interactive]
-  {"hash":"5be19b5ec9da0217","prefixes":{"":531}}, // [Beijing LangTaoJin Interactive]
-  {"hash":"c3dd7532c047b725","prefixes":{"":532}}, // [Conversant Mobile Media]
-  {"hash":"fd89a621a7abcb21","prefixes":{"":532}}, // [Conversant Mobile Media]
-  {"hash":"8b03c1ce3a37af3e","prefixes":{"":533}}, // [MM1X.nl]
-  {"hash":"51f16f2963b5ab62","prefixes":{"":533}}, // [MM1X.nl]
-  {"hash":"a34aa5b1e90b35d0","prefixes":{"":534}}, // [Trivu Media Inc.]
-  {"hash":"f5fe0a711d905029","prefixes":{"":534}}, // [Trivu Media Inc.]
-  {"hash":"284614e662fae11d","prefixes":{"*":535}}, // [BlueCava Inc.]
-  {"hash":"cd9e8f6b8e3bb0bb","prefixes":{"":536}}, // [Beijing Gridsum Technology Co. Ltd.]
-  {"hash":"97de03485c681efe","prefixes":{"":536}}, // [Beijing Gridsum Technology Co. Ltd.]
-  {"hash":"6c624568b77c2f15","prefixes":{"":536}}, // [Beijing Gridsum Technology Co. Ltd.]
-  {"hash":"2b74e65baabdf4a8","prefixes":{"":537}}, // [Adsvana DSP]
-  {"hash":"fcd2a83347336f39","prefixes":{"":537}}, // [Adsvana DSP]
-  {"hash":"7cadddba30cbf68b","prefixes":{"":367}}, // [revenue cloud]
-  {"hash":"39fe4b58f8d0c85a","prefixes":{"":538}}, // [Target Performance]
-  {"hash":"219259d49fac1ccb","prefixes":{"":539}}, // [Content Spread]
-  {"hash":"ca8d76b63fdfd7e7","prefixes":{"":367}}, // [revenue cloud]
-  {"hash":"ed86b10928624d27","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"205f80e614b45d0c","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"88c9d142721a0010","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"c918497df4612dee","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"ecc68ce18bc92eac","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"acd6e7d757515791","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"611fb7a1125a9f9d","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"b47f7e78adfcce8c","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"e7d6867de133fef3","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"022353c9ab0821d7","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"2571a0502f188936","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"f1efca13f787818a","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"1c982ec87cdd98c7","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"ffa62eae8604dfb9","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"8c7ba8485b195fda","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"188fb424b02d01b3","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"92807e8eb5ceed53","prefixes":{"":540}}, // [Datamind Effective Media]
-  {"hash":"b01a0f9c920b194e","prefixes":{"":541}}, // [ScaleOut Inc.]
-  {"hash":"da51b7d5383143f5","prefixes":{"":541}}, // [ScaleOut Inc.]
-  {"hash":"acca27df7ac50ef3","prefixes":{"":541}}, // [ScaleOut Inc.]
-  {"hash":"8a45863cac015863","prefixes":{"":541}}, // [ScaleOut Inc.]
-  {"hash":"ae50046a864ceafd","prefixes":{"":541}}, // [ScaleOut Inc.]
-  {"hash":"de57dfdaf9a2c48a","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"b1235d3bdac69ad1","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"b2717d6d54a069e3","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"d7152b8a7fbdcfd9","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"66d946b524ae15cb","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"cb87adb62a805e43","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"64b417a15cd2caba","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"fe5fbbb5f87923ec","prefixes":{"":542}}, // [Ensighten]
-  {"hash":"7955dee10fac2b43","prefixes":{"":543}}, // [Sony Electronics Inc.]
-  {"hash":"18b842a485714b88","prefixes":{"":543}}, // [Sony Electronics Inc.]
-  {"hash":"5e881c11a6141a0e","prefixes":{"*":544}}, // [Gravity Research and Development LTD]
-  {"hash":"eb0586aa7b44d1a7","prefixes":{"":545}}, // [Project SunBlock]
-  {"hash":"e49a615e7e072e05","prefixes":{"":546}}, // [Novem sp. z o.o.]
-  {"hash":"c36795d664275022","prefixes":{"*":547}}, // [Econda GmbH]
-  {"hash":"1dafa12902626628","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"ddc49ed0d5adc099","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"43e36030afe70656","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"f4acd265af4a8b2c","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"2d00af9d31137b46","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"6330d2d69fac5592","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"07924db4fbf62ed8","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"40fa76b0dfe6cba9","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"cb5e5323270dac31","prefixes":{"":548}}, // [AdMaxim LLC]
-  {"hash":"644395b50223d6f0","prefixes":{"":78}}, // [Adnologies GmbH]
-  {"hash":"e816f89057c8ad52","prefixes":{"":78}}, // [Adnologies GmbH]
-  {"hash":"8d2b1cab5958796f","prefixes":{"":549}}, // [Alliance Health Networks]
-  {"hash":"3568ed34edbd0a3b","prefixes":{"":550}}, // [Adsame Advertising Co., Ltd]
-  {"hash":"5fd75bdc8d48469a","prefixes":{"":550}}, // [Adsame Advertising Co., Ltd]
-  {"hash":"f24f098ee46d7e52","prefixes":{"":550}}, // [Adsame Advertising Co., Ltd]
-  {"hash":"695c924af8b7be90","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"8c21b1544107f44b","prefixes":{"":552}}, // [PK Online Ventures Limited]
-  {"hash":"b709e5fa7a0a3284","prefixes":{"":553}}, // [Bigpoint Gmbh]
-  {"hash":"54393b0479bf4296","prefixes":{"":553}}, // [Bigpoint Gmbh]
-  {"hash":"0228e75fa4f7ba29","prefixes":{"":553}}, // [Bigpoint Gmbh]
-  {"hash":"161b02c3430e8493","prefixes":{"":554}}, // [Mirapodo GmbH]
-  {"hash":"cbfa294f671394f5","prefixes":{"":555}}, // [Digitize New Media Ltd.]
-  {"hash":"126e76895e35030f","prefixes":{"":556}}, // [AdSage]
-  {"hash":"d1a3397960a0c962","prefixes":{"":556}}, // [AdSage]
-  {"hash":"27111f31c7f7870c","prefixes":{"":556}}, // [AdSage]
-  {"hash":"5066a54cd7ed6242","prefixes":{"":556}}, // [AdSage]
-  {"hash":"5447e7edfecbefc9","prefixes":{"":556}}, // [AdSage]
-  {"hash":"763e1c5a534cdce1","prefixes":{"":556}}, // [AdSage]
-  {"hash":"664f6761d6e1bdc5","prefixes":{"":556}}, // [AdSage]
-  {"hash":"85dc2dbb9cf8ba01","prefixes":{"":556}}, // [AdSage]
-  {"hash":"efd9939ccbcea7ca","prefixes":{"":556}}, // [AdSage]
-  {"hash":"5095b815554d166d","prefixes":{"":556}}, // [AdSage]
-  {"hash":"bbd5220662a5b37e","prefixes":{"":556}}, // [AdSage]
-  {"hash":"ad929f7cd3353264","prefixes":{"":556}}, // [AdSage]
-  {"hash":"aebf7b2a7ee1ff12","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"01ef28aab34283cc","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"c075f26f4aa57d43","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"f651f54211351ca7","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"98e7e8f01b1e7221","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"7f46832cdf7b45db","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"4a37345bf96b65b5","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"ee9f377ce8711040","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"f6f6db9a07009087","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"37414a33ff3de4a0","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"7cc06f83f0710408","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"beb1894d6a5dd8d5","prefixes":{"":557}}, // [Fingereach]
-  {"hash":"ab305fad96c94e68","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"abb33b12777d693c","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"cf57baa1fe60d65d","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"1e230cd699b878e6","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"0e9f493079696ce3","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"7d3350cd22011e53","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"f50b2ec037f5428b","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"c171c26c4996ef48","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"558975de73dc2727","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"ee6b8472f5558865","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"8183f3c56cedc5d3","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"9e46a78131a70a25","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"9805160753b78db8","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"9665241d465c8ced","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"0886098ece10411f","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"1b9aa72e21da1cf9","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"75eaf92a0259fced","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"6647ef959a9060b1","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"55bbd43420c048ba","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"769a3492166f2234","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"88bf787fe78aa617","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"62db61a5802ee5f9","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"ecc8b48b5b165bff","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"3b713a488717f579","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"7d501d2362243528","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"1e2c100fab457dce","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"7adb32ad76289644","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"3f4747021104b435","prefixes":{"":307}}, // [DMA Institute dba Hottraffic]
-  {"hash":"55ade41cc24f1b54","prefixes":{"":558}}, // [Calvin Klein]
-  {"hash":"210f025e6c6b8122","prefixes":{"":559}}, // [Medialets Servo]
-  {"hash":"233555f3daf9abb0","prefixes":{"":559}}, // [Medialets Servo]
-  {"hash":"eea93545b322651b","prefixes":{"":559}}, // [Medialets Servo]
-  {"hash":"d9fe49eeaf35eb01","prefixes":{"":559}}, // [Medialets Servo]
-  {"hash":"ea41698b95338591","prefixes":{"s-cdn-":559}}, // [Medialets Servo]
-  {"hash":"5f4e90726b181c95","prefixes":{"":560}}, // [Webmoblink Inc.]
-  {"hash":"9d51efd26ab44317","prefixes":{"":31}}, // [Retailigence]
-  {"hash":"32440ed26b61d14a","prefixes":{"":31}}, // [Retailigence]
-  {"hash":"8234d0306d8984eb","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"e35bf94930bc4d1a","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"aec3f56c7f99151f","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"ef395b96d922c238","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"5a053ab1bcfcfb41","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"2cf811bb8aa279b5","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"cd383e750e6cfcdb","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"c30fc77cd822188e","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"fb9678eef7ea227d","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"102facb286a88bbe","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"aa39a58ff4ed2114","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"e33908ca9604cfa4","prefixes":{"*":561,"":562}}, // [Moat Inc.] [Bannerflow AB]
-  {"hash":"31902ac0cc3e362b","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"796535f10f1e1ea0","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"681a390e8faf08c1","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"1ef04ebc565a6f48","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"1461b89b1a4a5e39","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"a7c34fe979c7afe2","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"30142bb0f24faa5a","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"dc8fdd8b9daae8d5","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"80a2d23602bd08d7","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"e8713f2da85d0fff","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"08fe20173c2a758a","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"105d629b41621e8f","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"c2c8a87c65874f50","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"ecc3d954923aa593","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"313e3d29b4712d5d","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"bf332f1705b05b91","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"c2fac5215807677b","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"b1db7fe55b719fd0","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"c405962725b0a49f","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"f30974f87632ff65","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"c3a0f51c7a475e24","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"470beffefc05bd89","prefixes":{"":561}}, // [Moat Inc.]
-  {"hash":"44c6bfd7fd3ae379","prefixes":{"*":561}}, // [Moat Inc.]
-  {"hash":"ed26e1a4862cb993","prefixes":{"":563}}, // [Batch Media Gmbh]
-  {"hash":"8cc35cd28ab69e7b","prefixes":{"":563}}, // [Batch Media Gmbh]
-  {"hash":"b480ee3cdb39aba3","prefixes":{"":563}}, // [Batch Media Gmbh]
-  {"hash":"42b8cf3c1fba5649","prefixes":{"":563}}, // [Batch Media Gmbh]
-  {"hash":"9c59afa20426083f","prefixes":{"":564}}, // [Twenga]
-  {"hash":"96fa4f0d4282b74b","prefixes":{"":564}}, // [Twenga]
-  {"hash":"147ff4cde8f7b63b","prefixes":{"":564}}, // [Twenga]
-  {"hash":"e6d43f305d0372aa","prefixes":{"":565}}, // [TraceAd]
-  {"hash":"e2a94bb0b8f09309","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"7b17e990632021fb","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"c82cc94c761aff4f","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"9bb0143d6745a1fc","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"9906e8d23a282ab0","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"c29531bb7c2a5a95","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"53972f8a807a3522","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"d8acabec202014c0","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"4062ceb50584895d","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"776d48fd287f99c8","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"caf4c25a1be2f9cc","prefixes":{"":566}}, // [Speed Shift Media]
-  {"hash":"ad66fb580dfc0f61","prefixes":{"*":567}}, // [CCB Paris]
-  {"hash":"2cd1c0997e13f343","prefixes":{"":568}}, // [Nielsen Digital Ad Ratings]
-  {"hash":"cc67f7e32922d026","prefixes":{"*":569}}, // [OpenDSP]
-  {"hash":"37ac881f55f6b624","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"6eaeb2fb0379f719","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"0f37e190c3f7659c","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"cd5e1f475a9a9cb9","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"70dae8af3c6cb2af","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"60e90d920044304d","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"9d34d5e680004543","prefixes":{"":551}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
-  {"hash":"b4b546c24d350673","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"d0b7581f4a3ff9b8","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"0c865d217e1f18f3","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"6333a18d75125edb","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"ed4cdc36d8829848","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"3643c909d7cbe0b8","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"296c21a7001df348","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"97079bad5fb6ead8","prefixes":{"":570}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
-  {"hash":"7b936711dd1e9a43","prefixes":{"":571}}, // [Mediarithmics]
-  {"hash":"c1d09d8bf99adaae","prefixes":{"":572}}, // [RUN, INC.]
-  {"hash":"c1a2559db78be890","prefixes":{"":572}}, // [RUN, INC.]
-  {"hash":"99a2370c6cb03aad","prefixes":{"":572}}, // [RUN, INC.]
-  {"hash":"58188c996594e74c","prefixes":{"":573}}, // [Shanghai Menlo Network Technologies Co.,Ltd]
-  {"hash":"ae01937a71f3c8ec","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"bb20b492d8e895ee","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"a174c7ffc06f1430","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"b04d26682765cf0f","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"3d8976d50a72415a","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"0b937695e283332d","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"5a633d8ed4134176","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"a3d5abb1d31313bb","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"651fcbfafdaa1c3b","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"210045798925d1ec","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"cb9c94ed4430c0d7","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"eb42b6b78e25a31e","prefixes":{"":574}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
-  {"hash":"e21aeaa35d9e4534","prefixes":{"*":575}}, // [NET-Metrix-Audit]
-  {"hash":"d563d7cb84148f5b","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"881b6320fa6c5a13","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"648b287843959e5a","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"aa60743a7bfcd1af","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"afa7ee2a02f86074","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"3b21af5a3fa47754","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"e8f690279ec23223","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"8763304c40959465","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"97be7bbbd0aa71f1","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"1610ab8331e9fa67","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"5cf6c3a758fb5a50","prefixes":{"":576}}, // [New Allyes Information Technology (Quantone)]
-  {"hash":"753372717104cecb","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"9868ccc3384ca704","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"834fc9317bd55432","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"77a58434eda65f1d","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"d6c8f549569824c7","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"605f200bf3a42aec","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"24475a888daf195d","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"577626a5c9b3a87c","prefixes":{"":577}}, // [Resonate Networks, Inc]
-  {"hash":"c258f6da0cd8b8cb","prefixes":{"":577}}, // [Resonate Networks, Inc]
-  {"hash":"d9483fc3fe68e764","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"7caa53e1a6ec2bae","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"dcd74656fa3b323d","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"10fa95c5f15310d2","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"6f83daf020ab465f","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"d3d1a09a28024ddc","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"9b208cc58454fb78","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"4645c6078dc34d50","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"b238cbc325c6ef22","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"49deee4d32200263","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"773d9411487a25e3","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"0f6cf491f7eb2baa","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"8dfcd3664fa1302b","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"800bb9e7968e58aa","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"b05b363e5a0511e8","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"20c70723848457f0","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"66114e4ff94b609f","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"f2d188b48acaeb7f","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"409d1c85462adead","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"4d380a7d15d0a78a","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"d5449f5767bfafa7","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"bd39dc0af22a3152","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"f86c1368c7c5eb92","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"e8f74e435e9df1dd","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"9b5fa6e2f606ce7d","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"9a9e03501130b17a","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"2a12549f5c240468","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"215711257cc47c2c","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"77f3f7c79d95de48","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"6d31870e0469ddc6","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"d43e8e7f0b7db722","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"cf4d5bbc8b02dc1c","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"fa69e0b93ab494f2","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"5df810b59c15eb88","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"1bad3858e6b1db68","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"1f0663d5a32c3b7d","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"0accadb2b8868065","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"29fa86d0b3c09f26","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"6c3481a4787dc989","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"dd2cdf0ae459961c","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"b7ddbc93720778f5","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"65db5bf588a1552c","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"d63dadf02badb9bc","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"12a0ac899815d56b","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"4e73ffb09594e8a6","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"7bd28c9beb85782f","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"e5a3c52df181ad93","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"5db249180904a1af","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"f33943be4b14e2cc","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"3304828c6a87914b","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"0dee81e461b3c8bb","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"23282a1244ed862f","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"8b1d859efda195f4","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"e22129fd14c58ef7","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"c11b0627d1105ed8","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"fee7a2b84c23b6bb","prefixes":{"":11}}, // [advanced STORE GmbH]
-  {"hash":"3f3d4a96d97bc12a","prefixes":{"":578}}, // [Triple Lift, Inc.]
-  {"hash":"7e4d08be26af0913","prefixes":{"":578}}, // [Triple Lift, Inc.]
-  {"hash":"ab1718aa8ada6ceb","prefixes":{"":578}}, // [Triple Lift, Inc.]
-  {"hash":"00810432ca3a5adf","prefixes":{"":578}}, // [Triple Lift, Inc.]
-  {"hash":"e597ba5088abb36a","prefixes":{"":578}}, // [Triple Lift, Inc.]
-  {"hash":"d206640e7ca174cd","prefixes":{"":579}}, // [Indie Ads]
-  {"hash":"d8ed39f1e603b870","prefixes":{"":580}}, // [Ocean Park Interactive]
-  {"hash":"a241e76a04cef012","prefixes":{"":580}}, // [Ocean Park Interactive]
-  {"hash":"dcc0a9d204aaa55d","prefixes":{"":580}}, // [Ocean Park Interactive]
-  {"hash":"8372761b0392f8a9","prefixes":{"":580}}, // [Ocean Park Interactive]
-  {"hash":"e7b8261c49b1fbf6","prefixes":{"":580}}, // [Ocean Park Interactive]
-  {"hash":"d5094d4667f378a7","prefixes":{"":580}}, // [Ocean Park Interactive]
-  {"hash":"4091c3043c2da68a","prefixes":{"":581}}, // [Impulse Media Pvt. Ltd.]
-  {"hash":"6eb5dacfebab8b02","prefixes":{"":582}}, // [CrowdTwist]
-  {"hash":"123db0626c48324c","prefixes":{"":582}}, // [CrowdTwist]
-  {"hash":"4f356e0d187085b0","prefixes":{"":583}}, // [Adzerk Inc.]
-  {"hash":"79c1600f16f0c0ad","prefixes":{"":583}}, // [Adzerk Inc.]
-  {"hash":"170c4bddaa53e87c","prefixes":{"":584}}, // [Adtarget.me]
-  {"hash":"b514da98fbd70da7","prefixes":{"":584}}, // [Adtarget.me]
-  {"hash":"e585ef712f906ce4","prefixes":{"":584}}, // [Adtarget.me]
-  {"hash":"ed5e6e621b9e9e9e","prefixes":{"":584}}, // [Adtarget.me]
-  {"hash":"904a8c71f0ac4b5c","prefixes":{"":584}}, // [Adtarget.me]
-  {"hash":"138d782ff8ef8b3d","prefixes":{"":585}}, // [Recruit Marketing Partners Co.,Ltd]
-  {"hash":"8899c2499d762095","prefixes":{"":586}}, // [Beijing Emar Online Technology Co.,Ltd]
-  {"hash":"29f87adefe40afd5","prefixes":{"":586}}, // [Beijing Emar Online Technology Co.,Ltd]
-  {"hash":"1f57d0a967ca4f30","prefixes":{"":586}}, // [Beijing Emar Online Technology Co.,Ltd]
-  {"hash":"378c4fbbd1d161e2","prefixes":{"":587}}, // [AdMagnet]
-  {"hash":"bb42bdad4318ee55","prefixes":{"":587}}, // [AdMagnet]
-  {"hash":"71d1cec71f53e140","prefixes":{"":587}}, // [AdMagnet]
-  {"hash":"e3bad45f1f3d21a5","prefixes":{"":587}}, // [AdMagnet]
-  {"hash":"aa63c60aa73e9d29","prefixes":{"":588}}, // [Momondo A/S]
-  {"hash":"b34444583646725a","prefixes":{"*":588}}, // [Momondo A/S]
-  {"hash":"cbf8a85fbf4c22e5","prefixes":{"*":589}}, // [DKK Agency]
-  {"hash":"e775e327a7a42402","prefixes":{"":590}}, // [OneScreen Inc.]
-  {"hash":"080fcbb984e6ecdd","prefixes":{"":590}}, // [OneScreen Inc.]
-  {"hash":"8c1ae0a34a3df5d0","prefixes":{"":590}}, // [OneScreen Inc.]
-  {"hash":"ba491e57276128df","prefixes":{"":591}}, // [AdElement Media Solutions Pvt Ltd]
-  {"hash":"620a368e66b0d054","prefixes":{"":591}}, // [AdElement Media Solutions Pvt Ltd]
-  {"hash":"f100a71a63d2ccfa","prefixes":{"":591}}, // [AdElement Media Solutions Pvt Ltd]
-  {"hash":"636877d8cc1827f4","prefixes":{"":592}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"e066625a70a1d5c0","prefixes":{"":592}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"117aaf00ef5036e3","prefixes":{"":592}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"4f795b8396901621","prefixes":{"":592}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"b8da1e9feb0bc01d","prefixes":{"":592}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"433e8fe3ca1684d7","prefixes":{"":592}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
-  {"hash":"f2fc51beddbeb4a9","prefixes":{"":593}}, // [Adsit Media Advertising Ltd. Co., (AdMan)]
-  {"hash":"ba7f680031ef6ba6","prefixes":{"":594}}, // [AdMan]
-  {"hash":"cba16dd5f4409e30","prefixes":{"":594}}, // [AdMan]
-  {"hash":"3e32b1ab3e9c66b6","prefixes":{"":593}}, // [Adsit Media Advertising Ltd. Co., (AdMan)]
-  {"hash":"59225b3e2dce506e","prefixes":{"":595}}, // [MicroAd Inc. (China)]
-  {"hash":"8a3b315693f80801","prefixes":{"":595}}, // [MicroAd Inc. (China)]
-  {"hash":"9ecae05881ad91ad","prefixes":{"":595}}, // [MicroAd Inc. (China)]
-  {"hash":"86a1bc63ec059f25","prefixes":{"":596}}, // [Adfonic]
-  {"hash":"ea28de00a6512e88","prefixes":{"":596}}, // [Adfonic]
-  {"hash":"42bb8749687dee83","prefixes":{"":597}}, // [OwnerIQ Inc.]
-  {"hash":"125539a4b58c9087","prefixes":{"":597}}, // [OwnerIQ Inc.]
-  {"hash":"895ef87fbdd546df","prefixes":{"":598}}, // [Mobile Space Ltd]
-  {"hash":"55e398544c3aeb40","prefixes":{"":598}}, // [Mobile Space Ltd]
-  {"hash":"c5e19d61efa129d7","prefixes":{"ap":598,"e":598,"":599}}, // [Mobile Space Ltd] [Mobile Space Ltd] [Jaduda GmbH]
-  {"hash":"3668b933b223ee50","prefixes":{"":600}}, // [Omotenashi Banner]
-  {"hash":"209fb323c4db09ef","prefixes":{"":600}}, // [Omotenashi Banner]
-  {"hash":"d95ee45ed75216b1","prefixes":{"":600}}, // [Omotenashi Banner]
-  {"hash":"7fb039cd298570d4","prefixes":{"":600}}, // [Omotenashi Banner]
-  {"hash":"a7d0a34772320297","prefixes":{"":600}}, // [Omotenashi Banner]
-  {"hash":"a86ff9f748f6a5ab","prefixes":{"":600}}, // [Omotenashi Banner]
-  {"hash":"046d69c93f0ab29e","prefixes":{"":601}}, // [Infectious Media Ltd.]
-  {"hash":"735a86882c4fccc6","prefixes":{"":602}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"c454c081e737b7e2","prefixes":{"":602}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"1e8ed560dc22bbb5","prefixes":{"":602}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"3a57d7982ec36d46","prefixes":{"":602}}, // [One97 Communications Limited (Ad Works)]
-  {"hash":"282d5dfa72aee67e","prefixes":{"":603}}, // [Walk Light Media Inc.]
-  {"hash":"350189fcd66d737d","prefixes":{"":604}}, // [AdBrite Inc.]
-  {"hash":"727c2c9dbde23217","prefixes":{"":604}}, // [AdBrite Inc.]
-  {"hash":"f0011932876966b7","prefixes":{"":605}}, // [Hi-Media]
-  {"hash":"49a154fb3339d1c9","prefixes":{"":605}}, // [Hi-Media]
-  {"hash":"bc9403b31553c2c3","prefixes":{"":605}}, // [Hi-Media]
-  {"hash":"4a763539fb83a309","prefixes":{"":605}}, // [Hi-Media]
-  {"hash":"ad517dcc393c2311","prefixes":{"":605}}, // [Hi-Media]
-  {"hash":"ea321c60d183257c","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"44405675d1af2241","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"703f39c13b597e32","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"5bdae611f2bbe659","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"87862d3ee53095a7","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"376d93acf5e8d717","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"3f0e8ced0049c1d6","prefixes":{"":606}}, // [Adlabs]
-  {"hash":"a04ea3bd56ab64bb","prefixes":{"":607}}, // [Arth Salutions]
-  {"hash":"b6ce2c8ae8e9a415","prefixes":{"":608}}, // [Konverta]
-  {"hash":"ebd466a03db9081b","prefixes":{"":608}}, // [Konverta]
-  {"hash":"2df213fa126d1ca4","prefixes":{"":608}}, // [Konverta]
-  {"hash":"901ec1b8062c3af6","prefixes":{"":608}}, // [Konverta]
-  {"hash":"3cdfbabfa37b6bd8","prefixes":{"":608}}, // [Konverta]
-  {"hash":"4a23a2c45d1e92c3","prefixes":{"":608}}, // [Konverta]
-  {"hash":"72784278d856920c","prefixes":{"":608}}, // [Konverta]
-  {"hash":"61aa8fff3eb4e893","prefixes":{"":103}}, // [Cogo Labs, Inc.]
-  {"hash":"def94469bdc7241e","prefixes":{"":103}}, // [Cogo Labs, Inc.]
-  {"hash":"f17d17eabacc3756","prefixes":{"":103}}, // [Cogo Labs, Inc.]
-  {"hash":"8644dbe4c2172593","prefixes":{"":609}}, // [Shopall]
-  {"hash":"4b55c6a7d9c2a9a2","prefixes":{"":609}}, // [Shopall]
-  {"hash":"305615cf8dbc9be2","prefixes":{"":610}}, // [targeting360 GmbH]
-  {"hash":"bed5b722b1bc1ba5","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"1528f8323f342e8b","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"3c0f20ff410483fa","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"929748002c9b8ecf","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"da8d84b561cc6dae","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"4d73c36d7413bcac","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"fa03c22fb3892bf3","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"9671a9ac26a91d0a","prefixes":{"":611}}, // [xplosion interactive GmbH]
-  {"hash":"ca13edee3fffee4e","prefixes":{"":612}}, // [Hubrus LLC]
-  {"hash":"e6c8579483f7b40c","prefixes":{"":612}}, // [Hubrus LLC]
-  {"hash":"5426e12fbea3fce8","prefixes":{"":612}}, // [Hubrus LLC]
-  {"hash":"e1b8d2118c9dc529","prefixes":{"":613}}, // [Here Media Inc.]
-  {"hash":"6ab38da002eadbc3","prefixes":{"":614}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"8ef09da008fcfae7","prefixes":{"":614}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"f09f918279f1e9ac","prefixes":{"":614}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"ddfd965ee920e41c","prefixes":{"":614}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"47758f4c45a57ea4","prefixes":{"":614}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"9b402085270b3ed3","prefixes":{"":614}}, // [Silver Egg Technology Co., Ltd.]
-  {"hash":"5a4e20d5da4d99f0","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"1a32d33420507504","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"c841d6764f10305d","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"c0be785071fbf1f8","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"a48b68d5e7caa5da","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"93764efbaea60a26","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"2d1e1dbc88160b0a","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"49c9a4898d7eda62","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"51f27880010fd487","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"1930e597dd2d66f9","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"9138d5d361766aa2","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"942211eb94fc3c91","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"ac957255586d114c","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"1174020d0986b7c7","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"1386eff7c87966ca","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"d3c3497dc1813ac6","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"ec8bb52d56c92778","prefixes":{"":615}}, // [QuarticOn.com]
-  {"hash":"b999321725f081a5","prefixes":{"":616}}, // [Kavanga LLC]
-  {"hash":"43f2f88cac5c1e66","prefixes":{"":617}}, // [Vodafone D2 GmbH]
-  {"hash":"71f43d2f0436d908","prefixes":{"":617}}, // [Vodafone D2 GmbH]
-  {"hash":"4b13b8a28b6556d3","prefixes":{"":617}}, // [Vodafone D2 GmbH]
-  {"hash":"b9c154f4d363eebc","prefixes":{"":618}}, // [Qubit Digital Ltd]
-  {"hash":"f3c32c6c7e1ac882","prefixes":{"":538,"ad":619,"tm":619}}, // [Target Performance] [NEORY GmbH] [NEORY GmbH]
-  {"hash":"728524adefe77058","prefixes":{"static-":620}}, // [Populis Ireland Limited]
-  {"hash":"7f78aff31bba38ad","prefixes":{"":620}}, // [Populis Ireland Limited]
-  {"hash":"cacb07348e9e3ca3","prefixes":{"":620}}, // [Populis Ireland Limited]
-  {"hash":"ce069e74d10aa948","prefixes":{"":621}}, // [LiquidM Technology GmbH]
-  {"hash":"b6284e5bbeacee78","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"f71102b0f2425eb8","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"da76d0a397ab42fc","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"d30b0fd7cd3dc387","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"d3643510dc9a55a3","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"f74f9b96eb974ad7","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"538d09650aaff88b","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"7533124cd83c8651","prefixes":{"":622}}, // [Celtra Inc.]
-  {"hash":"8413a3afa447ddd6","prefixes":{"":623}}, // [Adfox]
-  {"hash":"28b1ebc0a8b51b58","prefixes":{"":623}}, // [Adfox]
-  {"hash":"0c6cea5dd49d0361","prefixes":{"sd":623,"rt":623}}, // [Adfox] [Adfox]
-  {"hash":"2e3df7d60b00392d","prefixes":{"":623}}, // [Adfox]
-  {"hash":"4cdee950d7417a19","prefixes":{"":623}}, // [Adfox]
-  {"hash":"2060d81c3f4dbace","prefixes":{"":624}}, // [Accordant Media LLC]
-  {"hash":"f2c07b1834365ee5","prefixes":{"":625}}, // [Fiksu DSP]
-  {"hash":"c61068cc57f0f219","prefixes":{"":625}}, // [Fiksu DSP]
-  {"hash":"a1f4b4a83add949d","prefixes":{"":625}}, // [Fiksu DSP]
-  {"hash":"70b9063aeb27d88a","prefixes":{"":625}}, // [Fiksu DSP]
-  {"hash":"f66693ef14e4cd79","prefixes":{"":625}}, // [Fiksu DSP]
-  {"hash":"7f9c748aa884dba0","prefixes":{"":626}}, // [MdotM, Inc.]
-  {"hash":"13c8f5f12f3b9ca6","prefixes":{"":626}}, // [MdotM, Inc.]
-  {"hash":"c47f6172a03d7b4c","prefixes":{"":627}}, // [TNS GALLUP ADFACT, ZAO]
-  {"hash":"f9a74c430e157e57","prefixes":{"":627}}, // [TNS GALLUP ADFACT, ZAO]
-  {"hash":"534ec1b9f199f18a","prefixes":{"":628}}, // [MicroAd Inc. (APAC)]
-  {"hash":"98bec02f53970649","prefixes":{"":628}}, // [MicroAd Inc. (APAC)]
-  {"hash":"dab5b2f5150fe52c","prefixes":{"*":629}}, // [ECRITEL SARL]
-  {"hash":"039caee3c590ef51","prefixes":{"*":629}}, // [ECRITEL SARL]
-  {"hash":"56d4c8e77cf378ca","prefixes":{"*":629}}, // [ECRITEL SARL]
-  {"hash":"ea054eef4a7b535d","prefixes":{"*":629}}, // [ECRITEL SARL]
-  {"hash":"503f3e019cf902f7","prefixes":{"":104}}, // [AudienceProject]
-  {"hash":"d07ac29d5418a5a2","prefixes":{"":104}}, // [AudienceProject]
-  {"hash":"252a5f53fef3adef","prefixes":{"":630}}, // [Gloto Corp.]
-  {"hash":"c45cf16c98289ef3","prefixes":{"":630}}, // [Gloto Corp.]
-  {"hash":"43869a9fbc1e93ac","prefixes":{"":631}}, // [OOO GPM-Digital]
-  {"hash":"4334255596024dac","prefixes":{"*":632}}, // [adverserve digital advertising services]
-  {"hash":"c1cbc8c1a131b486","prefixes":{"":633}}, // [Abstract]
-  {"hash":"f0a24e1beb2ff006","prefixes":{"":633}}, // [Abstract]
-  {"hash":"5d7848291e6b2aac","prefixes":{"":633}}, // [Abstract]
-  {"hash":"678875d741d45390","prefixes":{"":634}}, // [Adscale GmbH]
-  {"hash":"bdf162f8a955792f","prefixes":{"":634}}, // [Adscale GmbH]
-  {"hash":"e2aa93ef150b6625","prefixes":{"":634}}, // [Adscale GmbH]
-  {"hash":"fbecc41bd388e9da","prefixes":{"":634}}, // [Adscale GmbH]
-  {"hash":"33d677c1746e032b","prefixes":{"":634}}, // [Adscale GmbH]
-  {"hash":"7b632e1d26173d9a","prefixes":{"":635}}, // [Weebly, Inc.]
-  {"hash":"d60691434c15d686","prefixes":{"":636}}, // [KPI Solutions Co.,Ltd.]
-  {"hash":"6bcb40c428dea82d","prefixes":{"*":636}}, // [KPI Solutions Co.,Ltd.]
-  {"hash":"a7261ab41534a5a9","prefixes":{"":637}}, // [LuckyBrand.com]
-  {"hash":"8ade692ce59ddf24","prefixes":{"":638}}, // [Bedrijvenweb.nl]
-  {"hash":"4f925a01c20725e2","prefixes":{"":639}}, // [CacheFly]
-  {"hash":"bd7deac394b9d8ec","prefixes":{"*":640}}, // [EdgeCast Networks Inc.]
-  {"hash":"d14784769a5e3e32","prefixes":{"*":640}}, // [EdgeCast Networks Inc.]
-  {"hash":"eeb0b9405b4e70a9","prefixes":{"*":640}}, // [EdgeCast Networks Inc.]
-  {"hash":"799a922119603cf7","prefixes":{"":641}}, // [AdFrontier]
-  {"hash":"b99f16bd08f23e1d","prefixes":{"":642}}, // [NFQ]
-  {"hash":"55b741a8d993b7af","prefixes":{"":642}}, // [NFQ]
-  {"hash":"7733707370fb05c7","prefixes":{"":642}}, // [NFQ]
-  {"hash":"9a42cb5421abffa9","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"47ee3c7f6cf3211f","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"5e4b5dd08e9b52fd","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"6bc3a667cd012222","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"18656382f2827e60","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"c73db0ed241d269e","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"bc0f02a06b74b7a3","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"0405bea2af551e19","prefixes":{"":643}}, // [DataLogix, Inc.]
-  {"hash":"c35511ecd49cebb7","prefixes":{"":644}}, // [Brightcove]
-  {"hash":"22bfe38898977ed4","prefixes":{"":644}}, // [Brightcove]
-  {"hash":"c095755780478f7e","prefixes":{"":645}}, // [Experian]
-  {"hash":"0f2014a09acf7abd","prefixes":{"*":646}}, // [Facebook Connect]
-  {"hash":"b7c70898d90f5bb3","prefixes":{"*":646}}, // [Facebook Connect]
-  {"hash":"18562cb1149fda1e","prefixes":{"*":647}}, // [Disqus]
-  {"hash":"37b749b8858eb61b","prefixes":{"*":648}}, // [Namecheap.com]
-  {"hash":"3d59be0f5f7101a0","prefixes":{"":649}}, // [Polldaddy]
-  {"hash":"510cff549d2cb397","prefixes":{"":650}}, // [Outbrain Inc.]
-  {"hash":"e23ebc9959ce4873","prefixes":{"":650}}, // [Outbrain Inc.]
-  {"hash":"623fd0210b11d4fb","prefixes":{"":651}}, // [Lijit Networks, Inc.]
-  {"hash":"686b7accbfa398fa","prefixes":{"":651}}, // [Lijit Networks, Inc.]
-  {"hash":"85c44f0602598dd8","prefixes":{"":651}}, // [Lijit Networks, Inc.]
-  {"hash":"a107b1fdcffae5b9","prefixes":{"*":484}}, // [NetDNA, LLC]
-  {"hash":"7f37823a3f5c76b3","prefixes":{"*":652}}, // [PubMatic]
-  {"hash":"6d306315a1fecfda","prefixes":{"":653}}, // [Say Media Inc.]
-  {"hash":"c2568516b08f0d3d","prefixes":{"":653}}, // [Say Media Inc.]
-  {"hash":"308d3a8d1ca52ff3","prefixes":{"":653}}, // [Say Media Inc.]
-  {"hash":"59e488c5f151e7c3","prefixes":{"":653}}, // [Say Media Inc.]
-  {"hash":"7efe6908db5a1d44","prefixes":{"":654}}, // [Rubicon Project Turing, Inc. (SSP)]
-  {"hash":"c6ee8faaa7d6734c","prefixes":{"":655}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"d93c07cc68e53d91","prefixes":{"":655}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"86ae2b216def9790","prefixes":{"":655}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"1267f5857549a6ab","prefixes":{"":655}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"367db80c0776f6d8","prefixes":{"":655}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"c4c762a7e666da1c","prefixes":{"":655}}, // [Rubicon Project Edison, Inc. (DSP)]
-  {"hash":"bb66261f843823d5","prefixes":{"":656}}, // [Wordpress Stats]
-  {"hash":"a0f3bb8dcd67010e","prefixes":{"":656}}, // [Wordpress Stats]
-  {"hash":"4a423f1da960eda6","prefixes":{"*":657}}, // [Twitter]
-  {"hash":"465806fbb3547c25","prefixes":{"*":657}}, // [Twitter]
-  {"hash":"13c55ef8102cbdbb","prefixes":{"":658}}, // [Yandex LLC]
-  {"hash":"db546baba3acb079","prefixes":{"":658}}, // [Yandex LLC]
-  {"hash":"3dd0667dbad0af61","prefixes":{"":658}}, // [Yandex LLC]
-  {"hash":"78e224c91aabe6de","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"75acb8a5a60ef63d","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"6f7720a054c19a2b","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"dbd76c26579bf2b1","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"2cd7f311595e164e","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"b08380cf2fcb4415","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"59ac14277edec497","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"88893eeb26e546a0","prefixes":{"":659}}, // [Rutarget / Segmento]
-  {"hash":"da151dbe8b815dfb","prefixes":{"":660}}, // [Addoor LatinMarkets, SL]
-  {"hash":"b2a44f920e268749","prefixes":{"":661}}, // [Kate Spade]
-  {"hash":"96a8c3ab1740bf2f","prefixes":{"":97}}, // [Tacoda]
-  {"hash":"95e85e3cbd858779","prefixes":{"":662}}, // [TARGUSinfo]
-  {"hash":"dbf2963c9bf26f55","prefixes":{"":663}}, // [Adblade]
-  {"hash":"8064758f6c80afed","prefixes":{"":663}}, // [Adblade]
-  {"hash":"b7aaa083e4151ca8","prefixes":{"":663}}, // [Adblade]
-  {"hash":"f4d5f13eb7d1ba2b","prefixes":{"":663}}, // [Adblade]
-  {"hash":"eca68f2e6cd8a07e","prefixes":{"":664}}, // [Adiant]
-  {"hash":"30f4c3f682592add","prefixes":{"":665}}, // [AddToAny]
-  {"hash":"39b76d24e28075d4","prefixes":{"*":666}}, // [Bizo Inc]
-  {"hash":"dabe4d73219c06e0","prefixes":{"":667}}, // [Google Analytics]
-  {"hash":"f8c6758a214299be","prefixes":{"":668}}, // [Gravatar]
-  {"hash":"0a130612d187bc06","prefixes":{"":668}}, // [Gravatar]
-  {"hash":"6802f0145385df51","prefixes":{"":669}}, // [MediaGlu]
-  {"hash":"ccbeaf028d3c721b","prefixes":{"":669}}, // [MediaGlu]
-  {"hash":"1d7daeed381c33aa","prefixes":{"":669}}, // [MediaGlu]
-  {"hash":"038b4d8cab2d2a58","prefixes":{"":669}}, // [MediaGlu]
-  {"hash":"bd4919274e19987e","prefixes":{"":669}}, // [MediaGlu]
-  {"hash":"dcdf95e5abf7c100","prefixes":{"":670}}, // [Tapstream Network Inc.]
-  {"hash":"1f751fd80b11ad3c","prefixes":{"":671}}, // [HUNT Mobile Ads]
-  {"hash":"de1c8591006ce969","prefixes":{"":672}}, // [Apsalar, Inc.]
-  {"hash":"9fd29903977b5176","prefixes":{"":672}}, // [Apsalar, Inc.]
-  {"hash":"c3930fc2f4cd70df","prefixes":{"*":673}}, // [Videology DSP]
-  {"hash":"8924b56175f6f114","prefixes":{"":674}}, // [Videostrip]
-  {"hash":"f4b2d76af9987952","prefixes":{"":675}}, // [Affinity – Hostway Corporation]
-  {"hash":"b11ec5ee5b26491a","prefixes":{"*":241,"":676}}, // [Scene Stealer Ltd.] [Rackspace, US Inc.]
-  {"hash":"5177084498d58bac","prefixes":{"":676}}, // [Rackspace, US Inc.]
-  {"hash":"3a0fe0aeaa847996","prefixes":{"*":676}}, // [Rackspace, US Inc.]
-  {"hash":"2b344a3d6c766cb7","prefixes":{"":676}}, // [Rackspace, US Inc.]
-  {"hash":"a0b6774e583d1787","prefixes":{"":677}}, // [Taptica]
-  {"hash":"e6ad999a7fc77500","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"4056609d04bfec9c","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"d1f59501d08f217a","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"bd467d941e65225d","prefixes":{"":241}}, // [Scene Stealer Ltd.]
-  {"hash":"0de83b2d387d2a84","prefixes":{"*":241}}, // [Scene Stealer Ltd.]
-  {"hash":"227a1699196d5009","prefixes":{"":678}}, // [LiveRamp, Inc.]
-  {"hash":"2077744d64232ddc","prefixes":{"":678}}, // [LiveRamp, Inc.]
-  {"hash":"5ff42e5327d8c926","prefixes":{"":679}}, // [Plista GmbH]
-  {"hash":"1d36941de87ee056","prefixes":{"":679}}, // [Plista GmbH]
-  {"hash":"0534ec41ce34cced","prefixes":{"":679}}, // [Plista GmbH]
-  {"hash":"c5ca32bf780ff41c","prefixes":{"":680}}, // [Netquest Ad Tracking]
-  {"hash":"fcb4d508b7c17d00","prefixes":{"":681}}, // [Mediasmart Mobile S.L.]
-  {"hash":"32de5cdddc7878d9","prefixes":{"":681}}, // [Mediasmart Mobile S.L.]
-  {"hash":"832d7e03cfa50775","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"5d0747bdde7700a5","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"6cda89e3ca547147","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"6825c9c2052b6d49","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"dac91e433fa392a8","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"5112708cd650c1bf","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"8c56edbaad9d7666","prefixes":{"":682}}, // [Netshelter Technology Media, Inc.]
-  {"hash":"e3f867313a3a22ff","prefixes":{"*":683}}, // [Mixmarket Affiliate Network]
-  {"hash":"337d4f2254b699bd","prefixes":{"":683}}, // [Mixmarket Affiliate Network]
-  {"hash":"7dd6cb3709637812","prefixes":{"*":684}}, // [Turbobytes]
-  {"hash":"b42ea914a5e25208","prefixes":{"":685}}, // [Voodoo Video AG]
-  {"hash":"441e902171e2e03a","prefixes":{"*":255}}, // [Google CDN]
-  {"hash":"ed45a52fc3b3ded7","prefixes":{"*":255}}, // [Google CDN]
-  {"hash":"b70fc2e7ac8321a4","prefixes":{"*":255}}, // [Google CDN]
-  {"hash":"a7ab005368d54a08","prefixes":{"*":255}}, // [Google CDN]
-  {"hash":"b3808fd8fb0b9d9b","prefixes":{"*":255}}, // [Google CDN]
-  {"hash":"273fe37ef5880422","prefixes":{"lh":255,"geo":255}}, // [Google CDN] [Google CDN]
-  {"hash":"cf71755ff09e2183","prefixes":{"":255}}, // [Google CDN]
-  {"hash":"3a32bf25eec1a95b","prefixes":{"*":686}}, // [Full Performance]
-  {"hash":"783c5679a80d5c10","prefixes":{"":687}}, // [eXelate Inc.]
-  {"hash":"40f709f76b1af3f1","prefixes":{"":687}}, // [eXelate Inc.]
-  {"hash":"a97762efe739bb85","prefixes":{"*":688}}, // [Oreck Canada]
-  {"hash":"f3460c4c9a5112cc","prefixes":{"":689}}, // [Beijing WuShuang Technology Ltd. (AGrant)]
-  {"hash":"1c1f6d178312c71a","prefixes":{"*":690}}, // [Limelight]
-  {"hash":"227010fe11d13050","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"5460e19d75ae0d01","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"f132b41fc3fed2c5","prefixes":{"":692}}, // [Matomy Media]
-  {"hash":"930103c79d1886c9","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"befa931c2b772e6d","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"e1a46a5a294589c8","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"7aaf1724444529c4","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"a8e6cfd540b8a74b","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"4dd30b722c120fe4","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"5785365f3a4da9e4","prefixes":{"":693}}, // [Mail.Ru Group]
-  {"hash":"b4cbadcc4ab58981","prefixes":{"":694}}, // [LSi - Lionsoft Studios, spol. s r.o.]
-  {"hash":"a41a0099a363da99","prefixes":{"":695}}, // [Adelphic Inc.]
-  {"hash":"9a9d3ceef9c489c7","prefixes":{"":695}}, // [Adelphic Inc.]
-  {"hash":"8c652e1d454ab3a2","prefixes":{"":695}}, // [Adelphic Inc.]
-  {"hash":"36e0703b50fb3eed","prefixes":{"":695}}, // [Adelphic Inc.]
-  {"hash":"a437c97b4d64cafd","prefixes":{"":696}}, // [Lincoln Technical Institute, Inc.]
-  {"hash":"f69a68a2d09d0720","prefixes":{"":697}}, // [Smartstream.tv]
-  {"hash":"26dfb2b8bad92f4f","prefixes":{"":697}}, // [Smartstream.tv]
-  {"hash":"dc67b62ecf5a9b08","prefixes":{"":697}}, // [Smartstream.tv]
-  {"hash":"23b6f2b40a209645","prefixes":{"":697}}, // [Smartstream.tv]
-  {"hash":"40536f7cc3f3bcdb","prefixes":{"":697}}, // [Smartstream.tv]
-  {"hash":"7eab1c802c1cb708","prefixes":{"*":697}}, // [Smartstream.tv]
-  {"hash":"8381e43653c976d7","prefixes":{"":697}}, // [Smartstream.tv]
-  {"hash":"010611867004fb28","prefixes":{"":698}}, // [Reklamport]
-  {"hash":"8c138e749437f931","prefixes":{"":698}}, // [Reklamport]
-  {"hash":"735ef6cfbe0d0549","prefixes":{"":699}}, // [Fattext LLC (DBA Moolah Media)]
-  {"hash":"7a17aa6bfdfb3de1","prefixes":{"":699}}, // [Fattext LLC (DBA Moolah Media)]
-  {"hash":"3c593814e40d8a9e","prefixes":{"":700}}, // [MoGo Marketing & Media Inc.]
-  {"hash":"0f36027c1644631a","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"ec8b441e84a18442","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"b923ca8213dfa24a","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"fe0b93fc6d0ad89a","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"b7164c05e2fb0d2f","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"6e085b0ec37b404f","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"d282ecf2666110dd","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"131054b9a54841da","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"556351c03849a4c1","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"bebf7033727205d4","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"e77b9add119d1d72","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"fbcb122264bcdbda","prefixes":{"":701}}, // [SA Media, llc]
-  {"hash":"10f64b8265e0b1be","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"cc468e0676f36482","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"a445930c60af8d98","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"63e594feafaae08b","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"045d86072bc5dc10","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"ea9d0ea08d06528d","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"94bc93c21ca5d014","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"bcfa082cf700866c","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"17f352a8e88349c9","prefixes":{"":702}}, // [Barons Media LLC]
-  {"hash":"8b18a83b14ef8906","prefixes":{"":703}}, // [apprupt GmbH]
-  {"hash":"46ba596945892a31","prefixes":{"":703}}, // [apprupt GmbH]
-  {"hash":"b0780943092b032a","prefixes":{"":703}}, // [apprupt GmbH]
-  {"hash":"7d76822bfe9ffcd9","prefixes":{"":703}}, // [apprupt GmbH]
-  {"hash":"87582b95561cf002","prefixes":{"":703}}, // [apprupt GmbH]
-  {"hash":"eb0a0cd03ec7f57b","prefixes":{"":704}}, // [PropellerADs media Ltd]
-  {"hash":"73009a8d32988e92","prefixes":{"*":705}}, // [CJ Affiliate by Conversant]
-  {"hash":"698b1ec9df8d6759","prefixes":{"*":705}}, // [CJ Affiliate by Conversant]
-  {"hash":"00e17f99243707e9","prefixes":{"":706}}, // [Millennial Media Inc]
-  {"hash":"62ddc5a87d328e5a","prefixes":{"":706}}, // [Millennial Media Inc]
-  {"hash":"0e02d11afea79a5e","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"56b1e984216b464b","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"815a3c2c1ed6f999","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"28175ac65441fbce","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"fe775b2f045dcced","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"d47b0a700d84bfba","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"1c34827419405aee","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"7e99ada6b2533f54","prefixes":{"":707}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
-  {"hash":"2c5ac4af628363a6","prefixes":{"*":708}}, // [Manage.com Group, Inc.]
-  {"hash":"f05737fe4b72d22f","prefixes":{"":709}}, // [CloudFlare, Inc.]
-  {"hash":"1b728798f387160d","prefixes":{"":710}}, // [MASSMOTIONMEDIA SARL]
-  {"hash":"fb80c91c77673741","prefixes":{"":711}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"6ff7dff7c1404e1b","prefixes":{"":711}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"bd6c259e3bb98101","prefixes":{"":711}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"0dcb02764319e823","prefixes":{"":711}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"258ec0f081f1c767","prefixes":{"":711}}, // [Brainworks Sp. z.o.o.]
-  {"hash":"518594f7ef9754dc","prefixes":{"*":712}}, // [Media Intelligence Platform (Aggregate Knowledge)]
-  {"hash":"223b1b79a6de9f04","prefixes":{"*":712}}, // [Media Intelligence Platform (Aggregate Knowledge)]
-  {"hash":"848f45768ee0ad4e","prefixes":{"":713}}, // [S4M]
-  {"hash":"77b7e5f4ec17a6e5","prefixes":{"":713}}, // [S4M]
-  {"hash":"f965c1f8d2cce837","prefixes":{"":713}}, // [S4M]
-  {"hash":"3e327352cea146b3","prefixes":{"":713}}, // [S4M]
-  {"hash":"0658ca5e4baec224","prefixes":{"":713}}, // [S4M]
-  {"hash":"f2e7a2604319636b","prefixes":{"":713}}, // [S4M]
-  {"hash":"c825977950596abc","prefixes":{"":713}}, // [S4M]
-  {"hash":"b55fc4c23b864e56","prefixes":{"":713}}, // [S4M]
-  {"hash":"3eddbbcdb5a13a1b","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"f133f36dd9e9688d","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"06ead346af8ecc6d","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"16a442ad35246027","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"778068a948335ee6","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"2bb088766e0a77ce","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"f54b41faf3e29ddb","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"3d71c7985374fc62","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"de336679348d46a5","prefixes":{"":714}}, // [Sobmag LTD]
-  {"hash":"6818fc4cb694f0d4","prefixes":{"*":715}}, // [Netbooster]
-  {"hash":"5682fbd14ad230ca","prefixes":{"":716}}, // [Musikhaus Thomann e.K.]
-  {"hash":"abbb14ff2ab0311d","prefixes":{"":716}}, // [Musikhaus Thomann e.K.]
-  {"hash":"578726cfc508157e","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"a141aaa30beb2f05","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"9161fa28951da89a","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"2e52f74b27e9eb2f","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"0ecdef2f55913790","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"409546c7e7a9ce63","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"3dceafc40a01cd8c","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"e748a008fcd2910c","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"499e3537aead5990","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"aad99655e792b7af","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"df381181135b37f3","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"49fe77e073f907d5","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"fe445db4579e7177","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"f7038d35f22c32db","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"184913b8eec78f63","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"4db6f08af3d6cf66","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"0a71646e475ff9c1","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"7847dd8c5608a507","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"cde33b0511f42c7c","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"6a5ae5d2380647dc","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"0821cc1422e91328","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"0e157baa999502bc","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"cb93fe6df3fe4097","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"657c19e08d899173","prefixes":{"":146}}, // [SiteScout AdServer]
-  {"hash":"e411fd988f243d89","prefixes":{"":717}}, // [Trovit]
-  {"hash":"1ea512003540106b","prefixes":{"":717}}, // [Trovit]
-  {"hash":"48255f09ec2021d3","prefixes":{"":717}}, // [Trovit]
-  {"hash":"7b5b7cfa3d62a886","prefixes":{"":717}}, // [Trovit]
-  {"hash":"1235b8279a106276","prefixes":{"":718}}, // [O2online]
-  {"hash":"cf76706eea2f0be6","prefixes":{"":719}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"766b747f8dec4417","prefixes":{"":720}}, // [Meteora]
-  {"hash":"270677f86b7f115b","prefixes":{"":720}}, // [Meteora]
-  {"hash":"0a500f94a8a562f0","prefixes":{"":721}}, // [Madison Logic, Inc.]
-  {"hash":"764d3a17a9512438","prefixes":{"":721}}, // [Madison Logic, Inc.]
-  {"hash":"38c3aac1b79f0478","prefixes":{"":721}}, // [Madison Logic, Inc.]
-  {"hash":"babcc401d384553f","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"2ddae58a55ab72ef","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"db564708d2871d3a","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"a4199cfcbe70d7f5","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"e6f5851275bc1fb3","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"16e6d7e84ad7fa3a","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"58ae73a3bb4327d7","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"366a0ad35670aef5","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"5b30682b9dfa7060","prefixes":{"":722}}, // [万相DSP(IZP Technologies)]
-  {"hash":"67128a22cdd1a7cd","prefixes":{"":23}}, // [AppNexus Open AdStream]
-  {"hash":"db56992e1a1a3f90","prefixes":{"":723}}, // [righTarget]
-  {"hash":"479ab75d77a40d72","prefixes":{"":723}}, // [righTarget]
-  {"hash":"17bcd2af46fb1fe6","prefixes":{"":723}}, // [righTarget]
-  {"hash":"45681f09a76fe33e","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"612f6aab80bc21df","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"ab7e80409519ca9d","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"a3ae7b8a84f28040","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"b25f21b316565014","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"cc9eeba2126e4261","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"9d4819b235a5272b","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"78bb032f283d8f48","prefixes":{"":725}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
-  {"hash":"de11a5b150526c21","prefixes":{"":725}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
-  {"hash":"bbd9e4a668c4e348","prefixes":{"":725}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
-  {"hash":"c38a1d9eab08d787","prefixes":{"*":724}}, // [e.QQ.com]
-  {"hash":"5b2c8d90176bd14e","prefixes":{"":724}}, // [e.QQ.com]
-  {"hash":"62980dc2fa42e1e0","prefixes":{"*":724}}, // [e.QQ.com]
-  {"hash":"9b37bab01bf28d39","prefixes":{"*":726}}, // [Bannercockpit]
-  {"hash":"01ec60ee4671b195","prefixes":{"":727}}, // [Outrigger Media Inc.]
-  {"hash":"4be86c0a73547960","prefixes":{"":727}}, // [Outrigger Media Inc.]
-  {"hash":"e3ab574adac96838","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"91bb53a0f22994f8","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"fd65eb28a70ed09a","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"9f41f821ddcb5092","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"ee70168f83fb2cce","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"c15fc4a18b25e6d3","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"f5f66dfaf3d2d2a3","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"e6e8716836c8a21d","prefixes":{"":105}}, // [Rockabox Media Ltd]
-  {"hash":"da37db68457e2782","prefixes":{"*":728}}, // [shopLocal]
-  {"hash":"ab8c1ee046adfbb1","prefixes":{"*":729}}, // [Impact Radius]
-  {"hash":"0e8c1ff7462c1084","prefixes":{"*":729}}, // [Impact Radius]
-  {"hash":"8f228d8317e4718d","prefixes":{"":729}}, // [Impact Radius]
-  {"hash":"29d7e31af4b1be0b","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"efeab3df1fe3849a","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"8f2fea31a1c79b34","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"9cda8eeaf1e150bf","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"714091c1b8581de0","prefixes":{"":731}}, // [Unister Media GmbH]
-  {"hash":"c7002b2b9e4b5370","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"1802591342537dae","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"787cbd14bb54b647","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"084ef5666af6a26c","prefixes":{"":730}}, // [Unister AdServer]
-  {"hash":"df72b5eb4be388d1","prefixes":{"":732}}, // [TLV Media Online Ltd]
-  {"hash":"64ffcabaf6ec2bcf","prefixes":{"":733}}, // [d3media AG]
-  {"hash":"a6d58332a182c9f4","prefixes":{"":733}}, // [d3media AG]
-  {"hash":"0bbd108959983b32","prefixes":{"":734}}, // [Innovative Metrics]
-  {"hash":"80eab7dfc5e4cc5f","prefixes":{"*":735}}, // [AthenaHealth]
-  {"hash":"131ce36599fa0d6c","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"9181181a015040bc","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"fca830abc4829657","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"e78333a733c1b05a","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"3f82423bd28a526a","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"f2da501e4086afa3","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"719080d33b283abc","prefixes":{"":736}}, // [TAPVALUE SAS]
-  {"hash":"3502e0d544b9b739","prefixes":{"":737}}, // [Meteor Worldwide LLC.]
-  {"hash":"a6227ad6f805c298","prefixes":{"":737}}, // [Meteor Worldwide LLC.]
-  {"hash":"0933cf49bb328213","prefixes":{"*":189}}, // [Relay42 Technology B.V.]
-  {"hash":"bea1d6b2a32d3927","prefixes":{"*":189}}, // [Relay42 Technology B.V.]
-  {"hash":"8d1313bfd522fcf6","prefixes":{"":738}}, // [Audience2Media Limited]
-  {"hash":"ec4f449051680a17","prefixes":{"":738}}, // [Audience2Media Limited]
-  {"hash":"9badeeb4c9cff3b3","prefixes":{"":739}}, // [HRB Digital LLC.]
-  {"hash":"e0e362bb66a6c5dd","prefixes":{"*":740}}, // [!NOOB]
-  {"hash":"e1e1866cde6f23c7","prefixes":{"":163}}, // [Tagtoo Tech Limited]
-  {"hash":"60a41acd40c494b4","prefixes":{"":163}}, // [Tagtoo Tech Limited]
-  {"hash":"4dbc45b703241615","prefixes":{"":163}}, // [Tagtoo Tech Limited]
-  {"hash":"d11722ff46ba063b","prefixes":{"":163}}, // [Tagtoo Tech Limited]
-  {"hash":"706cd1e56e4ca9f0","prefixes":{"":163}}, // [Tagtoo Tech Limited]
-  {"hash":"eabe2f56a564ea71","prefixes":{"":125}}, // [Mocean mobile, Inc.]
-  {"hash":"9ab3f80172f06a67","prefixes":{"":125}}, // [Mocean mobile, Inc.]
-  {"hash":"19c44c882811c0bd","prefixes":{"":741}}, // [OSV online]
-  {"hash":"1f888bdc491d19c5","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"3259bacc0853f3ce","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"4a7fe8ed74a69bb1","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"72680bf564258b75","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"d25a0b5dd4617071","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"4e53e370f5c0d9c8","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"2585ec8519ec2a03","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"9ebfdd26621d46c7","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"083fd3b939cbd105","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"3fd28ace41da6736","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"3f5d8ed1881e0849","prefixes":{"":742}}, // [Addroid™]
-  {"hash":"4f0f13d0fae2b262","prefixes":{"":743}}, // [AdAccess]
-  {"hash":"5a40dbdf15bc0d0c","prefixes":{"":743}}, // [AdAccess]
-  {"hash":"0eff5ff163f074f0","prefixes":{"":743}}, // [AdAccess]
-  {"hash":"f5ce32de4ea8770e","prefixes":{"":743}}, // [AdAccess]
-  {"hash":"8a367cea803ead3b","prefixes":{"":743}}, // [AdAccess]
-  {"hash":"960b38f18a31bf7f","prefixes":{"":743}}, // [AdAccess]
-  {"hash":"45b03c5f8881301a","prefixes":{"":744}}, // [Yabuka Media, Inc.]
-  {"hash":"c2875e9f5741c896","prefixes":{"":744}}, // [Yabuka Media, Inc.]
-  {"hash":"46751092d6f82d66","prefixes":{"":744}}, // [Yabuka Media, Inc.]
-  {"hash":"379f0fda3a2142b3","prefixes":{"*":745}}, // [Highwinds CDN]
-  {"hash":"5033b8e8796bc944","prefixes":{"":746}}, // [Bridgewell Incorporated]
-  {"hash":"fcbb4f6f5d116bcf","prefixes":{"":746}}, // [Bridgewell Incorporated]
-  {"hash":"6d68bbc023aff7a8","prefixes":{"":746}}, // [Bridgewell Incorporated]
-  {"hash":"98a17e63899d6f0f","prefixes":{"":746}}, // [Bridgewell Incorporated]
-  {"hash":"1cae38f50bbcbe1a","prefixes":{"":746}}, // [Bridgewell Incorporated]
-  {"hash":"df13ce542b6c0e84","prefixes":{"":747}}, // [Bidtheatre AB]
-  {"hash":"f9e2fc82f27f7b60","prefixes":{"":747}}, // [Bidtheatre AB]
-  {"hash":"0d324dc8c79d8b3c","prefixes":{"":747}}, // [Bidtheatre AB]
-  {"hash":"1d9569d0ee02dcee","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"73bd54b1be5e9df1","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"dae6130e1d796d90","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"53335dc721cbee0b","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"ae279eee4c5b4941","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"684276719f3b5728","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"b7376659acddae09","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"aa7f623da51e1603","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"6785583c4297f7c5","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"20138e51a97d179b","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"cc3a77dca011bc78","prefixes":{"":748}}, // [AdMoment]
-  {"hash":"6d441f7565cc5de4","prefixes":{"":749}}, // [UDG München GmbH]
-  {"hash":"f8c1c6199f46e722","prefixes":{"":749}}, // [UDG München GmbH]
-  {"hash":"151a96d84e31a957","prefixes":{"":749}}, // [UDG München GmbH]
-  {"hash":"5d34fdb93148d891","prefixes":{"":750}}, // [Pixalate, Inc.]
-  {"hash":"6855407f17ce6aec","prefixes":{"":750}}, // [Pixalate, Inc.]
-  {"hash":"b9f9a074ce5d4d07","prefixes":{"":750}}, // [Pixalate, Inc.]
-  {"hash":"41ddcdd6ba9e42fe","prefixes":{"":750}}, // [Pixalate, Inc.]
-  {"hash":"c72923bea1fa64ce","prefixes":{"":751}}, // [InMobi Inc.]
-  {"hash":"9085e035c617887b","prefixes":{"":751}}, // [InMobi Inc.]
-  {"hash":"0f7037ee4e476493","prefixes":{"":751}}, // [InMobi Inc.]
-  {"hash":"bdfbe6247c640d80","prefixes":{"":752}}, // [Crisp Media Inc.]
-  {"hash":"2cb723bdc82533b2","prefixes":{"":752}}, // [Crisp Media Inc.]
-  {"hash":"be72bf3ef3e3bd14","prefixes":{"":752}}, // [Crisp Media Inc.]
-  {"hash":"3af5f91fedb0e598","prefixes":{"":752}}, // [Crisp Media Inc.]
-  {"hash":"9feb6dbe57a5ab9b","prefixes":{"":752}}, // [Crisp Media Inc.]
-  {"hash":"1953012d699dc24e","prefixes":{"":753}}, // [Choozle, Inc.]
-  {"hash":"560479fb0478e76e","prefixes":{"":753}}, // [Choozle, Inc.]
-  {"hash":"fb3c191358de9e97","prefixes":{"*":754}}, // [Tapad]
-  {"hash":"faa63745af097785","prefixes":{"*":755}}, // [ReachLocal, Inc]
-  {"hash":"c6a0024a8fdbd244","prefixes":{"":756}}, // [OpenX Ad Exchange]
-  {"hash":"1b09e9588e619f63","prefixes":{"":756}}, // [OpenX Ad Exchange]
-  {"hash":"c923ecff86d0026f","prefixes":{"":756}}, // [OpenX Ad Exchange]
-  {"hash":"0b38e9ab66f134b5","prefixes":{"":756}}, // [OpenX Ad Exchange]
-  {"hash":"b07b0a6a32b39c67","prefixes":{"rtb-":756}}, // [OpenX Ad Exchange]
-  {"hash":"a66019bd1d8d6523","prefixes":{"":757}}, // [OpenX]
-  {"hash":"3461a8e14dfa7234","prefixes":{"*":756}}, // [OpenX Ad Exchange]
-  {"hash":"50f406d696ea09e2","prefixes":{"*":756}}, // [OpenX Ad Exchange]
-  {"hash":"28f15a404c22c5ae","prefixes":{"":758}}, // [Placester, Inc.]
-  {"hash":"2eabf2a9cc47f6db","prefixes":{"":758}}, // [Placester, Inc.]
-  {"hash":"04e56c0e39ffb379","prefixes":{"":759}}, // [Spiceworks, Inc]
-  {"hash":"a342cde98acae2a3","prefixes":{"":760}}, // [WapStart]
-  {"hash":"816943ad229d59bd","prefixes":{"":760}}, // [WapStart]
-  {"hash":"9aeccecf18437372","prefixes":{"":760}}, // [WapStart]
-  {"hash":"e24006f3d8614cdf","prefixes":{"":760}}, // [WapStart]
-  {"hash":"2678adb8d16c1bd0","prefixes":{"":760}}, // [WapStart]
-  {"hash":"690b9d06ee7b618c","prefixes":{"":760}}, // [WapStart]
-  {"hash":"ba64173aac6883fa","prefixes":{"":760}}, // [WapStart]
-  {"hash":"3f334c96b9489b6f","prefixes":{"":760}}, // [WapStart]
-  {"hash":"4acb6ede5efaa0ce","prefixes":{"":760}}, // [WapStart]
-  {"hash":"f848368a90033112","prefixes":{"":760}}, // [WapStart]
-  {"hash":"fc58526ac2c34887","prefixes":{"":760}}, // [WapStart]
-  {"hash":"bcec64a939aa6248","prefixes":{"":760}}, // [WapStart]
-  {"hash":"2237ba07a36c2440","prefixes":{"":760}}, // [WapStart]
-  {"hash":"9b1bd3e45cc8d37b","prefixes":{"":760}}, // [WapStart]
-  {"hash":"f9447e97a352a2e8","prefixes":{"":760}}, // [WapStart]
-  {"hash":"4aa3c10d0fa51575","prefixes":{"":760}}, // [WapStart]
-  {"hash":"edb1b5b0a2ecd2b9","prefixes":{"":760}}, // [WapStart]
-  {"hash":"3eee53fed713d5b2","prefixes":{"":760}}, // [WapStart]
-  {"hash":"5562c787acd84d8d","prefixes":{"":760}}, // [WapStart]
-  {"hash":"27d45cd108fe99b4","prefixes":{"":760}}, // [WapStart]
-  {"hash":"06da026d99fd30c4","prefixes":{"":760}}, // [WapStart]
-  {"hash":"43e91c0e2d266107","prefixes":{"":760}}, // [WapStart]
-  {"hash":"2b8ee71c143b611a","prefixes":{"":760}}, // [WapStart]
-  {"hash":"31773affdbc2f93f","prefixes":{"":760}}, // [WapStart]
-  {"hash":"24f5edbbeab30fc6","prefixes":{"":760}}, // [WapStart]
-  {"hash":"b1275f1680c5e050","prefixes":{"":760}}, // [WapStart]
-  {"hash":"1f0e98fd24844df9","prefixes":{"":760}}, // [WapStart]
-  {"hash":"207973ef90437496","prefixes":{"":760}}, // [WapStart]
-  {"hash":"5e573612b3181547","prefixes":{"":760}}, // [WapStart]
-  {"hash":"5237a5b231dbf245","prefixes":{"":760}}, // [WapStart]
-  {"hash":"b4872bd493703ef0","prefixes":{"":760}}, // [WapStart]
-  {"hash":"7268f40680faccfd","prefixes":{"":760}}, // [WapStart]
-  {"hash":"f18cc00e2cfb170d","prefixes":{"":760}}, // [WapStart]
-  {"hash":"2be692602def45f7","prefixes":{"":760}}, // [WapStart]
-  {"hash":"5d15e875488cccd1","prefixes":{"":760}}, // [WapStart]
-  {"hash":"7da3afc36d1c6b59","prefixes":{"":760}}, // [WapStart]
-  {"hash":"e0767b1a03a64ce6","prefixes":{"":760}}, // [WapStart]
-  {"hash":"202d0d2b1168aeb8","prefixes":{"":760}}, // [WapStart]
-  {"hash":"5e070df0dbe151e6","prefixes":{"":760}}, // [WapStart]
-  {"hash":"e4337ec6681cbc61","prefixes":{"":760}}, // [WapStart]
-  {"hash":"944f2609259bac7c","prefixes":{"":761}}, // [Ambercrow (Epayments)]
-  {"hash":"8bcd6f943c02d066","prefixes":{"":761}}, // [Ambercrow (Epayments)]
-  {"hash":"f0529ee08a090045","prefixes":{"":761}}, // [Ambercrow (Epayments)]
-  {"hash":"f44423b0de62f78e","prefixes":{"":761}}, // [Ambercrow (Epayments)]
-  {"hash":"00fb6871b70e1fd9","prefixes":{"":761}}, // [Ambercrow (Epayments)]
-  {"hash":"588e459942f9f953","prefixes":{"":762}}, // [Audiencevalue Pte Ltd]
-  {"hash":"2b94a7bb996b3a9c","prefixes":{"":762}}, // [Audiencevalue Pte Ltd]
-  {"hash":"5796b5e246266e0c","prefixes":{"":763}}, // [UNITED. Inc.]
-  {"hash":"aa1ee475645d94b7","prefixes":{"":763}}, // [UNITED. Inc.]
-  {"hash":"716f227b7327feba","prefixes":{"":763}}, // [UNITED. Inc.]
-  {"hash":"44c3a88f2dcdee6f","prefixes":{"":764}}, // [United Bypass Tech]
-  {"hash":"0f010d866f5763fa","prefixes":{"":765}}, // [SAS Naoplay]
-  {"hash":"6a978d7b8efc594d","prefixes":{"":765}}, // [SAS Naoplay]
-  {"hash":"d3e10ee4fc900d26","prefixes":{"":765}}, // [SAS Naoplay]
-  {"hash":"e83a4038aff02b6e","prefixes":{"":765}}, // [SAS Naoplay]
-  {"hash":"acce217e5e09149a","prefixes":{"":765}}, // [SAS Naoplay]
-  {"hash":"3a93fbc111c8603f","prefixes":{"":766}}, // [CuriosityStream]
-  {"hash":"065426aaa5552ffe","prefixes":{"":767}}, // [Alliance Internet (ntree)]
-  {"hash":"9a843715746291f3","prefixes":{"":767}}, // [Alliance Internet (ntree)]
-  {"hash":"2d4ed5b7f85f950a","prefixes":{"n":767}}, // [Alliance Internet (ntree)]
-  {"hash":"86f628e66b67be4d","prefixes":{"":768}}, // [Centraltag]
-  {"hash":"419e8a03b3f16a8c","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"b9ee79ef4e8c15f5","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"46e3b67ae4549155","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"3064ccb85e72d2df","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"1b58e47cefd5e220","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"93b3f973b09c5513","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"607d4f0311eec7af","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"311502ef7317df7d","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"cdf3897e12242607","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"a5a0d71d2f6b631c","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"10f5415b8d24f2b0","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"c126382fcba55688","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"a92d9d96a9338816","prefixes":{"":769}}, // [eTargeting]
-  {"hash":"74549e43319467f8","prefixes":{"":770}}, // [Walmart Inc]
-  {"hash":"3d8d433ae123d216","prefixes":{"":770}}, // [Walmart Inc]
-  {"hash":"6baa1cd3500dc43f","prefixes":{"":771}}, // [Walmart.com]
-  {"hash":"12bc009e74ca3655","prefixes":{"":770}}, // [Walmart Inc]
-  {"hash":"abb8ec1b9995e7db","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"a489082dd8c6d1b0","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"b8eaffd4f3298628","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"fa888dd08124e8f6","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"d33163e42a34ac6b","prefixes":{"":773}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"26271fd98d79e29f","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"f958e80b82fbeb15","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"0efc1cccd29292d2","prefixes":{"*":772}}, // [Extreme Reach, Inc.]
-  {"hash":"ec1cfeb7c8ad8e74","prefixes":{"*":772}}, // [Extreme Reach, Inc.]
-  {"hash":"06ea295dea974069","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"166f6d9041d2cffe","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"d209952bca4546fc","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"8977e19e27e82a31","prefixes":{"":772}}, // [Extreme Reach, Inc.]
-  {"hash":"f276cc84c3030bf7","prefixes":{"":774}}, // [Netflix]
-  {"hash":"cf97c9d0a75da1fb","prefixes":{"":774}}, // [Netflix]
-  {"hash":"acf43321c04d641b","prefixes":{"":774}}, // [Netflix]
-  {"hash":"bb55681ae13b2fa8","prefixes":{"":774}}, // [Netflix]
-  {"hash":"2d5400efd94a66d0","prefixes":{"":774}}, // [Netflix]
-  {"hash":"c4a2daa282a0af48","prefixes":{"":774}}, // [Netflix]
-  {"hash":"670a8e12f579ee63","prefixes":{"":775}}, // [Netflix, Inc.]
-  {"hash":"15b7e69ddffa3a8c","prefixes":{"":775}}, // [Netflix, Inc.]
-  {"hash":"7b7add7c969d93fe","prefixes":{"*":776}}, // [Scarab Personalized Ads]
-  {"hash":"4e1907aa0eb0ff71","prefixes":{"":776}}, // [Scarab Personalized Ads]
-  {"hash":"a3315978597aa707","prefixes":{"":777}}, // [CrowdMob Inc.]
-  {"hash":"452715cede41650c","prefixes":{"":778}}, // [Gruvi Ltd.]
-  {"hash":"36ce2eb140f75f32","prefixes":{"":777}}, // [CrowdMob Inc.]
-  {"hash":"ae6b13daf4bc714d","prefixes":{"":106}}, // [PocketMath]
-  {"hash":"13696777dabedeae","prefixes":{"":779}}, // [Macromill, Inc.]
-  {"hash":"9971928c88e3fa4e","prefixes":{"*":780}}, // [Nielsen (Cross Platform Brand Effect [IAG/TVBE])]
-  {"hash":"65df6515d4615cea","prefixes":{"f":781,"vast-":781,"ivid-":781}}, // [GetIntent] [GetIntent] [GetIntent]
-  {"hash":"b54db54df2c407f8","prefixes":{"":781}}, // [GetIntent]
-  {"hash":"2258062bb1ab01dd","prefixes":{"":781}}, // [GetIntent]
-  {"hash":"630338f7109ea305","prefixes":{"*":781}}, // [GetIntent]
-  {"hash":"b3c93c6142991123","prefixes":{"":781}}, // [GetIntent]
-  {"hash":"6ef8d315575de4c7","prefixes":{"":781}}, // [GetIntent]
-  {"hash":"b7769b25a2035147","prefixes":{"vid-":781}}, // [GetIntent]
-  {"hash":"2e2859be7da1ee82","prefixes":{"":782}}, // [Belboon]
-  {"hash":"ff591094a6a13480","prefixes":{"*":783}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"3bd09c8fad6ac0cd","prefixes":{"*":783}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"41385cd812900dd3","prefixes":{"*":783}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"78bdf43617c9f3ed","prefixes":{"":784}}, // [Hindustan Times Mobile Solutions Limited]
-  {"hash":"f669a1035330e753","prefixes":{"*":783}}, // [Ozone Media Solutions Pvt Ltd]
-  {"hash":"74c5a373ee6172a1","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"3762c6694e48ada4","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"885e91388dd960b6","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"f6a553969be0331b","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"48d6fc29b318593f","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"1e571da94b4242ba","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"e6770fd6222ae990","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"20b17ee9acc1afb9","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"c483854c67d0c950","prefixes":{"":785}}, // [SoftLayer Technologies, Inc.]
-  {"hash":"5214f14e27a71d7f","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"61c576ffa8275ef3","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"c6af9ddc14757f86","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"86e9128d66cc0207","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"c71d0bd2e6f83f82","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"97be67a3b0baedf9","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"9622fe3e417564fb","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"a63ebe94fca61ed9","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"bbc1dd12d3cdb0b4","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"962da7f5c63ff169","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"94bb51394747c625","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"3ff8867b3d239d21","prefixes":{"":786}}, // [GoldSpot Media]
-  {"hash":"a970a6e82a98c461","prefixes":{"":787}}, // [Zeeto Media]
-  {"hash":"4c975affcaea9100","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"dfd86d0838962249","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"91f2b2338b35b7b2","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"3bec5ca280ea1b83","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"3d88758bd6e0003a","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"5c4e7b396a2ff6d6","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"a95488bd107fec32","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"aa8e84bd80448410","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"63a0cca4218135c9","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"91a1733ac5874a1c","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"5c8abc657915fd35","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"917cc91081fe5b07","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"a53545381bdd0cbf","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"4bc186645ccbf442","prefixes":{"":788}}, // [DYNADMIC SAS]
-  {"hash":"3d6ddf04f9124237","prefixes":{"":789}}, // [Yoc Mobile Advertising GmbH]
-  {"hash":"ec5fe7560209f819","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"5fe3e321ae6e4bf6","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"8be056c242dd9d72","prefixes":{"":359}}, // [Quantcast Inc.]
-  {"hash":"f8ee5abf7ea1abc7","prefixes":{"":790}}, // [Velti]
-  {"hash":"59f840ce07769698","prefixes":{"":790}}, // [Velti]
-  {"hash":"e013843f461a8d4b","prefixes":{"":790}}, // [Velti]
-  {"hash":"bfe3cf089cc18922","prefixes":{"":790}}, // [Velti]
-  {"hash":"9bd20c9549f20865","prefixes":{"":791}}, // [Lockon]
-  {"hash":"f24f331de69a707a","prefixes":{"":791}}, // [Lockon]
-  {"hash":"566f866251bd714e","prefixes":{"":791}}, // [Lockon]
-  {"hash":"4baa350d3cc68f76","prefixes":{"":792}}, // [Recruit Co., Ltd. Communications]
-  {"hash":"9bc564a146df07e7","prefixes":{"":792}}, // [Recruit Co., Ltd. Communications]
-  {"hash":"35c56cfd7e378fad","prefixes":{"":793}}, // [RECRUIT Communications]
-  {"hash":"6b9aad5cb94eb206","prefixes":{"":793}}, // [RECRUIT Communications]
-  {"hash":"671a4bc2e5c9113e","prefixes":{"":794}}, // [Hatena Co., Ltd]
-  {"hash":"6d3fdce985f31bd4","prefixes":{"":795}}, // [Trafmag]
-  {"hash":"1a311d346529c16b","prefixes":{"":795}}, // [Trafmag]
-  {"hash":"cd26b0ae13c2440e","prefixes":{"":796}}, // [Pagewoo]
-  {"hash":"06e9b4b216458951","prefixes":{"":797}}, // [Adnet Media]
-  {"hash":"cc0e43344ef5e735","prefixes":{"":797}}, // [Adnet Media]
-  {"hash":"2bff36578242b6b3","prefixes":{"":797}}, // [Adnet Media]
-  {"hash":"6bcb758317103435","prefixes":{"":797}}, // [Adnet Media]
-  {"hash":"5819339a3e48afa9","prefixes":{"":797}}, // [Adnet Media]
-  {"hash":"4249805768b5eaf7","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"c5d5cf4beb6462cf","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"41b628c1a22b441e","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"88d751d3810273e3","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"41ec9f7d9d627e03","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"02eb3f21dd6df789","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"6b48a245a94ab12a","prefixes":{"":798}}, // [Ligatus GmbH]
-  {"hash":"41d07cfbdb75024a","prefixes":{"":799}}, // [Webtrekk GmbH]
-  {"hash":"be359c4fcc3f3a06","prefixes":{"":799}}, // [Webtrekk GmbH]
-  {"hash":"6f767739019dd808","prefixes":{"":799}}, // [Webtrekk GmbH]
-  {"hash":"f253ef05e042b018","prefixes":{"":800}}, // [Kantar World Panel]
-  {"hash":"d01896485cd39018","prefixes":{"":800}}, // [Kantar World Panel]
-  {"hash":"0e0818ed2e61ee95","prefixes":{"":801}}, // [PubSquared LLC]
-  {"hash":"b05f21964e55a827","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"d333d9afb4898681","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"1639db8eb5956a46","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"5549a4c097f9b83d","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"1dbbc11fea26048b","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"098ed47c32246e74","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"48556c67606eaf5a","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"e9846bc3bb03a920","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"49353a0b9f2b5bb5","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"96bcc9c54b64eb5b","prefixes":{"":802}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
-  {"hash":"f6e1c581da74f06c","prefixes":{"":803}}, // [travel audience GmbH]
-  {"hash":"a00eb1259ded5bb1","prefixes":{"":803}}, // [travel audience GmbH]
-  {"hash":"8026726dce357c58","prefixes":{"":804}}, // [Krux Digital, Inc.]
-  {"hash":"95e17daf76b8a492","prefixes":{"":804}}, // [Krux Digital, Inc.]
-  {"hash":"e2aedb8e35ba9ad0","prefixes":{"":804}}, // [Krux Digital, Inc.]
-  {"hash":"7e954379b20a3955","prefixes":{"":804}}, // [Krux Digital, Inc.]
-  {"hash":"bb2cd97362773074","prefixes":{"":804}}, // [Krux Digital, Inc.]
-  {"hash":"5f545b8ac29b5d2d","prefixes":{"":805}}, // [The Weather Channel]
-  {"hash":"188340d4038f111f","prefixes":{"":805}}, // [The Weather Channel]
-  {"hash":"88ce1340354cf56f","prefixes":{"":805}}, // [The Weather Channel]
-  {"hash":"6aa9e1031d5ce5ea","prefixes":{"":806}}, // [Social Quantum]
-  {"hash":"924b0bbf98095055","prefixes":{"":806}}, // [Social Quantum]
-  {"hash":"a8316ec9f577d677","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"4987a53ffae0e799","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"afafb80716e16e29","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"d0487d64f040dbfa","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"2c543734a4cbc5dd","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"067045f689cb5363","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"7ff291f0586a3dca","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"0a19a7d8484e10da","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"4614ce2d8cea29b5","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"c3164e283cfacd29","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"a1df629f546b9e31","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"6cbf35f72f18a347","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"1cb0768d21f55dd6","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"085272e0502f18c3","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"64b888da84877b17","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"c579af2db70b5cc0","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"306de8baaf32da18","prefixes":{"":807}}, // [AdVentori SAS]
-  {"hash":"1e9f7eb550327800","prefixes":{"":808}}, // [MindTake Research GmbH]
-  {"hash":"1c922be621564b9b","prefixes":{"":808}}, // [MindTake Research GmbH]
-  {"hash":"b3f33aa4d02b6fb2","prefixes":{"":809}}, // [Leger Marketing]
-  {"hash":"eead3245cdc680da","prefixes":{"":809}}, // [Leger Marketing]
-  {"hash":"1239f4aeb30a0c6e","prefixes":{"":810}}, // [BlisMedia Limited]
-  {"hash":"544a45aa905f9c6e","prefixes":{"":810}}, // [BlisMedia Limited]
-  {"hash":"c5e4c8510e3cac80","prefixes":{"":811}}, // [Double6]
-  {"hash":"d0fa41ada692b1b9","prefixes":{"":812}}, // [TRADEADS INTERACTIVE]
-  {"hash":"3db0a72bcd75db25","prefixes":{"":813}}, // [Epigrams, Inc.]
-  {"hash":"f42d4e28510cfcb3","prefixes":{"":813}}, // [Epigrams, Inc.]
-  {"hash":"22d2d672aad6f400","prefixes":{"":814}}, // [Activecore Inc.]
-  {"hash":"1ab5c06bec002a04","prefixes":{"":814}}, // [Activecore Inc.]
-  {"hash":"c34010f1f0a2a2bd","prefixes":{"":814}}, // [Activecore Inc.]
-  {"hash":"b274e3909d6409ff","prefixes":{"":815}}, // [Activecore,Inc.]
-  {"hash":"1bdc7aff17b34632","prefixes":{"":815}}, // [Activecore,Inc.]
-  {"hash":"a5f385ad8794bbf7","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"7fbf5ab845c319c3","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"636714c3598df906","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"9e6785892cd34bdd","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"047573e0075b371a","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"30468687bd7540d7","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"d38c33250529e4cf","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"311b59743017ebda","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"fceae2ba76fa56d8","prefixes":{"":816}}, // [ADCASH]
-  {"hash":"e3e53a304101f0b8","prefixes":{"*":817}}, // [Videoplaza]
-  {"hash":"66ae7f0627345a0e","prefixes":{"":818}}, // [Targetix LLC]
-  {"hash":"f2825950bbc13084","prefixes":{"":818}}, // [Targetix LLC]
-  {"hash":"5844bebbb6ebc2c8","prefixes":{"":818}}, // [Targetix LLC]
-  {"hash":"af1d9e1f4d4a29ee","prefixes":{"":818}}, // [Targetix LLC]
-  {"hash":"eabbec12e479563f","prefixes":{"":818}}, // [Targetix LLC]
-  {"hash":"063e5c59c898b6b2","prefixes":{"":818}}, // [Targetix LLC]
-  {"hash":"768e497f05eb9210","prefixes":{"":819}}, // [Adriver LLC]
-  {"hash":"a3e9e1ffdc9ef6f3","prefixes":{"":820}}, // [Beso]
-  {"hash":"dc3b4a3bb1a98472","prefixes":{"*":821}}, // [Voopter.com]
-  {"hash":"608c4fc0e1249087","prefixes":{"":822}}, // [Hostbasket]
-  {"hash":"ec50bd1f8e55703a","prefixes":{"":823}}, // [Rollad]
-  {"hash":"75f08f4a618e4c29","prefixes":{"":823}}, // [Rollad]
-  {"hash":"5e28845a397448ed","prefixes":{"":823}}, // [Rollad]
-  {"hash":"43baf1a2f5c604eb","prefixes":{"":823}}, // [Rollad]
-  {"hash":"9113c91f7c97eda8","prefixes":{"":823}}, // [Rollad]
-  {"hash":"6e46faf33af4223b","prefixes":{"":823}}, // [Rollad]
-  {"hash":"b8629ee4f4882cf4","prefixes":{"":823}}, // [Rollad]
-  {"hash":"c580bf68b5705ecc","prefixes":{"":823}}, // [Rollad]
-  {"hash":"30c1badbfab295cc","prefixes":{"":823}}, // [Rollad]
-  {"hash":"07206ed226f7d186","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"af031421c35c12bb","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"c1e9215522e84feb","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"f99b1e1004ffe36c","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"cc5aed10326009cd","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"a59bac0d7936d725","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"85c92ca45eb6137a","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"ecfa86f147eea591","prefixes":{"":824}}, // [hdtMedia]
-  {"hash":"89c418c61cc46dbf","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"36712fa880f9f4fd","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"77af178b53829cee","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"19e3098ce56eae94","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"605d50a0c132e0b5","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"9cb69b24762928be","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"7ad4195e3856bc8b","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"a1f419f69f83a3cb","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"a8184454cf33a5e3","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"8c22c5755c763066","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"862c4454fe07929d","prefixes":{"":826}}, // [ebuilders BV]
-  {"hash":"ac0afa5e86463dcf","prefixes":{"":827}}, // [COADVERTISE]
-  {"hash":"049d375ddb03cca6","prefixes":{"":827}}, // [COADVERTISE]
-  {"hash":"2ce968c3c01dac2b","prefixes":{"":828}}, // [Blizzard]
-  {"hash":"6e4734c6df5289ef","prefixes":{"":828}}, // [Blizzard]
-  {"hash":"9fe6f25a55c854ab","prefixes":{"":829}}, // [Adgibbon]
-  {"hash":"008bfe35bcbd016d","prefixes":{"":829}}, // [Adgibbon]
-  {"hash":"084705198bf3893b","prefixes":{"":829}}, // [Adgibbon]
-  {"hash":"a1b65ade9cc861cb","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"42f9c0b081bf4152","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"ea90626af94135dd","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"ae4cfcc8964ff838","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"29ed865d96c2134b","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"f0ad420cd06e916d","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"02fa3036dfdd1f55","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"2e1689e37ca87292","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"e0f93c05dad3c3c6","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"3a2e2804dc9fbb61","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"deed6c9248e53552","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"c4597285474e8048","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"e127ffe380012cba","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"2f548a00d118d32e","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"015756b75eb89403","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"35d2e95d1522b0c5","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"a43e409504b254d3","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"5a4147bb67b5b23c","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"9866a49aaacb720e","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"f101934b33880c8d","prefixes":{"":830}}, // [Wider Planet, Inc.]
-  {"hash":"5fc0aea809357158","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"ed7b8006e50dc195","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"fe112ea448efa84b","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"807a0ad2ef7d844d","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"24daf2e5c1e30aeb","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"9091656f8979f5f0","prefixes":{"":107}}, // [Kpsule]
-  {"hash":"bb5ef61e19944a06","prefixes":{"":831}}, // [ResponsiveAds, Inc]
-  {"hash":"ef4fefbe73da4a59","prefixes":{"":831}}, // [ResponsiveAds, Inc]
-  {"hash":"e78ef2faad563e6b","prefixes":{"":831}}, // [ResponsiveAds, Inc]
-  {"hash":"20e99abfa9e5de7c","prefixes":{"":831}}, // [ResponsiveAds, Inc]
-  {"hash":"0dedc650dbf5d391","prefixes":{"":831}}, // [ResponsiveAds, Inc]
-  {"hash":"5bdaec9fd3ff4dac","prefixes":{"":832}}, // [Duepuntozero Research SRL]
-  {"hash":"318bfe954294ea40","prefixes":{"":833}}, // [AdMovate, Inc.]
-  {"hash":"e24259ffed4d244f","prefixes":{"":833}}, // [AdMovate, Inc.]
-  {"hash":"c39b0621d7a8b616","prefixes":{"":834}}, // [go.pl]
-  {"hash":"29c359aefdd48c40","prefixes":{"":834}}, // [go.pl]
-  {"hash":"6ecf3c2aeb5aec2b","prefixes":{"":834}}, // [go.pl]
-  {"hash":"eea1a3478557a7a6","prefixes":{"":834}}, // [go.pl]
-  {"hash":"0b0e365de9c89436","prefixes":{"":834}}, // [go.pl]
-  {"hash":"875d9d8b11a6dff7","prefixes":{"":834}}, // [go.pl]
-  {"hash":"5edb8f1a6337d5d0","prefixes":{"":834}}, // [go.pl]
-  {"hash":"435808ca4dd1dce5","prefixes":{"":834}}, // [go.pl]
-  {"hash":"fd43d007391147de","prefixes":{"":710}}, // [MASSMOTIONMEDIA SARL]
-  {"hash":"633236a94b694dd7","prefixes":{"":710}}, // [MASSMOTIONMEDIA SARL]
-  {"hash":"a076e91e809efc28","prefixes":{"*":835}}, // [AppLovin Corporation]
-  {"hash":"14c26da0caac0796","prefixes":{"":836}}, // [twentysix ltd]
-  {"hash":"1f8d7bcebd64d2c9","prefixes":{"":15}}, // [Tamome]
-  {"hash":"41f4c0bf12c8f029","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"e674b14a061bb7d7","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"f485e2bb528d3147","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"82c09e315af7d70c","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"fc2b985669148068","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"cf9a9377bc72c2e4","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"d550149a2d5cfdde","prefixes":{"":336}}, // [EuroAds Group A/S]
-  {"hash":"d51c2c24cd771a6a","prefixes":{"":837}}, // [Epsilon International SA]
-  {"hash":"d34cf98578200c93","prefixes":{"":838}}, // [Zebestof]
-  {"hash":"44c2302577bd8e84","prefixes":{"":838}}, // [Zebestof]
-  {"hash":"52b835c5657206c1","prefixes":{"":838}}, // [Zebestof]
-  {"hash":"caa0c94cf57e2295","prefixes":{"":838}}, // [Zebestof]
-  {"hash":"02e54ec6b0aca548","prefixes":{"":839}}, // [SOL UTD Benelux BV]
-  {"hash":"1cf1a7f5c323d6e0","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"079a647886a5afa5","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"ec320d28ebdfac8c","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"e59449da7e642b45","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"1d61751db94dfc15","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"43f7746544162324","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"4f80c8700c459a79","prefixes":{"":840}}, // [M,P,NEWMEDIA, GmbH]
-  {"hash":"23f62ba113f0fa4f","prefixes":{"":841}}, // [MediaCrossing Inc.]
-  {"hash":"62fc0fc3102b918b","prefixes":{"":842}}, // [MBR Targeting Gmbh]
-  {"hash":"0066f0743ade259b","prefixes":{"":842}}, // [MBR Targeting Gmbh]
-  {"hash":"4288d021c49b7e1b","prefixes":{"":842}}, // [MBR Targeting Gmbh]
-  {"hash":"6620a58a1f4cd480","prefixes":{"":843}}, // [VivaKi]
-  {"hash":"47db57aade94670f","prefixes":{"":843}}, // [VivaKi]
-  {"hash":"2924b77c1d7eab3b","prefixes":{"":843}}, // [VivaKi]
-  {"hash":"d2143dbf1699f4fa","prefixes":{"":844}}, // [Affiliate Window]
-  {"hash":"13c2a94c46886705","prefixes":{"":844}}, // [Affiliate Window]
-  {"hash":"c0d30b023dc9139f","prefixes":{"*":845}}, // [TubeMogul Inc. (AdWords/YouTube)]
-  {"hash":"108d788939e4b7a4","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"6fdc121917e19eb9","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"5262a88cfa363303","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"b597af924fe5ff97","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"dca60f44a70d5d38","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"c44308d5c2e3bb8a","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"90f5b971c961816f","prefixes":{"":825}}, // [DXP Media]
-  {"hash":"5d64c1152c075739","prefixes":{"":846}}, // [Way2traffic Polska S.A.]
-  {"hash":"01b13121d2ce9699","prefixes":{"":846}}, // [Way2traffic Polska S.A.]
-  {"hash":"f48791a2746e2a93","prefixes":{"":847}}, // [TNS Sifo AB]
-  {"hash":"935b8079b74f344c","prefixes":{"":847}}, // [TNS Sifo AB]
-  {"hash":"24e5b8b342d1b1fe","prefixes":{"":848}}, // [3xchange/Hunkal]
-  {"hash":"ad8c8bc165611bf2","prefixes":{"":848}}, // [3xchange/Hunkal]
-  {"hash":"b1b5bdd82d143e90","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"aeddaa071ba3b313","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"474802ea42555e39","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"b28e42ea18df1c00","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"826635800b12eb0c","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"22c10728f555913e","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"0b7f364ef0beed45","prefixes":{"":849}}, // [Emerse Sverige AB]
-  {"hash":"8d31e79105c5380a","prefixes":{"":850}}, // [Sokno Media]
-  {"hash":"037264ef7d8383f6","prefixes":{"":850}}, // [Sokno Media]
-  {"hash":"ff6372e6621d88ba","prefixes":{"":851}}, // [Blackheart, a division of Hot Topic, Inc.]
-  {"hash":"37742852c2a4ccc8","prefixes":{"":852}}, // [Torrid]
-  {"hash":"a86786ce90b23e3f","prefixes":{"":853}}, // [Hot Topic, Inc.]
-  {"hash":"93e1c22a4427a32f","prefixes":{"":854}}, // [WebHue LLC]
-  {"hash":"fca0a42aad108345","prefixes":{"static":855,"img":855,"log":855}}, // [Content to Emotion] [Content to Emotion] [Content to Emotion]
-  {"hash":"15948cae619c2e58","prefixes":{"":855}}, // [Content to Emotion]
-  {"hash":"db2a81c15837ddbd","prefixes":{"":856}}, // [Adman Interactive SL]
-  {"hash":"accf1565984e2899","prefixes":{"":856}}, // [Adman Interactive SL]
-  {"hash":"45351e5c4862b2dd","prefixes":{"":856}}, // [Adman Interactive SL]
-  {"hash":"ba3196c50e6c1be4","prefixes":{"":856}}, // [Adman Interactive SL]
-  {"hash":"eab724fbba4f83d6","prefixes":{"":856}}, // [Adman Interactive SL]
-  {"hash":"0edc8e7b8a8fe3ee","prefixes":{"":857}}, // [AudienceFUEL, Inc.]
-  {"hash":"dfa423315ab48813","prefixes":{"":858}}, // [TapCommerce LLC]
-  {"hash":"777b0f4301aa1643","prefixes":{"":858}}, // [TapCommerce LLC]
-  {"hash":"294cba0ae232447c","prefixes":{"":859}}, // [AdTheorent, Inc.]
-  {"hash":"ba7ad5da6db014c7","prefixes":{"":860}}, // [AdTheorent, Inc]
-  {"hash":"09bfc8a7f1c7896f","prefixes":{"":859}}, // [AdTheorent, Inc.]
-  {"hash":"362136e847a35f7e","prefixes":{"":859}}, // [AdTheorent, Inc.]
-  {"hash":"5492d77bb75e6380","prefixes":{"":861}}, // [Barometric]
-  {"hash":"94bb816c4a375220","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"f10e1a418576d219","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"245fc951b0a9ce59","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"babdceabca3ae2b8","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"c6474114ede3195a","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"26faef64bd072723","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"0a19b1f547a3a935","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"b4ef56642916cc60","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"c1fc9d245fa85b02","prefixes":{"":862}}, // [CrossInstall, Inc]
-  {"hash":"0e3ddb4868b0e99f","prefixes":{"":863}}, // [Theorem Inc.]
-  {"hash":"976d4ea6507dfd2e","prefixes":{"":863}}, // [Theorem Inc.]
-  {"hash":"70a3fe87d3bbbae9","prefixes":{"":863}}, // [Theorem Inc.]
-  {"hash":"1cf1ec002a07d6a4","prefixes":{"":864}}, // [KeyVersion]
-  {"hash":"b2c480f3bc7b03b6","prefixes":{"":864}}, // [KeyVersion]
-  {"hash":"c94dbc0a3ffc6eda","prefixes":{"":865}}, // [Ancestry]
-  {"hash":"04fb46af993df556","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"b9adf25b55c4d0f3","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"1c1211c84dbee054","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"575fafb094c71d93","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"f2b020b3d3861db2","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"609d13c5cd3771c8","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"aeae313934102cfe","prefixes":{"":867}}, // [Shanghai Lijing Advertising Co., Ltd]
-  {"hash":"f8721bcf4d9f6196","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"09e5f7c9f30f4fd6","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"a1ce57d387427206","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"bb4b6377666172c4","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"d6a6a6cd062bc76e","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"0313ce8a9851d837","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"6862450d2314df40","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"0a34c9f6f0cf9556","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"8e311fce80eccafd","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"296fdad7e8336d5a","prefixes":{"":866}}, // [Shanghai Lijing Advertising Co., Ltd.]
-  {"hash":"27c0e177312a3c0f","prefixes":{"":108}}, // [Immedium, Inc.]
-  {"hash":"fc3c7114081863bd","prefixes":{"":108}}, // [Immedium, Inc.]
-  {"hash":"811582f5df157ff9","prefixes":{"":868}}, // [KissNoFrog.com]
-  {"hash":"284d8a4f9b174bab","prefixes":{"":869}}, // [DigiEQ]
-  {"hash":"aa0e7b7a1fe279dc","prefixes":{"":869}}, // [DigiEQ]
-  {"hash":"1f551f934400f81e","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"1c3b94cabbbc5b8c","prefixes":{"":86}}, // [MediaMath Inc.]
-  {"hash":"505b194aeebd6baf","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"8f2e12e9677e4d41","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"e2a3fe5e482432e8","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"7d03cd1b92c167a8","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"532402cd3ab13402","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"48e577ba3e61c748","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"1480a6580cb81dde","prefixes":{"":870}}, // [Mobile Professinals BV]
-  {"hash":"b1ec46dd2c4c824e","prefixes":{"*":109}}, // [Fractional Media, LLC]
-  {"hash":"6c6240697771befd","prefixes":{"*":109}}, // [Fractional Media, LLC]
-  {"hash":"f2e16038c0d83b85","prefixes":{"":871}}, // [Decisive, Inc.]
-  {"hash":"654da4ed85d77fb9","prefixes":{"":871}}, // [Decisive, Inc.]
-  {"hash":"c9e2ea0486216534","prefixes":{"":871}}, // [Decisive, Inc.]
-  {"hash":"546a2acb9b2363f2","prefixes":{"*":872}}, // [Microsoft Security Essentials]
-  {"hash":"9e4f5b2f200fbb25","prefixes":{"":873}}, // [Tumi, Inc. US]
-  {"hash":"4378c60894195c4f","prefixes":{"":874}}, // [Tumi, Inc. UK]
-  {"hash":"61e82c5e74c5ce7c","prefixes":{"":875}}, // [Tumi, Inc. DE]
-  {"hash":"712f010eb9792fa4","prefixes":{"":876}}, // [Nanigans, Inc]
-  {"hash":"589eceaef79619dd","prefixes":{"":876}}, // [Nanigans, Inc]
-  {"hash":"1d66f17c949dbaee","prefixes":{"":876}}, // [Nanigans, Inc]
-  {"hash":"6dbd7b9480163af0","prefixes":{"":876}}, // [Nanigans, Inc]
-  {"hash":"41d56e0870364212","prefixes":{"":139}}, // [Brandscreen Inc.]
-  {"hash":"2d701495cf72af5b","prefixes":{"*":877}}, // [AdSniper LLC]
-  {"hash":"0bd14e8d5a6b2f2d","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"9b504cc586da72e5","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"a89d4cb4490b4286","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"dce925353cbc1dbe","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"ff8d26679ce7dafc","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"11db2fec76a76647","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"00a09e8788ee6f2b","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"709d79bfe214aa48","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"7a37fa5ff1a37799","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"42a24e1ab1c2d947","prefixes":{"":877}}, // [AdSniper LLC]
-  {"hash":"63f4e4d315bc085b","prefixes":{"":878}}, // [Fabric Worldwide Inc]
-  {"hash":"b9c11e67d7eb2963","prefixes":{"":878}}, // [Fabric Worldwide Inc]
-  {"hash":"e3882e6bc0c2e382","prefixes":{"":879}}, // [Vorwerk Deutschland Stiftung & Co. KG]
-  {"hash":"944d86d40b9ae089","prefixes":{"":879}}, // [Vorwerk Deutschland Stiftung & Co. KG]
-  {"hash":"ebd456010571b5ae","prefixes":{"":879}}, // [Vorwerk Deutschland Stiftung & Co. KG]
-  {"hash":"4456fa769be90ba2","prefixes":{"":65}}, // [Active Agent]
-  {"hash":"84d65f5782dd26d6","prefixes":{"":880}}, // [Chico Distribution Services, LLC]
-  {"hash":"a6185f46e2849f58","prefixes":{"":881}}, // [12Mnkys GmbH]
-  {"hash":"bf874935c6972629","prefixes":{"":881}}, // [12Mnkys GmbH]
-  {"hash":"094b301a712414f2","prefixes":{"":881}}, // [12Mnkys GmbH]
-  {"hash":"56ee8d67408b2316","prefixes":{"":881}}, // [12Mnkys GmbH]
-  {"hash":"d62d9c20c47ec863","prefixes":{"":881}}, // [12Mnkys GmbH]
-  {"hash":"bb716a8269a2e79c","prefixes":{"":882}}, // [Spacyz, Inc.]
-  {"hash":"5a6ff8a620bb8de1","prefixes":{"":882}}, // [Spacyz, Inc.]
-  {"hash":"61cf0a8426083e54","prefixes":{"":882}}, // [Spacyz, Inc.]
-  {"hash":"4cf4aa4b0e37fdfd","prefixes":{"":719}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"745acee8f5973f56","prefixes":{"":719}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"9a834a1cc05cb878","prefixes":{"":883}}, // [MBuy, Inc.]
-  {"hash":"73cd161c10ebcf69","prefixes":{"":884}}, // [FullSpeed Inc.]
-  {"hash":"75c72b5cc4c40c16","prefixes":{"":884}}, // [FullSpeed Inc.]
-  {"hash":"33c5c398130ddfec","prefixes":{"":884}}, // [FullSpeed Inc.]
-  {"hash":"1c0653651245a014","prefixes":{"":884}}, // [FullSpeed Inc.]
-  {"hash":"271d057b15f67166","prefixes":{"":884}}, // [FullSpeed Inc.]
-  {"hash":"e9723a229b8b9eeb","prefixes":{"":884}}, // [FullSpeed Inc.]
-  {"hash":"8e3c99c5cc10c217","prefixes":{"":355}}, // [New Allyes Information Technology (winmax)]
-  {"hash":"07141bfb96faa93c","prefixes":{"":885}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"1d7294abbaa26e26","prefixes":{"":885}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"6872272e097d2cd9","prefixes":{"":885}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"66ec8aa560cf2231","prefixes":{"":885}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"17cd9dcba702b7e6","prefixes":{"":885}}, // [Madhouse Co. Limited (OptiMad)]
-  {"hash":"2347e9e88f6ead88","prefixes":{"":886}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"7f19740ff86dc642","prefixes":{"":886}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"18f553670e23734b","prefixes":{"":886}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"ca862d199926ad1c","prefixes":{"":886}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"2238776218564026","prefixes":{"":886}}, // [Nano Interactive / Audiencemanager]
-  {"hash":"d7e222c8d7ba68d8","prefixes":{"*":887}}, // [Youtube, LLC]
-  {"hash":"edff9009064b3fa4","prefixes":{"*":887}}, // [Youtube, LLC]
-  {"hash":"0d60795f6997311e","prefixes":{"":888}}, // [Omnibus co. Ltd]
-  {"hash":"f32008e13be0f96e","prefixes":{"":888}}, // [Omnibus co. Ltd]
-  {"hash":"dd5533aa2d49cc10","prefixes":{"":889}}, // [Omnibus co. Ltd.]
-  {"hash":"3bcd500b684d5142","prefixes":{"":888}}, // [Omnibus co. Ltd]
-  {"hash":"14eef63a2889c8da","prefixes":{"":888}}, // [Omnibus co. Ltd]
-  {"hash":"53f31e427551538d","prefixes":{"":888}}, // [Omnibus co. Ltd]
-  {"hash":"5296819de63f3444","prefixes":{"":888}}, // [Omnibus co. Ltd]
-  {"hash":"d8389fea989da8d7","prefixes":{"":41}}, // [Airpush, Inc.]
-  {"hash":"e251b17a002b679b","prefixes":{"":890}}, // [Education Management Corporation]
-  {"hash":"ec35188a522b7db9","prefixes":{"*":891}}, // [Screen6 (s6.io)]
-  {"hash":"8ee1cf907bbca914","prefixes":{"":892}}, // [LINK Marketing Services AG]
-  {"hash":"18a5decf96e8c80d","prefixes":{"":893}}, // [TiqIQ]
-  {"hash":"8927e5364d1bf1d1","prefixes":{"":893}}, // [TiqIQ]
-  {"hash":"86292c524ac79685","prefixes":{"":893}}, // [TiqIQ]
-  {"hash":"52562df3f7208c8f","prefixes":{"":893}}, // [TiqIQ]
-  {"hash":"a7d6fe32ab078e86","prefixes":{"":893}}, // [TiqIQ]
-  {"hash":"497857c899894a0f","prefixes":{"":893}}, // [TiqIQ]
-  {"hash":"0d8c5ad133d4c83e","prefixes":{"":894}}, // [Ibibo Group Private Limited]
-  {"hash":"a8c10e41d2d4b31a","prefixes":{"":894}}, // [Ibibo Group Private Limited]
-  {"hash":"9699d29520d1b9b8","prefixes":{"":894}}, // [Ibibo Group Private Limited]
-  {"hash":"103308c15ca4c459","prefixes":{"":889}}, // [Omnibus co. Ltd.]
-  {"hash":"d7a1b3fc5e1252ce","prefixes":{"":889}}, // [Omnibus co. Ltd.]
-  {"hash":"ee40bf7c9bae2361","prefixes":{"":895}}, // [justAd TV LTD]
-  {"hash":"8755d187f8ffb5e9","prefixes":{"":895}}, // [justAd TV LTD]
-  {"hash":"1bdf54cf79d18915","prefixes":{"":895}}, // [justAd TV LTD]
-  {"hash":"ed61950d43d99717","prefixes":{"":895}}, // [justAd TV LTD]
-  {"hash":"aff928fc58637cb3","prefixes":{"":896}}, // [Appier Inc.]
-  {"hash":"797f76218537ad5d","prefixes":{"*":896}}, // [Appier Inc.]
-  {"hash":"6bdcdb03ff6173af","prefixes":{"*":896}}, // [Appier Inc.]
-  {"hash":"6a3dec8b5a467987","prefixes":{"*":896}}, // [Appier Inc.]
-  {"hash":"a3d5f58bbde56b12","prefixes":{"":896}}, // [Appier Inc.]
-  {"hash":"7d0adb9089ff21ca","prefixes":{"":896}}, // [Appier Inc.]
-  {"hash":"c241f36263ea7c84","prefixes":{"":897}}, // [Kate Spade Saturday]
-  {"hash":"79dd595e79611766","prefixes":{"":898}}, // [Teufel GmbH]
-  {"hash":"df829b8e840c11e1","prefixes":{"":898}}, // [Teufel GmbH]
-  {"hash":"c3004b48539587e5","prefixes":{"":898}}, // [Teufel GmbH]
-  {"hash":"08eb365a3723ee17","prefixes":{"":898}}, // [Teufel GmbH]
-  {"hash":"71bc88c0bd0dc170","prefixes":{"":898}}, // [Teufel GmbH]
-  {"hash":"fb208e41a565430a","prefixes":{"":899}}, // [Aitarget LLC]
-  {"hash":"6121d39232612f56","prefixes":{"":899}}, // [Aitarget LLC]
-  {"hash":"0ef54a01a72fdbaf","prefixes":{"*":676}}, // [Rackspace, US Inc.]
-  {"hash":"532febae5cf9194f","prefixes":{"":900}}, // [Engage Lab Ltd.]
-  {"hash":"fbfff8f12503c208","prefixes":{"":901}}, // [Signal Digital, Inc dba Signal]
-  {"hash":"14afd1fc2da14d71","prefixes":{"":902}}, // [Motrixi Media Group LLC]
-  {"hash":"aa674bd59dee4716","prefixes":{"":902}}, // [Motrixi Media Group LLC]
-  {"hash":"7fd4fa8a06589cab","prefixes":{"":902}}, // [Motrixi Media Group LLC]
-  {"hash":"56f94b2620357eb5","prefixes":{"":902}}, // [Motrixi Media Group LLC]
-  {"hash":"32ddc8b6874f030b","prefixes":{"":903}}, // [WHITE HOUSE | BLACK MARKET, Chico Brands, Inc.]
-  {"hash":"fea26de6b70aafb9","prefixes":{"":904}}, // [Liftoff Mobile, Inc.]
-  {"hash":"4687be4922e9d22e","prefixes":{"":905}}, // [etracker GmbH]
-  {"hash":"b41f235329fba677","prefixes":{"*":906}}, // [MezzoMedia]
-  {"hash":"3362cc82ba37c826","prefixes":{"":906}}, // [MezzoMedia]
-  {"hash":"7c5cbde65c1f0a61","prefixes":{"":907}}, // [Eyeota Limited]
-  {"hash":"d85ebb0a3c0bdef4","prefixes":{"":908}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"52d134e034c55e1d","prefixes":{"":908}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"9d9805e510965156","prefixes":{"":908}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"5ed6426649a5142e","prefixes":{"":908}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"e629bb2b2df81562","prefixes":{"":908}}, // [Beijing PageChoice Network Technology co., Ltd.]
-  {"hash":"37a1384fb3fc6090","prefixes":{"":270}}, // [Intelliad]
-  {"hash":"9d931008b4067d12","prefixes":{"":909}}, // [Padopolis, Inc.]
-  {"hash":"2e0eb051f10f4fe7","prefixes":{"":909}}, // [Padopolis, Inc.]
-  {"hash":"e4e066ee012dd820","prefixes":{"":910}}, // [Republic Project, Inc.]
-  {"hash":"6bda23da60f6517c","prefixes":{"":910}}, // [Republic Project, Inc.]
-  {"hash":"8af361ef2f58932e","prefixes":{"":910}}, // [Republic Project, Inc.]
-  {"hash":"9cf685ac4bd3c1a0","prefixes":{"":910}}, // [Republic Project, Inc.]
-  {"hash":"ceb2ae18496c4062","prefixes":{"":910}}, // [Republic Project, Inc.]
-  {"hash":"a1c74be312c1e501","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"e2305a44231103a0","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"e9ea3f2053ff0ac5","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"18f65ffdee8f8402","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"dc902603963cc6c8","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"6addef0844f148c5","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"c2889776656d63b3","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"1a1ac1eeae181fe7","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"fa03396d4a303d45","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"f632f69c34840122","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"082e62ce70aa66fc","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"775c7d89c606cd3c","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"74b282bb3c686219","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"a8e1956c97315aaf","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"26dc9f78ec72cc0c","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"c4ef7b6eeeda12ce","prefixes":{"":911}}, // [C8 Network]
-  {"hash":"e78c2b0997dfa249","prefixes":{"":912}}, // [Data Artist Inc.]
-  {"hash":"41045058078214c7","prefixes":{"":912}}, // [Data Artist Inc.]
-  {"hash":"c3b23588f42fedff","prefixes":{"":912}}, // [Data Artist Inc.]
-  {"hash":"5e94c742d87aa747","prefixes":{"":912}}, // [Data Artist Inc.]
-  {"hash":"52632067f5495750","prefixes":{"":913}}, // [AirFrance]
-  {"hash":"0b27c948dba1fda0","prefixes":{"":914}}, // [YDigital Media]
-  {"hash":"7e30f931dbb7180a","prefixes":{"":915}}, // [Zentrick]
-  {"hash":"b3e2285b6fc03e5c","prefixes":{"":915}}, // [Zentrick]
-  {"hash":"e2f247795ad2ad87","prefixes":{"":915}}, // [Zentrick]
-  {"hash":"1c9e4d1810e659fa","prefixes":{"":915}}, // [Zentrick]
-  {"hash":"57511b10e2ed4785","prefixes":{"":915}}, // [Zentrick]
-  {"hash":"c012faa898c62e0b","prefixes":{"":916}}, // [FreeBit Co. Ltd.]
-  {"hash":"41b7f33c961162f8","prefixes":{"":916}}, // [FreeBit Co. Ltd.]
-  {"hash":"ffac4f6c5fa1aa82","prefixes":{"":916}}, // [FreeBit Co. Ltd.]
-  {"hash":"a23bae62ab25e2c1","prefixes":{"":916}}, // [FreeBit Co. Ltd.]
-  {"hash":"ae08459757b76c12","prefixes":{"":916}}, // [FreeBit Co. Ltd.]
-  {"hash":"83efb7fcb7770789","prefixes":{"":917}}, // [Dennoo Inc.]
-  {"hash":"042456e26a44a268","prefixes":{"":917}}, // [Dennoo Inc.]
-  {"hash":"cb0b16dd50ba9d7d","prefixes":{"":917}}, // [Dennoo Inc.]
-  {"hash":"541a895df01d2b2c","prefixes":{"":917}}, // [Dennoo Inc.]
-  {"hash":"8f01887bb7405ab5","prefixes":{"":918}}, // [Adbrain]
-  {"hash":"33734a86766d25a9","prefixes":{"*":919}}, // [MSI-ACI Europe BV]
-  {"hash":"f66543f279b3e1e7","prefixes":{"":920}}, // [A.Mob]
-  {"hash":"74ee8c0f2fb31813","prefixes":{"":920}}, // [A.Mob]
-  {"hash":"584db20b69521f40","prefixes":{"":921}}, // [Toys R Us]
-  {"hash":"6a001e8bc99fede6","prefixes":{"":922}}, // [Geniee,Inc]
-  {"hash":"b8ff7bd604535ea9","prefixes":{"":922}}, // [Geniee,Inc]
-  {"hash":"3e005c1dfdc23488","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"ddef7bb2f5930121","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"424399e643b329b8","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"23df92e04ec66406","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"06f0caf4a4fe6ed1","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"9697a0818cbd79bd","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"ec7f61f2511ae20e","prefixes":{"":923}}, // [Adsecure]
-  {"hash":"fb4e7ecb8304ade4","prefixes":{"":924}}, // [Kimia Solutions SL]
-  {"hash":"84f5d0f934bd60f1","prefixes":{"":924}}, // [Kimia Solutions SL]
-  {"hash":"b3fcc22fcd382f3b","prefixes":{"":924}}, // [Kimia Solutions SL]
-  {"hash":"4eca8c3218b372ae","prefixes":{"":925}}, // [Sojern]
-  {"hash":"9636bfb4feaef839","prefixes":{"":925}}, // [Sojern]
-  {"hash":"a525b67906a4cb94","prefixes":{"":926}}, // [Where 2 Get It, Inc.]
-  {"hash":"6c959985d7181026","prefixes":{"":926}}, // [Where 2 Get It, Inc.]
-  {"hash":"7843db8d760e28cb","prefixes":{"":927}}, // [Tomoko Cloud]
-  {"hash":"eb7b756fc1f88aa1","prefixes":{"":927}}, // [Tomoko Cloud]
-  {"hash":"ed4d672687c27603","prefixes":{"":927}}, // [Tomoko Cloud]
-  {"hash":"b156b34e4d693e49","prefixes":{"":927}}, // [Tomoko Cloud]
-  {"hash":"16e146e87e7d0383","prefixes":{"":928}}, // [RevenueMantra]
-  {"hash":"1457bcbc098b2864","prefixes":{"":928}}, // [RevenueMantra]
-  {"hash":"450eb4f9273a5014","prefixes":{"":929}}, // [Automobile Ltd.]
-  {"hash":"436e4eaa95b23fcb","prefixes":{"":929}}, // [Automobile Ltd.]
-  {"hash":"a47ee9f00ca4f855","prefixes":{"":929}}, // [Automobile Ltd.]
-  {"hash":"889ab5643c83668a","prefixes":{"":929}}, // [Automobile Ltd.]
-  {"hash":"4ea96f1e0388da92","prefixes":{"":930}}, // [Big Mobile Group Pty Ltd]
-  {"hash":"ae895a18cc8c416e","prefixes":{"":930}}, // [Big Mobile Group Pty Ltd]
-  {"hash":"bbb46a7f5062448e","prefixes":{"":931}}, // [ADMIZED AG]
-  {"hash":"0b4e26a40cc2e647","prefixes":{"":932}}, // [Sparks47 s.r.l.]
-  {"hash":"745030cd7ac80402","prefixes":{"":933}}, // [Between Digital dba Intency DSP]
-  {"hash":"55db959f7c533183","prefixes":{"":933}}, // [Between Digital dba Intency DSP]
-  {"hash":"15b9a82ccbf2d7ff","prefixes":{"":933}}, // [Between Digital dba Intency DSP]
-  {"hash":"c63156716e201b52","prefixes":{"":933}}, // [Between Digital dba Intency DSP]
-  {"hash":"801d43da2c97866b","prefixes":{"":933}}, // [Between Digital dba Intency DSP]
-  {"hash":"d9f810d72012d4c4","prefixes":{"":934}}, // [eprofessional GmbH]
-  {"hash":"23c665bb68cc30cc","prefixes":{"":934}}, // [eprofessional GmbH]
-  {"hash":"8439b0c8f73daf02","prefixes":{"":934}}, // [eprofessional GmbH]
-  {"hash":"6a17378968b598f2","prefixes":{"":934}}, // [eprofessional GmbH]
-  {"hash":"4e157cd578931a97","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"9cdf7d74bee2159f","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"58c684b764b4dcab","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"85218b0017b8f452","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"9f790c0c14fa8f4d","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"e7518acf5c44d0a4","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"ec763282f8f41299","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"41a0870b895e73b4","prefixes":{"":936}}, // [ConvertStar Incorporated]
-  {"hash":"f0134a17d368f3d8","prefixes":{"":936}}, // [ConvertStar Incorporated]
-  {"hash":"58f6c00f44fb69a4","prefixes":{"":936}}, // [ConvertStar Incorporated]
-  {"hash":"ff266e088e3010a8","prefixes":{"":937}}, // [VisualDNA (Imagini)]
-  {"hash":"9748c01f8dcd17ee","prefixes":{"":937}}, // [VisualDNA (Imagini)]
-  {"hash":"8e588a0818c4fcfe","prefixes":{"":937}}, // [VisualDNA (Imagini)]
-  {"hash":"b499a754cc7d2c9b","prefixes":{"":937}}, // [VisualDNA (Imagini)]
-  {"hash":"12d363fa8ee6c4d3","prefixes":{"":938}}, // [Avocet]
-  {"hash":"a8bc7b6f66702489","prefixes":{"":938}}, // [Avocet]
-  {"hash":"5166d9515e755f19","prefixes":{"":939}}, // [Auction.com, LLC]
-  {"hash":"3adf8560ada830b8","prefixes":{"":939}}, // [Auction.com, LLC]
-  {"hash":"f24f87c799e92ae5","prefixes":{"":939}}, // [Auction.com, LLC]
-  {"hash":"a60dedada0fd44b6","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5d0f226850d2e68c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e4c703070b535b17","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"bc640a9c42502b35","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"defb06aab760992e","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"9bb069524856b34b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ef253518584f013f","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e100ba963ad8ecf2","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"05b625ee62d8685f","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5a88fb5abffcefc9","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a31c0b568cc8ade8","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"3498894fbeac8341","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1b82605c41d8b709","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"8138ad98ed0394e9","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"751c9ebb221bb5f9","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"8e3793804d9cdab5","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a6ecf1a95c24b6a3","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d27fe0e9834e648b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"2a0c1b5a904b36c1","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"f0d6c35febee8008","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"3c01a29e3c9c7264","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"4a74fdfd9b816fe8","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"aac8184f18b04958","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"368da19a90db3ad7","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"116d46403c6e95b7","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"808bb76ca34e4d1b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"b19f61f6e35aaa6a","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"9afc01573e38d021","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"11d7bce194c54912","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a28be439cad08ebb","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"968792ffe85f5d2d","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d3bc9343531e6c0c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a11d6b37b0382222","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"4bf65fa3bba0c55b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"4e1d992a76cf0b41","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"b09978a8e01fdbca","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"7394b2453f854b55","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a76d4645267ff0be","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"7e60860df0c8945b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ed9d4b0db5598264","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"466d1d16f3a935fb","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"21ac8963bf026e1a","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e04f72461a1fdf7d","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"549860a6933e906e","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ddc7313241f77312","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d89759a9687ad368","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"343ad98c7f4d71ed","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"2cb5047919d88ce8","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e9739ef3b0403f17","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"2b8ce30f483d90da","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1d1295f1cdac7503","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"57fd3c09e35ca17e","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"050dd41acc3ac3be","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1b853fb5c08c8727","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1c3db6034ad5c3e7","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"4b87160668f51e71","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d0875bc7510fbaa1","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a46257724ca67bc0","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"c93d397e8d1ed4fe","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"2cc9ae96e6b56fc3","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"051e72fcceee74d6","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"c24b55da2a7095df","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"88981afd076ecf48","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1ac94ef8a4d9ad5b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a57f0b4ed1a21743","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ff1f4076329cb91c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1ea1f1044008a0b2","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5a9b4bfa6d03c94b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"16bcde8365ddf2a8","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"7d3732d8588ffedb","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"fb6a6a06e4463001","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e357e4b19a11617f","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ee8aa73feac66773","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"8aa426bd808ed75a","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e5eed224f946f11b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"3b812696a50c7061","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a04facc89859d775","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"37413c9d9331953b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d5713942d78606a2","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"52e5d6a64f47f9e8","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"bb49554e8d0ea27b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"9943d790e614f45a","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"b318da3bafca323e","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"8a6b3193ebf16daf","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"9a4e890c561b1f49","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"38f8c78460d0c171","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ceb269cfcbfb3737","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"6fc86b42fa2194c7","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"948868ae3f88e79e","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"f78a9daa44503acf","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"f065b37e2901ab44","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"03f33a24e5022801","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"db26cef88e3879aa","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"496f2ff2ad72eb56","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a33121c16f5e4d20","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1b5947476f3297ae","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ebaf8ad16d676e4c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5ec7e2368a41e7d1","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"f69cbc017c2bee73","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e2095571b8a4a9ea","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"8e8d9589ff612ccb","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"4acd7b14907d2eab","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"00b864b32ca6962f","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"0e7fd376997e0ce6","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"8947ab8c7604a712","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"12ae4c62954fb4d7","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5c70a05c3b20c460","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"7920d4521fc31742","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"14d71824a114fae5","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5c58f35ad11ea36d","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"c68ff69ac1086025","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"bfb4d21e0325cd27","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"1c5328ce70a7d781","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"3a27002f3a51c391","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"15c536b247ddda9b","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"b8dfd3383dc85e16","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d834384f74b37311","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"33ad4a447e65fe4c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"5f92334372103621","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"3b36a0673402ddea","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"b8e5c9de8614511a","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d6f7d0951a76b20f","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"dc731362e0a22c79","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"c37ce29a12797b87","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"b7f8903cecd3c417","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"e9aea7737083ea26","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ca849c611df2249c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"eba969c354d1a2b6","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"828d340d34a88e86","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"18a6bfdbc9b1999c","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"ea6de81ee5ad1594","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"46f992eaa836ef3e","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"a6c162781ee3a889","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"926d3b6bfe6e1943","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"7e15147781f2b0b4","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"221d9d61291eac74","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"d1c16d1fc4dc5998","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"25596ab30bae8f45","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"6f03c0e16553edcf","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"af7ab58246b4c2a5","prefixes":{"":940}}, // [White Ops, Inc.]
-  {"hash":"82a102dc6f580854","prefixes":{"":773}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"35f665efa0e2a55c","prefixes":{"":773}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"3a48f18bf340e74a","prefixes":{"":773}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"ee365433c62a5c89","prefixes":{"":773}}, // [Extreme Reach Digital (ER Digital)]
-  {"hash":"abe6370bd088dcf4","prefixes":{"":941}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"92dba1cdcba82d8a","prefixes":{"":941}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"ee0ccb57505565f7","prefixes":{"":941}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"f25f5e4909b9792c","prefixes":{"":941}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"8a9e6f7beeb084c5","prefixes":{"":941}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
-  {"hash":"94542c85cf399cbd","prefixes":{"":323}}, // [FinanceGenerator]
-  {"hash":"46ea052a92233562","prefixes":{"":942}}, // [Admetrics]
-  {"hash":"ea5d2271464ca35f","prefixes":{"":942}}, // [Admetrics]
-  {"hash":"286ad0ac5bca5d03","prefixes":{"":943}}, // [Admetrics GmbH]
-  {"hash":"ff1ffc67b7e3f33a","prefixes":{"":944}}, // [Amobee Inc. d/b/a Gradient X]
-  {"hash":"72cbc5ba1ec93b34","prefixes":{"":944}}, // [Amobee Inc. d/b/a Gradient X]
-  {"hash":"a6fc31f82c22f31e","prefixes":{"":25}}, // [Action Exchange, Inc.]
-  {"hash":"1ba64e5bb4889fc8","prefixes":{"":25}}, // [Action Exchange, Inc.]
-  {"hash":"1d75cb11df01626e","prefixes":{"":25}}, // [Action Exchange, Inc.]
-  {"hash":"91e1e972e2691a51","prefixes":{"":25}}, // [Action Exchange, Inc.]
-  {"hash":"23c68afb7d193b79","prefixes":{"":25}}, // [Action Exchange, Inc.]
-  {"hash":"63d64a70ef1c102e","prefixes":{"":792}}, // [Recruit Co., Ltd. Communications]
-  {"hash":"5e5fd982d3646780","prefixes":{"":793}}, // [RECRUIT Communications]
-  {"hash":"405787e06ebc6f4c","prefixes":{"dc":945}}, // [Datalicious Pty Ltd]
-  {"hash":"cddbf4fe7458433c","prefixes":{"":945}}, // [Datalicious Pty Ltd]
-  {"hash":"1c6b7ff16564ebc9","prefixes":{"":945}}, // [Datalicious Pty Ltd]
-  {"hash":"8b00b076af37f543","prefixes":{"":945}}, // [Datalicious Pty Ltd]
-  {"hash":"688a0b3764e1741b","prefixes":{"":946}}, // [Intent Media]
-  {"hash":"04bba28fa6468b07","prefixes":{"":947}}, // [AdNear Pte Ltd.]
-  {"hash":"c10761fe93bddd5e","prefixes":{"":948}}, // [Zhejiang MediaAdx Network Technology Co., Ltd]
-  {"hash":"3b0fa4efa209ebfa","prefixes":{"":948}}, // [Zhejiang MediaAdx Network Technology Co., Ltd]
-  {"hash":"e1b43b2549b03858","prefixes":{"":949}}, // [Harris Interactive]
-  {"hash":"6ade6d73b73295b2","prefixes":{"":949}}, // [Harris Interactive]
-  {"hash":"63efa9155999d096","prefixes":{"":950}}, // [BuzzCity Pte Ltd]
-  {"hash":"564ef19eef7254cf","prefixes":{"":950}}, // [BuzzCity Pte Ltd]
-  {"hash":"6bbdf3ce8eec6f52","prefixes":{"":950}}, // [BuzzCity Pte Ltd]
-  {"hash":"436cc9ab781b357d","prefixes":{"":950}}, // [BuzzCity Pte Ltd]
-  {"hash":"e8cc8c7d43c80259","prefixes":{"":951}}, // [Sputnyx]
-  {"hash":"2150e4c3d0f193b2","prefixes":{"":951}}, // [Sputnyx]
-  {"hash":"54d8f3466d5879bc","prefixes":{"":951}}, // [Sputnyx]
-  {"hash":"b930b780e12735dc","prefixes":{"":951}}, // [Sputnyx]
-  {"hash":"5817597124959a0f","prefixes":{"":952}}, // [CyberZ, Inc]
-  {"hash":"52a82bf3bc55f753","prefixes":{"":953}}, // [Spark Networks USA, LLC]
-  {"hash":"de87290af2710dce","prefixes":{"*":954}}, // [Ezakus]
-  {"hash":"9fa7220a9c513b82","prefixes":{"":955}}, // [V4x SAS]
-  {"hash":"cdea2314328db64c","prefixes":{"":955}}, // [V4x SAS]
-  {"hash":"9ab122baee7ffef0","prefixes":{"":955}}, // [V4x SAS]
-  {"hash":"5b7763887f62f0e2","prefixes":{"":956}}, // [Tapjoy Inc.]
-  {"hash":"c476f40a640ceb50","prefixes":{"":12}}, // [Madeleine Mode GmbH]
-  {"hash":"b03d8c48bc51a903","prefixes":{"":12}}, // [Madeleine Mode GmbH]
-  {"hash":"6ccfc9d681f1cce4","prefixes":{"":12}}, // [Madeleine Mode GmbH]
-  {"hash":"519e706c784712cd","prefixes":{"":12}}, // [Madeleine Mode GmbH]
-  {"hash":"4b99f5579a32d2ac","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"7bb686f653faf750","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"59bac04b09eb1850","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"c7c593cac7252275","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"9a2642b29d01ad5a","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"19e7f2b697047d0f","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"9ccde0a8ec3f9703","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"a81ee6b474d31f53","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"3b743b2fda71dd5f","prefixes":{"":957}}, // [EXEBID]
-  {"hash":"6378b3090ceafcf5","prefixes":{"*":562}}, // [Bannerflow AB]
-  {"hash":"09de5d9c8a08a419","prefixes":{"":958}}, // [Exposebox Ltd]
-  {"hash":"d88faf97f4f01be0","prefixes":{"":958}}, // [Exposebox Ltd]
-  {"hash":"1b7a8075387597c8","prefixes":{"":958}}, // [Exposebox Ltd]
-  {"hash":"42127ec758c4891f","prefixes":{"":959}}, // [MotoMiner]
-  {"hash":"f5fe6be8ffc65b45","prefixes":{"":960}}, // [BuySellAds.com Inc.]
-  {"hash":"4b9190a98d317014","prefixes":{"":960}}, // [BuySellAds.com Inc.]
-  {"hash":"3b55d9e306cf9e3c","prefixes":{"":960}}, // [BuySellAds.com Inc.]
-  {"hash":"a9da15f40498a6f3","prefixes":{"":961}}, // [Viking River Cruises]
-  {"hash":"e2a8d45a4c55dae6","prefixes":{"":962}}, // [Sittercity Incorporated]
-  {"hash":"5dd667d71a34b766","prefixes":{"":963}}, // [Facetz]
-  {"hash":"00776ec1c54574db","prefixes":{"":964}}, // [YOOSE Pte. Ltd.]
-  {"hash":"f8c3b8f01c62da3c","prefixes":{"":965}}, // [AdYapper, Inc.]
-  {"hash":"6c1804db5b6679a9","prefixes":{"":965}}, // [AdYapper, Inc.]
-  {"hash":"a361de3d2fcba609","prefixes":{"":965}}, // [AdYapper, Inc.]
-  {"hash":"1f805f58db63a12d","prefixes":{"":965}}, // [AdYapper, Inc.]
-  {"hash":"7090e79d9ec26768","prefixes":{"":965}}, // [AdYapper, Inc.]
-  {"hash":"727b3d1100b7d374","prefixes":{"":965}}, // [AdYapper, Inc.]
-  {"hash":"17b396141b96c236","prefixes":{"":799}}, // [Webtrekk GmbH]
-  {"hash":"b0149857f43862d9","prefixes":{"":144}}, // [Spark Flow S.A.]
-  {"hash":"f9c00c55ede792e2","prefixes":{"":144}}, // [Spark Flow S.A.]
-  {"hash":"8eb24e3340b4c707","prefixes":{"":966}}, // [Clickky LLP DBA Clickky]
-  {"hash":"2d27319a70fb6262","prefixes":{"":966}}, // [Clickky LLP DBA Clickky]
-  {"hash":"b140173de591dc64","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"7e2351ba05fefcce","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"88a66ce20c2df5e5","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"705049ea1378adbd","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"eadabb19d68f0e02","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"684343b8f00b5425","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"fedb0d981d151071","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"eb26cb8958b84143","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"b4f42222ff48d611","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"3ef4c3e15c3889aa","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"346ac90e489a0d27","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"f0685c9d889a4dcb","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"d2ae279176821009","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"98746e3eb9075cc5","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"f4e7d8ca3f73252e","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"145b69a5570cf0e6","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"b96e6d8a02aabe0f","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"5f7def46ec1776af","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"075bdf0eaa8a2d8a","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"374ddadb8b59c656","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"e75f11f13cf01278","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"fa9f043b6f9f0225","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"51046da25aac136a","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"e3d9117eacb00b04","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"2291e11d2ca518c2","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"208af3ccccac3a8a","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"8a7e7a7c9510a539","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"d62dab4e5ba19318","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"9faead99b5b9e15b","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"21ad4e7e6897e7be","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"5f6e332f4f7ad081","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"28c87295fd99d9b2","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"ec4d1f8447f0f153","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"bcdb0c5a6199a121","prefixes":{"":967}}, // [eRate Online Measurement Solutions Ltd.]
-  {"hash":"dc1424820d5085bc","prefixes":{"":967}}, // [eRate Online Measurement Solutions Ltd.]
-  {"hash":"d110aae732b1c80d","prefixes":{"":967}}, // [eRate Online Measurement Solutions Ltd.]
-  {"hash":"d461527c3648da49","prefixes":{"":968}}, // [Baumann Ber Rivnay]
-  {"hash":"da8fb21c56d3c224","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"abb93e258191198a","prefixes":{"":13}}, // [TripAdvisor LLC]
-  {"hash":"67ce1b0bfa972cc4","prefixes":{"":969}}, // [TUI Connect GmbH]
-  {"hash":"63c1158e18a5ea27","prefixes":{"":970}}, // [INFOnline GmbH]
-  {"hash":"46a40e7a328ffee7","prefixes":{"":971}}, // [Adizio]
-  {"hash":"c5ca269d09b7c25f","prefixes":{"*":972}}, // [Joystick Interactive]
-  {"hash":"93d3775dcb79f65b","prefixes":{"":973}}, // [EngageClick Inc]
-  {"hash":"0af466da8ca75d0b","prefixes":{"":973}}, // [EngageClick Inc]
-  {"hash":"111ffa6b19238149","prefixes":{"":974}}, // [GeeeN, Inc.]
-  {"hash":"46313b1a2b164e11","prefixes":{"":974}}, // [GeeeN, Inc.]
-  {"hash":"edeaec47d1406cde","prefixes":{"":974}}, // [GeeeN, Inc.]
-  {"hash":"e4fa03e71e81c717","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"b05d395ad43a6851","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"babf6252b4c60056","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"db86fc0d97ddf866","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"ea61f7fa94bc2f36","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"495d58c312a856b7","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"ce854368c8ba8c24","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"7c1ebbe2aa48388d","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"0ac9c5956a237913","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"5e22bf81f1721d99","prefixes":{"":975}}, // [Arbigo Inc.]
-  {"hash":"ad1ab56f3a151112","prefixes":{"":976}}, // [FlxOne BV]
-  {"hash":"6c833f73351e1f63","prefixes":{"":976}}, // [FlxOne BV]
-  {"hash":"82f8d328de710cff","prefixes":{"":976}}, // [FlxOne BV]
-  {"hash":"95c33537789a441f","prefixes":{"":976}}, // [FlxOne BV]
-  {"hash":"712c817d06c0d8c6","prefixes":{"":976}}, // [FlxOne BV]
-  {"hash":"63446ae2652818ab","prefixes":{"":10}}, // [eBay]
-  {"hash":"45b598cd3bc42672","prefixes":{"":977}}, // [ExtendTV, Inc.]
-  {"hash":"372fde25faa1c878","prefixes":{"":977}}, // [ExtendTV, Inc.]
-  {"hash":"db1da0ef7de3e1e6","prefixes":{"":978}}, // [momentM, Inc]
-  {"hash":"5710705dc9e3a971","prefixes":{"":978}}, // [momentM, Inc]
-  {"hash":"4ee3d75e96c8e3aa","prefixes":{"":978}}, // [momentM, Inc]
-  {"hash":"b329682f26e4fcc6","prefixes":{"":978}}, // [momentM, Inc]
-  {"hash":"71215c2931d79d35","prefixes":{"":978}}, // [momentM, Inc]
-  {"hash":"667a4fe4b59238b9","prefixes":{"":978}}, // [momentM, Inc]
-  {"hash":"a7fbeec4fb43f9d9","prefixes":{"*":979}}, // [OnCard Marketing dba RevTrax]
-  {"hash":"48a825a8c5ef9edd","prefixes":{"*":980}}, // [Youtube - API]
-  {"hash":"19459fb447ce4de4","prefixes":{"*":981}}, // [Thirdpresence Ltd]
-  {"hash":"f079f0a998c56593","prefixes":{"":981}}, // [Thirdpresence Ltd]
-  {"hash":"108dd21ceba53008","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"7b0dec2d8c1ec967","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"b5c3f2f3c1c37850","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"ba9b4eca15987843","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"4e521b3e57d76700","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"29ab2715e00761b0","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"688071d177180274","prefixes":{"":982}}, // [Visual IQ, Inc.]
-  {"hash":"4e682c7f7f2ebda9","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"4b6451297bd74247","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"95d75ced1262ecda","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"ac94d70ffcad5c63","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"578591a9eb9652f2","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"5528666c72c7c71c","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"3deb1cd39233765c","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"4e05303df9f07532","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"99936e7e455c77b7","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"f0e5986dc65416fd","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"5095285a4ab05444","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"670fdb8ea86ee233","prefixes":{"":983}}, // [Appreciate]
-  {"hash":"ad2de628bc6fd483","prefixes":{"":984,"lodeo-":985}}, // [CyberAgent d/b/a GameLogic] [Lodeo]
-  {"hash":"66e26f9703f2dd67","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"80451e302607b653","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"bb7f7e8ab7b99724","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"51dbfc01b5f86601","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"2a8926ec16272a9b","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"4e2334aabf3b7af7","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"1bbabf05900a894f","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"a45a66788779b9bc","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"c4d101005526e2ef","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"7f43400e381d40ff","prefixes":{"":984}}, // [CyberAgent d/b/a GameLogic]
-  {"hash":"e323697c02e1a841","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"11c505e6e21eefdb","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"afc246433e1284d8","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"c7322cd1ad0df953","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"a090f61c3ee5e028","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"846ea0c461560421","prefixes":{"":985}}, // [Lodeo]
-  {"hash":"b433db4fe5f6ed8d","prefixes":{"":987}}, // [LTD "RTB-MEDIA"]
-  {"hash":"e5b814009c134495","prefixes":{"":987}}, // [LTD "RTB-MEDIA"]
-  {"hash":"ce6b2c64ce23d14b","prefixes":{"":988}}, // [Maverick., inc.]
-  {"hash":"32ef8d9c49285e19","prefixes":{"":988}}, // [Maverick., inc.]
-  {"hash":"ac99e3b588f1d521","prefixes":{"":989}}, // [FuelX]
-  {"hash":"da9e2cf59b85610c","prefixes":{"":989}}, // [FuelX]
-  {"hash":"d86ff177f1095173","prefixes":{"":989}}, // [FuelX]
-  {"hash":"7853aedd1a267ffb","prefixes":{"":989}}, // [FuelX]
-  {"hash":"5f505217689c7174","prefixes":{"":989}}, // [FuelX]
-  {"hash":"27be294cbea039f9","prefixes":{"":989}}, // [FuelX]
-  {"hash":"bae6c7f50fff772d","prefixes":{"":989}}, // [FuelX]
-  {"hash":"63f51428712678ec","prefixes":{"":324}}, // [Telstra Corporation]
-  {"hash":"f1d920cc5a16b3a9","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"12a7d7495eb7a91f","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"6ca28320c4765235","prefixes":{"":986}}, // [CyberAgent d/b/a Dynalyst]
-  {"hash":"aeb171f5cad96320","prefixes":{"":990}}, // [Tutor.com]
-  {"hash":"5de1c09366f03919","prefixes":{"":164}}, // [wayStorm Co., Ltd.]
-  {"hash":"9977349a2c52c1b6","prefixes":{"":164}}, // [wayStorm Co., Ltd.]
-  {"hash":"3304d732f88c9ebe","prefixes":{"":164}}, // [wayStorm Co., Ltd.]
-  {"hash":"8b1b0e966a643448","prefixes":{"":164}}, // [wayStorm Co., Ltd.]
-  {"hash":"852a445ec03b1224","prefixes":{"":991}}, // [Rebelmouse]
-  {"hash":"ebef84a02e75b037","prefixes":{"*":991}}, // [Rebelmouse]
-  {"hash":"6ff0ad7b4d4ee2ef","prefixes":{"":992}}, // [Adviator DSP]
-  {"hash":"c28458e1bac3bb75","prefixes":{"":992}}, // [Adviator DSP]
-  {"hash":"041403702e0ae9f0","prefixes":{"":992}}, // [Adviator DSP]
-  {"hash":"31890d74ba2e0eca","prefixes":{"":525}}, // [abilicom GmbH]
-  {"hash":"16f2a07aea3c767b","prefixes":{"":993}}, // [Acens Technologies, S.L.]
-  {"hash":"4d628548402f2933","prefixes":{"":994}}, // [Yashi, Inc]
-  {"hash":"6f97eb7dc578c1d3","prefixes":{"":677}}, // [Taptica]
-  {"hash":"843cc26d64f855e3","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"7f81eef44c27fceb","prefixes":{"":495}}, // [Miaozhen Systems]
-  {"hash":"f36b5e4d896bf9fc","prefixes":{"":995}}, // [Flaminem Inc]
-  {"hash":"ec10935d7141abb2","prefixes":{"":996}}, // [Mediahead AG]
-  {"hash":"d074e5017286d25a","prefixes":{"":996}}, // [Mediahead AG]
-  {"hash":"e7aa39274c05edf9","prefixes":{"":996}}, // [Mediahead AG]
-  {"hash":"06d3dae2f13a3dcb","prefixes":{"":996}}, // [Mediahead AG]
-  {"hash":"1cc1098f16d364e0","prefixes":{"":996}}, // [Mediahead AG]
-  {"hash":"15ee5953d4c74d48","prefixes":{"":996}}, // [Mediahead AG]
-  {"hash":"b434b094029a84a8","prefixes":{"":997}}, // [Admixer]
-  {"hash":"766b3c24fb448820","prefixes":{"":998}}, // [Communication Services Tele2 GmbH]
-  {"hash":"35e369c14d37cb1c","prefixes":{"*":999}}, // [99click]
-  {"hash":"c5b7e1faef274865","prefixes":{"":1000}}, // [Ströer Mobile Media GmbH]
-  {"hash":"dc01aead4f784e4d","prefixes":{"":1000}}, // [Ströer Mobile Media GmbH]
-  {"hash":"39525c5c19a8a044","prefixes":{"":1000}}, // [Ströer Mobile Media GmbH]
-  {"hash":"397c77c97b7945f8","prefixes":{"":1000}}, // [Ströer Mobile Media GmbH]
-  {"hash":"3097a79ab689b320","prefixes":{"":1000}}, // [Ströer Mobile Media GmbH]
-  {"hash":"c27b66085df0c0da","prefixes":{"":1001}}, // [LLC "Life Style"]
-  {"hash":"3a7913ff0ce0cc21","prefixes":{"":1001}}, // [LLC "Life Style"]
-  {"hash":"9d1661dae6ff9304","prefixes":{"":1001}}, // [LLC "Life Style"]
-  {"hash":"cdd266d878d3e9d5","prefixes":{"":1001}}, // [LLC "Life Style"]
-  {"hash":"d3c08bf02865217e","prefixes":{"":1002}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"bbfe70399cd3fcb3","prefixes":{"":1002}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"a17b33aa94234849","prefixes":{"":1002}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"8e073ea44074ec93","prefixes":{"":1002}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"12afa442e09a07c9","prefixes":{"":1002}}, // [2Y Media SAS (adserverpub)]
-  {"hash":"7fa5ca05a3a0b474","prefixes":{"":1003}}, // [Platform IQ]
-  {"hash":"f6f0f65947909d69","prefixes":{"":1003}}, // [Platform IQ]
-  {"hash":"77b586602e5dec3f","prefixes":{"":1003}}, // [Platform IQ]
-  {"hash":"bba327f348a4693e","prefixes":{"":1003}}, // [Platform IQ]
-  {"hash":"a544a3b25c4d5113","prefixes":{"":1004}}, // [Silveredge Inc]
-  {"hash":"037cb4c9598870ee","prefixes":{"":1004}}, // [Silveredge Inc]
-  {"hash":"2a6ed7c1b6a78509","prefixes":{"":1004}}, // [Silveredge Inc]
-  {"hash":"06d23751a7963710","prefixes":{"":1005}}, // [SMADEX]
-  {"hash":"0a84ed2865a74b8a","prefixes":{"":1005}}, // [SMADEX]
-  {"hash":"e97a828dc740d645","prefixes":{"":1005}}, // [SMADEX]
-  {"hash":"aa964a10a9ccda5b","prefixes":{"":1005}}, // [SMADEX]
-  {"hash":"d7675b344c153db3","prefixes":{"":1005}}, // [SMADEX]
-  {"hash":"76eaf06fcd95e8e8","prefixes":{"":1006}}, // [Suzu Muchi]
-  {"hash":"fcf26d7eec95d72d","prefixes":{"":342}}, // [LOKA Research inc.]
-  {"hash":"3b238a232cbc26bd","prefixes":{"":342}}, // [LOKA Research inc.]
-  {"hash":"a544c76e7ec01862","prefixes":{"":342}}, // [LOKA Research inc.]
-  {"hash":"7922cb2f11972c85","prefixes":{"":342}}, // [LOKA Research inc.]
-  {"hash":"613551ec99bec944","prefixes":{"":1007}}, // [PlannTo Technologies Private Limited]
-  {"hash":"bb07eb5de3d95038","prefixes":{"":1007}}, // [PlannTo Technologies Private Limited]
-  {"hash":"729165b2ebbc6996","prefixes":{"":1007}}, // [PlannTo Technologies Private Limited]
-  {"hash":"187629571e0338cf","prefixes":{"":1007}}, // [PlannTo Technologies Private Limited]
-  {"hash":"bdd2e20221d7e507","prefixes":{"":1008}}, // [Viator, Inc]
-  {"hash":"1caf0cb7a05c5941","prefixes":{"":474}}, // [Xrost]
-  {"hash":"4c6513300966da08","prefixes":{"":1009}}, // [NODDINGTON TECHNOLOGIES LIMITED]
-  {"hash":"2c1d6a203788af2b","prefixes":{"":1010}}, // [Plan Blue Ltd]
-  {"hash":"3c0da2d4356e18a5","prefixes":{"":1010}}, // [Plan Blue Ltd]
-  {"hash":"2568d0917d238964","prefixes":{"":1011}}, // [Addictive Mobility]
-  {"hash":"f79c822ab2cca8ee","prefixes":{"":1011}}, // [Addictive Mobility]
-  {"hash":"c610b5ae3df923cd","prefixes":{"":1011}}, // [Addictive Mobility]
-  {"hash":"a614ab43bf2d906b","prefixes":{"":1011}}, // [Addictive Mobility]
-  {"hash":"747eeca86822f19c","prefixes":{"":1012}}, // [A6 Corporation]
-  {"hash":"cbdfdaeff8b7d933","prefixes":{"":1013}}, // [Mobusi Mobile Advertising]
-  {"hash":"5b2d082c7811bead","prefixes":{"":1014}}, // [Wishabi]
-  {"hash":"c811726b56670631","prefixes":{"":1014}}, // [Wishabi]
-  {"hash":"09d3b27d380d43a0","prefixes":{"":1014}}, // [Wishabi]
-  {"hash":"eecab68f555d1f9f","prefixes":{"":1015}}, // [onAd GmbH]
-  {"hash":"d05b20f38e3bb984","prefixes":{"":1016}}, // [Media Decision GmbH]
-  {"hash":"4a9b8dddd4c7567c","prefixes":{"":1016}}, // [Media Decision GmbH]
-  {"hash":"5121142c1b8676fd","prefixes":{"":1016}}, // [Media Decision GmbH]
-  {"hash":"e083b93d5a87c743","prefixes":{"":1017}}, // [Unitymedia NRW]
-  {"hash":"c665046a783daa9d","prefixes":{"":1018}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"663d5fdbc3a52729","prefixes":{"":1018}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"991e96310871571b","prefixes":{"":1018}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"0503d775704af4a2","prefixes":{"":1018}}, // [Nowspots INC, dba Perfect Audience]
-  {"hash":"2c55a4ef41531200","prefixes":{"":1019}}, // [Avis]
-  {"hash":"62817a7d196cbdcf","prefixes":{"":1020}}, // [Comcast]
-  {"hash":"2e4bb1f4d07f3180","prefixes":{"":1021}}, // [Jack Spade]
-  {"hash":"e7d369c24971784a","prefixes":{"":1022}}, // [Dollar General]
-  {"hash":"a8c9b93aae571ed5","prefixes":{"":1023}}, // [Care.com]
-  {"hash":"713775b7bc737116","prefixes":{"":1024}}, // [Clickagy, LLC]
-  {"hash":"8b6b45c1c86cd84b","prefixes":{"":1024}}, // [Clickagy, LLC]
-  {"hash":"34376185507c9ae0","prefixes":{"":1025}}, // [GlobalWebIndex]
-  {"hash":"8b17254892b590e3","prefixes":{"":1026}}, // [King.com]
-  {"hash":"8516f044f19bb3ae","prefixes":{"":1026}}, // [King.com]
-  {"hash":"d811179454fad251","prefixes":{"":1026}}, // [King.com]
-  {"hash":"946611fa2f4b067a","prefixes":{"":1027}}, // [Proquire LLC - Accenture]
-  {"hash":"cfa0e9025fcd5712","prefixes":{"":1028}}, // [Dynamic Yield]
-  {"hash":"b01c0239af74e72e","prefixes":{"":1028}}, // [Dynamic Yield]
-  {"hash":"e480d03a980d3bfc","prefixes":{"":1028}}, // [Dynamic Yield]
-  {"hash":"f22fe7e17c58b562","prefixes":{"":1028}}, // [Dynamic Yield]
-  {"hash":"f8da77c2fdcad106","prefixes":{"":1028}}, // [Dynamic Yield]
-  {"hash":"cea3bf4afe576984","prefixes":{"":1029}}, // [Charter business]
-  {"hash":"f8029c009186163f","prefixes":{"":1030}}, // [The ADEX]
-  {"hash":"61b09f5d40722e69","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"aa63151485efa109","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"ed37e98f45f10404","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"f9fda879239cf155","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"2dfe9124b3439d80","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"93a9e29ac238b380","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"5e080b13877f5de7","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"eb22d59d4594e6d3","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"a28e072f804db6a0","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"945f948eacea62c9","prefixes":{"":1031}}, // [OneDigitalAd Technologies]
-  {"hash":"b85074a47da33b83","prefixes":{"":1032}}, // [ADJUST]
-  {"hash":"9f369deb4f045364","prefixes":{"":1032}}, // [ADJUST]
-  {"hash":"2d6ceeb3eef38c27","prefixes":{"":1032}}, // [ADJUST]
-  {"hash":"65240dfe37410021","prefixes":{"":1032}}, // [ADJUST]
-  {"hash":"8d3dfcbf705f1191","prefixes":{"":1032}}, // [ADJUST]
-  {"hash":"a2d35afc9c960448","prefixes":{"":1033}}, // [ADmantX, SPA]
-  {"hash":"3d3bc7f00b0ef8d3","prefixes":{"":1034}}, // [Sogou.com]
-  {"hash":"9eb0737a130a6f08","prefixes":{"":1035}}, // [xAd, Inc.]
-  {"hash":"a9ff22250a3c29a1","prefixes":{"":1036}}, // [VideoBlocks]
-  {"hash":"61f27a00f3821730","prefixes":{"":1037}}, // [GraphicStocks]
-  {"hash":"f0792974945e7184","prefixes":{"":1038}}, // [Microsoft Advertising]
-  {"hash":"81f27cb33d47894b","prefixes":{"":1039}}, // [Rontar LTD]
-  {"hash":"e8ae13fee2796336","prefixes":{"":1039}}, // [Rontar LTD]
-  {"hash":"d979ed3048a9dc3d","prefixes":{"":1039}}, // [Rontar LTD]
-  {"hash":"187c7e948b323b3a","prefixes":{"dsp":1039}}, // [Rontar LTD]
-  {"hash":"1a5cfb3f08b31682","prefixes":{"":1040}}, // [Torrential, Inc.]
-  {"hash":"99bb29582234b47b","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"14a0b2d821feb403","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"4bfb576f457b3ad4","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"d2e32e6a4c73344a","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"3c8aa320c0f5fb9d","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"8c3cae9472fcd43a","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"18d673cc147eaba5","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"fb4f3dd591cba22f","prefixes":{"bid":1041}}, // [AMoAd, Inc.]
-  {"hash":"49aef0b488ab5024","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"2b7a17458f44228d","prefixes":{"":1041}}, // [AMoAd, Inc.]
-  {"hash":"7458cceedc9f812a","prefixes":{"":1042}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"dd47f178c7a055b8","prefixes":{"":1042}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"db975b73da86c8ce","prefixes":{"":1042}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"6216946891299e23","prefixes":{"":1042}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"52ee7c22862a74b6","prefixes":{"":1042}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
-  {"hash":"3cc39e801c92ea89","prefixes":{"":1043}}, // [Jampp/Devego S.A.]
-  {"hash":"31fb8bdf6d2b85d2","prefixes":{"":1044}}, // [Placed]
-  {"hash":"a6ff57032773fe41","prefixes":{"*":1045}}, // [Digitas Health]
-  {"hash":"caeb7a071a866e17","prefixes":{"*":1045}}, // [Digitas Health]
-  {"hash":"6e946f5fac72b0b4","prefixes":{"":1046}}, // [Answer Media, LLC]
-  {"hash":"31c3d7ef1499fd26","prefixes":{"":1046}}, // [Answer Media, LLC]
-  {"hash":"d681f06391c7f861","prefixes":{"":1047}}, // [1000mercis]
-  {"hash":"1549387212aaa6a3","prefixes":{"":1048}}, // [Upstart Network, Inc.]
-  {"hash":"e48f63d27d0c24c7","prefixes":{"":1049}}, // [Forensiq, LLC]
-  {"hash":"7579b1341b228f93","prefixes":{"":1049}}, // [Forensiq, LLC]
-  {"hash":"f2e570ecd2540399","prefixes":{"":1050}}, // [LoopMe Ltd]
-  {"hash":"7d4e3b90001a044e","prefixes":{"":1050}}, // [LoopMe Ltd]
-  {"hash":"528167a286d8ccf8","prefixes":{"":1051}}, // [Bannerlink (Liquidus)]
-  {"hash":"0b2d528c0dce5bba","prefixes":{"":1051}}, // [Bannerlink (Liquidus)]
-  {"hash":"758cc459053712cf","prefixes":{"":1051}}, // [Bannerlink (Liquidus)]
-  {"hash":"57951d4b34add1a9","prefixes":{"":1051}}, // [Bannerlink (Liquidus)]
-  {"hash":"3d93ddd2b1dc8083","prefixes":{"":1051}}, // [Bannerlink (Liquidus)]
-  {"hash":"88f0b992c4b99c65","prefixes":{"":1052}}, // [Dell Inc.]
-  {"hash":"f8820430b42f89f8","prefixes":{"":1053}}, // [My Perfect Resume]
-  {"hash":"6f018db6d7a12f5e","prefixes":{"":1054}}, // [Ajillion Max Ltd]
-  {"hash":"b591ab0baccecd52","prefixes":{"":1054}}, // [Ajillion Max Ltd]
-  {"hash":"35d86d0121dbd41a","prefixes":{"":1055}}, // [Swelen France SA.]
-  {"hash":"25b09dd0e8d2977a","prefixes":{"":1055}}, // [Swelen France SA.]
-  {"hash":"f5cb853eba61193a","prefixes":{"":1056}}, // [Sleeptrain]
-  {"hash":"c620109c65610aeb","prefixes":{"":1057}}, // [Sleepcountry]
-  {"hash":"9c6554ebebdbfa08","prefixes":{"":1058}}, // [Hoover]
-  {"hash":"f34ddb2b65330794","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"5d9eb2a8dc1a1687","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"e2207dc37f1b89e8","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"682ec1b47db930b9","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"638a2c2dc53d2ab7","prefixes":{"":1060}}, // [Mocoplex Inc.]
-  {"hash":"ee330ed89897a55c","prefixes":{"":1060}}, // [Mocoplex Inc.]
-  {"hash":"60ab035f28a35e30","prefixes":{"":1060}}, // [Mocoplex Inc.]
-  {"hash":"5929f2c289d9e073","prefixes":{"":778}}, // [Gruvi Ltd.]
-  {"hash":"c16c02248018a374","prefixes":{"":778}}, // [Gruvi Ltd.]
-  {"hash":"e6eb2d1c03d2be83","prefixes":{"":778}}, // [Gruvi Ltd.]
-  {"hash":"95fa4396cadc336e","prefixes":{"":778}}, // [Gruvi Ltd.]
-  {"hash":"2604a7d96f168c84","prefixes":{"":1061}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"294fdebfd41771a8","prefixes":{"":1061}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"c6beb451fe4c58c2","prefixes":{"":1061}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"b0f5f51210e6f2af","prefixes":{"":1061}}, // [Brightsparc Technologies Pty Ltd trading as Native]
-  {"hash":"ab3da2eb1a35cba6","prefixes":{"":1062}}, // [Verengo Solar]
-  {"hash":"c3bf5a10743772ec","prefixes":{"*":1063}}, // [Mobile Professionals BV]
-  {"hash":"d22325b6d6b04918","prefixes":{"*":1064}}, // [APNIC Pty Ltd]
-  {"hash":"27966131215e508a","prefixes":{"*":1064}}, // [APNIC Pty Ltd]
-  {"hash":"80022b9d8ddaffde","prefixes":{"*":1064}}, // [APNIC Pty Ltd]
-  {"hash":"9352d77ba286c03d","prefixes":{"":1065}}, // [Dun and Bradstreet Corporation]
-  {"hash":"74b7ef01f42d93ee","prefixes":{"":1066}}, // [UpToLike]
-  {"hash":"f2a78bb802dc4abd","prefixes":{"":1066}}, // [UpToLike]
-  {"hash":"f885798eaaace647","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"3bc813f113908f06","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"e1a6852c86da418c","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"0343b65d010db4b2","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"a9b74e1bcb339dd0","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"e8d325d7be0f046b","prefixes":{"*":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"f7ccb1753b9ae2ed","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"4a96db729cb9dd47","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"afde8c2ebcc380c8","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"05840eb3ff4432a8","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"3e5f0f83b0e34391","prefixes":{"":1067}}, // [Mobile360 Sdn Bhd]
-  {"hash":"f79fe1474c475ade","prefixes":{"":1068}}, // [Elite Fixtures]
-  {"hash":"b8b63e29130d798a","prefixes":{"":1069}}, // [Advanse Ads]
-  {"hash":"662442a875d5ae62","prefixes":{"":1069}}, // [Advanse Ads]
-  {"hash":"d8487e4c88a21c7f","prefixes":{"":1069}}, // [Advanse Ads]
-  {"hash":"37694729baf29aa5","prefixes":{"":1070}}, // [Insurance Step]
-  {"hash":"0153c16587a0c97c","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"c7bcca7e8dc820fe","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"2176b8c755bbab42","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"1979b33f68eb0ded","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"32a9ea6936225587","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"16fec67040bf3ff7","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"ed89b325a7c3ac6d","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"ae3bc4690ef89e8d","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"ed9a2a4f49ad4647","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"398d36669a77aca6","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"5bf9c0f450f9eb14","prefixes":{"":1071}}, // [Causal Impact]
-  {"hash":"30e7de1e277c7698","prefixes":{"":145}}, // [Aarki, Inc.]
-  {"hash":"888d9446d621d82f","prefixes":{"":145}}, // [Aarki, Inc.]
-  {"hash":"3061a4cd653ea2dc","prefixes":{"*":1072}}, // [Pixnet]
-  {"hash":"06daa5b82ebfa413","prefixes":{"":1073}}, // [Zapp360]
-  {"hash":"6f0f9a90c798715d","prefixes":{"":1074}}, // [Kijiji]
-  {"hash":"0259cba89f8f9676","prefixes":{"":1075}}, // [Spotad LTD.]
-  {"hash":"0ca2babbaeeca3bf","prefixes":{"":1075}}, // [Spotad LTD.]
-  {"hash":"e9a9d4fd1b468042","prefixes":{"":1075}}, // [Spotad LTD.]
-  {"hash":"6a79ac93cddc0cc5","prefixes":{"":1075}}, // [Spotad LTD.]
-  {"hash":"685b17838f2d9b82","prefixes":{"":1076}}, // [Go Daddy]
-  {"hash":"aa66f01be33256d0","prefixes":{"":1077}}, // [Bilendi]
-  {"hash":"3b8dfd79ab921d9b","prefixes":{"":1078}}, // [Hitokuse]
-  {"hash":"1992e397e0dff18d","prefixes":{"":1078}}, // [Hitokuse]
-  {"hash":"03eb230cd9f67c73","prefixes":{"":1078}}, // [Hitokuse]
-  {"hash":"0a75c26f5c580b3a","prefixes":{"*":1079}}, // [MGID Inc.]
-  {"hash":"4466d73d5d5dce19","prefixes":{"*":1079}}, // [MGID Inc.]
-  {"hash":"10bfb2327400e2ea","prefixes":{"":1079}}, // [MGID Inc.]
-  {"hash":"121b77f4b4412c85","prefixes":{"":1079}}, // [MGID Inc.]
-  {"hash":"e46ec8aa62f3f432","prefixes":{"":1080}}, // [AreaOne]
-  {"hash":"9849db4d4a694f16","prefixes":{"t":1081,"s":1081,"sna":1081}}, // [DynAd] [DynAd] [DynAd]
-  {"hash":"5fc0aef37d5fffca","prefixes":{"":1082}}, // [Loop Pay]
-  {"hash":"4cc75be32553222a","prefixes":{"":1083}}, // [Remerge GmbH]
-  {"hash":"b1a90d2aaa32932c","prefixes":{"":1083}}, // [Remerge GmbH]
-  {"hash":"3bea81bc90640751","prefixes":{"":1084}}, // [Audience Trading Platform LTD]
-  {"hash":"d193540bb7540e5c","prefixes":{"":1085}}, // [Whisla]
-  {"hash":"abd1c2a37733128b","prefixes":{"":1085}}, // [Whisla]
-  {"hash":"9546fe15199cbce1","prefixes":{"":1085}}, // [Whisla]
-  {"hash":"f43c40d1949f2c52","prefixes":{"":1086}}, // [Bridgevine]
-  {"hash":"28577f7c17c55b0f","prefixes":{"":1087}}, // [ADgraph DMP]
-  {"hash":"fa0c51dc55faddc6","prefixes":{"":1088}}, // [Gravity4 Inc.]
-  {"hash":"6dea119c4c95aaa8","prefixes":{"":1088}}, // [Gravity4 Inc.]
-  {"hash":"79b4752426dedd83","prefixes":{"":1089}}, // [Hipmunk]
-  {"hash":"ccba9f3966eabe6b","prefixes":{"*":1090}}, // [VideoHub DSP]
-  {"hash":"a6baef75f126450e","prefixes":{"":1091}}, // [DuMedia]
-  {"hash":"cf45efd3feda1ba3","prefixes":{"":1091}}, // [DuMedia]
-  {"hash":"efebf8c1ea6bab87","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"a866ff2bfe3133e7","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"49b89555382dac9e","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"e2d2b1537271ff61","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"5804e7cf2cdbbda0","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"db0ef2b4eff25274","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"d960535fd30704f8","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"258915df4406fd06","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"b34a1e3fd51aadb9","prefixes":{"":1092}}, // [F@N Communications, Inc.]
-  {"hash":"c0ad7ec6e1d46299","prefixes":{"":1093}}, // [VIVALU GmbH]
-  {"hash":"65c049a517720b5c","prefixes":{"":1093}}, // [VIVALU GmbH]
-  {"hash":"b60b2426028baba5","prefixes":{"":1094}}, // [Advertising Technologies LTD]
-  {"hash":"6d2df95e2bf52046","prefixes":{"":1094}}, // [Advertising Technologies LTD]
-  {"hash":"b4ad6ea6ca336f55","prefixes":{"":1094}}, // [Advertising Technologies LTD]
-  {"hash":"b750311cbd5c4013","prefixes":{"":1095}}, // [Authenticated Digital Inc]
-  {"hash":"aa634a3d8862b3be","prefixes":{"":1095}}, // [Authenticated Digital Inc]
-  {"hash":"361eefdfa29ada10","prefixes":{"":1096}}, // [PaeDae, Inc., DBA The Mobile Majority]
-  {"hash":"8a5c2c8d21fc6dd4","prefixes":{"":1096}}, // [PaeDae, Inc., DBA The Mobile Majority]
-  {"hash":"13b3d2e0ed78e518","prefixes":{"":1097}}, // [METROPCS]
-  {"hash":"c9b29fe277a47b8d","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"60f32eaa9335e4b9","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"c8f49035cb273e42","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"92d9e360f16ecdc9","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"2d3b5566afb5350b","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"0ca3b2088de2514c","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"67da96d5ae99faa0","prefixes":{"":1098}}, // [PapayaMobile Inc.]
-  {"hash":"347e898491d027ee","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"ae3f27ad4a4f2f7d","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"cd0c8a5dd793ee52","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"451f4083f03028e0","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"e1b048e4fa37eef2","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"837ae92d9cf6b933","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"6ae82aac87db94d3","prefixes":{"":1099}}, // [Raumfeld]
-  {"hash":"84ddfa5a2e93cb69","prefixes":{"":1100}}, // [GREE Ads DSP]
-  {"hash":"a7201f5a80824242","prefixes":{"":1100}}, // [GREE Ads DSP]
-  {"hash":"2ec22ca05310362a","prefixes":{"":1101}}, // [Tender Industries AB]
-  {"hash":"d159abbaeda22e7c","prefixes":{"":1102}}, // [BySide]
-  {"hash":"426783d6fe8d039e","prefixes":{"":1103}}, // [Sentrant Security Inc.]
-  {"hash":"d270ad50bb53fb01","prefixes":{"":1103}}, // [Sentrant Security Inc.]
-  {"hash":"49c693058534be83","prefixes":{"":1104}}, // [Locon Solutions Pvt. Ltd.]
-  {"hash":"a2b9f627da8737de","prefixes":{"":1105}}, // [Interrogare GmbH]
-  {"hash":"13b73169540642e5","prefixes":{"":1105}}, // [Interrogare GmbH]
-  {"hash":"afaa106d11846fa4","prefixes":{"*":1106}}, // [ChannelAdvisor]
-  {"hash":"b8b4eadeb5d3a123","prefixes":{"":1107}}, // [VideoAmp]
-  {"hash":"43546e9f6ff5bf2a","prefixes":{"":1107}}, // [VideoAmp]
-  {"hash":"61a9edb9af3769cf","prefixes":{"":1107}}, // [VideoAmp]
-  {"hash":"f76b3fe7048e93e2","prefixes":{"":1107}}, // [VideoAmp]
-  {"hash":"57263424c0e88a92","prefixes":{"track":1108}}, // [The Bridge]
-  {"hash":"516e9fc5ede4af0d","prefixes":{"":1108}}, // [The Bridge]
-  {"hash":"6bc0303a4262cb67","prefixes":{"":1108}}, // [The Bridge]
-  {"hash":"30a32fe2a89dccd8","prefixes":{"":1109}}, // [Pharmaca Integrative Pharmacy]
-  {"hash":"7881da604383a640","prefixes":{"":673}}, // [Videology DSP]
-  {"hash":"dec02c663bb06094","prefixes":{"":1110}}, // [Scrutineer]
-  {"hash":"6e2098af577c671d","prefixes":{"":1111}}, // [TF1 - FR]
-  {"hash":"60774075776e2612","prefixes":{"":1112}}, // [Core Digital]
-  {"hash":"79a775eea6a902e6","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"c0576db5cf4ba20b","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"d90fda985e3fb6bf","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"ee49dcf9326e853f","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"5b3c6abcd44de720","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"f97a320480541a27","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"57fc36302e0bde3c","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"736a8a8a0cef7bdf","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"36263b4a0d607a71","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"226480bf58f4fd1c","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"58379bd623597d70","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"f68e3a544a7397be","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"0f2880d71794e516","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"4ef52741fc1ade73","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"97d6a93635d72af0","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"ab75a46dc8bf2c1e","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"efeb8f966db03b87","prefixes":{"":110}}, // [Bonzai Digital Pvt. Ltd]
-  {"hash":"2a4d804c0fb397c1","prefixes":{"":1113}}, // [Adventive, Inc.]
-  {"hash":"29d370caa59b4ecc","prefixes":{"":1113}}, // [Adventive, Inc.]
-  {"hash":"a06632ec1be82319","prefixes":{"":1114}}, // [Turner Sports Interactive, Inc.]
-  {"hash":"bf10e40bae047225","prefixes":{"":1114}}, // [Turner Sports Interactive, Inc.]
-  {"hash":"67dbd4ebfca8ed7c","prefixes":{"":1114}}, // [Turner Sports Interactive, Inc.]
-  {"hash":"3ccffb010a6151f8","prefixes":{"":1115}}, // [SnappyTV]
-  {"hash":"7d838005a39552d8","prefixes":{"":1116}}, // [Target Media Partners]
-  {"hash":"003b7537bd9a7cfe","prefixes":{"":1116}}, // [Target Media Partners]
-  {"hash":"26b33a79482ab7ab","prefixes":{"":1117}}, // [KAIZEN platform Inc.]
-  {"hash":"15cdc1963890a6a2","prefixes":{"":1117}}, // [KAIZEN platform Inc.]
-  {"hash":"1f36b920b7ac4ebb","prefixes":{"":1118}}, // [Bidstalk Pte Ltd]
-  {"hash":"a59afaa1821362bd","prefixes":{"":1119}}, // [ESPN]
-  {"hash":"e0edcd5fafde3e7a","prefixes":{"":1119}}, // [ESPN]
-  {"hash":"7bd48d6255130db4","prefixes":{"":1120}}, // [Online Media Group]
-  {"hash":"88c41fbe0db9a483","prefixes":{"":1120}}, // [Online Media Group]
-  {"hash":"fc1080dbf4fae3f9","prefixes":{"":1120}}, // [Online Media Group]
-  {"hash":"37fc205007f7a040","prefixes":{"":1120}}, // [Online Media Group]
-  {"hash":"60c02a2ea01a737e","prefixes":{"":1121}}, // [Luxury Link]
-  {"hash":"24108d30b52b9587","prefixes":{"":1122}}, // [ESKIMI]
-  {"hash":"9de510a2d7f81a6e","prefixes":{"":1122}}, // [ESKIMI]
-  {"hash":"d0e18c7e72b51bf3","prefixes":{"":1122}}, // [ESKIMI]
-  {"hash":"6dbe16f5894e20af","prefixes":{"":1123}}, // [AdsYolo Media]
-  {"hash":"5292ef4ba83623a8","prefixes":{"":1124}}, // [Arrivalist]
-  {"hash":"b94285ae50bcb48e","prefixes":{"":1124}}, // [Arrivalist]
-  {"hash":"cd7b432729ab016a","prefixes":{"":1124}}, // [Arrivalist]
-  {"hash":"ae0442a300ebce47","prefixes":{"":1124}}, // [Arrivalist]
-  {"hash":"3c8cc56d5b514ec5","prefixes":{"":1124}}, // [Arrivalist]
-  {"hash":"794b2a51546b4f7f","prefixes":{"":1125}}, // [MobileWebAdz Ltd]
-  {"hash":"223eacf97254c888","prefixes":{"":1125}}, // [MobileWebAdz Ltd]
-  {"hash":"a3c5eeef285517f3","prefixes":{"":1125}}, // [MobileWebAdz Ltd]
-  {"hash":"b222f9498fcdb24c","prefixes":{"":1126}}, // [Demand Side Science, Inc.]
-  {"hash":"87af9974b30c5872","prefixes":{"":1126}}, // [Demand Side Science, Inc.]
-  {"hash":"db4cd3e487418898","prefixes":{"":1126}}, // [Demand Side Science, Inc.]
-  {"hash":"3fca6191597f44f2","prefixes":{"":1127}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
-  {"hash":"6873487b11c1952e","prefixes":{"":1127}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
-  {"hash":"d4b4ed3e1d07b00e","prefixes":{"":1127}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
-  {"hash":"e647f502df0429f5","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"34f8fc43e14bad03","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"5f43507f5a877784","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"1466e6f77352194a","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"e097497d606d17ed","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"05c9b2eb92c8b5ba","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"ce3bfbe09ddeb858","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"3aa96b751d2c0d1c","prefixes":{"":1128}}, // [Mobitrans FZ LLC]
-  {"hash":"289e565c9c686515","prefixes":{"":1129}}, // [CoCo Reef]
-  {"hash":"0b6740b395a65857","prefixes":{"":1130}}, // [Kumma DP LTD]
-  {"hash":"c00365ed4d1c464c","prefixes":{"":1131}}, // [Cablato Limited]
-  {"hash":"9ee2a07ebdef206f","prefixes":{"":1131}}, // [Cablato Limited]
-  {"hash":"e270375f27c5f31c","prefixes":{"":1131}}, // [Cablato Limited]
-  {"hash":"0ebf573ebb6b30e1","prefixes":{"":1131}}, // [Cablato Limited]
-  {"hash":"e28b4c253b1f854f","prefixes":{"":1132}}, // [EURO DISNEY SCA]
-  {"hash":"3c8900c851ba9b28","prefixes":{"":1133}}, // [Norstat]
-  {"hash":"39518e51adbe0cd7","prefixes":{"":1133}}, // [Norstat]
-  {"hash":"2c5efd1ea532f0eb","prefixes":{"":1134}}, // [John Varvatos]
-  {"hash":"5679368e6b2bb34c","prefixes":{"":1135}}, // [Spritz Technology, Inc.]
-  {"hash":"60be7d8a6a76b62f","prefixes":{"":1135}}, // [Spritz Technology, Inc.]
-  {"hash":"cefbe9240a377d95","prefixes":{"":1136}}, // [Wix.com]
-  {"hash":"a56824227bb496f7","prefixes":{"*":1137}}, // [TapTap Networks]
-  {"hash":"41f2ae7d2d6939ae","prefixes":{"":1137}}, // [TapTap Networks]
-  {"hash":"51fd8b1d5b983b31","prefixes":{"":1138}}, // [Permodo]
-  {"hash":"12c3d246c6d4e6b1","prefixes":{"":1138}}, // [Permodo]
-  {"hash":"69da2bfa4e414e2c","prefixes":{"":1138}}, // [Permodo]
-  {"hash":"67bb1e3460d8e2eb","prefixes":{"":1138}}, // [Permodo]
-  {"hash":"38912558a11ff73e","prefixes":{"":1138}}, // [Permodo]
-  {"hash":"eb4d36cf5e4909c1","prefixes":{"":1139}}, // [Gaiam, Inc.]
-  {"hash":"16578371f24a5e90","prefixes":{"":1140}}, // [Plusing interactive co.,Ltd]
-  {"hash":"ecdb68bd2622aa9e","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"8adccb3847cc8b0f","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"2b5433780334b542","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"c853c92986d0cc90","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"388da33e7f0adca1","prefixes":{"":42}}, // [Clinch.co]
-  {"hash":"03d7a65aa1bc87bc","prefixes":{"":1141}}, // [Paypersale]
-  {"hash":"176eb71c0938f4a5","prefixes":{"":111}}, // [Epic Combo Malta Ltd.]
-  {"hash":"4366ec3ae9f41f7c","prefixes":{"":111}}, // [Epic Combo Malta Ltd.]
-  {"hash":"2e9617ef727ff0b5","prefixes":{"":1142}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"11d6d13e3eb48a86","prefixes":{"":1142}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"20e14ef573248fec","prefixes":{"":1142}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"234345fe3c0da842","prefixes":{"":1142}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"30fb60c9c450221d","prefixes":{"":1142}}, // [OCP Collective Corp. (d/b/a AdCade)]
-  {"hash":"69ddc7852224e18f","prefixes":{"":1143}}, // [ESV Digital]
-  {"hash":"240174bad001108d","prefixes":{"":1144}}, // [RevJet LLC.]
-  {"hash":"5250a7a3f2e4f73a","prefixes":{"":1144}}, // [RevJet LLC.]
-  {"hash":"590feb6b793ba20a","prefixes":{"":1144}}, // [RevJet LLC.]
-  {"hash":"23db13cb66f769e3","prefixes":{"":1145}}, // [GET IT Mobile, Inc]
-  {"hash":"cd7cd6c16f714024","prefixes":{"":1145}}, // [GET IT Mobile, Inc]
-  {"hash":"00ea35d76275dbeb","prefixes":{"":1145}}, // [GET IT Mobile, Inc]
-  {"hash":"5239cdae00ff02ea","prefixes":{"":1146}}, // [IBM]
-  {"hash":"e2c539bef8d2970c","prefixes":{"":1147}}, // [Lucid Holdings, LLC]
-  {"hash":"7078be8707b5ec93","prefixes":{"":1147}}, // [Lucid Holdings, LLC]
-  {"hash":"d65fe9ed9f23afbd","prefixes":{"":1148}}, // [Stratio Big Data Inc.]
-  {"hash":"9ccfc7f2ecfbaeec","prefixes":{"":1148}}, // [Stratio Big Data Inc.]
-  {"hash":"54e80254bbf4e20b","prefixes":{"":1149}}, // [Tripping.com]
-  {"hash":"4aaf263b4bae6cd1","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"b782d6c10170e732","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"ceef29c52329c405","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"f14df6ca2e300bb9","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"514c355026c95637","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"b2529b7ebc0cbb27","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"14ebf9b0cbed945c","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"048147eea378ee03","prefixes":{"":1150}}, // [Vidible]
-  {"hash":"7b61440491bd2a65","prefixes":{"":1151}}, // [MiMTiD Corp]
-  {"hash":"036455e7801e853e","prefixes":{"":1151}}, // [MiMTiD Corp]
-  {"hash":"e631f0342d59176b","prefixes":{"":1152}}, // [Moloco, Inc.]
-  {"hash":"87938522c669c682","prefixes":{"":1152}}, // [Moloco, Inc.]
-  {"hash":"a102c87f9921beb6","prefixes":{"":1153}}, // [MEC SP. Z O.O]
-  {"hash":"f9133e4a069a0f4f","prefixes":{"":1153}}, // [MEC SP. Z O.O]
-  {"hash":"6c7737c0ecbf0d91","prefixes":{"":1153}}, // [MEC SP. Z O.O]
-  {"hash":"a82a0c18f6dfb959","prefixes":{"":1153}}, // [MEC SP. Z O.O]
-  {"hash":"e1bea08ea38dc600","prefixes":{"":1154}}, // [Abudantia LLC]
-  {"hash":"d60e1ada8dfa48fa","prefixes":{"":1154}}, // [Abudantia LLC]
-  {"hash":"b57f7b99f9deda72","prefixes":{"":1154}}, // [Abudantia LLC]
-  {"hash":"63f93976910e4aff","prefixes":{"":1154}}, // [Abudantia LLC]
-  {"hash":"93a75f3f5174e472","prefixes":{"":1154}}, // [Abudantia LLC]
-  {"hash":"ba1500537064494c","prefixes":{"":1155}}, // [Realzeit]
-  {"hash":"ce1c3e183853dec6","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"697384881bfb9a85","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"3b5e1e5d71bb095f","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"a55289ec43a1fd1c","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"0ea122741b5a296d","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"139c147db4a66d45","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"91a98ad80489e2aa","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"276f5a9d0ed20d4a","prefixes":{"":1156}}, // [Shanghai DigitalMatrix Information Technology Co.]
-  {"hash":"8408cf6c93d2f24f","prefixes":{"":1157}}, // [Alkemics]
-  {"hash":"658222dab2aa692d","prefixes":{"":1157}}, // [Alkemics]
-  {"hash":"8835156415ef5c70","prefixes":{"":1157}}, // [Alkemics]
-  {"hash":"7d76d0b7c2c49e1c","prefixes":{"":1158}}, // [Sodel Software Solutions Pvt. Ltd.]
-  {"hash":"26b315a19bf762cb","prefixes":{"":1159}}, // [Clearstream.TV, Inc]
-  {"hash":"80ce05889af3bb0e","prefixes":{"":1159}}, // [Clearstream.TV, Inc]
-  {"hash":"2d9798f06f3cd0f8","prefixes":{"":1159}}, // [Clearstream.TV, Inc]
-  {"hash":"4724e51f601e7bfa","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"e0f93294ef7c3cb7","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"ed1e0f5237be934f","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"4a0011b21f8d95f9","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"1af9efa73c3b3b29","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"49eea06f0c13da7f","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"584459c8cfe5595f","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"3b72d8e306588e71","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"f8d6e6d127d9c894","prefixes":{"":1161}}, // [Adluxe]
-  {"hash":"93d864f5e43a3230","prefixes":{"":1161}}, // [Adluxe]
-  {"hash":"793d5c9c5c35b0d9","prefixes":{"":1161}}, // [Adluxe]
-  {"hash":"7b9c5864364d5f5e","prefixes":{"*":1162}}, // [NinthDecimal]
-  {"hash":"7c86152a561c4b4b","prefixes":{"*":1162}}, // [NinthDecimal]
-  {"hash":"ec998efdf99b0c51","prefixes":{"*":1163}}, // [RICH MEDIA STUDIO]
-  {"hash":"e83c01ec741a261e","prefixes":{"":1164}}, // [TenMax Co., Ltd.]
-  {"hash":"e333d70ac6d1acda","prefixes":{"":1165}}, // [twiago GmbH]
-  {"hash":"bb81d5fd8a052b7f","prefixes":{"":1166}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"55b2516509252adb","prefixes":{"":1166}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"59e4e15b4fe6dccd","prefixes":{"":1166}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"f5005d7a14ac0a47","prefixes":{"":1166}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"ecf3dd9926cbe25e","prefixes":{"":1166}}, // [Ad Dynamo International (Pty) Ltd]
-  {"hash":"2ccdffccbbf20e3f","prefixes":{"":1167}}, // [Swarm Enterprises Inc]
-  {"hash":"bf0dd6fdbc53dfee","prefixes":{"":112}}, // [Quixey]
-  {"hash":"ac6a75f10f9f0391","prefixes":{"":1168}}, // [Media Forum]
-  {"hash":"2b5f5e731d08116b","prefixes":{"":1168}}, // [Media Forum]
-  {"hash":"8bf2fe7f00b3c760","prefixes":{"":1169}}, // [Beeswax.io]
-  {"hash":"480bd3bc762861ae","prefixes":{"":1170}}, // [Varick Media Management]
-  {"hash":"d9faa36410c39273","prefixes":{"":1170}}, // [Varick Media Management]
-  {"hash":"6114cbf7f45fd639","prefixes":{"":1171}}, // [JD]
-  {"hash":"739568f083f383e2","prefixes":{"":1171}}, // [JD]
-  {"hash":"1fc63d36c1d330fa","prefixes":{"":1171}}, // [JD]
-  {"hash":"bdb07c050de0bbd2","prefixes":{"":1171}}, // [JD]
-  {"hash":"6b6a891a61b05435","prefixes":{"":1172}}, // [Lotlinx Inc.]
-  {"hash":"b7831e02a1168f7b","prefixes":{"":1172}}, // [Lotlinx Inc.]
-  {"hash":"78f18ca9103e6031","prefixes":{"":1173}}, // [Lotlinx Inc]
-  {"hash":"9a1f751c74a01145","prefixes":{"":40}}, // [F# Inc.]
-  {"hash":"09ddf4e3268e6597","prefixes":{"":1174}}, // [Ingenio, LLC]
-  {"hash":"c5dd0849ac2febc6","prefixes":{"":1175}}, // [MVMT Watches]
-  {"hash":"3b471f8f08410883","prefixes":{"":1176}}, // [C1X Inc]
-  {"hash":"1bb74ab211a41c9c","prefixes":{"":1177}}, // [Vitro Agency]
-  {"hash":"96c0acfcd81b2dd4","prefixes":{"":1178}}, // [Kabbage]
-  {"hash":"0e5b93a6bd6f704b","prefixes":{"":1179}}, // [Redbranch, Inc. (dba Fraudlogix)]
-  {"hash":"a810be7236bf948f","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"ffe13e4342fd9a35","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"91d97869f45df6e0","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"c9f1716ec9d29c4b","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"4a9148e717cb46a9","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"9b57b296c2edd01c","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"1db72ea880eb28dc","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"61889d0078dd40a7","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"fd8f5971bf862430","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"d0da5b57fc3b9611","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"00449172b70d520c","prefixes":{"":1180}}, // [AutoWeb, Inc.]
-  {"hash":"7b3027f5a6cb4f20","prefixes":{"":1181}}, // [Aimee Soft Ltd.]
-  {"hash":"c29f58ba8b9fccc8","prefixes":{"":1181}}, // [Aimee Soft Ltd.]
-  {"hash":"e8cb0d7824f08de4","prefixes":{"":1181}}, // [Aimee Soft Ltd.]
-  {"hash":"97efe77626897346","prefixes":{"":1181}}, // [Aimee Soft Ltd.]
-  {"hash":"78afe44858076c81","prefixes":{"":1181}}, // [Aimee Soft Ltd.]
-  {"hash":"f5162869e573dcd7","prefixes":{"":1182}}, // [SAS Azameo]
-  {"hash":"3d35f5eb2971f5fe","prefixes":{"":17}}, // [iJento]
-  {"hash":"b98ddad6854c87b1","prefixes":{"":1183}}, // [Keyade]
-  {"hash":"65aab53cd46ccc7f","prefixes":{"":1184}}, // [Digital To Store (DTS)]
-  {"hash":"e1e5e1a4c7857257","prefixes":{"":1184}}, // [Digital To Store (DTS)]
-  {"hash":"c9f6517091430433","prefixes":{"":1184}}, // [Digital To Store (DTS)]
-  {"hash":"76d9ee307388af98","prefixes":{"":1184}}, // [Digital To Store (DTS)]
-  {"hash":"8fdb48d3b5466119","prefixes":{"":1184}}, // [Digital To Store (DTS)]
-  {"hash":"bd53e2fe0c663545","prefixes":{"":1185}}, // [Media iQ Digital]
-  {"hash":"58b54a485703f6ba","prefixes":{"":1185}}, // [Media iQ Digital]
-  {"hash":"35616fb4ea0feb94","prefixes":{"":1185}}, // [Media iQ Digital]
-  {"hash":"0a1563142096ed40","prefixes":{"":1186}}, // [Ingenious Technologies]
-  {"hash":"427d170b486c74e6","prefixes":{"":1186}}, // [Ingenious Technologies]
-  {"hash":"79480a2b5de32430","prefixes":{"":1186}}, // [Ingenious Technologies]
-  {"hash":"aaf44b046fb5c10d","prefixes":{"":1187}}, // [Sonicmoov co.,ltd]
-  {"hash":"e5d30ca87b591280","prefixes":{"":1187}}, // [Sonicmoov co.,ltd]
-  {"hash":"9ec9f8d7f0fc8c4a","prefixes":{"":1187}}, // [Sonicmoov co.,ltd]
-  {"hash":"dd0bf16db1e39f59","prefixes":{"":1187}}, // [Sonicmoov co.,ltd]
-  {"hash":"b32a4da2bc7363a0","prefixes":{"":1188}}, // [Bonadza LLC]
-  {"hash":"66a81343ae0223df","prefixes":{"":1188}}, // [Bonadza LLC]
-  {"hash":"ae76287d25b463d2","prefixes":{"":1188}}, // [Bonadza LLC]
-  {"hash":"7429b926177d09a6","prefixes":{"":1188}}, // [Bonadza LLC]
-  {"hash":"170cc20a9af99287","prefixes":{"":1189}}, // [Axis Shift Limited]
-  {"hash":"6e94333e674450ec","prefixes":{"":1190}}, // [TreSensa, Inc.]
-  {"hash":"8fac335d75d968fd","prefixes":{"":1190}}, // [TreSensa, Inc.]
-  {"hash":"eec936c95af6b31f","prefixes":{"":1190}}, // [TreSensa, Inc.]
-  {"hash":"3c744b206f15c46d","prefixes":{"":1190}}, // [TreSensa, Inc.]
-  {"hash":"049a71c722403987","prefixes":{"":1191}}, // [Media Logic Group LLC dba AerisWeather LLC]
-  {"hash":"efa6686cf4b6b73c","prefixes":{"":57}}, // [DeinDeal AG]
-  {"hash":"847219545b169784","prefixes":{"":1192}}, // [Fugumobile]
-  {"hash":"790ab0ec39724b71","prefixes":{"":1193}}, // [Localstars Ltd]
-  {"hash":"0133a556a80fd808","prefixes":{"":1194}}, // [Fluidads]
-  {"hash":"fc8901303bada188","prefixes":{"":1194}}, // [Fluidads]
-  {"hash":"ba549c39b1f43523","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"5d0b84261f7b6d5c","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"d48dde21b5917906","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"337dabe98702ae52","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"efad84d0a4dd4e46","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"019c3ee24427b355","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"ec79c848ccf2d648","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"ccf7fd5647b92698","prefixes":{"*":1195}}, // [Wayfair LLC]
-  {"hash":"3b03a24eea2a6345","prefixes":{"":1196}}, // [VCCORP CORPORATION]
-  {"hash":"f7f53c88139460cf","prefixes":{"":1197}}, // [IGAWorks]
-  {"hash":"93b9518285f54887","prefixes":{"":1198}}, // [Cellcom Ltd]
-  {"hash":"f59e6427783c3da0","prefixes":{"*":1199}}, // [Upsolver]
-  {"hash":"adb55d98bb4aef6e","prefixes":{"":1199}}, // [Upsolver]
-  {"hash":"7efba976eeea2d41","prefixes":{"":1199}}, // [Upsolver]
-  {"hash":"cdde375c1240991d","prefixes":{"":935}}, // [Channel Factory, LLC]
-  {"hash":"79c4dc57905857aa","prefixes":{"":1200}}, // [Phluidmedia, Inc.]
-  {"hash":"4948ea141d1a72e1","prefixes":{"":1200}}, // [Phluidmedia, Inc.]
-  {"hash":"e4aed5bf5c295c3a","prefixes":{"":1201}}, // [Roy Morgan Research Ltd]
-  {"hash":"547734f17effda77","prefixes":{"":1202}}, // [TapSense, Inc.]
-  {"hash":"96289aeef06d0a9f","prefixes":{"":1203}}, // [Southwest Airlines]
-  {"hash":"de497c6fbed4588d","prefixes":{"":794}}, // [Hatena Co., Ltd]
-  {"hash":"91412d534d321cb4","prefixes":{"":1204}}, // [Market Points, Inc.]
-  {"hash":"97aab20dd873dd2c","prefixes":{"":1205}}, // [UberMedia Inc.]
-  {"hash":"73cadeea8e1bd9e8","prefixes":{"":1205}}, // [UberMedia Inc.]
-  {"hash":"0e1bd2938a06a2e6","prefixes":{"":1206}}, // [Kadam SIA]
-  {"hash":"aa9658253aa81e62","prefixes":{"":1206}}, // [Kadam SIA]
-  {"hash":"75f1eab33abfa4f9","prefixes":{"":1206}}, // [Kadam SIA]
-  {"hash":"59f64b09b8e430ae","prefixes":{"":1206}}, // [Kadam SIA]
-  {"hash":"61947a042af2e3e8","prefixes":{"":1207}}, // [Alveo Platform (VMM own bidder)]
-  {"hash":"62c095e8dfbb0458","prefixes":{"":1208}}, // [Adbalancer EDV-DienstleistungsgesellschaftgmbH]
-  {"hash":"5cc57103c26df76f","prefixes":{"":1208}}, // [Adbalancer EDV-DienstleistungsgesellschaftgmbH]
-  {"hash":"53685a43fc711ea4","prefixes":{"":1209}}, // [JWPlayer]
-  {"hash":"53bdf03af7a44e2c","prefixes":{"":1209}}, // [JWPlayer]
-  {"hash":"eaff21a1a9591dab","prefixes":{"":1209}}, // [JWPlayer]
-  {"hash":"1d5626ba7394e6a1","prefixes":{"":1209}}, // [JWPlayer]
-  {"hash":"2e106bd1d1d064c6","prefixes":{"":1209}}, // [JWPlayer]
-  {"hash":"9f7691306b0805ea","prefixes":{"":1209}}, // [JWPlayer]
-  {"hash":"909df8f91bd33085","prefixes":{"*":1210}}, // [Adiquity Technologies Pvt Ltd]
-  {"hash":"d1eca614d3cc8883","prefixes":{"":1211}}, // [Smart Digital GmbH]
-  {"hash":"53d8de6b018c1793","prefixes":{"":1212}}, // [Auditorius LLC]
-  {"hash":"fd9a420ade305e17","prefixes":{"":1213}}, // [Treepodia]
-  {"hash":"c9fd06f055d4af40","prefixes":{"":1213}}, // [Treepodia]
-  {"hash":"6eb24d470a6f1018","prefixes":{"":1213}}, // [Treepodia]
-  {"hash":"e35bb07367786d4c","prefixes":{"":1214}}, // [Adamatic]
-  {"hash":"3943df18ad20915d","prefixes":{"":1214}}, // [Adamatic]
-  {"hash":"341d248dc25e4ea7","prefixes":{"":1214}}, // [Adamatic]
-  {"hash":"ad1f1681bab5cc6b","prefixes":{"":1215}}, // [SAS Web2ROI]
-  {"hash":"532b5bfa711f405e","prefixes":{"":1216}}, // [Cardlytics]
-  {"hash":"799c283a6f1c8ece","prefixes":{"":1217}}, // [MyFonts Inc.]
-  {"hash":"4448bee927dde7e6","prefixes":{"*":1218}}, // [Bluecore, Inc.]
-  {"hash":"a0bd7b7a099833b6","prefixes":{"":1218}}, // [Bluecore, Inc.]
-  {"hash":"fa3e77058c021551","prefixes":{"*":1218}}, // [Bluecore, Inc.]
-  {"hash":"4761d233715098ce","prefixes":{"":1219}}, // [EverQuote, Inc.]
-  {"hash":"35694b7df8059b22","prefixes":{"":1219}}, // [EverQuote, Inc.]
-  {"hash":"0740880077130a2d","prefixes":{"":1220}}, // [Optimize LCC D.B.A Genius Monkey]
-  {"hash":"bfe2c1b41278b804","prefixes":{"":1220}}, // [Optimize LCC D.B.A Genius Monkey]
-  {"hash":"6dd3f6dcd500314e","prefixes":{"":1220}}, // [Optimize LCC D.B.A Genius Monkey]
-  {"hash":"2f3f7cacd3fe0763","prefixes":{"*":1221}}, // [EverString Technology Ltd]
-  {"hash":"bca80e9becb74dcb","prefixes":{"*":1221}}, // [EverString Technology Ltd]
-  {"hash":"46edf29e9ba4ff96","prefixes":{"":1222}}, // [Axonix Limited]
-  {"hash":"98961093c86583f5","prefixes":{"":1223}}, // [Ubimo Ltd.]
-  {"hash":"1110ef291b2bd2e8","prefixes":{"":1224}}, // [gskinner.com,Inc]
-  {"hash":"e36b044e9f38bad6","prefixes":{"":1225}}, // [PlaceIQ, Inc.]
-  {"hash":"fe5b89fe7dbbd534","prefixes":{"":1226}}, // [DataBerries]
-  {"hash":"ddf083a57d484592","prefixes":{"":1227}}, // [Otto (GmbH & Co KG)]
-  {"hash":"7975f7864f4fa759","prefixes":{"":1228}}, // [Beijing ADirects Technology Corporation Limited]
-  {"hash":"657d40c4d7322985","prefixes":{"":1229}}, // [MagicGroup Asia Pte. Ltd.]
-  {"hash":"f5559eee02dd33ad","prefixes":{"":1229}}, // [MagicGroup Asia Pte. Ltd.]
-  {"hash":"e81aa2815c378230","prefixes":{"":1229}}, // [MagicGroup Asia Pte. Ltd.]
-  {"hash":"49269f9273c66c00","prefixes":{"":1230}}, // [Local Content, Inc.]
-  {"hash":"210fa7d8376be47a","prefixes":{"":1230}}, // [Local Content, Inc.]
-  {"hash":"e4ba8ed4e3abc143","prefixes":{"":1231}}, // [Flavia]
-  {"hash":"269e0d49e8a941b8","prefixes":{"":43}}, // [Transout Inc.]
-  {"hash":"b9cd0135bbe2cf40","prefixes":{"":43}}, // [Transout Inc.]
-  {"hash":"e4b01f2271c4171a","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"e5b4daaa6c4ae231","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"cfb3a28bf24f27aa","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"db9ed30c0cbece36","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"dd0d7f22eaea16dd","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"4f3fc6e6fa75b1e8","prefixes":{"":44}}, // [ADZIP]
-  {"hash":"17a3e1cbc6818d71","prefixes":{"*":1232}}, // [Webtype]
-  {"hash":"39697008117e49f0","prefixes":{"":1233}}, // [Aditor]
-  {"hash":"50bd67909486f9f5","prefixes":{"":1233}}, // [Aditor]
-  {"hash":"d58ef2e47a1b5b3b","prefixes":{"":1234}}, // [YCmedia]
-  {"hash":"fc8e2c447edda6c9","prefixes":{"":1235}}, // [Addwish Aps]
-  {"hash":"d5ac956c9f185ddc","prefixes":{"":1236}}, // [AIDO TECHNOLOGY INC.]
-  {"hash":"24015d44b9900d67","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"460c0600751cbd60","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"77050f5bbccffdb1","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"cdf17fb674f06ff0","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"8fb430c8ece16b19","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"c9d79e6f1f2694cd","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"80c75e37374a2ef0","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"5f9ca3a706ea1a32","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"2839cda166e75a72","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"762d13ee90c23c96","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"c0ea3a6ac5a15ff4","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"70c0b65944772c14","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"06d5db93059745e1","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"ea0e52e08087883d","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"dd48f2110336efda","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"bac37ceef6479f6b","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"a16d986f3ad09790","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"44addae7b850b89f","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"ef08ba4268518e6e","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"1f2560020ac4a5dd","prefixes":{"":1237}}, // [Herolens Group LLC]
-  {"hash":"67339d8f9c205d19","prefixes":{"":1238}}, // [Fuisz Media, Inc.]
-  {"hash":"b3ebdb16675afb79","prefixes":{"":1238}}, // [Fuisz Media, Inc.]
-  {"hash":"33e8b1a10d6cf9bb","prefixes":{"":1238}}, // [Fuisz Media, Inc.]
-  {"hash":"33c97b2942fbfb43","prefixes":{"":1239}}, // [Bucksense, Inc.]
-  {"hash":"f7be89ec6f521ed4","prefixes":{"":664}}, // [Adiant]
-  {"hash":"8ad32c44e7f009d9","prefixes":{"":1240}}, // [Taylor Nelson Sofres Ukraine LLC]
-  {"hash":"9913ba5c46add495","prefixes":{"*":1241}}, // [MotionLead]
-  {"hash":"ed341f6ed9722885","prefixes":{"":1242}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"b84298a2bc76c877","prefixes":{"":1242}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"d7bd450b5571f32e","prefixes":{"":1242}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"788739abab822f20","prefixes":{"":1242}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"5119113b90253a71","prefixes":{"":1242}}, // [CJSC Recomendatsii tovarov i uslug]
-  {"hash":"8391f54ef2dd8235","prefixes":{"":1243}}, // [Adobe Edge]
-  {"hash":"ecbec0da60be727e","prefixes":{"":1243}}, // [Adobe Edge]
-  {"hash":"45df05b3b1fd2039","prefixes":{"":1243}}, // [Adobe Edge]
-  {"hash":"7f8b63980ada138f","prefixes":{"":1244}}, // [Bizible]
-  {"hash":"fcff0eb6c45bdf72","prefixes":{"":1245}}, // [Adludio Limited]
-  {"hash":"58ae271664061630","prefixes":{"":1245}}, // [Adludio Limited]
-  {"hash":"19795a3ce2a7e620","prefixes":{"":1245}}, // [Adludio Limited]
-  {"hash":"aa3822d449c78db7","prefixes":{"":1245}}, // [Adludio Limited]
-  {"hash":"b1269cde121b05a1","prefixes":{"":1245}}, // [Adludio Limited]
-  {"hash":"1581c4afe0d48fa2","prefixes":{"":1246}}, // [Ally Financial]
-  {"hash":"2e171be7640cf4cd","prefixes":{"":1247}}, // [AIAd Ltd.]
-  {"hash":"ae7e973c225c0a01","prefixes":{"":1248}}, // [Petplan]
-  {"hash":"78db497564cd4bf9","prefixes":{"bis":1249,"":1249,"openrtb":1249}}, // [Vidazoo Ltd.] [Vidazoo Ltd.] [Vidazoo Ltd.]
-  {"hash":"c0fe1ea55404bcbb","prefixes":{"bis":1249}}, // [Vidazoo Ltd.]
-  {"hash":"f7fbe362db50024a","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"55abab5eb4ff10bd","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"e542a9dea283be31","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"a49f5bf572a22bae","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"7e02810393b6fe89","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"89c0cbd03222de92","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"31a98e1d5bba9ae8","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"15010236a7d3b5a4","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"9f927848d0417d12","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"7a2f5d3665e9a31a","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"02fb27611632d82c","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"0b95d00c8ef095ae","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"2d42c2d0a5ab84ae","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"5e405c19a402590e","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"d037ae4b54d7e7ec","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"fa3f8d822f471c8e","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"1fd9bf19c5906c01","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"f989a4e87da3e6d9","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"26937f461d535e88","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"755c357326a37b3f","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"aac0686686b2d53c","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"3ce944fa0cf0291a","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"7302f12cc4ace16b","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"52816f3d4542b887","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"59bf7df499fa52b5","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"ebabd6c7d62c634c","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"53ac53e2f538f2e2","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"3ed73abadb9c898a","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"9574295460ce8d22","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"d591fdb6045eb90f","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"8b39993907ef0e90","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"fff9c91a1d02e69d","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"d086a625516bdfc4","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"dedb3c41790f0b92","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"d9d28815b7351be9","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"0eceb2a8a6aa5014","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"c3cd28d4911901ef","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"906300510974cf1a","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"6bbcc411e84396ce","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"18f5beb4c7518ce0","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"445bbe1950cddd7b","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"2b7cc0f2bdc9e984","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"2e1ee42fbe53923e","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"0d75de8359eb1e90","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"5439763db9182a6c","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"924a269d7fa953ef","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"56592bc98da7add7","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"e350307b97e81944","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"62d2d232adb7f5ce","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"9dbd1f71df681f87","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"60aa872cca3ea408","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"574290c159276582","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"520b03b31ba99ffe","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"8927dc4db3ffd9a0","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"cea75e5e1bcb3e75","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"00fc1e5ba5cf11e1","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"241443df62a11bdb","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"958852e67d999446","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"d7dde4fdd1b42ac2","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"b9a6386a13d1f59c","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"1b00c21eb7dca0ba","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"3b5a0569a91c1f27","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"07b3c413dcf0891e","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"4b15aef39cd29476","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"25743e7a87ec9352","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"2fe16a518eee6e23","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"a154647a02beff09","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"73a06806ded66bc0","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"a82c6297f56276f8","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"514b9e5dcf88791d","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"80e10fe664c9676b","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"788de2248f446546","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"e1e58f0b49a0e5c7","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"c56afa9dadaace8c","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"4084c6a05941d212","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"fafe943a3ce4b828","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"00cfc10d1f469dfc","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"cdb86fef4fddecdd","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"97b3473c7082a4c8","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"99973a84d3bda612","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"ba67aff057d8dc5d","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"a3c0da72dbefc878","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"5925a6291dd2ab40","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"34129d9457495ffd","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"e2505c6002184e33","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"9bcac0e9fd77ddc6","prefixes":{"":1249}}, // [Vidazoo Ltd.]
-  {"hash":"737c1868e55d5b37","prefixes":{"":1250}}, // [RTBstar LLC]
-  {"hash":"302ec6d6755746d6","prefixes":{"*":1251}}, // [Chalk Media Holdings]
-  {"hash":"202f611d1eab4195","prefixes":{"*":1251}}, // [Chalk Media Holdings]
-  {"hash":"a6ab491761f03a1c","prefixes":{"":1252}}, // [Oxford Biochronometrics]
-  {"hash":"3f8968d2bc62134f","prefixes":{"":1252}}, // [Oxford Biochronometrics]
-  {"hash":"fbe6ab3bc9d21558","prefixes":{"":1252}}, // [Oxford Biochronometrics]
-  {"hash":"769529a9ad14a9b6","prefixes":{"":1253}}, // [SGN Games, Inc.]
-  {"hash":"f1a29a10c1ad80be","prefixes":{"*":1254}}, // [Crutchfield New Media, LLC]
-  {"hash":"930e98a126b97c02","prefixes":{"":113}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"915e8620d61e782c","prefixes":{"":113}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"0492037eab3835e9","prefixes":{"":113}}, // [YOOX NET-A-PORTER GROUP SPA]
-  {"hash":"5eee79daa9337871","prefixes":{"":1255}}, // [Laserlike Inc]
-  {"hash":"3262121ae456ec62","prefixes":{"":1256}}, // [Adtile Technologies Inc.]
-  {"hash":"eefeb24c8c0df59f","prefixes":{"":1256}}, // [Adtile Technologies Inc.]
-  {"hash":"2f77e3292a158b3c","prefixes":{"":1256}}, // [Adtile Technologies Inc.]
-  {"hash":"ed04984091cd6edc","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"63c7ce8ea1112262","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"842d35d55c520fe2","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"3fb91c004caeeba4","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"4673bf1b8fb41012","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"60c5047efc444089","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"9daf201eb861bd5a","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"8fb045042ba8dab7","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"b5c5f11aa533f8f8","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"e69760fd18a7e847","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"afdb50efeb58adb3","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"54ade0c2fc33d554","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"980a9356a0a0604b","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"0d064f41dd06b071","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"4e9cc6d069d0700f","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"abc81c5ff7313f61","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"4d8e54db683834b5","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"958c891ea7a22760","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"02b0aa7dbed4dc70","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"cd655ca6f3e7c5b4","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"117f6d5c385c0fbf","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"974b3e895eb889a1","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"2315e038cabe7cf3","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"256e6db135713c95","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"44b4921e1dd83428","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"2ececb465fbab022","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"b3a40f1c056c981d","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"c4f8f640f24e3592","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"0a6e85210f1d99c3","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"d12573269a748046","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"deabc924d996a1ca","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"cfae73045c7b29a6","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"c97db9d5ee0b71c7","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"ca6bb3442fa58646","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"f38fbdc9759c0ef4","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"6db47cd08bed3122","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"86c0634020121d1e","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"98c1045cd61f979d","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"7bdc1a49cf0ccc1d","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"cdceb4fead43eafb","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"b8a7ac4ace0ce6e9","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"081ccef35be56b36","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"e29de726004b6e06","prefixes":{"":1257}}, // [Adgravity]
-  {"hash":"3044eb15f0757788","prefixes":{"":1258}}, // [Protected Media LTD]
-  {"hash":"675f561d3f31df38","prefixes":{"":1258}}, // [Protected Media LTD]
-  {"hash":"506fa56f8b748a67","prefixes":{"":1259}}, // [Media Detect GmbH]
-  {"hash":"d8795d8df3c0b355","prefixes":{"":1260}}, // [Centro CDN]
-  {"hash":"92690e6cf2068609","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"bcb296520399e855","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"eeba4d486f2a193f","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"36ba79aa125ace1d","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"755e0fb3a6d853e7","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"926c7d8c47cdc6a4","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"112f8b5a749d05e9","prefixes":{"":1261}}, // [DeltaX]
-  {"hash":"9a9421d022c231d0","prefixes":{"":1262}}, // [jQuery]
-  {"hash":"7ed84366898b6e95","prefixes":{"":1263}}, // [SoMo Audience Corp.]
-  {"hash":"7b7b8f4fea812106","prefixes":{"":1263}}, // [SoMo Audience Corp.]
-  {"hash":"cd27a627925b605e","prefixes":{"":1263}}, // [SoMo Audience Corp.]
-  {"hash":"8de4d0c2e5a785d3","prefixes":{"":1263}}, // [SoMo Audience Corp.]
-  {"hash":"dd090795aa41d39d","prefixes":{"":1263}}, // [SoMo Audience Corp.]
-  {"hash":"a792d2d9ef8b7d44","prefixes":{"":1264}}, // [Distribute Ltd]
-  {"hash":"a41d8bffbb4dde29","prefixes":{"c":1264}}, // [Distribute Ltd]
-  {"hash":"cb03110aa3eafbc3","prefixes":{"":1264}}, // [Distribute Ltd]
-  {"hash":"f8d5c1c3c0137b95","prefixes":{"":1264}}, // [Distribute Ltd]
-  {"hash":"fdbd7675a0a4e4d2","prefixes":{"":1264}}, // [Distribute Ltd]
-  {"hash":"c152daf3639bfd61","prefixes":{"":1265}}, // [Poppin]
-  {"hash":"77afc197a9ed3c55","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"f000d51ba83c9b81","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"e6b0bd562a8a6c44","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"b67bb576e01ff3b8","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"b74cae0d407627c6","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"d02ca334243aeff6","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"27c4aebe8feb1d61","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"cffac58b1fe6a120","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"060b85b3672a94b9","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"993dbbd9a4428116","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"5d08c05fd8f3e6b6","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"733a8e48aa3496c3","prefixes":{"":1266}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
-  {"hash":"6dfff15240319d9a","prefixes":{"":1267}}, // [Art of Click Pte. Ltd]
-  {"hash":"3771e4f81d75a524","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"b2d089ed26249e9c","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"6cb0920968e42462","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"779587babf9a845a","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"21fd838e467abf9e","prefixes":{"":45}}, // [Adways SAS]
-  {"hash":"f35db5d8e41be046","prefixes":{"":1268}}, // [Quantasy LLC]
-  {"hash":"fb881e61783803db","prefixes":{"":1269}}, // [Wavenet Technology Co., Ltd.]
-  {"hash":"4a5a7154d849b6df","prefixes":{"":1270}}, // [ENVISIONX LTD]
-  {"hash":"4c0fc55e8fe8be51","prefixes":{"":1271}}, // [Adhood]
-  {"hash":"62b3383734c496fb","prefixes":{"":1271}}, // [Adhood]
-  {"hash":"27e40c1642b59b0e","prefixes":{"":1271}}, // [Adhood]
-  {"hash":"b7bcec8f502b24cf","prefixes":{"":1271}}, // [Adhood]
-  {"hash":"b8885905bf9e213f","prefixes":{"":1271}}, // [Adhood]
-  {"hash":"8238d8729bb3748c","prefixes":{"":1272}}, // [Telogical Systems, LLC]
-  {"hash":"92dbc0e618f7816a","prefixes":{"":1272}}, // [Telogical Systems, LLC]
-  {"hash":"d3be8ee2ff24c8dd","prefixes":{"":1272}}, // [Telogical Systems, LLC]
-  {"hash":"0767b016186f9908","prefixes":{"":1273}}, // [twyn group IT solutions & marketing services G]
-  {"hash":"1bf7b44093f4c0b5","prefixes":{"":1274}}, // [Marchex Sales, LLC]
-  {"hash":"b60099c5a3ff5579","prefixes":{"":1275}}, // [SmartyAds LLP]
-  {"hash":"e1e5cbc69ff27126","prefixes":{"":1275}}, // [SmartyAds LLP]
-  {"hash":"01e34dcf6356f25b","prefixes":{"":1275}}, // [SmartyAds LLP]
-  {"hash":"0587980840cbad28","prefixes":{"":1275}}, // [SmartyAds LLP]
-  {"hash":"c13574923293d7c7","prefixes":{"":1276}}, // [Reach150 Social, Inc.]
-  {"hash":"e87358da2b6ad070","prefixes":{"":1277}}, // [Leadmill ApS]
-  {"hash":"2a24bd7dfe371075","prefixes":{"":1277}}, // [Leadmill ApS]
-  {"hash":"3f6b6ba536add909","prefixes":{"":1278}}, // [TapHeaven, Inc.]
-  {"hash":"050f2328d34461a7","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"a66968f05d34f468","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"2c309ae9bbbe9384","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"fec9fa0c1f3ffe6e","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"49989970caa95c3d","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"32eb6e39519c6d65","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"5ecf91c30b7a0a6a","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"6394e1f93c660614","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"3c6f41d29f5df8e7","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"cda46d94d7efda5c","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"164782d64f732408","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"af8c779439f17da0","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"0394176d4d575a93","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"c9a808631e01ad1a","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"1478be442db9d539","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"171f00354c5c6b43","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"521c6ad185dff69d","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"a7c6cb92086909f4","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"efb2ad70cb64944c","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"35e50ce841196503","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"683154a56472f3e2","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"6664d0e4be1a2011","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"efefa03759c8eb89","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"20477544dc10c916","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"922d2397edef5dbd","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"a9591e706ed0da18","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"c073c895bf061908","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"8a7804498832f633","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"45c2a9f766453c46","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"2a167f8c5d41c9de","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"0992810376313bba","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"e4588caa0c232726","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"73fbee089a438309","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"48743ee797fa8c98","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"22561af78d8aeebe","prefixes":{"":1279}}, // [spring GmbH & Co. KG]
-  {"hash":"ee6f381082694c53","prefixes":{"":1280}}, // [Roq.ad GmbH]
-  {"hash":"606e92e46118e68c","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"5dd554237e590e7a","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"47c55cdc2352963b","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"698477bb42f577d9","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"4d35613bf3c5608c","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"8bbcbb68e24aba75","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"b5d289baee77f3bb","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"1eab99893ccb6812","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"2d38a36747a2e4c8","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"2aaee44de4212440","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"720594080864ccd0","prefixes":{"":1281}}, // [AdKernel LLC]
-  {"hash":"8cf8db96c95ad703","prefixes":{"":1282}}, // [Uprise Technologies]
-  {"hash":"bdc43b963f1225e2","prefixes":{"":1283}}, // [Sled, Inc.]
-  {"hash":"bd39b2a3b45ba87e","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"987e96fd53ac3377","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"ae49bd17dd4ead54","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"8d132f34a86f51b3","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"4210564496763546","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"c395c961fb4a60ae","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"2f37a86d54dbe4f9","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"04730e3fb984e716","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"8e040ece0573e008","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"a2aafd8d622f674d","prefixes":{"":1284}}, // [Pengtai Interactive Advertising Co.Ltd]
-  {"hash":"4da566f98e41e44f","prefixes":{"":1285}}, // [Adello Group AG]
-  {"hash":"469779ba0b2d7340","prefixes":{"":1286}}, // [BitGravity]
-  {"hash":"bfa6d675fa0c17c3","prefixes":{"":1287}}, // [44 Interactive]
-  {"hash":"ac3b5f670d7fd934","prefixes":{"*":1288}}, // [KeyCDN]
-  {"hash":"1058dbbc2bdc3042","prefixes":{"*":1288}}, // [KeyCDN]
-  {"hash":"d36cc93ea8fd1701","prefixes":{"":1289}}, // [Shopalyst Technologies Pvt Ltd]
-  {"hash":"95ad856091f4bc84","prefixes":{"":1289}}, // [Shopalyst Technologies Pvt Ltd]
-  {"hash":"848239e92ef8cdab","prefixes":{"":1290}}, // [Total Access Communication Public Company Limited]
-  {"hash":"0607ff309fec62de","prefixes":{"":1291}}, // [TACTIC Real-time marketing AS]
-  {"hash":"abcc33d7fb9de6d9","prefixes":{"":1292}}, // [Mobilewalla, Inc]
-  {"hash":"c7bbc2be78119074","prefixes":{"":1293}}, // [Nuviad Ltd]
-  {"hash":"63da29d5b072ec2a","prefixes":{"*":1294}}, // [AmberData LLC]
-  {"hash":"6c2f34d23d272f4b","prefixes":{"":1295}}, // [Aedgency]
-  {"hash":"2da837b490e2d01c","prefixes":{"":1296}}, // [MobPartner, Inc.]
-  {"hash":"900c7f6444e6ccdd","prefixes":{"":1297}}, // [AdTriba GmbH]
-  {"hash":"9110b2853fbfc1f4","prefixes":{"":1297}}, // [AdTriba GmbH]
-  {"hash":"0a9e29016a6f697e","prefixes":{"":1298}}, // [DISH Network L.L.C.]
-  {"hash":"8c7746484c824908","prefixes":{"":1299}}, // [Monotype Imaging Inc.]
-  {"hash":"11826b3490b70597","prefixes":{"":1299}}, // [Monotype Imaging Inc.]
-  {"hash":"55b9261efb54de8c","prefixes":{"":1299}}, // [Monotype Imaging Inc.]
-  {"hash":"57f3bae0dc69937f","prefixes":{"":1299}}, // [Monotype Imaging Inc.]
-  {"hash":"b5158a795c80a5a2","prefixes":{"":1300}}, // [MEDIAN Ltd.]
-  {"hash":"e79098d30fde1a28","prefixes":{"":1301}}, // [ClickForce Inc.]
-  {"hash":"36739070f3c0ff16","prefixes":{"":1301}}, // [ClickForce Inc.]
-  {"hash":"40febfb412ba6ddb","prefixes":{"":1302}}, // [Zemanta Inc.]
-  {"hash":"80e8d865a27bacac","prefixes":{"":237}}, // [Hostelworld.com Limited]
-  {"hash":"2a3acfae7d4bdd9b","prefixes":{"":861}}, // [Barometric]
-  {"hash":"a48dde8fab3a9ca1","prefixes":{"*":1303}}, // [jsdelivr.com]
-  {"hash":"82b544dbc2fdd536","prefixes":{"*":1304}}, // [Adssets AB]
-  {"hash":"46106972e3ebaddb","prefixes":{"":1305}}, // [Sellpoints Inc.]
-  {"hash":"bbc8c43681364c14","prefixes":{"":46}}, // [Opera Mediaworks Inc.]
-  {"hash":"a3ff6df6612f21df","prefixes":{"":46}}, // [Opera Mediaworks Inc.]
-  {"hash":"759162b5823db802","prefixes":{"":1306}}, // [HockeyCurve Growth Solutions Pvt Ltd]
-  {"hash":"b3f9f03fb2c77a95","prefixes":{"":1307}}, // [HockeyCurve Growth Solutions Pyt Ltd]
-  {"hash":"0dcbeed5fe35278e","prefixes":{"":1307}}, // [HockeyCurve Growth Solutions Pyt Ltd]
-  {"hash":"e6898006d78eca08","prefixes":{"":1308}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"c2ecb9f34950ae64","prefixes":{"":1308}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"e530de1f6ff8ed8c","prefixes":{"":1308}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"ef9efb2dfd9b223f","prefixes":{"":1308}}, // [Umeng Plus Beijing Technology Limited Company]
-  {"hash":"8dad79c9e968f7ca","prefixes":{"":1309}}, // [Survata, Inc.]
-  {"hash":"7a5110db80c0493f","prefixes":{"":1309}}, // [Survata, Inc.]
-  {"hash":"e8cb0ee7c430e881","prefixes":{"":1310}}, // [JustWatch GmbH]
-  {"hash":"c85404f2f558dbd2","prefixes":{"":1310}}, // [JustWatch GmbH]
-  {"hash":"b44b63d6e81094e4","prefixes":{"":1310}}, // [JustWatch GmbH]
-  {"hash":"e1614140e3cef4fd","prefixes":{"":1310}}, // [JustWatch GmbH]
-  {"hash":"2cfd0204e2673c60","prefixes":{"":1311}}, // [Interactive Tracker Next]
-  {"hash":"1c5f8f88ce98b360","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"fbac71ab5dbe5025","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"4e08c60f61b1ac87","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"3f4bfa67b5290ada","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"a9b4af4145bf90b2","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"d0d20b9b53b41e58","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"ff37598c00132a2a","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"daae3b285b4abeee","prefixes":{"":1312}}, // [Unisport A/S]
-  {"hash":"20cdb1f9a8066fe2","prefixes":{"":1313}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
-  {"hash":"a53281df69681314","prefixes":{"":1313}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
-  {"hash":"f25344f6f85b0f61","prefixes":{"":1313}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
-  {"hash":"b544d72a6726ee1d","prefixes":{"":1314}}, // [Softcube Inc.]
-  {"hash":"d924c399f5813397","prefixes":{"":1315}}, // [YOptima Media Solutions Pvt. Ltd]
-  {"hash":"3405e57b3b784a16","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"8a5251fd38cf1d3b","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"039987610c50338a","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"0f7d3c301f70dfd0","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"77f81cf76bb9bd07","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"ec6a93785f45f030","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"3fcf5b9a36bb776b","prefixes":{"":1316}}, // [ZMAGS INC]
-  {"hash":"b81945950b163ad1","prefixes":{"":1307}}, // [HockeyCurve Growth Solutions Pyt Ltd]
-  {"hash":"36c7ea48fdc42362","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"a3bfc331d20ba3e8","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"64a6cb69505f47a8","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"e7d85f73b7514aa9","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"0263af098607c6d6","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"5c911e8fdb9b3507","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"665d12aaa10c1858","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"206d02e9bc6dc66f","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"681210fb48272cc7","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"f42b80ceeefbc2e4","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"9b951656519bc7f0","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"f615949643fdcebb","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"814934c13235b868","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"d451d289ed990ba0","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"b2de6bb8607f747e","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"fa9dba37389c8a9e","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"fe776ee0016175b8","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"1a561a0db871620b","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"84440122e5725865","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"f98baedc7354d85b","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"cedef135a07c2d1b","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"b7196f696d55352b","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"90c8f9118f9c2653","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"7ec460729f94a446","prefixes":{"":1317}}, // [Realtag]
-  {"hash":"c84baed94e3d3a6c","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"88c72a0edf15af94","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"8ffa9e7ae82fdaf3","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"b2b5e138d12de438","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"1249b88e4ce20439","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"9555623f08217ce6","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"0358d164ffcdc51b","prefixes":{"":1318}}, // [Bitsngo.net]
-  {"hash":"d27b1458c8f91a54","prefixes":{"":1319}}, // [AdCanvas]
-  {"hash":"5fd4bc3f3699146f","prefixes":{"":1319}}, // [AdCanvas]
-  {"hash":"62f35089b9876ae5","prefixes":{"":1319}}, // [AdCanvas]
-  {"hash":"92d701b4810ee717","prefixes":{"":1319}}, // [AdCanvas]
-  {"hash":"3f927191adac8a66","prefixes":{"":1319}}, // [AdCanvas]
-  {"hash":"051c9e70f0515e04","prefixes":{"":1320}}, // [Happyfication, Inc.]
-  {"hash":"13580fc82945639c","prefixes":{"":1320}}, // [Happyfication, Inc.]
-  {"hash":"914acd1211445b65","prefixes":{"":1320}}, // [Happyfication, Inc.]
-  {"hash":"046e11a0cbc2124d","prefixes":{"":1320}}, // [Happyfication, Inc.]
-  {"hash":"df5483bdd241c0b5","prefixes":{"":258}}, // [HQ GmbH]
-  {"hash":"8ee2f36b1789e47d","prefixes":{"":1321,"*":1322}}, // [Cinarra Systems Japan株式会社] [Cinarra Systems Japan]
-  {"hash":"92d76828c2bc5e86","prefixes":{"":959}}, // [MotoMiner]
-  {"hash":"014c99288a655e93","prefixes":{"":1323}}, // [CUBED Attribution]
-  {"hash":"34d44a28a42c30fc","prefixes":{"":1323}}, // [CUBED Attribution]
-  {"hash":"6525e4a55892b035","prefixes":{"":1324}}, // [StackAdapt Inc.]
-  {"hash":"9108433b6be75366","prefixes":{"":1324}}, // [StackAdapt Inc.]
-  {"hash":"ca5914cdc3f95c5a","prefixes":{"":1324}}, // [StackAdapt Inc.]
-  {"hash":"e25d7e6b7298b655","prefixes":{"":1325}}, // [Statiq Ltd]
-  {"hash":"63a988f83e509eca","prefixes":{"":47}}, // [DistroScale Inc.]
-  {"hash":"e6c8188134efb49f","prefixes":{"":47}}, // [DistroScale Inc.]
-  {"hash":"eab29bab9fd4b969","prefixes":{"":47}}, // [DistroScale Inc.]
-  {"hash":"c24f6dcb16cfd4e4","prefixes":{"":47}}, // [DistroScale Inc.]
-  {"hash":"e6a95c6bb8d6efd4","prefixes":{"":1326}}, // [Tagular Analytics, LLC]
-  {"hash":"9c2dcc6473dee219","prefixes":{"":1326}}, // [Tagular Analytics, LLC]
-  {"hash":"986af10dd127ff07","prefixes":{"":1326}}, // [Tagular Analytics, LLC]
-  {"hash":"f74107ff21d433e9","prefixes":{"":1326}}, // [Tagular Analytics, LLC]
-  {"hash":"ce5c1378f1f941f6","prefixes":{"":1327}}, // [ComboTag Technologies Ltd.]
-  {"hash":"879f914a15df34e0","prefixes":{"":1328}}, // [Juice Mobile]
-  {"hash":"17e1300dbcc39afb","prefixes":{"":1328}}, // [Juice Mobile]
-  {"hash":"d22e60c27d37cebc","prefixes":{"":1328}}, // [Juice Mobile]
-  {"hash":"80d91748976f3124","prefixes":{"":1328}}, // [Juice Mobile]
-  {"hash":"74478806654499c0","prefixes":{"":1328}}, // [Juice Mobile]
-  {"hash":"1b02f5c5bfc0039d","prefixes":{"":1328}}, // [Juice Mobile]
-  {"hash":"ee644eb69f62cdec","prefixes":{"":1329}}, // [Bebe]
-  {"hash":"8fb13ead8b0754fb","prefixes":{"":1330}}, // [Augur]
-  {"hash":"cfbc4ef83efc3949","prefixes":{"*":1331}}, // [Seracast Digital LLC]
-  {"hash":"a8285782e9e5e7e8","prefixes":{"*":1331}}, // [Seracast Digital LLC]
-  {"hash":"3a9b5e5bcd74ba27","prefixes":{"":1332}}, // [AerServ LLC]
-  {"hash":"dd4e82ee18499196","prefixes":{"":1332}}, // [AerServ LLC]
-  {"hash":"2163ccdaf0c7ac04","prefixes":{"*":1321}}, // [Cinarra Systems Japan株式会社]
-  {"hash":"e16e6171a3e50ef3","prefixes":{"":1333}}, // [PT. Tokopedia]
-  {"hash":"74b1225f4470815b","prefixes":{"":1334}}, // [Terapeak, Inc.]
-  {"hash":"7eb7af632c622616","prefixes":{"*":1335}}, // [OpenStreetMap France]
-  {"hash":"63c3a3e6536f0b7f","prefixes":{"*":1336}}, // [Front Porch, Inc]
-  {"hash":"2c6aaec84cacd716","prefixes":{"*":1336}}, // [Front Porch, Inc]
-  {"hash":"6f469a516e0ea586","prefixes":{"":1337}}, // [Vertamedia]
-  {"hash":"d06485ea48298b7e","prefixes":{"":1338}}, // [Codewise (VoluumDSP)]
-  {"hash":"7a43b35e42bcef39","prefixes":{"":1339}}, // [Virool Inc.]
-  {"hash":"4ff7c90f1d23d419","prefixes":{"":1340}}, // [SpringServe LLC]
-  {"hash":"7f06352affc07566","prefixes":{"":1340}}, // [SpringServe LLC]
-  {"hash":"96ea998589a3f7ab","prefixes":{"":1340}}, // [SpringServe LLC]
-  {"hash":"32ec7c3af8d6ee95","prefixes":{"":1340}}, // [SpringServe LLC]
-  {"hash":"294e9804817557ed","prefixes":{"":1340}}, // [SpringServe LLC]
-  {"hash":"e9c681d4af45ad2c","prefixes":{"":1341}}, // [Intimate Merger]
-  {"hash":"68cc07724e870731","prefixes":{"":1341}}, // [Intimate Merger]
-  {"hash":"60f3c72e07bc4431","prefixes":{"":1342}}, // [Telecoming Connectivity S.A.]
-  {"hash":"22081b94e890803c","prefixes":{"":1343}}, // [Webssup]
-  {"hash":"00e22da76abf1e12","prefixes":{"":1343}}, // [Webssup]
-  {"hash":"498495a391901f22","prefixes":{"":1344}}, // [INCUBIQ Solutions Ltd]
-  {"hash":"606c712ed1507693","prefixes":{"":1344}}, // [INCUBIQ Solutions Ltd]
-  {"hash":"a9af6bbd9a022211","prefixes":{"*":1336}}, // [Front Porch, Inc]
-  {"hash":"5ad9370da8c17992","prefixes":{"":1345}}, // [ADSpend]
-  {"hash":"fdd6cbfd0c4ad857","prefixes":{"":1346}}, // [AdTradr Corporation]
-  {"hash":"81b9923f85553957","prefixes":{"":1346}}, // [AdTradr Corporation]
-  {"hash":"a145ad19f618929c","prefixes":{"":1346}}, // [AdTradr Corporation]
-  {"hash":"b1930e60745f4b68","prefixes":{"":1346}}, // [AdTradr Corporation]
-  {"hash":"57f97d99aaf44ad1","prefixes":{"":1346}}, // [AdTradr Corporation]
-  {"hash":"99143cae9fe8dcb7","prefixes":{"":1347}}, // [Quint Growth Inc.]
-  {"hash":"eb5cead7881dc3da","prefixes":{"":1348}}, // [ZAPR]
-  {"hash":"2fe0bb9349d1959b","prefixes":{"":1348}}, // [ZAPR]
-  {"hash":"b959bccbc132d322","prefixes":{"":20}}, // [On Device Research Ltd.]
-  {"hash":"8a8c554522b206ad","prefixes":{"":1349}}, // [1trn LLC]
-  {"hash":"45dfdbe509539a3b","prefixes":{"":1349}}, // [1trn LLC]
-  {"hash":"6265ceee0906cac8","prefixes":{"":1350}}, // [Matiro]
-  {"hash":"279177f20ce276af","prefixes":{"":1350}}, // [Matiro]
-  {"hash":"b90e8e5f5f114049","prefixes":{"":1350}}, // [Matiro]
-  {"hash":"68519953a094dc0c","prefixes":{"":1350}}, // [Matiro]
-  {"hash":"2c9356fdc6a3d512","prefixes":{"":1350}}, // [Matiro]
-  {"hash":"486312e316f3d301","prefixes":{"":1350}}, // [Matiro]
-  {"hash":"0dea0840245a2dd2","prefixes":{"*":1351}}, // [Inspired Mobile Ltd.]
-  {"hash":"e1e444909b156b50","prefixes":{"*":1351}}, // [Inspired Mobile Ltd.]
-  {"hash":"ba50b6623ecf06b7","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"bb2433b4d9ceaf93","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"752e7bd32ca03e2b","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"fecd6600c1d54571","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"e2f5a8707a39a63f","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"6e7cd3eb7639d09a","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"e0afc2f779238a59","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"51c4028642a5ca4c","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"1640e1eeb06df964","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"6c8c2f363cf647b5","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"d9f31e1a90e8fb75","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"845fb9c6387bef97","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"0459341df70cc072","prefixes":{"":1352}}, // [Selectmedia International LTD.]
-  {"hash":"be68419b316ae4c5","prefixes":{"":1353}}, // [Internet Billboard, a. s]
-  {"hash":"ba9be76fe6cba556","prefixes":{"":1353}}, // [Internet Billboard, a. s]
-  {"hash":"ec3aa5f11c754de6","prefixes":{"":1353}}, // [Internet Billboard, a. s]
-  {"hash":"5023d333c14740b4","prefixes":{"":1353}}, // [Internet Billboard, a. s]
-  {"hash":"eab4b496bc09743b","prefixes":{"":1354}}, // [Volvelle]
-  {"hash":"2afdaf8d1bad3cb9","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"c2367faa0f667908","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"ed58e98b46833296","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"e0249363e0c7a5fa","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"3f6dfa5fad816543","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"0daca079a0ddd2c5","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"eb2192ea666d6dfe","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"6a1269cf9dab66ee","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"39079f1183b1a260","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"9455a8e3fa7e9a01","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"bebc1faa9d73b7b0","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"c5069619b84c740e","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"8effee3cd53dcfe8","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"8251bfe6accaab04","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"f1019f4619cbfe25","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"825efa7e6eea91b6","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"cdeee95936c4dbc6","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"812ac20217e10e22","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"a20318efcc942b0c","prefixes":{"":1355}}, // [StreamRail Ltd.]
-  {"hash":"7ba3379a648cbc77","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"faca10de01f9747f","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"c4bada2290c2b41f","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"7e8290508a81ecfd","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"415fbdfa7cf95914","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"97322010e9179343","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"07549a667fcd0003","prefixes":{"":1356}}, // [E-Contenta]
-  {"hash":"f5359f09115e5a08","prefixes":{"":1357}}, // [Bath and Body Works]
-  {"hash":"93931937deeacde2","prefixes":{"":1160}}, // [KuaiziTech]
-  {"hash":"885efbcb155efd68","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"8515f5e803de693b","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"7990fea9b4cdbdf9","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"a6632e804a3dc853","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"ae4745b0fd104fbb","prefixes":{"":691}}, // [Aniview LTD.]
-  {"hash":"956dc47eeadd36f7","prefixes":{"":1358}}, // [WooTag Pte Ltd]
-  {"hash":"091b478316a2c133","prefixes":{"":1358}}, // [WooTag Pte Ltd]
-  {"hash":"dc8fa04b592b8307","prefixes":{"":1358}}, // [WooTag Pte Ltd]
-  {"hash":"fe0e326ac7dc8d7c","prefixes":{"":1358}}, // [WooTag Pte Ltd]
-  {"hash":"410a107d660ab1cd","prefixes":{"":1359}}, // [Cint AB]
-  {"hash":"b294fa0e55fcd2f4","prefixes":{"":1359}}, // [Cint AB]
-  {"hash":"5519fa5da5e57ad1","prefixes":{"":1360}}, // [Stein Mart]
-  {"hash":"7277d1fc5bc3c416","prefixes":{"":1361}}, // [Sift Media, Inc.]
-  {"hash":"4b89510469e15939","prefixes":{"":1362}}, // [StartApp Inc.]
-  {"hash":"d3b5600174198250","prefixes":{"":1362}}, // [StartApp Inc.]
-  {"hash":"5597070a34018ed8","prefixes":{"":1362}}, // [StartApp Inc.]
-  {"hash":"17f290970639d124","prefixes":{"":1363}}, // [Pxene - DSP]
-  {"hash":"263ee2028bc08b39","prefixes":{"":1363}}, // [Pxene - DSP]
-  {"hash":"da0f3a897355dd67","prefixes":{"":1363}}, // [Pxene - DSP]
-  {"hash":"9ca84ba93389421b","prefixes":{"":1363}}, // [Pxene - DSP]
-  {"hash":"4d5f045a10baa819","prefixes":{"":1364}}, // [Integral Marketing]
-  {"hash":"50bc395b6101613b","prefixes":{"":1364}}, // [Integral Marketing]
-  {"hash":"3affd533937e3000","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"971d313a32301476","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"c5351f32e51be2fe","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"4d91e6834270bed5","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"5d662bce285c4f62","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"acf96648fc83494b","prefixes":{"":48}}, // [Enzymic Consultancy]
-  {"hash":"ea62a03194f9fd95","prefixes":{"":1365}}, // [Expedia, Inc.]
-  {"hash":"d3ff1633dded1329","prefixes":{"":1366}}, // [DeepIntent, Inc]
-  {"hash":"2b5d6ad4574423ab","prefixes":{"":1366}}, // [DeepIntent, Inc]
-  {"hash":"dd8c5b641bb2871c","prefixes":{"":1366}}, // [DeepIntent, Inc]
-  {"hash":"4ba3d981f5073f12","prefixes":{"":1366}}, // [DeepIntent, Inc]
-  {"hash":"92f845f3cbfc83ca","prefixes":{"":181}}, // [Rakuten Attribution]
-  {"hash":"ff93f30e29dd79ce","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"1219256c57d362c2","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"588a30ada75d3716","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"f99b3a1ad217ec24","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"cffe29c52b1b73c5","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"f03d942c23c65a90","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"272d4c035a088de6","prefixes":{"":1367}}, // [OmniVirt]
-  {"hash":"724568d0c3fc08a4","prefixes":{"":1368}}, // ["Index20" LLC]
-  {"hash":"be108323d132726d","prefixes":{"":1369}}, // [Conversion Logic, Inc.]
-  {"hash":"9fc3b91614502933","prefixes":{"":1370}}, // [Collegehumor]
-  {"hash":"bb96895ad0b3fb46","prefixes":{"":1370}}, // [Collegehumor]
-  {"hash":"830074aed1a53d22","prefixes":{"":1370}}, // [Collegehumor]
-  {"hash":"db32b2c0136553c9","prefixes":{"":775}}, // [Netflix, Inc.]
-  {"hash":"47df197461b802d5","prefixes":{"":775}}, // [Netflix, Inc.]
-  {"hash":"acbf0ad8badc6915","prefixes":{"":775}}, // [Netflix, Inc.]
-  {"hash":"c0b6c8d5b1736dc3","prefixes":{"":775}}, // [Netflix, Inc.]
-  {"hash":"05dd2a6c687d34c0","prefixes":{"":1371}}, // [Silence Media Limited]
-  {"hash":"cea7d6ed17648fbf","prefixes":{"":1371}}, // [Silence Media Limited]
-  {"hash":"ad7149f316532231","prefixes":{"":1372}}, // [Zuuvi Aps]
-  {"hash":"693751faddbb5801","prefixes":{"":1372}}, // [Zuuvi Aps]
-  {"hash":"8da87b729d579d09","prefixes":{"":1372}}, // [Zuuvi Aps]
-  {"hash":"ab5cc3951d346c77","prefixes":{"":1372}}, // [Zuuvi Aps]
-  {"hash":"f41a4b1ac6a3bfb2","prefixes":{"":1373}}, // [SoftBank Corp.]
-  {"hash":"1d0977195dc18825","prefixes":{"":1374}}, // [ConnectOM, Inc.]
-  {"hash":"912365bfc81f780a","prefixes":{"":1374}}, // [ConnectOM, Inc.]
-  {"hash":"7434a888611cfaf2","prefixes":{"":1374}}, // [ConnectOM, Inc.]
-  {"hash":"1d73404a4d6b3cda","prefixes":{"":49}}, // [Fluct Inc.]
-  {"hash":"938fa93131d63045","prefixes":{"":49}}, // [Fluct Inc.]
-  {"hash":"67f35499d1bf5216","prefixes":{"":1375}}, // [Skillup Video Technologies Corporation]
-  {"hash":"c8e2c0c42c388ceb","prefixes":{"":1375}}, // [Skillup Video Technologies Corporation]
-  {"hash":"0800074e9a8aa9e0","prefixes":{"":1375}}, // [Skillup Video Technologies Corporation]
-  {"hash":"f6853fba1d5c8366","prefixes":{"":1376}}, // [Adara Impact Analytics]
-  {"hash":"7d5aa0875b5b03ee","prefixes":{"":1376}}, // [Adara Impact Analytics]
-  {"hash":"e1a55205d635d049","prefixes":{"":1376}}, // [Adara Impact Analytics]
-  {"hash":"b5ea51bb0aec174c","prefixes":{"":1376}}, // [Adara Impact Analytics]
-  {"hash":"e4140b78afda4fb4","prefixes":{"":1376}}, // [Adara Impact Analytics]
-  {"hash":"a4c74032025e0589","prefixes":{"":1377}}, // [TabMo SAS]
-  {"hash":"d9638d78485cff41","prefixes":{"":1377}}, // [TabMo SAS]
-  {"hash":"6ea3e003ed64d138","prefixes":{"":58}}, // [Sixt Leasing SE]
-  {"hash":"22ae0beb131c4b8c","prefixes":{"":1378}}, // [Casale Media]
-  {"hash":"29d1aaca6b9e6edd","prefixes":{"":1378}}, // [Casale Media]
-  {"hash":"7d1380d196e0f347","prefixes":{"":1379}}, // [StickyADStv]
-  {"hash":"147ac7b767355a32","prefixes":{"":1380}}, // [Teads Technology SAS]
-  {"hash":"4b60266ba860a4c5","prefixes":{"":1381}}, // [Anomaly Communications, LLC]
-  {"hash":"296893a9570ca935","prefixes":{"*":1382}}, // [ClickTicker, LTD]
-  {"hash":"094df71f27ebd6f1","prefixes":{"":1383}}, // [Tremour]
-  {"hash":"a1119d262b86de34","prefixes":{"":1384}}, // [Roket Media LTD]
-  {"hash":"b1ed20b79d8a43cb","prefixes":{"":152}}, // [e-Planning]
-  {"hash":"5bd05c801bb32096","prefixes":{"":1385}}, // [Video Jam (MauDau LTD)]
-  {"hash":"dacf613410c17f5e","prefixes":{"":1385}}, // [Video Jam (MauDau LTD)]
-  {"hash":"561f104ba38d6e64","prefixes":{"":1385}}, // [Video Jam (MauDau LTD)]
-  {"hash":"a43509d6a08d1777","prefixes":{"":1386}}, // [MINIMOB (CY) LTD]
-  {"hash":"b66514ac6530a3fd","prefixes":{"":1387}}, // [Snitcher B.V.]
-  {"hash":"79b3660bde132ba1","prefixes":{"":1387}}, // [Snitcher B.V.]
-  {"hash":"aaf7781b800509ba","prefixes":{"":1387}}, // [Snitcher B.V.]
-  {"hash":"8fec6c672f5b204a","prefixes":{"":1387}}, // [Snitcher B.V.]
-  {"hash":"825e7df4dfb9bae0","prefixes":{"":1387}}, // [Snitcher B.V.]
-  {"hash":"379899626d07c3b5","prefixes":{"":1388}}, // [Analights]
-  {"hash":"664ce6265f73ec6a","prefixes":{"":1388}}, // [Analights]
-  {"hash":"ab33f6650feb44c2","prefixes":{"":1388}}, // [Analights]
-  {"hash":"557404c787c545cb","prefixes":{"":1388}}, // [Analights]
-  {"hash":"0c881f692e8ec0de","prefixes":{"":1388}}, // [Analights]
-  {"hash":"36c7264c1d06cc29","prefixes":{"":1388}}, // [Analights]
-  {"hash":"2f7b75786675821b","prefixes":{"":1388}}, // [Analights]
-  {"hash":"714fd218f12fce7a","prefixes":{"":1388}}, // [Analights]
-  {"hash":"d140a5f747a666f1","prefixes":{"":1388}}, // [Analights]
-  {"hash":"cbcfd9d592f2d19d","prefixes":{"":1388}}, // [Analights]
-  {"hash":"a214f6ac537cafa2","prefixes":{"":1389}}, // [Romir Panel Ltd.]
-  {"hash":"84fe21a8c3ba3818","prefixes":{"":1390}}, // [Dievision]
-  {"hash":"c709bff0d2284ecc","prefixes":{"":1391}}, // [Ignite Technologies]
-  {"hash":"3510f10ff5914868","prefixes":{"*":1392}}, // [Navegg]
-  {"hash":"ea594377060cafc6","prefixes":{"":1393}}, // [Adalyser]
-  {"hash":"631a68a191554bae","prefixes":{"":1393}}, // [Adalyser]
-  {"hash":"8d9638d9355607ba","prefixes":{"":1393}}, // [Adalyser]
-  {"hash":"d6e288fc5cf14c83","prefixes":{"":1393}}, // [Adalyser]
-  {"hash":"90ec5cb29381e1ca","prefixes":{"":1393}}, // [Adalyser]
-  {"hash":"3debdfa22ee00230","prefixes":{"":1393}}, // [Adalyser]
-  {"hash":"45852dff86c0a7e0","prefixes":{"":1394}}, // [Nordic Factory International Inc.]
-  {"hash":"063e04585364c0e5","prefixes":{"":719}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"aa4bfba1bb15cb76","prefixes":{"":719}}, // [E-Plus Mobilfunk GmbH & Co. KG]
-  {"hash":"3f43b05864c28c77","prefixes":{"":1395}}, // [Addition Plus Ltd]
-  {"hash":"9e1057ca77b6610c","prefixes":{"":1395}}, // [Addition Plus Ltd]
-  {"hash":"a6278ebdf3ca7bce","prefixes":{"":1396}}, // [Karmatech Mediaworks Pvt Ltd]
-  {"hash":"954044969f047c6c","prefixes":{"":1396}}, // [Karmatech Mediaworks Pvt Ltd]
-  {"hash":"ca32fcf3a3101ca0","prefixes":{"":1397}}, // [Mediatropy Pte Ltd]
-  {"hash":"54a24d41044c0730","prefixes":{"":26}}, // [FSN ASIA PRIVATE LIMITED]
-  {"hash":"b3302c4e4fc23cb8","prefixes":{"":856}}, // [Adman Interactive SL]
-  {"hash":"328eed54ff330e78","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"98ed7d7c1ae050b7","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"226e8c98a3e2e091","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"9e777471181caa70","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"9df613858a859407","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"37af06459214925d","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"0fdc04aa3cd4e402","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"f33f14a479b17a13","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"535ad6947981986b","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"0db16a6e891b1ff5","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"11b3c502d4eb1fa3","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"001bd6970eef2bbe","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"93505db1f9bf4a47","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"a1c9ac37054fc828","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"f4f375e269f34a60","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"e61b3b137beecfbc","prefixes":{"":1398}}, // [Wayve Limited]
-  {"hash":"07bf22fe56be8d20","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"619e27568b55894c","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"374b60567f3c7f8b","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"af11cb377f269b3b","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"6bd694da478fa87b","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"75c4aedcbc945c91","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"71e8a51762fe81b6","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"5412f8017660207b","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"ba29363e3e139066","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"05de1e7e9f3271c3","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"5d73b4b9b8705846","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"711d9c4ce084aa7d","prefixes":{"*":1399}}, // [Kreditech Holding SSL GmbH]
-  {"hash":"1ed6fde4c65ef6f7","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"4a6b1490dc059d0b","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"cab81dbe20c0957f","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"af1f3ce39e3b4862","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"19e97b139ae15342","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"fb46fee1ceef4719","prefixes":{"*":269}}, // [DePauli AG]
-  {"hash":"798bda76da15abeb","prefixes":{"*":21}}, // [SuperVista AG]
-  {"hash":"38bf7a598ad0c498","prefixes":{"*":21}}, // [SuperVista AG]
-  {"hash":"48651b09d312b814","prefixes":{"*":21}}, // [SuperVista AG]
-  {"hash":"bb2482d6022a94ba","prefixes":{"*":21}}, // [SuperVista AG]
-  {"hash":"d58f8af9ff4e691e","prefixes":{"":1400}}, // [Yengo]
-  {"hash":"8e9bee1bb54d54ee","prefixes":{"":1400}}, // [Yengo]
-  {"hash":"06689ed650e2b8c3","prefixes":{"":1401}}, // [DANtrack]
-  {"hash":"96c97b30a03579ac","prefixes":{"":1401}}, // [DANtrack]
-  {"hash":"407face2b2c27397","prefixes":{"":1402}}, // [Integral Markt- und Meinungsforschungsges.m.b.H.]
-  {"hash":"184f80ef53a0f178","prefixes":{"":1402}}, // [Integral Markt- und Meinungsforschungsges.m.b.H.]
-  {"hash":"076a460590b496bf","prefixes":{"":1403}}, // [Millemedia GmbH]
-  {"hash":"9febeed138f5f2ce","prefixes":{"":1404}}, // [Hiro-Media]
-  {"hash":"dd35fc0a5f5fa07b","prefixes":{"":1404}}, // [Hiro-Media]
-  {"hash":"b22687a0d4bd341f","prefixes":{"":1404}}, // [Hiro-Media]
-  {"hash":"1625640192348305","prefixes":{"*":1405}}, // [Simplaex Gmbh]
-  {"hash":"444356542461e7d2","prefixes":{"":1405}}, // [Simplaex Gmbh]
-  {"hash":"b9edac442e488ddf","prefixes":{"":1405}}, // [Simplaex Gmbh]
-  {"hash":"afed9502218fc1cd","prefixes":{"":1406}}, // [Telekom Deutschland GmbH]
-  {"hash":"286d994374ce8a57","prefixes":{"":1407}}, // [Infernotions Technologies Limited]
-  {"hash":"385225c96e123b3f","prefixes":{"":1408}}, // [Goldfish Media LLC]
-  {"hash":"19c11b9ad47802f9","prefixes":{"":1365}}, // [Expedia, Inc.]
-  {"hash":"d710ea66b904cd82","prefixes":{"":1409}}, // [Smartology Limited]
-  {"hash":"24bbec831a84a114","prefixes":{"":1409}}, // [Smartology Limited]
-  {"hash":"9c3279986e25304c","prefixes":{"":1409}}, // [Smartology Limited]
-  {"hash":"8ce94299572dc9b8","prefixes":{"":1409}}, // [Smartology Limited]
-  {"hash":"e51f784e66ceb1cb","prefixes":{"":1410}}, // [GroupM]
-  {"hash":"72bd4ec98dea633b","prefixes":{"":1410}}, // [GroupM]
-  {"hash":"0836c753510a4fd6","prefixes":{"*":1411}}, // [Haystagg Inc.]
-  {"hash":"4a13b1d65c372006","prefixes":{"*":1411}}, // [Haystagg Inc.]
-  {"hash":"14ec018232a87385","prefixes":{"":1412}}, // [Digital Turbine Media, Inc]
-  {"hash":"fdabfb7535e313a7","prefixes":{"":1412}}, // [Digital Turbine Media, Inc]
-  {"hash":"cddef42a99b1f0e2","prefixes":{"":1413}}, // [MDSP INC]
-  {"hash":"1bcc84762c0f2df8","prefixes":{"":1414}}, // [Quadas (YiDong Data Inc.)]
-  {"hash":"6c46a69428837566","prefixes":{"":1415}}, // [Recruit Career Co., Ltd.]
-  {"hash":"17319e35b3b89b68","prefixes":{"":1416}}, // [R2Net Inc.]
-  {"hash":"0825a9da5dd17373","prefixes":{"":1416}}, // [R2Net Inc.]
-  {"hash":"aaa00ce722ea0d35","prefixes":{"":1416}}, // [R2Net Inc.]
-  {"hash":"40b683cc8c061f6f","prefixes":{"":1417}}, // [Madberry OY]
-  {"hash":"ea76804ad8af9b5c","prefixes":{"":1417}}, // [Madberry OY]
-  {"hash":"985cce26aeab90d8","prefixes":{"":1417}}, // [Madberry OY]
-  {"hash":"d67d98cbb9553a81","prefixes":{"":1417}}, // [Madberry OY]
-  {"hash":"ee1c2ae2ffdaa754","prefixes":{"":1417}}, // [Madberry OY]
-  {"hash":"8c162379b63896e6","prefixes":{"":1418}}, // [QVC]
-  {"hash":"4c23d567b98e413f","prefixes":{"*":1419}}, // [Micro Cube Digital Limited]
-  {"hash":"9e74e9e50b7e6116","prefixes":{"":1420}}, // [egg.de GmbH]
-  {"hash":"8242efdacea6ca14","prefixes":{"":1421}}, // [Headway Mexico]
-  {"hash":"82b90117a5beb869","prefixes":{"":1422}}, // [RTBiQ Inc.]
-  {"hash":"7d4bc30e9d495d00","prefixes":{"":1194}}, // [Fluidads]
-  {"hash":"44305a81af328854","prefixes":{"":1194}}, // [Fluidads]
-  {"hash":"f5d44df23b5b7f0a","prefixes":{"":1423}}, // [SCIBIDS TECHNOLOGY S.A.S.]
-  {"hash":"e86f56889ef213b9","prefixes":{"*":1424}}, // [Kyocera Communication Systems]
-  {"hash":"e4f3abfdd94fbb95","prefixes":{"":1425}}, // [Cortex Media Group]
-  {"hash":"7525243b1d665de2","prefixes":{"":1426}}, // [appTV]
-  {"hash":"f27453a19aa2370e","prefixes":{"":1426}}, // [appTV]
-  {"hash":"8156979d25af9817","prefixes":{"":1427}}, // [ProgSol, Programmatic Solution, s.r.o.]
-  {"hash":"888e465d14dbfeb5","prefixes":{"":1427}}, // [ProgSol, Programmatic Solution, s.r.o.]
-  {"hash":"6bcdb8e4cf28b730","prefixes":{"":1427}}, // [ProgSol, Programmatic Solution, s.r.o.]
-  {"hash":"cc229228113699d8","prefixes":{"":1428}}, // [Rezonence]
-  {"hash":"fd7695df1dfe9f20","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"fbee76565472bc95","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"e53efe28417732fd","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"4f76dc8807a1b25a","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"b7cd9e7666d175e1","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"ba124e354a70dcb2","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"8c9e63d24d4fbe6b","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"ea6157fcb7c5c718","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"6063abef39fb89be","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"8a3b3647f6fae243","prefixes":{"":1429}}, // [LKQD Platform]
-  {"hash":"25b652ead7abb3b0","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"ff03eb40846eaa12","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"649ada5375fff936","prefixes":{"":1059}}, // [Bidtellect]
-  {"hash":"79b86a55d8f149ef","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"a6e4ebed7d417fec","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"e7a27d73288188b6","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"24028ce468194c75","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"d7f89ed8a6431a69","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"079f75aa60b736a9","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"55ab38530ebcb2e7","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"244a99d8deb4343c","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"02afdba2d61c6d76","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"50fcadafe2e2734b","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"0a5d998860b7968b","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"ff1ef9a23c2bdf51","prefixes":{"":1430}}, // [target value GmbH]
-  {"hash":"b7be02479c9268a9","prefixes":{"":1431}}, // [Firecracker]
-  {"hash":"2841b43a0e0ddb37","prefixes":{"":1431}}, // [Firecracker]
-  {"hash":"ea77ccf69493306c","prefixes":{"":1431}}, // [Firecracker]
-  {"hash":"786060a6ba793b32","prefixes":{"":1431}}, // [Firecracker]
-  {"hash":"af58243a5817c930","prefixes":{"":1431}}, // [Firecracker]
-  {"hash":"b90ffee242259e26","prefixes":{"":1432}}, // [MADGIC]
-  {"hash":"037e84a783130203","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"724c85c96cc72a57","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"df235ed188c82f5b","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"df21bf354a2570e1","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"52a9b224dd3e1b02","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"ef749fa483d558a9","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"a6b20df6c2ce3063","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"7e7e73dfe402883c","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"1cafe416eb8d746c","prefixes":{"":1433}}, // [Digiseg]
-  {"hash":"45c0ef64ecfb6525","prefixes":{"":1434}}, // [Bulbit Inc.]
-  {"hash":"d3710c2900e90f84","prefixes":{"":1434}}, // [Bulbit Inc.]
-  {"hash":"fed8a97b9e855887","prefixes":{"":1435}}, // [Lost My Name]
-  {"hash":"5c18434d5d721456","prefixes":{"":1436}}, // [People Media]
-  {"hash":"fd4a671d34b4c76c","prefixes":{"":1436}}, // [People Media]
-  {"hash":"181b385a8ea5a687","prefixes":{"":1437}}, // [Platform.io]
-  {"hash":"00393673ca5c1d8a","prefixes":{"":1437}}, // [Platform.io]
-  {"hash":"6479d1c5a241da2f","prefixes":{"":1438}}, // [Bidspeaker]
-  {"hash":"f30e44d5503f39c4","prefixes":{"":1439}}, // [YouGov PLC]
-  {"hash":"4f07a6c89151a2eb","prefixes":{"":1440}}, // [SAP SE]
-  {"hash":"519e46f12c141c48","prefixes":{"":1440}}, // [SAP SE]
-  {"hash":"413cdfaa8215b8f5","prefixes":{"":1440}}, // [SAP SE]
-  {"hash":"dd8e150b503eb12f","prefixes":{"":1441}}, // [Adchex]
-  {"hash":"58e19248782ce688","prefixes":{"":1442}}, // [Smart Bid Limited]
-  {"hash":"8ccc1dd45e305817","prefixes":{"":1443}}, // [UAd Exchange]
-  {"hash":"9543cb4330fa1d6e","prefixes":{"":1444}}, // [UAd Exchange - IBV]
-  {"hash":"fc1a7604d6ced7c3","prefixes":{"":1445}}, // [esc mediagroup GmbH]
-  {"hash":"90c354743de0b811","prefixes":{"":1446}}, // [defacto smart reach GmbH]
-  {"hash":"0d8f41278d702251","prefixes":{"":1447}}, // [Research and Analysis of Media in Sweden AB]
-  {"hash":"607c4919b3c8d5cd","prefixes":{"":1447}}, // [Research and Analysis of Media in Sweden AB]
-  {"hash":"d0d7647dc2ea9dd9","prefixes":{"":1448}}, // [OnAudience.com]
-  {"hash":"3c0c99d90a16804f","prefixes":{"":1449}}, // [OneTag]
-  {"hash":"a50e8a4129f160c8","prefixes":{"":1449}}, // [OneTag]
-  {"hash":"62105b8204658950","prefixes":{"":1449}}, // [OneTag]
-  {"hash":"8069afc9a94b92b9","prefixes":{"*":1349}}, // [1trn LLC]
-  {"hash":"c9cc947471099a0e","prefixes":{"":59}}, // [Air Berlin]
-  {"hash":"516352d734faa684","prefixes":{"":1450}}, // [Fiverr International Ltd.]
-  {"hash":"562a3da1a81ae4ec","prefixes":{"":1450}}, // [Fiverr International Ltd.]
-  {"hash":"1ba262fef7c9b94b","prefixes":{"":1451}}, // [Adikteev]
-  {"hash":"cd63e73725fa2b8d","prefixes":{"":1451}}, // [Adikteev]
-  {"hash":"f24819f2edd93c69","prefixes":{"":1451}}, // [Adikteev]
-  {"hash":"e3b1538bced5ec72","prefixes":{"":1451}}, // [Adikteev]
-  {"hash":"341df4e708fbbc07","prefixes":{"":1452}}, // [CenterPoint Media]
-  {"hash":"1f984187723f0399","prefixes":{"":1452}}, // [CenterPoint Media]
-  {"hash":"6ed35b33de5147be","prefixes":{"":1452}}, // [CenterPoint Media]
-  {"hash":"d3f04891cabd56f8","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"8429b5e7c7905de9","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"eadb7778a29b9617","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"15595532c38662ea","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"ce365566d66a72ee","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"60ef24e820a6a881","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"176be2434ca2f68b","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"3f72f2b4ec7f816e","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"bcc519027914bd79","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"86628b5f01332c66","prefixes":{"":1453}}, // [Digital Trace]
-  {"hash":"1c34c62a587e6c1e","prefixes":{"":1454}}, // [Pure Cobalt]
-  {"hash":"a30f9c646772cf0f","prefixes":{"":60}}, // [Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper]
-  {"hash":"b23d960b2ea25b51","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"030115e352ac8e99","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"77da2d98a4da970f","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"aa0555e19cf5d6cc","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"badc121e99935aa5","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"115df78aa77ac9c4","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"04713a193ed96cc0","prefixes":{"s":1455}}, // [Cedato]
-  {"hash":"fd6fd1f29de71285","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"c5de6239a6efe818","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"4c0be33a1c14428d","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"09eaafed5beae0e1","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"ff987bad618809e7","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"2b50033d06870385","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"8b399204d27d07c0","prefixes":{"s":1455}}, // [Cedato]
-  {"hash":"5f78d380fa9514b1","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"c4912c3d8f04b948","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"361fa6df6bb3216e","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"b18ab9dfb513f02b","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"de511a44653105ea","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"f990d873e1622766","prefixes":{"":1455}}, // [Cedato]
-  {"hash":"f53618fe52956dbf","prefixes":{"s":1455}}, // [Cedato]
-  {"hash":"96ed69252978cab9","prefixes":{"cdn":1455}}, // [Cedato]
-  {"hash":"f38b31b7e204355c","prefixes":{"":943}}, // [Admetrics GmbH]
-  {"hash":"895a9c8a3b52c95f","prefixes":{"":943}}, // [Admetrics GmbH]
-  {"hash":"62ba002fe91498c3","prefixes":{"":943}}, // [Admetrics GmbH]
-  {"hash":"30fe524e700bd89f","prefixes":{"":943}}, // [Admetrics GmbH]
-  {"hash":"6ce86e7a47d6dfbc","prefixes":{"":1456}}, // [Jonsden Properties Limited]
-  {"hash":"8bed3db3f252b657","prefixes":{"":1457}}, // [Realytics]
-  {"hash":"c2dcbb4796436e89","prefixes":{"":1458}}, // [Twinpine]
-  {"hash":"97a8b5033c272f3c","prefixes":{"":1458}}, // [Twinpine]
-  {"hash":"3d39eae9e2370c3e","prefixes":{"":1459}}, // [Mopedo AB]
-  {"hash":"38a9bfae76c9b2f1","prefixes":{"*":1460}}, // [Netsales]
-  {"hash":"9b1148932500d0b5","prefixes":{"":1461}}, // [ViewersLogic LTD]
-  {"hash":"901b2f7c0272451b","prefixes":{"":1461}}, // [ViewersLogic LTD]
-  {"hash":"7d45cf386f5c3f27","prefixes":{"":1462}}, // [ADMAN]
-  {"hash":"e68e2f7630af032b","prefixes":{"":1462}}, // [ADMAN]
-  {"hash":"79dc640f62208944","prefixes":{"":1462}}, // [ADMAN]
-  {"hash":"4d6e312d6aba1117","prefixes":{"":1462}}, // [ADMAN]
-  {"hash":"29e85c5af35e3751","prefixes":{"":1462}}, // [ADMAN]
-  {"hash":"e5f2b6b92cc6daa3","prefixes":{"":1463}}, // [Hyper]
-  {"hash":"f867e04c6dde165d","prefixes":{"":1464}}, // [Hurra Communications]
-  {"hash":"8353a34ee35ff30c","prefixes":{"":1464}}, // [Hurra Communications]
-  {"hash":"cc7f69fa55a7518f","prefixes":{"":1465}}, // [Groundhog TW]
-  {"hash":"95ba2d10b1b0675c","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"e8f62a52edbdf4bd","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"321a7e08d4b4fd55","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"c6f272ed0a206999","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"bd34d2733467c1af","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"1b49f6113458dc63","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"58b83e3b3a97943e","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"814bcd9589533387","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"9465fc7c156593f4","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"7c1c219e78b2f270","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"9d376bb5982319b0","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"12ec9a0b2888a4a9","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"f3d7dfcb60972b0c","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"460cac48ec149c6d","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"2614d3ffa05e19a5","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"1f9b770c08378ced","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"054864ff1578657a","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"a5505306000e20f2","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"12cae8bbd22d8673","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"d7724f8a49b96fa6","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"3013078a26f31e2f","prefixes":{"":1466}}, // [ImediaMax]
-  {"hash":"80193dea6eb67372","prefixes":{"":1467}}, // [Flixbus]
-  {"hash":"02c439b9cc7e33b5","prefixes":{"":1468}}, // [AudienceTV]
-  {"hash":"fcb4adbb2bc559e7","prefixes":{"":1469}}, // [b34106183_test]
-  {"hash":"b08446a676a287b4","prefixes":{"":1469}}, // [b34106183_test]
-  {"hash":"12105a6cc17c32e7","prefixes":{"":1470}}, // [Netscore]
-  {"hash":"036d15c3ad4a0735","prefixes":{"":1470}}, // [Netscore]
-  {"hash":"c0c40e6f63813be1","prefixes":{"":1471}}, // [Chu Technology Limited]
-  {"hash":"4c434a52325c0b6e","prefixes":{"":1472}}, // [SmartyAds LLC]
-  {"hash":"825a99c46b61053a","prefixes":{"":1473}}, // [dbupdate1]
-  {"hash":"31ab5366866e8622","prefixes":{"":1473}}, // [dbupdate1]
-  {"hash":"32a21f3a47cb8ddc","prefixes":{"":128}}, // [ConvertMedia Ltd.]
-  {"hash":"44a7af6d373bd713","prefixes":{"":985}}, // [Lodeo]
-  {"hash":"36d8680483227de8","prefixes":{"":985}}, // [Lodeo]
-  {"hash":"9709c6b69d2e3e90","prefixes":{"":985}}, // [Lodeo]
-  {"hash":"5efefb78ec9b146f","prefixes":{"":1474}}, // [The Big Willow Inc.]
-  {"hash":"3e5b3c0010f7172f","prefixes":{"":1475}}, // [LiveIntent Inc]
-  {"hash":"07bf09263d039040","prefixes":{"":1476}}, // [OpenLedger ApS]
-  {"hash":"db879c71876741d0","prefixes":{"":1477}}, // [Whichit]
-  {"hash":"4a6caded0a4565d9","prefixes":{"":1477}}, // [Whichit]
-  {"hash":"05e0b02a9af28e89","prefixes":{"":1477}}, // [Whichit]
-  {"hash":"3aca7ac4649f240c","prefixes":{"":1477}}, // [Whichit]
-  {"hash":"81abe9587250fab1","prefixes":{"":1477}}, // [Whichit]
-  {"hash":"a3b6bac891e57819","prefixes":{"":1478}}, // [ParkDIA]
-  {"hash":"ddc3507bc6f79de4","prefixes":{"":1479}}, // [Atedra Inc.]
-  {"hash":"881c2002027de2ec","prefixes":{"":1479}}, // [Atedra Inc.]
-  {"hash":"28084881f4e51f6c","prefixes":{"":1480}}, // [Digital Forest OÜ]
-  {"hash":"d563745e0fed92f4","prefixes":{"":1481}}, // [Isobar Werbeagentur GmbH]
-  {"hash":"d6d13ce525771ba4","prefixes":{"":1482}}, // [Valuepotion Pte. Ltd.]
-  {"hash":"446766a73edf76a2","prefixes":{"":1483}}, // [Vuble Inc]
-  {"hash":"0753aa310a2a75aa","prefixes":{"":1484}}, // [adlocal.net]
-  {"hash":"772284fa4bfb8e5a","prefixes":{"":1484}}, // [adlocal.net]
-  {"hash":"0dd444b76d1727ab","prefixes":{"":1484}}, // [adlocal.net]
-  {"hash":"1db1fc299e2dc73a","prefixes":{"":1484}}, // [adlocal.net]
-  {"hash":"169447ab5f0b2b32","prefixes":{"":1485}}, // [Freckle IoT]
-  {"hash":"143b45f2e52d871c","prefixes":{"":1486}}, // [Personalization LLC]
-  {"hash":"bdc55693a2c62858","prefixes":{"":1487}}, // [ThoughtLeadr Inc.]
-  {"hash":"e69058fe073a8d07","prefixes":{"":1487}}, // [ThoughtLeadr Inc.]
-  {"hash":"ded94145085d34ed","prefixes":{"":1487}}, // [ThoughtLeadr Inc.]
-  {"hash":"ef66f2e1bb6a3605","prefixes":{"":1487}}, // [ThoughtLeadr Inc.]
-  {"hash":"5f62ecd0eec6b82a","prefixes":{"":1487}}, // [ThoughtLeadr Inc.]
-  {"hash":"45281cea83398309","prefixes":{"":1488,"web":1488,"app":1488,"cdn":1488,"api":1488,"p":1488,"mobpages":1488}}, // [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC]
-  {"hash":"7ea0c7c8484fb7b4","prefixes":{"cdn":1488}}, // [Noqoush Mobile Media Group FZ-LLC]
-  {"hash":"6839ebcbc8dce175","prefixes":{"":1488,"p":1488}}, // [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC]
-  {"hash":"c338016e1aa2a5f7","prefixes":{"":1489}}, // [G-Core Labs]
-  {"hash":"3bb879b5ab17cbeb","prefixes":{"":1490}}, // [Haensel AMS GmbH]
-  {"hash":"26627407df51f73d","prefixes":{"t":1490,"d":1490,"s":1490}}, // [Haensel AMS GmbH] [Haensel AMS GmbH] [Haensel AMS GmbH]
-  {"hash":"44e07e9341e20fd0","prefixes":{"":1491}}, // [LemonPI]
-  {"hash":"71d7abda3a6093b3","prefixes":{"":1491}}, // [LemonPI]
-  {"hash":"f57717e6df039cd1","prefixes":{"":1491}}, // [LemonPI]
-  {"hash":"0ae0087cfa7b79c3","prefixes":{"":1491}}, // [LemonPI]
-  {"hash":"59afc0d091a22f58","prefixes":{"":1492}}, // [4Info, Inc.]
-  {"hash":"fd299e0138ad90c1","prefixes":{"":1492}}, // [4Info, Inc.]
-  {"hash":"1e408d2e9033a6e2","prefixes":{"":1492}} // [4Info, Inc.]
+  {"hash":"20d393bb0e5c4de5","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"583365b5f9d44cae","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"dcde9b6a7ed731d0","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"0b618d2d6d12ff65","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"5ca7dfe6f0741d1b","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"f10aac9be30b9153","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"a29e3fb3581debcc","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"586a404a027dd51d","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"b772cd4d229b926f","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"5f153f573d601ed5","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"d08d00723aa41a8b","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"154c00442038842c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"bb5191c2744e5157","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"24f8ee8d41010340","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"dde97a25d741083b","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"c40e51f0d4308aef","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"dafae404fe4bf9e0","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"2965d60c41f24692","prefixes":{"*":{"product":2}}}, // [AdGenie]
+  {"hash":"947df9bf1ccc5af0","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"5874ab2040fd92e5","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"12c9a3fc47eec655","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"ff950154b65538b5","prefixes":{"":{"product":5}}}, // [Conversant Ad Server]
+  {"hash":"cca88c18c3a955c3","prefixes":{"*":{"product":6}}}, // [Napster Luxemburg SARL]
+  {"hash":"cf583a4f1b85a63d","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"b1f24fb9f4e82bc4","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"7ed3ef3bd9b7964c","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"802185637db97f57","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"69ac52e6452dcdcc","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"99d6e276a9f3dce4","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"20cea422f633f132","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"abac0e92b7c09189","prefixes":{"":{"product":12}}}, // [Madeleine Mode GmbH]
+  {"hash":"ab6d5bcfcb13c98c","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"17c760570121cb8e","prefixes":{"":{"product":14}}}, // [Telefonica UK / O2 UK]
+  {"hash":"cca991b6ab7e6463","prefixes":{"":{"product":15}}}, // [Tamome]
+  {"hash":"b24aab8ad8822e3b","prefixes":{"":{"product":15}}}, // [Tamome]
+  {"hash":"e068190951dbb5ef","prefixes":{"":{"product":15}}}, // [Tamome]
+  {"hash":"c5a5fd495c44b8e2","prefixes":{"":{"product":15}}}, // [Tamome]
+  {"hash":"95305154969e81b9","prefixes":{"":{"product":15}}}, // [Tamome]
+  {"hash":"f40a7549c998fd96","prefixes":{"":{"product":16}}}, // [TUI UK Limited]
+  {"hash":"96eeaa2c9afb8955","prefixes":{"":{"product":16}}}, // [TUI UK Limited]
+  {"hash":"bfeca1a08eac1f5e","prefixes":{"*":{"product":17}}}, // [iJento]
+  {"hash":"cfbb894fdba5489a","prefixes":{"":{"product":18}}}, // [McCann Erikson]
+  {"hash":"4ce21296b7adb20d","prefixes":{"":{"product":19}}}, // [Tribes Research Limited]
+  {"hash":"72b12a834f93bbd1","prefixes":{"":{"product":20}}}, // [On Device Research Ltd.]
+  {"hash":"5a885783941e6540","prefixes":{"*":{"product":21}}}, // [SuperVista AG]
+  {"hash":"382734d54ddf7100","prefixes":{"":{"product":22}}}, // [National Lottery]
+  {"hash":"397eccbf74cd0328","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"bf0f9d6566d29693","prefixes":{"*":{"product":0}}}, // [1&1 Internet AG]
+  {"hash":"8fd259996da5f3d8","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"56837fe2597a4f9e","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"fb4ddfafadb387cf","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"07a11d9d007c60f8","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"9f36fc0bb2911046","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"57c7af60819b3f3e","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"c3363b1ccf0e2ab6","prefixes":{"":{"product":24}}}, // [Interworks Media, Inc.]
+  {"hash":"9d16bd99e929eccd","prefixes":{"":{"product":24}}}, // [Interworks Media, Inc.]
+  {"hash":"211d3b9ea9bf8f2e","prefixes":{"":{"product":25}}}, // [Action Exchange, Inc.]
+  {"hash":"414adfe007d3587f","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"4486e584990f9603","prefixes":{"":{"product":26}}}, // [FSN ASIA PRIVATE LIMITED]
+  {"hash":"8cfb66b1b7bbe43b","prefixes":{"":{"product":27}}}, // [iPromote]
+  {"hash":"fba2a0cd626a5289","prefixes":{"":{"product":27}}}, // [iPromote]
+  {"hash":"113620ff3bb3ea60","prefixes":{"":{"product":27}}}, // [iPromote]
+  {"hash":"b5f6b4570a07977c","prefixes":{"*":{"product":28}}}, // [33Across Inc.]
+  {"hash":"877f3b2ffe34bf4a","prefixes":{"*":{"product":29}}}, // [8thBridge]
+  {"hash":"bc5882cc43d24a0b","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"5506a3935677620c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"4a8f0380d8c0ee22","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"54e1d163948509ad","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"534e3733e4e5309d","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"c7db8e0e25c7df2d","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"222afdeb29be30ca","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"a082f434d9ec1f91","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"e00092cf7fb8c74a","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"6b3557e54073f90d","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"b825724682d4bd41","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"62a0c6b3cd3ed567","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"7e5f80275a654f93","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"426c5ded1145b847","prefixes":{"*":{"product":1}}}, // [A9]
+  {"hash":"14f8bb92c4036403","prefixes":{"*":{"product":1}}}, // [A9]
+  {"hash":"8aaada51ee8ebb86","prefixes":{"*":{"product":1}}}, // [A9]
+  {"hash":"38eac8937b706b6f","prefixes":{"*":{"product":1}}}, // [A9]
+  {"hash":"7e1d4edc3530e448","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"c0bf2b011199054e","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"b4dd68c5d9b68922","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"8d943586f8f86d04","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"f60b51325cdf4f80","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"080dea15fa602a8c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"a01c9f1f745acb3b","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"eae49b84950db230","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"dabd2bc95093ab29","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"8912c7bdde481292","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"c735e4adfc754475","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"297bba8cd045b252","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"b4ee04e1cb1b0cb0","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"1f9925b611b3db5e","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"e63f21a01153ba8c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"5df92c4776ddb318","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"995e4fe402d230d4","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"f27bb2795a31311c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"7ef41a846501bb38","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"f69c9d0a6726d8a2","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"fbe82cac507c4685","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"b30108dc4fef7d3d","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"3db91f22497fff29","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"8c93f288d1c9adaa","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"dd3abfa7756f945e","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"562f4260ff4f65a6","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"94d8ddce749b5392","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"031269afdaee38ca","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"0c0ba1aaf374eac4","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"cb1dbab4bb9d139b","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"144dac73c5669441","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"b6b232e5fbf868f0","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"3c15562b6abc1319","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"722c811d70136506","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"78a792effa9e4967","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"a59637a7ca9dc579","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"6b3ce5ea793ecbbf","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"2b5bd0c505a178d0","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"c41cefa39852e538","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"e572b55cf0c6834b","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"80d0b8e46094b1c9","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"343036881041aa23","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"2559ed3163479794","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"95acf3d42f565375","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"a3fe80607786880e","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"b7629e7fab881e7a","prefixes":{"":{"product":31}}}, // [Retailigence]
+  {"hash":"03ec1a841574bd4d","prefixes":{"":{"product":32}}}, // [Logly DSP]
+  {"hash":"7ff5ce1768464e16","prefixes":{"":{"product":32}}}, // [Logly DSP]
+  {"hash":"10fb9dcb49e1abe6","prefixes":{"":{"product":33}}}, // [App-CM Inc.]
+  {"hash":"6d3713ad37a0966c","prefixes":{"":{"product":33}}}, // [App-CM Inc.]
+  {"hash":"41670ff004a04f19","prefixes":{"":{"product":33}}}, // [App-CM Inc.]
+  {"hash":"cd681b4891935464","prefixes":{"":{"product":34}}}, // [Yahoo! Japan Corporation]
+  {"hash":"b97383320b594f18","prefixes":{"":{"product":34}}}, // [Yahoo! Japan Corporation]
+  {"hash":"e2fff6e598b3035e","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"cb3ceda4f0c38995","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"a218e065250d793c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"deb1ce911dfb392b","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"de5ead15f1d0f171","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"92615d394883ce3c","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"6cd842b12d20b208","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"dc6acfacad6c1026","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"81aa25ff76990996","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"1254067a80cf3d7b","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"31e2549e82b92770","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"be41bb940608434e","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"05a4ab4a11bd1fbf","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"05677aca712e9b65","prefixes":{"":{"product":1}}}, // [A9]
+  {"hash":"00620801050945d1","prefixes":{"":{"product":35}}}, // [Oggifinogi]
+  {"hash":"c0ceae7cfc4144c6","prefixes":{"":{"product":36}}}, // [PaperG]
+  {"hash":"996c3990310cfc19","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"14210f0f0a8d71cb","prefixes":{"":{"product":38}}}, // [The Trade Desk Inc.]
+  {"hash":"0f07ec261c73a8fb","prefixes":{"*":{"product":39},"":{"product":40}}}, // [Amazon] [F# Inc.]
+  {"hash":"736b87f504b5e113","prefixes":{"":{"product":41}}}, // [Airpush, Inc.]
+  {"hash":"0bcef81372eadfe9","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"9ea6769e672968e9","prefixes":{"":{"product":40}}}, // [F# Inc.]
+  {"hash":"0fde612c20c42c6f","prefixes":{"":{"product":43}}}, // [Transout Inc.]
+  {"hash":"5ed995763ce85029","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"497082972c1c0dfd","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"6d7e4a203b969d9e","prefixes":{"":{"product":46}}}, // [Opera Mediaworks Inc.]
+  {"hash":"d3a9057528c14a56","prefixes":{"":{"product":47}}}, // [DistroScale Inc.]
+  {"hash":"479d2f8d9b7a2efe","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"6f7f9fb0065f745f","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"893d967f4540bb44","prefixes":{"":{"product":49}}}, // [Fluct Inc.]
+  {"hash":"3830f0b6ca460fe9","prefixes":{"*":{"product":50}}}, // [Acuity Ads]
+  {"hash":"e917237ee7b0ad79","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"e0792ffd5eca94d8","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"29beee316a393584","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"ce9e7bf17bba4aae","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"fcf604f90166bb66","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"f11d9059950b4a07","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"7d142a85f84f3402","prefixes":{"":{"product":50}}}, // [Acuity Ads]
+  {"hash":"83c0bb224cb5622f","prefixes":{"*":{"product":51}}}, // [iLead]
+  {"hash":"27841e5ac1581a67","prefixes":{"":{"product":52}}}, // [Canned Banners LLC]
+  {"hash":"83fbdce4f2519684","prefixes":{"":{"product":52}}}, // [Canned Banners LLC]
+  {"hash":"db7bac94f2b2d2b7","prefixes":{"":{"product":53}}}, // [AdBroker GmbH]
+  {"hash":"e0de5430253205fc","prefixes":{"":{"product":53}}}, // [AdBroker GmbH]
+  {"hash":"bde57b6011499edf","prefixes":{"":{"product":53}}}, // [AdBroker GmbH]
+  {"hash":"077ad042e29c79fb","prefixes":{"":{"product":53}}}, // [AdBroker GmbH]
+  {"hash":"d3c6fc5ff77f0d5c","prefixes":{"":{"product":53}}}, // [AdBroker GmbH]
+  {"hash":"b88fb01ba215894e","prefixes":{"*":{"product":54}}}, // [InMind Opinion Media]
+  {"hash":"3d509f557aeca6de","prefixes":{"*":{"product":55}}}, // [Adcentric]
+  {"hash":"3a9959c8cadd20af","prefixes":{"*":{"product":56}}}, // [AdClear GmbH]
+  {"hash":"e8adb806a39f661d","prefixes":{"":{"product":57}}}, // [DeinDeal AG]
+  {"hash":"da7343c16a51f1d4","prefixes":{"":{"product":58}}}, // [Sixt Leasing SE]
+  {"hash":"5b4d4595453d5b23","prefixes":{"":{"product":59}}}, // [Air Berlin]
+  {"hash":"b5085d3a3ede7503","prefixes":{"":{"product":60}}}, // [Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper]
+  {"hash":"076e39b7aa354c83","prefixes":{"":{"product":56}}}, // [AdClear GmbH]
+  {"hash":"61c6a6d15b340f45","prefixes":{"":{"product":61}}}, // [Adform DSP]
+  {"hash":"36f5cb213a4d1469","prefixes":{"":{"product":61}}}, // [Adform DSP]
+  {"hash":"95b61c012402be18","prefixes":{"":{"product":61}}}, // [Adform DSP]
+  {"hash":"34e291794974e891","prefixes":{"":{"product":61}}}, // [Adform DSP]
+  {"hash":"1d0d393655ae7ce4","prefixes":{"*":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"dbeb328acc5a5a14","prefixes":{"*":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"9e6e5f626bc3d43c","prefixes":{"":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"66659e79ff807f39","prefixes":{"":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"ce965bb06760436e","prefixes":{"":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"ca8e04a5cdd8fd1f","prefixes":{"":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"1084f1e2b04f5f93","prefixes":{"":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"04b3778457a3ba99","prefixes":{"*":{"product":62}}}, // [Adconion Media Group]
+  {"hash":"1b843f2f1a39c98b","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"8c7beead1ea37382","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"2b59e3efe59d97d5","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"518308907f5f69a2","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"07d4474fae9c6b06","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"47c590566f0c869a","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"409240a38e5e72b9","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"98421a6d07f5517b","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"4f00fb001635132a","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"c6ba94708f6d7d53","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"caae109e8a3bec4f","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"9137b5cdfcb54ca8","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"ae96d818a0674db2","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"f67fecc339ee273d","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"763cc84e4a6c6fce","prefixes":{"":{"product":63}}}, // [Adform]
+  {"hash":"170707627205d14d","prefixes":{"*":{"product":64}}}, // [Adition]
+  {"hash":"4b3783127a962269","prefixes":{"":{"product":64}}}, // [Adition]
+  {"hash":"457cb5e9c72500bd","prefixes":{"":{"product":64}}}, // [Adition]
+  {"hash":"0f529dc32c1b9057","prefixes":{"":{"product":64}}}, // [Adition]
+  {"hash":"e63845bad50263e0","prefixes":{"":{"product":65}}}, // [Active Agent]
+  {"hash":"08b8d8e397848984","prefixes":{"":{"product":65}}}, // [Active Agent]
+  {"hash":"146ac0ff21924e7d","prefixes":{"*":{"product":64}}}, // [Adition]
+  {"hash":"a51da6855de3a256","prefixes":{"":{"product":66}}}, // [mov.ad GmbH]
+  {"hash":"150498b9d10f053f","prefixes":{"*":{"product":64}}}, // [Adition]
+  {"hash":"fa1803e00adafe6b","prefixes":{"":{"product":66}}}, // [mov.ad GmbH]
+  {"hash":"ba820e9bd3ccd291","prefixes":{"":{"product":66}}}, // [mov.ad GmbH]
+  {"hash":"73f70045beea25cc","prefixes":{"":{"product":66}}}, // [mov.ad GmbH]
+  {"hash":"14725cb7b6e3ed94","prefixes":{"":{"product":66}}}, // [mov.ad GmbH]
+  {"hash":"fd2740cbee10696e","prefixes":{"":{"product":66}}}, // [mov.ad GmbH]
+  {"hash":"e150d6342c6a3952","prefixes":{"*":{"product":67}}}, // [AdJug]
+  {"hash":"50b8b93a8b536983","prefixes":{"*":{"product":68}}}, // [AdJuggler]
+  {"hash":"85335d83efc9839b","prefixes":{"*":{"product":68}}}, // [AdJuggler]
+  {"hash":"08f0bb45326cffe3","prefixes":{"*":{"product":69}}}, // [AdKeeper]
+  {"hash":"5e2b2393dad3f5eb","prefixes":{"*":{"product":69}}}, // [AdKeeper]
+  {"hash":"da818bcf61df9002","prefixes":{"*":{"product":69}}}, // [AdKeeper]
+  {"hash":"846fc96edd68e2f8","prefixes":{"*":{"product":70}}}, // [AdKnife]
+  {"hash":"914d48df3d7aeaae","prefixes":{"*":{"product":71}}}, // [Adku]
+  {"hash":"8a5b58174cc938bf","prefixes":{"*":{"product":72}}}, // [AdLantic Online Advertising]
+  {"hash":"218eb49612488266","prefixes":{"":{"product":73}}}, // [Adloox]
+  {"hash":"85c9a55ea5b2a32a","prefixes":{"data":{"product":73},"am":{"product":73}}}, // [Adloox] [Adloox]
+  {"hash":"9827ba4725b53982","prefixes":{"":{"product":73}}}, // [Adloox]
+  {"hash":"bfbbf6b81b109b36","prefixes":{"*":{"product":74}}}, // [adMarketplace]
+  {"hash":"006d6718806b7562","prefixes":{"*":{"product":75}}}, // [AdMotion]
+  {"hash":"43871f2ce46890ca","prefixes":{"":{"product":76}}}, // [AdMotion USA Inc.]
+  {"hash":"2648f20c5fa7ee09","prefixes":{"":{"product":76}}}, // [AdMotion USA Inc.]
+  {"hash":"63e0b0f085a8b214","prefixes":{"*":{"product":77}}}, // [Digilant]
+  {"hash":"7288a07f340911e5","prefixes":{"":{"product":78}}}, // [Adnologies GmbH]
+  {"hash":"a9fe843107d85e5c","prefixes":{"":{"product":78}}}, // [Adnologies GmbH]
+  {"hash":"230c59512261d73d","prefixes":{"cdn-":{"product":78}}}, // [Adnologies GmbH]
+  {"hash":"8ca4fb13619b77f1","prefixes":{"*":{"product":79}}}, // [Adometry by Google]
+  {"hash":"18652cba5445b34f","prefixes":{"":{"product":80}}}, // [Adperium BV]
+  {"hash":"6d09f83aefc4501e","prefixes":{"*":{"product":81}}}, // [AdPredictive]
+  {"hash":"70732e61af9adb0a","prefixes":{"":{"product":82}}}, // [Usemax]
+  {"hash":"b4ede094fe706ace","prefixes":{"*":{"product":83}}}, // [Adrime]
+  {"hash":"b19cfc95f67d0fa7","prefixes":{"*":{"product":83}}}, // [Adrime]
+  {"hash":"a6e49b6248014fa6","prefixes":{"*":{"product":84}}}, // [AdRiver]
+  {"hash":"4a53a59490c4a38e","prefixes":{"*":{"product":85}}}, // [Adroit Interactive]
+  {"hash":"683e22cafa5f3bd9","prefixes":{"":{"product":85}}}, // [Adroit Interactive]
+  {"hash":"02e8a15ca61fbc33","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"a3c3a62c565da599","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"73e23ad84157f244","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"b8bd71aaaa715a18","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"34049e798c80bbab","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"838eef1c1fe8af0c","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"3a7e3dfea00e8162","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"0173cd7bab46f6fd","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"c14663d78cbafed8","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"308a1884ba632254","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"0e219f63d92e9f36","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"f01c179c5f1e71ec","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"37523eaeb9b1fe5b","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"65eb7e97acb7c098","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"3caa5b10b768447a","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"c8ca517332beacb1","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"8af902c81b793154","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"38ed924c01545a3b","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"5b57e356a62d6828","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"4281a0a413796f1b","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"66e356358c42a9dd","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"ebe26069a0940456","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"9d2283ab81bb7a35","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"d5e05919c2d72fad","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"519afd00add32a74","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"88d48f3ceb8d02bb","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"d93b7d2660301b12","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"6a71009da4358f28","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"71f627786ab80897","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"f1b3147102656b41","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"1a3040f79f3eda5d","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"1c81402568ca4c6f","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"5a0f681f5d3714ed","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"fb3d4d280f621627","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"6811c6e8c717b25b","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"2b559615c990392b","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"d8447dd40d9ce63f","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"98a32e82bd6110c6","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"e3ff44ab0bbc3669","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"d8a244effa85d1e6","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"fa65d62c20cc94bb","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"1d55dfbdf9f318d1","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"e06269227a02ae45","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"2d2bf9a9cb6e9f86","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"0adbf6085946bbf6","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"61d2d4f25972fccd","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"d9506dcf3ab8ec68","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"61448b088aea7146","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"12b1ed92371498e2","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"b8f763d46b3d230a","prefixes":{"":{"product":88}}}, // [Integral Ad Science Firewall]
+  {"hash":"d4033ecbe069d318","prefixes":{"":{"product":87}}}, // [Campaign Monitor]
+  {"hash":"b45ea1eb9c9290a1","prefixes":{"*":{"product":89}}}, // [AdShuffle]
+  {"hash":"333bed71fe872c88","prefixes":{"":{"product":90}}}, // [ADSOVO]
+  {"hash":"ad77e48d841a15a8","prefixes":{"":{"product":90}}}, // [ADSOVO]
+  {"hash":"f822525b349866b4","prefixes":{"*":{"product":91}}}, // [ADTECH GmbH]
+  {"hash":"6cda8dd1b92f6c35","prefixes":{"*":{"product":91}}}, // [ADTECH GmbH]
+  {"hash":"4d592efbff40197f","prefixes":{"*":{"product":92}}}, // [Adtelligence]
+  {"hash":"0f57dc611a2e469e","prefixes":{"":{"product":93}}}, // [Adverline]
+  {"hash":"ef6cb8337223cbd6","prefixes":{"*":{"product":93}}}, // [Adverline]
+  {"hash":"1902c407bbf1add8","prefixes":{"*":{"product":94}}}, // [AOL Advertising.com]
+  {"hash":"c0956c63084023a8","prefixes":{"":{"product":95}}}, // [Adap.tv Inc. (AdX)]
+  {"hash":"f029d231882ed252","prefixes":{"":{"product":95}}}, // [Adap.tv Inc. (AdX)]
+  {"hash":"ee175aa478efb9b3","prefixes":{"*":{"product":94}}}, // [AOL Advertising.com]
+  {"hash":"c0fff6b8232710c4","prefixes":{"*":{"product":94}}}, // [AOL Advertising.com]
+  {"hash":"a846e3340ac27ada","prefixes":{"":{"product":96}}}, // [Convertro Inc]
+  {"hash":"548e9e34dbc275b6","prefixes":{"":{"product":97}}}, // [Tacoda]
+  {"hash":"e9695f56eaa054e2","prefixes":{"":{"product":94}}}, // [AOL Advertising.com]
+  {"hash":"f7f6bc8c4345347a","prefixes":{"*":{"product":98}}}, // [Digital Control GmbH (Advolution)]
+  {"hash":"484a656ace404140","prefixes":{"":{"product":98}}}, // [Digital Control GmbH (Advolution)]
+  {"hash":"a224f896601ec717","prefixes":{"":{"product":98}}}, // [Digital Control GmbH (Advolution)]
+  {"hash":"3a79a6d9af12ef9a","prefixes":{"*":{"product":99}}}, // [AdXcel]
+  {"hash":"b3dec77d20a55dcb","prefixes":{"*":{"product":99}}}, // [AdXcel]
+  {"hash":"1f25b55eca65221c","prefixes":{"":{"product":99}}}, // [AdXcel]
+  {"hash":"f531a655b1982ee7","prefixes":{"":{"product":100}}}, // [Alenty S.A.S]
+  {"hash":"b884f71dddd78a28","prefixes":{"":{"product":101}}}, // [DoubleClick Bid Manager]
+  {"hash":"839eb75d0e9ef128","prefixes":{"":{"product":102}}}, // [BigaBid Media Ltd.]
+  {"hash":"ad920773d5c3e050","prefixes":{"":{"product":103}}}, // [Cogo Labs, Inc.]
+  {"hash":"6cbe6bc5d5fed35c","prefixes":{"":{"product":104}}}, // [AudienceProject]
+  {"hash":"98bc51a23a37253c","prefixes":{"*":{"product":39}}}, // [Amazon]
+  {"hash":"78cfcb50606e44f8","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"37f3aa55bd48760c","prefixes":{"":{"product":106}}}, // [PocketMath]
+  {"hash":"fa92c520ca116999","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"26d760f54a265d93","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"c046bec428f602d5","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"7fbe2c9290629394","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"16d261a6c03c3de9","prefixes":{"":{"product":108}}}, // [Immedium, Inc.]
+  {"hash":"1787c49522ce0278","prefixes":{"":{"product":109}}}, // [Fractional Media, LLC]
+  {"hash":"45ccf99ac2ed3af1","prefixes":{"":{"product":109}}}, // [Fractional Media, LLC]
+  {"hash":"8c431268cc5c116b","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"645dd2a279a77bf5","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"53aaf4b4f2f2cc8b","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"a6175c31fc587fa2","prefixes":{"":{"product":111}}}, // [Epic Combo Malta Ltd.]
+  {"hash":"c0e7c2ad3d5d28a0","prefixes":{"":{"product":111}}}, // [Epic Combo Malta Ltd.]
+  {"hash":"b6a3ce0dea65f762","prefixes":{"":{"product":112}}}, // [Quixey]
+  {"hash":"29e07de898fa18f4","prefixes":{"":{"product":112}}}, // [Quixey]
+  {"hash":"1959efaae117c9fa","prefixes":{"":{"product":113}}}, // [YOOX NET-A-PORTER GROUP SPA]
+  {"hash":"0a59c33253f15970","prefixes":{"":{"product":114}}}, // [TapTap Networks S.L.]
+  {"hash":"383161133467d12b","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"e2e18e4ba75c8e58","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"1f9da694ae6dd7cf","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"5038b4de783848d4","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"3542b95dcaa08c84","prefixes":{"":{"product":115}}}, // [ComScore (AdXpose)]
+  {"hash":"7bbbdfeb3d7b8ad3","prefixes":{"*":{"product":116}}}, // [AdYard]
+  {"hash":"2ff57c503c5f110d","prefixes":{"":{"product":117}}}, // [Affectv]
+  {"hash":"7558d4293841e1f0","prefixes":{"":{"product":117}}}, // [Affectv]
+  {"hash":"a8adad05a6ff5945","prefixes":{"":{"product":117}}}, // [Affectv]
+  {"hash":"cd1a91dee22478d6","prefixes":{"":{"product":117}}}, // [Affectv]
+  {"hash":"ebca243af085210f","prefixes":{"":{"product":117}}}, // [Affectv]
+  {"hash":"bc7fe0dc5bf3e869","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"c894a0e3f6a6b627","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"bfdba513f8cb5b8b","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"1227c609f898a707","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"4f884065e1e88de2","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"93d5950ea0bfe437","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"560c5b8e23e29733","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"28d74bfc94c9635f","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"8f7f83e4f5f9e2c0","prefixes":{"":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"fd2b5d860fd44749","prefixes":{"*":{"product":3}}}, // [Affilinet GmbH]
+  {"hash":"1d0953961a14d2fc","prefixes":{"*":{"product":118}}}, // [SET.tv]
+  {"hash":"5edf63353d8e0fcd","prefixes":{"":{"product":118}}}, // [SET.tv]
+  {"hash":"e4e5eb11299f703e","prefixes":{"*":{"product":119}}}, // [Adroit Digital Solutions (ADS)]
+  {"hash":"e5cf3445847fef93","prefixes":{"*":{"product":119}}}, // [Adroit Digital Solutions (ADS)]
+  {"hash":"8441a2216167c3d4","prefixes":{"at":{"product":100}}}, // [Alenty S.A.S]
+  {"hash":"b9dab57457cf6477","prefixes":{"":{"product":100}}}, // [Alenty S.A.S]
+  {"hash":"94b55596aadb2893","prefixes":{"":{"product":100}}}, // [Alenty S.A.S]
+  {"hash":"16b31027fd40c9ad","prefixes":{"":{"product":100}}}, // [Alenty S.A.S]
+  {"hash":"bb4adabba7b0b6b8","prefixes":{"*":{"product":120}}}, // [AppNexus Inc]
+  {"hash":"3b2105469f3563e3","prefixes":{"*":{"product":121}}}, // [Adfusion]
+  {"hash":"2f29d38052b5a8a6","prefixes":{"":{"product":122}}}, // [ARC Media Group]
+  {"hash":"c133787bd9e605a7","prefixes":{"":{"product":123}}}, // [Semasio GmbH]
+  {"hash":"b9a83d8bd4f31543","prefixes":{"":{"product":124}}}, // [Mojiva]
+  {"hash":"2a1b04ad13f24350","prefixes":{"":{"product":124}}}, // [Mojiva]
+  {"hash":"a3c6b5ffd4fe1547","prefixes":{"":{"product":125}}}, // [Mocean mobile, Inc.]
+  {"hash":"0d52aafa33281228","prefixes":{"":{"product":126}}}, // [Phluant]
+  {"hash":"655e31ecb8719994","prefixes":{"":{"product":126}}}, // [Phluant]
+  {"hash":"dca17bd2f3edb917","prefixes":{"":{"product":126}}}, // [Phluant]
+  {"hash":"53de58004f88a1c2","prefixes":{"*":{"product":127}}}, // [AdSpirit]
+  {"hash":"6a1ebf671194b458","prefixes":{"*":{"product":127}}}, // [AdSpirit]
+  {"hash":"6ae5a4877aab564f","prefixes":{"":{"product":127}}}, // [AdSpirit]
+  {"hash":"9dcf8d17ea42466e","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"32e0acbf3d2ecfcf","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"708d275466f5230b","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"7532d83428e05417","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"3258e49c5f504307","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"2c381faaa3144a37","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"776a64cc3a9c6f81","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"d38247a8e8d14a7c","prefixes":{"*":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"50e5ca70dbb69c03","prefixes":{"":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"c1dfde405c173e3b","prefixes":{"":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"5bce52b0f221aac2","prefixes":{"":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"5a0e5730145156e2","prefixes":{"":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"c081c626ad2c0f1f","prefixes":{"":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"a31f53c0c58e67c0","prefixes":{"":{"product":129}}}, // [ATK Media GmbH]
+  {"hash":"514b4f19cbdabb49","prefixes":{"":{"product":129}}}, // [ATK Media GmbH]
+  {"hash":"264493bb5046087f","prefixes":{"":{"product":129}}}, // [ATK Media GmbH]
+  {"hash":"f4e40d6832493420","prefixes":{"":{"product":129}}}, // [ATK Media GmbH]
+  {"hash":"126b6492c0b1b53a","prefixes":{"*":{"product":130}}}, // [Atlas]
+  {"hash":"0493e6c92c59fd4d","prefixes":{"":{"product":130}}}, // [Atlas]
+  {"hash":"d6d40b4417fefcf6","prefixes":{"":{"product":130}}}, // [Atlas]
+  {"hash":"0b16a7cf8dcb70ee","prefixes":{"*":{"product":131}}}, // [AudienceScience]
+  {"hash":"edbae80f2449aaee","prefixes":{"":{"product":132}}}, // [BeWebMedia]
+  {"hash":"c1196b1418bf9de9","prefixes":{"*":{"product":133}}}, // [Bidalpha Inc.]
+  {"hash":"87016c0f34162bc6","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"2db3b8adb9c37590","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"a10756ccfb034a50","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"1ea7188c5cc22ccf","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"c70dfe98c3735972","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"05aa49d024d6d67c","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"27c08401857f47aa","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"9a569266b426d074","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"5a764c1f870e4e38","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"64b993405c35034f","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"afe660eca2d01217","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"cd398b1d3fe6caf4","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"bb2cf5a27552ba10","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"b79ee8778f5b56d6","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"cae97638b357a30e","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"2c552297aa3abdf1","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"75bbf901ed30d891","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"365bc710167be24c","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"49849f3497cc7ff5","prefixes":{"":{"product":134}}}, // [AdGear Technologies Inc.]
+  {"hash":"14bb8555907973f5","prefixes":{"":{"product":135}}}, // [BlueKai]
+  {"hash":"db6cb381e20a210a","prefixes":{"":{"product":135}}}, // [BlueKai]
+  {"hash":"8e4e07437ae4b61c","prefixes":{"*":{"product":136}}}, // [Bluestreak]
+  {"hash":"4bb6a17c8b5ec2e7","prefixes":{"":{"product":137}}}, // [blurbIQ]
+  {"hash":"4aefb106f857a0de","prefixes":{"":{"product":137}}}, // [blurbIQ]
+  {"hash":"a7b4452428f93120","prefixes":{"":{"product":137}}}, // [blurbIQ]
+  {"hash":"38f01d050feb50e8","prefixes":{"":{"product":137}}}, // [blurbIQ]
+  {"hash":"d4ab70ba7caf1ed7","prefixes":{"":{"product":138}}}, // [Brand.net]
+  {"hash":"94655d9cadd8e829","prefixes":{"":{"product":138}}}, // [Brand.net]
+  {"hash":"f3347a75843fd9c6","prefixes":{"":{"product":138}}}, // [Brand.net]
+  {"hash":"60e2856d32c1da23","prefixes":{"*":{"product":139}}}, // [Brandscreen Inc.]
+  {"hash":"16460b1ac6e3b229","prefixes":{"*":{"product":140}}}, // [BrightRoll Inc.]
+  {"hash":"814fef93d6498b58","prefixes":{"*":{"product":140}}}, // [BrightRoll Inc.]
+  {"hash":"72fc1d7c40b9af03","prefixes":{"":{"product":141}}}, // [Brightroll Inc.]
+  {"hash":"80f8944423cc936c","prefixes":{"*":{"product":142}}}, // [Vindico]
+  {"hash":"bf2db20b09960c7b","prefixes":{"":{"product":142}}}, // [Vindico]
+  {"hash":"e180a56826bf4ba6","prefixes":{"*":{"product":143}}}, // [Edgesuite]
+  {"hash":"1e90c625da6683a5","prefixes":{"":{"product":144}}}, // [Spark Flow S.A.]
+  {"hash":"d385e514fe92e6d9","prefixes":{"":{"product":145}}}, // [Aarki, Inc.]
+  {"hash":"4646e46d55455ffe","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"a8c5f49831b36ab9","prefixes":{"*":{"product":147}}}, // [Burst Media LLC d/b/a AdConductor]
+  {"hash":"f22276edaf005231","prefixes":{"*":{"product":148}}}, // [Advertising.com Dynamic Retargeter]
+  {"hash":"220db526eb84992d","prefixes":{"*":{"product":149}}}, // [NetAffiliation]
+  {"hash":"cda3d9612026866c","prefixes":{"*":{"product":149}}}, // [NetAffiliation]
+  {"hash":"9f8018bcbf15a592","prefixes":{"*":{"product":150}}}, // [C3 Metrics Inc.]
+  {"hash":"78ec342986654215","prefixes":{"":{"product":150}}}, // [C3 Metrics Inc.]
+  {"hash":"e4ad94837095a9bc","prefixes":{"*":{"product":150}}}, // [C3 Metrics Inc.]
+  {"hash":"32401b2118eff57a","prefixes":{"":{"product":151}}}, // [CAPITALDATA (SARL)]
+  {"hash":"a5f9db92cb5aeb3e","prefixes":{"":{"product":151}}}, // [CAPITALDATA (SARL)]
+  {"hash":"ae12db7e0621ec0b","prefixes":{"*":{"product":151}}}, // [CAPITALDATA (SARL)]
+  {"hash":"d7c4970fde31fd62","prefixes":{"*":{"product":152}}}, // [e-Planning]
+  {"hash":"20cadab7abdae752","prefixes":{"*":{"product":153}}}, // [Chango Inc.]
+  {"hash":"38363f7ac872a916","prefixes":{"":{"product":154}}}, // [Chango]
+  {"hash":"114215c6a5b66e37","prefixes":{"":{"product":154}}}, // [Chango]
+  {"hash":"1ab7b29d135c11fc","prefixes":{"":{"product":155}}}, // [Channel Intelligence]
+  {"hash":"6e8e21cf50387d5b","prefixes":{"":{"product":155}}}, // [Channel Intelligence]
+  {"hash":"cbd8c46855691ac9","prefixes":{"*":{"product":155}}}, // [Channel Intelligence]
+  {"hash":"8bde0d3ba731b24b","prefixes":{"":{"product":155}}}, // [Channel Intelligence]
+  {"hash":"d415664f4794184e","prefixes":{"":{"product":155}}}, // [Channel Intelligence]
+  {"hash":"bc8edad5208e36aa","prefixes":{"*":{"product":155}}}, // [Channel Intelligence]
+  {"hash":"00900e4af3795b7d","prefixes":{"":{"product":156}}}, // [Chartbeat Inc]
+  {"hash":"dddd416675de98d6","prefixes":{"":{"product":156}}}, // [Chartbeat Inc]
+  {"hash":"085835cbbea3af5b","prefixes":{"":{"product":156}}}, // [Chartbeat Inc]
+  {"hash":"0a5fd555ed989cf1","prefixes":{"":{"product":156}}}, // [Chartbeat Inc]
+  {"hash":"38e6dfa04599d610","prefixes":{"":{"product":156}}}, // [Chartbeat Inc]
+  {"hash":"282ab213b57d8196","prefixes":{"":{"product":156}}}, // [Chartbeat Inc]
+  {"hash":"465922959fd197de","prefixes":{"*":{"product":157}}}, // [Choicestream Inc.]
+  {"hash":"07b64c6d94aaeede","prefixes":{"*":{"product":158}}}, // [AddThis, Inc]
+  {"hash":"8285ed75ebbab1bf","prefixes":{"*":{"product":158}}}, // [AddThis, Inc]
+  {"hash":"397da235f9c6c4dc","prefixes":{"*":{"product":159}}}, // [Platform 161]
+  {"hash":"3e4380669a97a9da","prefixes":{"":{"product":159}}}, // [Platform 161]
+  {"hash":"0cf7c3db283e4fde","prefixes":{"":{"product":160}}}, // [ClickPoint]
+  {"hash":"e3f610966ee4998e","prefixes":{"":{"product":161}}}, // [Cobalt Group]
+  {"hash":"5458332ef0eff5a0","prefixes":{"":{"product":161}}}, // [Cobalt Group]
+  {"hash":"755391831ca3c171","prefixes":{"*":{"product":161}}}, // [Cobalt Group]
+  {"hash":"82d7785d13750576","prefixes":{"*":{"product":161}}}, // [Cobalt Group]
+  {"hash":"f1b10b28e8a1e8a9","prefixes":{"*":{"product":161}}}, // [Cobalt Group]
+  {"hash":"ca9dc80141cf19b5","prefixes":{"*":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"d02173b857f779a2","prefixes":{"*":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"987bec8a1c07a02f","prefixes":{"*":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"da18ae94f7dd99ab","prefixes":{"":{"product":163}}}, // [Tagtoo Tech Limited]
+  {"hash":"5e1256c5e919daf9","prefixes":{"":{"product":164}}}, // [wayStorm Co., Ltd.]
+  {"hash":"9e92efa06a26b83d","prefixes":{"*":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"cf3c8c24a0eb24a6","prefixes":{"*":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"eac24a30a92872f1","prefixes":{"":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"a508105d922876fe","prefixes":{"":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"b7f1551e6c1615df","prefixes":{"":{"product":162}}}, // [Cognitive Match Limited]
+  {"hash":"e56a388aae6f063e","prefixes":{"*":{"product":165}}}, // [Collective Media LLC]
+  {"hash":"adc75d0087df3e89","prefixes":{"":{"product":166}}}, // [ComScore Campaign Essentials (CE)]
+  {"hash":"6f0ca09cdc147fb0","prefixes":{"":{"product":166}}}, // [ComScore Campaign Essentials (CE)]
+  {"hash":"11f6ca20d229d8ad","prefixes":{"":{"product":166}}}, // [ComScore Campaign Essentials (CE)]
+  {"hash":"e4d55634b8d3126d","prefixes":{"":{"product":166}}}, // [ComScore Campaign Essentials (CE)]
+  {"hash":"6100cc0a622faa8e","prefixes":{"":{"product":167}}}, // [ComScore Validated Campaign Essentials (vCE)]
+  {"hash":"a30e99f000f781c7","prefixes":{"":{"product":167}}}, // [ComScore Validated Campaign Essentials (vCE)]
+  {"hash":"1ee7cb55ae2cb071","prefixes":{"":{"product":166}}}, // [ComScore Campaign Essentials (CE)]
+  {"hash":"7dfd981d4c018953","prefixes":{"":{"product":167}}}, // [ComScore Validated Campaign Essentials (vCE)]
+  {"hash":"5011cb94579baba5","prefixes":{"*":{"product":168}}}, // [VoiceFive (ComScore)]
+  {"hash":"a0cff89b286fc309","prefixes":{"":{"product":168}}}, // [VoiceFive (ComScore)]
+  {"hash":"4782e75d195d3144","prefixes":{"":{"product":168}}}, // [VoiceFive (ComScore)]
+  {"hash":"e63472329b04aab9","prefixes":{"":{"product":168}}}, // [VoiceFive (ComScore)]
+  {"hash":"5814e7da11d65131","prefixes":{"":{"product":168}}}, // [VoiceFive (ComScore)]
+  {"hash":"26c9b653ef6bfb53","prefixes":{"*":{"product":169}}}, // [Connexity LLC]
+  {"hash":"eb38b3659a232a56","prefixes":{"":{"product":169}}}, // [Connexity LLC]
+  {"hash":"08abcdb9184877f9","prefixes":{"":{"product":169}}}, // [Connexity LLC]
+  {"hash":"65a439ff09c9f7dc","prefixes":{"":{"product":169}}}, // [Connexity LLC]
+  {"hash":"b3afc505f1f5487b","prefixes":{"":{"product":169}}}, // [Connexity LLC]
+  {"hash":"b35a41328f2a6830","prefixes":{"*":{"product":170}}}, // [Constant Contact]
+  {"hash":"e7a596af94ad559e","prefixes":{"":{"product":171}}}, // [ContextWeb Inc.]
+  {"hash":"25ccc25c112607e9","prefixes":{"":{"product":171}}}, // [ContextWeb Inc.]
+  {"hash":"44e652990824ddee","prefixes":{"":{"product":171}}}, // [ContextWeb Inc.]
+  {"hash":"8eac48fda4ccaec8","prefixes":{"":{"product":171}}}, // [ContextWeb Inc.]
+  {"hash":"0b4eee92ed72b991","prefixes":{"ant-":{"product":172}}}, // [Conversive BV]
+  {"hash":"dae78afe5d5cc699","prefixes":{"":{"product":172}}}, // [Conversive BV]
+  {"hash":"7729d423a7fc3adf","prefixes":{"*":{"product":96}}}, // [Convertro Inc]
+  {"hash":"cdff1e442509fafe","prefixes":{"":{"product":173}}}, // [IBM Digital Analytics]
+  {"hash":"a07829ef9a9d6762","prefixes":{"*":{"product":174}}}, // [Crimtan]
+  {"hash":"43c19f0523939982","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"2c4f3b76ebfafe80","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"078603692b0949b1","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"aa8844a1d3e7c3aa","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"15ef2aafaa03e60b","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"5f1ef71046a359f7","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"2fb5d0d81abd43be","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"75ce1d1edaf8f426","prefixes":{"":{"product":174}}}, // [Crimtan]
+  {"hash":"a7b80b09927034f7","prefixes":{"*":{"product":175}}}, // [Criteo]
+  {"hash":"3a96f385ff402ab6","prefixes":{"*":{"product":175}}}, // [Criteo]
+  {"hash":"189c3bab631d09cf","prefixes":{"":{"product":176}}}, // [D.A. Consortium Inc. (EffectiveOne)]
+  {"hash":"3d9109a2e81eee2d","prefixes":{"":{"product":176}}}, // [D.A. Consortium Inc. (EffectiveOne)]
+  {"hash":"e7170acff5d6fda1","prefixes":{"":{"product":176}}}, // [D.A. Consortium Inc. (EffectiveOne)]
+  {"hash":"e0496c88da22371f","prefixes":{"":{"product":176}}}, // [D.A. Consortium Inc. (EffectiveOne)]
+  {"hash":"59ab4e7744543242","prefixes":{"":{"product":177}}}, // [Platform One]
+  {"hash":"f6b2b21a0a0417b3","prefixes":{"":{"product":177}}}, // [Platform One]
+  {"hash":"4384a84e6276861a","prefixes":{"*":{"product":178}}}, // [Dapper Inc.]
+  {"hash":"1ccbc5b91f4c5fc9","prefixes":{"*":{"product":179}}}, // [DataXu Inc.]
+  {"hash":"4840192a8cb4b1ca","prefixes":{"*":{"product":179}}}, // [DataXu Inc.]
+  {"hash":"b50faf8c7e5fc38c","prefixes":{"":{"product":180}}}, // [Aperture]
+  {"hash":"bdcf8ed53f1b3802","prefixes":{"*":{"product":181}}}, // [Rakuten Attribution]
+  {"hash":"d31e7c4efd1a5191","prefixes":{"*":{"product":181}}}, // [Rakuten Attribution]
+  {"hash":"68318c6d8f72133b","prefixes":{"*":{"product":181}}}, // [Rakuten Attribution]
+  {"hash":"c0c4eb0ce58ef4b1","prefixes":{"*":{"product":181}}}, // [Rakuten Attribution]
+  {"hash":"ae713ee10231204e","prefixes":{"*":{"product":182}}}, // [AdAction]
+  {"hash":"e4282cef85ee5728","prefixes":{"":{"product":183}}}, // [Demandbase Inc.]
+  {"hash":"79f6c3d16c278e94","prefixes":{"":{"product":183}}}, // [Demandbase Inc.]
+  {"hash":"13e7a7b6c40ef05b","prefixes":{"":{"product":183}}}, // [Demandbase Inc.]
+  {"hash":"57e736fc045f8fbd","prefixes":{"":{"product":183}}}, // [Demandbase Inc.]
+  {"hash":"82137a4a2aa17f33","prefixes":{"*":{"product":184}}}, // [Omniture]
+  {"hash":"ddc305710749f5b7","prefixes":{"*":{"product":184}}}, // [Omniture]
+  {"hash":"3cd74441fc237226","prefixes":{"*":{"product":184}}}, // [Omniture]
+  {"hash":"5b40000c858b730d","prefixes":{"":{"product":185}}}, // [Rovion, Inc.]
+  {"hash":"47d66d29363322cd","prefixes":{"":{"product":186}}}, // [AdHui.com LLC]
+  {"hash":"10a0efb999eedf90","prefixes":{"":{"product":186}}}, // [AdHui.com LLC]
+  {"hash":"b1bf29ae383ea0cd","prefixes":{"":{"product":187}}}, // [Bidlab sp. z o.o]
+  {"hash":"baa26df04dbce196","prefixes":{"":{"product":187}}}, // [Bidlab sp. z o.o]
+  {"hash":"c3f807fb12d64ef3","prefixes":{"":{"product":188}}}, // [CyberAgent Inc.]
+  {"hash":"8caed248711d066a","prefixes":{"":{"product":188}}}, // [CyberAgent Inc.]
+  {"hash":"03524472b71baf6f","prefixes":{"":{"product":189}}}, // [Relay42 Technology B.V.]
+  {"hash":"c26a754afcf8496d","prefixes":{"":{"product":189}}}, // [Relay42 Technology B.V.]
+  {"hash":"fa7ea4c2400b9304","prefixes":{"":{"product":189}}}, // [Relay42 Technology B.V.]
+  {"hash":"f91d12ea09409395","prefixes":{"":{"product":189}}}, // [Relay42 Technology B.V.]
+  {"hash":"a3404139a451726c","prefixes":{"":{"product":190}}}, // [Nielsen Digital Ad Ratings (JS)]
+  {"hash":"072f7bf8cea1803c","prefixes":{"":{"product":190}}}, // [Nielsen Digital Ad Ratings (JS)]
+  {"hash":"8a6e324bbf4e02dc","prefixes":{"":{"product":190}}}, // [Nielsen Digital Ad Ratings (JS)]
+  {"hash":"e59faa8d364c3ad2","prefixes":{"":{"product":190}}}, // [Nielsen Digital Ad Ratings (JS)]
+  {"hash":"fe39de2cc1550ee8","prefixes":{"":{"product":190}}}, // [Nielsen Digital Ad Ratings (JS)]
+  {"hash":"41808f1a9bcd4cdf","prefixes":{"":{"product":190}}}, // [Nielsen Digital Ad Ratings (JS)]
+  {"hash":"1774fa7feee9a3ba","prefixes":{"":{"product":191}}}, // [Nielsen (Audience Measurement Platform)]
+  {"hash":"8bcfafa30bb9a496","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"04a15100eebd5238","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"37669b02a11574d6","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"b0e609cae76778ef","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"8602961190244c78","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"cf6160cc55083e3f","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"d8e0147c7067e033","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"fa4e638adbad854a","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"bfc104d8ae540578","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"a77b609ecb948524","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"5b2d6c6512b90826","prefixes":{"":{"product":193}}}, // [Nielsen (Sales Effect)]
+  {"hash":"3f0eefad5865a4ed","prefixes":{"":{"product":194}}}, // [Ohana Media India Private Limited]
+  {"hash":"ba149fc47bfe9e3c","prefixes":{"":{"product":194}}}, // [Ohana Media India Private Limited]
+  {"hash":"cfe9fa124d3faa0b","prefixes":{"*":{"product":195}}}, // [DisplayCDN]
+  {"hash":"3f8d8705aeaf2a69","prefixes":{"":{"product":196}}}, // [Avail Intelligence]
+  {"hash":"3aa373d150e55bb8","prefixes":{"":{"product":196}}}, // [Avail Intelligence]
+  {"hash":"01168e37c54407ec","prefixes":{"":{"product":196}}}, // [Avail Intelligence]
+  {"hash":"9d0088e875d03291","prefixes":{"":{"product":197}}}, // [Adobe Scene 7]
+  {"hash":"7892719f65634daf","prefixes":{"":{"product":198}}}, // [Asda]
+  {"hash":"76913c314e7299f2","prefixes":{"":{"product":199}}}, // [Adsfactor Limited]
+  {"hash":"ec3d301a1049a29c","prefixes":{"":{"product":200}}}, // [Trademob GmbH]
+  {"hash":"0407237113d1e01a","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"3c2b08727db96f57","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"28d8cdf30ea5e75d","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"4ba6006c59a0afb3","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"34b0d82da56a6e14","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"c9293b8324f3a30f","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"78ad5395bf22ddd5","prefixes":{"":{"product":201}}}, // [Zamplus Technology Co., Ltd.]
+  {"hash":"b0a5ecf647236d2a","prefixes":{"*":{"product":202}}}, // [Telemetry Limited]
+  {"hash":"7d7cd86e56968411","prefixes":{"*":{"product":202}}}, // [Telemetry Limited]
+  {"hash":"ccaf0946d1809711","prefixes":{"*":{"product":202}}}, // [Telemetry Limited]
+  {"hash":"d08bcd58e153f333","prefixes":{"*":{"product":203}}}, // [AdPilot]
+  {"hash":"c1ee73ca85937956","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"b3ee9fcc7f773476","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"0dededd99d2513e4","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"efd59a0198028c96","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"b43b6c20f3008842","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"5d96f09a039b26e6","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"039408a17f3d50d7","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"16d696fe52cae068","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"ebb9da6e533fc7e4","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"c8afb150eb1b6ac1","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"1e21c92ae4d08330","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"07ef420d707be72c","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"3d9fb95e3108b648","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"938e971e186be4f8","prefixes":{"":{"product":203}}}, // [AdPilot]
+  {"hash":"94682de65e11f128","prefixes":{"":{"product":204}}}, // [ebookers]
+  {"hash":"32548cc45dcf9e95","prefixes":{"":{"product":204}}}, // [ebookers]
+  {"hash":"baa9bf6209e38821","prefixes":{"":{"product":204}}}, // [ebookers]
+  {"hash":"25a263451425f7e3","prefixes":{"*":{"product":205}}}, // [Mashero GmbH]
+  {"hash":"4871ba81fe73b693","prefixes":{"":{"product":206}}}, // [4wMarketPlace Srl]
+  {"hash":"f95f038fea1148ab","prefixes":{"*":{"product":207}}}, // [Meetic Partners]
+  {"hash":"8c555d8aa0a96ecc","prefixes":{"*":{"product":208}}}, // [Adara Media]
+  {"hash":"a31f9bce31634750","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"bb0d6b4eac177896","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"02712dc83414bc52","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"03cfa92cdadd6c20","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"4d8640e955380082","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"42ab78ba8d28d0d9","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"113f35a595990303","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"9566d797c39bca8e","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"caab6878aaf1b900","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"13581af42d29c3fd","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"8ad4e9b59b6cfebf","prefixes":{"":{"product":209}}}, // [Adledge]
+  {"hash":"025223bda779fb50","prefixes":{"":{"product":210}}}, // [Adledge: Ad Swapping]
+  {"hash":"6c7970d8fe11d946","prefixes":{"":{"product":211}}}, // [LifeStreet Corportation]
+  {"hash":"226c377d19c24dca","prefixes":{"":{"product":211}}}, // [LifeStreet Corportation]
+  {"hash":"bc64475cc35aba69","prefixes":{"":{"product":211}}}, // [LifeStreet Corportation]
+  {"hash":"8a184297457cd4e1","prefixes":{"":{"product":211}}}, // [LifeStreet Corportation]
+  {"hash":"900f97a5320abcc7","prefixes":{"":{"product":212}}}, // [AdCirrus]
+  {"hash":"39b102bb2f01d1b4","prefixes":{"":{"product":213}}}, // [Dimestore]
+  {"hash":"a144c6442bbc8a0a","prefixes":{"":{"product":213}}}, // [Dimestore]
+  {"hash":"8020cac4e8fee023","prefixes":{"":{"product":213}}}, // [Dimestore]
+  {"hash":"2dcefe5fe106e478","prefixes":{"*":{"product":214}}}, // [GfK SE]
+  {"hash":"d8f9a95c0ea00853","prefixes":{"*":{"product":213}}}, // [Dimestore]
+  {"hash":"829fbeefc45bca87","prefixes":{"*":{"product":215}}}, // [Conversant CRM]
+  {"hash":"357a04f93d25ae56","prefixes":{"cdn":{"product":216},"log":{"product":216},"tps":{"product":216},"rtb":{"product":217}}}, // [DoubleVerify Inc.] [DoubleVerify Inc.] [DoubleVerify Inc.] [DoubleVerify Inc. (BrandShield): Ad Swapping]
+  {"hash":"e88f040d82035294","prefixes":{"":{"product":216}}}, // [DoubleVerify Inc.]
+  {"hash":"a378f9f7b3d5241c","prefixes":{"*":{"product":218}}}, // [Dynamic Video LLC]
+  {"hash":"665ab90fa95fb304","prefixes":{"":{"product":218}}}, // [Dynamic Video LLC]
+  {"hash":"1358623e271c4d67","prefixes":{"":{"product":218}}}, // [Dynamic Video LLC]
+  {"hash":"a11e7a579fa98970","prefixes":{"*":{"product":219}}}, // [Think RealTime, LLC]
+  {"hash":"9225aaedf058b2a2","prefixes":{"":{"product":220}}}, // [Effective Measure]
+  {"hash":"36703887ac49b84b","prefixes":{"":{"product":220}}}, // [Effective Measure]
+  {"hash":"eabfdf13f38b7671","prefixes":{"*":{"product":221}}}, // [Adobe Media Optimizer]
+  {"hash":"e6c60b5e8bab7589","prefixes":{"*":{"product":221}}}, // [Adobe Media Optimizer]
+  {"hash":"d4ca4e6c8a0bedf0","prefixes":{"*":{"product":221}}}, // [Adobe Media Optimizer]
+  {"hash":"2e2899c7688fb6b3","prefixes":{"":{"product":222}}}, // [Effiliation]
+  {"hash":"3a8f463e807ab596","prefixes":{"":{"product":222}}}, // [Effiliation]
+  {"hash":"4c49524999954857","prefixes":{"":{"product":222}}}, // [Effiliation]
+  {"hash":"99a4dc2c14dac648","prefixes":{"*":{"product":223}}}, // [EmediateAd]
+  {"hash":"eb4d633002c35102","prefixes":{"*":{"product":223}}}, // [EmediateAd]
+  {"hash":"a4155988849d9899","prefixes":{"":{"product":223}}}, // [EmediateAd]
+  {"hash":"a29dc15ab67e4109","prefixes":{"*":{"product":223}}}, // [EmediateAd]
+  {"hash":"244ed2f383a41c11","prefixes":{"*":{"product":223}}}, // [EmediateAd]
+  {"hash":"f1d41523d742a4c4","prefixes":{"*":{"product":224}}}, // [engage:BDR Inc.]
+  {"hash":"0c985c5bee46dcca","prefixes":{"":{"product":224}}}, // [engage:BDR Inc.]
+  {"hash":"6f92a4165360659f","prefixes":{"":{"product":224}}}, // [engage:BDR Inc.]
+  {"hash":"e65b14b1de797d5e","prefixes":{"":{"product":224}}}, // [engage:BDR Inc.]
+  {"hash":"8908058eec675b88","prefixes":{"*":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"dae357b5105fb541","prefixes":{"*":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"7e5c5286bc6286af","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"6459463a599e26cf","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"d49c14999963fa7c","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"f7508ecdfd1b76f8","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"747ac3c2114de916","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"5445e9650966f2c9","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"b701368b6964f28f","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"b8d4853208b3d665","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"a3c05ce1535a1bb0","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"4113e02fa7f80330","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"1ec6c8299f47c92d","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"6213db1c94ff78b4","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"afdce1f639f05293","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"c00800107f132ba6","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"f989cf5678a6cd73","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"7248d6bb2e2d2812","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"5decec320495d46c","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"ffffd176ae6095cd","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"a0ead46cc7797fc4","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"d1b36183709cf97c","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"f08e0f4d46762277","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"1082450fce471aec","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"0c44a72359ff962b","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"c6ced7239fa526b8","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"bcd4afcb16a1bf83","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"c4629483e0f61849","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"3a8a51dc5059eb82","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"10d4846e0b0f6213","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"8e03e96054cde307","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"d1c591453eeceb89","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"a9ee5e0b07924cbe","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"4909d0f68d7f7dd5","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"1954dcac7d36e9a9","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"855fab1b44b2cc38","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"9a977de69b69e767","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"32c7999b9a328d48","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"675aab76d51e4be4","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"454f35d478088b2f","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"af6f37ce228476e6","prefixes":{"*":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"dfa2565386557dbb","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"7bdee1b08b69b7fa","prefixes":{"*":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"259e3811976143d2","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"29633cedc9fc7e43","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"758fea4a1e3ad80f","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"cf9bd7435c526efc","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"913928e477b69d4d","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"391c770feaa49fc6","prefixes":{"":{"product":4}}}, // [Eulerian Technologies SARL]
+  {"hash":"9aea11673c37df0c","prefixes":{"*":{"product":225}}}, // [Ghostery Enterprise]
+  {"hash":"5efff70d6937c916","prefixes":{"*":{"product":226}}}, // [Experteer GmbH]
+  {"hash":"070f9075bd0072ca","prefixes":{"":{"product":227}}}, // [Action Allocator]
+  {"hash":"2a8c1779456949e3","prefixes":{"":{"product":228}}}, // [AdTraxx]
+  {"hash":"0d3994abeed42b53","prefixes":{"*":{"product":229}}}, // [eyeDemand]
+  {"hash":"f804a9a8eb6b2828","prefixes":{"*":{"product":230}}}, // [EyeReturn Marketing]
+  {"hash":"e7b16a7fe9d18804","prefixes":{"*":{"product":230}}}, // [EyeReturn Marketing]
+  {"hash":"9a826150ea3a7b3d","prefixes":{"*":{"product":231}}}, // [EyeView Inc.]
+  {"hash":"00f40aaf7abec691","prefixes":{"":{"product":232}}}, // [EyeView, Inc]
+  {"hash":"a47b1640e108c4e8","prefixes":{"":{"product":232}}}, // [EyeView, Inc]
+  {"hash":"73c2e89f340530ca","prefixes":{"*":{"product":233}}}, // [Eyewonder Inc.]
+  {"hash":"ab1869399e555ac8","prefixes":{"":{"product":234}}}, // [MLB Advanced Media, L.P.]
+  {"hash":"6792c3d3132bf7d7","prefixes":{"":{"product":234}}}, // [MLB Advanced Media, L.P.]
+  {"hash":"3d02d3a5042f5ad8","prefixes":{"":{"product":234}}}, // [MLB Advanced Media, L.P.]
+  {"hash":"c75b8641d2e585d7","prefixes":{"*":{"product":235}}}, // [Facilitate For Agencies (FFA)]
+  {"hash":"535ecf05ae26ef66","prefixes":{"*":{"product":235}}}, // [Facilitate For Agencies (FFA)]
+  {"hash":"2393220aafcd7f07","prefixes":{"*":{"product":235}}}, // [Facilitate For Agencies (FFA)]
+  {"hash":"ead2626488917d96","prefixes":{"*":{"product":235}}}, // [Facilitate For Agencies (FFA)]
+  {"hash":"82402af773d46078","prefixes":{"*":{"product":235}}}, // [Facilitate For Agencies (FFA)]
+  {"hash":"0afacf5097d4ca72","prefixes":{"*":{"product":236}}}, // [Flashtalking]
+  {"hash":"5215ee9300af8125","prefixes":{"":{"product":237}}}, // [Hostelworld.com Limited]
+  {"hash":"e8d6e54e3ce31711","prefixes":{"":{"product":238}}}, // [Knorex Pte. Ltd.]
+  {"hash":"a8ac5a522ae936d9","prefixes":{"":{"product":238}}}, // [Knorex Pte. Ltd.]
+  {"hash":"c88080a9090fa828","prefixes":{"":{"product":238}}}, // [Knorex Pte. Ltd.]
+  {"hash":"90727ba23e427206","prefixes":{"":{"product":238}}}, // [Knorex Pte. Ltd.]
+  {"hash":"d496e8a41b845c1e","prefixes":{"":{"product":238}}}, // [Knorex Pte. Ltd.]
+  {"hash":"e3463a0b0d9d0b84","prefixes":{"*":{"product":239}}}, // [Flite Inc.]
+  {"hash":"93eff417d773ad79","prefixes":{"*":{"product":239}}}, // [Flite Inc.]
+  {"hash":"48c727cb39130203","prefixes":{"*":{"product":239}}}, // [Flite Inc.]
+  {"hash":"1f8b889072fc177c","prefixes":{"*":{"product":240}}}, // [Forbes Media LLC]
+  {"hash":"830e0f5dd1181234","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"daf4edc7545d5166","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"f786c1dcc4eb883e","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"82534a9af0bc48e0","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"091c6487b80c3425","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"5250da9f53cd928c","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"9a8514c0fd5d6754","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"ad91bc98d2a8be55","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"91e5780ca48d75cc","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"481acfc271cd8a12","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"ef2a23dc677d8426","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"c6c8ce28b06bbda5","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"2bb2e1ea24146c0b","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"a0f3f5041ae3893c","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"4d6c5ce49301c775","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"747c952599211285","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"59f1e6a6110f9a68","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"f76895f67d1585b2","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"a2e125e235d1ffd4","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"17cbbfe7617725b3","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"1c118cc87c632e94","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"a48217ad66a56eb4","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"949fd73ca6fcc6f5","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"7d647d3164d8e6e2","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"e6d9d61b6785d883","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"aad9a81ea12d3c42","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"f0d9b5588abc50f9","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"dcb3db79fcab6476","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"1985d21c9c0b8366","prefixes":{"":{"product":242}}}, // [FreakOut Inc.]
+  {"hash":"a268d22dc85b4108","prefixes":{"*":{"product":243}}}, // [FreeWheel]
+  {"hash":"a796f300b3d2c84e","prefixes":{"*":{"product":244}}}, // [Fringe81 Inc.]
+  {"hash":"bb563c63d09f3d76","prefixes":{"":{"product":245}}}, // [Fringe81 - IBV]
+  {"hash":"c6ac10cc9ddfb3e7","prefixes":{"":{"product":245}}}, // [Fringe81 - IBV]
+  {"hash":"48983a0d5a27b120","prefixes":{"*":{"product":246}}}, // [FuseBox Inc.]
+  {"hash":"6f59caebdaac019e","prefixes":{"":{"product":246}}}, // [FuseBox Inc.]
+  {"hash":"8090c608651eca30","prefixes":{"*":{"product":247}}}, // [gemiusDirectEffect+]
+  {"hash":"e7b75209bd73a1d9","prefixes":{"*":{"product":248}}}, // [AdOcean Ltd]
+  {"hash":"24fb4ed27ae8cf88","prefixes":{"*":{"product":249}}}, // [Intomart GfK (GfK Daphne)]
+  {"hash":"91571a34ff0fcf44","prefixes":{"*":{"product":250}}}, // [Gigya]
+  {"hash":"bd66201f4f935a9d","prefixes":{"*":{"product":251}}}, // [Global Market Insite Inc.]
+  {"hash":"c0854a371610fbf2","prefixes":{"*":{"product":251}}}, // [Global Market Insite Inc.]
+  {"hash":"4a32fa997117f00d","prefixes":{"*":{"product":252},"":{"product":253}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
+  {"hash":"68d0356c33bd8ec4","prefixes":{"*":{"product":252},"":{"product":253}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
+  {"hash":"813ca9ac3483af55","prefixes":{"*":{"product":252},"":{"product":253}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
+  {"hash":"ee88383142da014d","prefixes":{"*":{"product":252},"":{"product":253}}}, // [DoubleClick Campaign Manager] [DoubleClick Bidder Pilot for Networks]
+  {"hash":"1332f3da43091ed3","prefixes":{"":{"product":252},"*":{"product":254}}}, // [DoubleClick Campaign Manager] [DoubleClick for Publishers Premium]
+  {"hash":"f04082d14282d452","prefixes":{"":{"product":252}}}, // [DoubleClick Campaign Manager]
+  {"hash":"c6ad6c580aef6ce5","prefixes":{"":{"product":252}}}, // [DoubleClick Campaign Manager]
+  {"hash":"642706b0b0335500","prefixes":{"":{"product":252}}}, // [DoubleClick Campaign Manager]
+  {"hash":"baea954b95731c68","prefixes":{"*":{"product":255}}}, // [Google CDN]
+  {"hash":"8e23699963552b18","prefixes":{"*":{"product":252}}}, // [DoubleClick Campaign Manager]
+  {"hash":"bafedfe69ed92305","prefixes":{"*":{"product":253}}}, // [DoubleClick Bidder Pilot for Networks]
+  {"hash":"f2b999c597cd97af","prefixes":{"*":{"product":253}}}, // [DoubleClick Bidder Pilot for Networks]
+  {"hash":"66399889a04f9513","prefixes":{"cdn":{"product":256},"ads":{"product":256},"db":{"product":256},"img":{"product":256},"ssl":{"product":256}}}, // [GroovinAds] [GroovinAds] [GroovinAds] [GroovinAds] [GroovinAds]
+  {"hash":"ea8510cdf6991d43","prefixes":{"":{"product":256}}}, // [GroovinAds]
+  {"hash":"fc2e03aac9426552","prefixes":{"":{"product":257}}}, // [Reddion]
+  {"hash":"6db39bcc7e0f7fed","prefixes":{"":{"product":258}}}, // [HQ GmbH]
+  {"hash":"4de0590ca954b13b","prefixes":{"*":{"product":259}}}, // [Performance Display Advertising]
+  {"hash":"44f4a1b16ff856e5","prefixes":{"":{"product":5}}}, // [Conversant Ad Server]
+  {"hash":"127f97cfaedd763a","prefixes":{"":{"product":5}}}, // [Conversant Ad Server]
+  {"hash":"508035bfa2d95844","prefixes":{"*":{"product":5}}}, // [Conversant Ad Server]
+  {"hash":"6ea225859ddfba18","prefixes":{"*":{"product":5}}}, // [Conversant Ad Server]
+  {"hash":"600a5a5f53775d42","prefixes":{"*":{"product":216}}}, // [DoubleVerify Inc.]
+  {"hash":"cabba15c5ee8f039","prefixes":{"*":{"product":260}}}, // [Avazu Inc.]
+  {"hash":"ec98881ed60ffe62","prefixes":{"":{"product":91}}}, // [ADTECH GmbH]
+  {"hash":"b1e5dca23b928251","prefixes":{"":{"product":91}}}, // [ADTECH GmbH]
+  {"hash":"87e919d72e293303","prefixes":{"*":{"product":261}}}, // [Aerify Media]
+  {"hash":"652d7fe0079512a8","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"8e1afef4fbf079f4","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"3f697fb2c06659ac","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"cb5ae4cc94e8cb57","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"3cd44a0f52d69fed","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"fd87dfe8678e2630","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"274e4476c8fbfe0c","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"e3f56a006c4f8fc8","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"11d582be18893073","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"54768ce9ed6664fc","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"6de580016869f523","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"7fc8a77e5f366b6d","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"06838afa0ce9cde5","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"d788f92161d75b72","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"bd27e9c073c7b133","prefixes":{"":{"product":262}}}, // [IClick Interactive Ltd.]
+  {"hash":"71096991891dc36f","prefixes":{"*":{"product":263}}}, // [iCrossing]
+  {"hash":"0a48c6448ca1af83","prefixes":{"":{"product":263}}}, // [iCrossing]
+  {"hash":"23cce2ff5ce35111","prefixes":{"*":{"product":264}}}, // [Impact Engine Inc.]
+  {"hash":"b63329d63303bcac","prefixes":{"*":{"product":265}}}, // [Inadco Inc.]
+  {"hash":"9dab6f7b066953b6","prefixes":{"":{"product":265}}}, // [Inadco Inc.]
+  {"hash":"83efdfb00e5e0bb5","prefixes":{"":{"product":266}}}, // [Innity Singapore Pte Ltd.]
+  {"hash":"5cdf5c58d4a95757","prefixes":{"":{"product":266}}}, // [Innity Singapore Pte Ltd.]
+  {"hash":"e84e4c75279b444c","prefixes":{"":{"product":266}}}, // [Innity Singapore Pte Ltd.]
+  {"hash":"0ad278b0f1bf83c7","prefixes":{"":{"product":267}}}, // [Insight Express (Cross Media - Ignite)]
+  {"hash":"75089fef153b99d9","prefixes":{"":{"product":267}}}, // [Insight Express (Cross Media - Ignite)]
+  {"hash":"17e48170b29e8c55","prefixes":{"":{"product":268}}}, // [intelliAd Media GmbH]
+  {"hash":"8ff3a159f3a3dd37","prefixes":{"":{"product":268}}}, // [intelliAd Media GmbH]
+  {"hash":"d5ad6ce37d416c20","prefixes":{"":{"product":268}}}, // [intelliAd Media GmbH]
+  {"hash":"829116e73bbd766e","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"58b6a73b811a6744","prefixes":{"":{"product":268}}}, // [intelliAd Media GmbH]
+  {"hash":"1b02753d1ebc5935","prefixes":{"":{"product":270}}}, // [Intelliad]
+  {"hash":"2d4767b28a0a3dc9","prefixes":{"":{"product":270}}}, // [Intelliad]
+  {"hash":"04e4138ad91eba43","prefixes":{"*":{"product":271}}}, // [Genome]
+  {"hash":"a80259001a08f5fe","prefixes":{"":{"product":271}}}, // [Genome]
+  {"hash":"bccc7d85fcbd6406","prefixes":{"*":{"product":272}}}, // [Intergi LLC dba PlaywireMedia]
+  {"hash":"c0e12f3f6483d539","prefixes":{"":{"product":273}}}, // [Intermundo Media LLC]
+  {"hash":"aa0d2346396993dc","prefixes":{"*":{"product":274}}}, // [Interpolls]
+  {"hash":"391f02c89579c41e","prefixes":{"*":{"product":275}}}, // [Intelligent Reach (Intuitive Search Technologies)]
+  {"hash":"dd7ece8c8b4dd4db","prefixes":{"*":{"product":275}}}, // [Intelligent Reach (Intuitive Search Technologies)]
+  {"hash":"51beebfd5a677c74","prefixes":{"":{"product":275}}}, // [Intelligent Reach (Intuitive Search Technologies)]
+  {"hash":"15a557d1be0b55bc","prefixes":{"*":{"product":276}}}, // [IPONWEB Limited]
+  {"hash":"ab800ebb45ab5e96","prefixes":{"":{"product":276}}}, // [IPONWEB Limited]
+  {"hash":"cf6003cf8be11c49","prefixes":{"*":{"product":276}}}, // [IPONWEB Limited]
+  {"hash":"bd97f2dac673ccef","prefixes":{"*":{"product":277}}}, // [JasperLabs Inc.]
+  {"hash":"833a1bb3e47002bf","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"925afb63a81d22ae","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"e3546ee6177ce1af","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"a6e81a993b0dc090","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"57cf72a6bcc6ed09","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"aef508a87f7b9342","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"a1a0984cf6e12596","prefixes":{"":{"product":278}}}, // [Jivox Corporation]
+  {"hash":"c1b82a9e7564881f","prefixes":{"*":{"product":279}}}, // [Joinville AB]
+  {"hash":"e20dd6e83cbd14d9","prefixes":{"":{"product":280}}}, // [KliKKicom Oy]
+  {"hash":"a1f03f455fc97850","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"fb87830648f1fe7c","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"93a6bcd7660ef88b","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"14fba951393c4cc1","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"96bf72901db53556","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"00ceea10fed6f827","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"5deb6288aeb4b20d","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"30a9e5cf761c2db9","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"b49fda322943ed64","prefixes":{"":{"product":281}}}, // [Komli Media Inc.]
+  {"hash":"30067241c16c9f88","prefixes":{"*":{"product":282}}}, // [Koninklijke Luchtvaart Maatschappij N.V.]
+  {"hash":"06076b672be3af43","prefixes":{"*":{"product":283}}}, // [J.D. Power O2O]
+  {"hash":"1e23ff61443f919a","prefixes":{"*":{"product":284}}}, // [Kwanzoo Inc.]
+  {"hash":"32327b1f6a21f5e3","prefixes":{"":{"product":285}}}, // [Legolas Media Inc.]
+  {"hash":"0a98bd3ecf6d4f39","prefixes":{"":{"product":285}}}, // [Legolas Media Inc.]
+  {"hash":"4141a8162aadd52a","prefixes":{"":{"product":285}}}, // [Legolas Media Inc.]
+  {"hash":"9562185c6a06e194","prefixes":{"*":{"product":286}}}, // [Undertone Ad System (UAS)]
+  {"hash":"d8be1c121ccbdb84","prefixes":{"":{"product":287}}}, // [LEVEL Studios]
+  {"hash":"1b274516ac601c1d","prefixes":{"*":{"product":288}}}, // [LinkedIn Corporation]
+  {"hash":"a9aceb9b28670518","prefixes":{"*":{"product":288}}}, // [LinkedIn Corporation]
+  {"hash":"f202e32e7503e766","prefixes":{"":{"product":288}}}, // [LinkedIn Corporation]
+  {"hash":"cf2094771b42b367","prefixes":{"*":{"product":288}}}, // [LinkedIn Corporation]
+  {"hash":"ad94f98bfc0092ce","prefixes":{"*":{"product":289}}}, // [Content Directions, Inc. dba Linkstorm]
+  {"hash":"2c97a2e1f7f59cde","prefixes":{"*":{"product":290}}}, // [Liverail Inc.]
+  {"hash":"562dd0a17776cfc3","prefixes":{"*":{"product":291}}}, // [Lotame Solutions Inc.]
+  {"hash":"85c409cdb78a6fec","prefixes":{"*":{"product":292}}}, // [LucidMedia Networks Inc.]
+  {"hash":"25cdc372f14aa636","prefixes":{"":{"product":293}}}, // [Magnetic Media Online Inc.]
+  {"hash":"490a692feb4f5f83","prefixes":{"":{"product":293}}}, // [Magnetic Media Online Inc.]
+  {"hash":"8cd182ca413a6770","prefixes":{"":{"product":293}}}, // [Magnetic Media Online Inc.]
+  {"hash":"891ff79862603ca1","prefixes":{"*":{"product":294}}}, // [Mate1.com]
+  {"hash":"ae4598324ee10cb2","prefixes":{"":{"product":295}}}, // [MaxPoint Interactive Inc.]
+  {"hash":"66eafecb064a6d3f","prefixes":{"*":{"product":296}}}, // [Media Armor Inc.]
+  {"hash":"d9921090d75b28f3","prefixes":{"*":{"product":297}}}, // [Xaxis, Inc]
+  {"hash":"4c897372b3205c67","prefixes":{"*":{"product":298}}}, // [Dstillery]
+  {"hash":"78172051b147ff71","prefixes":{"*":{"product":298}}}, // [Dstillery]
+  {"hash":"3e32e501635bb994","prefixes":{"*":{"product":299}}}, // [Rakuten MediaForge]
+  {"hash":"ab3637f7ff19f3be","prefixes":{"*":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"eacb348c2bfde7c6","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"6ec884dc33afd8e3","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"6a0b44c268e0ea34","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"5ec2ba6f16455240","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"f6a166105958340d","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"1bafa194e1b43948","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"c4c10492cf3f1e5c","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"fb29996f4dbe86a3","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"33cba419c0d99c36","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"1471e355753e333a","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"8445471e74aaf1ad","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"fe448fc8fa6792c7","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"7142d0f7c95e6c11","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"f71e7939a3a06b85","prefixes":{"":{"product":300}}}, // [Sizmek]
+  {"hash":"25c9493f4ceef0b3","prefixes":{"*":{"product":300}}}, // [Sizmek]
+  {"hash":"1c0486f5c9ddccc1","prefixes":{"":{"product":301}}}, // [MediaMind]
+  {"hash":"511f53552d7c07f9","prefixes":{"*":{"product":302}}}, // [Paypal]
+  {"hash":"c23b8169e8d6f935","prefixes":{"*":{"product":302}}}, // [Paypal]
+  {"hash":"4cb72fa17c1e6b21","prefixes":{"*":{"product":303}}}, // [ZEDO Inc.]
+  {"hash":"1f5866beb3a2da29","prefixes":{"":{"product":304}}}, // [Contobox]
+  {"hash":"ab4011df7412e85a","prefixes":{"":{"product":304}}}, // [Contobox]
+  {"hash":"4c55c99f7e731e4a","prefixes":{"":{"product":304}}}, // [Contobox]
+  {"hash":"b32dad95de4864bb","prefixes":{"":{"product":304}}}, // [Contobox]
+  {"hash":"e0636cdabf7592eb","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"9e011383339e65c3","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"c7f6b97c8a7defa6","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"ba29743e534631a5","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"df986bbd43ef130c","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"32e39349c0434e31","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"4b920fabf61fd6f3","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"068f3a0cd7e03112","prefixes":{"":{"product":305}}}, // [Melt Tecnologia e Informatica S.A]
+  {"hash":"95cce4f80c49239f","prefixes":{"*":{"product":306}}}, // [MeMo2 / Hottraffic]
+  {"hash":"7672c0e258e0a20b","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"065ac7f58737b759","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"f0c15855e3418345","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"45068fe6a5fe83c0","prefixes":{"*":{"product":308}}}, // [Mercado Livre.com Atividades de Internet Ltda]
+  {"hash":"a3fbfa83663a40a6","prefixes":{"*":{"product":308}}}, // [Mercado Livre.com Atividades de Internet Ltda]
+  {"hash":"5241d2ae86ff307f","prefixes":{"":{"product":309}}}, // [Merchenta Limited]
+  {"hash":"7b92690c1232eb23","prefixes":{"":{"product":309}}}, // [Merchenta Limited]
+  {"hash":"e5b1a15c3a7a1ee6","prefixes":{"":{"product":309}}}, // [Merchenta Limited]
+  {"hash":"f0b40488d9ecd9a2","prefixes":{"":{"product":309}}}, // [Merchenta Limited]
+  {"hash":"63600c9242f10b0d","prefixes":{"":{"product":309}}}, // [Merchenta Limited]
+  {"hash":"e89e81c1ed314cc1","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"297f0571158ef576","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"2228e5ce36c007c1","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"798bcbf9415873df","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"ab03f3b496037843","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"eca01f0508fbf30b","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"0d839898fade319a","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"4fc010b1e52ce252","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"31e7fb81bf0ec52f","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"a6edfa074ceff9c5","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"289dc75a912dcc97","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"5a8de8926c410758","prefixes":{"":{"product":310}}}, // [Metapeople GmbH]
+  {"hash":"79c798a9d8e32afc","prefixes":{"":{"product":311}}}, // [MetrixLab B.V.]
+  {"hash":"61617058e6206283","prefixes":{"":{"product":311}}}, // [MetrixLab B.V.]
+  {"hash":"cf945767a2fa79f3","prefixes":{"*":{"product":312}}}, // [Mixpo Inc.]
+  {"hash":"541f85cbc710f2b3","prefixes":{"":{"product":313}}}, // [Monsoon Ads Pvt. Ltd.]
+  {"hash":"c800e798e160fe89","prefixes":{"*":{"product":314}}}, // [Monster]
+  {"hash":"775035c4c49057eb","prefixes":{"":{"product":314}}}, // [Monster]
+  {"hash":"2a26221290e24a08","prefixes":{"":{"product":314}}}, // [Monster]
+  {"hash":"fda966b5c6ec2b2f","prefixes":{"":{"product":314}}}, // [Monster]
+  {"hash":"887d148a8ae98b2e","prefixes":{"*":{"product":315}}}, // [neckermann.de GmbH]
+  {"hash":"35c76c9165e3349f","prefixes":{"*":{"product":316}}}, // [Ad.agio]
+  {"hash":"d5c7d1240bf8989e","prefixes":{"":{"product":316}}}, // [Ad.agio]
+  {"hash":"1e5ea56690a0716d","prefixes":{"*":{"product":316}}}, // [Ad.agio]
+  {"hash":"a54661777ef51189","prefixes":{"*":{"product":317}}}, // [Netmining LLC]
+  {"hash":"cc673c90c8abe830","prefixes":{"*":{"product":318}}}, // [AdoTube]
+  {"hash":"5f4b0cbb95552b3f","prefixes":{"*":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"a78e1096b3c03fbc","prefixes":{"":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"582d973b69391ebe","prefixes":{"":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"18585076a5b0c6dd","prefixes":{"":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"1df4ee86fc680406","prefixes":{"":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"ecd80a6a46f6a1ce","prefixes":{"":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"8ee876aaaaf537e0","prefixes":{"":{"product":319}}}, // [Next Audience GmbH]
+  {"hash":"92bc4f011133f05a","prefixes":{"*":{"product":320}}}, // [Nextperf]
+  {"hash":"b10d35d6cde76082","prefixes":{"*":{"product":320}}}, // [Nextperf]
+  {"hash":"8e6e5d6dc4720f98","prefixes":{"":{"product":320}}}, // [Nextperf]
+  {"hash":"edc7f4e87a8ea4a3","prefixes":{"":{"product":320}}}, // [Nextperf]
+  {"hash":"f0c76e07985c56c5","prefixes":{"":{"product":320}}}, // [Nextperf]
+  {"hash":"cff1b3137482e5e3","prefixes":{"":{"product":320}}}, // [Nextperf]
+  {"hash":"33f28c5ebbd4525e","prefixes":{"":{"product":320}}}, // [Nextperf]
+  {"hash":"849c8324d4c32ea5","prefixes":{"*":{"product":321}}}, // [Calibex]
+  {"hash":"0bbcc61ed60a63c7","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"7da7b69cf130f867","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"524bf7ee34882325","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"0fc0858e8d42a096","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"94d1d06666f458b2","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"9515f9226eae0ee6","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"c610850a50287c6c","prefixes":{"":{"product":322}}}, // [ViziAds for Advertisers]
+  {"hash":"1324d12fd047205a","prefixes":{"":{"product":322}}}, // [ViziAds for Advertisers]
+  {"hash":"922df75b11e4bdb8","prefixes":{"":{"product":322}}}, // [ViziAds for Advertisers]
+  {"hash":"94be9a0ad636acc1","prefixes":{"":{"product":322}}}, // [ViziAds for Advertisers]
+  {"hash":"921f858655989bdb","prefixes":{"":{"product":322}}}, // [ViziAds for Advertisers]
+  {"hash":"0f44f6f2024007e3","prefixes":{"":{"product":323}}}, // [FinanceGenerator]
+  {"hash":"c5d545736ea3f40c","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"c5190fb3c11efd5c","prefixes":{"":{"product":324}}}, // [Telstra Corporation]
+  {"hash":"f8e19bba6ecb9d4d","prefixes":{"":{"product":324}}}, // [Telstra Corporation]
+  {"hash":"78cb9e34e18a70c6","prefixes":{"":{"product":324}}}, // [Telstra Corporation]
+  {"hash":"555b77a6dbc1077b","prefixes":{"":{"product":324}}}, // [Telstra Corporation]
+  {"hash":"04cd318d8c9e0aa1","prefixes":{"":{"product":325}}}, // [The Online Research Unit]
+  {"hash":"44b28a9d35489468","prefixes":{"":{"product":326}}}, // [Webling Pty Ltd]
+  {"hash":"ce2a97a2bc3975b0","prefixes":{"*":{"product":327}}}, // [Lasoo Pty Ltd]
+  {"hash":"70c03e717046730c","prefixes":{"":{"product":327}}}, // [Lasoo Pty Ltd]
+  {"hash":"a1956c55f379362a","prefixes":{"":{"product":327}}}, // [Lasoo Pty Ltd]
+  {"hash":"78761e0920b86d00","prefixes":{"":{"product":327}}}, // [Lasoo Pty Ltd]
+  {"hash":"fb49a17ebf575b4b","prefixes":{"":{"product":327}}}, // [Lasoo Pty Ltd]
+  {"hash":"3ba767e322876167","prefixes":{"":{"product":327}}}, // [Lasoo Pty Ltd]
+  {"hash":"db60b4edeb07e6e0","prefixes":{"*":{"product":328}}}, // [Salefinder Ltd.]
+  {"hash":"1a2b2619e15f81ed","prefixes":{"":{"product":329}}}, // [The Monkeys Pty Ltd]
+  {"hash":"d33c5423234580d2","prefixes":{"":{"product":330}}}, // [Louder Digital Pty Ltd]
+  {"hash":"35c305dfff8e956a","prefixes":{"":{"product":331}}}, // [Publisher’s Internationale Pty Ltd]
+  {"hash":"ab95fd39f34e1919","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"e394eac0c09e952a","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"d754759cedf098a4","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"469abb509832dcba","prefixes":{"":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"089ade7154cdafd2","prefixes":{"":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"7c4e77c7146bc27c","prefixes":{"":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"27943a61af56578c","prefixes":{"":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"5b9d47d01e06e207","prefixes":{"":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"efae037999b8354a","prefixes":{"":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"64b1c22f19588e65","prefixes":{"*":{"product":7}}}, // [Wize Commerce, Inc.]
+  {"hash":"1b500703c376dccf","prefixes":{"":{"product":332}}}, // [NowSpots]
+  {"hash":"0b8a5111da2a18e6","prefixes":{"":{"product":332}}}, // [NowSpots]
+  {"hash":"6cbd63b4b5a258e2","prefixes":{"":{"product":333}}}, // [Ocapi]
+  {"hash":"2ecb3e4de562d83f","prefixes":{"*":{"product":334}}}, // [Predicta]
+  {"hash":"b0032d1f28de6b8e","prefixes":{"*":{"product":334}}}, // [Predicta]
+  {"hash":"495b10f97369710c","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"07b876ce04abdfc9","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"bd1d888d58054387","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"deb9a6a0e78770f8","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"3d9897472cebdff7","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"a036e7b2680b1720","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"ae8e27c2a1195c9d","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"685a4ece024544f3","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"d705e49e2ecfc500","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"4fd0a4a032a34191","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"2640f60d445d4d0d","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"0067af133fbf162f","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"62e23e8e0a53b097","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"57643f79e10fdc91","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"fe70aef371b87e0d","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"c80b88907c4da662","prefixes":{"":{"product":335}}}, // [Comune SA]
+  {"hash":"3c027bef12167411","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"9e7ef06636d0b122","prefixes":{"":{"product":337}}}, // [Hotwords Informação LTDA]
+  {"hash":"ac577d2ba001c2f9","prefixes":{"":{"product":337}}}, // [Hotwords Informação LTDA]
+  {"hash":"8baa23f77cec98d3","prefixes":{"":{"product":337}}}, // [Hotwords Informação LTDA]
+  {"hash":"86e7352358e7a0a1","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"461a9aacd5db8b62","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"4523c8dd39cb10d8","prefixes":{"":{"product":338}}}, // [uMotion]
+  {"hash":"a7eaf4ae4152200d","prefixes":{"":{"product":338}}}, // [uMotion]
+  {"hash":"1874ed5aa610db51","prefixes":{"*":{"product":339}}}, // [Google Zoo]
+  {"hash":"0dc9eb6c8b1c77fa","prefixes":{"*":{"product":35}}}, // [Oggifinogi]
+  {"hash":"60d67cd6819e7de4","prefixes":{"*":{"product":340}}}, // [Audience Manager]
+  {"hash":"2ae524eac16b06f8","prefixes":{"":{"product":341}}}, // [ONDCP]
+  {"hash":"8210c1a27bdc1916","prefixes":{"*":{"product":143}}}, // [Edgesuite]
+  {"hash":"ca8cb9c623002dc9","prefixes":{"*":{"product":143}}}, // [Edgesuite]
+  {"hash":"3ba6cc7216a7d5ae","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"24267a212835b827","prefixes":{"*":{"product":143}}}, // [Edgesuite]
+  {"hash":"060ee4c312a8e977","prefixes":{"":{"product":342}}}, // [LOKA Research inc.]
+  {"hash":"c7e974006ec125b7","prefixes":{"*":{"product":343}}}, // [OpenX OnRamp]
+  {"hash":"a985fc121086ead8","prefixes":{"*":{"product":344}}}, // [OpenX Ad Server]
+  {"hash":"402ca9fbb308a1c5","prefixes":{"*":{"product":36}}}, // [PaperG]
+  {"hash":"53f1cd9b06aea643","prefixes":{"*":{"product":36}}}, // [PaperG]
+  {"hash":"36b3ccfb92c2fb71","prefixes":{"*":{"product":345}}}, // [Parship]
+  {"hash":"28832d626c0b0925","prefixes":{"*":{"product":346}}}, // [pauldirekt GmbH]
+  {"hash":"1d474301c170499d","prefixes":{"*":{"product":347}}}, // [Pictela Inc.]
+  {"hash":"fd1aa96507b2bf44","prefixes":{"":{"product":347}}}, // [Pictela Inc.]
+  {"hash":"7f890c0fd0c6a4d9","prefixes":{"":{"product":348}}}, // [Pilot 1/0 GmbH & Co KG]
+  {"hash":"549e294957d756d8","prefixes":{"":{"product":348}}}, // [Pilot 1/0 GmbH & Co KG]
+  {"hash":"5dc046f77f32adf1","prefixes":{"*":{"product":349}}}, // [Piximedia]
+  {"hash":"637b449ba51266a3","prefixes":{"*":{"product":349}}}, // [Piximedia]
+  {"hash":"013ba3dd6b18ee4a","prefixes":{"*":{"product":350}}}, // [Pointroll]
+  {"hash":"d96024cf9bafa9d0","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"4f0c9093d18b4ecd","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"d63f961e0c8cc056","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"1bcfb023adee2b08","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"6ed6fb838bd994d7","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"9fd07c030d45578d","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"5370f7b026779f44","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"c367910d58376fa0","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"670926f337b85492","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"77d7124c8aa87819","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"3726ef9236aeff59","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"84078980dc7d0310","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"496666ed92d32be6","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"3e8a19db4e7dd91a","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"33cfdc955bd4ab90","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"543046798ae8e38d","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"54537a7d4ce6fc35","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"242ab5d44fae500c","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"e81d4aa82d04d068","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"7c7f55d8a75cb9bc","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"e4a82caa59141478","prefixes":{"":{"product":351}}}, // [Beijing PinYou Interactive Information Technology]
+  {"hash":"caf06dc269e4cbd7","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"70584cd7bcb88744","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"c9cabfef49bb4ec1","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"993089a2d306632e","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"cf04aaaa5ae5f383","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"a1cd6a668ae89bc8","prefixes":{"*":{"product":353}}}, // [AdMaster]
+  {"hash":"f72dd5293eba3ca3","prefixes":{"":{"product":353}}}, // [AdMaster]
+  {"hash":"e946e6b718e0e81a","prefixes":{"":{"product":353}}}, // [AdMaster]
+  {"hash":"01b5e469f3b6d1d9","prefixes":{"":{"product":354}}}, // [D.A.Consortium Beijing (Platform One China)]
+  {"hash":"f091b3175305cced","prefixes":{"":{"product":354}}}, // [D.A.Consortium Beijing (Platform One China)]
+  {"hash":"1a095d1901f0940b","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"f66f99ee20105c2c","prefixes":{"*":{"product":356}}}, // [PurposeLab]
+  {"hash":"86c250cf0da31481","prefixes":{"":{"product":356}}}, // [PurposeLab]
+  {"hash":"8f204c79d6b23736","prefixes":{"*":{"product":334}}}, // [Predicta]
+  {"hash":"43d06db6d6527876","prefixes":{"":{"product":357}}}, // [Proclivity Systems]
+  {"hash":"5f76990173953807","prefixes":{"":{"product":357}}}, // [Proclivity Systems]
+  {"hash":"7d3947ee9533bf30","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"fb241396adc3ebde","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"b8c5f46fb8945332","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"ade9cbc2becb390f","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"874cfa4e9fe27233","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"2cd6bee614e910f1","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"854f37cd1f444e62","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"19a83c7a2b673a6d","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"ca312e078723d178","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"4aa2d41fa2878d8f","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"8931cc3c2d6bbbff","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"e67e88dcc0afe050","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"3f6c08baf48fa0ae","prefixes":{"":{"product":37}}}, // [Public-Idées]
+  {"hash":"6303a58061eaabd1","prefixes":{"*":{"product":358}}}, // [Viewbix]
+  {"hash":"4fdc8f2ff122ce2e","prefixes":{"":{"product":358}}}, // [Viewbix]
+  {"hash":"ba78a984ad7a8c06","prefixes":{"":{"product":358}}}, // [Viewbix]
+  {"hash":"00885ce869b93eab","prefixes":{"":{"product":358}}}, // [Viewbix]
+  {"hash":"eb59f3a64b415670","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"243c70f61da9731c","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"ed6b204d6b8f351e","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"e6888b5be4ecca23","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"8034327c12c77172","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"d48f950e0036e4ee","prefixes":{"*":{"product":360}}}, // [QuinStreet]
+  {"hash":"6118e4e0e4001349","prefixes":{"*":{"product":361}}}, // [Quisma GmbH]
+  {"hash":"1b2f3dadf0889c1c","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"491acc9692437dcc","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"95be38e789f1c074","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"7d13c9a93867cfd5","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"aee8b719a85b0392","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"03c0d3572439e910","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"42c10737e9d2eb44","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"1ece70926dbb1e9c","prefixes":{"*":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"15b1b56db686d6b8","prefixes":{"":{"product":362}}}, // [Quismatch / Quisma Tracker]
+  {"hash":"6f2fb017c596785a","prefixes":{"*":{"product":363}}}, // [Qwobl Inc.]
+  {"hash":"45bd1c4bac827eb4","prefixes":{"*":{"product":364}}}, // [RadiumOne Inc.]
+  {"hash":"a4cc28a873663be4","prefixes":{"*":{"product":365}}}, // [Core Audience, Inc]
+  {"hash":"b1b347108c9875ae","prefixes":{"*":{"product":366}}}, // [The Reach Group]
+  {"hash":"9680c32132a31294","prefixes":{"":{"product":367}}}, // [revenue cloud]
+  {"hash":"4654f1b3d29f0a2a","prefixes":{"":{"product":367}}}, // [revenue cloud]
+  {"hash":"c8daf5a2befc762c","prefixes":{"":{"product":367}}}, // [revenue cloud]
+  {"hash":"cd7c04dcaab54cf3","prefixes":{"":{"product":366}}}, // [The Reach Group]
+  {"hash":"6a7ac3b20a8267da","prefixes":{"*":{"product":368}}}, // [Register.it]
+  {"hash":"24064a7ef37c0464","prefixes":{"":{"product":369}}}, // [ReleStar]
+  {"hash":"28a4e40561f9acae","prefixes":{"":{"product":369}}}, // [ReleStar]
+  {"hash":"3de1987cea55e4a5","prefixes":{"":{"product":369}}}, // [ReleStar]
+  {"hash":"827fd98c61df481c","prefixes":{"":{"product":369}}}, // [ReleStar]
+  {"hash":"eec1a8a2a7fb129b","prefixes":{"":{"product":369}}}, // [ReleStar]
+  {"hash":"6c1b7209cced7033","prefixes":{"*":{"product":370}}}, // [Research Horizons LLC dba Phoenix Marketing]
+  {"hash":"c946c0fe5eecd55f","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"2feb43f5f97da585","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"4847977384b78f1d","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"308241d0fe4d6897","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"2cb30990aa0823eb","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"2c25ebde178886b1","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"d4eeb4a4736e8358","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"12498108d00bd104","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"c7437019688a5c87","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"ebc599442a1e60e0","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"ab9c2a8a5ed26375","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"c9473e1a1e9213bc","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"a15bca05fb29201f","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"8c2336c1a87e9c7e","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"67f7079b53ce160f","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"a07c7ea743bca71c","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"ce0849726cb792fb","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"6d2feeb6316bf983","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"056132328ebc8a3b","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"c0dd251eb151bbdd","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"02e6b230a73d95aa","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"62cef89124c9831e","prefixes":{"*":{"product":8}}}, // [Research Now Limited]
+  {"hash":"1bb2fad94e9dfd9e","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"0bca341ab2881187","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"fb725c5783121bc4","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"6d442fcb13dbd9da","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"6020c585ae546ba6","prefixes":{"":{"product":8}}}, // [Research Now Limited]
+  {"hash":"bf994d767fc23e27","prefixes":{"":{"product":371}}}, // [Retention Media Inc.]
+  {"hash":"5c801bba74bf0884","prefixes":{"":{"product":372}}}, // [Suite 66]
+  {"hash":"f727f4c8af36c75c","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"d0ffa461035bdf6a","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"f1381513cbb99bf4","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"2b675a4d048f6d58","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"ff9153951d29d7eb","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"9a2d88a64367054f","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"22fc5e00cc71b2ca","prefixes":{"":{"product":373}}}, // [Dynamic Logic / Safecount (AdIndex)]
+  {"hash":"d680287680a3b47b","prefixes":{"*":{"product":374}}}, // [BridgeTrack]
+  {"hash":"6659ffe0ec0db1a1","prefixes":{"*":{"product":375}}}, // [adnanny.com GmbH]
+  {"hash":"cdef303f827a483a","prefixes":{"":{"product":375}}}, // [adnanny.com GmbH]
+  {"hash":"d37d706078f5ef0e","prefixes":{"":{"product":375}}}, // [adnanny.com GmbH]
+  {"hash":"cefa23f603f78274","prefixes":{"":{"product":375}}}, // [adnanny.com GmbH]
+  {"hash":"9beed54a2448f091","prefixes":{"*":{"product":376}}}, // [AdRoll]
+  {"hash":"131ff02cd8b2b585","prefixes":{"*":{"product":377}}}, // [AdExtent]
+  {"hash":"7b03a999ce62649a","prefixes":{"*":{"product":377}}}, // [AdExtent]
+  {"hash":"d888444955526bb9","prefixes":{"*":{"product":378}}}, // [ShareThis Inc.]
+  {"hash":"24bedaecde8de52e","prefixes":{"*":{"product":379}}}, // [Shirtinator]
+  {"hash":"b2227832d5aab97c","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"29d1a1af90fe4764","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"55d58888ac21e28e","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"15a0a565c098bb6c","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"c740f7042a936f94","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"83b6131729d98b9a","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"df61075a3761234c","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"31d664b6a0c86fc5","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"b3f1fda5ca08f66c","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"a505bd8c5fdbe348","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"ff4b6ade85c0fa47","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"55fbb05b573abfc0","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"7509d096b740a94e","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"3e05ad70e7b857f6","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"f3122b05b916b4d8","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"7df77439ca0af167","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"7b6f3b92d848f180","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"c50b3a11c75c1de2","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"42bd2bd016c36072","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"d964e110e03add5e","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"b2f31dc5aea81475","prefixes":{"":{"product":380}}}, // [Simplifi Holdings Inc.]
+  {"hash":"fd3e5505c689b1bc","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"e21937d0011ae5da","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"0f5e4a0353dbf996","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"0ece74eb8682685e","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"3d8ea3f0d5d389d5","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"b5602307e99e9538","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"c13decc96884eb9a","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"b815964fd4b63ffe","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"a49f2db509757639","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"a3ff80b45a2b0087","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"b1b2c1399cbf19be","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"ba44917903f4a6c0","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"ad5130e5aa2d0bcd","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"ceb371583c3948ee","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"5d5d4fe496a7b543","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"30e80084c1e7285e","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"d1d0fc6a034973b5","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"e2814abcd5399a68","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"9d4acd34336a73d4","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"dcbf7d7841f88317","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"c19fe37a92d8a1f4","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"dd502cbc700beb03","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"a76947b64ea18232","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"75875c5fcc471f0e","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"5323dbf9f56befc9","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"fd3df839224700c5","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"dc544506e0acf31c","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"fbadeeb25ac766a9","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"f344fa72c3acea98","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"e0d1929f5490ba3c","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"150d5c444034d16f","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"63c9992c37df81e6","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"9a2f65999a2602e7","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"b13d21bc9d60e3cf","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"36778688c2c8550d","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"7764641665318d7a","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"137839bac6b52f11","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"75b17e7427d84ec0","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"f576b8f6b5698927","prefixes":{"":{"product":381}}}, // [Centro DSP]
+  {"hash":"a0bef488713fd8ba","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"c4f4b5d7a3bc8772","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"652de2e0257cc6f9","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"e1eb84d2322dd53f","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"0759e6e60e23806b","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"b97f9d3a0092f5df","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"6f7d322aac5f6093","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"d6d2092af97f6672","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"700b4497422246d3","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"24758e00974c4842","prefixes":{"*":{"product":382}}}, // [Smart Adserver]
+  {"hash":"229fb1e217ec3254","prefixes":{"*":{"product":382}}}, // [Smart Adserver]
+  {"hash":"24f84ec66db45f3d","prefixes":{"":{"product":383}}}, // [smartclip Holding AG]
+  {"hash":"7bce0d8d711753ea","prefixes":{"":{"product":383}}}, // [smartclip Holding AG]
+  {"hash":"f748f5ce8e9c4b7d","prefixes":{"*":{"product":384}}}, // [Snap Technologies Inc.]
+  {"hash":"c17d7dedc318749c","prefixes":{"":{"product":385}}}, // [So-net Media Networks]
+  {"hash":"d3a65eea99debc9b","prefixes":{"":{"product":385}}}, // [So-net Media Networks]
+  {"hash":"f28c7fc4a06bcfa7","prefixes":{"*":{"product":386}}}, // [SocialMedia.com]
+  {"hash":"17591c31cbbe7cf8","prefixes":{"":{"product":387}}}, // [Content to Emotion (CTE)]
+  {"hash":"7c350f8bcf5a54b9","prefixes":{"":{"product":387}}}, // [Content to Emotion (CTE)]
+  {"hash":"e003938122f9ac4f","prefixes":{"":{"product":387}}}, // [Content to Emotion (CTE)]
+  {"hash":"6deac101ca463319","prefixes":{"static":{"product":387}}}, // [Content to Emotion (CTE)]
+  {"hash":"304e631663a87e67","prefixes":{"*":{"product":388}}}, // [Sociomantic.com]
+  {"hash":"e86474f9c6ad794d","prefixes":{"":{"product":389}}}, // [AdSpeed]
+  {"hash":"de0816aa39c8b153","prefixes":{"*":{"product":390}}}, // [Sophus3]
+  {"hash":"df8355613a445a85","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"a72f2b989760c8dc","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"fbdc1704c28873c8","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"d4674ccaf8fb7e31","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"f184677fb7e2abca","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"e7d695bf507e45d5","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"ea3f746342f05dbf","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"96ce83a8f0d84d99","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"62c6410f3e4000d8","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"b5172a6eee01acbe","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"36f9ba3a735ea443","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"f4d96ab5c7d0f720","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"7c8204a143e83abb","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"cb5b72c4fdc90b38","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"01c1382916f7a580","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"49505fd99e787062","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"a931030a5dbd7346","prefixes":{"":{"product":9}}}, // [Spartoo]
+  {"hash":"3a09b22266ba0b12","prefixes":{"*":{"product":391}}}, // [Specific Media Inc.]
+  {"hash":"2136a3b6f6600ad0","prefixes":{"*":{"product":391}}}, // [Specific Media Inc.]
+  {"hash":"600e429523014251","prefixes":{"*":{"product":391}}}, // [Specific Media Inc.]
+  {"hash":"e8b1c9274a662ad3","prefixes":{"":{"product":392}}}, // [Metrigo GmbH]
+  {"hash":"d0ffd80eda189780","prefixes":{"":{"product":392}}}, // [Metrigo GmbH]
+  {"hash":"e4ab3c31faef2b98","prefixes":{"":{"product":392}}}, // [Metrigo GmbH]
+  {"hash":"97db8dd1bcbc33b8","prefixes":{"*":{"product":393}}}, // [SpongeCell]
+  {"hash":"363a0f26e680d077","prefixes":{"":{"product":394}}}, // [SpngeCell LLC]
+  {"hash":"fbef9c1b28b0cb05","prefixes":{"*":{"product":393}}}, // [SpongeCell]
+  {"hash":"2218b5ce1e656e21","prefixes":{"":{"product":395}}}, // [SpotXchange]
+  {"hash":"a520f16cf6177ebd","prefixes":{"":{"product":395}}}, // [SpotXchange]
+  {"hash":"cda310d3654d07a5","prefixes":{"":{"product":395}}}, // [SpotXchange]
+  {"hash":"2fc5567578510af6","prefixes":{"":{"product":396}}}, // [Spotxchange]
+  {"hash":"abab2d20e98c266d","prefixes":{"":{"product":395}}}, // [SpotXchange]
+  {"hash":"0d78cf3b068120c3","prefixes":{"":{"product":395}}}, // [SpotXchange]
+  {"hash":"6da7c1b25ca845b3","prefixes":{"":{"product":395}}}, // [SpotXchange]
+  {"hash":"c824df0fb0fdf482","prefixes":{"":{"product":397}}}, // [Encore Attribution Platform]
+  {"hash":"9796e014709ccbec","prefixes":{"":{"product":397}}}, // [Encore Attribution Platform]
+  {"hash":"fced1a8e32fb989c","prefixes":{"*":{"product":398}}}, // [Steelhouse]
+  {"hash":"314523d1c217734f","prefixes":{"*":{"product":399}}}, // [Strike New Media Limited]
+  {"hash":"276a5e6003750c07","prefixes":{"*":{"product":400}}}, // [Struq Limited]
+  {"hash":"e5652beb11c7fceb","prefixes":{"*":{"product":401}}}, // [SundaySky Inc.]
+  {"hash":"173a426f6562928a","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"81a2745fc67a8ecf","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"0aea8cde58b4f14e","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"b73e77077b022d36","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"fcf0d2e1f5fa003b","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"361c645b41a96807","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"81df9375fed9172e","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"c1493a0cd3b358a5","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"bdedb9447527960a","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"1cb83aa94e1a92ed","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"2172731c879fab72","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"7dd683bf50ce5c95","prefixes":{"":{"product":402}}}, // [Symphony Advanced Media]
+  {"hash":"aa47b70219d2ee5e","prefixes":{"*":{"product":403}}}, // [TagMan Ltd.]
+  {"hash":"097edb88beda9a20","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"bc65fc5f46cd88c9","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"a4d1bf696dde4d0b","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"c94f9318ace953f1","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"9e2b38828859944c","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"02319fc6286418de","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"dacc570e07ffd91a","prefixes":{"img":{"product":404}}}, // [Taobao]
+  {"hash":"e8ccbc8f652e85a2","prefixes":{"*":{"product":404}}}, // [Taobao]
+  {"hash":"da1ba7cc516336c0","prefixes":{"":{"product":404}}}, // [Taobao]
+  {"hash":"41035e7733acf867","prefixes":{"":{"product":405}}}, // [Target.com]
+  {"hash":"0509bdf297db5010","prefixes":{"*":{"product":406}}}, // [Teadma]
+  {"hash":"69925c7888575612","prefixes":{"":{"product":407}}}, // [BannerConnect BV]
+  {"hash":"4d44c3cec23aea09","prefixes":{"":{"product":407}}}, // [BannerConnect BV]
+  {"hash":"447ea46d0797b32f","prefixes":{"*":{"product":408}}}, // [Teracent Corporation]
+  {"hash":"26ca7e33d194e46e","prefixes":{"":{"product":408}}}, // [Teracent Corporation]
+  {"hash":"b49b79e2e870c3e9","prefixes":{"":{"product":408}}}, // [Teracent Corporation]
+  {"hash":"3a555db76a46f881","prefixes":{"*":{"product":38}}}, // [The Trade Desk Inc.]
+  {"hash":"c4684dd3ef28687a","prefixes":{"*":{"product":409}}}, // [The Travelers Indemnity Company]
+  {"hash":"1c38e7ac2dcf5d58","prefixes":{"":{"product":410}}}, // [Videology]
+  {"hash":"4872cdec0944a698","prefixes":{"":{"product":410}}}, // [Videology]
+  {"hash":"d4e30248b2920988","prefixes":{"*":{"product":411}}}, // [TNS Custom Research Inc.]
+  {"hash":"48a3c2e049507f03","prefixes":{"*":{"product":412}}}, // [TrackingSoft LLC]
+  {"hash":"4c5b26902a10b85b","prefixes":{"*":{"product":412}}}, // [TrackingSoft LLC]
+  {"hash":"51a48ea23568f817","prefixes":{"*":{"product":413}}}, // [Tradedoubler]
+  {"hash":"14251708a577d8c0","prefixes":{"*":{"product":414}}}, // [Epic Marketplace]
+  {"hash":"20f50db7213cc9ee","prefixes":{"*":{"product":415}}}, // [Tribal Fusion]
+  {"hash":"37b92f46ce8d0fa5","prefixes":{"":{"product":415}}}, // [Tribal Fusion]
+  {"hash":"218cac8e116dcf7a","prefixes":{"":{"product":416}}}, // [Triggit]
+  {"hash":"135ee5dfe108d144","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"f6afa26369731900","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"600a58efa4b0a4fa","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"c274f6336d4a40c8","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"0476503f0fc5138a","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"f6364185e21bdfb4","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"3b746cbe2984928e","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"2966c06482ab340c","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"1320f91c88734ed7","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"49e73f2dfe503088","prefixes":{"":{"product":417}}}, // [True Ultimate Standards Everywhere Inc.]
+  {"hash":"345de3574a5cef61","prefixes":{"":{"product":418}}}, // [CarMax Business Services LLC]
+  {"hash":"8aba77355315b602","prefixes":{"":{"product":419}}}, // [Charter Communications]
+  {"hash":"f7e3882cd37d1a5b","prefixes":{"":{"product":419}}}, // [Charter Communications]
+  {"hash":"a62179d5dc8551f8","prefixes":{"":{"product":419}}}, // [Charter Communications]
+  {"hash":"ac3760dc99259bf9","prefixes":{"":{"product":420}}}, // [General Nutrition Centers Inc.]
+  {"hash":"e1c51fbf9b39950a","prefixes":{"":{"product":421}}}, // [Hamilton Beach]
+  {"hash":"68a80c829eb9c95e","prefixes":{"":{"product":422}}}, // [JacquieLawson.com]
+  {"hash":"a02b27c9af68c051","prefixes":{"":{"product":423}}}, // [TruEffect]
+  {"hash":"76b54dcac102ae32","prefixes":{"":{"product":423}}}, // [TruEffect]
+  {"hash":"f36743b8c729a3e5","prefixes":{"":{"product":424}}}, // [American Greetings]
+  {"hash":"0d479c4b1d2026b9","prefixes":{"":{"product":425}}}, // [BlueMountain]
+  {"hash":"c442eae221355ece","prefixes":{"":{"product":426}}}, // [Cardstore]
+  {"hash":"1277d75c5bace94e","prefixes":{"":{"product":427}}}, // [Chemistry.com]
+  {"hash":"2534adb635b0540f","prefixes":{"":{"product":428}}}, // [Donald J Pliner]
+  {"hash":"6e81f110e25ceba1","prefixes":{"*":{"product":429}}}, // [Gevalia]
+  {"hash":"58cb024039904795","prefixes":{"":{"product":430}}}, // [GSI Media]
+  {"hash":"36b7a450ddb92a81","prefixes":{"":{"product":431}}}, // [Match.com]
+  {"hash":"7f6a517c8eef7bf6","prefixes":{"":{"product":431}}}, // [Match.com]
+  {"hash":"b5aa9057f4ab3a79","prefixes":{"":{"product":431}}}, // [Match.com]
+  {"hash":"177eb410b9eee3c2","prefixes":{"":{"product":431}}}, // [Match.com]
+  {"hash":"5a75e9cff48a157c","prefixes":{"":{"product":431}}}, // [Match.com]
+  {"hash":"e561536f4b9b0f5e","prefixes":{"*":{"product":432}}}, // [Optimum Response]
+  {"hash":"3aaed06dec8e119b","prefixes":{"":{"product":433}}}, // [Oreck]
+  {"hash":"e7b19cb5471c10b3","prefixes":{"":{"product":434}}}, // [Tassimo]
+  {"hash":"5eca8c8aa7c01b0e","prefixes":{"*":{"product":435}}}, // [uSwitch]
+  {"hash":"974734b3e01eab8f","prefixes":{"*":{"product":436}}}, // [TubeMogul Inc.]
+  {"hash":"9f562a308fffc5c4","prefixes":{"*":{"product":437}}}, // [Tumri]
+  {"hash":"09845e50cbc70b8a","prefixes":{"*":{"product":182}}}, // [AdAction]
+  {"hash":"82ae5c9a96804ec8","prefixes":{"":{"product":102}}}, // [BigaBid Media Ltd.]
+  {"hash":"b91b0c7d1d3bb786","prefixes":{"":{"product":102}}}, // [BigaBid Media Ltd.]
+  {"hash":"2804070c2606fca7","prefixes":{"":{"product":102}}}, // [BigaBid Media Ltd.]
+  {"hash":"d601d362a989dcf9","prefixes":{"":{"product":438}}}, // [iMarker]
+  {"hash":"0a0084b896887917","prefixes":{"":{"product":438}}}, // [iMarker]
+  {"hash":"64596506e8398578","prefixes":{"":{"product":438}}}, // [iMarker]
+  {"hash":"4af3f67573bdbad8","prefixes":{"":{"product":438}}}, // [iMarker]
+  {"hash":"1348f7d07273dfcf","prefixes":{"":{"product":438}}}, // [iMarker]
+  {"hash":"4329a4ad527e4779","prefixes":{"":{"product":438}}}, // [iMarker]
+  {"hash":"5eca470b27725f28","prefixes":{"*":{"product":439}}}, // [Turn Inc.]
+  {"hash":"83807aae08d0747f","prefixes":{"*":{"product":439}}}, // [Turn Inc.]
+  {"hash":"a0542aaf969b6041","prefixes":{"*":{"product":440}}}, // [Twelvefold Media]
+  {"hash":"7837c4e8623f0409","prefixes":{"":{"product":440}}}, // [Twelvefold Media]
+  {"hash":"13c46ea92caeecf8","prefixes":{"":{"product":441}}}, // [Tynt]
+  {"hash":"5f7c83b68361da73","prefixes":{"*":{"product":442}}}, // [Unica an IBM Company]
+  {"hash":"bd242bcdc493f1d5","prefixes":{"*":{"product":443}}}, // [Unicast]
+  {"hash":"58ad481190b46e2e","prefixes":{"":{"product":444}}}, // [UniQlick]
+  {"hash":"7f5d2102ab11e53c","prefixes":{"":{"product":444}}}, // [UniQlick]
+  {"hash":"c9dd94a27435350b","prefixes":{"":{"product":444}}}, // [UniQlick]
+  {"hash":"4ba8d85cfc1bf5de","prefixes":{"*":{"product":445}}}, // [United Virtualities]
+  {"hash":"0e4c474511c6dfff","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"875bbc4dbaee8734","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"58b08ddd9e3cccf9","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"356603d457828911","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"77c85cb3240da7c5","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"010912cf400592bc","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"28e6d587198883be","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"e64d00be64f97a79","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"fa0271d4d3cf41f2","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"a227d04cd3bf04f7","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"b69205c5372d2357","prefixes":{"":{"product":446}}}, // [VideoHub]
+  {"hash":"da30259edef87286","prefixes":{"*":{"product":447}}}, // [Visible Measures Corp.]
+  {"hash":"46ff1406588e7ceb","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"32ca2bff73328a83","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"3fc1dc351d4952c8","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"80d2379485452f29","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"35183abb3e2c864c","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"3b235045cc005d15","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"34e6561d9300f451","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"08980f63c2ca7971","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"327755ab5ee91d4e","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"c3d3383046b5690f","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"d196d3b7e439011e","prefixes":{"":{"product":192}}}, // [Nielsen OBE (Vizu)]
+  {"hash":"09582bb8c4f0bdcd","prefixes":{"*":{"product":448}}}, // [Vizury Interactive Solutions Pvt. Ltd.]
+  {"hash":"ccbe4ed34be8ea01","prefixes":{"":{"product":449}}}, // [Markit On Demand (Adhesion)]
+  {"hash":"5c0c23d6d5b2aa7d","prefixes":{"":{"product":449}}}, // [Markit On Demand (Adhesion)]
+  {"hash":"6fe5393d68aec474","prefixes":{"":{"product":449}}}, // [Markit On Demand (Adhesion)]
+  {"hash":"24de99047e3e2592","prefixes":{"":{"product":449}}}, // [Markit On Demand (Adhesion)]
+  {"hash":"a1d810c22ef4c8c1","prefixes":{"":{"product":449}}}, // [Markit On Demand (Adhesion)]
+  {"hash":"a961c235191ccc5c","prefixes":{"":{"product":449}}}, // [Markit On Demand (Adhesion)]
+  {"hash":"30327e228a69909d","prefixes":{"":{"product":450}}}, // [WebMetro Inc]
+  {"hash":"1440114026d0b8a7","prefixes":{"*":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"178b8b7280deb93c","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"8398687ebe990cf1","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"5cad65c27ef8d2b4","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"f28574a110053221","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"64eae6bdfc8cc1be","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"36b0c30f5f967ffd","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"10c282544a39807b","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"ce2ed22191804ffa","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"bd56114f26a64020","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"54e283b8884709c3","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"313822ab7be9585a","prefixes":{"":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"d54943c8060334b5","prefixes":{"":{"product":452}}}, // [Weborama Campaign Manager]
+  {"hash":"7928274bf854b28b","prefixes":{"*":{"product":451}}}, // [Weborama Campaign Manager (former name AdPerf)]
+  {"hash":"80415fbb74db7704","prefixes":{"":{"product":453}}}, // [Shopping Network]
+  {"hash":"0840f634995e25fb","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"5fd40859cc837b00","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"c58731043a973263","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"ee286fbf0440d595","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"660d555331a8be68","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"c412040c18d978ce","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"667b34ab71cb2381","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"b888d9e69003de82","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"38dafaa727179ef7","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"78da2db9d3a51f98","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"94a731a76dd26bfc","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"c4ca9b6aebf488dc","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"0a42e116235fec6e","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"ac4d0bcf3017cc3d","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"6653125411676c31","prefixes":{"":{"product":454}}}, // [Shanghai WiseMedia Technology Co. Ltd.]
+  {"hash":"062b10abe02277c1","prefixes":{"":{"product":455}}}, // [XA.net]
+  {"hash":"b0e3a57e8f415aec","prefixes":{"":{"product":455}}}, // [XA.net]
+  {"hash":"6e1bb44d175a20af","prefixes":{"":{"product":455}}}, // [XA.net]
+  {"hash":"34984bab025a1372","prefixes":{"":{"product":455}}}, // [XA.net]
+  {"hash":"d9eb2f654e80ebc6","prefixes":{"*":{"product":456}}}, // [Xaxis LLC]
+  {"hash":"b86d63843110e02a","prefixes":{"*":{"product":457}}}, // [Net Edge]
+  {"hash":"8b526a29c7f2b3dc","prefixes":{"*":{"product":458}}}, // [Xplusone Solutions Inc.]
+  {"hash":"fe0ea2a1c212cfde","prefixes":{"":{"product":459}}}, // [Yahoo! Ad Exchange]
+  {"hash":"dc06a1403eb499df","prefixes":{"":{"product":459}}}, // [Yahoo! Ad Exchange]
+  {"hash":"5a36dbbd382aa12c","prefixes":{"":{"product":459}}}, // [Yahoo! Ad Exchange]
+  {"hash":"c8fd15f0a5fc19aa","prefixes":{"":{"product":459}}}, // [Yahoo! Ad Exchange]
+  {"hash":"ce63a8ab511ec5bb","prefixes":{"":{"product":459}}}, // [Yahoo! Ad Exchange]
+  {"hash":"a6d2abe55f73bc22","prefixes":{"":{"product":460}}}, // [Yahoo Ad Manager Plus]
+  {"hash":"707a11e6dcfa57db","prefixes":{"":{"product":460}}}, // [Yahoo Ad Manager Plus]
+  {"hash":"f75439bd7693fa84","prefixes":{"":{"product":460}}}, // [Yahoo Ad Manager Plus]
+  {"hash":"2f7feb27a1b93524","prefixes":{"":{"product":460}}}, // [Yahoo Ad Manager Plus]
+  {"hash":"f801c9750710d30a","prefixes":{"":{"product":460}}}, // [Yahoo Ad Manager Plus]
+  {"hash":"9b96f7700d727da9","prefixes":{"":{"product":461}}}, // [APT from Yahoo!]
+  {"hash":"e4de2f3b2c06e193","prefixes":{"":{"product":461}}}, // [APT from Yahoo!]
+  {"hash":"21aa62a45ef75fb2","prefixes":{"*":{"product":462}}}, // [Yieldr]
+  {"hash":"85bf1ed3ee6ee615","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"2cf45ce27d0b73c2","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"e8595ade1fd26e2f","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"5660279fe13cfe3b","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"ad26a995ee586915","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"23412da5a5a538cc","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"6b333dd78d119434","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"f3621ca5777d61d5","prefixes":{"":{"product":462}}}, // [Yieldr]
+  {"hash":"cafa71178e1de4db","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"2ca490afaa90c2b3","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"8f0dd7539cf77aa5","prefixes":{"":{"product":352}}}, // [YoYi Interactive]
+  {"hash":"005700973b435023","prefixes":{"":{"product":463}}}, // [YuMe Inc.]
+  {"hash":"bd83427751c351a9","prefixes":{"":{"product":463}}}, // [YuMe Inc.]
+  {"hash":"e504ebfcb6b2722e","prefixes":{"":{"product":463}}}, // [YuMe Inc.]
+  {"hash":"8080438b5792b260","prefixes":{"":{"product":464}}}, // [Ebuzzing]
+  {"hash":"274889e98fbfc776","prefixes":{"":{"product":464}}}, // [Ebuzzing]
+  {"hash":"b62ee5e77fde7ec7","prefixes":{"":{"product":464}}}, // [Ebuzzing]
+  {"hash":"cc6a7a565374c257","prefixes":{"":{"product":464}}}, // [Ebuzzing]
+  {"hash":"e02936a6a6a2cb94","prefixes":{"":{"product":465}}}, // [Ziff Davis]
+  {"hash":"223b94a95f6849cf","prefixes":{"":{"product":465}}}, // [Ziff Davis]
+  {"hash":"a8742ddae80b031b","prefixes":{"":{"product":466}}}, // [DataPoint Media Inc.]
+  {"hash":"fd4a16bf59718107","prefixes":{"":{"product":467}}}, // [Simplytics Limited]
+  {"hash":"a3d523521bc4ba12","prefixes":{"":{"product":467}}}, // [Simplytics Limited]
+  {"hash":"9da8a1153308d7f2","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"d9cc216c8d482336","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"166c65d7776be9f8","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"55f15e5b7746999f","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"213194bd445e551d","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"31406bff4dc35eea","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"ea9607b28f4238c2","prefixes":{"":{"product":468}}}, // [Makazi]
+  {"hash":"707d5310f27d0dd2","prefixes":{"":{"product":469}}}, // [Rich Relevance]
+  {"hash":"59fa19b8a48477fe","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"efb9b464f6ebaa1d","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"8848350bd85fffe4","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"519275c83a5a1c92","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"fc92bec8fbcb03ef","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"91fa39bc27e156b4","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"408d55e8995335ad","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"d0efa7323c77b1a5","prefixes":{"":{"product":470}}}, // [MainADV]
+  {"hash":"baa5cf88a0176bc6","prefixes":{"":{"product":471}}}, // [MediaV Advertising]
+  {"hash":"3ea0854e74c32c87","prefixes":{"":{"product":471}}}, // [MediaV Advertising]
+  {"hash":"88a70c2ebfe38ffe","prefixes":{"":{"product":471}}}, // [MediaV Advertising]
+  {"hash":"dc0b1dfe6de6a967","prefixes":{"":{"product":471}}}, // [MediaV Advertising]
+  {"hash":"cb234228af27fa32","prefixes":{"":{"product":471}}}, // [MediaV Advertising]
+  {"hash":"c7abee58863b27a4","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"7e34b0d37ded49ed","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"d7255d3135b0294d","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"e21264db24be060c","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"466676eb4c2066ac","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"2505a55ead3f2266","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"e97b9e2d31ac962d","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"906215055f6880fa","prefixes":{"":{"product":472}}}, // [MicroAd Inc.]
+  {"hash":"df04046f11aea628","prefixes":{"*":{"product":473}}}, // [Platform ID Inc.]
+  {"hash":"9fe8e93d55562003","prefixes":{"":{"product":474}}}, // [Xrost]
+  {"hash":"6b29d401833f79d8","prefixes":{"":{"product":473}}}, // [Platform ID Inc.]
+  {"hash":"00928c6f847a4785","prefixes":{"":{"product":475}}}, // [Sociocast Networks LLC D/B/A Velos]
+  {"hash":"c3964f299adbe862","prefixes":{"":{"product":476}}}, // [Trend Research]
+  {"hash":"76b5ddb10f769c6b","prefixes":{"*":{"product":248}}}, // [AdOcean Ltd]
+  {"hash":"f52edd3926705507","prefixes":{"":{"product":477}}}, // [Black Swan Verification]
+  {"hash":"d63e38f4eba51f77","prefixes":{"":{"product":478}}}, // [Momentum K.K]
+  {"hash":"6c0f8db03b28099b","prefixes":{"":{"product":477}}}, // [Black Swan Verification]
+  {"hash":"248772911542d550","prefixes":{"*":{"product":479}}}, // [Betgenius Limited]
+  {"hash":"38a72a4924027d8f","prefixes":{"*":{"product":480}}}, // [AT Internet]
+  {"hash":"255b63d169bd9d10","prefixes":{"*":{"product":480}}}, // [AT Internet]
+  {"hash":"3a7fbbad166769ad","prefixes":{"":{"product":481}}}, // [DataLab]
+  {"hash":"fe64230a84967d3c","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"a91296d609efe0b4","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"947fa5564eccc0b2","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"89a64fe46687237f","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"ce1cd4220063df2d","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"1c489f83a79301c6","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"9dc25ef9b3ed3e5d","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"9898ab0c57d683ae","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"0229fe19979f88b0","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"6dedd3fca4d243ac","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"cbc23a15e9f02987","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"95119cbc05f9e42a","prefixes":{"":{"product":482}}}, // [Innovid Inc.]
+  {"hash":"784647d3eb0236dc","prefixes":{"*":{"product":483}}}, // [Adacado]
+  {"hash":"4be5d3939998bc39","prefixes":{"":{"product":483}}}, // [Adacado]
+  {"hash":"cec4d2059bbb1365","prefixes":{"*":{"product":484}}}, // [NetDNA, LLC]
+  {"hash":"87a9bf2f660b2673","prefixes":{"":{"product":478}}}, // [Momentum K.K]
+  {"hash":"33f6a4c9eb1313f6","prefixes":{"":{"product":478}}}, // [Momentum K.K]
+  {"hash":"38afcf5464d4a46e","prefixes":{"":{"product":478}}}, // [Momentum K.K]
+  {"hash":"4a13b10532de4033","prefixes":{"*":{"product":485}}}, // [Pipewave Inc.]
+  {"hash":"a703750c918980b9","prefixes":{"":{"product":486}}}, // [US Media Consulting]
+  {"hash":"77b351109047edb2","prefixes":{"":{"product":487}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
+  {"hash":"f9f554c96902397e","prefixes":{"":{"product":487}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
+  {"hash":"e8f2c7f5eb75983e","prefixes":{"":{"product":487}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
+  {"hash":"f8680fe819857e65","prefixes":{"image":{"product":487}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
+  {"hash":"fe12b35f78c433a6","prefixes":{"":{"product":487}}}, // [SKYTOUCH TECHNOLOGY CO., LIMITED]
+  {"hash":"531f5c369a189473","prefixes":{"":{"product":488}}}, // [Hanesbrands Direct LLC]
+  {"hash":"4bfbc25da5ec8116","prefixes":{"":{"product":489}}}, // [A1platform]
+  {"hash":"56cea5c2b408989a","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"2c24b521f38d28dd","prefixes":{"":{"product":10}}}, // [eBay]
+  {"hash":"d6449351ee8e33eb","prefixes":{"*":{"product":490}}}, // [Agency.com]
+  {"hash":"5e040f7b958d9ee5","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"379ed8ab1690a74c","prefixes":{"":{"product":10}}}, // [eBay]
+  {"hash":"6ed4dac9c333ef4b","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"b4a9e54654a6de08","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"687aa30619ec8e7f","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"5ac823af612c4492","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"ce4e70466c43ade3","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"c865cf822ab64a71","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"083c339aac7e418c","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"8d689bf60029c98f","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"19d0e1eba389dfe1","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"b789395149868329","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"25e9f5191f3d2397","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"82a743999425aaad","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"97a729e5b41fd4ed","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"0db7dee9d3c756cc","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"10981271cb66af25","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"8c86bc9ba67482c6","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"d36efad270e3e7c6","prefixes":{"*":{"product":10}}}, // [eBay]
+  {"hash":"b709ca3f38e77645","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"3cba207e4aa9d6c6","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"fd8da92d6de2518b","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"d9e4d4444ebd418f","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"4c1c4999d1501943","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"a635762b8125bba5","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"99818fe6fd4c4a9c","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"cae59de4e054a5a8","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"d1ec771fe9489a9f","prefixes":{"":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"d9effad74da2b097","prefixes":{"*":{"product":491}}}, // [Adap.tv Inc. (AdWords/YouTube)]
+  {"hash":"46b1fc5fe9da3681","prefixes":{"*":{"product":492}}}, // [Fjord Technologies S.A.S.]
+  {"hash":"e0b6d05a8e75e14a","prefixes":{"*":{"product":492}}}, // [Fjord Technologies S.A.S.]
+  {"hash":"11a89bdf6bc5cf28","prefixes":{"":{"product":493}}}, // [Refined Ads]
+  {"hash":"8e6414939f586d4c","prefixes":{"":{"product":493}}}, // [Refined Ads]
+  {"hash":"6462a1b97a382278","prefixes":{"":{"product":493}}}, // [Refined Ads]
+  {"hash":"9f99479854cea2e7","prefixes":{"":{"product":493}}}, // [Refined Ads]
+  {"hash":"72b40aacd2b4e226","prefixes":{"":{"product":493}}}, // [Refined Ads]
+  {"hash":"67401ef133d2ed76","prefixes":{"":{"product":494}}}, // [nugg.ad AG]
+  {"hash":"696757eb9e07845f","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"c84660fcf8a4c99c","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"df10c5e0e18fda2b","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"c71dfe726124b24c","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"f603a3b56996fe4c","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"149593d24f74e3e1","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"a1b9a8ff7b829f8f","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"37cb27fb57319c52","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"16e50e7e7b499ab7","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"c10f5df1adb6160f","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"df3ea734f608dc0d","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"3014b8652e4fd340","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"68034e41a59505be","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"4ff550d2f5a384d7","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"266c6cb54cc8f810","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"c174c4c7c469cbb9","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"19b8f26cb5987d86","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"0301de7ebef3ded7","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"5f6ccacecc90b6ab","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"cee43a3e7001e664","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"27d64efa61e9fb8c","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"05eae7c7a976d6b2","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"da375ad9bc86ad05","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"1a62d22c13d4f003","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"65f8018fc9a58ba7","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"c790c87ca2abbb6c","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"5aefca188560242d","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"eaa7adee1317cb7d","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"db5afb1288bacbff","prefixes":{"*":{"product":496}}}, // [Meetrics GmbH]
+  {"hash":"7d618e8de39f548c","prefixes":{"*":{"product":496}}}, // [Meetrics GmbH]
+  {"hash":"b5c30978f10b1f56","prefixes":{"s":{"product":496},"":{"product":497}}}, // [Meetrics GmbH] [Meetrics]
+  {"hash":"5c4a10a5bc0897c7","prefixes":{"":{"product":498}}}, // [Digital Control GmbH & Co. KG]
+  {"hash":"38d57267aeada6cc","prefixes":{"":{"product":498}}}, // [Digital Control GmbH & Co. KG]
+  {"hash":"7dc82de98d234295","prefixes":{"":{"product":499}}}, // [Dedicated Media]
+  {"hash":"98cac3ed2db221c5","prefixes":{"":{"product":499}}}, // [Dedicated Media]
+  {"hash":"74da617dd78c4c25","prefixes":{"":{"product":499}}}, // [Dedicated Media]
+  {"hash":"ad829d4fccaec076","prefixes":{"":{"product":499}}}, // [Dedicated Media]
+  {"hash":"93214296470961ea","prefixes":{"":{"product":500}}}, // [Accuen]
+  {"hash":"fb8e16c2a3413e04","prefixes":{"*":{"product":501}}}, // [Pulse 360, Inc.]
+  {"hash":"56de3497c2b187f9","prefixes":{"*":{"product":501}}}, // [Pulse 360, Inc.]
+  {"hash":"1763cb8cd4ecb455","prefixes":{"*":{"product":502}}}, // [ZANOX AG]
+  {"hash":"dd420134fd0b31f7","prefixes":{"*":{"product":502}}}, // [ZANOX AG]
+  {"hash":"f942b375b4c9d301","prefixes":{"":{"product":503}}}, // [Webgains Ltd]
+  {"hash":"03b41741559a5775","prefixes":{"":{"product":504}}}, // [Virgin Media Limited]
+  {"hash":"e01702c3ace07a42","prefixes":{"*":{"product":505}}}, // [MyBuys MyAds]
+  {"hash":"a09aa03b7ab4a6a0","prefixes":{"*":{"product":506}}}, // [VCCP Search LTD]
+  {"hash":"8ae53030752d70fd","prefixes":{"":{"product":507}}}, // [Conversant Media]
+  {"hash":"3f911ef887ffe5a7","prefixes":{"":{"product":507}}}, // [Conversant Media]
+  {"hash":"dd0195d7ab665db3","prefixes":{"":{"product":507}}}, // [Conversant Media]
+  {"hash":"6ac275e8e99e5fb3","prefixes":{"":{"product":507}}}, // [Conversant Media]
+  {"hash":"5960f055d64bd6fb","prefixes":{"":{"product":507}}}, // [Conversant Media]
+  {"hash":"d07a0c93a2f5da33","prefixes":{"":{"product":507}}}, // [Conversant Media]
+  {"hash":"b7e7f7ab4a600ced","prefixes":{"":{"product":508}}}, // [Up-Value GmbH & Co. KG]
+  {"hash":"e92a06c68de2a79d","prefixes":{"":{"product":509}}}, // [Unruly Media]
+  {"hash":"789659215cb1620d","prefixes":{"":{"product":509}}}, // [Unruly Media]
+  {"hash":"b61a48cd46cb7b06","prefixes":{"*":{"product":510}}}, // [Underdog Media LLC]
+  {"hash":"eea5fa46bce35e24","prefixes":{"":{"product":511}}}, // [SVG Media Pvt. Ltd.]
+  {"hash":"9b346c0d77f1fcf2","prefixes":{"*":{"product":512}}}, // [TRAFFIQ LLC]
+  {"hash":"51324f52aa5eb734","prefixes":{"*":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"26e3ca8cc9a6afd8","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"2e9a57a3dcc61e3e","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"2e6202e113ae62e3","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"9a1d6d8445e2cce9","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"88015c5982735097","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"9cf10e72a2db48a9","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"cf5ba41c477d8aa5","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"fe50c8a7f665cf78","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"5c9fb160269ccb5c","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"366f4f435bfb9255","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"5dde0b5371aae6bb","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"ebd682e181b553a7","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"df61db1cec60b5a1","prefixes":{"":{"product":513}}}, // [TellApart Inc.]
+  {"hash":"bdf8043c482f8afd","prefixes":{"*":{"product":514}}}, // [Shopzilla Inc.]
+  {"hash":"83ce758172dc68fb","prefixes":{"*":{"product":514}}}, // [Shopzilla Inc.]
+  {"hash":"45cc9e8ea0e405cc","prefixes":{"*":{"product":514}}}, // [Shopzilla Inc.]
+  {"hash":"bc8d543772676fe4","prefixes":{"*":{"product":514}}}, // [Shopzilla Inc.]
+  {"hash":"6a51a8a28265901e","prefixes":{"*":{"product":515}}}, // [Reactivpub]
+  {"hash":"b03903f1abac9b82","prefixes":{"*":{"product":515}}}, // [Reactivpub]
+  {"hash":"14281bd870fa9e85","prefixes":{"*":{"product":515}}}, // [Reactivpub]
+  {"hash":"52c9dfb471edf4de","prefixes":{"*":{"product":515}}}, // [Reactivpub]
+  {"hash":"b9cf807aee694b90","prefixes":{"*":{"product":516}}}, // [Netseer Inc.]
+  {"hash":"720c7cdaeb3d3edf","prefixes":{"":{"product":516}}}, // [Netseer Inc.]
+  {"hash":"a7e82477ddc48f23","prefixes":{"*":{"product":517}}}, // [eBay Enterprise]
+  {"hash":"c35bcff10cd62a44","prefixes":{"":{"product":518}}}, // [Goodway Group]
+  {"hash":"a45b6c7292b7b560","prefixes":{"":{"product":518}}}, // [Goodway Group]
+  {"hash":"d76efc82324fb8d5","prefixes":{"":{"product":518}}}, // [Goodway Group]
+  {"hash":"5eb742c77c59dd05","prefixes":{"":{"product":518}}}, // [Goodway Group]
+  {"hash":"33f9a4e4a440eeda","prefixes":{"*":{"product":519}}}, // [Double Positive Marketing Group Inc.]
+  {"hash":"285da2e20d7ae651","prefixes":{"*":{"product":520}}}, // [Chitika Inc.]
+  {"hash":"9ac26bc76037dd72","prefixes":{"*":{"product":521}}}, // [Scigineer Inc.]
+  {"hash":"11971f02aee2996f","prefixes":{"*":{"product":522}}}, // [Sales Spider Inc.]
+  {"hash":"0dfb620c1f99f67a","prefixes":{"*":{"product":522}}}, // [Sales Spider Inc.]
+  {"hash":"dee182aa38b90802","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"ee4bb512aa7bff3f","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"051b6a2f5170871a","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"ef2266eab416e344","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"40701593c87a2a6d","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"4dfd82e7fcbfe056","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"2848c783f1d69118","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"26fd0c0c1bbdf578","prefixes":{"":{"product":523}}}, // [Rocket Fuel Inc.]
+  {"hash":"9362d437c6649ac0","prefixes":{"":{"product":524}}}, // [RTBlab]
+  {"hash":"83cd554cdc78cc1c","prefixes":{"":{"product":524}}}, // [RTBlab]
+  {"hash":"e4e3ec12949d311d","prefixes":{"":{"product":524}}}, // [RTBlab]
+  {"hash":"9db675ca1ddbc25e","prefixes":{"":{"product":524}}}, // [RTBlab]
+  {"hash":"c407f5eb4837736a","prefixes":{"":{"product":524}}}, // [RTBlab]
+  {"hash":"27e52d41a00bf2fd","prefixes":{"":{"product":524}}}, // [RTBlab]
+  {"hash":"efa545dd9d577a82","prefixes":{"":{"product":525}}}, // [abilicom GmbH]
+  {"hash":"f690d50313c4d883","prefixes":{"":{"product":525}}}, // [abilicom GmbH]
+  {"hash":"e59063ed858c1ac6","prefixes":{"":{"product":525}}}, // [abilicom GmbH]
+  {"hash":"08ecd0f7d816b029","prefixes":{"":{"product":30}}}, // [Rakuten Display]
+  {"hash":"6321d1d2e3ff13cf","prefixes":{"":{"product":526}}}, // [Pulpo Media Inc]
+  {"hash":"68778ff49de5f6b7","prefixes":{"":{"product":526}}}, // [Pulpo Media Inc]
+  {"hash":"4fe62a295bf7110a","prefixes":{"*":{"product":527}}}, // [OneSpot]
+  {"hash":"0a03e9309eac6fef","prefixes":{"*":{"product":528}}}, // [MyThings UK Ltd]
+  {"hash":"aefee6cf21fb21d0","prefixes":{"*":{"product":528}}}, // [MyThings UK Ltd]
+  {"hash":"013cf49561a61d0a","prefixes":{"":{"product":529}}}, // [Exactag]
+  {"hash":"a5db93b0474bf88a","prefixes":{"":{"product":529}}}, // [Exactag]
+  {"hash":"8eaf146d58acaea3","prefixes":{"":{"product":353}}}, // [AdMaster]
+  {"hash":"62f9a92e2fa55157","prefixes":{"":{"product":353}}}, // [AdMaster]
+  {"hash":"2246fe417fb594d4","prefixes":{"":{"product":353}}}, // [AdMaster]
+  {"hash":"46be6b3d05c938b5","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"b588a450d30940dc","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"9013d3536e80f01a","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"705829297e5108ae","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"bfd58f70292d02ab","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"ff5875b2546d8499","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"ccc16a9e8656612f","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"a764b52c155c440b","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"a8a184b600fd3af1","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"6c106d279e66ed61","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"7c8663ad744aeec9","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"c3860e5673290a36","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"485e37ef683e6da8","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"03c59eef464ffa9d","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"e8d28d6ae9ed1064","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"1fc896b89972c4a3","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"89d45cf6716d92c4","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"c374b8ef2cc0a6d3","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"e0a60df6ec972762","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"dfd819866072d81c","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"dbaab38c6254fc44","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"25e404b1d7cfa7b3","prefixes":{"":{"product":530}}}, // [Kyocera Communication Systems Co. Ltd.]
+  {"hash":"f9b4a878a9f66629","prefixes":{"":{"product":531}}}, // [Beijing LangTaoJin Interactive]
+  {"hash":"5be19b5ec9da0217","prefixes":{"":{"product":531}}}, // [Beijing LangTaoJin Interactive]
+  {"hash":"c3dd7532c047b725","prefixes":{"":{"product":532}}}, // [Conversant Mobile Media]
+  {"hash":"fd89a621a7abcb21","prefixes":{"":{"product":532}}}, // [Conversant Mobile Media]
+  {"hash":"8b03c1ce3a37af3e","prefixes":{"":{"product":533}}}, // [MM1X.nl]
+  {"hash":"51f16f2963b5ab62","prefixes":{"":{"product":533}}}, // [MM1X.nl]
+  {"hash":"a34aa5b1e90b35d0","prefixes":{"":{"product":534}}}, // [Trivu Media Inc.]
+  {"hash":"f5fe0a711d905029","prefixes":{"":{"product":534}}}, // [Trivu Media Inc.]
+  {"hash":"284614e662fae11d","prefixes":{"*":{"product":535}}}, // [BlueCava Inc.]
+  {"hash":"cd9e8f6b8e3bb0bb","prefixes":{"":{"product":536}}}, // [Beijing Gridsum Technology Co. Ltd.]
+  {"hash":"97de03485c681efe","prefixes":{"":{"product":536}}}, // [Beijing Gridsum Technology Co. Ltd.]
+  {"hash":"6c624568b77c2f15","prefixes":{"":{"product":536}}}, // [Beijing Gridsum Technology Co. Ltd.]
+  {"hash":"2b74e65baabdf4a8","prefixes":{"":{"product":537}}}, // [Adsvana DSP]
+  {"hash":"fcd2a83347336f39","prefixes":{"":{"product":537}}}, // [Adsvana DSP]
+  {"hash":"7cadddba30cbf68b","prefixes":{"":{"product":367}}}, // [revenue cloud]
+  {"hash":"39fe4b58f8d0c85a","prefixes":{"":{"product":538}}}, // [Target Performance]
+  {"hash":"219259d49fac1ccb","prefixes":{"":{"product":539}}}, // [Content Spread]
+  {"hash":"ca8d76b63fdfd7e7","prefixes":{"":{"product":367}}}, // [revenue cloud]
+  {"hash":"ed86b10928624d27","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"205f80e614b45d0c","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"88c9d142721a0010","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"c918497df4612dee","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"ecc68ce18bc92eac","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"acd6e7d757515791","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"611fb7a1125a9f9d","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"b47f7e78adfcce8c","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"e7d6867de133fef3","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"022353c9ab0821d7","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"2571a0502f188936","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"f1efca13f787818a","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"1c982ec87cdd98c7","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"ffa62eae8604dfb9","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"8c7ba8485b195fda","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"188fb424b02d01b3","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"92807e8eb5ceed53","prefixes":{"":{"product":540}}}, // [Datamind Effective Media]
+  {"hash":"b01a0f9c920b194e","prefixes":{"":{"product":541}}}, // [ScaleOut Inc.]
+  {"hash":"da51b7d5383143f5","prefixes":{"":{"product":541}}}, // [ScaleOut Inc.]
+  {"hash":"acca27df7ac50ef3","prefixes":{"":{"product":541}}}, // [ScaleOut Inc.]
+  {"hash":"8a45863cac015863","prefixes":{"":{"product":541}}}, // [ScaleOut Inc.]
+  {"hash":"ae50046a864ceafd","prefixes":{"":{"product":541}}}, // [ScaleOut Inc.]
+  {"hash":"de57dfdaf9a2c48a","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"b1235d3bdac69ad1","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"b2717d6d54a069e3","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"d7152b8a7fbdcfd9","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"66d946b524ae15cb","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"cb87adb62a805e43","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"64b417a15cd2caba","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"fe5fbbb5f87923ec","prefixes":{"":{"product":542}}}, // [Ensighten]
+  {"hash":"7955dee10fac2b43","prefixes":{"":{"product":543}}}, // [Sony Electronics Inc.]
+  {"hash":"18b842a485714b88","prefixes":{"":{"product":543}}}, // [Sony Electronics Inc.]
+  {"hash":"5e881c11a6141a0e","prefixes":{"*":{"product":544}}}, // [Gravity Research and Development LTD]
+  {"hash":"eb0586aa7b44d1a7","prefixes":{"":{"product":545}}}, // [Project SunBlock]
+  {"hash":"e49a615e7e072e05","prefixes":{"":{"product":546}}}, // [Novem sp. z o.o.]
+  {"hash":"c36795d664275022","prefixes":{"*":{"product":547}}}, // [Econda GmbH]
+  {"hash":"1dafa12902626628","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"ddc49ed0d5adc099","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"43e36030afe70656","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"f4acd265af4a8b2c","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"2d00af9d31137b46","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"6330d2d69fac5592","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"07924db4fbf62ed8","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"40fa76b0dfe6cba9","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"cb5e5323270dac31","prefixes":{"":{"product":548}}}, // [AdMaxim LLC]
+  {"hash":"644395b50223d6f0","prefixes":{"":{"product":78}}}, // [Adnologies GmbH]
+  {"hash":"e816f89057c8ad52","prefixes":{"":{"product":78}}}, // [Adnologies GmbH]
+  {"hash":"8d2b1cab5958796f","prefixes":{"":{"product":549}}}, // [Alliance Health Networks]
+  {"hash":"3568ed34edbd0a3b","prefixes":{"":{"product":550}}}, // [Adsame Advertising Co., Ltd]
+  {"hash":"5fd75bdc8d48469a","prefixes":{"":{"product":550}}}, // [Adsame Advertising Co., Ltd]
+  {"hash":"f24f098ee46d7e52","prefixes":{"":{"product":550}}}, // [Adsame Advertising Co., Ltd]
+  {"hash":"695c924af8b7be90","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"8c21b1544107f44b","prefixes":{"":{"product":552}}}, // [PK Online Ventures Limited]
+  {"hash":"b709e5fa7a0a3284","prefixes":{"":{"product":553}}}, // [Bigpoint Gmbh]
+  {"hash":"54393b0479bf4296","prefixes":{"":{"product":553}}}, // [Bigpoint Gmbh]
+  {"hash":"0228e75fa4f7ba29","prefixes":{"":{"product":553}}}, // [Bigpoint Gmbh]
+  {"hash":"161b02c3430e8493","prefixes":{"":{"product":554}}}, // [Mirapodo GmbH]
+  {"hash":"cbfa294f671394f5","prefixes":{"":{"product":555}}}, // [Digitize New Media Ltd.]
+  {"hash":"126e76895e35030f","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"d1a3397960a0c962","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"27111f31c7f7870c","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"5066a54cd7ed6242","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"5447e7edfecbefc9","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"763e1c5a534cdce1","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"664f6761d6e1bdc5","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"85dc2dbb9cf8ba01","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"efd9939ccbcea7ca","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"5095b815554d166d","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"bbd5220662a5b37e","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"ad929f7cd3353264","prefixes":{"":{"product":556}}}, // [AdSage]
+  {"hash":"aebf7b2a7ee1ff12","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"01ef28aab34283cc","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"c075f26f4aa57d43","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"f651f54211351ca7","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"98e7e8f01b1e7221","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"7f46832cdf7b45db","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"4a37345bf96b65b5","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"ee9f377ce8711040","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"f6f6db9a07009087","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"37414a33ff3de4a0","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"7cc06f83f0710408","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"beb1894d6a5dd8d5","prefixes":{"":{"product":557}}}, // [Fingereach]
+  {"hash":"ab305fad96c94e68","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"abb33b12777d693c","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"cf57baa1fe60d65d","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"1e230cd699b878e6","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"0e9f493079696ce3","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"7d3350cd22011e53","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"f50b2ec037f5428b","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"c171c26c4996ef48","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"558975de73dc2727","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"ee6b8472f5558865","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"8183f3c56cedc5d3","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"9e46a78131a70a25","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"9805160753b78db8","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"9665241d465c8ced","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"0886098ece10411f","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"1b9aa72e21da1cf9","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"75eaf92a0259fced","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"6647ef959a9060b1","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"55bbd43420c048ba","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"769a3492166f2234","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"88bf787fe78aa617","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"62db61a5802ee5f9","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"ecc8b48b5b165bff","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"3b713a488717f579","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"7d501d2362243528","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"1e2c100fab457dce","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"7adb32ad76289644","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"3f4747021104b435","prefixes":{"":{"product":307}}}, // [DMA Institute dba Hottraffic]
+  {"hash":"55ade41cc24f1b54","prefixes":{"":{"product":558}}}, // [Calvin Klein]
+  {"hash":"210f025e6c6b8122","prefixes":{"":{"product":559}}}, // [Medialets Servo]
+  {"hash":"233555f3daf9abb0","prefixes":{"":{"product":559}}}, // [Medialets Servo]
+  {"hash":"eea93545b322651b","prefixes":{"":{"product":559}}}, // [Medialets Servo]
+  {"hash":"d9fe49eeaf35eb01","prefixes":{"":{"product":559}}}, // [Medialets Servo]
+  {"hash":"ea41698b95338591","prefixes":{"s-cdn-":{"product":559}}}, // [Medialets Servo]
+  {"hash":"5f4e90726b181c95","prefixes":{"":{"product":560}}}, // [Webmoblink Inc.]
+  {"hash":"9d51efd26ab44317","prefixes":{"":{"product":31}}}, // [Retailigence]
+  {"hash":"32440ed26b61d14a","prefixes":{"":{"product":31}}}, // [Retailigence]
+  {"hash":"8234d0306d8984eb","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"e35bf94930bc4d1a","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"aec3f56c7f99151f","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"ef395b96d922c238","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"5a053ab1bcfcfb41","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"2cf811bb8aa279b5","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"cd383e750e6cfcdb","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"c30fc77cd822188e","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"fb9678eef7ea227d","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"102facb286a88bbe","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"aa39a58ff4ed2114","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"e33908ca9604cfa4","prefixes":{"*":{"product":561},"":{"product":562}}}, // [Moat Inc.] [Bannerflow AB]
+  {"hash":"31902ac0cc3e362b","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"796535f10f1e1ea0","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"681a390e8faf08c1","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"1ef04ebc565a6f48","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"1461b89b1a4a5e39","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"a7c34fe979c7afe2","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"30142bb0f24faa5a","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"dc8fdd8b9daae8d5","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"80a2d23602bd08d7","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"e8713f2da85d0fff","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"08fe20173c2a758a","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"105d629b41621e8f","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"c2c8a87c65874f50","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"ecc3d954923aa593","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"313e3d29b4712d5d","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"bf332f1705b05b91","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"c2fac5215807677b","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"b1db7fe55b719fd0","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"c405962725b0a49f","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"f30974f87632ff65","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"c3a0f51c7a475e24","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"470beffefc05bd89","prefixes":{"":{"product":561}}}, // [Moat Inc.]
+  {"hash":"44c6bfd7fd3ae379","prefixes":{"*":{"product":561}}}, // [Moat Inc.]
+  {"hash":"ed26e1a4862cb993","prefixes":{"":{"product":563}}}, // [Batch Media Gmbh]
+  {"hash":"8cc35cd28ab69e7b","prefixes":{"":{"product":563}}}, // [Batch Media Gmbh]
+  {"hash":"b480ee3cdb39aba3","prefixes":{"":{"product":563}}}, // [Batch Media Gmbh]
+  {"hash":"42b8cf3c1fba5649","prefixes":{"":{"product":563}}}, // [Batch Media Gmbh]
+  {"hash":"9c59afa20426083f","prefixes":{"":{"product":564}}}, // [Twenga]
+  {"hash":"96fa4f0d4282b74b","prefixes":{"":{"product":564}}}, // [Twenga]
+  {"hash":"147ff4cde8f7b63b","prefixes":{"":{"product":564}}}, // [Twenga]
+  {"hash":"e6d43f305d0372aa","prefixes":{"":{"product":565}}}, // [TraceAd]
+  {"hash":"e2a94bb0b8f09309","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"7b17e990632021fb","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"c82cc94c761aff4f","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"9bb0143d6745a1fc","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"9906e8d23a282ab0","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"c29531bb7c2a5a95","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"53972f8a807a3522","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"d8acabec202014c0","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"4062ceb50584895d","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"776d48fd287f99c8","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"caf4c25a1be2f9cc","prefixes":{"":{"product":566}}}, // [Speed Shift Media]
+  {"hash":"ad66fb580dfc0f61","prefixes":{"*":{"product":567}}}, // [CCB Paris]
+  {"hash":"2cd1c0997e13f343","prefixes":{"":{"product":568}}}, // [Nielsen Digital Ad Ratings]
+  {"hash":"cc67f7e32922d026","prefixes":{"*":{"product":569}}}, // [OpenDSP]
+  {"hash":"37ac881f55f6b624","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"6eaeb2fb0379f719","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"0f37e190c3f7659c","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"cd5e1f475a9a9cb9","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"70dae8af3c6cb2af","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"60e90d920044304d","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"9d34d5e680004543","prefixes":{"":{"product":551}}}, // [Guangzhou Shunfei Infomation Technology Corporatio]
+  {"hash":"b4b546c24d350673","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"d0b7581f4a3ff9b8","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"0c865d217e1f18f3","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"6333a18d75125edb","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"ed4cdc36d8829848","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"3643c909d7cbe0b8","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"296c21a7001df348","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"97079bad5fb6ead8","prefixes":{"":{"product":570}}}, // [Beijing NetEase YouDao Computer System Co., Ltd.]
+  {"hash":"7b936711dd1e9a43","prefixes":{"":{"product":571}}}, // [Mediarithmics]
+  {"hash":"c1d09d8bf99adaae","prefixes":{"":{"product":572}}}, // [RUN, INC.]
+  {"hash":"c1a2559db78be890","prefixes":{"":{"product":572}}}, // [RUN, INC.]
+  {"hash":"99a2370c6cb03aad","prefixes":{"":{"product":572}}}, // [RUN, INC.]
+  {"hash":"58188c996594e74c","prefixes":{"":{"product":573}}}, // [Shanghai Menlo Network Technologies Co.,Ltd]
+  {"hash":"ae01937a71f3c8ec","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"bb20b492d8e895ee","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"a174c7ffc06f1430","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"b04d26682765cf0f","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"3d8976d50a72415a","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"0b937695e283332d","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"5a633d8ed4134176","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"a3d5abb1d31313bb","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"651fcbfafdaa1c3b","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"210045798925d1ec","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"cb9c94ed4430c0d7","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"eb42b6b78e25a31e","prefixes":{"":{"product":574}}}, // [Beijing Oasis Technology Co. Ltd (Mjoys)]
+  {"hash":"e21aeaa35d9e4534","prefixes":{"*":{"product":575}}}, // [NET-Metrix-Audit]
+  {"hash":"d563d7cb84148f5b","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"881b6320fa6c5a13","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"648b287843959e5a","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"aa60743a7bfcd1af","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"afa7ee2a02f86074","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"3b21af5a3fa47754","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"e8f690279ec23223","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"8763304c40959465","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"97be7bbbd0aa71f1","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"1610ab8331e9fa67","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"5cf6c3a758fb5a50","prefixes":{"":{"product":576}}}, // [New Allyes Information Technology (Quantone)]
+  {"hash":"753372717104cecb","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"9868ccc3384ca704","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"834fc9317bd55432","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"77a58434eda65f1d","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"d6c8f549569824c7","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"605f200bf3a42aec","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"24475a888daf195d","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"577626a5c9b3a87c","prefixes":{"":{"product":577}}}, // [Resonate Networks, Inc]
+  {"hash":"c258f6da0cd8b8cb","prefixes":{"":{"product":577}}}, // [Resonate Networks, Inc]
+  {"hash":"d9483fc3fe68e764","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"7caa53e1a6ec2bae","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"dcd74656fa3b323d","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"10fa95c5f15310d2","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"6f83daf020ab465f","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"d3d1a09a28024ddc","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"9b208cc58454fb78","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"4645c6078dc34d50","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"b238cbc325c6ef22","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"49deee4d32200263","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"773d9411487a25e3","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"0f6cf491f7eb2baa","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"8dfcd3664fa1302b","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"800bb9e7968e58aa","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"b05b363e5a0511e8","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"20c70723848457f0","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"66114e4ff94b609f","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"f2d188b48acaeb7f","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"409d1c85462adead","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"4d380a7d15d0a78a","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"d5449f5767bfafa7","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"bd39dc0af22a3152","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"f86c1368c7c5eb92","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"e8f74e435e9df1dd","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"9b5fa6e2f606ce7d","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"9a9e03501130b17a","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"2a12549f5c240468","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"215711257cc47c2c","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"77f3f7c79d95de48","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"6d31870e0469ddc6","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"d43e8e7f0b7db722","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"cf4d5bbc8b02dc1c","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"fa69e0b93ab494f2","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"5df810b59c15eb88","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"1bad3858e6b1db68","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"1f0663d5a32c3b7d","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"0accadb2b8868065","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"29fa86d0b3c09f26","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"6c3481a4787dc989","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"dd2cdf0ae459961c","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"b7ddbc93720778f5","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"65db5bf588a1552c","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"d63dadf02badb9bc","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"12a0ac899815d56b","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"4e73ffb09594e8a6","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"7bd28c9beb85782f","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"e5a3c52df181ad93","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"5db249180904a1af","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"f33943be4b14e2cc","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"3304828c6a87914b","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"0dee81e461b3c8bb","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"23282a1244ed862f","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"8b1d859efda195f4","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"e22129fd14c58ef7","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"c11b0627d1105ed8","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"fee7a2b84c23b6bb","prefixes":{"":{"product":11}}}, // [advanced STORE GmbH]
+  {"hash":"3f3d4a96d97bc12a","prefixes":{"":{"product":578}}}, // [Triple Lift, Inc.]
+  {"hash":"7e4d08be26af0913","prefixes":{"":{"product":578}}}, // [Triple Lift, Inc.]
+  {"hash":"ab1718aa8ada6ceb","prefixes":{"":{"product":578}}}, // [Triple Lift, Inc.]
+  {"hash":"00810432ca3a5adf","prefixes":{"":{"product":578}}}, // [Triple Lift, Inc.]
+  {"hash":"e597ba5088abb36a","prefixes":{"":{"product":578}}}, // [Triple Lift, Inc.]
+  {"hash":"d206640e7ca174cd","prefixes":{"":{"product":579}}}, // [Indie Ads]
+  {"hash":"d8ed39f1e603b870","prefixes":{"":{"product":580}}}, // [Ocean Park Interactive]
+  {"hash":"a241e76a04cef012","prefixes":{"":{"product":580}}}, // [Ocean Park Interactive]
+  {"hash":"dcc0a9d204aaa55d","prefixes":{"":{"product":580}}}, // [Ocean Park Interactive]
+  {"hash":"8372761b0392f8a9","prefixes":{"":{"product":580}}}, // [Ocean Park Interactive]
+  {"hash":"e7b8261c49b1fbf6","prefixes":{"":{"product":580}}}, // [Ocean Park Interactive]
+  {"hash":"d5094d4667f378a7","prefixes":{"":{"product":580}}}, // [Ocean Park Interactive]
+  {"hash":"4091c3043c2da68a","prefixes":{"":{"product":581}}}, // [Impulse Media Pvt. Ltd.]
+  {"hash":"6eb5dacfebab8b02","prefixes":{"":{"product":582}}}, // [CrowdTwist]
+  {"hash":"123db0626c48324c","prefixes":{"":{"product":582}}}, // [CrowdTwist]
+  {"hash":"4f356e0d187085b0","prefixes":{"":{"product":583}}}, // [Adzerk Inc.]
+  {"hash":"79c1600f16f0c0ad","prefixes":{"":{"product":583}}}, // [Adzerk Inc.]
+  {"hash":"170c4bddaa53e87c","prefixes":{"":{"product":584}}}, // [Adtarget.me]
+  {"hash":"b514da98fbd70da7","prefixes":{"":{"product":584}}}, // [Adtarget.me]
+  {"hash":"e585ef712f906ce4","prefixes":{"":{"product":584}}}, // [Adtarget.me]
+  {"hash":"ed5e6e621b9e9e9e","prefixes":{"":{"product":584}}}, // [Adtarget.me]
+  {"hash":"904a8c71f0ac4b5c","prefixes":{"":{"product":584}}}, // [Adtarget.me]
+  {"hash":"138d782ff8ef8b3d","prefixes":{"":{"product":585}}}, // [Recruit Marketing Partners Co.,Ltd]
+  {"hash":"8899c2499d762095","prefixes":{"":{"product":586}}}, // [Beijing Emar Online Technology Co.,Ltd]
+  {"hash":"29f87adefe40afd5","prefixes":{"":{"product":586}}}, // [Beijing Emar Online Technology Co.,Ltd]
+  {"hash":"1f57d0a967ca4f30","prefixes":{"":{"product":586}}}, // [Beijing Emar Online Technology Co.,Ltd]
+  {"hash":"378c4fbbd1d161e2","prefixes":{"":{"product":587}}}, // [AdMagnet]
+  {"hash":"bb42bdad4318ee55","prefixes":{"":{"product":587}}}, // [AdMagnet]
+  {"hash":"71d1cec71f53e140","prefixes":{"":{"product":587}}}, // [AdMagnet]
+  {"hash":"e3bad45f1f3d21a5","prefixes":{"":{"product":587}}}, // [AdMagnet]
+  {"hash":"aa63c60aa73e9d29","prefixes":{"":{"product":588}}}, // [Momondo A/S]
+  {"hash":"b34444583646725a","prefixes":{"*":{"product":588}}}, // [Momondo A/S]
+  {"hash":"cbf8a85fbf4c22e5","prefixes":{"*":{"product":589}}}, // [DKK Agency]
+  {"hash":"e775e327a7a42402","prefixes":{"":{"product":590}}}, // [OneScreen Inc.]
+  {"hash":"080fcbb984e6ecdd","prefixes":{"":{"product":590}}}, // [OneScreen Inc.]
+  {"hash":"8c1ae0a34a3df5d0","prefixes":{"":{"product":590}}}, // [OneScreen Inc.]
+  {"hash":"ba491e57276128df","prefixes":{"":{"product":591}}}, // [AdElement Media Solutions Pvt Ltd]
+  {"hash":"620a368e66b0d054","prefixes":{"":{"product":591}}}, // [AdElement Media Solutions Pvt Ltd]
+  {"hash":"f100a71a63d2ccfa","prefixes":{"":{"product":591}}}, // [AdElement Media Solutions Pvt Ltd]
+  {"hash":"636877d8cc1827f4","prefixes":{"":{"product":592}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
+  {"hash":"e066625a70a1d5c0","prefixes":{"":{"product":592}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
+  {"hash":"117aaf00ef5036e3","prefixes":{"":{"product":592}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
+  {"hash":"4f795b8396901621","prefixes":{"":{"product":592}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
+  {"hash":"b8da1e9feb0bc01d","prefixes":{"":{"product":592}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
+  {"hash":"433e8fe3ca1684d7","prefixes":{"":{"product":592}}}, // [Beijing Sheng Jin Lan Advertising Co., Ltd.]
+  {"hash":"f2fc51beddbeb4a9","prefixes":{"":{"product":593}}}, // [Adsit Media Advertising Ltd. Co., (AdMan)]
+  {"hash":"ba7f680031ef6ba6","prefixes":{"":{"product":594}}}, // [AdMan]
+  {"hash":"cba16dd5f4409e30","prefixes":{"":{"product":594}}}, // [AdMan]
+  {"hash":"3e32b1ab3e9c66b6","prefixes":{"":{"product":593}}}, // [Adsit Media Advertising Ltd. Co., (AdMan)]
+  {"hash":"59225b3e2dce506e","prefixes":{"":{"product":595}}}, // [MicroAd Inc. (China)]
+  {"hash":"8a3b315693f80801","prefixes":{"":{"product":595}}}, // [MicroAd Inc. (China)]
+  {"hash":"9ecae05881ad91ad","prefixes":{"":{"product":595}}}, // [MicroAd Inc. (China)]
+  {"hash":"86a1bc63ec059f25","prefixes":{"":{"product":596}}}, // [Adfonic]
+  {"hash":"ea28de00a6512e88","prefixes":{"":{"product":596}}}, // [Adfonic]
+  {"hash":"42bb8749687dee83","prefixes":{"":{"product":597}}}, // [OwnerIQ Inc.]
+  {"hash":"125539a4b58c9087","prefixes":{"":{"product":597}}}, // [OwnerIQ Inc.]
+  {"hash":"895ef87fbdd546df","prefixes":{"":{"product":598}}}, // [Mobile Space Ltd]
+  {"hash":"55e398544c3aeb40","prefixes":{"":{"product":598}}}, // [Mobile Space Ltd]
+  {"hash":"c5e19d61efa129d7","prefixes":{"ap":{"product":598},"e":{"product":598},"":{"product":599}}}, // [Mobile Space Ltd] [Mobile Space Ltd] [Jaduda GmbH]
+  {"hash":"3668b933b223ee50","prefixes":{"":{"product":600}}}, // [Omotenashi Banner]
+  {"hash":"209fb323c4db09ef","prefixes":{"":{"product":600}}}, // [Omotenashi Banner]
+  {"hash":"d95ee45ed75216b1","prefixes":{"":{"product":600}}}, // [Omotenashi Banner]
+  {"hash":"7fb039cd298570d4","prefixes":{"":{"product":600}}}, // [Omotenashi Banner]
+  {"hash":"a7d0a34772320297","prefixes":{"":{"product":600}}}, // [Omotenashi Banner]
+  {"hash":"a86ff9f748f6a5ab","prefixes":{"":{"product":600}}}, // [Omotenashi Banner]
+  {"hash":"046d69c93f0ab29e","prefixes":{"":{"product":601}}}, // [Infectious Media Ltd.]
+  {"hash":"735a86882c4fccc6","prefixes":{"":{"product":602}}}, // [One97 Communications Limited (Ad Works)]
+  {"hash":"c454c081e737b7e2","prefixes":{"":{"product":602}}}, // [One97 Communications Limited (Ad Works)]
+  {"hash":"1e8ed560dc22bbb5","prefixes":{"":{"product":602}}}, // [One97 Communications Limited (Ad Works)]
+  {"hash":"3a57d7982ec36d46","prefixes":{"":{"product":602}}}, // [One97 Communications Limited (Ad Works)]
+  {"hash":"282d5dfa72aee67e","prefixes":{"":{"product":603}}}, // [Walk Light Media Inc.]
+  {"hash":"350189fcd66d737d","prefixes":{"":{"product":604}}}, // [AdBrite Inc.]
+  {"hash":"727c2c9dbde23217","prefixes":{"":{"product":604}}}, // [AdBrite Inc.]
+  {"hash":"f0011932876966b7","prefixes":{"":{"product":605}}}, // [Hi-Media]
+  {"hash":"49a154fb3339d1c9","prefixes":{"":{"product":605}}}, // [Hi-Media]
+  {"hash":"bc9403b31553c2c3","prefixes":{"":{"product":605}}}, // [Hi-Media]
+  {"hash":"4a763539fb83a309","prefixes":{"":{"product":605}}}, // [Hi-Media]
+  {"hash":"ad517dcc393c2311","prefixes":{"":{"product":605}}}, // [Hi-Media]
+  {"hash":"ea321c60d183257c","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"44405675d1af2241","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"703f39c13b597e32","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"5bdae611f2bbe659","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"87862d3ee53095a7","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"376d93acf5e8d717","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"3f0e8ced0049c1d6","prefixes":{"":{"product":606}}}, // [Adlabs]
+  {"hash":"a04ea3bd56ab64bb","prefixes":{"":{"product":607}}}, // [Arth Salutions]
+  {"hash":"b6ce2c8ae8e9a415","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"ebd466a03db9081b","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"2df213fa126d1ca4","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"901ec1b8062c3af6","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"3cdfbabfa37b6bd8","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"4a23a2c45d1e92c3","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"72784278d856920c","prefixes":{"":{"product":608}}}, // [Konverta]
+  {"hash":"61aa8fff3eb4e893","prefixes":{"":{"product":103}}}, // [Cogo Labs, Inc.]
+  {"hash":"def94469bdc7241e","prefixes":{"":{"product":103}}}, // [Cogo Labs, Inc.]
+  {"hash":"f17d17eabacc3756","prefixes":{"":{"product":103}}}, // [Cogo Labs, Inc.]
+  {"hash":"8644dbe4c2172593","prefixes":{"":{"product":609}}}, // [Shopall]
+  {"hash":"4b55c6a7d9c2a9a2","prefixes":{"":{"product":609}}}, // [Shopall]
+  {"hash":"305615cf8dbc9be2","prefixes":{"":{"product":610}}}, // [targeting360 GmbH]
+  {"hash":"bed5b722b1bc1ba5","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"1528f8323f342e8b","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"3c0f20ff410483fa","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"929748002c9b8ecf","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"da8d84b561cc6dae","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"4d73c36d7413bcac","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"fa03c22fb3892bf3","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"9671a9ac26a91d0a","prefixes":{"":{"product":611}}}, // [xplosion interactive GmbH]
+  {"hash":"ca13edee3fffee4e","prefixes":{"":{"product":612}}}, // [Hubrus LLC]
+  {"hash":"e6c8579483f7b40c","prefixes":{"":{"product":612}}}, // [Hubrus LLC]
+  {"hash":"5426e12fbea3fce8","prefixes":{"":{"product":612}}}, // [Hubrus LLC]
+  {"hash":"e1b8d2118c9dc529","prefixes":{"":{"product":613}}}, // [Here Media Inc.]
+  {"hash":"6ab38da002eadbc3","prefixes":{"":{"product":614}}}, // [Silver Egg Technology Co., Ltd.]
+  {"hash":"8ef09da008fcfae7","prefixes":{"":{"product":614}}}, // [Silver Egg Technology Co., Ltd.]
+  {"hash":"f09f918279f1e9ac","prefixes":{"":{"product":614}}}, // [Silver Egg Technology Co., Ltd.]
+  {"hash":"ddfd965ee920e41c","prefixes":{"":{"product":614}}}, // [Silver Egg Technology Co., Ltd.]
+  {"hash":"47758f4c45a57ea4","prefixes":{"":{"product":614}}}, // [Silver Egg Technology Co., Ltd.]
+  {"hash":"9b402085270b3ed3","prefixes":{"":{"product":614}}}, // [Silver Egg Technology Co., Ltd.]
+  {"hash":"5a4e20d5da4d99f0","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"1a32d33420507504","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"c841d6764f10305d","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"c0be785071fbf1f8","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"a48b68d5e7caa5da","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"93764efbaea60a26","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"2d1e1dbc88160b0a","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"49c9a4898d7eda62","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"51f27880010fd487","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"1930e597dd2d66f9","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"9138d5d361766aa2","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"942211eb94fc3c91","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"ac957255586d114c","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"1174020d0986b7c7","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"1386eff7c87966ca","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"d3c3497dc1813ac6","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"ec8bb52d56c92778","prefixes":{"":{"product":615}}}, // [QuarticOn.com]
+  {"hash":"b999321725f081a5","prefixes":{"":{"product":616}}}, // [Kavanga LLC]
+  {"hash":"43f2f88cac5c1e66","prefixes":{"":{"product":617}}}, // [Vodafone D2 GmbH]
+  {"hash":"71f43d2f0436d908","prefixes":{"":{"product":617}}}, // [Vodafone D2 GmbH]
+  {"hash":"4b13b8a28b6556d3","prefixes":{"":{"product":617}}}, // [Vodafone D2 GmbH]
+  {"hash":"b9c154f4d363eebc","prefixes":{"":{"product":618}}}, // [Qubit Digital Ltd]
+  {"hash":"f3c32c6c7e1ac882","prefixes":{"":{"product":538},"ad":{"product":619},"tm":{"product":619}}}, // [Target Performance] [NEORY GmbH] [NEORY GmbH]
+  {"hash":"728524adefe77058","prefixes":{"static-":{"product":620}}}, // [Populis Ireland Limited]
+  {"hash":"7f78aff31bba38ad","prefixes":{"":{"product":620}}}, // [Populis Ireland Limited]
+  {"hash":"cacb07348e9e3ca3","prefixes":{"":{"product":620}}}, // [Populis Ireland Limited]
+  {"hash":"ce069e74d10aa948","prefixes":{"":{"product":621}}}, // [LiquidM Technology GmbH]
+  {"hash":"b6284e5bbeacee78","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"f71102b0f2425eb8","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"da76d0a397ab42fc","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"d30b0fd7cd3dc387","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"d3643510dc9a55a3","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"f74f9b96eb974ad7","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"538d09650aaff88b","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"7533124cd83c8651","prefixes":{"":{"product":622}}}, // [Celtra Inc.]
+  {"hash":"8413a3afa447ddd6","prefixes":{"":{"product":623}}}, // [Adfox]
+  {"hash":"28b1ebc0a8b51b58","prefixes":{"":{"product":623}}}, // [Adfox]
+  {"hash":"0c6cea5dd49d0361","prefixes":{"sd":{"product":623},"rt":{"product":623}}}, // [Adfox] [Adfox]
+  {"hash":"2e3df7d60b00392d","prefixes":{"":{"product":623}}}, // [Adfox]
+  {"hash":"4cdee950d7417a19","prefixes":{"":{"product":623}}}, // [Adfox]
+  {"hash":"2060d81c3f4dbace","prefixes":{"":{"product":624}}}, // [Accordant Media LLC]
+  {"hash":"f2c07b1834365ee5","prefixes":{"":{"product":625}}}, // [Fiksu DSP]
+  {"hash":"c61068cc57f0f219","prefixes":{"":{"product":625}}}, // [Fiksu DSP]
+  {"hash":"a1f4b4a83add949d","prefixes":{"":{"product":625}}}, // [Fiksu DSP]
+  {"hash":"70b9063aeb27d88a","prefixes":{"":{"product":625}}}, // [Fiksu DSP]
+  {"hash":"f66693ef14e4cd79","prefixes":{"":{"product":625}}}, // [Fiksu DSP]
+  {"hash":"7f9c748aa884dba0","prefixes":{"":{"product":626}}}, // [MdotM, Inc.]
+  {"hash":"13c8f5f12f3b9ca6","prefixes":{"":{"product":626}}}, // [MdotM, Inc.]
+  {"hash":"c47f6172a03d7b4c","prefixes":{"":{"product":627}}}, // [TNS GALLUP ADFACT, ZAO]
+  {"hash":"f9a74c430e157e57","prefixes":{"":{"product":627}}}, // [TNS GALLUP ADFACT, ZAO]
+  {"hash":"534ec1b9f199f18a","prefixes":{"":{"product":628}}}, // [MicroAd Inc. (APAC)]
+  {"hash":"98bec02f53970649","prefixes":{"":{"product":628}}}, // [MicroAd Inc. (APAC)]
+  {"hash":"dab5b2f5150fe52c","prefixes":{"*":{"product":629}}}, // [ECRITEL SARL]
+  {"hash":"039caee3c590ef51","prefixes":{"*":{"product":629}}}, // [ECRITEL SARL]
+  {"hash":"56d4c8e77cf378ca","prefixes":{"*":{"product":629}}}, // [ECRITEL SARL]
+  {"hash":"ea054eef4a7b535d","prefixes":{"*":{"product":629}}}, // [ECRITEL SARL]
+  {"hash":"503f3e019cf902f7","prefixes":{"":{"product":104}}}, // [AudienceProject]
+  {"hash":"d07ac29d5418a5a2","prefixes":{"":{"product":104}}}, // [AudienceProject]
+  {"hash":"252a5f53fef3adef","prefixes":{"":{"product":630}}}, // [Gloto Corp.]
+  {"hash":"c45cf16c98289ef3","prefixes":{"":{"product":630}}}, // [Gloto Corp.]
+  {"hash":"43869a9fbc1e93ac","prefixes":{"":{"product":631}}}, // [OOO GPM-Digital]
+  {"hash":"4334255596024dac","prefixes":{"*":{"product":632}}}, // [adverserve digital advertising services]
+  {"hash":"c1cbc8c1a131b486","prefixes":{"":{"product":633}}}, // [Abstract]
+  {"hash":"f0a24e1beb2ff006","prefixes":{"":{"product":633}}}, // [Abstract]
+  {"hash":"5d7848291e6b2aac","prefixes":{"":{"product":633}}}, // [Abstract]
+  {"hash":"678875d741d45390","prefixes":{"":{"product":634}}}, // [Adscale GmbH]
+  {"hash":"bdf162f8a955792f","prefixes":{"":{"product":634}}}, // [Adscale GmbH]
+  {"hash":"e2aa93ef150b6625","prefixes":{"":{"product":634}}}, // [Adscale GmbH]
+  {"hash":"fbecc41bd388e9da","prefixes":{"":{"product":634}}}, // [Adscale GmbH]
+  {"hash":"33d677c1746e032b","prefixes":{"":{"product":634}}}, // [Adscale GmbH]
+  {"hash":"7b632e1d26173d9a","prefixes":{"":{"product":635}}}, // [Weebly, Inc.]
+  {"hash":"d60691434c15d686","prefixes":{"":{"product":636}}}, // [KPI Solutions Co.,Ltd.]
+  {"hash":"6bcb40c428dea82d","prefixes":{"*":{"product":636}}}, // [KPI Solutions Co.,Ltd.]
+  {"hash":"a7261ab41534a5a9","prefixes":{"":{"product":637}}}, // [LuckyBrand.com]
+  {"hash":"8ade692ce59ddf24","prefixes":{"":{"product":638}}}, // [Bedrijvenweb.nl]
+  {"hash":"4f925a01c20725e2","prefixes":{"":{"product":639}}}, // [CacheFly]
+  {"hash":"bd7deac394b9d8ec","prefixes":{"*":{"product":640}}}, // [EdgeCast Networks Inc.]
+  {"hash":"d14784769a5e3e32","prefixes":{"*":{"product":640}}}, // [EdgeCast Networks Inc.]
+  {"hash":"eeb0b9405b4e70a9","prefixes":{"*":{"product":640}}}, // [EdgeCast Networks Inc.]
+  {"hash":"799a922119603cf7","prefixes":{"":{"product":641}}}, // [AdFrontier]
+  {"hash":"b99f16bd08f23e1d","prefixes":{"":{"product":642}}}, // [NFQ]
+  {"hash":"55b741a8d993b7af","prefixes":{"":{"product":642}}}, // [NFQ]
+  {"hash":"7733707370fb05c7","prefixes":{"":{"product":642}}}, // [NFQ]
+  {"hash":"9a42cb5421abffa9","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"47ee3c7f6cf3211f","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"5e4b5dd08e9b52fd","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"6bc3a667cd012222","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"18656382f2827e60","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"c73db0ed241d269e","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"bc0f02a06b74b7a3","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"0405bea2af551e19","prefixes":{"":{"product":643}}}, // [DataLogix, Inc.]
+  {"hash":"c35511ecd49cebb7","prefixes":{"":{"product":644}}}, // [Brightcove]
+  {"hash":"22bfe38898977ed4","prefixes":{"":{"product":644}}}, // [Brightcove]
+  {"hash":"c095755780478f7e","prefixes":{"":{"product":645}}}, // [Experian]
+  {"hash":"0f2014a09acf7abd","prefixes":{"*":{"product":646}}}, // [Facebook Connect]
+  {"hash":"b7c70898d90f5bb3","prefixes":{"*":{"product":646}}}, // [Facebook Connect]
+  {"hash":"18562cb1149fda1e","prefixes":{"*":{"product":647}}}, // [Disqus]
+  {"hash":"37b749b8858eb61b","prefixes":{"*":{"product":648}}}, // [Namecheap.com]
+  {"hash":"3d59be0f5f7101a0","prefixes":{"":{"product":649}}}, // [Polldaddy]
+  {"hash":"510cff549d2cb397","prefixes":{"":{"product":650}}}, // [Outbrain Inc.]
+  {"hash":"e23ebc9959ce4873","prefixes":{"":{"product":650}}}, // [Outbrain Inc.]
+  {"hash":"623fd0210b11d4fb","prefixes":{"":{"product":651}}}, // [Lijit Networks, Inc.]
+  {"hash":"686b7accbfa398fa","prefixes":{"":{"product":651}}}, // [Lijit Networks, Inc.]
+  {"hash":"85c44f0602598dd8","prefixes":{"":{"product":651}}}, // [Lijit Networks, Inc.]
+  {"hash":"a107b1fdcffae5b9","prefixes":{"*":{"product":484}}}, // [NetDNA, LLC]
+  {"hash":"7f37823a3f5c76b3","prefixes":{"*":{"product":652}}}, // [PubMatic]
+  {"hash":"6d306315a1fecfda","prefixes":{"":{"product":653}}}, // [Say Media Inc.]
+  {"hash":"c2568516b08f0d3d","prefixes":{"":{"product":653}}}, // [Say Media Inc.]
+  {"hash":"308d3a8d1ca52ff3","prefixes":{"":{"product":653}}}, // [Say Media Inc.]
+  {"hash":"59e488c5f151e7c3","prefixes":{"":{"product":653}}}, // [Say Media Inc.]
+  {"hash":"7efe6908db5a1d44","prefixes":{"":{"product":654}}}, // [Rubicon Project Turing, Inc. (SSP)]
+  {"hash":"c6ee8faaa7d6734c","prefixes":{"":{"product":655}}}, // [Rubicon Project Edison, Inc. (DSP)]
+  {"hash":"d93c07cc68e53d91","prefixes":{"":{"product":655}}}, // [Rubicon Project Edison, Inc. (DSP)]
+  {"hash":"86ae2b216def9790","prefixes":{"":{"product":655}}}, // [Rubicon Project Edison, Inc. (DSP)]
+  {"hash":"1267f5857549a6ab","prefixes":{"":{"product":655}}}, // [Rubicon Project Edison, Inc. (DSP)]
+  {"hash":"367db80c0776f6d8","prefixes":{"":{"product":655}}}, // [Rubicon Project Edison, Inc. (DSP)]
+  {"hash":"c4c762a7e666da1c","prefixes":{"":{"product":655}}}, // [Rubicon Project Edison, Inc. (DSP)]
+  {"hash":"bb66261f843823d5","prefixes":{"":{"product":656}}}, // [Wordpress Stats]
+  {"hash":"a0f3bb8dcd67010e","prefixes":{"":{"product":656}}}, // [Wordpress Stats]
+  {"hash":"4a423f1da960eda6","prefixes":{"*":{"product":657}}}, // [Twitter]
+  {"hash":"465806fbb3547c25","prefixes":{"*":{"product":657}}}, // [Twitter]
+  {"hash":"13c55ef8102cbdbb","prefixes":{"":{"product":658}}}, // [Yandex LLC]
+  {"hash":"db546baba3acb079","prefixes":{"":{"product":658}}}, // [Yandex LLC]
+  {"hash":"3dd0667dbad0af61","prefixes":{"":{"product":658}}}, // [Yandex LLC]
+  {"hash":"78e224c91aabe6de","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"75acb8a5a60ef63d","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"6f7720a054c19a2b","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"dbd76c26579bf2b1","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"2cd7f311595e164e","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"b08380cf2fcb4415","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"59ac14277edec497","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"88893eeb26e546a0","prefixes":{"":{"product":659}}}, // [Rutarget / Segmento]
+  {"hash":"da151dbe8b815dfb","prefixes":{"":{"product":660}}}, // [Addoor LatinMarkets, SL]
+  {"hash":"b2a44f920e268749","prefixes":{"":{"product":661}}}, // [Kate Spade]
+  {"hash":"96a8c3ab1740bf2f","prefixes":{"":{"product":97}}}, // [Tacoda]
+  {"hash":"95e85e3cbd858779","prefixes":{"":{"product":662}}}, // [TARGUSinfo]
+  {"hash":"dbf2963c9bf26f55","prefixes":{"":{"product":663}}}, // [Adblade]
+  {"hash":"8064758f6c80afed","prefixes":{"":{"product":663}}}, // [Adblade]
+  {"hash":"b7aaa083e4151ca8","prefixes":{"":{"product":663}}}, // [Adblade]
+  {"hash":"f4d5f13eb7d1ba2b","prefixes":{"":{"product":663}}}, // [Adblade]
+  {"hash":"eca68f2e6cd8a07e","prefixes":{"":{"product":664}}}, // [Adiant]
+  {"hash":"30f4c3f682592add","prefixes":{"":{"product":665}}}, // [AddToAny]
+  {"hash":"39b76d24e28075d4","prefixes":{"*":{"product":666}}}, // [Bizo Inc]
+  {"hash":"dabe4d73219c06e0","prefixes":{"":{"product":667}}}, // [Google Analytics]
+  {"hash":"f8c6758a214299be","prefixes":{"":{"product":668}}}, // [Gravatar]
+  {"hash":"0a130612d187bc06","prefixes":{"":{"product":668}}}, // [Gravatar]
+  {"hash":"6802f0145385df51","prefixes":{"":{"product":669}}}, // [MediaGlu]
+  {"hash":"ccbeaf028d3c721b","prefixes":{"":{"product":669}}}, // [MediaGlu]
+  {"hash":"1d7daeed381c33aa","prefixes":{"":{"product":669}}}, // [MediaGlu]
+  {"hash":"038b4d8cab2d2a58","prefixes":{"":{"product":669}}}, // [MediaGlu]
+  {"hash":"bd4919274e19987e","prefixes":{"":{"product":669}}}, // [MediaGlu]
+  {"hash":"dcdf95e5abf7c100","prefixes":{"":{"product":670}}}, // [Tapstream Network Inc.]
+  {"hash":"1f751fd80b11ad3c","prefixes":{"":{"product":671}}}, // [HUNT Mobile Ads]
+  {"hash":"de1c8591006ce969","prefixes":{"":{"product":672}}}, // [Apsalar, Inc.]
+  {"hash":"9fd29903977b5176","prefixes":{"":{"product":672}}}, // [Apsalar, Inc.]
+  {"hash":"c3930fc2f4cd70df","prefixes":{"*":{"product":673}}}, // [Videology DSP]
+  {"hash":"8924b56175f6f114","prefixes":{"":{"product":674}}}, // [Videostrip]
+  {"hash":"f4b2d76af9987952","prefixes":{"":{"product":675}}}, // [Affinity – Hostway Corporation]
+  {"hash":"b11ec5ee5b26491a","prefixes":{"*":{"product":241},"":{"product":676}}}, // [Scene Stealer Ltd.] [Rackspace, US Inc.]
+  {"hash":"5177084498d58bac","prefixes":{"":{"product":676}}}, // [Rackspace, US Inc.]
+  {"hash":"3a0fe0aeaa847996","prefixes":{"*":{"product":676}}}, // [Rackspace, US Inc.]
+  {"hash":"2b344a3d6c766cb7","prefixes":{"":{"product":676}}}, // [Rackspace, US Inc.]
+  {"hash":"a0b6774e583d1787","prefixes":{"":{"product":677}}}, // [Taptica]
+  {"hash":"e6ad999a7fc77500","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"4056609d04bfec9c","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"d1f59501d08f217a","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"bd467d941e65225d","prefixes":{"":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"0de83b2d387d2a84","prefixes":{"*":{"product":241}}}, // [Scene Stealer Ltd.]
+  {"hash":"227a1699196d5009","prefixes":{"":{"product":678}}}, // [LiveRamp, Inc.]
+  {"hash":"2077744d64232ddc","prefixes":{"":{"product":678}}}, // [LiveRamp, Inc.]
+  {"hash":"5ff42e5327d8c926","prefixes":{"":{"product":679}}}, // [Plista GmbH]
+  {"hash":"1d36941de87ee056","prefixes":{"":{"product":679}}}, // [Plista GmbH]
+  {"hash":"0534ec41ce34cced","prefixes":{"":{"product":679}}}, // [Plista GmbH]
+  {"hash":"c5ca32bf780ff41c","prefixes":{"":{"product":680}}}, // [Netquest Ad Tracking]
+  {"hash":"fcb4d508b7c17d00","prefixes":{"":{"product":681}}}, // [Mediasmart Mobile S.L.]
+  {"hash":"32de5cdddc7878d9","prefixes":{"":{"product":681}}}, // [Mediasmart Mobile S.L.]
+  {"hash":"832d7e03cfa50775","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"5d0747bdde7700a5","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"6cda89e3ca547147","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"6825c9c2052b6d49","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"dac91e433fa392a8","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"5112708cd650c1bf","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"8c56edbaad9d7666","prefixes":{"":{"product":682}}}, // [Netshelter Technology Media, Inc.]
+  {"hash":"e3f867313a3a22ff","prefixes":{"*":{"product":683}}}, // [Mixmarket Affiliate Network]
+  {"hash":"337d4f2254b699bd","prefixes":{"":{"product":683}}}, // [Mixmarket Affiliate Network]
+  {"hash":"7dd6cb3709637812","prefixes":{"*":{"product":684}}}, // [Turbobytes]
+  {"hash":"b42ea914a5e25208","prefixes":{"":{"product":685}}}, // [Voodoo Video AG]
+  {"hash":"441e902171e2e03a","prefixes":{"*":{"product":255}}}, // [Google CDN]
+  {"hash":"ed45a52fc3b3ded7","prefixes":{"*":{"product":255}}}, // [Google CDN]
+  {"hash":"b70fc2e7ac8321a4","prefixes":{"*":{"product":255}}}, // [Google CDN]
+  {"hash":"a7ab005368d54a08","prefixes":{"*":{"product":255}}}, // [Google CDN]
+  {"hash":"b3808fd8fb0b9d9b","prefixes":{"*":{"product":255}}}, // [Google CDN]
+  {"hash":"273fe37ef5880422","prefixes":{"lh":{"product":255},"geo":{"product":255}}}, // [Google CDN] [Google CDN]
+  {"hash":"cf71755ff09e2183","prefixes":{"":{"product":255}}}, // [Google CDN]
+  {"hash":"3a32bf25eec1a95b","prefixes":{"*":{"product":686}}}, // [Full Performance]
+  {"hash":"783c5679a80d5c10","prefixes":{"":{"product":687}}}, // [eXelate Inc.]
+  {"hash":"40f709f76b1af3f1","prefixes":{"":{"product":687}}}, // [eXelate Inc.]
+  {"hash":"a97762efe739bb85","prefixes":{"*":{"product":688}}}, // [Oreck Canada]
+  {"hash":"f3460c4c9a5112cc","prefixes":{"":{"product":689}}}, // [Beijing WuShuang Technology Ltd. (AGrant)]
+  {"hash":"1c1f6d178312c71a","prefixes":{"*":{"product":690}}}, // [Limelight]
+  {"hash":"227010fe11d13050","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"5460e19d75ae0d01","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"f132b41fc3fed2c5","prefixes":{"":{"product":692}}}, // [Matomy Media]
+  {"hash":"930103c79d1886c9","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"befa931c2b772e6d","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"e1a46a5a294589c8","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"7aaf1724444529c4","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"a8e6cfd540b8a74b","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"4dd30b722c120fe4","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"5785365f3a4da9e4","prefixes":{"":{"product":693}}}, // [Mail.Ru Group]
+  {"hash":"b4cbadcc4ab58981","prefixes":{"":{"product":694}}}, // [LSi - Lionsoft Studios, spol. s r.o.]
+  {"hash":"a41a0099a363da99","prefixes":{"":{"product":695}}}, // [Adelphic Inc.]
+  {"hash":"9a9d3ceef9c489c7","prefixes":{"":{"product":695}}}, // [Adelphic Inc.]
+  {"hash":"8c652e1d454ab3a2","prefixes":{"":{"product":695}}}, // [Adelphic Inc.]
+  {"hash":"36e0703b50fb3eed","prefixes":{"":{"product":695}}}, // [Adelphic Inc.]
+  {"hash":"a437c97b4d64cafd","prefixes":{"":{"product":696}}}, // [Lincoln Technical Institute, Inc.]
+  {"hash":"f69a68a2d09d0720","prefixes":{"":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"26dfb2b8bad92f4f","prefixes":{"":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"dc67b62ecf5a9b08","prefixes":{"":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"23b6f2b40a209645","prefixes":{"":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"40536f7cc3f3bcdb","prefixes":{"":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"7eab1c802c1cb708","prefixes":{"*":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"8381e43653c976d7","prefixes":{"":{"product":697}}}, // [Smartstream.tv]
+  {"hash":"010611867004fb28","prefixes":{"":{"product":698}}}, // [Reklamport]
+  {"hash":"8c138e749437f931","prefixes":{"":{"product":698}}}, // [Reklamport]
+  {"hash":"735ef6cfbe0d0549","prefixes":{"":{"product":699}}}, // [Fattext LLC (DBA Moolah Media)]
+  {"hash":"7a17aa6bfdfb3de1","prefixes":{"":{"product":699}}}, // [Fattext LLC (DBA Moolah Media)]
+  {"hash":"3c593814e40d8a9e","prefixes":{"":{"product":700}}}, // [MoGo Marketing & Media Inc.]
+  {"hash":"0f36027c1644631a","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"ec8b441e84a18442","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"b923ca8213dfa24a","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"fe0b93fc6d0ad89a","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"b7164c05e2fb0d2f","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"6e085b0ec37b404f","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"d282ecf2666110dd","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"131054b9a54841da","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"556351c03849a4c1","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"bebf7033727205d4","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"e77b9add119d1d72","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"fbcb122264bcdbda","prefixes":{"":{"product":701}}}, // [SA Media, llc]
+  {"hash":"10f64b8265e0b1be","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"cc468e0676f36482","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"a445930c60af8d98","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"63e594feafaae08b","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"045d86072bc5dc10","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"ea9d0ea08d06528d","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"94bc93c21ca5d014","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"bcfa082cf700866c","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"17f352a8e88349c9","prefixes":{"":{"product":702}}}, // [Barons Media LLC]
+  {"hash":"8b18a83b14ef8906","prefixes":{"":{"product":703}}}, // [apprupt GmbH]
+  {"hash":"46ba596945892a31","prefixes":{"":{"product":703}}}, // [apprupt GmbH]
+  {"hash":"b0780943092b032a","prefixes":{"":{"product":703}}}, // [apprupt GmbH]
+  {"hash":"7d76822bfe9ffcd9","prefixes":{"":{"product":703}}}, // [apprupt GmbH]
+  {"hash":"87582b95561cf002","prefixes":{"":{"product":703}}}, // [apprupt GmbH]
+  {"hash":"eb0a0cd03ec7f57b","prefixes":{"":{"product":704}}}, // [PropellerADs media Ltd]
+  {"hash":"73009a8d32988e92","prefixes":{"*":{"product":705}}}, // [CJ Affiliate by Conversant]
+  {"hash":"698b1ec9df8d6759","prefixes":{"*":{"product":705}}}, // [CJ Affiliate by Conversant]
+  {"hash":"00e17f99243707e9","prefixes":{"":{"product":706}}}, // [Millennial Media Inc]
+  {"hash":"62ddc5a87d328e5a","prefixes":{"":{"product":706}}}, // [Millennial Media Inc]
+  {"hash":"0e02d11afea79a5e","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"56b1e984216b464b","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"815a3c2c1ed6f999","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"28175ac65441fbce","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"fe775b2f045dcced","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"d47b0a700d84bfba","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"1c34827419405aee","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"7e99ada6b2533f54","prefixes":{"":{"product":707}}}, // [BEIJING BEHE SCIENCE & TECHNOLOGY Co., Ltd]
+  {"hash":"2c5ac4af628363a6","prefixes":{"*":{"product":708}}}, // [Manage.com Group, Inc.]
+  {"hash":"f05737fe4b72d22f","prefixes":{"":{"product":709}}}, // [CloudFlare, Inc.]
+  {"hash":"1b728798f387160d","prefixes":{"":{"product":710}}}, // [MASSMOTIONMEDIA SARL]
+  {"hash":"fb80c91c77673741","prefixes":{"":{"product":711}}}, // [Brainworks Sp. z.o.o.]
+  {"hash":"6ff7dff7c1404e1b","prefixes":{"":{"product":711}}}, // [Brainworks Sp. z.o.o.]
+  {"hash":"bd6c259e3bb98101","prefixes":{"":{"product":711}}}, // [Brainworks Sp. z.o.o.]
+  {"hash":"0dcb02764319e823","prefixes":{"":{"product":711}}}, // [Brainworks Sp. z.o.o.]
+  {"hash":"258ec0f081f1c767","prefixes":{"":{"product":711}}}, // [Brainworks Sp. z.o.o.]
+  {"hash":"518594f7ef9754dc","prefixes":{"*":{"product":712}}}, // [Media Intelligence Platform (Aggregate Knowledge)]
+  {"hash":"223b1b79a6de9f04","prefixes":{"*":{"product":712}}}, // [Media Intelligence Platform (Aggregate Knowledge)]
+  {"hash":"848f45768ee0ad4e","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"77b7e5f4ec17a6e5","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"f965c1f8d2cce837","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"3e327352cea146b3","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"0658ca5e4baec224","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"f2e7a2604319636b","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"c825977950596abc","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"b55fc4c23b864e56","prefixes":{"":{"product":713}}}, // [S4M]
+  {"hash":"3eddbbcdb5a13a1b","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"f133f36dd9e9688d","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"06ead346af8ecc6d","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"16a442ad35246027","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"778068a948335ee6","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"2bb088766e0a77ce","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"f54b41faf3e29ddb","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"3d71c7985374fc62","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"de336679348d46a5","prefixes":{"":{"product":714}}}, // [Sobmag LTD]
+  {"hash":"6818fc4cb694f0d4","prefixes":{"*":{"product":715}}}, // [Netbooster]
+  {"hash":"5682fbd14ad230ca","prefixes":{"":{"product":716}}}, // [Musikhaus Thomann e.K.]
+  {"hash":"abbb14ff2ab0311d","prefixes":{"":{"product":716}}}, // [Musikhaus Thomann e.K.]
+  {"hash":"578726cfc508157e","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"a141aaa30beb2f05","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"9161fa28951da89a","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"2e52f74b27e9eb2f","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"0ecdef2f55913790","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"409546c7e7a9ce63","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"3dceafc40a01cd8c","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"e748a008fcd2910c","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"499e3537aead5990","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"aad99655e792b7af","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"df381181135b37f3","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"49fe77e073f907d5","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"fe445db4579e7177","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"f7038d35f22c32db","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"184913b8eec78f63","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"4db6f08af3d6cf66","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"0a71646e475ff9c1","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"7847dd8c5608a507","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"cde33b0511f42c7c","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"6a5ae5d2380647dc","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"0821cc1422e91328","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"0e157baa999502bc","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"cb93fe6df3fe4097","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"657c19e08d899173","prefixes":{"":{"product":146}}}, // [SiteScout AdServer]
+  {"hash":"e411fd988f243d89","prefixes":{"":{"product":717}}}, // [Trovit]
+  {"hash":"1ea512003540106b","prefixes":{"":{"product":717}}}, // [Trovit]
+  {"hash":"48255f09ec2021d3","prefixes":{"":{"product":717}}}, // [Trovit]
+  {"hash":"7b5b7cfa3d62a886","prefixes":{"":{"product":717}}}, // [Trovit]
+  {"hash":"1235b8279a106276","prefixes":{"":{"product":718}}}, // [O2online]
+  {"hash":"cf76706eea2f0be6","prefixes":{"":{"product":719}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
+  {"hash":"766b747f8dec4417","prefixes":{"":{"product":720}}}, // [Meteora]
+  {"hash":"270677f86b7f115b","prefixes":{"":{"product":720}}}, // [Meteora]
+  {"hash":"0a500f94a8a562f0","prefixes":{"":{"product":721}}}, // [Madison Logic, Inc.]
+  {"hash":"764d3a17a9512438","prefixes":{"":{"product":721}}}, // [Madison Logic, Inc.]
+  {"hash":"38c3aac1b79f0478","prefixes":{"":{"product":721}}}, // [Madison Logic, Inc.]
+  {"hash":"babcc401d384553f","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"2ddae58a55ab72ef","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"db564708d2871d3a","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"a4199cfcbe70d7f5","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"e6f5851275bc1fb3","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"16e6d7e84ad7fa3a","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"58ae73a3bb4327d7","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"366a0ad35670aef5","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"5b30682b9dfa7060","prefixes":{"":{"product":722}}}, // [万相DSP(IZP Technologies)]
+  {"hash":"67128a22cdd1a7cd","prefixes":{"":{"product":23}}}, // [AppNexus Open AdStream]
+  {"hash":"db56992e1a1a3f90","prefixes":{"":{"product":723}}}, // [righTarget]
+  {"hash":"479ab75d77a40d72","prefixes":{"":{"product":723}}}, // [righTarget]
+  {"hash":"17bcd2af46fb1fe6","prefixes":{"":{"product":723}}}, // [righTarget]
+  {"hash":"45681f09a76fe33e","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"612f6aab80bc21df","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"ab7e80409519ca9d","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"a3ae7b8a84f28040","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"b25f21b316565014","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"cc9eeba2126e4261","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"9d4819b235a5272b","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"78bb032f283d8f48","prefixes":{"":{"product":725}}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
+  {"hash":"de11a5b150526c21","prefixes":{"":{"product":725}}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
+  {"hash":"bbd9e4a668c4e348","prefixes":{"":{"product":725}}}, // [Shen Zhen ShiJi KaiXuan Technology Company Ltd.]
+  {"hash":"c38a1d9eab08d787","prefixes":{"*":{"product":724}}}, // [e.QQ.com]
+  {"hash":"5b2c8d90176bd14e","prefixes":{"":{"product":724}}}, // [e.QQ.com]
+  {"hash":"62980dc2fa42e1e0","prefixes":{"*":{"product":724}}}, // [e.QQ.com]
+  {"hash":"9b37bab01bf28d39","prefixes":{"*":{"product":726}}}, // [Bannercockpit]
+  {"hash":"01ec60ee4671b195","prefixes":{"":{"product":727}}}, // [Outrigger Media Inc.]
+  {"hash":"4be86c0a73547960","prefixes":{"":{"product":727}}}, // [Outrigger Media Inc.]
+  {"hash":"e3ab574adac96838","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"91bb53a0f22994f8","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"fd65eb28a70ed09a","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"9f41f821ddcb5092","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"ee70168f83fb2cce","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"c15fc4a18b25e6d3","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"f5f66dfaf3d2d2a3","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"e6e8716836c8a21d","prefixes":{"":{"product":105}}}, // [Rockabox Media Ltd]
+  {"hash":"da37db68457e2782","prefixes":{"*":{"product":728}}}, // [shopLocal]
+  {"hash":"ab8c1ee046adfbb1","prefixes":{"*":{"product":729}}}, // [Impact Radius]
+  {"hash":"0e8c1ff7462c1084","prefixes":{"*":{"product":729}}}, // [Impact Radius]
+  {"hash":"8f228d8317e4718d","prefixes":{"":{"product":729}}}, // [Impact Radius]
+  {"hash":"29d7e31af4b1be0b","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"efeab3df1fe3849a","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"8f2fea31a1c79b34","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"9cda8eeaf1e150bf","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"714091c1b8581de0","prefixes":{"":{"product":731}}}, // [Unister Media GmbH]
+  {"hash":"c7002b2b9e4b5370","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"1802591342537dae","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"787cbd14bb54b647","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"084ef5666af6a26c","prefixes":{"":{"product":730}}}, // [Unister AdServer]
+  {"hash":"df72b5eb4be388d1","prefixes":{"":{"product":732}}}, // [TLV Media Online Ltd]
+  {"hash":"64ffcabaf6ec2bcf","prefixes":{"":{"product":733}}}, // [d3media AG]
+  {"hash":"a6d58332a182c9f4","prefixes":{"":{"product":733}}}, // [d3media AG]
+  {"hash":"0bbd108959983b32","prefixes":{"":{"product":734}}}, // [Innovative Metrics]
+  {"hash":"80eab7dfc5e4cc5f","prefixes":{"*":{"product":735}}}, // [AthenaHealth]
+  {"hash":"131ce36599fa0d6c","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"9181181a015040bc","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"fca830abc4829657","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"e78333a733c1b05a","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"3f82423bd28a526a","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"f2da501e4086afa3","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"719080d33b283abc","prefixes":{"":{"product":736}}}, // [TAPVALUE SAS]
+  {"hash":"3502e0d544b9b739","prefixes":{"":{"product":737}}}, // [Meteor Worldwide LLC.]
+  {"hash":"a6227ad6f805c298","prefixes":{"":{"product":737}}}, // [Meteor Worldwide LLC.]
+  {"hash":"0933cf49bb328213","prefixes":{"*":{"product":189}}}, // [Relay42 Technology B.V.]
+  {"hash":"bea1d6b2a32d3927","prefixes":{"*":{"product":189}}}, // [Relay42 Technology B.V.]
+  {"hash":"8d1313bfd522fcf6","prefixes":{"":{"product":738}}}, // [Audience2Media Limited]
+  {"hash":"ec4f449051680a17","prefixes":{"":{"product":738}}}, // [Audience2Media Limited]
+  {"hash":"9badeeb4c9cff3b3","prefixes":{"":{"product":739}}}, // [HRB Digital LLC.]
+  {"hash":"e0e362bb66a6c5dd","prefixes":{"*":{"product":740}}}, // [!NOOB]
+  {"hash":"e1e1866cde6f23c7","prefixes":{"":{"product":163}}}, // [Tagtoo Tech Limited]
+  {"hash":"60a41acd40c494b4","prefixes":{"":{"product":163}}}, // [Tagtoo Tech Limited]
+  {"hash":"4dbc45b703241615","prefixes":{"":{"product":163}}}, // [Tagtoo Tech Limited]
+  {"hash":"d11722ff46ba063b","prefixes":{"":{"product":163}}}, // [Tagtoo Tech Limited]
+  {"hash":"706cd1e56e4ca9f0","prefixes":{"":{"product":163}}}, // [Tagtoo Tech Limited]
+  {"hash":"eabe2f56a564ea71","prefixes":{"":{"product":125}}}, // [Mocean mobile, Inc.]
+  {"hash":"9ab3f80172f06a67","prefixes":{"":{"product":125}}}, // [Mocean mobile, Inc.]
+  {"hash":"19c44c882811c0bd","prefixes":{"":{"product":741}}}, // [OSV online]
+  {"hash":"1f888bdc491d19c5","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"3259bacc0853f3ce","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"4a7fe8ed74a69bb1","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"72680bf564258b75","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"d25a0b5dd4617071","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"4e53e370f5c0d9c8","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"2585ec8519ec2a03","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"9ebfdd26621d46c7","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"083fd3b939cbd105","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"3fd28ace41da6736","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"3f5d8ed1881e0849","prefixes":{"":{"product":742}}}, // [Addroid™]
+  {"hash":"4f0f13d0fae2b262","prefixes":{"":{"product":743}}}, // [AdAccess]
+  {"hash":"5a40dbdf15bc0d0c","prefixes":{"":{"product":743}}}, // [AdAccess]
+  {"hash":"0eff5ff163f074f0","prefixes":{"":{"product":743}}}, // [AdAccess]
+  {"hash":"f5ce32de4ea8770e","prefixes":{"":{"product":743}}}, // [AdAccess]
+  {"hash":"8a367cea803ead3b","prefixes":{"":{"product":743}}}, // [AdAccess]
+  {"hash":"960b38f18a31bf7f","prefixes":{"":{"product":743}}}, // [AdAccess]
+  {"hash":"45b03c5f8881301a","prefixes":{"":{"product":744}}}, // [Yabuka Media, Inc.]
+  {"hash":"c2875e9f5741c896","prefixes":{"":{"product":744}}}, // [Yabuka Media, Inc.]
+  {"hash":"46751092d6f82d66","prefixes":{"":{"product":744}}}, // [Yabuka Media, Inc.]
+  {"hash":"379f0fda3a2142b3","prefixes":{"*":{"product":745}}}, // [Highwinds CDN]
+  {"hash":"5033b8e8796bc944","prefixes":{"":{"product":746}}}, // [Bridgewell Incorporated]
+  {"hash":"fcbb4f6f5d116bcf","prefixes":{"":{"product":746}}}, // [Bridgewell Incorporated]
+  {"hash":"6d68bbc023aff7a8","prefixes":{"":{"product":746}}}, // [Bridgewell Incorporated]
+  {"hash":"98a17e63899d6f0f","prefixes":{"":{"product":746}}}, // [Bridgewell Incorporated]
+  {"hash":"1cae38f50bbcbe1a","prefixes":{"":{"product":746}}}, // [Bridgewell Incorporated]
+  {"hash":"df13ce542b6c0e84","prefixes":{"":{"product":747}}}, // [Bidtheatre AB]
+  {"hash":"f9e2fc82f27f7b60","prefixes":{"":{"product":747}}}, // [Bidtheatre AB]
+  {"hash":"0d324dc8c79d8b3c","prefixes":{"":{"product":747}}}, // [Bidtheatre AB]
+  {"hash":"1d9569d0ee02dcee","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"73bd54b1be5e9df1","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"dae6130e1d796d90","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"53335dc721cbee0b","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"ae279eee4c5b4941","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"684276719f3b5728","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"b7376659acddae09","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"aa7f623da51e1603","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"6785583c4297f7c5","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"20138e51a97d179b","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"cc3a77dca011bc78","prefixes":{"":{"product":748}}}, // [AdMoment]
+  {"hash":"6d441f7565cc5de4","prefixes":{"":{"product":749}}}, // [UDG München GmbH]
+  {"hash":"f8c1c6199f46e722","prefixes":{"":{"product":749}}}, // [UDG München GmbH]
+  {"hash":"151a96d84e31a957","prefixes":{"":{"product":749}}}, // [UDG München GmbH]
+  {"hash":"5d34fdb93148d891","prefixes":{"":{"product":750}}}, // [Pixalate, Inc.]
+  {"hash":"6855407f17ce6aec","prefixes":{"":{"product":750}}}, // [Pixalate, Inc.]
+  {"hash":"b9f9a074ce5d4d07","prefixes":{"":{"product":750}}}, // [Pixalate, Inc.]
+  {"hash":"41ddcdd6ba9e42fe","prefixes":{"":{"product":750}}}, // [Pixalate, Inc.]
+  {"hash":"c72923bea1fa64ce","prefixes":{"":{"product":751}}}, // [InMobi Inc.]
+  {"hash":"9085e035c617887b","prefixes":{"":{"product":751}}}, // [InMobi Inc.]
+  {"hash":"0f7037ee4e476493","prefixes":{"":{"product":751}}}, // [InMobi Inc.]
+  {"hash":"bdfbe6247c640d80","prefixes":{"":{"product":752}}}, // [Crisp Media Inc.]
+  {"hash":"2cb723bdc82533b2","prefixes":{"":{"product":752}}}, // [Crisp Media Inc.]
+  {"hash":"be72bf3ef3e3bd14","prefixes":{"":{"product":752}}}, // [Crisp Media Inc.]
+  {"hash":"3af5f91fedb0e598","prefixes":{"":{"product":752}}}, // [Crisp Media Inc.]
+  {"hash":"9feb6dbe57a5ab9b","prefixes":{"":{"product":752}}}, // [Crisp Media Inc.]
+  {"hash":"1953012d699dc24e","prefixes":{"":{"product":753}}}, // [Choozle, Inc.]
+  {"hash":"560479fb0478e76e","prefixes":{"":{"product":753}}}, // [Choozle, Inc.]
+  {"hash":"fb3c191358de9e97","prefixes":{"*":{"product":754}}}, // [Tapad]
+  {"hash":"faa63745af097785","prefixes":{"*":{"product":755}}}, // [ReachLocal, Inc]
+  {"hash":"c6a0024a8fdbd244","prefixes":{"":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"1b09e9588e619f63","prefixes":{"":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"c923ecff86d0026f","prefixes":{"":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"0b38e9ab66f134b5","prefixes":{"":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"b07b0a6a32b39c67","prefixes":{"rtb-":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"a66019bd1d8d6523","prefixes":{"":{"product":757}}}, // [OpenX]
+  {"hash":"3461a8e14dfa7234","prefixes":{"*":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"50f406d696ea09e2","prefixes":{"*":{"product":756}}}, // [OpenX Ad Exchange]
+  {"hash":"28f15a404c22c5ae","prefixes":{"":{"product":758}}}, // [Placester, Inc.]
+  {"hash":"2eabf2a9cc47f6db","prefixes":{"":{"product":758}}}, // [Placester, Inc.]
+  {"hash":"04e56c0e39ffb379","prefixes":{"":{"product":759}}}, // [Spiceworks, Inc]
+  {"hash":"a342cde98acae2a3","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"816943ad229d59bd","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"9aeccecf18437372","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"e24006f3d8614cdf","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"2678adb8d16c1bd0","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"690b9d06ee7b618c","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"ba64173aac6883fa","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"3f334c96b9489b6f","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"4acb6ede5efaa0ce","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"f848368a90033112","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"fc58526ac2c34887","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"bcec64a939aa6248","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"2237ba07a36c2440","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"9b1bd3e45cc8d37b","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"f9447e97a352a2e8","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"4aa3c10d0fa51575","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"edb1b5b0a2ecd2b9","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"3eee53fed713d5b2","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"5562c787acd84d8d","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"27d45cd108fe99b4","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"06da026d99fd30c4","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"43e91c0e2d266107","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"2b8ee71c143b611a","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"31773affdbc2f93f","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"24f5edbbeab30fc6","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"b1275f1680c5e050","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"1f0e98fd24844df9","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"207973ef90437496","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"5e573612b3181547","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"5237a5b231dbf245","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"b4872bd493703ef0","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"7268f40680faccfd","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"f18cc00e2cfb170d","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"2be692602def45f7","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"5d15e875488cccd1","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"7da3afc36d1c6b59","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"e0767b1a03a64ce6","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"202d0d2b1168aeb8","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"5e070df0dbe151e6","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"e4337ec6681cbc61","prefixes":{"":{"product":760}}}, // [WapStart]
+  {"hash":"944f2609259bac7c","prefixes":{"":{"product":761}}}, // [Ambercrow (Epayments)]
+  {"hash":"8bcd6f943c02d066","prefixes":{"":{"product":761}}}, // [Ambercrow (Epayments)]
+  {"hash":"f0529ee08a090045","prefixes":{"":{"product":761}}}, // [Ambercrow (Epayments)]
+  {"hash":"f44423b0de62f78e","prefixes":{"":{"product":761}}}, // [Ambercrow (Epayments)]
+  {"hash":"00fb6871b70e1fd9","prefixes":{"":{"product":761}}}, // [Ambercrow (Epayments)]
+  {"hash":"588e459942f9f953","prefixes":{"":{"product":762}}}, // [Audiencevalue Pte Ltd]
+  {"hash":"2b94a7bb996b3a9c","prefixes":{"":{"product":762}}}, // [Audiencevalue Pte Ltd]
+  {"hash":"5796b5e246266e0c","prefixes":{"":{"product":763}}}, // [UNITED. Inc.]
+  {"hash":"aa1ee475645d94b7","prefixes":{"":{"product":763}}}, // [UNITED. Inc.]
+  {"hash":"716f227b7327feba","prefixes":{"":{"product":763}}}, // [UNITED. Inc.]
+  {"hash":"44c3a88f2dcdee6f","prefixes":{"":{"product":764}}}, // [United Bypass Tech]
+  {"hash":"0f010d866f5763fa","prefixes":{"":{"product":765}}}, // [SAS Naoplay]
+  {"hash":"6a978d7b8efc594d","prefixes":{"":{"product":765}}}, // [SAS Naoplay]
+  {"hash":"d3e10ee4fc900d26","prefixes":{"":{"product":765}}}, // [SAS Naoplay]
+  {"hash":"e83a4038aff02b6e","prefixes":{"":{"product":765}}}, // [SAS Naoplay]
+  {"hash":"acce217e5e09149a","prefixes":{"":{"product":765}}}, // [SAS Naoplay]
+  {"hash":"3a93fbc111c8603f","prefixes":{"":{"product":766}}}, // [CuriosityStream]
+  {"hash":"065426aaa5552ffe","prefixes":{"":{"product":767}}}, // [Alliance Internet (ntree)]
+  {"hash":"9a843715746291f3","prefixes":{"":{"product":767}}}, // [Alliance Internet (ntree)]
+  {"hash":"2d4ed5b7f85f950a","prefixes":{"n":{"product":767}}}, // [Alliance Internet (ntree)]
+  {"hash":"86f628e66b67be4d","prefixes":{"":{"product":768}}}, // [Centraltag]
+  {"hash":"419e8a03b3f16a8c","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"b9ee79ef4e8c15f5","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"46e3b67ae4549155","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"3064ccb85e72d2df","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"1b58e47cefd5e220","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"93b3f973b09c5513","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"607d4f0311eec7af","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"311502ef7317df7d","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"cdf3897e12242607","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"a5a0d71d2f6b631c","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"10f5415b8d24f2b0","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"c126382fcba55688","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"a92d9d96a9338816","prefixes":{"":{"product":769}}}, // [eTargeting]
+  {"hash":"74549e43319467f8","prefixes":{"":{"product":770}}}, // [Walmart Inc]
+  {"hash":"3d8d433ae123d216","prefixes":{"":{"product":770}}}, // [Walmart Inc]
+  {"hash":"6baa1cd3500dc43f","prefixes":{"":{"product":771}}}, // [Walmart.com]
+  {"hash":"12bc009e74ca3655","prefixes":{"":{"product":770}}}, // [Walmart Inc]
+  {"hash":"abb8ec1b9995e7db","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"a489082dd8c6d1b0","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"b8eaffd4f3298628","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"fa888dd08124e8f6","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"d33163e42a34ac6b","prefixes":{"":{"product":773}}}, // [Extreme Reach Digital (ER Digital)]
+  {"hash":"26271fd98d79e29f","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"f958e80b82fbeb15","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"0efc1cccd29292d2","prefixes":{"*":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"ec1cfeb7c8ad8e74","prefixes":{"*":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"06ea295dea974069","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"166f6d9041d2cffe","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"d209952bca4546fc","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"8977e19e27e82a31","prefixes":{"":{"product":772}}}, // [Extreme Reach, Inc.]
+  {"hash":"f276cc84c3030bf7","prefixes":{"":{"product":774}}}, // [Netflix]
+  {"hash":"cf97c9d0a75da1fb","prefixes":{"":{"product":774}}}, // [Netflix]
+  {"hash":"acf43321c04d641b","prefixes":{"":{"product":774}}}, // [Netflix]
+  {"hash":"bb55681ae13b2fa8","prefixes":{"":{"product":774}}}, // [Netflix]
+  {"hash":"2d5400efd94a66d0","prefixes":{"":{"product":774}}}, // [Netflix]
+  {"hash":"c4a2daa282a0af48","prefixes":{"":{"product":774}}}, // [Netflix]
+  {"hash":"670a8e12f579ee63","prefixes":{"":{"product":775}}}, // [Netflix, Inc.]
+  {"hash":"15b7e69ddffa3a8c","prefixes":{"":{"product":775}}}, // [Netflix, Inc.]
+  {"hash":"7b7add7c969d93fe","prefixes":{"*":{"product":776}}}, // [Scarab Personalized Ads]
+  {"hash":"4e1907aa0eb0ff71","prefixes":{"":{"product":776}}}, // [Scarab Personalized Ads]
+  {"hash":"a3315978597aa707","prefixes":{"":{"product":777}}}, // [CrowdMob Inc.]
+  {"hash":"452715cede41650c","prefixes":{"":{"product":778}}}, // [Gruvi Ltd.]
+  {"hash":"36ce2eb140f75f32","prefixes":{"":{"product":777}}}, // [CrowdMob Inc.]
+  {"hash":"ae6b13daf4bc714d","prefixes":{"":{"product":106}}}, // [PocketMath]
+  {"hash":"13696777dabedeae","prefixes":{"":{"product":779}}}, // [Macromill, Inc.]
+  {"hash":"9971928c88e3fa4e","prefixes":{"*":{"product":780}}}, // [Nielsen (Cross Platform Brand Effect [IAG/TVBE])]
+  {"hash":"65df6515d4615cea","prefixes":{"f":{"product":781},"vast-":{"product":781},"ivid-":{"product":781}}}, // [GetIntent] [GetIntent] [GetIntent]
+  {"hash":"b54db54df2c407f8","prefixes":{"":{"product":781}}}, // [GetIntent]
+  {"hash":"2258062bb1ab01dd","prefixes":{"":{"product":781}}}, // [GetIntent]
+  {"hash":"630338f7109ea305","prefixes":{"*":{"product":781}}}, // [GetIntent]
+  {"hash":"b3c93c6142991123","prefixes":{"":{"product":781}}}, // [GetIntent]
+  {"hash":"6ef8d315575de4c7","prefixes":{"":{"product":781}}}, // [GetIntent]
+  {"hash":"b7769b25a2035147","prefixes":{"vid-":{"product":781}}}, // [GetIntent]
+  {"hash":"2e2859be7da1ee82","prefixes":{"":{"product":782}}}, // [Belboon]
+  {"hash":"ff591094a6a13480","prefixes":{"*":{"product":783}}}, // [Ozone Media Solutions Pvt Ltd]
+  {"hash":"3bd09c8fad6ac0cd","prefixes":{"*":{"product":783}}}, // [Ozone Media Solutions Pvt Ltd]
+  {"hash":"41385cd812900dd3","prefixes":{"*":{"product":783}}}, // [Ozone Media Solutions Pvt Ltd]
+  {"hash":"78bdf43617c9f3ed","prefixes":{"":{"product":784}}}, // [Hindustan Times Mobile Solutions Limited]
+  {"hash":"f669a1035330e753","prefixes":{"*":{"product":783}}}, // [Ozone Media Solutions Pvt Ltd]
+  {"hash":"74c5a373ee6172a1","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"3762c6694e48ada4","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"885e91388dd960b6","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"f6a553969be0331b","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"48d6fc29b318593f","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"1e571da94b4242ba","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"e6770fd6222ae990","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"20b17ee9acc1afb9","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"c483854c67d0c950","prefixes":{"":{"product":785}}}, // [SoftLayer Technologies, Inc.]
+  {"hash":"5214f14e27a71d7f","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"61c576ffa8275ef3","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"c6af9ddc14757f86","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"86e9128d66cc0207","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"c71d0bd2e6f83f82","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"97be67a3b0baedf9","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"9622fe3e417564fb","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"a63ebe94fca61ed9","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"bbc1dd12d3cdb0b4","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"962da7f5c63ff169","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"94bb51394747c625","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"3ff8867b3d239d21","prefixes":{"":{"product":786}}}, // [GoldSpot Media]
+  {"hash":"a970a6e82a98c461","prefixes":{"":{"product":787}}}, // [Zeeto Media]
+  {"hash":"4c975affcaea9100","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"dfd86d0838962249","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"91f2b2338b35b7b2","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"3bec5ca280ea1b83","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"3d88758bd6e0003a","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"5c4e7b396a2ff6d6","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"a95488bd107fec32","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"aa8e84bd80448410","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"63a0cca4218135c9","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"91a1733ac5874a1c","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"5c8abc657915fd35","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"917cc91081fe5b07","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"a53545381bdd0cbf","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"4bc186645ccbf442","prefixes":{"":{"product":788}}}, // [DYNADMIC SAS]
+  {"hash":"3d6ddf04f9124237","prefixes":{"":{"product":789}}}, // [Yoc Mobile Advertising GmbH]
+  {"hash":"ec5fe7560209f819","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"5fe3e321ae6e4bf6","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"8be056c242dd9d72","prefixes":{"":{"product":359}}}, // [Quantcast Inc.]
+  {"hash":"f8ee5abf7ea1abc7","prefixes":{"":{"product":790}}}, // [Velti]
+  {"hash":"59f840ce07769698","prefixes":{"":{"product":790}}}, // [Velti]
+  {"hash":"e013843f461a8d4b","prefixes":{"":{"product":790}}}, // [Velti]
+  {"hash":"bfe3cf089cc18922","prefixes":{"":{"product":790}}}, // [Velti]
+  {"hash":"9bd20c9549f20865","prefixes":{"":{"product":791}}}, // [Lockon]
+  {"hash":"f24f331de69a707a","prefixes":{"":{"product":791}}}, // [Lockon]
+  {"hash":"566f866251bd714e","prefixes":{"":{"product":791}}}, // [Lockon]
+  {"hash":"4baa350d3cc68f76","prefixes":{"":{"product":792}}}, // [Recruit Co., Ltd. Communications]
+  {"hash":"9bc564a146df07e7","prefixes":{"":{"product":792}}}, // [Recruit Co., Ltd. Communications]
+  {"hash":"35c56cfd7e378fad","prefixes":{"":{"product":793}}}, // [RECRUIT Communications]
+  {"hash":"6b9aad5cb94eb206","prefixes":{"":{"product":793}}}, // [RECRUIT Communications]
+  {"hash":"671a4bc2e5c9113e","prefixes":{"":{"product":794}}}, // [Hatena Co., Ltd]
+  {"hash":"6d3fdce985f31bd4","prefixes":{"":{"product":795}}}, // [Trafmag]
+  {"hash":"1a311d346529c16b","prefixes":{"":{"product":795}}}, // [Trafmag]
+  {"hash":"cd26b0ae13c2440e","prefixes":{"":{"product":796}}}, // [Pagewoo]
+  {"hash":"06e9b4b216458951","prefixes":{"":{"product":797}}}, // [Adnet Media]
+  {"hash":"cc0e43344ef5e735","prefixes":{"":{"product":797}}}, // [Adnet Media]
+  {"hash":"2bff36578242b6b3","prefixes":{"":{"product":797}}}, // [Adnet Media]
+  {"hash":"6bcb758317103435","prefixes":{"":{"product":797}}}, // [Adnet Media]
+  {"hash":"5819339a3e48afa9","prefixes":{"":{"product":797}}}, // [Adnet Media]
+  {"hash":"4249805768b5eaf7","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"c5d5cf4beb6462cf","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"41b628c1a22b441e","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"88d751d3810273e3","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"41ec9f7d9d627e03","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"02eb3f21dd6df789","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"6b48a245a94ab12a","prefixes":{"":{"product":798}}}, // [Ligatus GmbH]
+  {"hash":"41d07cfbdb75024a","prefixes":{"":{"product":799}}}, // [Webtrekk GmbH]
+  {"hash":"be359c4fcc3f3a06","prefixes":{"":{"product":799}}}, // [Webtrekk GmbH]
+  {"hash":"6f767739019dd808","prefixes":{"":{"product":799}}}, // [Webtrekk GmbH]
+  {"hash":"f253ef05e042b018","prefixes":{"":{"product":800}}}, // [Kantar World Panel]
+  {"hash":"d01896485cd39018","prefixes":{"":{"product":800}}}, // [Kantar World Panel]
+  {"hash":"0e0818ed2e61ee95","prefixes":{"":{"product":801}}}, // [PubSquared LLC]
+  {"hash":"b05f21964e55a827","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"d333d9afb4898681","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"1639db8eb5956a46","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"5549a4c097f9b83d","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"1dbbc11fea26048b","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"098ed47c32246e74","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"48556c67606eaf5a","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"e9846bc3bb03a920","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"49353a0b9f2b5bb5","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"96bcc9c54b64eb5b","prefixes":{"":{"product":802}}}, // [Baidu.com Times Technology (Beijing) Co., Ltd]
+  {"hash":"f6e1c581da74f06c","prefixes":{"":{"product":803}}}, // [travel audience GmbH]
+  {"hash":"a00eb1259ded5bb1","prefixes":{"":{"product":803}}}, // [travel audience GmbH]
+  {"hash":"8026726dce357c58","prefixes":{"":{"product":804}}}, // [Krux Digital, Inc.]
+  {"hash":"95e17daf76b8a492","prefixes":{"":{"product":804}}}, // [Krux Digital, Inc.]
+  {"hash":"e2aedb8e35ba9ad0","prefixes":{"":{"product":804}}}, // [Krux Digital, Inc.]
+  {"hash":"7e954379b20a3955","prefixes":{"":{"product":804}}}, // [Krux Digital, Inc.]
+  {"hash":"bb2cd97362773074","prefixes":{"":{"product":804}}}, // [Krux Digital, Inc.]
+  {"hash":"5f545b8ac29b5d2d","prefixes":{"":{"product":805}}}, // [The Weather Channel]
+  {"hash":"188340d4038f111f","prefixes":{"":{"product":805}}}, // [The Weather Channel]
+  {"hash":"88ce1340354cf56f","prefixes":{"":{"product":805}}}, // [The Weather Channel]
+  {"hash":"6aa9e1031d5ce5ea","prefixes":{"":{"product":806}}}, // [Social Quantum]
+  {"hash":"924b0bbf98095055","prefixes":{"":{"product":806}}}, // [Social Quantum]
+  {"hash":"a8316ec9f577d677","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"4987a53ffae0e799","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"afafb80716e16e29","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"d0487d64f040dbfa","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"2c543734a4cbc5dd","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"067045f689cb5363","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"7ff291f0586a3dca","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"0a19a7d8484e10da","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"4614ce2d8cea29b5","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"c3164e283cfacd29","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"a1df629f546b9e31","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"6cbf35f72f18a347","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"1cb0768d21f55dd6","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"085272e0502f18c3","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"64b888da84877b17","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"c579af2db70b5cc0","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"306de8baaf32da18","prefixes":{"":{"product":807}}}, // [AdVentori SAS]
+  {"hash":"1e9f7eb550327800","prefixes":{"":{"product":808}}}, // [MindTake Research GmbH]
+  {"hash":"1c922be621564b9b","prefixes":{"":{"product":808}}}, // [MindTake Research GmbH]
+  {"hash":"b3f33aa4d02b6fb2","prefixes":{"":{"product":809}}}, // [Leger Marketing]
+  {"hash":"eead3245cdc680da","prefixes":{"":{"product":809}}}, // [Leger Marketing]
+  {"hash":"1239f4aeb30a0c6e","prefixes":{"":{"product":810}}}, // [BlisMedia Limited]
+  {"hash":"544a45aa905f9c6e","prefixes":{"":{"product":810}}}, // [BlisMedia Limited]
+  {"hash":"c5e4c8510e3cac80","prefixes":{"":{"product":811}}}, // [Double6]
+  {"hash":"d0fa41ada692b1b9","prefixes":{"":{"product":812}}}, // [TRADEADS INTERACTIVE]
+  {"hash":"3db0a72bcd75db25","prefixes":{"":{"product":813}}}, // [Epigrams, Inc.]
+  {"hash":"f42d4e28510cfcb3","prefixes":{"":{"product":813}}}, // [Epigrams, Inc.]
+  {"hash":"22d2d672aad6f400","prefixes":{"":{"product":814}}}, // [Activecore Inc.]
+  {"hash":"1ab5c06bec002a04","prefixes":{"":{"product":814}}}, // [Activecore Inc.]
+  {"hash":"c34010f1f0a2a2bd","prefixes":{"":{"product":814}}}, // [Activecore Inc.]
+  {"hash":"b274e3909d6409ff","prefixes":{"":{"product":815}}}, // [Activecore,Inc.]
+  {"hash":"1bdc7aff17b34632","prefixes":{"":{"product":815}}}, // [Activecore,Inc.]
+  {"hash":"a5f385ad8794bbf7","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"7fbf5ab845c319c3","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"636714c3598df906","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"9e6785892cd34bdd","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"047573e0075b371a","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"30468687bd7540d7","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"d38c33250529e4cf","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"311b59743017ebda","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"fceae2ba76fa56d8","prefixes":{"":{"product":816}}}, // [ADCASH]
+  {"hash":"e3e53a304101f0b8","prefixes":{"*":{"product":817}}}, // [Videoplaza]
+  {"hash":"66ae7f0627345a0e","prefixes":{"":{"product":818}}}, // [Targetix LLC]
+  {"hash":"f2825950bbc13084","prefixes":{"":{"product":818}}}, // [Targetix LLC]
+  {"hash":"5844bebbb6ebc2c8","prefixes":{"":{"product":818}}}, // [Targetix LLC]
+  {"hash":"af1d9e1f4d4a29ee","prefixes":{"":{"product":818}}}, // [Targetix LLC]
+  {"hash":"eabbec12e479563f","prefixes":{"":{"product":818}}}, // [Targetix LLC]
+  {"hash":"063e5c59c898b6b2","prefixes":{"":{"product":818}}}, // [Targetix LLC]
+  {"hash":"768e497f05eb9210","prefixes":{"":{"product":819}}}, // [Adriver LLC]
+  {"hash":"a3e9e1ffdc9ef6f3","prefixes":{"":{"product":820}}}, // [Beso]
+  {"hash":"dc3b4a3bb1a98472","prefixes":{"*":{"product":821}}}, // [Voopter.com]
+  {"hash":"608c4fc0e1249087","prefixes":{"":{"product":822}}}, // [Hostbasket]
+  {"hash":"ec50bd1f8e55703a","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"75f08f4a618e4c29","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"5e28845a397448ed","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"43baf1a2f5c604eb","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"9113c91f7c97eda8","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"6e46faf33af4223b","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"b8629ee4f4882cf4","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"c580bf68b5705ecc","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"30c1badbfab295cc","prefixes":{"":{"product":823}}}, // [Rollad]
+  {"hash":"07206ed226f7d186","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"af031421c35c12bb","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"c1e9215522e84feb","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"f99b1e1004ffe36c","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"cc5aed10326009cd","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"a59bac0d7936d725","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"85c92ca45eb6137a","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"ecfa86f147eea591","prefixes":{"":{"product":824}}}, // [hdtMedia]
+  {"hash":"89c418c61cc46dbf","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"36712fa880f9f4fd","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"77af178b53829cee","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"19e3098ce56eae94","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"605d50a0c132e0b5","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"9cb69b24762928be","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"7ad4195e3856bc8b","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"a1f419f69f83a3cb","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"a8184454cf33a5e3","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"8c22c5755c763066","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"862c4454fe07929d","prefixes":{"":{"product":826}}}, // [ebuilders BV]
+  {"hash":"ac0afa5e86463dcf","prefixes":{"":{"product":827}}}, // [COADVERTISE]
+  {"hash":"049d375ddb03cca6","prefixes":{"":{"product":827}}}, // [COADVERTISE]
+  {"hash":"2ce968c3c01dac2b","prefixes":{"":{"product":828}}}, // [Blizzard]
+  {"hash":"6e4734c6df5289ef","prefixes":{"":{"product":828}}}, // [Blizzard]
+  {"hash":"9fe6f25a55c854ab","prefixes":{"":{"product":829}}}, // [Adgibbon]
+  {"hash":"008bfe35bcbd016d","prefixes":{"":{"product":829}}}, // [Adgibbon]
+  {"hash":"084705198bf3893b","prefixes":{"":{"product":829}}}, // [Adgibbon]
+  {"hash":"a1b65ade9cc861cb","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"42f9c0b081bf4152","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"ea90626af94135dd","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"ae4cfcc8964ff838","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"29ed865d96c2134b","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"f0ad420cd06e916d","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"02fa3036dfdd1f55","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"2e1689e37ca87292","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"e0f93c05dad3c3c6","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"3a2e2804dc9fbb61","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"deed6c9248e53552","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"c4597285474e8048","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"e127ffe380012cba","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"2f548a00d118d32e","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"015756b75eb89403","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"35d2e95d1522b0c5","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"a43e409504b254d3","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"5a4147bb67b5b23c","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"9866a49aaacb720e","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"f101934b33880c8d","prefixes":{"":{"product":830}}}, // [Wider Planet, Inc.]
+  {"hash":"5fc0aea809357158","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"ed7b8006e50dc195","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"fe112ea448efa84b","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"807a0ad2ef7d844d","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"24daf2e5c1e30aeb","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"9091656f8979f5f0","prefixes":{"":{"product":107}}}, // [Kpsule]
+  {"hash":"bb5ef61e19944a06","prefixes":{"":{"product":831}}}, // [ResponsiveAds, Inc]
+  {"hash":"ef4fefbe73da4a59","prefixes":{"":{"product":831}}}, // [ResponsiveAds, Inc]
+  {"hash":"e78ef2faad563e6b","prefixes":{"":{"product":831}}}, // [ResponsiveAds, Inc]
+  {"hash":"20e99abfa9e5de7c","prefixes":{"":{"product":831}}}, // [ResponsiveAds, Inc]
+  {"hash":"0dedc650dbf5d391","prefixes":{"":{"product":831}}}, // [ResponsiveAds, Inc]
+  {"hash":"5bdaec9fd3ff4dac","prefixes":{"":{"product":832}}}, // [Duepuntozero Research SRL]
+  {"hash":"318bfe954294ea40","prefixes":{"":{"product":833}}}, // [AdMovate, Inc.]
+  {"hash":"e24259ffed4d244f","prefixes":{"":{"product":833}}}, // [AdMovate, Inc.]
+  {"hash":"c39b0621d7a8b616","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"29c359aefdd48c40","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"6ecf3c2aeb5aec2b","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"eea1a3478557a7a6","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"0b0e365de9c89436","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"875d9d8b11a6dff7","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"5edb8f1a6337d5d0","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"435808ca4dd1dce5","prefixes":{"":{"product":834}}}, // [go.pl]
+  {"hash":"fd43d007391147de","prefixes":{"":{"product":710}}}, // [MASSMOTIONMEDIA SARL]
+  {"hash":"633236a94b694dd7","prefixes":{"":{"product":710}}}, // [MASSMOTIONMEDIA SARL]
+  {"hash":"a076e91e809efc28","prefixes":{"*":{"product":835}}}, // [AppLovin Corporation]
+  {"hash":"14c26da0caac0796","prefixes":{"":{"product":836}}}, // [twentysix ltd]
+  {"hash":"1f8d7bcebd64d2c9","prefixes":{"":{"product":15}}}, // [Tamome]
+  {"hash":"41f4c0bf12c8f029","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"e674b14a061bb7d7","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"f485e2bb528d3147","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"82c09e315af7d70c","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"fc2b985669148068","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"cf9a9377bc72c2e4","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"d550149a2d5cfdde","prefixes":{"":{"product":336}}}, // [EuroAds Group A/S]
+  {"hash":"d51c2c24cd771a6a","prefixes":{"":{"product":837}}}, // [Epsilon International SA]
+  {"hash":"d34cf98578200c93","prefixes":{"":{"product":838}}}, // [Zebestof]
+  {"hash":"44c2302577bd8e84","prefixes":{"":{"product":838}}}, // [Zebestof]
+  {"hash":"52b835c5657206c1","prefixes":{"":{"product":838}}}, // [Zebestof]
+  {"hash":"caa0c94cf57e2295","prefixes":{"":{"product":838}}}, // [Zebestof]
+  {"hash":"02e54ec6b0aca548","prefixes":{"":{"product":839}}}, // [SOL UTD Benelux BV]
+  {"hash":"1cf1a7f5c323d6e0","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"079a647886a5afa5","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"ec320d28ebdfac8c","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"e59449da7e642b45","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"1d61751db94dfc15","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"43f7746544162324","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"4f80c8700c459a79","prefixes":{"":{"product":840}}}, // [M,P,NEWMEDIA, GmbH]
+  {"hash":"23f62ba113f0fa4f","prefixes":{"":{"product":841}}}, // [MediaCrossing Inc.]
+  {"hash":"62fc0fc3102b918b","prefixes":{"":{"product":842}}}, // [MBR Targeting Gmbh]
+  {"hash":"0066f0743ade259b","prefixes":{"":{"product":842}}}, // [MBR Targeting Gmbh]
+  {"hash":"4288d021c49b7e1b","prefixes":{"":{"product":842}}}, // [MBR Targeting Gmbh]
+  {"hash":"6620a58a1f4cd480","prefixes":{"":{"product":843}}}, // [VivaKi]
+  {"hash":"47db57aade94670f","prefixes":{"":{"product":843}}}, // [VivaKi]
+  {"hash":"2924b77c1d7eab3b","prefixes":{"":{"product":843}}}, // [VivaKi]
+  {"hash":"d2143dbf1699f4fa","prefixes":{"":{"product":844}}}, // [Affiliate Window]
+  {"hash":"13c2a94c46886705","prefixes":{"":{"product":844}}}, // [Affiliate Window]
+  {"hash":"c0d30b023dc9139f","prefixes":{"*":{"product":845}}}, // [TubeMogul Inc. (AdWords/YouTube)]
+  {"hash":"108d788939e4b7a4","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"6fdc121917e19eb9","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"5262a88cfa363303","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"b597af924fe5ff97","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"dca60f44a70d5d38","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"c44308d5c2e3bb8a","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"90f5b971c961816f","prefixes":{"":{"product":825}}}, // [DXP Media]
+  {"hash":"5d64c1152c075739","prefixes":{"":{"product":846}}}, // [Way2traffic Polska S.A.]
+  {"hash":"01b13121d2ce9699","prefixes":{"":{"product":846}}}, // [Way2traffic Polska S.A.]
+  {"hash":"f48791a2746e2a93","prefixes":{"":{"product":847}}}, // [TNS Sifo AB]
+  {"hash":"935b8079b74f344c","prefixes":{"":{"product":847}}}, // [TNS Sifo AB]
+  {"hash":"24e5b8b342d1b1fe","prefixes":{"":{"product":848}}}, // [3xchange/Hunkal]
+  {"hash":"ad8c8bc165611bf2","prefixes":{"":{"product":848}}}, // [3xchange/Hunkal]
+  {"hash":"b1b5bdd82d143e90","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"aeddaa071ba3b313","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"474802ea42555e39","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"b28e42ea18df1c00","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"826635800b12eb0c","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"22c10728f555913e","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"0b7f364ef0beed45","prefixes":{"":{"product":849}}}, // [Emerse Sverige AB]
+  {"hash":"8d31e79105c5380a","prefixes":{"":{"product":850}}}, // [Sokno Media]
+  {"hash":"037264ef7d8383f6","prefixes":{"":{"product":850}}}, // [Sokno Media]
+  {"hash":"ff6372e6621d88ba","prefixes":{"":{"product":851}}}, // [Blackheart, a division of Hot Topic, Inc.]
+  {"hash":"37742852c2a4ccc8","prefixes":{"":{"product":852}}}, // [Torrid]
+  {"hash":"a86786ce90b23e3f","prefixes":{"":{"product":853}}}, // [Hot Topic, Inc.]
+  {"hash":"93e1c22a4427a32f","prefixes":{"":{"product":854}}}, // [WebHue LLC]
+  {"hash":"fca0a42aad108345","prefixes":{"static":{"product":855},"img":{"product":855},"log":{"product":855}}}, // [Content to Emotion] [Content to Emotion] [Content to Emotion]
+  {"hash":"15948cae619c2e58","prefixes":{"":{"product":855}}}, // [Content to Emotion]
+  {"hash":"db2a81c15837ddbd","prefixes":{"":{"product":856}}}, // [Adman Interactive SL]
+  {"hash":"accf1565984e2899","prefixes":{"":{"product":856}}}, // [Adman Interactive SL]
+  {"hash":"45351e5c4862b2dd","prefixes":{"":{"product":856}}}, // [Adman Interactive SL]
+  {"hash":"ba3196c50e6c1be4","prefixes":{"":{"product":856}}}, // [Adman Interactive SL]
+  {"hash":"eab724fbba4f83d6","prefixes":{"":{"product":856}}}, // [Adman Interactive SL]
+  {"hash":"0edc8e7b8a8fe3ee","prefixes":{"":{"product":857}}}, // [AudienceFUEL, Inc.]
+  {"hash":"dfa423315ab48813","prefixes":{"":{"product":858}}}, // [TapCommerce LLC]
+  {"hash":"777b0f4301aa1643","prefixes":{"":{"product":858}}}, // [TapCommerce LLC]
+  {"hash":"294cba0ae232447c","prefixes":{"":{"product":859}}}, // [AdTheorent, Inc.]
+  {"hash":"ba7ad5da6db014c7","prefixes":{"":{"product":860}}}, // [AdTheorent, Inc]
+  {"hash":"09bfc8a7f1c7896f","prefixes":{"":{"product":859}}}, // [AdTheorent, Inc.]
+  {"hash":"362136e847a35f7e","prefixes":{"":{"product":859}}}, // [AdTheorent, Inc.]
+  {"hash":"5492d77bb75e6380","prefixes":{"":{"product":861}}}, // [Barometric]
+  {"hash":"94bb816c4a375220","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"f10e1a418576d219","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"245fc951b0a9ce59","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"babdceabca3ae2b8","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"c6474114ede3195a","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"26faef64bd072723","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"0a19b1f547a3a935","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"b4ef56642916cc60","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"c1fc9d245fa85b02","prefixes":{"":{"product":862}}}, // [CrossInstall, Inc]
+  {"hash":"0e3ddb4868b0e99f","prefixes":{"":{"product":863}}}, // [Theorem Inc.]
+  {"hash":"976d4ea6507dfd2e","prefixes":{"":{"product":863}}}, // [Theorem Inc.]
+  {"hash":"70a3fe87d3bbbae9","prefixes":{"":{"product":863}}}, // [Theorem Inc.]
+  {"hash":"1cf1ec002a07d6a4","prefixes":{"":{"product":864}}}, // [KeyVersion]
+  {"hash":"b2c480f3bc7b03b6","prefixes":{"":{"product":864}}}, // [KeyVersion]
+  {"hash":"c94dbc0a3ffc6eda","prefixes":{"":{"product":865}}}, // [Ancestry]
+  {"hash":"04fb46af993df556","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"b9adf25b55c4d0f3","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"1c1211c84dbee054","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"575fafb094c71d93","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"f2b020b3d3861db2","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"609d13c5cd3771c8","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"aeae313934102cfe","prefixes":{"":{"product":867}}}, // [Shanghai Lijing Advertising Co., Ltd]
+  {"hash":"f8721bcf4d9f6196","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"09e5f7c9f30f4fd6","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"a1ce57d387427206","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"bb4b6377666172c4","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"d6a6a6cd062bc76e","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"0313ce8a9851d837","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"6862450d2314df40","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"0a34c9f6f0cf9556","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"8e311fce80eccafd","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"296fdad7e8336d5a","prefixes":{"":{"product":866}}}, // [Shanghai Lijing Advertising Co., Ltd.]
+  {"hash":"27c0e177312a3c0f","prefixes":{"":{"product":108}}}, // [Immedium, Inc.]
+  {"hash":"fc3c7114081863bd","prefixes":{"":{"product":108}}}, // [Immedium, Inc.]
+  {"hash":"811582f5df157ff9","prefixes":{"":{"product":868}}}, // [KissNoFrog.com]
+  {"hash":"284d8a4f9b174bab","prefixes":{"":{"product":869}}}, // [DigiEQ]
+  {"hash":"aa0e7b7a1fe279dc","prefixes":{"":{"product":869}}}, // [DigiEQ]
+  {"hash":"1f551f934400f81e","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"1c3b94cabbbc5b8c","prefixes":{"":{"product":86}}}, // [MediaMath Inc.]
+  {"hash":"505b194aeebd6baf","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"8f2e12e9677e4d41","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"e2a3fe5e482432e8","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"7d03cd1b92c167a8","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"532402cd3ab13402","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"48e577ba3e61c748","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"1480a6580cb81dde","prefixes":{"":{"product":870}}}, // [Mobile Professinals BV]
+  {"hash":"b1ec46dd2c4c824e","prefixes":{"*":{"product":109}}}, // [Fractional Media, LLC]
+  {"hash":"6c6240697771befd","prefixes":{"*":{"product":109}}}, // [Fractional Media, LLC]
+  {"hash":"f2e16038c0d83b85","prefixes":{"":{"product":871}}}, // [Decisive, Inc.]
+  {"hash":"654da4ed85d77fb9","prefixes":{"":{"product":871}}}, // [Decisive, Inc.]
+  {"hash":"c9e2ea0486216534","prefixes":{"":{"product":871}}}, // [Decisive, Inc.]
+  {"hash":"546a2acb9b2363f2","prefixes":{"*":{"product":872}}}, // [Microsoft Security Essentials]
+  {"hash":"9e4f5b2f200fbb25","prefixes":{"":{"product":873}}}, // [Tumi, Inc. US]
+  {"hash":"4378c60894195c4f","prefixes":{"":{"product":874}}}, // [Tumi, Inc. UK]
+  {"hash":"61e82c5e74c5ce7c","prefixes":{"":{"product":875}}}, // [Tumi, Inc. DE]
+  {"hash":"712f010eb9792fa4","prefixes":{"":{"product":876}}}, // [Nanigans, Inc]
+  {"hash":"589eceaef79619dd","prefixes":{"":{"product":876}}}, // [Nanigans, Inc]
+  {"hash":"1d66f17c949dbaee","prefixes":{"":{"product":876}}}, // [Nanigans, Inc]
+  {"hash":"6dbd7b9480163af0","prefixes":{"":{"product":876}}}, // [Nanigans, Inc]
+  {"hash":"41d56e0870364212","prefixes":{"":{"product":139}}}, // [Brandscreen Inc.]
+  {"hash":"2d701495cf72af5b","prefixes":{"*":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"0bd14e8d5a6b2f2d","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"9b504cc586da72e5","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"a89d4cb4490b4286","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"dce925353cbc1dbe","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"ff8d26679ce7dafc","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"11db2fec76a76647","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"00a09e8788ee6f2b","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"709d79bfe214aa48","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"7a37fa5ff1a37799","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"42a24e1ab1c2d947","prefixes":{"":{"product":877}}}, // [AdSniper LLC]
+  {"hash":"63f4e4d315bc085b","prefixes":{"":{"product":878}}}, // [Fabric Worldwide Inc]
+  {"hash":"b9c11e67d7eb2963","prefixes":{"":{"product":878}}}, // [Fabric Worldwide Inc]
+  {"hash":"e3882e6bc0c2e382","prefixes":{"":{"product":879}}}, // [Vorwerk Deutschland Stiftung & Co. KG]
+  {"hash":"944d86d40b9ae089","prefixes":{"":{"product":879}}}, // [Vorwerk Deutschland Stiftung & Co. KG]
+  {"hash":"ebd456010571b5ae","prefixes":{"":{"product":879}}}, // [Vorwerk Deutschland Stiftung & Co. KG]
+  {"hash":"4456fa769be90ba2","prefixes":{"":{"product":65}}}, // [Active Agent]
+  {"hash":"84d65f5782dd26d6","prefixes":{"":{"product":880}}}, // [Chico Distribution Services, LLC]
+  {"hash":"a6185f46e2849f58","prefixes":{"":{"product":881}}}, // [12Mnkys GmbH]
+  {"hash":"bf874935c6972629","prefixes":{"":{"product":881}}}, // [12Mnkys GmbH]
+  {"hash":"094b301a712414f2","prefixes":{"":{"product":881}}}, // [12Mnkys GmbH]
+  {"hash":"56ee8d67408b2316","prefixes":{"":{"product":881}}}, // [12Mnkys GmbH]
+  {"hash":"d62d9c20c47ec863","prefixes":{"":{"product":881}}}, // [12Mnkys GmbH]
+  {"hash":"bb716a8269a2e79c","prefixes":{"":{"product":882}}}, // [Spacyz, Inc.]
+  {"hash":"5a6ff8a620bb8de1","prefixes":{"":{"product":882}}}, // [Spacyz, Inc.]
+  {"hash":"61cf0a8426083e54","prefixes":{"":{"product":882}}}, // [Spacyz, Inc.]
+  {"hash":"4cf4aa4b0e37fdfd","prefixes":{"":{"product":719}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
+  {"hash":"745acee8f5973f56","prefixes":{"":{"product":719}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
+  {"hash":"9a834a1cc05cb878","prefixes":{"":{"product":883}}}, // [MBuy, Inc.]
+  {"hash":"73cd161c10ebcf69","prefixes":{"":{"product":884}}}, // [FullSpeed Inc.]
+  {"hash":"75c72b5cc4c40c16","prefixes":{"":{"product":884}}}, // [FullSpeed Inc.]
+  {"hash":"33c5c398130ddfec","prefixes":{"":{"product":884}}}, // [FullSpeed Inc.]
+  {"hash":"1c0653651245a014","prefixes":{"":{"product":884}}}, // [FullSpeed Inc.]
+  {"hash":"271d057b15f67166","prefixes":{"":{"product":884}}}, // [FullSpeed Inc.]
+  {"hash":"e9723a229b8b9eeb","prefixes":{"":{"product":884}}}, // [FullSpeed Inc.]
+  {"hash":"8e3c99c5cc10c217","prefixes":{"":{"product":355}}}, // [New Allyes Information Technology (winmax)]
+  {"hash":"07141bfb96faa93c","prefixes":{"":{"product":885}}}, // [Madhouse Co. Limited (OptiMad)]
+  {"hash":"1d7294abbaa26e26","prefixes":{"":{"product":885}}}, // [Madhouse Co. Limited (OptiMad)]
+  {"hash":"6872272e097d2cd9","prefixes":{"":{"product":885}}}, // [Madhouse Co. Limited (OptiMad)]
+  {"hash":"66ec8aa560cf2231","prefixes":{"":{"product":885}}}, // [Madhouse Co. Limited (OptiMad)]
+  {"hash":"17cd9dcba702b7e6","prefixes":{"":{"product":885}}}, // [Madhouse Co. Limited (OptiMad)]
+  {"hash":"2347e9e88f6ead88","prefixes":{"":{"product":886}}}, // [Nano Interactive / Audiencemanager]
+  {"hash":"7f19740ff86dc642","prefixes":{"":{"product":886}}}, // [Nano Interactive / Audiencemanager]
+  {"hash":"18f553670e23734b","prefixes":{"":{"product":886}}}, // [Nano Interactive / Audiencemanager]
+  {"hash":"ca862d199926ad1c","prefixes":{"":{"product":886}}}, // [Nano Interactive / Audiencemanager]
+  {"hash":"2238776218564026","prefixes":{"":{"product":886}}}, // [Nano Interactive / Audiencemanager]
+  {"hash":"d7e222c8d7ba68d8","prefixes":{"*":{"product":887}}}, // [Youtube, LLC]
+  {"hash":"edff9009064b3fa4","prefixes":{"*":{"product":887}}}, // [Youtube, LLC]
+  {"hash":"0d60795f6997311e","prefixes":{"":{"product":888}}}, // [Omnibus co. Ltd]
+  {"hash":"f32008e13be0f96e","prefixes":{"":{"product":888}}}, // [Omnibus co. Ltd]
+  {"hash":"dd5533aa2d49cc10","prefixes":{"":{"product":889}}}, // [Omnibus co. Ltd.]
+  {"hash":"3bcd500b684d5142","prefixes":{"":{"product":888}}}, // [Omnibus co. Ltd]
+  {"hash":"14eef63a2889c8da","prefixes":{"":{"product":888}}}, // [Omnibus co. Ltd]
+  {"hash":"53f31e427551538d","prefixes":{"":{"product":888}}}, // [Omnibus co. Ltd]
+  {"hash":"5296819de63f3444","prefixes":{"":{"product":888}}}, // [Omnibus co. Ltd]
+  {"hash":"d8389fea989da8d7","prefixes":{"":{"product":41}}}, // [Airpush, Inc.]
+  {"hash":"e251b17a002b679b","prefixes":{"":{"product":890}}}, // [Education Management Corporation]
+  {"hash":"ec35188a522b7db9","prefixes":{"*":{"product":891}}}, // [Screen6 (s6.io)]
+  {"hash":"8ee1cf907bbca914","prefixes":{"":{"product":892}}}, // [LINK Marketing Services AG]
+  {"hash":"18a5decf96e8c80d","prefixes":{"":{"product":893}}}, // [TiqIQ]
+  {"hash":"8927e5364d1bf1d1","prefixes":{"":{"product":893}}}, // [TiqIQ]
+  {"hash":"86292c524ac79685","prefixes":{"":{"product":893}}}, // [TiqIQ]
+  {"hash":"52562df3f7208c8f","prefixes":{"":{"product":893}}}, // [TiqIQ]
+  {"hash":"a7d6fe32ab078e86","prefixes":{"":{"product":893}}}, // [TiqIQ]
+  {"hash":"497857c899894a0f","prefixes":{"":{"product":893}}}, // [TiqIQ]
+  {"hash":"0d8c5ad133d4c83e","prefixes":{"":{"product":894}}}, // [Ibibo Group Private Limited]
+  {"hash":"a8c10e41d2d4b31a","prefixes":{"":{"product":894}}}, // [Ibibo Group Private Limited]
+  {"hash":"9699d29520d1b9b8","prefixes":{"":{"product":894}}}, // [Ibibo Group Private Limited]
+  {"hash":"103308c15ca4c459","prefixes":{"":{"product":889}}}, // [Omnibus co. Ltd.]
+  {"hash":"d7a1b3fc5e1252ce","prefixes":{"":{"product":889}}}, // [Omnibus co. Ltd.]
+  {"hash":"ee40bf7c9bae2361","prefixes":{"":{"product":895}}}, // [justAd TV LTD]
+  {"hash":"8755d187f8ffb5e9","prefixes":{"":{"product":895}}}, // [justAd TV LTD]
+  {"hash":"1bdf54cf79d18915","prefixes":{"":{"product":895}}}, // [justAd TV LTD]
+  {"hash":"ed61950d43d99717","prefixes":{"":{"product":895}}}, // [justAd TV LTD]
+  {"hash":"aff928fc58637cb3","prefixes":{"":{"product":896}}}, // [Appier Inc.]
+  {"hash":"797f76218537ad5d","prefixes":{"*":{"product":896}}}, // [Appier Inc.]
+  {"hash":"6bdcdb03ff6173af","prefixes":{"*":{"product":896}}}, // [Appier Inc.]
+  {"hash":"6a3dec8b5a467987","prefixes":{"*":{"product":896}}}, // [Appier Inc.]
+  {"hash":"a3d5f58bbde56b12","prefixes":{"":{"product":896}}}, // [Appier Inc.]
+  {"hash":"7d0adb9089ff21ca","prefixes":{"":{"product":896}}}, // [Appier Inc.]
+  {"hash":"c241f36263ea7c84","prefixes":{"":{"product":897}}}, // [Kate Spade Saturday]
+  {"hash":"79dd595e79611766","prefixes":{"":{"product":898}}}, // [Teufel GmbH]
+  {"hash":"df829b8e840c11e1","prefixes":{"":{"product":898}}}, // [Teufel GmbH]
+  {"hash":"c3004b48539587e5","prefixes":{"":{"product":898}}}, // [Teufel GmbH]
+  {"hash":"08eb365a3723ee17","prefixes":{"":{"product":898}}}, // [Teufel GmbH]
+  {"hash":"71bc88c0bd0dc170","prefixes":{"":{"product":898}}}, // [Teufel GmbH]
+  {"hash":"fb208e41a565430a","prefixes":{"":{"product":899}}}, // [Aitarget LLC]
+  {"hash":"6121d39232612f56","prefixes":{"":{"product":899}}}, // [Aitarget LLC]
+  {"hash":"0ef54a01a72fdbaf","prefixes":{"*":{"product":676}}}, // [Rackspace, US Inc.]
+  {"hash":"532febae5cf9194f","prefixes":{"":{"product":900}}}, // [Engage Lab Ltd.]
+  {"hash":"fbfff8f12503c208","prefixes":{"":{"product":901}}}, // [Signal Digital, Inc dba Signal]
+  {"hash":"14afd1fc2da14d71","prefixes":{"":{"product":902}}}, // [Motrixi Media Group LLC]
+  {"hash":"aa674bd59dee4716","prefixes":{"":{"product":902}}}, // [Motrixi Media Group LLC]
+  {"hash":"7fd4fa8a06589cab","prefixes":{"":{"product":902}}}, // [Motrixi Media Group LLC]
+  {"hash":"56f94b2620357eb5","prefixes":{"":{"product":902}}}, // [Motrixi Media Group LLC]
+  {"hash":"32ddc8b6874f030b","prefixes":{"":{"product":903}}}, // [WHITE HOUSE | BLACK MARKET, Chico Brands, Inc.]
+  {"hash":"fea26de6b70aafb9","prefixes":{"":{"product":904}}}, // [Liftoff Mobile, Inc.]
+  {"hash":"4687be4922e9d22e","prefixes":{"":{"product":905}}}, // [etracker GmbH]
+  {"hash":"b41f235329fba677","prefixes":{"*":{"product":906}}}, // [MezzoMedia]
+  {"hash":"3362cc82ba37c826","prefixes":{"":{"product":906}}}, // [MezzoMedia]
+  {"hash":"7c5cbde65c1f0a61","prefixes":{"":{"product":907}}}, // [Eyeota Limited]
+  {"hash":"d85ebb0a3c0bdef4","prefixes":{"":{"product":908}}}, // [Beijing PageChoice Network Technology co., Ltd.]
+  {"hash":"52d134e034c55e1d","prefixes":{"":{"product":908}}}, // [Beijing PageChoice Network Technology co., Ltd.]
+  {"hash":"9d9805e510965156","prefixes":{"":{"product":908}}}, // [Beijing PageChoice Network Technology co., Ltd.]
+  {"hash":"5ed6426649a5142e","prefixes":{"":{"product":908}}}, // [Beijing PageChoice Network Technology co., Ltd.]
+  {"hash":"e629bb2b2df81562","prefixes":{"":{"product":908}}}, // [Beijing PageChoice Network Technology co., Ltd.]
+  {"hash":"37a1384fb3fc6090","prefixes":{"":{"product":270}}}, // [Intelliad]
+  {"hash":"9d931008b4067d12","prefixes":{"":{"product":909}}}, // [Padopolis, Inc.]
+  {"hash":"2e0eb051f10f4fe7","prefixes":{"":{"product":909}}}, // [Padopolis, Inc.]
+  {"hash":"e4e066ee012dd820","prefixes":{"":{"product":910}}}, // [Republic Project, Inc.]
+  {"hash":"6bda23da60f6517c","prefixes":{"":{"product":910}}}, // [Republic Project, Inc.]
+  {"hash":"8af361ef2f58932e","prefixes":{"":{"product":910}}}, // [Republic Project, Inc.]
+  {"hash":"9cf685ac4bd3c1a0","prefixes":{"":{"product":910}}}, // [Republic Project, Inc.]
+  {"hash":"ceb2ae18496c4062","prefixes":{"":{"product":910}}}, // [Republic Project, Inc.]
+  {"hash":"a1c74be312c1e501","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"e2305a44231103a0","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"e9ea3f2053ff0ac5","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"18f65ffdee8f8402","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"dc902603963cc6c8","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"6addef0844f148c5","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"c2889776656d63b3","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"1a1ac1eeae181fe7","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"fa03396d4a303d45","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"f632f69c34840122","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"082e62ce70aa66fc","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"775c7d89c606cd3c","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"74b282bb3c686219","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"a8e1956c97315aaf","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"26dc9f78ec72cc0c","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"c4ef7b6eeeda12ce","prefixes":{"":{"product":911}}}, // [C8 Network]
+  {"hash":"e78c2b0997dfa249","prefixes":{"":{"product":912}}}, // [Data Artist Inc.]
+  {"hash":"41045058078214c7","prefixes":{"":{"product":912}}}, // [Data Artist Inc.]
+  {"hash":"c3b23588f42fedff","prefixes":{"":{"product":912}}}, // [Data Artist Inc.]
+  {"hash":"5e94c742d87aa747","prefixes":{"":{"product":912}}}, // [Data Artist Inc.]
+  {"hash":"52632067f5495750","prefixes":{"":{"product":913}}}, // [AirFrance]
+  {"hash":"0b27c948dba1fda0","prefixes":{"":{"product":914}}}, // [YDigital Media]
+  {"hash":"7e30f931dbb7180a","prefixes":{"":{"product":915}}}, // [Zentrick]
+  {"hash":"b3e2285b6fc03e5c","prefixes":{"":{"product":915}}}, // [Zentrick]
+  {"hash":"e2f247795ad2ad87","prefixes":{"":{"product":915}}}, // [Zentrick]
+  {"hash":"1c9e4d1810e659fa","prefixes":{"":{"product":915}}}, // [Zentrick]
+  {"hash":"57511b10e2ed4785","prefixes":{"":{"product":915}}}, // [Zentrick]
+  {"hash":"c012faa898c62e0b","prefixes":{"":{"product":916}}}, // [FreeBit Co. Ltd.]
+  {"hash":"41b7f33c961162f8","prefixes":{"":{"product":916}}}, // [FreeBit Co. Ltd.]
+  {"hash":"ffac4f6c5fa1aa82","prefixes":{"":{"product":916}}}, // [FreeBit Co. Ltd.]
+  {"hash":"a23bae62ab25e2c1","prefixes":{"":{"product":916}}}, // [FreeBit Co. Ltd.]
+  {"hash":"ae08459757b76c12","prefixes":{"":{"product":916}}}, // [FreeBit Co. Ltd.]
+  {"hash":"83efb7fcb7770789","prefixes":{"":{"product":917}}}, // [Dennoo Inc.]
+  {"hash":"042456e26a44a268","prefixes":{"":{"product":917}}}, // [Dennoo Inc.]
+  {"hash":"cb0b16dd50ba9d7d","prefixes":{"":{"product":917}}}, // [Dennoo Inc.]
+  {"hash":"541a895df01d2b2c","prefixes":{"":{"product":917}}}, // [Dennoo Inc.]
+  {"hash":"8f01887bb7405ab5","prefixes":{"":{"product":918}}}, // [Adbrain]
+  {"hash":"33734a86766d25a9","prefixes":{"*":{"product":919}}}, // [MSI-ACI Europe BV]
+  {"hash":"f66543f279b3e1e7","prefixes":{"":{"product":920}}}, // [A.Mob]
+  {"hash":"74ee8c0f2fb31813","prefixes":{"":{"product":920}}}, // [A.Mob]
+  {"hash":"584db20b69521f40","prefixes":{"":{"product":921}}}, // [Toys R Us]
+  {"hash":"6a001e8bc99fede6","prefixes":{"":{"product":922}}}, // [Geniee,Inc]
+  {"hash":"b8ff7bd604535ea9","prefixes":{"":{"product":922}}}, // [Geniee,Inc]
+  {"hash":"3e005c1dfdc23488","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"ddef7bb2f5930121","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"424399e643b329b8","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"23df92e04ec66406","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"06f0caf4a4fe6ed1","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"9697a0818cbd79bd","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"ec7f61f2511ae20e","prefixes":{"":{"product":923}}}, // [Adsecure]
+  {"hash":"fb4e7ecb8304ade4","prefixes":{"":{"product":924}}}, // [Kimia Solutions SL]
+  {"hash":"84f5d0f934bd60f1","prefixes":{"":{"product":924}}}, // [Kimia Solutions SL]
+  {"hash":"b3fcc22fcd382f3b","prefixes":{"":{"product":924}}}, // [Kimia Solutions SL]
+  {"hash":"4eca8c3218b372ae","prefixes":{"":{"product":925}}}, // [Sojern]
+  {"hash":"9636bfb4feaef839","prefixes":{"":{"product":925}}}, // [Sojern]
+  {"hash":"a525b67906a4cb94","prefixes":{"":{"product":926}}}, // [Where 2 Get It, Inc.]
+  {"hash":"6c959985d7181026","prefixes":{"":{"product":926}}}, // [Where 2 Get It, Inc.]
+  {"hash":"7843db8d760e28cb","prefixes":{"":{"product":927}}}, // [Tomoko Cloud]
+  {"hash":"eb7b756fc1f88aa1","prefixes":{"":{"product":927}}}, // [Tomoko Cloud]
+  {"hash":"ed4d672687c27603","prefixes":{"":{"product":927}}}, // [Tomoko Cloud]
+  {"hash":"b156b34e4d693e49","prefixes":{"":{"product":927}}}, // [Tomoko Cloud]
+  {"hash":"16e146e87e7d0383","prefixes":{"":{"product":928}}}, // [RevenueMantra]
+  {"hash":"1457bcbc098b2864","prefixes":{"":{"product":928}}}, // [RevenueMantra]
+  {"hash":"450eb4f9273a5014","prefixes":{"":{"product":929}}}, // [Automobile Ltd.]
+  {"hash":"436e4eaa95b23fcb","prefixes":{"":{"product":929}}}, // [Automobile Ltd.]
+  {"hash":"a47ee9f00ca4f855","prefixes":{"":{"product":929}}}, // [Automobile Ltd.]
+  {"hash":"889ab5643c83668a","prefixes":{"":{"product":929}}}, // [Automobile Ltd.]
+  {"hash":"4ea96f1e0388da92","prefixes":{"":{"product":930}}}, // [Big Mobile Group Pty Ltd]
+  {"hash":"ae895a18cc8c416e","prefixes":{"":{"product":930}}}, // [Big Mobile Group Pty Ltd]
+  {"hash":"bbb46a7f5062448e","prefixes":{"":{"product":931}}}, // [ADMIZED AG]
+  {"hash":"0b4e26a40cc2e647","prefixes":{"":{"product":932}}}, // [Sparks47 s.r.l.]
+  {"hash":"745030cd7ac80402","prefixes":{"":{"product":933}}}, // [Between Digital dba Intency DSP]
+  {"hash":"55db959f7c533183","prefixes":{"":{"product":933}}}, // [Between Digital dba Intency DSP]
+  {"hash":"15b9a82ccbf2d7ff","prefixes":{"":{"product":933}}}, // [Between Digital dba Intency DSP]
+  {"hash":"c63156716e201b52","prefixes":{"":{"product":933}}}, // [Between Digital dba Intency DSP]
+  {"hash":"801d43da2c97866b","prefixes":{"":{"product":933}}}, // [Between Digital dba Intency DSP]
+  {"hash":"d9f810d72012d4c4","prefixes":{"":{"product":934}}}, // [eprofessional GmbH]
+  {"hash":"23c665bb68cc30cc","prefixes":{"":{"product":934}}}, // [eprofessional GmbH]
+  {"hash":"8439b0c8f73daf02","prefixes":{"":{"product":934}}}, // [eprofessional GmbH]
+  {"hash":"6a17378968b598f2","prefixes":{"":{"product":934}}}, // [eprofessional GmbH]
+  {"hash":"4e157cd578931a97","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"9cdf7d74bee2159f","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"58c684b764b4dcab","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"85218b0017b8f452","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"9f790c0c14fa8f4d","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"e7518acf5c44d0a4","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"ec763282f8f41299","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"41a0870b895e73b4","prefixes":{"":{"product":936}}}, // [ConvertStar Incorporated]
+  {"hash":"f0134a17d368f3d8","prefixes":{"":{"product":936}}}, // [ConvertStar Incorporated]
+  {"hash":"58f6c00f44fb69a4","prefixes":{"":{"product":936}}}, // [ConvertStar Incorporated]
+  {"hash":"ff266e088e3010a8","prefixes":{"":{"product":937}}}, // [VisualDNA (Imagini)]
+  {"hash":"9748c01f8dcd17ee","prefixes":{"":{"product":937}}}, // [VisualDNA (Imagini)]
+  {"hash":"8e588a0818c4fcfe","prefixes":{"":{"product":937}}}, // [VisualDNA (Imagini)]
+  {"hash":"b499a754cc7d2c9b","prefixes":{"":{"product":937}}}, // [VisualDNA (Imagini)]
+  {"hash":"12d363fa8ee6c4d3","prefixes":{"":{"product":938}}}, // [Avocet]
+  {"hash":"a8bc7b6f66702489","prefixes":{"":{"product":938}}}, // [Avocet]
+  {"hash":"5166d9515e755f19","prefixes":{"":{"product":939}}}, // [Auction.com, LLC]
+  {"hash":"3adf8560ada830b8","prefixes":{"":{"product":939}}}, // [Auction.com, LLC]
+  {"hash":"f24f87c799e92ae5","prefixes":{"":{"product":939}}}, // [Auction.com, LLC]
+  {"hash":"a60dedada0fd44b6","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5d0f226850d2e68c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e4c703070b535b17","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"bc640a9c42502b35","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"defb06aab760992e","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"9bb069524856b34b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ef253518584f013f","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e100ba963ad8ecf2","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"05b625ee62d8685f","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5a88fb5abffcefc9","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a31c0b568cc8ade8","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"3498894fbeac8341","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1b82605c41d8b709","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"8138ad98ed0394e9","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"751c9ebb221bb5f9","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"8e3793804d9cdab5","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a6ecf1a95c24b6a3","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d27fe0e9834e648b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"2a0c1b5a904b36c1","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"f0d6c35febee8008","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"3c01a29e3c9c7264","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"4a74fdfd9b816fe8","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"aac8184f18b04958","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"368da19a90db3ad7","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"116d46403c6e95b7","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"808bb76ca34e4d1b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"b19f61f6e35aaa6a","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"9afc01573e38d021","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"11d7bce194c54912","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a28be439cad08ebb","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"968792ffe85f5d2d","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d3bc9343531e6c0c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a11d6b37b0382222","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"4bf65fa3bba0c55b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"4e1d992a76cf0b41","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"b09978a8e01fdbca","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"7394b2453f854b55","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a76d4645267ff0be","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"7e60860df0c8945b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ed9d4b0db5598264","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"466d1d16f3a935fb","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"21ac8963bf026e1a","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e04f72461a1fdf7d","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"549860a6933e906e","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ddc7313241f77312","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d89759a9687ad368","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"343ad98c7f4d71ed","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"2cb5047919d88ce8","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e9739ef3b0403f17","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"2b8ce30f483d90da","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1d1295f1cdac7503","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"57fd3c09e35ca17e","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"050dd41acc3ac3be","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1b853fb5c08c8727","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1c3db6034ad5c3e7","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"4b87160668f51e71","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d0875bc7510fbaa1","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a46257724ca67bc0","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"c93d397e8d1ed4fe","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"2cc9ae96e6b56fc3","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"051e72fcceee74d6","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"c24b55da2a7095df","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"88981afd076ecf48","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1ac94ef8a4d9ad5b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a57f0b4ed1a21743","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ff1f4076329cb91c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1ea1f1044008a0b2","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5a9b4bfa6d03c94b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"16bcde8365ddf2a8","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"7d3732d8588ffedb","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"fb6a6a06e4463001","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e357e4b19a11617f","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ee8aa73feac66773","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"8aa426bd808ed75a","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e5eed224f946f11b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"3b812696a50c7061","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a04facc89859d775","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"37413c9d9331953b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d5713942d78606a2","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"52e5d6a64f47f9e8","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"bb49554e8d0ea27b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"9943d790e614f45a","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"b318da3bafca323e","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"8a6b3193ebf16daf","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"9a4e890c561b1f49","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"38f8c78460d0c171","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ceb269cfcbfb3737","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"6fc86b42fa2194c7","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"948868ae3f88e79e","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"f78a9daa44503acf","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"f065b37e2901ab44","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"03f33a24e5022801","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"db26cef88e3879aa","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"496f2ff2ad72eb56","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a33121c16f5e4d20","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1b5947476f3297ae","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ebaf8ad16d676e4c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5ec7e2368a41e7d1","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"f69cbc017c2bee73","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e2095571b8a4a9ea","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"8e8d9589ff612ccb","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"4acd7b14907d2eab","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"00b864b32ca6962f","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"0e7fd376997e0ce6","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"8947ab8c7604a712","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"12ae4c62954fb4d7","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5c70a05c3b20c460","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"7920d4521fc31742","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"14d71824a114fae5","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5c58f35ad11ea36d","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"c68ff69ac1086025","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"bfb4d21e0325cd27","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"1c5328ce70a7d781","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"3a27002f3a51c391","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"15c536b247ddda9b","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"b8dfd3383dc85e16","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d834384f74b37311","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"33ad4a447e65fe4c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"5f92334372103621","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"3b36a0673402ddea","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"b8e5c9de8614511a","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d6f7d0951a76b20f","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"dc731362e0a22c79","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"c37ce29a12797b87","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"b7f8903cecd3c417","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"e9aea7737083ea26","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ca849c611df2249c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"eba969c354d1a2b6","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"828d340d34a88e86","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"18a6bfdbc9b1999c","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"ea6de81ee5ad1594","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"46f992eaa836ef3e","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"a6c162781ee3a889","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"926d3b6bfe6e1943","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"7e15147781f2b0b4","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"221d9d61291eac74","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"d1c16d1fc4dc5998","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"25596ab30bae8f45","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"6f03c0e16553edcf","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"af7ab58246b4c2a5","prefixes":{"":{"product":940}}}, // [White Ops, Inc.]
+  {"hash":"82a102dc6f580854","prefixes":{"":{"product":773}}}, // [Extreme Reach Digital (ER Digital)]
+  {"hash":"35f665efa0e2a55c","prefixes":{"":{"product":773}}}, // [Extreme Reach Digital (ER Digital)]
+  {"hash":"3a48f18bf340e74a","prefixes":{"":{"product":773}}}, // [Extreme Reach Digital (ER Digital)]
+  {"hash":"ee365433c62a5c89","prefixes":{"":{"product":773}}}, // [Extreme Reach Digital (ER Digital)]
+  {"hash":"abe6370bd088dcf4","prefixes":{"":{"product":941}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
+  {"hash":"92dba1cdcba82d8a","prefixes":{"":{"product":941}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
+  {"hash":"ee0ccb57505565f7","prefixes":{"":{"product":941}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
+  {"hash":"f25f5e4909b9792c","prefixes":{"":{"product":941}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
+  {"hash":"8a9e6f7beeb084c5","prefixes":{"":{"product":941}}}, // [Hangzhou Qiguan Network Technology Co., Ltd.]
+  {"hash":"94542c85cf399cbd","prefixes":{"":{"product":323}}}, // [FinanceGenerator]
+  {"hash":"46ea052a92233562","prefixes":{"":{"product":942}}}, // [Admetrics]
+  {"hash":"ea5d2271464ca35f","prefixes":{"":{"product":942}}}, // [Admetrics]
+  {"hash":"286ad0ac5bca5d03","prefixes":{"":{"product":943}}}, // [Admetrics GmbH]
+  {"hash":"ff1ffc67b7e3f33a","prefixes":{"":{"product":944}}}, // [Amobee Inc. d/b/a Gradient X]
+  {"hash":"72cbc5ba1ec93b34","prefixes":{"":{"product":944}}}, // [Amobee Inc. d/b/a Gradient X]
+  {"hash":"a6fc31f82c22f31e","prefixes":{"":{"product":25}}}, // [Action Exchange, Inc.]
+  {"hash":"1ba64e5bb4889fc8","prefixes":{"":{"product":25}}}, // [Action Exchange, Inc.]
+  {"hash":"1d75cb11df01626e","prefixes":{"":{"product":25}}}, // [Action Exchange, Inc.]
+  {"hash":"91e1e972e2691a51","prefixes":{"":{"product":25}}}, // [Action Exchange, Inc.]
+  {"hash":"23c68afb7d193b79","prefixes":{"":{"product":25}}}, // [Action Exchange, Inc.]
+  {"hash":"63d64a70ef1c102e","prefixes":{"":{"product":792}}}, // [Recruit Co., Ltd. Communications]
+  {"hash":"5e5fd982d3646780","prefixes":{"":{"product":793}}}, // [RECRUIT Communications]
+  {"hash":"405787e06ebc6f4c","prefixes":{"dc":{"product":945}}}, // [Datalicious Pty Ltd]
+  {"hash":"cddbf4fe7458433c","prefixes":{"":{"product":945}}}, // [Datalicious Pty Ltd]
+  {"hash":"1c6b7ff16564ebc9","prefixes":{"":{"product":945}}}, // [Datalicious Pty Ltd]
+  {"hash":"8b00b076af37f543","prefixes":{"":{"product":945}}}, // [Datalicious Pty Ltd]
+  {"hash":"688a0b3764e1741b","prefixes":{"":{"product":946}}}, // [Intent Media]
+  {"hash":"04bba28fa6468b07","prefixes":{"":{"product":947}}}, // [AdNear Pte Ltd.]
+  {"hash":"c10761fe93bddd5e","prefixes":{"":{"product":948}}}, // [Zhejiang MediaAdx Network Technology Co., Ltd]
+  {"hash":"3b0fa4efa209ebfa","prefixes":{"":{"product":948}}}, // [Zhejiang MediaAdx Network Technology Co., Ltd]
+  {"hash":"e1b43b2549b03858","prefixes":{"":{"product":949}}}, // [Harris Interactive]
+  {"hash":"6ade6d73b73295b2","prefixes":{"":{"product":949}}}, // [Harris Interactive]
+  {"hash":"63efa9155999d096","prefixes":{"":{"product":950}}}, // [BuzzCity Pte Ltd]
+  {"hash":"564ef19eef7254cf","prefixes":{"":{"product":950}}}, // [BuzzCity Pte Ltd]
+  {"hash":"6bbdf3ce8eec6f52","prefixes":{"":{"product":950}}}, // [BuzzCity Pte Ltd]
+  {"hash":"436cc9ab781b357d","prefixes":{"":{"product":950}}}, // [BuzzCity Pte Ltd]
+  {"hash":"e8cc8c7d43c80259","prefixes":{"":{"product":951}}}, // [Sputnyx]
+  {"hash":"2150e4c3d0f193b2","prefixes":{"":{"product":951}}}, // [Sputnyx]
+  {"hash":"54d8f3466d5879bc","prefixes":{"":{"product":951}}}, // [Sputnyx]
+  {"hash":"b930b780e12735dc","prefixes":{"":{"product":951}}}, // [Sputnyx]
+  {"hash":"5817597124959a0f","prefixes":{"":{"product":952}}}, // [CyberZ, Inc]
+  {"hash":"52a82bf3bc55f753","prefixes":{"":{"product":953}}}, // [Spark Networks USA, LLC]
+  {"hash":"de87290af2710dce","prefixes":{"*":{"product":954}}}, // [Ezakus]
+  {"hash":"9fa7220a9c513b82","prefixes":{"":{"product":955}}}, // [V4x SAS]
+  {"hash":"cdea2314328db64c","prefixes":{"":{"product":955}}}, // [V4x SAS]
+  {"hash":"9ab122baee7ffef0","prefixes":{"":{"product":955}}}, // [V4x SAS]
+  {"hash":"5b7763887f62f0e2","prefixes":{"":{"product":956}}}, // [Tapjoy Inc.]
+  {"hash":"c476f40a640ceb50","prefixes":{"":{"product":12}}}, // [Madeleine Mode GmbH]
+  {"hash":"b03d8c48bc51a903","prefixes":{"":{"product":12}}}, // [Madeleine Mode GmbH]
+  {"hash":"6ccfc9d681f1cce4","prefixes":{"":{"product":12}}}, // [Madeleine Mode GmbH]
+  {"hash":"519e706c784712cd","prefixes":{"":{"product":12}}}, // [Madeleine Mode GmbH]
+  {"hash":"4b99f5579a32d2ac","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"7bb686f653faf750","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"59bac04b09eb1850","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"c7c593cac7252275","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"9a2642b29d01ad5a","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"19e7f2b697047d0f","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"9ccde0a8ec3f9703","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"a81ee6b474d31f53","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"3b743b2fda71dd5f","prefixes":{"":{"product":957}}}, // [EXEBID]
+  {"hash":"6378b3090ceafcf5","prefixes":{"*":{"product":562}}}, // [Bannerflow AB]
+  {"hash":"09de5d9c8a08a419","prefixes":{"":{"product":958}}}, // [Exposebox Ltd]
+  {"hash":"d88faf97f4f01be0","prefixes":{"":{"product":958}}}, // [Exposebox Ltd]
+  {"hash":"1b7a8075387597c8","prefixes":{"":{"product":958}}}, // [Exposebox Ltd]
+  {"hash":"42127ec758c4891f","prefixes":{"":{"product":959}}}, // [MotoMiner]
+  {"hash":"f5fe6be8ffc65b45","prefixes":{"":{"product":960}}}, // [BuySellAds.com Inc.]
+  {"hash":"4b9190a98d317014","prefixes":{"":{"product":960}}}, // [BuySellAds.com Inc.]
+  {"hash":"3b55d9e306cf9e3c","prefixes":{"":{"product":960}}}, // [BuySellAds.com Inc.]
+  {"hash":"a9da15f40498a6f3","prefixes":{"":{"product":961}}}, // [Viking River Cruises]
+  {"hash":"e2a8d45a4c55dae6","prefixes":{"":{"product":962}}}, // [Sittercity Incorporated]
+  {"hash":"5dd667d71a34b766","prefixes":{"":{"product":963}}}, // [Facetz]
+  {"hash":"00776ec1c54574db","prefixes":{"":{"product":964}}}, // [YOOSE Pte. Ltd.]
+  {"hash":"f8c3b8f01c62da3c","prefixes":{"":{"product":965}}}, // [AdYapper, Inc.]
+  {"hash":"6c1804db5b6679a9","prefixes":{"":{"product":965}}}, // [AdYapper, Inc.]
+  {"hash":"a361de3d2fcba609","prefixes":{"":{"product":965}}}, // [AdYapper, Inc.]
+  {"hash":"1f805f58db63a12d","prefixes":{"":{"product":965}}}, // [AdYapper, Inc.]
+  {"hash":"7090e79d9ec26768","prefixes":{"":{"product":965}}}, // [AdYapper, Inc.]
+  {"hash":"727b3d1100b7d374","prefixes":{"":{"product":965}}}, // [AdYapper, Inc.]
+  {"hash":"17b396141b96c236","prefixes":{"":{"product":799}}}, // [Webtrekk GmbH]
+  {"hash":"b0149857f43862d9","prefixes":{"":{"product":144}}}, // [Spark Flow S.A.]
+  {"hash":"f9c00c55ede792e2","prefixes":{"":{"product":144}}}, // [Spark Flow S.A.]
+  {"hash":"8eb24e3340b4c707","prefixes":{"":{"product":966}}}, // [Clickky LLP DBA Clickky]
+  {"hash":"2d27319a70fb6262","prefixes":{"":{"product":966}}}, // [Clickky LLP DBA Clickky]
+  {"hash":"b140173de591dc64","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"7e2351ba05fefcce","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"88a66ce20c2df5e5","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"705049ea1378adbd","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"eadabb19d68f0e02","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"684343b8f00b5425","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"fedb0d981d151071","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"eb26cb8958b84143","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"b4f42222ff48d611","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"3ef4c3e15c3889aa","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"346ac90e489a0d27","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"f0685c9d889a4dcb","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"d2ae279176821009","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"98746e3eb9075cc5","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"f4e7d8ca3f73252e","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"145b69a5570cf0e6","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"b96e6d8a02aabe0f","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"5f7def46ec1776af","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"075bdf0eaa8a2d8a","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"374ddadb8b59c656","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"e75f11f13cf01278","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"fa9f043b6f9f0225","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"51046da25aac136a","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"e3d9117eacb00b04","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"2291e11d2ca518c2","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"208af3ccccac3a8a","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"8a7e7a7c9510a539","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"d62dab4e5ba19318","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"9faead99b5b9e15b","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"21ad4e7e6897e7be","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"5f6e332f4f7ad081","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"28c87295fd99d9b2","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"ec4d1f8447f0f153","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"bcdb0c5a6199a121","prefixes":{"":{"product":967}}}, // [eRate Online Measurement Solutions Ltd.]
+  {"hash":"dc1424820d5085bc","prefixes":{"":{"product":967}}}, // [eRate Online Measurement Solutions Ltd.]
+  {"hash":"d110aae732b1c80d","prefixes":{"":{"product":967}}}, // [eRate Online Measurement Solutions Ltd.]
+  {"hash":"d461527c3648da49","prefixes":{"":{"product":968}}}, // [Baumann Ber Rivnay]
+  {"hash":"da8fb21c56d3c224","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"abb93e258191198a","prefixes":{"":{"product":13}}}, // [TripAdvisor LLC]
+  {"hash":"67ce1b0bfa972cc4","prefixes":{"":{"product":969}}}, // [TUI Connect GmbH]
+  {"hash":"63c1158e18a5ea27","prefixes":{"":{"product":970}}}, // [INFOnline GmbH]
+  {"hash":"46a40e7a328ffee7","prefixes":{"":{"product":971}}}, // [Adizio]
+  {"hash":"c5ca269d09b7c25f","prefixes":{"*":{"product":972}}}, // [Joystick Interactive]
+  {"hash":"93d3775dcb79f65b","prefixes":{"":{"product":973}}}, // [EngageClick Inc]
+  {"hash":"0af466da8ca75d0b","prefixes":{"":{"product":973}}}, // [EngageClick Inc]
+  {"hash":"111ffa6b19238149","prefixes":{"":{"product":974}}}, // [GeeeN, Inc.]
+  {"hash":"46313b1a2b164e11","prefixes":{"":{"product":974}}}, // [GeeeN, Inc.]
+  {"hash":"edeaec47d1406cde","prefixes":{"":{"product":974}}}, // [GeeeN, Inc.]
+  {"hash":"e4fa03e71e81c717","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"b05d395ad43a6851","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"babf6252b4c60056","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"db86fc0d97ddf866","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"ea61f7fa94bc2f36","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"495d58c312a856b7","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"ce854368c8ba8c24","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"7c1ebbe2aa48388d","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"0ac9c5956a237913","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"5e22bf81f1721d99","prefixes":{"":{"product":975}}}, // [Arbigo Inc.]
+  {"hash":"ad1ab56f3a151112","prefixes":{"":{"product":976}}}, // [FlxOne BV]
+  {"hash":"6c833f73351e1f63","prefixes":{"":{"product":976}}}, // [FlxOne BV]
+  {"hash":"82f8d328de710cff","prefixes":{"":{"product":976}}}, // [FlxOne BV]
+  {"hash":"95c33537789a441f","prefixes":{"":{"product":976}}}, // [FlxOne BV]
+  {"hash":"712c817d06c0d8c6","prefixes":{"":{"product":976}}}, // [FlxOne BV]
+  {"hash":"63446ae2652818ab","prefixes":{"":{"product":10}}}, // [eBay]
+  {"hash":"45b598cd3bc42672","prefixes":{"":{"product":977}}}, // [ExtendTV, Inc.]
+  {"hash":"372fde25faa1c878","prefixes":{"":{"product":977}}}, // [ExtendTV, Inc.]
+  {"hash":"db1da0ef7de3e1e6","prefixes":{"":{"product":978}}}, // [momentM, Inc]
+  {"hash":"5710705dc9e3a971","prefixes":{"":{"product":978}}}, // [momentM, Inc]
+  {"hash":"4ee3d75e96c8e3aa","prefixes":{"":{"product":978}}}, // [momentM, Inc]
+  {"hash":"b329682f26e4fcc6","prefixes":{"":{"product":978}}}, // [momentM, Inc]
+  {"hash":"71215c2931d79d35","prefixes":{"":{"product":978}}}, // [momentM, Inc]
+  {"hash":"667a4fe4b59238b9","prefixes":{"":{"product":978}}}, // [momentM, Inc]
+  {"hash":"a7fbeec4fb43f9d9","prefixes":{"*":{"product":979}}}, // [OnCard Marketing dba RevTrax]
+  {"hash":"48a825a8c5ef9edd","prefixes":{"*":{"product":980}}}, // [Youtube - API]
+  {"hash":"19459fb447ce4de4","prefixes":{"*":{"product":981}}}, // [Thirdpresence Ltd]
+  {"hash":"f079f0a998c56593","prefixes":{"":{"product":981}}}, // [Thirdpresence Ltd]
+  {"hash":"108dd21ceba53008","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"7b0dec2d8c1ec967","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"b5c3f2f3c1c37850","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"ba9b4eca15987843","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"4e521b3e57d76700","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"29ab2715e00761b0","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"688071d177180274","prefixes":{"":{"product":982}}}, // [Visual IQ, Inc.]
+  {"hash":"4e682c7f7f2ebda9","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"4b6451297bd74247","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"95d75ced1262ecda","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"ac94d70ffcad5c63","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"578591a9eb9652f2","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"5528666c72c7c71c","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"3deb1cd39233765c","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"4e05303df9f07532","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"99936e7e455c77b7","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"f0e5986dc65416fd","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"5095285a4ab05444","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"670fdb8ea86ee233","prefixes":{"":{"product":983}}}, // [Appreciate]
+  {"hash":"ad2de628bc6fd483","prefixes":{"":{"product":984},"lodeo-":{"product":985}}}, // [CyberAgent d/b/a GameLogic] [Lodeo]
+  {"hash":"66e26f9703f2dd67","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"80451e302607b653","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"bb7f7e8ab7b99724","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"51dbfc01b5f86601","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"2a8926ec16272a9b","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"4e2334aabf3b7af7","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"1bbabf05900a894f","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"a45a66788779b9bc","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"c4d101005526e2ef","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"7f43400e381d40ff","prefixes":{"":{"product":984}}}, // [CyberAgent d/b/a GameLogic]
+  {"hash":"e323697c02e1a841","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"11c505e6e21eefdb","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"afc246433e1284d8","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"c7322cd1ad0df953","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"a090f61c3ee5e028","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"846ea0c461560421","prefixes":{"":{"product":985}}}, // [Lodeo]
+  {"hash":"b433db4fe5f6ed8d","prefixes":{"":{"product":987}}}, // [LTD "RTB-MEDIA"]
+  {"hash":"e5b814009c134495","prefixes":{"":{"product":987}}}, // [LTD "RTB-MEDIA"]
+  {"hash":"ce6b2c64ce23d14b","prefixes":{"":{"product":988}}}, // [Maverick., inc.]
+  {"hash":"32ef8d9c49285e19","prefixes":{"":{"product":988}}}, // [Maverick., inc.]
+  {"hash":"ac99e3b588f1d521","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"da9e2cf59b85610c","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"d86ff177f1095173","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"7853aedd1a267ffb","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"5f505217689c7174","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"27be294cbea039f9","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"bae6c7f50fff772d","prefixes":{"":{"product":989}}}, // [FuelX]
+  {"hash":"63f51428712678ec","prefixes":{"":{"product":324}}}, // [Telstra Corporation]
+  {"hash":"f1d920cc5a16b3a9","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"12a7d7495eb7a91f","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"6ca28320c4765235","prefixes":{"":{"product":986}}}, // [CyberAgent d/b/a Dynalyst]
+  {"hash":"aeb171f5cad96320","prefixes":{"":{"product":990}}}, // [Tutor.com]
+  {"hash":"5de1c09366f03919","prefixes":{"":{"product":164}}}, // [wayStorm Co., Ltd.]
+  {"hash":"9977349a2c52c1b6","prefixes":{"":{"product":164}}}, // [wayStorm Co., Ltd.]
+  {"hash":"3304d732f88c9ebe","prefixes":{"":{"product":164}}}, // [wayStorm Co., Ltd.]
+  {"hash":"8b1b0e966a643448","prefixes":{"":{"product":164}}}, // [wayStorm Co., Ltd.]
+  {"hash":"852a445ec03b1224","prefixes":{"":{"product":991}}}, // [Rebelmouse]
+  {"hash":"ebef84a02e75b037","prefixes":{"*":{"product":991}}}, // [Rebelmouse]
+  {"hash":"6ff0ad7b4d4ee2ef","prefixes":{"":{"product":992}}}, // [Adviator DSP]
+  {"hash":"c28458e1bac3bb75","prefixes":{"":{"product":992}}}, // [Adviator DSP]
+  {"hash":"041403702e0ae9f0","prefixes":{"":{"product":992}}}, // [Adviator DSP]
+  {"hash":"31890d74ba2e0eca","prefixes":{"":{"product":525}}}, // [abilicom GmbH]
+  {"hash":"16f2a07aea3c767b","prefixes":{"":{"product":993}}}, // [Acens Technologies, S.L.]
+  {"hash":"4d628548402f2933","prefixes":{"":{"product":994}}}, // [Yashi, Inc]
+  {"hash":"6f97eb7dc578c1d3","prefixes":{"":{"product":677}}}, // [Taptica]
+  {"hash":"843cc26d64f855e3","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"7f81eef44c27fceb","prefixes":{"":{"product":495}}}, // [Miaozhen Systems]
+  {"hash":"f36b5e4d896bf9fc","prefixes":{"":{"product":995}}}, // [Flaminem Inc]
+  {"hash":"ec10935d7141abb2","prefixes":{"":{"product":996}}}, // [Mediahead AG]
+  {"hash":"d074e5017286d25a","prefixes":{"":{"product":996}}}, // [Mediahead AG]
+  {"hash":"e7aa39274c05edf9","prefixes":{"":{"product":996}}}, // [Mediahead AG]
+  {"hash":"06d3dae2f13a3dcb","prefixes":{"":{"product":996}}}, // [Mediahead AG]
+  {"hash":"1cc1098f16d364e0","prefixes":{"":{"product":996}}}, // [Mediahead AG]
+  {"hash":"15ee5953d4c74d48","prefixes":{"":{"product":996}}}, // [Mediahead AG]
+  {"hash":"b434b094029a84a8","prefixes":{"":{"product":997}}}, // [Admixer]
+  {"hash":"766b3c24fb448820","prefixes":{"":{"product":998}}}, // [Communication Services Tele2 GmbH]
+  {"hash":"35e369c14d37cb1c","prefixes":{"*":{"product":999}}}, // [99click]
+  {"hash":"c5b7e1faef274865","prefixes":{"":{"product":1000}}}, // [Ströer Mobile Media GmbH]
+  {"hash":"dc01aead4f784e4d","prefixes":{"":{"product":1000}}}, // [Ströer Mobile Media GmbH]
+  {"hash":"39525c5c19a8a044","prefixes":{"":{"product":1000}}}, // [Ströer Mobile Media GmbH]
+  {"hash":"397c77c97b7945f8","prefixes":{"":{"product":1000}}}, // [Ströer Mobile Media GmbH]
+  {"hash":"3097a79ab689b320","prefixes":{"":{"product":1000}}}, // [Ströer Mobile Media GmbH]
+  {"hash":"c27b66085df0c0da","prefixes":{"":{"product":1001}}}, // [LLC "Life Style"]
+  {"hash":"3a7913ff0ce0cc21","prefixes":{"":{"product":1001}}}, // [LLC "Life Style"]
+  {"hash":"9d1661dae6ff9304","prefixes":{"":{"product":1001}}}, // [LLC "Life Style"]
+  {"hash":"cdd266d878d3e9d5","prefixes":{"":{"product":1001}}}, // [LLC "Life Style"]
+  {"hash":"d3c08bf02865217e","prefixes":{"":{"product":1002}}}, // [2Y Media SAS (adserverpub)]
+  {"hash":"bbfe70399cd3fcb3","prefixes":{"":{"product":1002}}}, // [2Y Media SAS (adserverpub)]
+  {"hash":"a17b33aa94234849","prefixes":{"":{"product":1002}}}, // [2Y Media SAS (adserverpub)]
+  {"hash":"8e073ea44074ec93","prefixes":{"":{"product":1002}}}, // [2Y Media SAS (adserverpub)]
+  {"hash":"12afa442e09a07c9","prefixes":{"":{"product":1002}}}, // [2Y Media SAS (adserverpub)]
+  {"hash":"7fa5ca05a3a0b474","prefixes":{"":{"product":1003}}}, // [Platform IQ]
+  {"hash":"f6f0f65947909d69","prefixes":{"":{"product":1003}}}, // [Platform IQ]
+  {"hash":"77b586602e5dec3f","prefixes":{"":{"product":1003}}}, // [Platform IQ]
+  {"hash":"bba327f348a4693e","prefixes":{"":{"product":1003}}}, // [Platform IQ]
+  {"hash":"a544a3b25c4d5113","prefixes":{"":{"product":1004}}}, // [Silveredge Inc]
+  {"hash":"037cb4c9598870ee","prefixes":{"":{"product":1004}}}, // [Silveredge Inc]
+  {"hash":"2a6ed7c1b6a78509","prefixes":{"":{"product":1004}}}, // [Silveredge Inc]
+  {"hash":"06d23751a7963710","prefixes":{"":{"product":1005}}}, // [SMADEX]
+  {"hash":"0a84ed2865a74b8a","prefixes":{"":{"product":1005}}}, // [SMADEX]
+  {"hash":"e97a828dc740d645","prefixes":{"":{"product":1005}}}, // [SMADEX]
+  {"hash":"aa964a10a9ccda5b","prefixes":{"":{"product":1005}}}, // [SMADEX]
+  {"hash":"d7675b344c153db3","prefixes":{"":{"product":1005}}}, // [SMADEX]
+  {"hash":"76eaf06fcd95e8e8","prefixes":{"":{"product":1006}}}, // [Suzu Muchi]
+  {"hash":"fcf26d7eec95d72d","prefixes":{"":{"product":342}}}, // [LOKA Research inc.]
+  {"hash":"3b238a232cbc26bd","prefixes":{"":{"product":342}}}, // [LOKA Research inc.]
+  {"hash":"a544c76e7ec01862","prefixes":{"":{"product":342}}}, // [LOKA Research inc.]
+  {"hash":"7922cb2f11972c85","prefixes":{"":{"product":342}}}, // [LOKA Research inc.]
+  {"hash":"613551ec99bec944","prefixes":{"":{"product":1007}}}, // [PlannTo Technologies Private Limited]
+  {"hash":"bb07eb5de3d95038","prefixes":{"":{"product":1007}}}, // [PlannTo Technologies Private Limited]
+  {"hash":"729165b2ebbc6996","prefixes":{"":{"product":1007}}}, // [PlannTo Technologies Private Limited]
+  {"hash":"187629571e0338cf","prefixes":{"":{"product":1007}}}, // [PlannTo Technologies Private Limited]
+  {"hash":"bdd2e20221d7e507","prefixes":{"":{"product":1008}}}, // [Viator, Inc]
+  {"hash":"1caf0cb7a05c5941","prefixes":{"":{"product":474}}}, // [Xrost]
+  {"hash":"4c6513300966da08","prefixes":{"":{"product":1009}}}, // [NODDINGTON TECHNOLOGIES LIMITED]
+  {"hash":"2c1d6a203788af2b","prefixes":{"":{"product":1010}}}, // [Plan Blue Ltd]
+  {"hash":"3c0da2d4356e18a5","prefixes":{"":{"product":1010}}}, // [Plan Blue Ltd]
+  {"hash":"2568d0917d238964","prefixes":{"":{"product":1011}}}, // [Addictive Mobility]
+  {"hash":"f79c822ab2cca8ee","prefixes":{"":{"product":1011}}}, // [Addictive Mobility]
+  {"hash":"c610b5ae3df923cd","prefixes":{"":{"product":1011}}}, // [Addictive Mobility]
+  {"hash":"a614ab43bf2d906b","prefixes":{"":{"product":1011}}}, // [Addictive Mobility]
+  {"hash":"747eeca86822f19c","prefixes":{"":{"product":1012}}}, // [A6 Corporation]
+  {"hash":"cbdfdaeff8b7d933","prefixes":{"":{"product":1013}}}, // [Mobusi Mobile Advertising]
+  {"hash":"5b2d082c7811bead","prefixes":{"":{"product":1014}}}, // [Wishabi]
+  {"hash":"c811726b56670631","prefixes":{"":{"product":1014}}}, // [Wishabi]
+  {"hash":"09d3b27d380d43a0","prefixes":{"":{"product":1014}}}, // [Wishabi]
+  {"hash":"eecab68f555d1f9f","prefixes":{"":{"product":1015}}}, // [onAd GmbH]
+  {"hash":"d05b20f38e3bb984","prefixes":{"":{"product":1016}}}, // [Media Decision GmbH]
+  {"hash":"4a9b8dddd4c7567c","prefixes":{"":{"product":1016}}}, // [Media Decision GmbH]
+  {"hash":"5121142c1b8676fd","prefixes":{"":{"product":1016}}}, // [Media Decision GmbH]
+  {"hash":"e083b93d5a87c743","prefixes":{"":{"product":1017}}}, // [Unitymedia NRW]
+  {"hash":"c665046a783daa9d","prefixes":{"":{"product":1018}}}, // [Nowspots INC, dba Perfect Audience]
+  {"hash":"663d5fdbc3a52729","prefixes":{"":{"product":1018}}}, // [Nowspots INC, dba Perfect Audience]
+  {"hash":"991e96310871571b","prefixes":{"":{"product":1018}}}, // [Nowspots INC, dba Perfect Audience]
+  {"hash":"0503d775704af4a2","prefixes":{"":{"product":1018}}}, // [Nowspots INC, dba Perfect Audience]
+  {"hash":"2c55a4ef41531200","prefixes":{"":{"product":1019}}}, // [Avis]
+  {"hash":"62817a7d196cbdcf","prefixes":{"":{"product":1020}}}, // [Comcast]
+  {"hash":"2e4bb1f4d07f3180","prefixes":{"":{"product":1021}}}, // [Jack Spade]
+  {"hash":"e7d369c24971784a","prefixes":{"":{"product":1022}}}, // [Dollar General]
+  {"hash":"a8c9b93aae571ed5","prefixes":{"":{"product":1023}}}, // [Care.com]
+  {"hash":"713775b7bc737116","prefixes":{"":{"product":1024}}}, // [Clickagy, LLC]
+  {"hash":"8b6b45c1c86cd84b","prefixes":{"":{"product":1024}}}, // [Clickagy, LLC]
+  {"hash":"34376185507c9ae0","prefixes":{"":{"product":1025}}}, // [GlobalWebIndex]
+  {"hash":"8b17254892b590e3","prefixes":{"":{"product":1026}}}, // [King.com]
+  {"hash":"8516f044f19bb3ae","prefixes":{"":{"product":1026}}}, // [King.com]
+  {"hash":"d811179454fad251","prefixes":{"":{"product":1026}}}, // [King.com]
+  {"hash":"946611fa2f4b067a","prefixes":{"":{"product":1027}}}, // [Proquire LLC - Accenture]
+  {"hash":"cfa0e9025fcd5712","prefixes":{"":{"product":1028}}}, // [Dynamic Yield]
+  {"hash":"b01c0239af74e72e","prefixes":{"":{"product":1028}}}, // [Dynamic Yield]
+  {"hash":"e480d03a980d3bfc","prefixes":{"":{"product":1028}}}, // [Dynamic Yield]
+  {"hash":"f22fe7e17c58b562","prefixes":{"":{"product":1028}}}, // [Dynamic Yield]
+  {"hash":"f8da77c2fdcad106","prefixes":{"":{"product":1028}}}, // [Dynamic Yield]
+  {"hash":"cea3bf4afe576984","prefixes":{"":{"product":1029}}}, // [Charter business]
+  {"hash":"f8029c009186163f","prefixes":{"":{"product":1030}}}, // [The ADEX]
+  {"hash":"61b09f5d40722e69","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"aa63151485efa109","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"ed37e98f45f10404","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"f9fda879239cf155","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"2dfe9124b3439d80","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"93a9e29ac238b380","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"5e080b13877f5de7","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"eb22d59d4594e6d3","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"a28e072f804db6a0","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"945f948eacea62c9","prefixes":{"":{"product":1031}}}, // [OneDigitalAd Technologies]
+  {"hash":"b85074a47da33b83","prefixes":{"":{"product":1032}}}, // [ADJUST]
+  {"hash":"9f369deb4f045364","prefixes":{"":{"product":1032}}}, // [ADJUST]
+  {"hash":"2d6ceeb3eef38c27","prefixes":{"":{"product":1032}}}, // [ADJUST]
+  {"hash":"65240dfe37410021","prefixes":{"":{"product":1032}}}, // [ADJUST]
+  {"hash":"8d3dfcbf705f1191","prefixes":{"":{"product":1032}}}, // [ADJUST]
+  {"hash":"a2d35afc9c960448","prefixes":{"":{"product":1033}}}, // [ADmantX, SPA]
+  {"hash":"3d3bc7f00b0ef8d3","prefixes":{"":{"product":1034}}}, // [Sogou.com]
+  {"hash":"9eb0737a130a6f08","prefixes":{"":{"product":1035}}}, // [xAd, Inc.]
+  {"hash":"a9ff22250a3c29a1","prefixes":{"":{"product":1036}}}, // [VideoBlocks]
+  {"hash":"61f27a00f3821730","prefixes":{"":{"product":1037}}}, // [GraphicStocks]
+  {"hash":"f0792974945e7184","prefixes":{"":{"product":1038}}}, // [Microsoft Advertising]
+  {"hash":"81f27cb33d47894b","prefixes":{"":{"product":1039}}}, // [Rontar LTD]
+  {"hash":"e8ae13fee2796336","prefixes":{"":{"product":1039}}}, // [Rontar LTD]
+  {"hash":"d979ed3048a9dc3d","prefixes":{"":{"product":1039}}}, // [Rontar LTD]
+  {"hash":"187c7e948b323b3a","prefixes":{"dsp":{"product":1039}}}, // [Rontar LTD]
+  {"hash":"1a5cfb3f08b31682","prefixes":{"":{"product":1040}}}, // [Torrential, Inc.]
+  {"hash":"99bb29582234b47b","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"14a0b2d821feb403","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"4bfb576f457b3ad4","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"d2e32e6a4c73344a","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"3c8aa320c0f5fb9d","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"8c3cae9472fcd43a","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"18d673cc147eaba5","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"fb4f3dd591cba22f","prefixes":{"bid":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"49aef0b488ab5024","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"2b7a17458f44228d","prefixes":{"":{"product":1041}}}, // [AMoAd, Inc.]
+  {"hash":"7458cceedc9f812a","prefixes":{"":{"product":1042}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
+  {"hash":"dd47f178c7a055b8","prefixes":{"":{"product":1042}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
+  {"hash":"db975b73da86c8ce","prefixes":{"":{"product":1042}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
+  {"hash":"6216946891299e23","prefixes":{"":{"product":1042}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
+  {"hash":"52ee7c22862a74b6","prefixes":{"":{"product":1042}}}, // [Tukmob Information Technology(Shanghai)Co. Ltd]
+  {"hash":"3cc39e801c92ea89","prefixes":{"":{"product":1043}}}, // [Jampp/Devego S.A.]
+  {"hash":"31fb8bdf6d2b85d2","prefixes":{"":{"product":1044}}}, // [Placed]
+  {"hash":"a6ff57032773fe41","prefixes":{"*":{"product":1045}}}, // [Digitas Health]
+  {"hash":"caeb7a071a866e17","prefixes":{"*":{"product":1045}}}, // [Digitas Health]
+  {"hash":"6e946f5fac72b0b4","prefixes":{"":{"product":1046}}}, // [Answer Media, LLC]
+  {"hash":"31c3d7ef1499fd26","prefixes":{"":{"product":1046}}}, // [Answer Media, LLC]
+  {"hash":"d681f06391c7f861","prefixes":{"":{"product":1047}}}, // [1000mercis]
+  {"hash":"1549387212aaa6a3","prefixes":{"":{"product":1048}}}, // [Upstart Network, Inc.]
+  {"hash":"e48f63d27d0c24c7","prefixes":{"":{"product":1049}}}, // [Forensiq, LLC]
+  {"hash":"7579b1341b228f93","prefixes":{"":{"product":1049}}}, // [Forensiq, LLC]
+  {"hash":"f2e570ecd2540399","prefixes":{"":{"product":1050}}}, // [LoopMe Ltd]
+  {"hash":"7d4e3b90001a044e","prefixes":{"":{"product":1050}}}, // [LoopMe Ltd]
+  {"hash":"528167a286d8ccf8","prefixes":{"":{"product":1051}}}, // [Bannerlink (Liquidus)]
+  {"hash":"0b2d528c0dce5bba","prefixes":{"":{"product":1051}}}, // [Bannerlink (Liquidus)]
+  {"hash":"758cc459053712cf","prefixes":{"":{"product":1051}}}, // [Bannerlink (Liquidus)]
+  {"hash":"57951d4b34add1a9","prefixes":{"":{"product":1051}}}, // [Bannerlink (Liquidus)]
+  {"hash":"3d93ddd2b1dc8083","prefixes":{"":{"product":1051}}}, // [Bannerlink (Liquidus)]
+  {"hash":"88f0b992c4b99c65","prefixes":{"":{"product":1052}}}, // [Dell Inc.]
+  {"hash":"f8820430b42f89f8","prefixes":{"":{"product":1053}}}, // [My Perfect Resume]
+  {"hash":"6f018db6d7a12f5e","prefixes":{"":{"product":1054}}}, // [Ajillion Max Ltd]
+  {"hash":"b591ab0baccecd52","prefixes":{"":{"product":1054}}}, // [Ajillion Max Ltd]
+  {"hash":"35d86d0121dbd41a","prefixes":{"":{"product":1055}}}, // [Swelen France SA.]
+  {"hash":"25b09dd0e8d2977a","prefixes":{"":{"product":1055}}}, // [Swelen France SA.]
+  {"hash":"f5cb853eba61193a","prefixes":{"":{"product":1056}}}, // [Sleeptrain]
+  {"hash":"c620109c65610aeb","prefixes":{"":{"product":1057}}}, // [Sleepcountry]
+  {"hash":"9c6554ebebdbfa08","prefixes":{"":{"product":1058}}}, // [Hoover]
+  {"hash":"f34ddb2b65330794","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"5d9eb2a8dc1a1687","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"e2207dc37f1b89e8","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"682ec1b47db930b9","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"638a2c2dc53d2ab7","prefixes":{"":{"product":1060}}}, // [Mocoplex Inc.]
+  {"hash":"ee330ed89897a55c","prefixes":{"":{"product":1060}}}, // [Mocoplex Inc.]
+  {"hash":"60ab035f28a35e30","prefixes":{"":{"product":1060}}}, // [Mocoplex Inc.]
+  {"hash":"5929f2c289d9e073","prefixes":{"":{"product":778}}}, // [Gruvi Ltd.]
+  {"hash":"c16c02248018a374","prefixes":{"":{"product":778}}}, // [Gruvi Ltd.]
+  {"hash":"e6eb2d1c03d2be83","prefixes":{"":{"product":778}}}, // [Gruvi Ltd.]
+  {"hash":"95fa4396cadc336e","prefixes":{"":{"product":778}}}, // [Gruvi Ltd.]
+  {"hash":"2604a7d96f168c84","prefixes":{"":{"product":1061}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
+  {"hash":"294fdebfd41771a8","prefixes":{"":{"product":1061}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
+  {"hash":"c6beb451fe4c58c2","prefixes":{"":{"product":1061}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
+  {"hash":"b0f5f51210e6f2af","prefixes":{"":{"product":1061}}}, // [Brightsparc Technologies Pty Ltd trading as Native]
+  {"hash":"ab3da2eb1a35cba6","prefixes":{"":{"product":1062}}}, // [Verengo Solar]
+  {"hash":"c3bf5a10743772ec","prefixes":{"*":{"product":1063}}}, // [Mobile Professionals BV]
+  {"hash":"d22325b6d6b04918","prefixes":{"*":{"product":1064}}}, // [APNIC Pty Ltd]
+  {"hash":"27966131215e508a","prefixes":{"*":{"product":1064}}}, // [APNIC Pty Ltd]
+  {"hash":"80022b9d8ddaffde","prefixes":{"*":{"product":1064}}}, // [APNIC Pty Ltd]
+  {"hash":"9352d77ba286c03d","prefixes":{"":{"product":1065}}}, // [Dun and Bradstreet Corporation]
+  {"hash":"74b7ef01f42d93ee","prefixes":{"":{"product":1066}}}, // [UpToLike]
+  {"hash":"f2a78bb802dc4abd","prefixes":{"":{"product":1066}}}, // [UpToLike]
+  {"hash":"f885798eaaace647","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"3bc813f113908f06","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"e1a6852c86da418c","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"0343b65d010db4b2","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"a9b74e1bcb339dd0","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"e8d325d7be0f046b","prefixes":{"*":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"f7ccb1753b9ae2ed","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"4a96db729cb9dd47","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"afde8c2ebcc380c8","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"05840eb3ff4432a8","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"3e5f0f83b0e34391","prefixes":{"":{"product":1067}}}, // [Mobile360 Sdn Bhd]
+  {"hash":"f79fe1474c475ade","prefixes":{"":{"product":1068}}}, // [Elite Fixtures]
+  {"hash":"b8b63e29130d798a","prefixes":{"":{"product":1069}}}, // [Advanse Ads]
+  {"hash":"662442a875d5ae62","prefixes":{"":{"product":1069}}}, // [Advanse Ads]
+  {"hash":"d8487e4c88a21c7f","prefixes":{"":{"product":1069}}}, // [Advanse Ads]
+  {"hash":"37694729baf29aa5","prefixes":{"":{"product":1070}}}, // [Insurance Step]
+  {"hash":"0153c16587a0c97c","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"c7bcca7e8dc820fe","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"2176b8c755bbab42","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"1979b33f68eb0ded","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"32a9ea6936225587","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"16fec67040bf3ff7","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"ed89b325a7c3ac6d","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"ae3bc4690ef89e8d","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"ed9a2a4f49ad4647","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"398d36669a77aca6","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"5bf9c0f450f9eb14","prefixes":{"":{"product":1071}}}, // [Causal Impact]
+  {"hash":"30e7de1e277c7698","prefixes":{"":{"product":145}}}, // [Aarki, Inc.]
+  {"hash":"888d9446d621d82f","prefixes":{"":{"product":145}}}, // [Aarki, Inc.]
+  {"hash":"3061a4cd653ea2dc","prefixes":{"*":{"product":1072}}}, // [Pixnet]
+  {"hash":"06daa5b82ebfa413","prefixes":{"":{"product":1073}}}, // [Zapp360]
+  {"hash":"6f0f9a90c798715d","prefixes":{"":{"product":1074}}}, // [Kijiji]
+  {"hash":"0259cba89f8f9676","prefixes":{"":{"product":1075}}}, // [Spotad LTD.]
+  {"hash":"0ca2babbaeeca3bf","prefixes":{"":{"product":1075}}}, // [Spotad LTD.]
+  {"hash":"e9a9d4fd1b468042","prefixes":{"":{"product":1075}}}, // [Spotad LTD.]
+  {"hash":"6a79ac93cddc0cc5","prefixes":{"":{"product":1075}}}, // [Spotad LTD.]
+  {"hash":"685b17838f2d9b82","prefixes":{"":{"product":1076}}}, // [Go Daddy]
+  {"hash":"aa66f01be33256d0","prefixes":{"":{"product":1077}}}, // [Bilendi]
+  {"hash":"3b8dfd79ab921d9b","prefixes":{"":{"product":1078}}}, // [Hitokuse]
+  {"hash":"1992e397e0dff18d","prefixes":{"":{"product":1078}}}, // [Hitokuse]
+  {"hash":"03eb230cd9f67c73","prefixes":{"":{"product":1078}}}, // [Hitokuse]
+  {"hash":"0a75c26f5c580b3a","prefixes":{"*":{"product":1079}}}, // [MGID Inc.]
+  {"hash":"4466d73d5d5dce19","prefixes":{"*":{"product":1079}}}, // [MGID Inc.]
+  {"hash":"10bfb2327400e2ea","prefixes":{"":{"product":1079}}}, // [MGID Inc.]
+  {"hash":"121b77f4b4412c85","prefixes":{"":{"product":1079}}}, // [MGID Inc.]
+  {"hash":"e46ec8aa62f3f432","prefixes":{"":{"product":1080}}}, // [AreaOne]
+  {"hash":"9849db4d4a694f16","prefixes":{"t":{"product":1081},"s":{"product":1081},"sna":{"product":1081}}}, // [DynAd] [DynAd] [DynAd]
+  {"hash":"5fc0aef37d5fffca","prefixes":{"":{"product":1082}}}, // [Loop Pay]
+  {"hash":"4cc75be32553222a","prefixes":{"":{"product":1083}}}, // [Remerge GmbH]
+  {"hash":"b1a90d2aaa32932c","prefixes":{"":{"product":1083}}}, // [Remerge GmbH]
+  {"hash":"3bea81bc90640751","prefixes":{"":{"product":1084}}}, // [Audience Trading Platform LTD]
+  {"hash":"d193540bb7540e5c","prefixes":{"":{"product":1085}}}, // [Whisla]
+  {"hash":"abd1c2a37733128b","prefixes":{"":{"product":1085}}}, // [Whisla]
+  {"hash":"9546fe15199cbce1","prefixes":{"":{"product":1085}}}, // [Whisla]
+  {"hash":"f43c40d1949f2c52","prefixes":{"":{"product":1086}}}, // [Bridgevine]
+  {"hash":"28577f7c17c55b0f","prefixes":{"":{"product":1087}}}, // [ADgraph DMP]
+  {"hash":"fa0c51dc55faddc6","prefixes":{"":{"product":1088}}}, // [Gravity4 Inc.]
+  {"hash":"6dea119c4c95aaa8","prefixes":{"":{"product":1088}}}, // [Gravity4 Inc.]
+  {"hash":"79b4752426dedd83","prefixes":{"":{"product":1089}}}, // [Hipmunk]
+  {"hash":"ccba9f3966eabe6b","prefixes":{"*":{"product":1090}}}, // [VideoHub DSP]
+  {"hash":"a6baef75f126450e","prefixes":{"":{"product":1091}}}, // [DuMedia]
+  {"hash":"cf45efd3feda1ba3","prefixes":{"":{"product":1091}}}, // [DuMedia]
+  {"hash":"efebf8c1ea6bab87","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"a866ff2bfe3133e7","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"49b89555382dac9e","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"e2d2b1537271ff61","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"5804e7cf2cdbbda0","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"db0ef2b4eff25274","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"d960535fd30704f8","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"258915df4406fd06","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"b34a1e3fd51aadb9","prefixes":{"":{"product":1092}}}, // [F@N Communications, Inc.]
+  {"hash":"c0ad7ec6e1d46299","prefixes":{"":{"product":1093}}}, // [VIVALU GmbH]
+  {"hash":"65c049a517720b5c","prefixes":{"":{"product":1093}}}, // [VIVALU GmbH]
+  {"hash":"b60b2426028baba5","prefixes":{"":{"product":1094}}}, // [Advertising Technologies LTD]
+  {"hash":"6d2df95e2bf52046","prefixes":{"":{"product":1094}}}, // [Advertising Technologies LTD]
+  {"hash":"b4ad6ea6ca336f55","prefixes":{"":{"product":1094}}}, // [Advertising Technologies LTD]
+  {"hash":"b750311cbd5c4013","prefixes":{"":{"product":1095}}}, // [Authenticated Digital Inc]
+  {"hash":"aa634a3d8862b3be","prefixes":{"":{"product":1095}}}, // [Authenticated Digital Inc]
+  {"hash":"361eefdfa29ada10","prefixes":{"":{"product":1096}}}, // [PaeDae, Inc., DBA The Mobile Majority]
+  {"hash":"8a5c2c8d21fc6dd4","prefixes":{"":{"product":1096}}}, // [PaeDae, Inc., DBA The Mobile Majority]
+  {"hash":"13b3d2e0ed78e518","prefixes":{"":{"product":1097}}}, // [METROPCS]
+  {"hash":"c9b29fe277a47b8d","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"60f32eaa9335e4b9","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"c8f49035cb273e42","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"92d9e360f16ecdc9","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"2d3b5566afb5350b","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"0ca3b2088de2514c","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"67da96d5ae99faa0","prefixes":{"":{"product":1098}}}, // [PapayaMobile Inc.]
+  {"hash":"347e898491d027ee","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"ae3f27ad4a4f2f7d","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"cd0c8a5dd793ee52","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"451f4083f03028e0","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"e1b048e4fa37eef2","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"837ae92d9cf6b933","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"6ae82aac87db94d3","prefixes":{"":{"product":1099}}}, // [Raumfeld]
+  {"hash":"84ddfa5a2e93cb69","prefixes":{"":{"product":1100}}}, // [GREE Ads DSP]
+  {"hash":"a7201f5a80824242","prefixes":{"":{"product":1100}}}, // [GREE Ads DSP]
+  {"hash":"2ec22ca05310362a","prefixes":{"":{"product":1101}}}, // [Tender Industries AB]
+  {"hash":"d159abbaeda22e7c","prefixes":{"":{"product":1102}}}, // [BySide]
+  {"hash":"426783d6fe8d039e","prefixes":{"":{"product":1103}}}, // [Sentrant Security Inc.]
+  {"hash":"d270ad50bb53fb01","prefixes":{"":{"product":1103}}}, // [Sentrant Security Inc.]
+  {"hash":"49c693058534be83","prefixes":{"":{"product":1104}}}, // [Locon Solutions Pvt. Ltd.]
+  {"hash":"a2b9f627da8737de","prefixes":{"":{"product":1105}}}, // [Interrogare GmbH]
+  {"hash":"13b73169540642e5","prefixes":{"":{"product":1105}}}, // [Interrogare GmbH]
+  {"hash":"afaa106d11846fa4","prefixes":{"*":{"product":1106}}}, // [ChannelAdvisor]
+  {"hash":"b8b4eadeb5d3a123","prefixes":{"":{"product":1107}}}, // [VideoAmp]
+  {"hash":"43546e9f6ff5bf2a","prefixes":{"":{"product":1107}}}, // [VideoAmp]
+  {"hash":"61a9edb9af3769cf","prefixes":{"":{"product":1107}}}, // [VideoAmp]
+  {"hash":"f76b3fe7048e93e2","prefixes":{"":{"product":1107}}}, // [VideoAmp]
+  {"hash":"57263424c0e88a92","prefixes":{"track":{"product":1108}}}, // [The Bridge]
+  {"hash":"516e9fc5ede4af0d","prefixes":{"":{"product":1108}}}, // [The Bridge]
+  {"hash":"6bc0303a4262cb67","prefixes":{"":{"product":1108}}}, // [The Bridge]
+  {"hash":"30a32fe2a89dccd8","prefixes":{"":{"product":1109}}}, // [Pharmaca Integrative Pharmacy]
+  {"hash":"7881da604383a640","prefixes":{"":{"product":673}}}, // [Videology DSP]
+  {"hash":"dec02c663bb06094","prefixes":{"":{"product":1110}}}, // [Scrutineer]
+  {"hash":"6e2098af577c671d","prefixes":{"":{"product":1111}}}, // [TF1 - FR]
+  {"hash":"60774075776e2612","prefixes":{"":{"product":1112}}}, // [Core Digital]
+  {"hash":"79a775eea6a902e6","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"c0576db5cf4ba20b","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"d90fda985e3fb6bf","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"ee49dcf9326e853f","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"5b3c6abcd44de720","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"f97a320480541a27","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"57fc36302e0bde3c","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"736a8a8a0cef7bdf","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"36263b4a0d607a71","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"226480bf58f4fd1c","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"58379bd623597d70","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"f68e3a544a7397be","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"0f2880d71794e516","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"4ef52741fc1ade73","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"97d6a93635d72af0","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"ab75a46dc8bf2c1e","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"efeb8f966db03b87","prefixes":{"":{"product":110}}}, // [Bonzai Digital Pvt. Ltd]
+  {"hash":"2a4d804c0fb397c1","prefixes":{"":{"product":1113}}}, // [Adventive, Inc.]
+  {"hash":"29d370caa59b4ecc","prefixes":{"":{"product":1113}}}, // [Adventive, Inc.]
+  {"hash":"a06632ec1be82319","prefixes":{"":{"product":1114}}}, // [Turner Sports Interactive, Inc.]
+  {"hash":"bf10e40bae047225","prefixes":{"":{"product":1114}}}, // [Turner Sports Interactive, Inc.]
+  {"hash":"67dbd4ebfca8ed7c","prefixes":{"":{"product":1114}}}, // [Turner Sports Interactive, Inc.]
+  {"hash":"3ccffb010a6151f8","prefixes":{"":{"product":1115}}}, // [SnappyTV]
+  {"hash":"7d838005a39552d8","prefixes":{"":{"product":1116}}}, // [Target Media Partners]
+  {"hash":"003b7537bd9a7cfe","prefixes":{"":{"product":1116}}}, // [Target Media Partners]
+  {"hash":"26b33a79482ab7ab","prefixes":{"":{"product":1117}}}, // [KAIZEN platform Inc.]
+  {"hash":"15cdc1963890a6a2","prefixes":{"":{"product":1117}}}, // [KAIZEN platform Inc.]
+  {"hash":"1f36b920b7ac4ebb","prefixes":{"":{"product":1118}}}, // [Bidstalk Pte Ltd]
+  {"hash":"a59afaa1821362bd","prefixes":{"":{"product":1119}}}, // [ESPN]
+  {"hash":"e0edcd5fafde3e7a","prefixes":{"":{"product":1119}}}, // [ESPN]
+  {"hash":"7bd48d6255130db4","prefixes":{"":{"product":1120}}}, // [Online Media Group]
+  {"hash":"88c41fbe0db9a483","prefixes":{"":{"product":1120}}}, // [Online Media Group]
+  {"hash":"fc1080dbf4fae3f9","prefixes":{"":{"product":1120}}}, // [Online Media Group]
+  {"hash":"37fc205007f7a040","prefixes":{"":{"product":1120}}}, // [Online Media Group]
+  {"hash":"60c02a2ea01a737e","prefixes":{"":{"product":1121}}}, // [Luxury Link]
+  {"hash":"24108d30b52b9587","prefixes":{"":{"product":1122}}}, // [ESKIMI]
+  {"hash":"9de510a2d7f81a6e","prefixes":{"":{"product":1122}}}, // [ESKIMI]
+  {"hash":"d0e18c7e72b51bf3","prefixes":{"":{"product":1122}}}, // [ESKIMI]
+  {"hash":"6dbe16f5894e20af","prefixes":{"":{"product":1123}}}, // [AdsYolo Media]
+  {"hash":"5292ef4ba83623a8","prefixes":{"":{"product":1124}}}, // [Arrivalist]
+  {"hash":"b94285ae50bcb48e","prefixes":{"":{"product":1124}}}, // [Arrivalist]
+  {"hash":"cd7b432729ab016a","prefixes":{"":{"product":1124}}}, // [Arrivalist]
+  {"hash":"ae0442a300ebce47","prefixes":{"":{"product":1124}}}, // [Arrivalist]
+  {"hash":"3c8cc56d5b514ec5","prefixes":{"":{"product":1124}}}, // [Arrivalist]
+  {"hash":"794b2a51546b4f7f","prefixes":{"":{"product":1125}}}, // [MobileWebAdz Ltd]
+  {"hash":"223eacf97254c888","prefixes":{"":{"product":1125}}}, // [MobileWebAdz Ltd]
+  {"hash":"a3c5eeef285517f3","prefixes":{"":{"product":1125}}}, // [MobileWebAdz Ltd]
+  {"hash":"b222f9498fcdb24c","prefixes":{"":{"product":1126}}}, // [Demand Side Science, Inc.]
+  {"hash":"87af9974b30c5872","prefixes":{"":{"product":1126}}}, // [Demand Side Science, Inc.]
+  {"hash":"db4cd3e487418898","prefixes":{"":{"product":1126}}}, // [Demand Side Science, Inc.]
+  {"hash":"3fca6191597f44f2","prefixes":{"":{"product":1127}}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
+  {"hash":"6873487b11c1952e","prefixes":{"":{"product":1127}}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
+  {"hash":"d4b4ed3e1d07b00e","prefixes":{"":{"product":1127}}}, // [SOCIETE FRANCAISE DU RADIOTELEPHONE]
+  {"hash":"e647f502df0429f5","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"34f8fc43e14bad03","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"5f43507f5a877784","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"1466e6f77352194a","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"e097497d606d17ed","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"05c9b2eb92c8b5ba","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"ce3bfbe09ddeb858","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"3aa96b751d2c0d1c","prefixes":{"":{"product":1128}}}, // [Mobitrans FZ LLC]
+  {"hash":"289e565c9c686515","prefixes":{"":{"product":1129}}}, // [CoCo Reef]
+  {"hash":"0b6740b395a65857","prefixes":{"":{"product":1130}}}, // [Kumma DP LTD]
+  {"hash":"c00365ed4d1c464c","prefixes":{"":{"product":1131}}}, // [Cablato Limited]
+  {"hash":"9ee2a07ebdef206f","prefixes":{"":{"product":1131}}}, // [Cablato Limited]
+  {"hash":"e270375f27c5f31c","prefixes":{"":{"product":1131}}}, // [Cablato Limited]
+  {"hash":"0ebf573ebb6b30e1","prefixes":{"":{"product":1131}}}, // [Cablato Limited]
+  {"hash":"e28b4c253b1f854f","prefixes":{"":{"product":1132}}}, // [EURO DISNEY SCA]
+  {"hash":"3c8900c851ba9b28","prefixes":{"":{"product":1133}}}, // [Norstat]
+  {"hash":"39518e51adbe0cd7","prefixes":{"":{"product":1133}}}, // [Norstat]
+  {"hash":"2c5efd1ea532f0eb","prefixes":{"":{"product":1134}}}, // [John Varvatos]
+  {"hash":"5679368e6b2bb34c","prefixes":{"":{"product":1135}}}, // [Spritz Technology, Inc.]
+  {"hash":"60be7d8a6a76b62f","prefixes":{"":{"product":1135}}}, // [Spritz Technology, Inc.]
+  {"hash":"cefbe9240a377d95","prefixes":{"":{"product":1136}}}, // [Wix.com]
+  {"hash":"a56824227bb496f7","prefixes":{"*":{"product":1137}}}, // [TapTap Networks]
+  {"hash":"41f2ae7d2d6939ae","prefixes":{"":{"product":1137}}}, // [TapTap Networks]
+  {"hash":"51fd8b1d5b983b31","prefixes":{"":{"product":1138}}}, // [Permodo]
+  {"hash":"12c3d246c6d4e6b1","prefixes":{"":{"product":1138}}}, // [Permodo]
+  {"hash":"69da2bfa4e414e2c","prefixes":{"":{"product":1138}}}, // [Permodo]
+  {"hash":"67bb1e3460d8e2eb","prefixes":{"":{"product":1138}}}, // [Permodo]
+  {"hash":"38912558a11ff73e","prefixes":{"":{"product":1138}}}, // [Permodo]
+  {"hash":"eb4d36cf5e4909c1","prefixes":{"":{"product":1139}}}, // [Gaiam, Inc.]
+  {"hash":"16578371f24a5e90","prefixes":{"":{"product":1140}}}, // [Plusing interactive co.,Ltd]
+  {"hash":"ecdb68bd2622aa9e","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"8adccb3847cc8b0f","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"2b5433780334b542","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"c853c92986d0cc90","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"388da33e7f0adca1","prefixes":{"":{"product":42}}}, // [Clinch.co]
+  {"hash":"03d7a65aa1bc87bc","prefixes":{"":{"product":1141}}}, // [Paypersale]
+  {"hash":"176eb71c0938f4a5","prefixes":{"":{"product":111}}}, // [Epic Combo Malta Ltd.]
+  {"hash":"4366ec3ae9f41f7c","prefixes":{"":{"product":111}}}, // [Epic Combo Malta Ltd.]
+  {"hash":"2e9617ef727ff0b5","prefixes":{"":{"product":1142}}}, // [OCP Collective Corp. (d/b/a AdCade)]
+  {"hash":"11d6d13e3eb48a86","prefixes":{"":{"product":1142}}}, // [OCP Collective Corp. (d/b/a AdCade)]
+  {"hash":"20e14ef573248fec","prefixes":{"":{"product":1142}}}, // [OCP Collective Corp. (d/b/a AdCade)]
+  {"hash":"234345fe3c0da842","prefixes":{"":{"product":1142}}}, // [OCP Collective Corp. (d/b/a AdCade)]
+  {"hash":"30fb60c9c450221d","prefixes":{"":{"product":1142}}}, // [OCP Collective Corp. (d/b/a AdCade)]
+  {"hash":"69ddc7852224e18f","prefixes":{"":{"product":1143}}}, // [ESV Digital]
+  {"hash":"240174bad001108d","prefixes":{"":{"product":1144}}}, // [RevJet LLC.]
+  {"hash":"5250a7a3f2e4f73a","prefixes":{"":{"product":1144}}}, // [RevJet LLC.]
+  {"hash":"590feb6b793ba20a","prefixes":{"":{"product":1144}}}, // [RevJet LLC.]
+  {"hash":"23db13cb66f769e3","prefixes":{"":{"product":1145}}}, // [GET IT Mobile, Inc]
+  {"hash":"cd7cd6c16f714024","prefixes":{"":{"product":1145}}}, // [GET IT Mobile, Inc]
+  {"hash":"00ea35d76275dbeb","prefixes":{"":{"product":1145}}}, // [GET IT Mobile, Inc]
+  {"hash":"5239cdae00ff02ea","prefixes":{"":{"product":1146}}}, // [IBM]
+  {"hash":"e2c539bef8d2970c","prefixes":{"":{"product":1147}}}, // [Lucid Holdings, LLC]
+  {"hash":"7078be8707b5ec93","prefixes":{"":{"product":1147}}}, // [Lucid Holdings, LLC]
+  {"hash":"d65fe9ed9f23afbd","prefixes":{"":{"product":1148}}}, // [Stratio Big Data Inc.]
+  {"hash":"9ccfc7f2ecfbaeec","prefixes":{"":{"product":1148}}}, // [Stratio Big Data Inc.]
+  {"hash":"54e80254bbf4e20b","prefixes":{"":{"product":1149}}}, // [Tripping.com]
+  {"hash":"4aaf263b4bae6cd1","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"b782d6c10170e732","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"ceef29c52329c405","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"f14df6ca2e300bb9","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"514c355026c95637","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"b2529b7ebc0cbb27","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"14ebf9b0cbed945c","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"048147eea378ee03","prefixes":{"":{"product":1150}}}, // [Vidible]
+  {"hash":"7b61440491bd2a65","prefixes":{"":{"product":1151}}}, // [MiMTiD Corp]
+  {"hash":"036455e7801e853e","prefixes":{"":{"product":1151}}}, // [MiMTiD Corp]
+  {"hash":"e631f0342d59176b","prefixes":{"":{"product":1152}}}, // [Moloco, Inc.]
+  {"hash":"87938522c669c682","prefixes":{"":{"product":1152}}}, // [Moloco, Inc.]
+  {"hash":"a102c87f9921beb6","prefixes":{"":{"product":1153}}}, // [MEC SP. Z O.O]
+  {"hash":"f9133e4a069a0f4f","prefixes":{"":{"product":1153}}}, // [MEC SP. Z O.O]
+  {"hash":"6c7737c0ecbf0d91","prefixes":{"":{"product":1153}}}, // [MEC SP. Z O.O]
+  {"hash":"a82a0c18f6dfb959","prefixes":{"":{"product":1153}}}, // [MEC SP. Z O.O]
+  {"hash":"e1bea08ea38dc600","prefixes":{"":{"product":1154}}}, // [Abudantia LLC]
+  {"hash":"d60e1ada8dfa48fa","prefixes":{"":{"product":1154}}}, // [Abudantia LLC]
+  {"hash":"b57f7b99f9deda72","prefixes":{"":{"product":1154}}}, // [Abudantia LLC]
+  {"hash":"63f93976910e4aff","prefixes":{"":{"product":1154}}}, // [Abudantia LLC]
+  {"hash":"93a75f3f5174e472","prefixes":{"":{"product":1154}}}, // [Abudantia LLC]
+  {"hash":"ba1500537064494c","prefixes":{"":{"product":1155}}}, // [Realzeit]
+  {"hash":"ce1c3e183853dec6","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"697384881bfb9a85","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"3b5e1e5d71bb095f","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"a55289ec43a1fd1c","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"0ea122741b5a296d","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"139c147db4a66d45","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"91a98ad80489e2aa","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"276f5a9d0ed20d4a","prefixes":{"":{"product":1156}}}, // [Shanghai DigitalMatrix Information Technology Co.]
+  {"hash":"8408cf6c93d2f24f","prefixes":{"":{"product":1157}}}, // [Alkemics]
+  {"hash":"658222dab2aa692d","prefixes":{"":{"product":1157}}}, // [Alkemics]
+  {"hash":"8835156415ef5c70","prefixes":{"":{"product":1157}}}, // [Alkemics]
+  {"hash":"7d76d0b7c2c49e1c","prefixes":{"":{"product":1158}}}, // [Sodel Software Solutions Pvt. Ltd.]
+  {"hash":"26b315a19bf762cb","prefixes":{"":{"product":1159}}}, // [Clearstream.TV, Inc]
+  {"hash":"80ce05889af3bb0e","prefixes":{"":{"product":1159}}}, // [Clearstream.TV, Inc]
+  {"hash":"2d9798f06f3cd0f8","prefixes":{"":{"product":1159}}}, // [Clearstream.TV, Inc]
+  {"hash":"4724e51f601e7bfa","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"e0f93294ef7c3cb7","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"ed1e0f5237be934f","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"4a0011b21f8d95f9","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"1af9efa73c3b3b29","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"49eea06f0c13da7f","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"584459c8cfe5595f","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"3b72d8e306588e71","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"f8d6e6d127d9c894","prefixes":{"":{"product":1161}}}, // [Adluxe]
+  {"hash":"93d864f5e43a3230","prefixes":{"":{"product":1161}}}, // [Adluxe]
+  {"hash":"793d5c9c5c35b0d9","prefixes":{"":{"product":1161}}}, // [Adluxe]
+  {"hash":"7b9c5864364d5f5e","prefixes":{"*":{"product":1162}}}, // [NinthDecimal]
+  {"hash":"7c86152a561c4b4b","prefixes":{"*":{"product":1162}}}, // [NinthDecimal]
+  {"hash":"ec998efdf99b0c51","prefixes":{"*":{"product":1163}}}, // [RICH MEDIA STUDIO]
+  {"hash":"e83c01ec741a261e","prefixes":{"":{"product":1164}}}, // [TenMax Co., Ltd.]
+  {"hash":"e333d70ac6d1acda","prefixes":{"":{"product":1165}}}, // [twiago GmbH]
+  {"hash":"bb81d5fd8a052b7f","prefixes":{"":{"product":1166}}}, // [Ad Dynamo International (Pty) Ltd]
+  {"hash":"55b2516509252adb","prefixes":{"":{"product":1166}}}, // [Ad Dynamo International (Pty) Ltd]
+  {"hash":"59e4e15b4fe6dccd","prefixes":{"":{"product":1166}}}, // [Ad Dynamo International (Pty) Ltd]
+  {"hash":"f5005d7a14ac0a47","prefixes":{"":{"product":1166}}}, // [Ad Dynamo International (Pty) Ltd]
+  {"hash":"ecf3dd9926cbe25e","prefixes":{"":{"product":1166}}}, // [Ad Dynamo International (Pty) Ltd]
+  {"hash":"2ccdffccbbf20e3f","prefixes":{"":{"product":1167}}}, // [Swarm Enterprises Inc]
+  {"hash":"bf0dd6fdbc53dfee","prefixes":{"":{"product":112}}}, // [Quixey]
+  {"hash":"ac6a75f10f9f0391","prefixes":{"":{"product":1168}}}, // [Media Forum]
+  {"hash":"2b5f5e731d08116b","prefixes":{"":{"product":1168}}}, // [Media Forum]
+  {"hash":"8bf2fe7f00b3c760","prefixes":{"":{"product":1169}}}, // [Beeswax.io]
+  {"hash":"480bd3bc762861ae","prefixes":{"":{"product":1170}}}, // [Varick Media Management]
+  {"hash":"d9faa36410c39273","prefixes":{"":{"product":1170}}}, // [Varick Media Management]
+  {"hash":"6114cbf7f45fd639","prefixes":{"":{"product":1171}}}, // [JD]
+  {"hash":"739568f083f383e2","prefixes":{"":{"product":1171}}}, // [JD]
+  {"hash":"1fc63d36c1d330fa","prefixes":{"":{"product":1171}}}, // [JD]
+  {"hash":"bdb07c050de0bbd2","prefixes":{"":{"product":1171}}}, // [JD]
+  {"hash":"6b6a891a61b05435","prefixes":{"":{"product":1172}}}, // [Lotlinx Inc.]
+  {"hash":"b7831e02a1168f7b","prefixes":{"":{"product":1172}}}, // [Lotlinx Inc.]
+  {"hash":"78f18ca9103e6031","prefixes":{"":{"product":1173}}}, // [Lotlinx Inc]
+  {"hash":"9a1f751c74a01145","prefixes":{"":{"product":40}}}, // [F# Inc.]
+  {"hash":"09ddf4e3268e6597","prefixes":{"":{"product":1174}}}, // [Ingenio, LLC]
+  {"hash":"c5dd0849ac2febc6","prefixes":{"":{"product":1175}}}, // [MVMT Watches]
+  {"hash":"3b471f8f08410883","prefixes":{"":{"product":1176}}}, // [C1X Inc]
+  {"hash":"1bb74ab211a41c9c","prefixes":{"":{"product":1177}}}, // [Vitro Agency]
+  {"hash":"96c0acfcd81b2dd4","prefixes":{"":{"product":1178}}}, // [Kabbage]
+  {"hash":"0e5b93a6bd6f704b","prefixes":{"":{"product":1179}}}, // [Redbranch, Inc. (dba Fraudlogix)]
+  {"hash":"a810be7236bf948f","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"ffe13e4342fd9a35","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"91d97869f45df6e0","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"c9f1716ec9d29c4b","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"4a9148e717cb46a9","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"9b57b296c2edd01c","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"1db72ea880eb28dc","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"61889d0078dd40a7","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"fd8f5971bf862430","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"d0da5b57fc3b9611","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"00449172b70d520c","prefixes":{"":{"product":1180}}}, // [AutoWeb, Inc.]
+  {"hash":"7b3027f5a6cb4f20","prefixes":{"":{"product":1181}}}, // [Aimee Soft Ltd.]
+  {"hash":"c29f58ba8b9fccc8","prefixes":{"":{"product":1181}}}, // [Aimee Soft Ltd.]
+  {"hash":"e8cb0d7824f08de4","prefixes":{"":{"product":1181}}}, // [Aimee Soft Ltd.]
+  {"hash":"97efe77626897346","prefixes":{"":{"product":1181}}}, // [Aimee Soft Ltd.]
+  {"hash":"78afe44858076c81","prefixes":{"":{"product":1181}}}, // [Aimee Soft Ltd.]
+  {"hash":"f5162869e573dcd7","prefixes":{"":{"product":1182}}}, // [SAS Azameo]
+  {"hash":"3d35f5eb2971f5fe","prefixes":{"":{"product":17}}}, // [iJento]
+  {"hash":"b98ddad6854c87b1","prefixes":{"":{"product":1183}}}, // [Keyade]
+  {"hash":"65aab53cd46ccc7f","prefixes":{"":{"product":1184}}}, // [Digital To Store (DTS)]
+  {"hash":"e1e5e1a4c7857257","prefixes":{"":{"product":1184}}}, // [Digital To Store (DTS)]
+  {"hash":"c9f6517091430433","prefixes":{"":{"product":1184}}}, // [Digital To Store (DTS)]
+  {"hash":"76d9ee307388af98","prefixes":{"":{"product":1184}}}, // [Digital To Store (DTS)]
+  {"hash":"8fdb48d3b5466119","prefixes":{"":{"product":1184}}}, // [Digital To Store (DTS)]
+  {"hash":"bd53e2fe0c663545","prefixes":{"":{"product":1185}}}, // [Media iQ Digital]
+  {"hash":"58b54a485703f6ba","prefixes":{"":{"product":1185}}}, // [Media iQ Digital]
+  {"hash":"35616fb4ea0feb94","prefixes":{"":{"product":1185}}}, // [Media iQ Digital]
+  {"hash":"0a1563142096ed40","prefixes":{"":{"product":1186}}}, // [Ingenious Technologies]
+  {"hash":"427d170b486c74e6","prefixes":{"":{"product":1186}}}, // [Ingenious Technologies]
+  {"hash":"79480a2b5de32430","prefixes":{"":{"product":1186}}}, // [Ingenious Technologies]
+  {"hash":"aaf44b046fb5c10d","prefixes":{"":{"product":1187}}}, // [Sonicmoov co.,ltd]
+  {"hash":"e5d30ca87b591280","prefixes":{"":{"product":1187}}}, // [Sonicmoov co.,ltd]
+  {"hash":"9ec9f8d7f0fc8c4a","prefixes":{"":{"product":1187}}}, // [Sonicmoov co.,ltd]
+  {"hash":"dd0bf16db1e39f59","prefixes":{"":{"product":1187}}}, // [Sonicmoov co.,ltd]
+  {"hash":"b32a4da2bc7363a0","prefixes":{"":{"product":1188}}}, // [Bonadza LLC]
+  {"hash":"66a81343ae0223df","prefixes":{"":{"product":1188}}}, // [Bonadza LLC]
+  {"hash":"ae76287d25b463d2","prefixes":{"":{"product":1188}}}, // [Bonadza LLC]
+  {"hash":"7429b926177d09a6","prefixes":{"":{"product":1188}}}, // [Bonadza LLC]
+  {"hash":"170cc20a9af99287","prefixes":{"":{"product":1189}}}, // [Axis Shift Limited]
+  {"hash":"6e94333e674450ec","prefixes":{"":{"product":1190}}}, // [TreSensa, Inc.]
+  {"hash":"8fac335d75d968fd","prefixes":{"":{"product":1190}}}, // [TreSensa, Inc.]
+  {"hash":"eec936c95af6b31f","prefixes":{"":{"product":1190}}}, // [TreSensa, Inc.]
+  {"hash":"3c744b206f15c46d","prefixes":{"":{"product":1190}}}, // [TreSensa, Inc.]
+  {"hash":"049a71c722403987","prefixes":{"":{"product":1191}}}, // [Media Logic Group LLC dba AerisWeather LLC]
+  {"hash":"efa6686cf4b6b73c","prefixes":{"":{"product":57}}}, // [DeinDeal AG]
+  {"hash":"847219545b169784","prefixes":{"":{"product":1192}}}, // [Fugumobile]
+  {"hash":"790ab0ec39724b71","prefixes":{"":{"product":1193}}}, // [Localstars Ltd]
+  {"hash":"0133a556a80fd808","prefixes":{"":{"product":1194}}}, // [Fluidads]
+  {"hash":"fc8901303bada188","prefixes":{"":{"product":1194}}}, // [Fluidads]
+  {"hash":"ba549c39b1f43523","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"5d0b84261f7b6d5c","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"d48dde21b5917906","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"337dabe98702ae52","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"efad84d0a4dd4e46","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"019c3ee24427b355","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"ec79c848ccf2d648","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"ccf7fd5647b92698","prefixes":{"*":{"product":1195}}}, // [Wayfair LLC]
+  {"hash":"3b03a24eea2a6345","prefixes":{"":{"product":1196}}}, // [VCCORP CORPORATION]
+  {"hash":"f7f53c88139460cf","prefixes":{"":{"product":1197}}}, // [IGAWorks]
+  {"hash":"93b9518285f54887","prefixes":{"":{"product":1198}}}, // [Cellcom Ltd]
+  {"hash":"f59e6427783c3da0","prefixes":{"*":{"product":1199}}}, // [Upsolver]
+  {"hash":"adb55d98bb4aef6e","prefixes":{"":{"product":1199}}}, // [Upsolver]
+  {"hash":"7efba976eeea2d41","prefixes":{"":{"product":1199}}}, // [Upsolver]
+  {"hash":"cdde375c1240991d","prefixes":{"":{"product":935}}}, // [Channel Factory, LLC]
+  {"hash":"79c4dc57905857aa","prefixes":{"":{"product":1200}}}, // [Phluidmedia, Inc.]
+  {"hash":"4948ea141d1a72e1","prefixes":{"":{"product":1200}}}, // [Phluidmedia, Inc.]
+  {"hash":"e4aed5bf5c295c3a","prefixes":{"":{"product":1201}}}, // [Roy Morgan Research Ltd]
+  {"hash":"547734f17effda77","prefixes":{"":{"product":1202}}}, // [TapSense, Inc.]
+  {"hash":"96289aeef06d0a9f","prefixes":{"":{"product":1203}}}, // [Southwest Airlines]
+  {"hash":"de497c6fbed4588d","prefixes":{"":{"product":794}}}, // [Hatena Co., Ltd]
+  {"hash":"91412d534d321cb4","prefixes":{"":{"product":1204}}}, // [Market Points, Inc.]
+  {"hash":"97aab20dd873dd2c","prefixes":{"":{"product":1205}}}, // [UberMedia Inc.]
+  {"hash":"73cadeea8e1bd9e8","prefixes":{"":{"product":1205}}}, // [UberMedia Inc.]
+  {"hash":"0e1bd2938a06a2e6","prefixes":{"":{"product":1206}}}, // [Kadam SIA]
+  {"hash":"aa9658253aa81e62","prefixes":{"":{"product":1206}}}, // [Kadam SIA]
+  {"hash":"75f1eab33abfa4f9","prefixes":{"":{"product":1206}}}, // [Kadam SIA]
+  {"hash":"59f64b09b8e430ae","prefixes":{"":{"product":1206}}}, // [Kadam SIA]
+  {"hash":"61947a042af2e3e8","prefixes":{"":{"product":1207}}}, // [Alveo Platform (VMM own bidder)]
+  {"hash":"62c095e8dfbb0458","prefixes":{"":{"product":1208}}}, // [Adbalancer EDV-DienstleistungsgesellschaftgmbH]
+  {"hash":"5cc57103c26df76f","prefixes":{"":{"product":1208}}}, // [Adbalancer EDV-DienstleistungsgesellschaftgmbH]
+  {"hash":"53685a43fc711ea4","prefixes":{"":{"product":1209}}}, // [JWPlayer]
+  {"hash":"53bdf03af7a44e2c","prefixes":{"":{"product":1209}}}, // [JWPlayer]
+  {"hash":"eaff21a1a9591dab","prefixes":{"":{"product":1209}}}, // [JWPlayer]
+  {"hash":"1d5626ba7394e6a1","prefixes":{"":{"product":1209}}}, // [JWPlayer]
+  {"hash":"2e106bd1d1d064c6","prefixes":{"":{"product":1209}}}, // [JWPlayer]
+  {"hash":"9f7691306b0805ea","prefixes":{"":{"product":1209}}}, // [JWPlayer]
+  {"hash":"909df8f91bd33085","prefixes":{"*":{"product":1210}}}, // [Adiquity Technologies Pvt Ltd]
+  {"hash":"d1eca614d3cc8883","prefixes":{"":{"product":1211}}}, // [Smart Digital GmbH]
+  {"hash":"53d8de6b018c1793","prefixes":{"":{"product":1212}}}, // [Auditorius LLC]
+  {"hash":"fd9a420ade305e17","prefixes":{"":{"product":1213}}}, // [Treepodia]
+  {"hash":"c9fd06f055d4af40","prefixes":{"":{"product":1213}}}, // [Treepodia]
+  {"hash":"6eb24d470a6f1018","prefixes":{"":{"product":1213}}}, // [Treepodia]
+  {"hash":"e35bb07367786d4c","prefixes":{"":{"product":1214}}}, // [Adamatic]
+  {"hash":"3943df18ad20915d","prefixes":{"":{"product":1214}}}, // [Adamatic]
+  {"hash":"341d248dc25e4ea7","prefixes":{"":{"product":1214}}}, // [Adamatic]
+  {"hash":"ad1f1681bab5cc6b","prefixes":{"":{"product":1215}}}, // [SAS Web2ROI]
+  {"hash":"532b5bfa711f405e","prefixes":{"":{"product":1216}}}, // [Cardlytics]
+  {"hash":"799c283a6f1c8ece","prefixes":{"":{"product":1217}}}, // [MyFonts Inc.]
+  {"hash":"4448bee927dde7e6","prefixes":{"*":{"product":1218}}}, // [Bluecore, Inc.]
+  {"hash":"a0bd7b7a099833b6","prefixes":{"":{"product":1218}}}, // [Bluecore, Inc.]
+  {"hash":"fa3e77058c021551","prefixes":{"*":{"product":1218}}}, // [Bluecore, Inc.]
+  {"hash":"4761d233715098ce","prefixes":{"":{"product":1219}}}, // [EverQuote, Inc.]
+  {"hash":"35694b7df8059b22","prefixes":{"":{"product":1219}}}, // [EverQuote, Inc.]
+  {"hash":"0740880077130a2d","prefixes":{"":{"product":1220}}}, // [Optimize LCC D.B.A Genius Monkey]
+  {"hash":"bfe2c1b41278b804","prefixes":{"":{"product":1220}}}, // [Optimize LCC D.B.A Genius Monkey]
+  {"hash":"6dd3f6dcd500314e","prefixes":{"":{"product":1220}}}, // [Optimize LCC D.B.A Genius Monkey]
+  {"hash":"2f3f7cacd3fe0763","prefixes":{"*":{"product":1221}}}, // [EverString Technology Ltd]
+  {"hash":"bca80e9becb74dcb","prefixes":{"*":{"product":1221}}}, // [EverString Technology Ltd]
+  {"hash":"46edf29e9ba4ff96","prefixes":{"":{"product":1222}}}, // [Axonix Limited]
+  {"hash":"98961093c86583f5","prefixes":{"":{"product":1223}}}, // [Ubimo Ltd.]
+  {"hash":"1110ef291b2bd2e8","prefixes":{"":{"product":1224}}}, // [gskinner.com,Inc]
+  {"hash":"e36b044e9f38bad6","prefixes":{"":{"product":1225}}}, // [PlaceIQ, Inc.]
+  {"hash":"fe5b89fe7dbbd534","prefixes":{"":{"product":1226}}}, // [DataBerries]
+  {"hash":"ddf083a57d484592","prefixes":{"":{"product":1227}}}, // [Otto (GmbH & Co KG)]
+  {"hash":"7975f7864f4fa759","prefixes":{"":{"product":1228}}}, // [Beijing ADirects Technology Corporation Limited]
+  {"hash":"657d40c4d7322985","prefixes":{"":{"product":1229}}}, // [MagicGroup Asia Pte. Ltd.]
+  {"hash":"f5559eee02dd33ad","prefixes":{"":{"product":1229}}}, // [MagicGroup Asia Pte. Ltd.]
+  {"hash":"e81aa2815c378230","prefixes":{"":{"product":1229}}}, // [MagicGroup Asia Pte. Ltd.]
+  {"hash":"49269f9273c66c00","prefixes":{"":{"product":1230}}}, // [Local Content, Inc.]
+  {"hash":"210fa7d8376be47a","prefixes":{"":{"product":1230}}}, // [Local Content, Inc.]
+  {"hash":"e4ba8ed4e3abc143","prefixes":{"":{"product":1231}}}, // [Flavia]
+  {"hash":"269e0d49e8a941b8","prefixes":{"":{"product":43}}}, // [Transout Inc.]
+  {"hash":"b9cd0135bbe2cf40","prefixes":{"":{"product":43}}}, // [Transout Inc.]
+  {"hash":"e4b01f2271c4171a","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"e5b4daaa6c4ae231","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"cfb3a28bf24f27aa","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"db9ed30c0cbece36","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"dd0d7f22eaea16dd","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"4f3fc6e6fa75b1e8","prefixes":{"":{"product":44}}}, // [ADZIP]
+  {"hash":"17a3e1cbc6818d71","prefixes":{"*":{"product":1232}}}, // [Webtype]
+  {"hash":"39697008117e49f0","prefixes":{"":{"product":1233}}}, // [Aditor]
+  {"hash":"50bd67909486f9f5","prefixes":{"":{"product":1233}}}, // [Aditor]
+  {"hash":"d58ef2e47a1b5b3b","prefixes":{"":{"product":1234}}}, // [YCmedia]
+  {"hash":"fc8e2c447edda6c9","prefixes":{"":{"product":1235}}}, // [Addwish Aps]
+  {"hash":"d5ac956c9f185ddc","prefixes":{"":{"product":1236}}}, // [AIDO TECHNOLOGY INC.]
+  {"hash":"24015d44b9900d67","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"460c0600751cbd60","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"77050f5bbccffdb1","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"cdf17fb674f06ff0","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"8fb430c8ece16b19","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"c9d79e6f1f2694cd","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"80c75e37374a2ef0","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"5f9ca3a706ea1a32","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"2839cda166e75a72","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"762d13ee90c23c96","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"c0ea3a6ac5a15ff4","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"70c0b65944772c14","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"06d5db93059745e1","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"ea0e52e08087883d","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"dd48f2110336efda","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"bac37ceef6479f6b","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"a16d986f3ad09790","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"44addae7b850b89f","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"ef08ba4268518e6e","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"1f2560020ac4a5dd","prefixes":{"":{"product":1237}}}, // [Herolens Group LLC]
+  {"hash":"67339d8f9c205d19","prefixes":{"":{"product":1238}}}, // [Fuisz Media, Inc.]
+  {"hash":"b3ebdb16675afb79","prefixes":{"":{"product":1238}}}, // [Fuisz Media, Inc.]
+  {"hash":"33e8b1a10d6cf9bb","prefixes":{"":{"product":1238}}}, // [Fuisz Media, Inc.]
+  {"hash":"33c97b2942fbfb43","prefixes":{"":{"product":1239}}}, // [Bucksense, Inc.]
+  {"hash":"f7be89ec6f521ed4","prefixes":{"":{"product":664}}}, // [Adiant]
+  {"hash":"8ad32c44e7f009d9","prefixes":{"":{"product":1240}}}, // [Taylor Nelson Sofres Ukraine LLC]
+  {"hash":"9913ba5c46add495","prefixes":{"*":{"product":1241}}}, // [MotionLead]
+  {"hash":"ed341f6ed9722885","prefixes":{"":{"product":1242}}}, // [CJSC Recomendatsii tovarov i uslug]
+  {"hash":"b84298a2bc76c877","prefixes":{"":{"product":1242}}}, // [CJSC Recomendatsii tovarov i uslug]
+  {"hash":"d7bd450b5571f32e","prefixes":{"":{"product":1242}}}, // [CJSC Recomendatsii tovarov i uslug]
+  {"hash":"788739abab822f20","prefixes":{"":{"product":1242}}}, // [CJSC Recomendatsii tovarov i uslug]
+  {"hash":"5119113b90253a71","prefixes":{"":{"product":1242}}}, // [CJSC Recomendatsii tovarov i uslug]
+  {"hash":"8391f54ef2dd8235","prefixes":{"":{"product":1243}}}, // [Adobe Edge]
+  {"hash":"ecbec0da60be727e","prefixes":{"":{"product":1243}}}, // [Adobe Edge]
+  {"hash":"45df05b3b1fd2039","prefixes":{"":{"product":1243}}}, // [Adobe Edge]
+  {"hash":"7f8b63980ada138f","prefixes":{"":{"product":1244}}}, // [Bizible]
+  {"hash":"fcff0eb6c45bdf72","prefixes":{"":{"product":1245}}}, // [Adludio Limited]
+  {"hash":"58ae271664061630","prefixes":{"":{"product":1245}}}, // [Adludio Limited]
+  {"hash":"19795a3ce2a7e620","prefixes":{"":{"product":1245}}}, // [Adludio Limited]
+  {"hash":"aa3822d449c78db7","prefixes":{"":{"product":1245}}}, // [Adludio Limited]
+  {"hash":"b1269cde121b05a1","prefixes":{"":{"product":1245}}}, // [Adludio Limited]
+  {"hash":"1581c4afe0d48fa2","prefixes":{"":{"product":1246}}}, // [Ally Financial]
+  {"hash":"2e171be7640cf4cd","prefixes":{"":{"product":1247}}}, // [AIAd Ltd.]
+  {"hash":"ae7e973c225c0a01","prefixes":{"":{"product":1248}}}, // [Petplan]
+  {"hash":"78db497564cd4bf9","prefixes":{"bis":{"product":1249},"":{"product":1249},"openrtb":{"product":1249}}}, // [Vidazoo Ltd.] [Vidazoo Ltd.] [Vidazoo Ltd.]
+  {"hash":"c0fe1ea55404bcbb","prefixes":{"bis":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"f7fbe362db50024a","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"55abab5eb4ff10bd","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"e542a9dea283be31","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"a49f5bf572a22bae","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"7e02810393b6fe89","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"89c0cbd03222de92","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"31a98e1d5bba9ae8","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"15010236a7d3b5a4","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"9f927848d0417d12","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"7a2f5d3665e9a31a","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"02fb27611632d82c","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"0b95d00c8ef095ae","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"2d42c2d0a5ab84ae","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"5e405c19a402590e","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"d037ae4b54d7e7ec","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"fa3f8d822f471c8e","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"1fd9bf19c5906c01","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"f989a4e87da3e6d9","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"26937f461d535e88","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"755c357326a37b3f","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"aac0686686b2d53c","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"3ce944fa0cf0291a","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"7302f12cc4ace16b","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"52816f3d4542b887","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"59bf7df499fa52b5","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"ebabd6c7d62c634c","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"53ac53e2f538f2e2","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"3ed73abadb9c898a","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"9574295460ce8d22","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"d591fdb6045eb90f","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"8b39993907ef0e90","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"fff9c91a1d02e69d","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"d086a625516bdfc4","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"dedb3c41790f0b92","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"d9d28815b7351be9","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"0eceb2a8a6aa5014","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"c3cd28d4911901ef","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"906300510974cf1a","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"6bbcc411e84396ce","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"18f5beb4c7518ce0","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"445bbe1950cddd7b","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"2b7cc0f2bdc9e984","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"2e1ee42fbe53923e","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"0d75de8359eb1e90","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"5439763db9182a6c","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"924a269d7fa953ef","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"56592bc98da7add7","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"e350307b97e81944","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"62d2d232adb7f5ce","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"9dbd1f71df681f87","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"60aa872cca3ea408","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"574290c159276582","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"520b03b31ba99ffe","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"8927dc4db3ffd9a0","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"cea75e5e1bcb3e75","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"00fc1e5ba5cf11e1","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"241443df62a11bdb","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"958852e67d999446","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"d7dde4fdd1b42ac2","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"b9a6386a13d1f59c","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"1b00c21eb7dca0ba","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"3b5a0569a91c1f27","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"07b3c413dcf0891e","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"4b15aef39cd29476","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"25743e7a87ec9352","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"2fe16a518eee6e23","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"a154647a02beff09","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"73a06806ded66bc0","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"a82c6297f56276f8","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"514b9e5dcf88791d","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"80e10fe664c9676b","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"788de2248f446546","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"e1e58f0b49a0e5c7","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"c56afa9dadaace8c","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"4084c6a05941d212","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"fafe943a3ce4b828","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"00cfc10d1f469dfc","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"cdb86fef4fddecdd","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"97b3473c7082a4c8","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"99973a84d3bda612","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"ba67aff057d8dc5d","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"a3c0da72dbefc878","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"5925a6291dd2ab40","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"34129d9457495ffd","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"e2505c6002184e33","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"9bcac0e9fd77ddc6","prefixes":{"":{"product":1249}}}, // [Vidazoo Ltd.]
+  {"hash":"737c1868e55d5b37","prefixes":{"":{"product":1250}}}, // [RTBstar LLC]
+  {"hash":"302ec6d6755746d6","prefixes":{"*":{"product":1251}}}, // [Chalk Media Holdings]
+  {"hash":"202f611d1eab4195","prefixes":{"*":{"product":1251}}}, // [Chalk Media Holdings]
+  {"hash":"a6ab491761f03a1c","prefixes":{"":{"product":1252}}}, // [Oxford Biochronometrics]
+  {"hash":"3f8968d2bc62134f","prefixes":{"":{"product":1252}}}, // [Oxford Biochronometrics]
+  {"hash":"fbe6ab3bc9d21558","prefixes":{"":{"product":1252}}}, // [Oxford Biochronometrics]
+  {"hash":"769529a9ad14a9b6","prefixes":{"":{"product":1253}}}, // [SGN Games, Inc.]
+  {"hash":"f1a29a10c1ad80be","prefixes":{"*":{"product":1254}}}, // [Crutchfield New Media, LLC]
+  {"hash":"930e98a126b97c02","prefixes":{"":{"product":113}}}, // [YOOX NET-A-PORTER GROUP SPA]
+  {"hash":"915e8620d61e782c","prefixes":{"":{"product":113}}}, // [YOOX NET-A-PORTER GROUP SPA]
+  {"hash":"0492037eab3835e9","prefixes":{"":{"product":113}}}, // [YOOX NET-A-PORTER GROUP SPA]
+  {"hash":"5eee79daa9337871","prefixes":{"":{"product":1255}}}, // [Laserlike Inc]
+  {"hash":"3262121ae456ec62","prefixes":{"":{"product":1256}}}, // [Adtile Technologies Inc.]
+  {"hash":"eefeb24c8c0df59f","prefixes":{"":{"product":1256}}}, // [Adtile Technologies Inc.]
+  {"hash":"2f77e3292a158b3c","prefixes":{"":{"product":1256}}}, // [Adtile Technologies Inc.]
+  {"hash":"ed04984091cd6edc","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"63c7ce8ea1112262","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"842d35d55c520fe2","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"3fb91c004caeeba4","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"4673bf1b8fb41012","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"60c5047efc444089","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"9daf201eb861bd5a","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"8fb045042ba8dab7","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"b5c5f11aa533f8f8","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"e69760fd18a7e847","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"afdb50efeb58adb3","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"54ade0c2fc33d554","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"980a9356a0a0604b","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"0d064f41dd06b071","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"4e9cc6d069d0700f","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"abc81c5ff7313f61","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"4d8e54db683834b5","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"958c891ea7a22760","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"02b0aa7dbed4dc70","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"cd655ca6f3e7c5b4","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"117f6d5c385c0fbf","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"974b3e895eb889a1","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"2315e038cabe7cf3","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"256e6db135713c95","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"44b4921e1dd83428","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"2ececb465fbab022","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"b3a40f1c056c981d","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"c4f8f640f24e3592","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"0a6e85210f1d99c3","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"d12573269a748046","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"deabc924d996a1ca","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"cfae73045c7b29a6","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"c97db9d5ee0b71c7","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"ca6bb3442fa58646","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"f38fbdc9759c0ef4","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"6db47cd08bed3122","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"86c0634020121d1e","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"98c1045cd61f979d","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"7bdc1a49cf0ccc1d","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"cdceb4fead43eafb","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"b8a7ac4ace0ce6e9","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"081ccef35be56b36","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"e29de726004b6e06","prefixes":{"":{"product":1257}}}, // [Adgravity]
+  {"hash":"3044eb15f0757788","prefixes":{"":{"product":1258}}}, // [Protected Media LTD]
+  {"hash":"675f561d3f31df38","prefixes":{"":{"product":1258}}}, // [Protected Media LTD]
+  {"hash":"506fa56f8b748a67","prefixes":{"":{"product":1259}}}, // [Media Detect GmbH]
+  {"hash":"d8795d8df3c0b355","prefixes":{"":{"product":1260}}}, // [Centro CDN]
+  {"hash":"92690e6cf2068609","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"bcb296520399e855","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"eeba4d486f2a193f","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"36ba79aa125ace1d","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"755e0fb3a6d853e7","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"926c7d8c47cdc6a4","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"112f8b5a749d05e9","prefixes":{"":{"product":1261}}}, // [DeltaX]
+  {"hash":"9a9421d022c231d0","prefixes":{"":{"product":1262}}}, // [jQuery]
+  {"hash":"7ed84366898b6e95","prefixes":{"":{"product":1263}}}, // [SoMo Audience Corp.]
+  {"hash":"7b7b8f4fea812106","prefixes":{"":{"product":1263}}}, // [SoMo Audience Corp.]
+  {"hash":"cd27a627925b605e","prefixes":{"":{"product":1263}}}, // [SoMo Audience Corp.]
+  {"hash":"8de4d0c2e5a785d3","prefixes":{"":{"product":1263}}}, // [SoMo Audience Corp.]
+  {"hash":"dd090795aa41d39d","prefixes":{"":{"product":1263}}}, // [SoMo Audience Corp.]
+  {"hash":"a792d2d9ef8b7d44","prefixes":{"":{"product":1264}}}, // [Distribute Ltd]
+  {"hash":"a41d8bffbb4dde29","prefixes":{"c":{"product":1264}}}, // [Distribute Ltd]
+  {"hash":"cb03110aa3eafbc3","prefixes":{"":{"product":1264}}}, // [Distribute Ltd]
+  {"hash":"f8d5c1c3c0137b95","prefixes":{"":{"product":1264}}}, // [Distribute Ltd]
+  {"hash":"fdbd7675a0a4e4d2","prefixes":{"":{"product":1264}}}, // [Distribute Ltd]
+  {"hash":"c152daf3639bfd61","prefixes":{"":{"product":1265}}}, // [Poppin]
+  {"hash":"77afc197a9ed3c55","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"f000d51ba83c9b81","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"e6b0bd562a8a6c44","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"b67bb576e01ff3b8","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"b74cae0d407627c6","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"d02ca334243aeff6","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"27c4aebe8feb1d61","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"cffac58b1fe6a120","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"060b85b3672a94b9","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"993dbbd9a4428116","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"5d08c05fd8f3e6b6","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"733a8e48aa3496c3","prefixes":{"":{"product":1266}}}, // [EUROZEST MEDIA LIMITED/Avid Ad Server]
+  {"hash":"6dfff15240319d9a","prefixes":{"":{"product":1267}}}, // [Art of Click Pte. Ltd]
+  {"hash":"3771e4f81d75a524","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"b2d089ed26249e9c","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"6cb0920968e42462","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"779587babf9a845a","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"21fd838e467abf9e","prefixes":{"":{"product":45}}}, // [Adways SAS]
+  {"hash":"f35db5d8e41be046","prefixes":{"":{"product":1268}}}, // [Quantasy LLC]
+  {"hash":"fb881e61783803db","prefixes":{"":{"product":1269}}}, // [Wavenet Technology Co., Ltd.]
+  {"hash":"4a5a7154d849b6df","prefixes":{"":{"product":1270}}}, // [ENVISIONX LTD]
+  {"hash":"4c0fc55e8fe8be51","prefixes":{"":{"product":1271}}}, // [Adhood]
+  {"hash":"62b3383734c496fb","prefixes":{"":{"product":1271}}}, // [Adhood]
+  {"hash":"27e40c1642b59b0e","prefixes":{"":{"product":1271}}}, // [Adhood]
+  {"hash":"b7bcec8f502b24cf","prefixes":{"":{"product":1271}}}, // [Adhood]
+  {"hash":"b8885905bf9e213f","prefixes":{"":{"product":1271}}}, // [Adhood]
+  {"hash":"8238d8729bb3748c","prefixes":{"":{"product":1272}}}, // [Telogical Systems, LLC]
+  {"hash":"92dbc0e618f7816a","prefixes":{"":{"product":1272}}}, // [Telogical Systems, LLC]
+  {"hash":"d3be8ee2ff24c8dd","prefixes":{"":{"product":1272}}}, // [Telogical Systems, LLC]
+  {"hash":"0767b016186f9908","prefixes":{"":{"product":1273}}}, // [twyn group IT solutions & marketing services G]
+  {"hash":"1bf7b44093f4c0b5","prefixes":{"":{"product":1274}}}, // [Marchex Sales, LLC]
+  {"hash":"b60099c5a3ff5579","prefixes":{"":{"product":1275}}}, // [SmartyAds LLP]
+  {"hash":"e1e5cbc69ff27126","prefixes":{"":{"product":1275}}}, // [SmartyAds LLP]
+  {"hash":"01e34dcf6356f25b","prefixes":{"":{"product":1275}}}, // [SmartyAds LLP]
+  {"hash":"0587980840cbad28","prefixes":{"":{"product":1275}}}, // [SmartyAds LLP]
+  {"hash":"c13574923293d7c7","prefixes":{"":{"product":1276}}}, // [Reach150 Social, Inc.]
+  {"hash":"e87358da2b6ad070","prefixes":{"":{"product":1277}}}, // [Leadmill ApS]
+  {"hash":"2a24bd7dfe371075","prefixes":{"":{"product":1277}}}, // [Leadmill ApS]
+  {"hash":"3f6b6ba536add909","prefixes":{"":{"product":1278}}}, // [TapHeaven, Inc.]
+  {"hash":"050f2328d34461a7","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"a66968f05d34f468","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"2c309ae9bbbe9384","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"fec9fa0c1f3ffe6e","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"49989970caa95c3d","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"32eb6e39519c6d65","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"5ecf91c30b7a0a6a","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"6394e1f93c660614","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"3c6f41d29f5df8e7","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"cda46d94d7efda5c","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"164782d64f732408","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"af8c779439f17da0","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"0394176d4d575a93","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"c9a808631e01ad1a","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"1478be442db9d539","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"171f00354c5c6b43","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"521c6ad185dff69d","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"a7c6cb92086909f4","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"efb2ad70cb64944c","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"35e50ce841196503","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"683154a56472f3e2","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"6664d0e4be1a2011","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"efefa03759c8eb89","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"20477544dc10c916","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"922d2397edef5dbd","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"a9591e706ed0da18","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"c073c895bf061908","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"8a7804498832f633","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"45c2a9f766453c46","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"2a167f8c5d41c9de","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"0992810376313bba","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"e4588caa0c232726","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"73fbee089a438309","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"48743ee797fa8c98","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"22561af78d8aeebe","prefixes":{"":{"product":1279}}}, // [spring GmbH & Co. KG]
+  {"hash":"ee6f381082694c53","prefixes":{"":{"product":1280}}}, // [Roq.ad GmbH]
+  {"hash":"606e92e46118e68c","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"5dd554237e590e7a","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"47c55cdc2352963b","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"698477bb42f577d9","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"4d35613bf3c5608c","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"8bbcbb68e24aba75","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"b5d289baee77f3bb","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"1eab99893ccb6812","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"2d38a36747a2e4c8","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"2aaee44de4212440","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"720594080864ccd0","prefixes":{"":{"product":1281}}}, // [AdKernel LLC]
+  {"hash":"8cf8db96c95ad703","prefixes":{"":{"product":1282}}}, // [Uprise Technologies]
+  {"hash":"bdc43b963f1225e2","prefixes":{"":{"product":1283}}}, // [Sled, Inc.]
+  {"hash":"bd39b2a3b45ba87e","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"987e96fd53ac3377","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"ae49bd17dd4ead54","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"8d132f34a86f51b3","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"4210564496763546","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"c395c961fb4a60ae","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"2f37a86d54dbe4f9","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"04730e3fb984e716","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"8e040ece0573e008","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"a2aafd8d622f674d","prefixes":{"":{"product":1284}}}, // [Pengtai Interactive Advertising Co.Ltd]
+  {"hash":"4da566f98e41e44f","prefixes":{"":{"product":1285}}}, // [Adello Group AG]
+  {"hash":"469779ba0b2d7340","prefixes":{"":{"product":1286}}}, // [BitGravity]
+  {"hash":"bfa6d675fa0c17c3","prefixes":{"":{"product":1287}}}, // [44 Interactive]
+  {"hash":"ac3b5f670d7fd934","prefixes":{"*":{"product":1288}}}, // [KeyCDN]
+  {"hash":"1058dbbc2bdc3042","prefixes":{"*":{"product":1288}}}, // [KeyCDN]
+  {"hash":"d36cc93ea8fd1701","prefixes":{"":{"product":1289}}}, // [Shopalyst Technologies Pvt Ltd]
+  {"hash":"95ad856091f4bc84","prefixes":{"":{"product":1289}}}, // [Shopalyst Technologies Pvt Ltd]
+  {"hash":"848239e92ef8cdab","prefixes":{"":{"product":1290}}}, // [Total Access Communication Public Company Limited]
+  {"hash":"0607ff309fec62de","prefixes":{"":{"product":1291}}}, // [TACTIC Real-time marketing AS]
+  {"hash":"abcc33d7fb9de6d9","prefixes":{"":{"product":1292}}}, // [Mobilewalla, Inc]
+  {"hash":"c7bbc2be78119074","prefixes":{"":{"product":1293}}}, // [Nuviad Ltd]
+  {"hash":"63da29d5b072ec2a","prefixes":{"*":{"product":1294}}}, // [AmberData LLC]
+  {"hash":"6c2f34d23d272f4b","prefixes":{"":{"product":1295}}}, // [Aedgency]
+  {"hash":"2da837b490e2d01c","prefixes":{"":{"product":1296}}}, // [MobPartner, Inc.]
+  {"hash":"900c7f6444e6ccdd","prefixes":{"":{"product":1297}}}, // [AdTriba GmbH]
+  {"hash":"9110b2853fbfc1f4","prefixes":{"":{"product":1297}}}, // [AdTriba GmbH]
+  {"hash":"0a9e29016a6f697e","prefixes":{"":{"product":1298}}}, // [DISH Network L.L.C.]
+  {"hash":"8c7746484c824908","prefixes":{"":{"product":1299}}}, // [Monotype Imaging Inc.]
+  {"hash":"11826b3490b70597","prefixes":{"":{"product":1299}}}, // [Monotype Imaging Inc.]
+  {"hash":"55b9261efb54de8c","prefixes":{"":{"product":1299}}}, // [Monotype Imaging Inc.]
+  {"hash":"57f3bae0dc69937f","prefixes":{"":{"product":1299}}}, // [Monotype Imaging Inc.]
+  {"hash":"b5158a795c80a5a2","prefixes":{"":{"product":1300}}}, // [MEDIAN Ltd.]
+  {"hash":"e79098d30fde1a28","prefixes":{"":{"product":1301}}}, // [ClickForce Inc.]
+  {"hash":"36739070f3c0ff16","prefixes":{"":{"product":1301}}}, // [ClickForce Inc.]
+  {"hash":"40febfb412ba6ddb","prefixes":{"":{"product":1302}}}, // [Zemanta Inc.]
+  {"hash":"80e8d865a27bacac","prefixes":{"":{"product":237}}}, // [Hostelworld.com Limited]
+  {"hash":"2a3acfae7d4bdd9b","prefixes":{"":{"product":861}}}, // [Barometric]
+  {"hash":"a48dde8fab3a9ca1","prefixes":{"*":{"product":1303}}}, // [jsdelivr.com]
+  {"hash":"82b544dbc2fdd536","prefixes":{"*":{"product":1304}}}, // [Adssets AB]
+  {"hash":"46106972e3ebaddb","prefixes":{"":{"product":1305}}}, // [Sellpoints Inc.]
+  {"hash":"bbc8c43681364c14","prefixes":{"":{"product":46}}}, // [Opera Mediaworks Inc.]
+  {"hash":"a3ff6df6612f21df","prefixes":{"":{"product":46}}}, // [Opera Mediaworks Inc.]
+  {"hash":"759162b5823db802","prefixes":{"":{"product":1306}}}, // [HockeyCurve Growth Solutions Pvt Ltd]
+  {"hash":"b3f9f03fb2c77a95","prefixes":{"":{"product":1307}}}, // [HockeyCurve Growth Solutions Pyt Ltd]
+  {"hash":"0dcbeed5fe35278e","prefixes":{"":{"product":1307}}}, // [HockeyCurve Growth Solutions Pyt Ltd]
+  {"hash":"e6898006d78eca08","prefixes":{"":{"product":1308}}}, // [Umeng Plus Beijing Technology Limited Company]
+  {"hash":"c2ecb9f34950ae64","prefixes":{"":{"product":1308}}}, // [Umeng Plus Beijing Technology Limited Company]
+  {"hash":"e530de1f6ff8ed8c","prefixes":{"":{"product":1308}}}, // [Umeng Plus Beijing Technology Limited Company]
+  {"hash":"ef9efb2dfd9b223f","prefixes":{"":{"product":1308}}}, // [Umeng Plus Beijing Technology Limited Company]
+  {"hash":"8dad79c9e968f7ca","prefixes":{"":{"product":1309}}}, // [Survata, Inc.]
+  {"hash":"7a5110db80c0493f","prefixes":{"":{"product":1309}}}, // [Survata, Inc.]
+  {"hash":"e8cb0ee7c430e881","prefixes":{"":{"product":1310}}}, // [JustWatch GmbH]
+  {"hash":"c85404f2f558dbd2","prefixes":{"":{"product":1310}}}, // [JustWatch GmbH]
+  {"hash":"b44b63d6e81094e4","prefixes":{"":{"product":1310}}}, // [JustWatch GmbH]
+  {"hash":"e1614140e3cef4fd","prefixes":{"":{"product":1310}}}, // [JustWatch GmbH]
+  {"hash":"2cfd0204e2673c60","prefixes":{"":{"product":1311}}}, // [Interactive Tracker Next]
+  {"hash":"1c5f8f88ce98b360","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"fbac71ab5dbe5025","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"4e08c60f61b1ac87","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"3f4bfa67b5290ada","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"a9b4af4145bf90b2","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"d0d20b9b53b41e58","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"ff37598c00132a2a","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"daae3b285b4abeee","prefixes":{"":{"product":1312}}}, // [Unisport A/S]
+  {"hash":"20cdb1f9a8066fe2","prefixes":{"":{"product":1313}}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
+  {"hash":"a53281df69681314","prefixes":{"":{"product":1313}}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
+  {"hash":"f25344f6f85b0f61","prefixes":{"":{"product":1313}}}, // [OPTDCOM TEKNOLOJİ YATIRIM ANONİM ŞİRKETİ]
+  {"hash":"b544d72a6726ee1d","prefixes":{"":{"product":1314}}}, // [Softcube Inc.]
+  {"hash":"d924c399f5813397","prefixes":{"":{"product":1315}}}, // [YOptima Media Solutions Pvt. Ltd]
+  {"hash":"3405e57b3b784a16","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"8a5251fd38cf1d3b","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"039987610c50338a","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"0f7d3c301f70dfd0","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"77f81cf76bb9bd07","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"ec6a93785f45f030","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"3fcf5b9a36bb776b","prefixes":{"":{"product":1316}}}, // [ZMAGS INC]
+  {"hash":"b81945950b163ad1","prefixes":{"":{"product":1307}}}, // [HockeyCurve Growth Solutions Pyt Ltd]
+  {"hash":"36c7ea48fdc42362","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"a3bfc331d20ba3e8","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"64a6cb69505f47a8","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"e7d85f73b7514aa9","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"0263af098607c6d6","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"5c911e8fdb9b3507","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"665d12aaa10c1858","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"206d02e9bc6dc66f","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"681210fb48272cc7","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"f42b80ceeefbc2e4","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"9b951656519bc7f0","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"f615949643fdcebb","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"814934c13235b868","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"d451d289ed990ba0","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"b2de6bb8607f747e","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"fa9dba37389c8a9e","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"fe776ee0016175b8","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"1a561a0db871620b","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"84440122e5725865","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"f98baedc7354d85b","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"cedef135a07c2d1b","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"b7196f696d55352b","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"90c8f9118f9c2653","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"7ec460729f94a446","prefixes":{"":{"product":1317}}}, // [Realtag]
+  {"hash":"c84baed94e3d3a6c","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"88c72a0edf15af94","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"8ffa9e7ae82fdaf3","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"b2b5e138d12de438","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"1249b88e4ce20439","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"9555623f08217ce6","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"0358d164ffcdc51b","prefixes":{"":{"product":1318}}}, // [Bitsngo.net]
+  {"hash":"d27b1458c8f91a54","prefixes":{"":{"product":1319}}}, // [AdCanvas]
+  {"hash":"5fd4bc3f3699146f","prefixes":{"":{"product":1319}}}, // [AdCanvas]
+  {"hash":"62f35089b9876ae5","prefixes":{"":{"product":1319}}}, // [AdCanvas]
+  {"hash":"92d701b4810ee717","prefixes":{"":{"product":1319}}}, // [AdCanvas]
+  {"hash":"3f927191adac8a66","prefixes":{"":{"product":1319}}}, // [AdCanvas]
+  {"hash":"051c9e70f0515e04","prefixes":{"":{"product":1320}}}, // [Happyfication, Inc.]
+  {"hash":"13580fc82945639c","prefixes":{"":{"product":1320}}}, // [Happyfication, Inc.]
+  {"hash":"914acd1211445b65","prefixes":{"":{"product":1320}}}, // [Happyfication, Inc.]
+  {"hash":"046e11a0cbc2124d","prefixes":{"":{"product":1320}}}, // [Happyfication, Inc.]
+  {"hash":"df5483bdd241c0b5","prefixes":{"":{"product":258}}}, // [HQ GmbH]
+  {"hash":"8ee2f36b1789e47d","prefixes":{"":{"product":1321},"*":{"product":1322}}}, // [Cinarra Systems Japan株式会社] [Cinarra Systems Japan]
+  {"hash":"92d76828c2bc5e86","prefixes":{"":{"product":959}}}, // [MotoMiner]
+  {"hash":"014c99288a655e93","prefixes":{"":{"product":1323}}}, // [CUBED Attribution]
+  {"hash":"34d44a28a42c30fc","prefixes":{"":{"product":1323}}}, // [CUBED Attribution]
+  {"hash":"6525e4a55892b035","prefixes":{"":{"product":1324}}}, // [StackAdapt Inc.]
+  {"hash":"9108433b6be75366","prefixes":{"":{"product":1324}}}, // [StackAdapt Inc.]
+  {"hash":"ca5914cdc3f95c5a","prefixes":{"":{"product":1324}}}, // [StackAdapt Inc.]
+  {"hash":"e25d7e6b7298b655","prefixes":{"":{"product":1325}}}, // [Statiq Ltd]
+  {"hash":"63a988f83e509eca","prefixes":{"":{"product":47}}}, // [DistroScale Inc.]
+  {"hash":"e6c8188134efb49f","prefixes":{"":{"product":47}}}, // [DistroScale Inc.]
+  {"hash":"eab29bab9fd4b969","prefixes":{"":{"product":47}}}, // [DistroScale Inc.]
+  {"hash":"c24f6dcb16cfd4e4","prefixes":{"":{"product":47}}}, // [DistroScale Inc.]
+  {"hash":"e6a95c6bb8d6efd4","prefixes":{"":{"product":1326}}}, // [Tagular Analytics, LLC]
+  {"hash":"9c2dcc6473dee219","prefixes":{"":{"product":1326}}}, // [Tagular Analytics, LLC]
+  {"hash":"986af10dd127ff07","prefixes":{"":{"product":1326}}}, // [Tagular Analytics, LLC]
+  {"hash":"f74107ff21d433e9","prefixes":{"":{"product":1326}}}, // [Tagular Analytics, LLC]
+  {"hash":"ce5c1378f1f941f6","prefixes":{"":{"product":1327}}}, // [ComboTag Technologies Ltd.]
+  {"hash":"879f914a15df34e0","prefixes":{"":{"product":1328}}}, // [Juice Mobile]
+  {"hash":"17e1300dbcc39afb","prefixes":{"":{"product":1328}}}, // [Juice Mobile]
+  {"hash":"d22e60c27d37cebc","prefixes":{"":{"product":1328}}}, // [Juice Mobile]
+  {"hash":"80d91748976f3124","prefixes":{"":{"product":1328}}}, // [Juice Mobile]
+  {"hash":"74478806654499c0","prefixes":{"":{"product":1328}}}, // [Juice Mobile]
+  {"hash":"1b02f5c5bfc0039d","prefixes":{"":{"product":1328}}}, // [Juice Mobile]
+  {"hash":"ee644eb69f62cdec","prefixes":{"":{"product":1329}}}, // [Bebe]
+  {"hash":"8fb13ead8b0754fb","prefixes":{"":{"product":1330}}}, // [Augur]
+  {"hash":"cfbc4ef83efc3949","prefixes":{"*":{"product":1331}}}, // [Seracast Digital LLC]
+  {"hash":"a8285782e9e5e7e8","prefixes":{"*":{"product":1331}}}, // [Seracast Digital LLC]
+  {"hash":"3a9b5e5bcd74ba27","prefixes":{"":{"product":1332}}}, // [AerServ LLC]
+  {"hash":"dd4e82ee18499196","prefixes":{"":{"product":1332}}}, // [AerServ LLC]
+  {"hash":"2163ccdaf0c7ac04","prefixes":{"*":{"product":1321}}}, // [Cinarra Systems Japan株式会社]
+  {"hash":"e16e6171a3e50ef3","prefixes":{"":{"product":1333}}}, // [PT. Tokopedia]
+  {"hash":"74b1225f4470815b","prefixes":{"":{"product":1334}}}, // [Terapeak, Inc.]
+  {"hash":"7eb7af632c622616","prefixes":{"*":{"product":1335}}}, // [OpenStreetMap France]
+  {"hash":"63c3a3e6536f0b7f","prefixes":{"*":{"product":1336}}}, // [Front Porch, Inc]
+  {"hash":"2c6aaec84cacd716","prefixes":{"*":{"product":1336}}}, // [Front Porch, Inc]
+  {"hash":"6f469a516e0ea586","prefixes":{"":{"product":1337}}}, // [Vertamedia]
+  {"hash":"d06485ea48298b7e","prefixes":{"":{"product":1338}}}, // [Codewise (VoluumDSP)]
+  {"hash":"7a43b35e42bcef39","prefixes":{"":{"product":1339}}}, // [Virool Inc.]
+  {"hash":"4ff7c90f1d23d419","prefixes":{"":{"product":1340}}}, // [SpringServe LLC]
+  {"hash":"7f06352affc07566","prefixes":{"":{"product":1340}}}, // [SpringServe LLC]
+  {"hash":"96ea998589a3f7ab","prefixes":{"":{"product":1340}}}, // [SpringServe LLC]
+  {"hash":"32ec7c3af8d6ee95","prefixes":{"":{"product":1340}}}, // [SpringServe LLC]
+  {"hash":"294e9804817557ed","prefixes":{"":{"product":1340}}}, // [SpringServe LLC]
+  {"hash":"e9c681d4af45ad2c","prefixes":{"":{"product":1341}}}, // [Intimate Merger]
+  {"hash":"68cc07724e870731","prefixes":{"":{"product":1341}}}, // [Intimate Merger]
+  {"hash":"60f3c72e07bc4431","prefixes":{"":{"product":1342}}}, // [Telecoming Connectivity S.A.]
+  {"hash":"22081b94e890803c","prefixes":{"":{"product":1343}}}, // [Webssup]
+  {"hash":"00e22da76abf1e12","prefixes":{"":{"product":1343}}}, // [Webssup]
+  {"hash":"498495a391901f22","prefixes":{"":{"product":1344}}}, // [INCUBIQ Solutions Ltd]
+  {"hash":"606c712ed1507693","prefixes":{"":{"product":1344}}}, // [INCUBIQ Solutions Ltd]
+  {"hash":"a9af6bbd9a022211","prefixes":{"*":{"product":1336}}}, // [Front Porch, Inc]
+  {"hash":"5ad9370da8c17992","prefixes":{"":{"product":1345}}}, // [ADSpend]
+  {"hash":"fdd6cbfd0c4ad857","prefixes":{"":{"product":1346}}}, // [AdTradr Corporation]
+  {"hash":"81b9923f85553957","prefixes":{"":{"product":1346}}}, // [AdTradr Corporation]
+  {"hash":"a145ad19f618929c","prefixes":{"":{"product":1346}}}, // [AdTradr Corporation]
+  {"hash":"b1930e60745f4b68","prefixes":{"":{"product":1346}}}, // [AdTradr Corporation]
+  {"hash":"57f97d99aaf44ad1","prefixes":{"":{"product":1346}}}, // [AdTradr Corporation]
+  {"hash":"99143cae9fe8dcb7","prefixes":{"":{"product":1347}}}, // [Quint Growth Inc.]
+  {"hash":"eb5cead7881dc3da","prefixes":{"":{"product":1348}}}, // [ZAPR]
+  {"hash":"2fe0bb9349d1959b","prefixes":{"":{"product":1348}}}, // [ZAPR]
+  {"hash":"b959bccbc132d322","prefixes":{"":{"product":20}}}, // [On Device Research Ltd.]
+  {"hash":"8a8c554522b206ad","prefixes":{"":{"product":1349}}}, // [1trn LLC]
+  {"hash":"45dfdbe509539a3b","prefixes":{"":{"product":1349}}}, // [1trn LLC]
+  {"hash":"6265ceee0906cac8","prefixes":{"":{"product":1350}}}, // [Matiro]
+  {"hash":"279177f20ce276af","prefixes":{"":{"product":1350}}}, // [Matiro]
+  {"hash":"b90e8e5f5f114049","prefixes":{"":{"product":1350}}}, // [Matiro]
+  {"hash":"68519953a094dc0c","prefixes":{"":{"product":1350}}}, // [Matiro]
+  {"hash":"2c9356fdc6a3d512","prefixes":{"":{"product":1350}}}, // [Matiro]
+  {"hash":"486312e316f3d301","prefixes":{"":{"product":1350}}}, // [Matiro]
+  {"hash":"0dea0840245a2dd2","prefixes":{"*":{"product":1351}}}, // [Inspired Mobile Ltd.]
+  {"hash":"e1e444909b156b50","prefixes":{"*":{"product":1351}}}, // [Inspired Mobile Ltd.]
+  {"hash":"ba50b6623ecf06b7","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"bb2433b4d9ceaf93","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"752e7bd32ca03e2b","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"fecd6600c1d54571","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"e2f5a8707a39a63f","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"6e7cd3eb7639d09a","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"e0afc2f779238a59","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"51c4028642a5ca4c","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"1640e1eeb06df964","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"6c8c2f363cf647b5","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"d9f31e1a90e8fb75","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"845fb9c6387bef97","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"0459341df70cc072","prefixes":{"":{"product":1352}}}, // [Selectmedia International LTD.]
+  {"hash":"be68419b316ae4c5","prefixes":{"":{"product":1353}}}, // [Internet Billboard, a. s]
+  {"hash":"ba9be76fe6cba556","prefixes":{"":{"product":1353}}}, // [Internet Billboard, a. s]
+  {"hash":"ec3aa5f11c754de6","prefixes":{"":{"product":1353}}}, // [Internet Billboard, a. s]
+  {"hash":"5023d333c14740b4","prefixes":{"":{"product":1353}}}, // [Internet Billboard, a. s]
+  {"hash":"eab4b496bc09743b","prefixes":{"":{"product":1354}}}, // [Volvelle]
+  {"hash":"2afdaf8d1bad3cb9","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"c2367faa0f667908","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"ed58e98b46833296","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"e0249363e0c7a5fa","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"3f6dfa5fad816543","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"0daca079a0ddd2c5","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"eb2192ea666d6dfe","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"6a1269cf9dab66ee","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"39079f1183b1a260","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"9455a8e3fa7e9a01","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"bebc1faa9d73b7b0","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"c5069619b84c740e","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"8effee3cd53dcfe8","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"8251bfe6accaab04","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"f1019f4619cbfe25","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"825efa7e6eea91b6","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"cdeee95936c4dbc6","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"812ac20217e10e22","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"a20318efcc942b0c","prefixes":{"":{"product":1355}}}, // [StreamRail Ltd.]
+  {"hash":"7ba3379a648cbc77","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"faca10de01f9747f","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"c4bada2290c2b41f","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"7e8290508a81ecfd","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"415fbdfa7cf95914","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"97322010e9179343","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"07549a667fcd0003","prefixes":{"":{"product":1356}}}, // [E-Contenta]
+  {"hash":"f5359f09115e5a08","prefixes":{"":{"product":1357}}}, // [Bath and Body Works]
+  {"hash":"93931937deeacde2","prefixes":{"":{"product":1160}}}, // [KuaiziTech]
+  {"hash":"885efbcb155efd68","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"8515f5e803de693b","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"7990fea9b4cdbdf9","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"a6632e804a3dc853","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"ae4745b0fd104fbb","prefixes":{"":{"product":691}}}, // [Aniview LTD.]
+  {"hash":"956dc47eeadd36f7","prefixes":{"":{"product":1358}}}, // [WooTag Pte Ltd]
+  {"hash":"091b478316a2c133","prefixes":{"":{"product":1358}}}, // [WooTag Pte Ltd]
+  {"hash":"dc8fa04b592b8307","prefixes":{"":{"product":1358}}}, // [WooTag Pte Ltd]
+  {"hash":"fe0e326ac7dc8d7c","prefixes":{"":{"product":1358}}}, // [WooTag Pte Ltd]
+  {"hash":"410a107d660ab1cd","prefixes":{"":{"product":1359}}}, // [Cint AB]
+  {"hash":"b294fa0e55fcd2f4","prefixes":{"":{"product":1359}}}, // [Cint AB]
+  {"hash":"5519fa5da5e57ad1","prefixes":{"":{"product":1360}}}, // [Stein Mart]
+  {"hash":"7277d1fc5bc3c416","prefixes":{"":{"product":1361}}}, // [Sift Media, Inc.]
+  {"hash":"4b89510469e15939","prefixes":{"":{"product":1362}}}, // [StartApp Inc.]
+  {"hash":"d3b5600174198250","prefixes":{"":{"product":1362}}}, // [StartApp Inc.]
+  {"hash":"5597070a34018ed8","prefixes":{"":{"product":1362}}}, // [StartApp Inc.]
+  {"hash":"17f290970639d124","prefixes":{"":{"product":1363}}}, // [Pxene - DSP]
+  {"hash":"263ee2028bc08b39","prefixes":{"":{"product":1363}}}, // [Pxene - DSP]
+  {"hash":"da0f3a897355dd67","prefixes":{"":{"product":1363}}}, // [Pxene - DSP]
+  {"hash":"9ca84ba93389421b","prefixes":{"":{"product":1363}}}, // [Pxene - DSP]
+  {"hash":"4d5f045a10baa819","prefixes":{"":{"product":1364}}}, // [Integral Marketing]
+  {"hash":"50bc395b6101613b","prefixes":{"":{"product":1364}}}, // [Integral Marketing]
+  {"hash":"3affd533937e3000","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"971d313a32301476","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"c5351f32e51be2fe","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"4d91e6834270bed5","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"5d662bce285c4f62","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"acf96648fc83494b","prefixes":{"":{"product":48}}}, // [Enzymic Consultancy]
+  {"hash":"ea62a03194f9fd95","prefixes":{"":{"product":1365}}}, // [Expedia, Inc.]
+  {"hash":"d3ff1633dded1329","prefixes":{"":{"product":1366}}}, // [DeepIntent, Inc]
+  {"hash":"2b5d6ad4574423ab","prefixes":{"":{"product":1366}}}, // [DeepIntent, Inc]
+  {"hash":"dd8c5b641bb2871c","prefixes":{"":{"product":1366}}}, // [DeepIntent, Inc]
+  {"hash":"4ba3d981f5073f12","prefixes":{"":{"product":1366}}}, // [DeepIntent, Inc]
+  {"hash":"92f845f3cbfc83ca","prefixes":{"":{"product":181}}}, // [Rakuten Attribution]
+  {"hash":"ff93f30e29dd79ce","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"1219256c57d362c2","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"588a30ada75d3716","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"f99b3a1ad217ec24","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"cffe29c52b1b73c5","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"f03d942c23c65a90","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"272d4c035a088de6","prefixes":{"":{"product":1367}}}, // [OmniVirt]
+  {"hash":"724568d0c3fc08a4","prefixes":{"":{"product":1368}}}, // ["Index20" LLC]
+  {"hash":"be108323d132726d","prefixes":{"":{"product":1369}}}, // [Conversion Logic, Inc.]
+  {"hash":"9fc3b91614502933","prefixes":{"":{"product":1370}}}, // [Collegehumor]
+  {"hash":"bb96895ad0b3fb46","prefixes":{"":{"product":1370}}}, // [Collegehumor]
+  {"hash":"830074aed1a53d22","prefixes":{"":{"product":1370}}}, // [Collegehumor]
+  {"hash":"db32b2c0136553c9","prefixes":{"":{"product":775}}}, // [Netflix, Inc.]
+  {"hash":"47df197461b802d5","prefixes":{"":{"product":775}}}, // [Netflix, Inc.]
+  {"hash":"acbf0ad8badc6915","prefixes":{"":{"product":775}}}, // [Netflix, Inc.]
+  {"hash":"c0b6c8d5b1736dc3","prefixes":{"":{"product":775}}}, // [Netflix, Inc.]
+  {"hash":"05dd2a6c687d34c0","prefixes":{"":{"product":1371}}}, // [Silence Media Limited]
+  {"hash":"cea7d6ed17648fbf","prefixes":{"":{"product":1371}}}, // [Silence Media Limited]
+  {"hash":"ad7149f316532231","prefixes":{"":{"product":1372}}}, // [Zuuvi Aps]
+  {"hash":"693751faddbb5801","prefixes":{"":{"product":1372}}}, // [Zuuvi Aps]
+  {"hash":"8da87b729d579d09","prefixes":{"":{"product":1372}}}, // [Zuuvi Aps]
+  {"hash":"ab5cc3951d346c77","prefixes":{"":{"product":1372}}}, // [Zuuvi Aps]
+  {"hash":"f41a4b1ac6a3bfb2","prefixes":{"":{"product":1373}}}, // [SoftBank Corp.]
+  {"hash":"1d0977195dc18825","prefixes":{"":{"product":1374}}}, // [ConnectOM, Inc.]
+  {"hash":"912365bfc81f780a","prefixes":{"":{"product":1374}}}, // [ConnectOM, Inc.]
+  {"hash":"7434a888611cfaf2","prefixes":{"":{"product":1374}}}, // [ConnectOM, Inc.]
+  {"hash":"1d73404a4d6b3cda","prefixes":{"":{"product":49}}}, // [Fluct Inc.]
+  {"hash":"938fa93131d63045","prefixes":{"":{"product":49}}}, // [Fluct Inc.]
+  {"hash":"67f35499d1bf5216","prefixes":{"":{"product":1375}}}, // [Skillup Video Technologies Corporation]
+  {"hash":"c8e2c0c42c388ceb","prefixes":{"":{"product":1375}}}, // [Skillup Video Technologies Corporation]
+  {"hash":"0800074e9a8aa9e0","prefixes":{"":{"product":1375}}}, // [Skillup Video Technologies Corporation]
+  {"hash":"f6853fba1d5c8366","prefixes":{"":{"product":1376}}}, // [Adara Impact Analytics]
+  {"hash":"7d5aa0875b5b03ee","prefixes":{"":{"product":1376}}}, // [Adara Impact Analytics]
+  {"hash":"e1a55205d635d049","prefixes":{"":{"product":1376}}}, // [Adara Impact Analytics]
+  {"hash":"b5ea51bb0aec174c","prefixes":{"":{"product":1376}}}, // [Adara Impact Analytics]
+  {"hash":"e4140b78afda4fb4","prefixes":{"":{"product":1376}}}, // [Adara Impact Analytics]
+  {"hash":"a4c74032025e0589","prefixes":{"":{"product":1377}}}, // [TabMo SAS]
+  {"hash":"d9638d78485cff41","prefixes":{"":{"product":1377}}}, // [TabMo SAS]
+  {"hash":"6ea3e003ed64d138","prefixes":{"":{"product":58}}}, // [Sixt Leasing SE]
+  {"hash":"22ae0beb131c4b8c","prefixes":{"":{"product":1378}}}, // [Casale Media]
+  {"hash":"29d1aaca6b9e6edd","prefixes":{"":{"product":1378}}}, // [Casale Media]
+  {"hash":"7d1380d196e0f347","prefixes":{"":{"product":1379}}}, // [StickyADStv]
+  {"hash":"147ac7b767355a32","prefixes":{"":{"product":1380}}}, // [Teads Technology SAS]
+  {"hash":"4b60266ba860a4c5","prefixes":{"":{"product":1381}}}, // [Anomaly Communications, LLC]
+  {"hash":"296893a9570ca935","prefixes":{"*":{"product":1382}}}, // [ClickTicker, LTD]
+  {"hash":"094df71f27ebd6f1","prefixes":{"":{"product":1383}}}, // [Tremour]
+  {"hash":"a1119d262b86de34","prefixes":{"":{"product":1384}}}, // [Roket Media LTD]
+  {"hash":"b1ed20b79d8a43cb","prefixes":{"":{"product":152}}}, // [e-Planning]
+  {"hash":"5bd05c801bb32096","prefixes":{"":{"product":1385}}}, // [Video Jam (MauDau LTD)]
+  {"hash":"dacf613410c17f5e","prefixes":{"":{"product":1385}}}, // [Video Jam (MauDau LTD)]
+  {"hash":"561f104ba38d6e64","prefixes":{"":{"product":1385}}}, // [Video Jam (MauDau LTD)]
+  {"hash":"a43509d6a08d1777","prefixes":{"":{"product":1386}}}, // [MINIMOB (CY) LTD]
+  {"hash":"b66514ac6530a3fd","prefixes":{"":{"product":1387}}}, // [Snitcher B.V.]
+  {"hash":"79b3660bde132ba1","prefixes":{"":{"product":1387}}}, // [Snitcher B.V.]
+  {"hash":"aaf7781b800509ba","prefixes":{"":{"product":1387}}}, // [Snitcher B.V.]
+  {"hash":"8fec6c672f5b204a","prefixes":{"":{"product":1387}}}, // [Snitcher B.V.]
+  {"hash":"825e7df4dfb9bae0","prefixes":{"":{"product":1387}}}, // [Snitcher B.V.]
+  {"hash":"379899626d07c3b5","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"664ce6265f73ec6a","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"ab33f6650feb44c2","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"557404c787c545cb","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"0c881f692e8ec0de","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"36c7264c1d06cc29","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"2f7b75786675821b","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"714fd218f12fce7a","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"d140a5f747a666f1","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"cbcfd9d592f2d19d","prefixes":{"":{"product":1388}}}, // [Analights]
+  {"hash":"a214f6ac537cafa2","prefixes":{"":{"product":1389}}}, // [Romir Panel Ltd.]
+  {"hash":"84fe21a8c3ba3818","prefixes":{"":{"product":1390}}}, // [Dievision]
+  {"hash":"c709bff0d2284ecc","prefixes":{"":{"product":1391}}}, // [Ignite Technologies]
+  {"hash":"3510f10ff5914868","prefixes":{"*":{"product":1392}}}, // [Navegg]
+  {"hash":"ea594377060cafc6","prefixes":{"":{"product":1393}}}, // [Adalyser]
+  {"hash":"631a68a191554bae","prefixes":{"":{"product":1393}}}, // [Adalyser]
+  {"hash":"8d9638d9355607ba","prefixes":{"":{"product":1393}}}, // [Adalyser]
+  {"hash":"d6e288fc5cf14c83","prefixes":{"":{"product":1393}}}, // [Adalyser]
+  {"hash":"90ec5cb29381e1ca","prefixes":{"":{"product":1393}}}, // [Adalyser]
+  {"hash":"3debdfa22ee00230","prefixes":{"":{"product":1393}}}, // [Adalyser]
+  {"hash":"45852dff86c0a7e0","prefixes":{"":{"product":1394}}}, // [Nordic Factory International Inc.]
+  {"hash":"063e04585364c0e5","prefixes":{"":{"product":719}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
+  {"hash":"aa4bfba1bb15cb76","prefixes":{"":{"product":719}}}, // [E-Plus Mobilfunk GmbH & Co. KG]
+  {"hash":"3f43b05864c28c77","prefixes":{"":{"product":1395}}}, // [Addition Plus Ltd]
+  {"hash":"9e1057ca77b6610c","prefixes":{"":{"product":1395}}}, // [Addition Plus Ltd]
+  {"hash":"a6278ebdf3ca7bce","prefixes":{"":{"product":1396}}}, // [Karmatech Mediaworks Pvt Ltd]
+  {"hash":"954044969f047c6c","prefixes":{"":{"product":1396}}}, // [Karmatech Mediaworks Pvt Ltd]
+  {"hash":"ca32fcf3a3101ca0","prefixes":{"":{"product":1397}}}, // [Mediatropy Pte Ltd]
+  {"hash":"54a24d41044c0730","prefixes":{"":{"product":26}}}, // [FSN ASIA PRIVATE LIMITED]
+  {"hash":"b3302c4e4fc23cb8","prefixes":{"":{"product":856}}}, // [Adman Interactive SL]
+  {"hash":"328eed54ff330e78","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"98ed7d7c1ae050b7","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"226e8c98a3e2e091","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"9e777471181caa70","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"9df613858a859407","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"37af06459214925d","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"0fdc04aa3cd4e402","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"f33f14a479b17a13","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"535ad6947981986b","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"0db16a6e891b1ff5","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"11b3c502d4eb1fa3","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"001bd6970eef2bbe","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"93505db1f9bf4a47","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"a1c9ac37054fc828","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"f4f375e269f34a60","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"e61b3b137beecfbc","prefixes":{"":{"product":1398}}}, // [Wayve Limited]
+  {"hash":"07bf22fe56be8d20","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"619e27568b55894c","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"374b60567f3c7f8b","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"af11cb377f269b3b","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"6bd694da478fa87b","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"75c4aedcbc945c91","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"71e8a51762fe81b6","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"5412f8017660207b","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"ba29363e3e139066","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"05de1e7e9f3271c3","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"5d73b4b9b8705846","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"711d9c4ce084aa7d","prefixes":{"*":{"product":1399}}}, // [Kreditech Holding SSL GmbH]
+  {"hash":"1ed6fde4c65ef6f7","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"4a6b1490dc059d0b","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"cab81dbe20c0957f","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"af1f3ce39e3b4862","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"19e97b139ae15342","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"fb46fee1ceef4719","prefixes":{"*":{"product":269}}}, // [DePauli AG]
+  {"hash":"798bda76da15abeb","prefixes":{"*":{"product":21}}}, // [SuperVista AG]
+  {"hash":"38bf7a598ad0c498","prefixes":{"*":{"product":21}}}, // [SuperVista AG]
+  {"hash":"48651b09d312b814","prefixes":{"*":{"product":21}}}, // [SuperVista AG]
+  {"hash":"bb2482d6022a94ba","prefixes":{"*":{"product":21}}}, // [SuperVista AG]
+  {"hash":"d58f8af9ff4e691e","prefixes":{"":{"product":1400}}}, // [Yengo]
+  {"hash":"8e9bee1bb54d54ee","prefixes":{"":{"product":1400}}}, // [Yengo]
+  {"hash":"06689ed650e2b8c3","prefixes":{"":{"product":1401}}}, // [DANtrack]
+  {"hash":"96c97b30a03579ac","prefixes":{"":{"product":1401}}}, // [DANtrack]
+  {"hash":"407face2b2c27397","prefixes":{"":{"product":1402}}}, // [Integral Markt- und Meinungsforschungsges.m.b.H.]
+  {"hash":"184f80ef53a0f178","prefixes":{"":{"product":1402}}}, // [Integral Markt- und Meinungsforschungsges.m.b.H.]
+  {"hash":"076a460590b496bf","prefixes":{"":{"product":1403}}}, // [Millemedia GmbH]
+  {"hash":"9febeed138f5f2ce","prefixes":{"":{"product":1404}}}, // [Hiro-Media]
+  {"hash":"dd35fc0a5f5fa07b","prefixes":{"":{"product":1404}}}, // [Hiro-Media]
+  {"hash":"b22687a0d4bd341f","prefixes":{"":{"product":1404}}}, // [Hiro-Media]
+  {"hash":"1625640192348305","prefixes":{"*":{"product":1405}}}, // [Simplaex Gmbh]
+  {"hash":"444356542461e7d2","prefixes":{"":{"product":1405}}}, // [Simplaex Gmbh]
+  {"hash":"b9edac442e488ddf","prefixes":{"":{"product":1405}}}, // [Simplaex Gmbh]
+  {"hash":"afed9502218fc1cd","prefixes":{"":{"product":1406}}}, // [Telekom Deutschland GmbH]
+  {"hash":"286d994374ce8a57","prefixes":{"":{"product":1407}}}, // [Infernotions Technologies Limited]
+  {"hash":"385225c96e123b3f","prefixes":{"":{"product":1408}}}, // [Goldfish Media LLC]
+  {"hash":"19c11b9ad47802f9","prefixes":{"":{"product":1365}}}, // [Expedia, Inc.]
+  {"hash":"d710ea66b904cd82","prefixes":{"":{"product":1409}}}, // [Smartology Limited]
+  {"hash":"24bbec831a84a114","prefixes":{"":{"product":1409}}}, // [Smartology Limited]
+  {"hash":"9c3279986e25304c","prefixes":{"":{"product":1409}}}, // [Smartology Limited]
+  {"hash":"8ce94299572dc9b8","prefixes":{"":{"product":1409}}}, // [Smartology Limited]
+  {"hash":"e51f784e66ceb1cb","prefixes":{"":{"product":1410}}}, // [GroupM]
+  {"hash":"72bd4ec98dea633b","prefixes":{"":{"product":1410}}}, // [GroupM]
+  {"hash":"0836c753510a4fd6","prefixes":{"*":{"product":1411}}}, // [Haystagg Inc.]
+  {"hash":"4a13b1d65c372006","prefixes":{"*":{"product":1411}}}, // [Haystagg Inc.]
+  {"hash":"14ec018232a87385","prefixes":{"":{"product":1412}}}, // [Digital Turbine Media, Inc]
+  {"hash":"fdabfb7535e313a7","prefixes":{"":{"product":1412}}}, // [Digital Turbine Media, Inc]
+  {"hash":"cddef42a99b1f0e2","prefixes":{"":{"product":1413}}}, // [MDSP INC]
+  {"hash":"1bcc84762c0f2df8","prefixes":{"":{"product":1414}}}, // [Quadas (YiDong Data Inc.)]
+  {"hash":"6c46a69428837566","prefixes":{"":{"product":1415}}}, // [Recruit Career Co., Ltd.]
+  {"hash":"17319e35b3b89b68","prefixes":{"":{"product":1416}}}, // [R2Net Inc.]
+  {"hash":"0825a9da5dd17373","prefixes":{"":{"product":1416}}}, // [R2Net Inc.]
+  {"hash":"aaa00ce722ea0d35","prefixes":{"":{"product":1416}}}, // [R2Net Inc.]
+  {"hash":"40b683cc8c061f6f","prefixes":{"":{"product":1417}}}, // [Madberry OY]
+  {"hash":"ea76804ad8af9b5c","prefixes":{"":{"product":1417}}}, // [Madberry OY]
+  {"hash":"985cce26aeab90d8","prefixes":{"":{"product":1417}}}, // [Madberry OY]
+  {"hash":"d67d98cbb9553a81","prefixes":{"":{"product":1417}}}, // [Madberry OY]
+  {"hash":"ee1c2ae2ffdaa754","prefixes":{"":{"product":1417}}}, // [Madberry OY]
+  {"hash":"8c162379b63896e6","prefixes":{"":{"product":1418}}}, // [QVC]
+  {"hash":"4c23d567b98e413f","prefixes":{"*":{"product":1419}}}, // [Micro Cube Digital Limited]
+  {"hash":"9e74e9e50b7e6116","prefixes":{"":{"product":1420}}}, // [egg.de GmbH]
+  {"hash":"8242efdacea6ca14","prefixes":{"":{"product":1421}}}, // [Headway Mexico]
+  {"hash":"82b90117a5beb869","prefixes":{"":{"product":1422}}}, // [RTBiQ Inc.]
+  {"hash":"7d4bc30e9d495d00","prefixes":{"":{"product":1194}}}, // [Fluidads]
+  {"hash":"44305a81af328854","prefixes":{"":{"product":1194}}}, // [Fluidads]
+  {"hash":"f5d44df23b5b7f0a","prefixes":{"":{"product":1423}}}, // [SCIBIDS TECHNOLOGY S.A.S.]
+  {"hash":"e86f56889ef213b9","prefixes":{"*":{"product":1424}}}, // [Kyocera Communication Systems]
+  {"hash":"e4f3abfdd94fbb95","prefixes":{"":{"product":1425}}}, // [Cortex Media Group]
+  {"hash":"7525243b1d665de2","prefixes":{"":{"product":1426}}}, // [appTV]
+  {"hash":"f27453a19aa2370e","prefixes":{"":{"product":1426}}}, // [appTV]
+  {"hash":"8156979d25af9817","prefixes":{"":{"product":1427}}}, // [ProgSol, Programmatic Solution, s.r.o.]
+  {"hash":"888e465d14dbfeb5","prefixes":{"":{"product":1427}}}, // [ProgSol, Programmatic Solution, s.r.o.]
+  {"hash":"6bcdb8e4cf28b730","prefixes":{"":{"product":1427}}}, // [ProgSol, Programmatic Solution, s.r.o.]
+  {"hash":"cc229228113699d8","prefixes":{"":{"product":1428}}}, // [Rezonence]
+  {"hash":"fd7695df1dfe9f20","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"fbee76565472bc95","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"e53efe28417732fd","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"4f76dc8807a1b25a","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"b7cd9e7666d175e1","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"ba124e354a70dcb2","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"8c9e63d24d4fbe6b","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"ea6157fcb7c5c718","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"6063abef39fb89be","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"8a3b3647f6fae243","prefixes":{"":{"product":1429}}}, // [LKQD Platform]
+  {"hash":"25b652ead7abb3b0","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"ff03eb40846eaa12","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"649ada5375fff936","prefixes":{"":{"product":1059}}}, // [Bidtellect]
+  {"hash":"79b86a55d8f149ef","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"a6e4ebed7d417fec","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"e7a27d73288188b6","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"24028ce468194c75","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"d7f89ed8a6431a69","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"079f75aa60b736a9","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"55ab38530ebcb2e7","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"244a99d8deb4343c","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"02afdba2d61c6d76","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"50fcadafe2e2734b","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"0a5d998860b7968b","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"ff1ef9a23c2bdf51","prefixes":{"":{"product":1430}}}, // [target value GmbH]
+  {"hash":"b7be02479c9268a9","prefixes":{"":{"product":1431}}}, // [Firecracker]
+  {"hash":"2841b43a0e0ddb37","prefixes":{"":{"product":1431}}}, // [Firecracker]
+  {"hash":"ea77ccf69493306c","prefixes":{"":{"product":1431}}}, // [Firecracker]
+  {"hash":"786060a6ba793b32","prefixes":{"":{"product":1431}}}, // [Firecracker]
+  {"hash":"af58243a5817c930","prefixes":{"":{"product":1431}}}, // [Firecracker]
+  {"hash":"b90ffee242259e26","prefixes":{"":{"product":1432}}}, // [MADGIC]
+  {"hash":"037e84a783130203","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"724c85c96cc72a57","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"df235ed188c82f5b","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"df21bf354a2570e1","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"52a9b224dd3e1b02","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"ef749fa483d558a9","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"a6b20df6c2ce3063","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"7e7e73dfe402883c","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"1cafe416eb8d746c","prefixes":{"":{"product":1433}}}, // [Digiseg]
+  {"hash":"45c0ef64ecfb6525","prefixes":{"":{"product":1434}}}, // [Bulbit Inc.]
+  {"hash":"d3710c2900e90f84","prefixes":{"":{"product":1434}}}, // [Bulbit Inc.]
+  {"hash":"fed8a97b9e855887","prefixes":{"":{"product":1435}}}, // [Lost My Name]
+  {"hash":"5c18434d5d721456","prefixes":{"":{"product":1436}}}, // [People Media]
+  {"hash":"fd4a671d34b4c76c","prefixes":{"":{"product":1436}}}, // [People Media]
+  {"hash":"181b385a8ea5a687","prefixes":{"":{"product":1437}}}, // [Platform.io]
+  {"hash":"00393673ca5c1d8a","prefixes":{"":{"product":1437}}}, // [Platform.io]
+  {"hash":"6479d1c5a241da2f","prefixes":{"":{"product":1438}}}, // [Bidspeaker]
+  {"hash":"f30e44d5503f39c4","prefixes":{"":{"product":1439}}}, // [YouGov PLC]
+  {"hash":"4f07a6c89151a2eb","prefixes":{"":{"product":1440}}}, // [SAP SE]
+  {"hash":"519e46f12c141c48","prefixes":{"":{"product":1440}}}, // [SAP SE]
+  {"hash":"413cdfaa8215b8f5","prefixes":{"":{"product":1440}}}, // [SAP SE]
+  {"hash":"dd8e150b503eb12f","prefixes":{"":{"product":1441}}}, // [Adchex]
+  {"hash":"58e19248782ce688","prefixes":{"":{"product":1442}}}, // [Smart Bid Limited]
+  {"hash":"8ccc1dd45e305817","prefixes":{"":{"product":1443}}}, // [UAd Exchange]
+  {"hash":"9543cb4330fa1d6e","prefixes":{"":{"product":1444}}}, // [UAd Exchange - IBV]
+  {"hash":"fc1a7604d6ced7c3","prefixes":{"":{"product":1445}}}, // [esc mediagroup GmbH]
+  {"hash":"90c354743de0b811","prefixes":{"":{"product":1446}}}, // [defacto smart reach GmbH]
+  {"hash":"0d8f41278d702251","prefixes":{"":{"product":1447}}}, // [Research and Analysis of Media in Sweden AB]
+  {"hash":"607c4919b3c8d5cd","prefixes":{"":{"product":1447}}}, // [Research and Analysis of Media in Sweden AB]
+  {"hash":"d0d7647dc2ea9dd9","prefixes":{"":{"product":1448}}}, // [OnAudience.com]
+  {"hash":"3c0c99d90a16804f","prefixes":{"":{"product":1449}}}, // [OneTag]
+  {"hash":"a50e8a4129f160c8","prefixes":{"":{"product":1449}}}, // [OneTag]
+  {"hash":"62105b8204658950","prefixes":{"":{"product":1449}}}, // [OneTag]
+  {"hash":"8069afc9a94b92b9","prefixes":{"*":{"product":1349}}}, // [1trn LLC]
+  {"hash":"c9cc947471099a0e","prefixes":{"":{"product":59}}}, // [Air Berlin]
+  {"hash":"516352d734faa684","prefixes":{"":{"product":1450}}}, // [Fiverr International Ltd.]
+  {"hash":"562a3da1a81ae4ec","prefixes":{"":{"product":1450}}}, // [Fiverr International Ltd.]
+  {"hash":"1ba262fef7c9b94b","prefixes":{"":{"product":1451}}}, // [Adikteev]
+  {"hash":"cd63e73725fa2b8d","prefixes":{"":{"product":1451}}}, // [Adikteev]
+  {"hash":"f24819f2edd93c69","prefixes":{"":{"product":1451}}}, // [Adikteev]
+  {"hash":"e3b1538bced5ec72","prefixes":{"":{"product":1451}}}, // [Adikteev]
+  {"hash":"341df4e708fbbc07","prefixes":{"":{"product":1452}}}, // [CenterPoint Media]
+  {"hash":"1f984187723f0399","prefixes":{"":{"product":1452}}}, // [CenterPoint Media]
+  {"hash":"6ed35b33de5147be","prefixes":{"":{"product":1452}}}, // [CenterPoint Media]
+  {"hash":"d3f04891cabd56f8","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"8429b5e7c7905de9","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"eadb7778a29b9617","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"15595532c38662ea","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"ce365566d66a72ee","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"60ef24e820a6a881","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"176be2434ca2f68b","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"3f72f2b4ec7f816e","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"bcc519027914bd79","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"86628b5f01332c66","prefixes":{"":{"product":1453}}}, // [Digital Trace]
+  {"hash":"1c34c62a587e6c1e","prefixes":{"":{"product":1454}}}, // [Pure Cobalt]
+  {"hash":"a30f9c646772cf0f","prefixes":{"":{"product":60}}}, // [Aegon ESPAÑA, S.A. de Seguros y Reaseguros, Uniper]
+  {"hash":"b23d960b2ea25b51","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"030115e352ac8e99","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"77da2d98a4da970f","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"aa0555e19cf5d6cc","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"badc121e99935aa5","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"115df78aa77ac9c4","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"04713a193ed96cc0","prefixes":{"s":{"product":1455}}}, // [Cedato]
+  {"hash":"fd6fd1f29de71285","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"c5de6239a6efe818","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"4c0be33a1c14428d","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"09eaafed5beae0e1","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"ff987bad618809e7","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"2b50033d06870385","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"8b399204d27d07c0","prefixes":{"s":{"product":1455}}}, // [Cedato]
+  {"hash":"5f78d380fa9514b1","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"c4912c3d8f04b948","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"361fa6df6bb3216e","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"b18ab9dfb513f02b","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"de511a44653105ea","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"f990d873e1622766","prefixes":{"":{"product":1455}}}, // [Cedato]
+  {"hash":"f53618fe52956dbf","prefixes":{"s":{"product":1455}}}, // [Cedato]
+  {"hash":"96ed69252978cab9","prefixes":{"cdn":{"product":1455}}}, // [Cedato]
+  {"hash":"f38b31b7e204355c","prefixes":{"":{"product":943}}}, // [Admetrics GmbH]
+  {"hash":"895a9c8a3b52c95f","prefixes":{"":{"product":943}}}, // [Admetrics GmbH]
+  {"hash":"62ba002fe91498c3","prefixes":{"":{"product":943}}}, // [Admetrics GmbH]
+  {"hash":"30fe524e700bd89f","prefixes":{"":{"product":943}}}, // [Admetrics GmbH]
+  {"hash":"6ce86e7a47d6dfbc","prefixes":{"":{"product":1456}}}, // [Jonsden Properties Limited]
+  {"hash":"8bed3db3f252b657","prefixes":{"":{"product":1457}}}, // [Realytics]
+  {"hash":"c2dcbb4796436e89","prefixes":{"":{"product":1458}}}, // [Twinpine]
+  {"hash":"97a8b5033c272f3c","prefixes":{"":{"product":1458}}}, // [Twinpine]
+  {"hash":"3d39eae9e2370c3e","prefixes":{"":{"product":1459}}}, // [Mopedo AB]
+  {"hash":"38a9bfae76c9b2f1","prefixes":{"*":{"product":1460}}}, // [Netsales]
+  {"hash":"9b1148932500d0b5","prefixes":{"":{"product":1461}}}, // [ViewersLogic LTD]
+  {"hash":"901b2f7c0272451b","prefixes":{"":{"product":1461}}}, // [ViewersLogic LTD]
+  {"hash":"7d45cf386f5c3f27","prefixes":{"":{"product":1462}}}, // [ADMAN]
+  {"hash":"e68e2f7630af032b","prefixes":{"":{"product":1462}}}, // [ADMAN]
+  {"hash":"79dc640f62208944","prefixes":{"":{"product":1462}}}, // [ADMAN]
+  {"hash":"4d6e312d6aba1117","prefixes":{"":{"product":1462}}}, // [ADMAN]
+  {"hash":"29e85c5af35e3751","prefixes":{"":{"product":1462}}}, // [ADMAN]
+  {"hash":"e5f2b6b92cc6daa3","prefixes":{"":{"product":1463}}}, // [Hyper]
+  {"hash":"f867e04c6dde165d","prefixes":{"":{"product":1464}}}, // [Hurra Communications]
+  {"hash":"8353a34ee35ff30c","prefixes":{"":{"product":1464}}}, // [Hurra Communications]
+  {"hash":"cc7f69fa55a7518f","prefixes":{"":{"product":1465}}}, // [Groundhog TW]
+  {"hash":"95ba2d10b1b0675c","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"e8f62a52edbdf4bd","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"321a7e08d4b4fd55","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"c6f272ed0a206999","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"bd34d2733467c1af","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"1b49f6113458dc63","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"58b83e3b3a97943e","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"814bcd9589533387","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"9465fc7c156593f4","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"7c1c219e78b2f270","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"9d376bb5982319b0","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"12ec9a0b2888a4a9","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"f3d7dfcb60972b0c","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"460cac48ec149c6d","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"2614d3ffa05e19a5","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"1f9b770c08378ced","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"054864ff1578657a","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"a5505306000e20f2","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"12cae8bbd22d8673","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"d7724f8a49b96fa6","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"3013078a26f31e2f","prefixes":{"":{"product":1466}}}, // [ImediaMax]
+  {"hash":"80193dea6eb67372","prefixes":{"":{"product":1467}}}, // [Flixbus]
+  {"hash":"02c439b9cc7e33b5","prefixes":{"":{"product":1468}}}, // [AudienceTV]
+  {"hash":"fcb4adbb2bc559e7","prefixes":{"":{"product":1469}}}, // [b34106183_test]
+  {"hash":"b08446a676a287b4","prefixes":{"":{"product":1469}}}, // [b34106183_test]
+  {"hash":"12105a6cc17c32e7","prefixes":{"":{"product":1470}}}, // [Netscore]
+  {"hash":"036d15c3ad4a0735","prefixes":{"":{"product":1470}}}, // [Netscore]
+  {"hash":"c0c40e6f63813be1","prefixes":{"":{"product":1471}}}, // [Chu Technology Limited]
+  {"hash":"4c434a52325c0b6e","prefixes":{"":{"product":1472}}}, // [SmartyAds LLC]
+  {"hash":"825a99c46b61053a","prefixes":{"":{"product":1473}}}, // [dbupdate1]
+  {"hash":"31ab5366866e8622","prefixes":{"":{"product":1473}}}, // [dbupdate1]
+  {"hash":"32a21f3a47cb8ddc","prefixes":{"":{"product":128}}}, // [ConvertMedia Ltd.]
+  {"hash":"44a7af6d373bd713","prefixes":{"":{"product":985}}}, // [Lodeo]
+  {"hash":"36d8680483227de8","prefixes":{"":{"product":985}}}, // [Lodeo]
+  {"hash":"9709c6b69d2e3e90","prefixes":{"":{"product":985}}}, // [Lodeo]
+  {"hash":"5efefb78ec9b146f","prefixes":{"":{"product":1474}}}, // [The Big Willow Inc.]
+  {"hash":"3e5b3c0010f7172f","prefixes":{"":{"product":1475}}}, // [LiveIntent Inc]
+  {"hash":"07bf09263d039040","prefixes":{"":{"product":1476}}}, // [OpenLedger ApS]
+  {"hash":"db879c71876741d0","prefixes":{"":{"product":1477}}}, // [Whichit]
+  {"hash":"4a6caded0a4565d9","prefixes":{"":{"product":1477}}}, // [Whichit]
+  {"hash":"05e0b02a9af28e89","prefixes":{"":{"product":1477}}}, // [Whichit]
+  {"hash":"3aca7ac4649f240c","prefixes":{"":{"product":1477}}}, // [Whichit]
+  {"hash":"81abe9587250fab1","prefixes":{"":{"product":1477}}}, // [Whichit]
+  {"hash":"a3b6bac891e57819","prefixes":{"":{"product":1478}}}, // [ParkDIA]
+  {"hash":"ddc3507bc6f79de4","prefixes":{"":{"product":1479}}}, // [Atedra Inc.]
+  {"hash":"881c2002027de2ec","prefixes":{"":{"product":1479}}}, // [Atedra Inc.]
+  {"hash":"28084881f4e51f6c","prefixes":{"":{"product":1480}}}, // [Digital Forest OÜ]
+  {"hash":"d563745e0fed92f4","prefixes":{"":{"product":1481}}}, // [Isobar Werbeagentur GmbH]
+  {"hash":"d6d13ce525771ba4","prefixes":{"":{"product":1482}}}, // [Valuepotion Pte. Ltd.]
+  {"hash":"446766a73edf76a2","prefixes":{"":{"product":1483}}}, // [Vuble Inc]
+  {"hash":"0753aa310a2a75aa","prefixes":{"":{"product":1484}}}, // [adlocal.net]
+  {"hash":"772284fa4bfb8e5a","prefixes":{"":{"product":1484}}}, // [adlocal.net]
+  {"hash":"0dd444b76d1727ab","prefixes":{"":{"product":1484}}}, // [adlocal.net]
+  {"hash":"1db1fc299e2dc73a","prefixes":{"":{"product":1484}}}, // [adlocal.net]
+  {"hash":"169447ab5f0b2b32","prefixes":{"":{"product":1485}}}, // [Freckle IoT]
+  {"hash":"143b45f2e52d871c","prefixes":{"":{"product":1486}}}, // [Personalization LLC]
+  {"hash":"bdc55693a2c62858","prefixes":{"":{"product":1487}}}, // [ThoughtLeadr Inc.]
+  {"hash":"e69058fe073a8d07","prefixes":{"":{"product":1487}}}, // [ThoughtLeadr Inc.]
+  {"hash":"ded94145085d34ed","prefixes":{"":{"product":1487}}}, // [ThoughtLeadr Inc.]
+  {"hash":"ef66f2e1bb6a3605","prefixes":{"":{"product":1487}}}, // [ThoughtLeadr Inc.]
+  {"hash":"5f62ecd0eec6b82a","prefixes":{"":{"product":1487}}}, // [ThoughtLeadr Inc.]
+  {"hash":"45281cea83398309","prefixes":{"":{"product":1488},"web":{"product":1488},"app":{"product":1488},"cdn":{"product":1488},"api":{"product":1488},"p":{"product":1488},"mobpages":{"product":1488}}}, // [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC]
+  {"hash":"7ea0c7c8484fb7b4","prefixes":{"cdn":{"product":1488}}}, // [Noqoush Mobile Media Group FZ-LLC]
+  {"hash":"6839ebcbc8dce175","prefixes":{"":{"product":1488},"p":{"product":1488}}}, // [Noqoush Mobile Media Group FZ-LLC] [Noqoush Mobile Media Group FZ-LLC]
+  {"hash":"c338016e1aa2a5f7","prefixes":{"":{"product":1489}}}, // [G-Core Labs]
+  {"hash":"3bb879b5ab17cbeb","prefixes":{"":{"product":1490}}}, // [Haensel AMS GmbH]
+  {"hash":"26627407df51f73d","prefixes":{"t":{"product":1490},"d":{"product":1490},"s":{"product":1490}}}, // [Haensel AMS GmbH] [Haensel AMS GmbH] [Haensel AMS GmbH]
+  {"hash":"44e07e9341e20fd0","prefixes":{"":{"product":1491}}}, // [LemonPI]
+  {"hash":"71d7abda3a6093b3","prefixes":{"":{"product":1491}}}, // [LemonPI]
+  {"hash":"f57717e6df039cd1","prefixes":{"":{"product":1491}}}, // [LemonPI]
+  {"hash":"0ae0087cfa7b79c3","prefixes":{"":{"product":1491}}}, // [LemonPI]
+  {"hash":"59afc0d091a22f58","prefixes":{"":{"product":1492}}}, // [4Info, Inc.]
+  {"hash":"fd299e0138ad90c1","prefixes":{"":{"product":1492}}}, // [4Info, Inc.]
+  {"hash":"1e408d2e9033a6e2","prefixes":{"":{"product":1492}}} // [4Info, Inc.]
 ]);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Icon.js b/third_party/WebKit/Source/devtools/front_end/ui/Icon.js
index dfdec25..3492278 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/Icon.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Icon.js
@@ -140,6 +140,7 @@
   'smallicon-triangle-up': {position: 'b1', spritesheet: 'smallicons', isMask: true},
   'smallicon-user-command': {position: 'c1', spritesheet: 'smallicons'},
   'smallicon-warning': {position: 'd1', spritesheet: 'smallicons'},
+  'smallicon-network-product': {position: 'e1', spritesheet: 'smallicons'},
 
   'mediumicon-clear-storage': {position: 'a4', spritesheet: 'mediumicons', isMask: true},
   'mediumicon-cookie': {position: 'b4', spritesheet: 'mediumicons', isMask: true},
diff --git a/third_party/WebKit/Source/devtools/scripts/convert-3pas-product-registry.js b/third_party/WebKit/Source/devtools/scripts/convert-3pas-product-registry.js
index a187664..79d63d3c 100644
--- a/third_party/WebKit/Source/devtools/scripts/convert-3pas-product-registry.js
+++ b/third_party/WebKit/Source/devtools/scripts/convert-3pas-product-registry.js
@@ -1,3 +1,6 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 const fs = require('fs');
 
 /*
@@ -19,6 +22,13 @@
 const b64pad = '='; /* base-64 pad character. "=" for strict RFC compliance   */
 const chrsz = 8;    /* bits per input character. 8 - ASCII; 16 - Unicode      */
 
+const typeClassifications = new Map([
+  ['cdn_provider', 'CDN'], ['cdn_commercial_owner', 'CDN'], ['cdn_creative_agency', 'CDN'], ['ad_blocking', 'Ad'],
+  ['ad_exchange', 'Ad'], ['ad_server_ad_network', 'Ad'], ['ad_server_advertiser', 'Ad'], ['demand_side_platform', 'Ad'],
+  ['vast_provider', 'Ad'], ['data_management_platform', 'Tracking'], ['research_analytics', 'Tracking'],
+  ['research_verification', 'Tracking'], ['research_brand_lift', 'Tracking']
+]);
+
 var data = fs.readFileSync('3pas.csv', 'utf8');
 var headerLine = data.split('\n', 1)[0];
 data = data.substr(headerLine.length);
@@ -114,6 +124,7 @@
 }
 
 var outputProducts = [];
+var outputTypes = [];
 var outputObj = new Map();
 for (var [baseDomain, subdomains] of map) {
   for (var prefixes of subdomains.values()) {
@@ -154,7 +165,7 @@
         outputPart = {hash: hex_sha1(fullSubdomain).substr(0, 16), prefixes: {}};
         outputObj.set(fullSubdomain, outputPart);
       }
-      outputPart.prefixes[lineObj.prefix] = registerOutputProduct(lineObj.name_legal_product);
+      outputPart.prefixes[lineObj.prefix] = registerOutputProduct(lineObj.name_legal_product, lineObj.type_vendor);
     }
   }
 }
@@ -166,6 +177,12 @@
     '// clang-format off\n' +
     '/* eslint-disable */\n' +
     'ProductRegistry.register([');
+if (outputTypes.length) {
+  var data = JSON.stringify(outputTypes).replace(/","/g, '",\n  "');
+  console.log('  ' + data.substring(1, data.length - 1));
+}
+console.log('],');
+console.log('[');
 var data = JSON.stringify(outputProducts).replace(/","/g, '",\n  "');
 console.log('  ' + data.substring(1, data.length - 1));
 console.log('],');
@@ -175,8 +192,14 @@
   var obj = outputObjArray[i];
   var lineEnding = (i === outputObjArray.length - 1) ? '' : ',';
   var comments = [];
-  for (var prefix in obj.prefixes)
-    comments.push('[' + outputProducts[obj.prefixes[prefix]] + ']');
+  for (var prefix in obj.prefixes) {
+    var typeName = outputTypes[obj.prefixes[prefix].type];
+    if (!typeName)
+      typeName = '';
+    else
+      typeName = ':' + typeName;
+    comments.push('[' + outputProducts[obj.prefixes[prefix].product] + typeName + ']');
+  }
   console.log('  ' + JSON.stringify(obj) + lineEnding + ' // ' + comments.join(' '));
 }
 console.log(']);');
@@ -189,11 +212,27 @@
 
 
 // Linear but meh.
-function registerOutputProduct(name) {
+function registerOutputProduct(name, type) {
   var index = outputProducts.indexOf(name);
+  var typeIndex = registerOutputType(type);
+  var outObj = {product: index};
   if (index === -1) {
     outputProducts.push(name);
-    return outputProducts.length - 1;
+    outObj.product = outputProducts.length - 1;
+  }
+  if (typeIndex !== -1)
+    outObj.type = typeIndex;
+  return outObj;
+}
+
+function registerOutputType(type) {
+  var name = typeClassifications.get(type);
+  if (!name)
+    return -1;
+  var index = outputTypes.indexOf(name);
+  if (index === -1) {
+    outputTypes.push(name);
+    return outputTypes.length - 1;
   }
   return index;
 }
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index 44ccdb3c..bbeb7d5 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -1122,7 +1122,7 @@
   }
   if (image_source->IsCanvasElement()) {
     HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(image_source);
-    if (canvas->IsAnimated2D()) {
+    if (canvas->IsAnimated2d()) {
       *reason = kDisableDeferralReasonDrawImageOfAnimated2dCanvas;
       return true;
     }
diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
index 42a7867..9d9c5f2 100644
--- a/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
+++ b/third_party/WebKit/Source/modules/indexeddb/IDBTransaction.cpp
@@ -195,7 +195,7 @@
 
 IDBObjectStore* IDBTransaction::objectStore(const String& name,
                                             ExceptionState& exception_state) {
-  if (IsFinished()) {
+  if (IsFinished() || IsFinishing()) {
     exception_state.ThrowDOMException(
         kInvalidStateError, IDBDatabase::kTransactionFinishedErrorMessage);
     return nullptr;
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
index 46f1f6f..1dcaab2e 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -529,7 +529,9 @@
 bool MediaControlsImpl::ShouldHideMediaControls(unsigned behavior_flags) const {
   // Never hide for a media element without visual representation.
   if (!MediaElement().IsHTMLVideoElement() || !MediaElement().HasVideo() ||
-      MediaElement().IsPlayingRemotely()) {
+      MediaElement().IsPlayingRemotely() ||
+      toHTMLVideoElement(MediaElement()).GetMediaRemotingStatus() ==
+          HTMLVideoElement::MediaRemotingStatus::kStarted) {
     return false;
   }
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index 4a8e117a..bfbd9ea 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -4982,7 +4982,7 @@
     GLint xoffset,
     GLint yoffset,
     const IntRect& source_sub_rectangle) {
-  if (!canvas->Is3D()) {
+  if (!canvas->Is3d()) {
     ImageBuffer* buffer = canvas->Buffer();
     if (buffer &&
         !buffer->CopyToPlatformTexture(
diff --git a/third_party/WebKit/Source/platform/ThemeTypes.h b/third_party/WebKit/Source/platform/ThemeTypes.h
index 73060c81..65d01139 100644
--- a/third_party/WebKit/Source/platform/ThemeTypes.h
+++ b/third_party/WebKit/Source/platform/ThemeTypes.h
@@ -78,6 +78,7 @@
   kMediaSubtitlesIconPart,
   kMediaOverflowMenuButtonPart,
   kMediaDownloadIconPart,
+  kMediaRemotingCastIconPart,
   kMenulistPart,
   kMenulistButtonPart,
   kMenulistTextPart,
diff --git a/third_party/WebKit/Source/platform/geometry/TransformState.cpp b/third_party/WebKit/Source/platform/geometry/TransformState.cpp
index a80b4af..1bdc814 100644
--- a/third_party/WebKit/Source/platform/geometry/TransformState.cpp
+++ b/third_party/WebKit/Source/platform/geometry/TransformState.cpp
@@ -49,12 +49,13 @@
 }
 
 void TransformState::TranslateTransform(const LayoutSize& offset) {
-  if (direction_ == kApplyTransformDirection)
-    accumulated_transform_->TranslateRight(offset.Width().ToDouble(),
-                                           offset.Height().ToDouble());
-  else
+  if (direction_ == kApplyTransformDirection) {
+    accumulated_transform_->PostTranslate(offset.Width().ToDouble(),
+                                          offset.Height().ToDouble());
+  } else {
     accumulated_transform_->Translate(offset.Width().ToDouble(),
                                       offset.Height().ToDouble());
+  }
 }
 
 void TransformState::TranslateMappedCoordinates(const LayoutSize& offset) {
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
index e4bbc8d5..e0b6a388 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
@@ -5,6 +5,7 @@
 #include "platform/graphics/gpu/SharedGpuContext.h"
 
 #include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/capabilities.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/WaitableEvent.h"
 #include "platform/WebTaskRunner.h"
@@ -127,4 +128,12 @@
              ->GetGraphicsResetStatusKHR() == GL_NO_ERROR;
 }
 
+bool SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() {
+  if (!IsValid())
+    return kNoSharedContext;
+  SharedGpuContext* this_ptr = GetInstanceForCurrentThread();
+  return this_ptr->context_provider_->GetCapabilities()
+      .software_to_accelerated_canvas_upgrade;
+}
+
 }  // blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h
index cbd4fe9..d773626a 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.h
@@ -34,6 +34,9 @@
   Gl();                    // May re-create context if context was lost
   static GrContext* Gr();  // May re-create context if context was lost
   static bool IsValid();   // May re-create context if context was lost
+  // May re-create context if context was lost
+  static bool AllowSoftwareToAcceleratedCanvasUpgrade();
+
   static bool IsValidWithoutRestoring();
   typedef std::function<std::unique_ptr<WebGraphicsContext3DProvider>()>
       ContextProviderFactory;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp
index a215a535..75f9fdd2 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.cpp
@@ -23,12 +23,11 @@
   list->AppendClipPathItem(clip_path_, true);
 }
 
-int BeginClipPathDisplayItem::NumberOfSlowPaths() const {
+void BeginClipPathDisplayItem::AnalyzeForGpuRasterization(
+    SkPictureGpuAnalyzer& analyzer) const {
   // Temporarily disabled (pref regressions due to GPU veto stickiness:
   // http://crbug.com/603969).
   // analyzer.analyzeClipPath(m_clipPath, SkRegion::kIntersect_Op, true);
-  // TODO(enne): fixup this code to return an int.
-  return 0;
 }
 
 void EndClipPathDisplayItem::Replay(GraphicsContext& context) const {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
index 3952c87..42434ae 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
@@ -24,7 +24,7 @@
   void AppendToWebDisplayItemList(const IntRect&,
                                   WebDisplayItemList*) const override;
 
-  int NumberOfSlowPaths() const override;
+  void AnalyzeForGpuRasterization(SkPictureGpuAnalyzer&) const override;
 
  private:
 #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
index 7eac3491..cdcd8fd 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
@@ -29,8 +29,58 @@
 CompositingRecorder::~CompositingRecorder() {
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
     return;
-  graphics_context_.GetPaintController().EndItem<EndCompositingDisplayItem>(
-      client_);
+  // If the end of the current display list is of the form
+  // [BeginCompositingDisplayItem] [DrawingDisplayItem], then fold the
+  // BeginCompositingDisplayItem into a new DrawingDisplayItem that replaces
+  // them both. This allows Skia to optimize for the case when the
+  // BeginCompositingDisplayItem represents a simple opacity/color that can be
+  // merged into the opacity/color of the drawing. See crbug.com/628831 for more
+  // details.
+  PaintController& paint_controller = graphics_context_.GetPaintController();
+  const DisplayItem* last_display_item = paint_controller.LastDisplayItem(0);
+  const DisplayItem* second_to_last_display_item =
+      paint_controller.LastDisplayItem(1);
+  // TODO(chrishtr): remove the call to LastDisplayItemIsSubsequenceEnd when
+  // https://codereview.chromium.org/2768143002 lands.
+  if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && last_display_item &&
+      second_to_last_display_item && last_display_item->DrawsContent() &&
+      second_to_last_display_item->GetType() ==
+          DisplayItem::kBeginCompositing &&
+      !paint_controller.LastDisplayItemIsSubsequenceEnd()) {
+    FloatRect cull_rect(
+        ((DrawingDisplayItem*)last_display_item)->GetPaintRecord()->cullRect());
+    const DisplayItemClient& display_item_client = last_display_item->Client();
+    DisplayItem::Type display_item_type = last_display_item->GetType();
+
+    // Re-record the last two DisplayItems into a new drawing. The new item
+    // cannot be cached, because it is a mutation of the DisplayItem the client
+    // thought it was painting.
+    paint_controller.BeginSkippingCache();
+    {
+#if DCHECK_IS_ON()
+      // In the recorder's scope we remove the last two display items which
+      // are combined into a new drawing.
+      DisableListModificationCheck disabler;
+#endif
+      DrawingRecorder new_recorder(graphics_context_, display_item_client,
+                                   display_item_type, cull_rect);
+      DCHECK(!DrawingRecorder::UseCachedDrawingIfPossible(
+          graphics_context_, display_item_client, display_item_type));
+
+      second_to_last_display_item->Replay(graphics_context_);
+      last_display_item->Replay(graphics_context_);
+      EndCompositingDisplayItem(client_).Replay(graphics_context_);
+
+      // Remove the DrawingDisplayItem.
+      paint_controller.RemoveLastDisplayItem();
+      // Remove the BeginCompositingDisplayItem.
+      paint_controller.RemoveLastDisplayItem();
+    }
+    paint_controller.EndSkippingCache();
+  } else {
+    graphics_context_.GetPaintController().EndItem<EndCompositingDisplayItem>(
+        client_);
+  }
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
index d5f344e6..a9afcd1 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
@@ -17,6 +17,8 @@
 #include "platform/wtf/text/WTFString.h"
 #endif
 
+class SkPictureGpuAnalyzer;
+
 namespace blink {
 
 class GraphicsContext;
@@ -335,7 +337,7 @@
   virtual bool DrawsContent() const { return false; }
 
   // Override to implement specific analysis strategies.
-  virtual int NumberOfSlowPaths() const { return 0; }
+  virtual void AnalyzeForGpuRasterization(SkPictureGpuAnalyzer&) const {}
 
 #ifndef NDEBUG
   static WTF::String TypeAsDebugString(DisplayItem::Type);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
index 4fe7853..474a7d12 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
@@ -7,6 +7,7 @@
 #include "platform/graphics/LoggingCanvas.h"
 #include "platform/graphics/paint/DrawingDisplayItem.h"
 #include "platform/graphics/paint/PaintChunk.h"
+#include "third_party/skia/include/core/SkPictureAnalyzer.h"
 
 #ifndef NDEBUG
 #include "platform/wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
index 7c14717..2a17f3d 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.cpp
@@ -10,6 +10,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkData.h"
+#include "third_party/skia/include/core/SkPictureAnalyzer.h"
 
 namespace blink {
 
@@ -29,8 +30,14 @@
   return record_.get();
 }
 
-int DrawingDisplayItem::NumberOfSlowPaths() const {
-  return record_ ? record_->numSlowPaths() : 0;
+void DrawingDisplayItem::AnalyzeForGpuRasterization(
+    SkPictureGpuAnalyzer& analyzer) const {
+  // TODO(enne): Need an SkPictureGpuAnalyzer on PictureRecord.
+  // This is a bit overkill to ToSkPicture a record just to get
+  // numSlowPaths.
+  if (!record_)
+    return;
+  analyzer.analyzePicture(ToSkPicture(record_).get());
 }
 
 #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h
index 3dedbcbd..e5f989f8 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingDisplayItem.h
@@ -41,7 +41,7 @@
     return known_to_be_opaque_;
   }
 
-  int NumberOfSlowPaths() const override;
+  void AnalyzeForGpuRasterization(SkPictureGpuAnalyzer&) const override;
 
  private:
 #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index d3b7553..e26681df 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -16,8 +16,6 @@
 #include <stdio.h>
 #endif
 
-static constexpr int kMaxNumberOfSlowPathsBeforeVeto = 5;
-
 namespace blink {
 
 void PaintController::SetTracksRasterInvalidations(bool value) {
@@ -537,7 +535,7 @@
       !new_display_item_list_.IsEmpty())
     GenerateChunkRasterInvalidationRects(new_paint_chunks_.LastChunk());
 
-  int num_slow_paths = 0;
+  SkPictureGpuAnalyzer gpu_analyzer;
 
   current_cache_generation_ =
       DisplayItemClient::CacheGenerationOrInvalidationReason::Next();
@@ -556,8 +554,8 @@
   Vector<const DisplayItemClient*> skipped_cache_clients;
   for (const auto& item : new_display_item_list_) {
     // No reason to continue the analysis once we have a veto.
-    if (num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto)
-      num_slow_paths += item.NumberOfSlowPaths();
+    if (gpu_analyzer.suitableForGpuRasterization())
+      item.AnalyzeForGpuRasterization(gpu_analyzer);
 
     // TODO(wkorman): Only compute and append visual rect for drawings.
     new_display_item_list_.AppendVisualRect(
@@ -595,7 +593,7 @@
   new_display_item_list_.ShrinkToFit();
   current_paint_artifact_ = PaintArtifact(
       std::move(new_display_item_list_), new_paint_chunks_.ReleasePaintChunks(),
-      num_slow_paths <= kMaxNumberOfSlowPathsBeforeVeto);
+      gpu_analyzer.suitableForGpuRasterization());
   ResetCurrentListIndices();
   out_of_order_item_indices_.Clear();
   out_of_order_chunk_indices_.Clear();
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index 038f0bd..f5f45cc8 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -2273,6 +2273,40 @@
     DisplayItemClient::EndShouldKeepAliveAllClients();
 #endif
   }
+
+  void TestFoldCompositingDrawingInSubsequence() {
+    FakeDisplayItemClient container("container");
+    FakeDisplayItemClient content("content");
+    GraphicsContext context(GetPaintController());
+
+    {
+      SubsequenceRecorder subsequence(context, container);
+      CompositingRecorder compositing(context, content, SkBlendMode::kSrc, 0.5);
+      DrawRect(context, content, kBackgroundDrawingType,
+               FloatRect(100, 100, 300, 300));
+    }
+    GetPaintController().CommitNewDisplayItems();
+    EXPECT_EQ(
+        1u,
+        GetPaintController().GetPaintArtifact().GetDisplayItemList().size());
+
+    {
+      EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
+          context, container));
+      SubsequenceRecorder subsequence(context, container);
+      CompositingRecorder compositing(context, content, SkBlendMode::kSrc, 0.5);
+      DrawRect(context, content, kBackgroundDrawingType,
+               FloatRect(100, 100, 300, 300));
+    }
+    GetPaintController().CommitNewDisplayItems();
+    EXPECT_EQ(
+        1u,
+        GetPaintController().GetPaintArtifact().GetDisplayItemList().size());
+
+#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+    DisplayItemClient::EndShouldKeepAliveAllClients();
+#endif
+  }
 };
 
 TEST_F(PaintControllerUnderInvalidationTest, ChangeDrawing) {
@@ -2329,6 +2363,11 @@
   TestInvalidationInSubsequence();
 }
 
+TEST_F(PaintControllerUnderInvalidationTest,
+       FoldCompositingDrawingInSubsequence) {
+  TestFoldCompositingDrawingInSubsequence();
+}
+
 #endif  // defined(GTEST_HAS_DEATH_TEST) && !OS(ANDROID)
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm b/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm
index e3eada5..6379d6a 100644
--- a/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm
+++ b/third_party/WebKit/Source/platform/mac/LocalCurrentGraphicsContext.mm
@@ -24,7 +24,6 @@
 #include "platform/graphics/paint/PaintCanvas.h"
 #include "platform/mac/ThemeMac.h"
 #include "platform_canvas.h"
-#include "third_party/skia/include/core/SkRegion.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp
index d8c1da9..d6eeed0 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp
+++ b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.cpp
@@ -72,19 +72,6 @@
 // to be held responsible. Basically, don't be a jerk, and remember that
 // anything free comes with no guarantee.
 
-// A clarification about the storage of matrix elements
-//
-// This class uses a 2 dimensional array internally to store the elements of the
-// matrix.  The first index into the array refers to the column that the element
-// lies in; the second index refers to the row.
-//
-// In other words, this is the layout of the matrix:
-//
-// | matrix_[0][0] matrix_[1][0] matrix_[2][0] matrix_[3][0] |
-// | matrix_[0][1] matrix_[1][1] matrix_[2][1] matrix_[3][1] |
-// | matrix_[0][2] matrix_[1][2] matrix_[2][2] matrix_[3][2] |
-// | matrix_[0][3] matrix_[1][3] matrix_[2][3] matrix_[3][3] |
-
 typedef double Vector4[4];
 typedef double Vector3[3];
 
@@ -1203,8 +1190,8 @@
   return *this;
 }
 
-TransformationMatrix& TransformationMatrix::TranslateRight(double tx,
-                                                           double ty) {
+TransformationMatrix& TransformationMatrix::PostTranslate(double tx,
+                                                          double ty) {
   if (tx != 0) {
     matrix_[0][0] += matrix_[0][3] * tx;
     matrix_[1][0] += matrix_[1][3] * tx;
@@ -1222,10 +1209,10 @@
   return *this;
 }
 
-TransformationMatrix& TransformationMatrix::TranslateRight3d(double tx,
-                                                             double ty,
-                                                             double tz) {
-  TranslateRight(tx, ty);
+TransformationMatrix& TransformationMatrix::PostTranslate3d(double tx,
+                                                            double ty,
+                                                            double tz) {
+  PostTranslate(tx, ty);
   if (tz != 0) {
     matrix_[0][2] += matrix_[0][3] * tz;
     matrix_[1][2] += matrix_[1][3] * tz;
@@ -1262,7 +1249,7 @@
 TransformationMatrix& TransformationMatrix::ApplyTransformOrigin(double x,
                                                                  double y,
                                                                  double z) {
-  TranslateRight3d(x, y, z);
+  PostTranslate3d(x, y, z);
   Translate3d(-x, -y, -z);
   return *this;
 }
@@ -1278,32 +1265,37 @@
 }
 
 // Calculates *this = *this * mat.
-// Note: A * B means that the transforms represented by A happen first, and
-// then the transforms represented by B. That is, the matrix A * B corresponds
-// to a CSS transform list <transform-function-A> <transform-function-B>.
-// Some branches of this function may make use of the fact that
-// transpose(A * B) == transpose(B) * transpose(A); remember that
-// matrix_[a][b] is matrix element row b, col a.
-// FIXME: As of 2016-05-04, the ARM64 branch is NOT triggered by tests on the CQ
-// bots, see crbug.com/477892 and crbug.com/584508.
+// Note: As we are using the column vector convention, i.e. T * P,
+// (lhs * rhs) * P = lhs * (rhs * P)
+// That means from the perspective of the transformed object, the combined
+// transform is equal to applying the rhs(mat) first, then lhs(*this) second.
+// For example:
+// TransformationMatrix lhs; lhs.Rotate(90.f);
+// TransformationMatrix rhs; rhs.Translate(12.f, 34.f);
+// TransformationMatrix prod = lhs;
+// prod.Multiply(rhs);
+// lhs.MapPoint(rhs.MapPoint(p)) == prod.MapPoint(p)
+// Also 'prod' corresponds to CSS transform:rotateZ(90deg)translate(12px,34px).
+// TODO(crbug.com/584508): As of 2017-04-11, the ARM64 CQ bots skip
+// blink_platform_unittests, therefore the ARM64 branch is not tested by CQ.
 TransformationMatrix& TransformationMatrix::Multiply(
     const TransformationMatrix& mat) {
 #if CPU(ARM64)
-  double* right_matrix = &(matrix_[0][0]);
-  const double* left_matrix = &(mat.matrix_[0][0]);
+  double* left_matrix = &(matrix_[0][0]);
+  const double* right_matrix = &(mat.matrix_[0][0]);
   asm volatile(
+      // Load this->matrix_ to v24 - v31.
       // Load mat.matrix_ to v16 - v23.
-      // Load this.matrix_ to v24 - v31.
-      // Result: this = mat * this
-      // | v0, v1 |   | v16, v17 |   | v24, v25 |
-      // | v2, v3 | = | v18, v19 | * | v26, v27 |
-      // | v4, v5 |   | v20, v21 |   | v28, v29 |
-      // | v6, v7 |   | v22, v23 |   | v30, v31 |
-      "mov x9, %[right_matrix]   \t\n"
-      "ld1 {v16.2d - v19.2d}, [%[left_matrix]], 64  \t\n"
-      "ld1 {v20.2d - v23.2d}, [%[left_matrix]]      \t\n"
-      "ld1 {v24.2d - v27.2d}, [%[right_matrix]], 64 \t\n"
-      "ld1 {v28.2d - v31.2d}, [%[right_matrix]]     \t\n"
+      // Result: *this = *this * mat
+      // | v0 v2 v4 v6 |   | v24 v26 v28 v30 |   | v16 v18 v20 v22 |
+      // |             | = |                 | * |                 |
+      // | v1 v3 v5 v7 |   | v25 v27 v29 v31 |   | v17 v19 v21 v23 |
+      // |             |   |                 |   |                 |
+      "mov x9, %[left_matrix]   \t\n"
+      "ld1 {v16.2d - v19.2d}, [%[right_matrix]], 64  \t\n"
+      "ld1 {v20.2d - v23.2d}, [%[right_matrix]]      \t\n"
+      "ld1 {v24.2d - v27.2d}, [%[left_matrix]], 64 \t\n"
+      "ld1 {v28.2d - v31.2d}, [%[left_matrix]]     \t\n"
 
       "fmul v0.2d, v24.2d, v16.d[0]  \t\n"
       "fmul v1.2d, v25.2d, v16.d[0]  \t\n"
@@ -1343,95 +1335,95 @@
 
       "st1 {v0.2d - v3.2d}, [x9], 64 \t\n"
       "st1 {v4.2d - v7.2d}, [x9]     \t\n"
-      : [left_matrix] "+r"(left_matrix), [right_matrix] "+r"(right_matrix)
+      : [right_matrix] "+r"(right_matrix), [left_matrix] "+r"(left_matrix)
       :
       : "memory", "x9", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
         "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "v0", "v1",
         "v2", "v3", "v4", "v5", "v6", "v7");
 #elif HAVE(MIPS_MSA_INTRINSICS)
-  v2f64 v_left_m0, v_left_m1, v_left_m2, v_left_m3, v_left_m4, v_left_m5,
-      v_left_m6, v_left_m7;
   v2f64 v_right_m0, v_right_m1, v_right_m2, v_right_m3, v_right_m4, v_right_m5,
       v_right_m6, v_right_m7;
+  v2f64 v_left_m0, v_left_m1, v_left_m2, v_left_m3, v_left_m4, v_left_m5,
+      v_left_m6, v_left_m7;
   v2f64 v_tmp_m0, v_tmp_m1, v_tmp_m2, v_tmp_m3;
 
-  v_right_m0 = LD_DP(&(matrix_[0][0]));
-  v_right_m1 = LD_DP(&(matrix_[0][2]));
-  v_right_m2 = LD_DP(&(matrix_[1][0]));
-  v_right_m3 = LD_DP(&(matrix_[1][2]));
-  v_right_m4 = LD_DP(&(matrix_[2][0]));
-  v_right_m5 = LD_DP(&(matrix_[2][2]));
-  v_right_m6 = LD_DP(&(matrix_[3][0]));
-  v_right_m7 = LD_DP(&(matrix_[3][2]));
+  v_left_m0 = LD_DP(&(matrix_[0][0]));
+  v_left_m1 = LD_DP(&(matrix_[0][2]));
+  v_left_m2 = LD_DP(&(matrix_[1][0]));
+  v_left_m3 = LD_DP(&(matrix_[1][2]));
+  v_left_m4 = LD_DP(&(matrix_[2][0]));
+  v_left_m5 = LD_DP(&(matrix_[2][2]));
+  v_left_m6 = LD_DP(&(matrix_[3][0]));
+  v_left_m7 = LD_DP(&(matrix_[3][2]));
 
-  v_left_m0 = LD_DP(&(mat.matrix_[0][0]));
-  v_left_m2 = LD_DP(&(mat.matrix_[0][2]));
-  v_left_m4 = LD_DP(&(mat.matrix_[1][0]));
-  v_left_m6 = LD_DP(&(mat.matrix_[1][2]));
+  v_right_m0 = LD_DP(&(mat.matrix_[0][0]));
+  v_right_m2 = LD_DP(&(mat.matrix_[0][2]));
+  v_right_m4 = LD_DP(&(mat.matrix_[1][0]));
+  v_right_m6 = LD_DP(&(mat.matrix_[1][2]));
 
-  v_left_m1 = (v2f64)__msa_splati_d((v2i64)v_left_m0, 1);
-  v_left_m0 = (v2f64)__msa_splati_d((v2i64)v_left_m0, 0);
-  v_left_m3 = (v2f64)__msa_splati_d((v2i64)v_left_m2, 1);
-  v_left_m2 = (v2f64)__msa_splati_d((v2i64)v_left_m2, 0);
-  v_left_m5 = (v2f64)__msa_splati_d((v2i64)v_left_m4, 1);
-  v_left_m4 = (v2f64)__msa_splati_d((v2i64)v_left_m4, 0);
-  v_left_m7 = (v2f64)__msa_splati_d((v2i64)v_left_m6, 1);
-  v_left_m6 = (v2f64)__msa_splati_d((v2i64)v_left_m6, 0);
+  v_right_m1 = (v2f64)__msa_splati_d((v2i64)v_right_m0, 1);
+  v_right_m0 = (v2f64)__msa_splati_d((v2i64)v_right_m0, 0);
+  v_right_m3 = (v2f64)__msa_splati_d((v2i64)v_right_m2, 1);
+  v_right_m2 = (v2f64)__msa_splati_d((v2i64)v_right_m2, 0);
+  v_right_m5 = (v2f64)__msa_splati_d((v2i64)v_right_m4, 1);
+  v_right_m4 = (v2f64)__msa_splati_d((v2i64)v_right_m4, 0);
+  v_right_m7 = (v2f64)__msa_splati_d((v2i64)v_right_m6, 1);
+  v_right_m6 = (v2f64)__msa_splati_d((v2i64)v_right_m6, 0);
 
-  v_tmp_m0 = v_left_m0 * v_right_m0;
-  v_tmp_m1 = v_left_m0 * v_right_m1;
-  v_tmp_m0 += v_left_m1 * v_right_m2;
-  v_tmp_m1 += v_left_m1 * v_right_m3;
-  v_tmp_m0 += v_left_m2 * v_right_m4;
-  v_tmp_m1 += v_left_m2 * v_right_m5;
-  v_tmp_m0 += v_left_m3 * v_right_m6;
-  v_tmp_m1 += v_left_m3 * v_right_m7;
+  v_tmp_m0 = v_right_m0 * v_left_m0;
+  v_tmp_m1 = v_right_m0 * v_left_m1;
+  v_tmp_m0 += v_right_m1 * v_left_m2;
+  v_tmp_m1 += v_right_m1 * v_left_m3;
+  v_tmp_m0 += v_right_m2 * v_left_m4;
+  v_tmp_m1 += v_right_m2 * v_left_m5;
+  v_tmp_m0 += v_right_m3 * v_left_m6;
+  v_tmp_m1 += v_right_m3 * v_left_m7;
 
-  v_tmp_m2 = v_left_m4 * v_right_m0;
-  v_tmp_m3 = v_left_m4 * v_right_m1;
-  v_tmp_m2 += v_left_m5 * v_right_m2;
-  v_tmp_m3 += v_left_m5 * v_right_m3;
-  v_tmp_m2 += v_left_m6 * v_right_m4;
-  v_tmp_m3 += v_left_m6 * v_right_m5;
-  v_tmp_m2 += v_left_m7 * v_right_m6;
-  v_tmp_m3 += v_left_m7 * v_right_m7;
+  v_tmp_m2 = v_right_m4 * v_left_m0;
+  v_tmp_m3 = v_right_m4 * v_left_m1;
+  v_tmp_m2 += v_right_m5 * v_left_m2;
+  v_tmp_m3 += v_right_m5 * v_left_m3;
+  v_tmp_m2 += v_right_m6 * v_left_m4;
+  v_tmp_m3 += v_right_m6 * v_left_m5;
+  v_tmp_m2 += v_right_m7 * v_left_m6;
+  v_tmp_m3 += v_right_m7 * v_left_m7;
 
-  v_left_m0 = LD_DP(&(mat.matrix_[2][0]));
-  v_left_m2 = LD_DP(&(mat.matrix_[2][2]));
-  v_left_m4 = LD_DP(&(mat.matrix_[3][0]));
-  v_left_m6 = LD_DP(&(mat.matrix_[3][2]));
+  v_right_m0 = LD_DP(&(mat.matrix_[2][0]));
+  v_right_m2 = LD_DP(&(mat.matrix_[2][2]));
+  v_right_m4 = LD_DP(&(mat.matrix_[3][0]));
+  v_right_m6 = LD_DP(&(mat.matrix_[3][2]));
 
   ST_DP(v_tmp_m0, &(matrix_[0][0]));
   ST_DP(v_tmp_m1, &(matrix_[0][2]));
   ST_DP(v_tmp_m2, &(matrix_[1][0]));
   ST_DP(v_tmp_m3, &(matrix_[1][2]));
 
-  v_left_m1 = (v2f64)__msa_splati_d((v2i64)v_left_m0, 1);
-  v_left_m0 = (v2f64)__msa_splati_d((v2i64)v_left_m0, 0);
-  v_left_m3 = (v2f64)__msa_splati_d((v2i64)v_left_m2, 1);
-  v_left_m2 = (v2f64)__msa_splati_d((v2i64)v_left_m2, 0);
-  v_left_m5 = (v2f64)__msa_splati_d((v2i64)v_left_m4, 1);
-  v_left_m4 = (v2f64)__msa_splati_d((v2i64)v_left_m4, 0);
-  v_left_m7 = (v2f64)__msa_splati_d((v2i64)v_left_m6, 1);
-  v_left_m6 = (v2f64)__msa_splati_d((v2i64)v_left_m6, 0);
+  v_right_m1 = (v2f64)__msa_splati_d((v2i64)v_right_m0, 1);
+  v_right_m0 = (v2f64)__msa_splati_d((v2i64)v_right_m0, 0);
+  v_right_m3 = (v2f64)__msa_splati_d((v2i64)v_right_m2, 1);
+  v_right_m2 = (v2f64)__msa_splati_d((v2i64)v_right_m2, 0);
+  v_right_m5 = (v2f64)__msa_splati_d((v2i64)v_right_m4, 1);
+  v_right_m4 = (v2f64)__msa_splati_d((v2i64)v_right_m4, 0);
+  v_right_m7 = (v2f64)__msa_splati_d((v2i64)v_right_m6, 1);
+  v_right_m6 = (v2f64)__msa_splati_d((v2i64)v_right_m6, 0);
 
-  v_tmp_m0 = v_left_m0 * v_right_m0;
-  v_tmp_m1 = v_left_m0 * v_right_m1;
-  v_tmp_m0 += v_left_m1 * v_right_m2;
-  v_tmp_m1 += v_left_m1 * v_right_m3;
-  v_tmp_m0 += v_left_m2 * v_right_m4;
-  v_tmp_m1 += v_left_m2 * v_right_m5;
-  v_tmp_m0 += v_left_m3 * v_right_m6;
-  v_tmp_m1 += v_left_m3 * v_right_m7;
+  v_tmp_m0 = v_right_m0 * v_left_m0;
+  v_tmp_m1 = v_right_m0 * v_left_m1;
+  v_tmp_m0 += v_right_m1 * v_left_m2;
+  v_tmp_m1 += v_right_m1 * v_left_m3;
+  v_tmp_m0 += v_right_m2 * v_left_m4;
+  v_tmp_m1 += v_right_m2 * v_left_m5;
+  v_tmp_m0 += v_right_m3 * v_left_m6;
+  v_tmp_m1 += v_right_m3 * v_left_m7;
 
-  v_tmp_m2 = v_left_m4 * v_right_m0;
-  v_tmp_m3 = v_left_m4 * v_right_m1;
-  v_tmp_m2 += v_left_m5 * v_right_m2;
-  v_tmp_m3 += v_left_m5 * v_right_m3;
-  v_tmp_m2 += v_left_m6 * v_right_m4;
-  v_tmp_m3 += v_left_m6 * v_right_m5;
-  v_tmp_m2 += v_left_m7 * v_right_m6;
-  v_tmp_m3 += v_left_m7 * v_right_m7;
+  v_tmp_m2 = v_right_m4 * v_left_m0;
+  v_tmp_m3 = v_right_m4 * v_left_m1;
+  v_tmp_m2 += v_right_m5 * v_left_m2;
+  v_tmp_m3 += v_right_m5 * v_left_m3;
+  v_tmp_m2 += v_right_m6 * v_left_m4;
+  v_tmp_m3 += v_right_m6 * v_left_m5;
+  v_tmp_m2 += v_right_m7 * v_left_m6;
+  v_tmp_m3 += v_right_m7 * v_left_m7;
 
   ST_DP(v_tmp_m0, &(matrix_[2][0]));
   ST_DP(v_tmp_m1, &(matrix_[2][2]));
@@ -1445,7 +1437,7 @@
   __m128d matrix_block_e = _mm_load_pd(&(matrix_[2][0]));
   __m128d matrix_block_g = _mm_load_pd(&(matrix_[3][0]));
 
-  // First row.
+  // First column.
   __m128d other_matrix_first_param = _mm_set1_pd(mat.matrix_[0][0]);
   __m128d other_matrix_second_param = _mm_set1_pd(mat.matrix_[0][1]);
   __m128d other_matrix_third_param = _mm_set1_pd(mat.matrix_[0][2]);
@@ -1478,7 +1470,7 @@
   accumulator = _mm_add_pd(accumulator, temp3);
   _mm_store_pd(&matrix_[0][2], accumulator);
 
-  // Second row.
+  // Second column.
   other_matrix_first_param = _mm_set1_pd(mat.matrix_[1][0]);
   other_matrix_second_param = _mm_set1_pd(mat.matrix_[1][1]);
   other_matrix_third_param = _mm_set1_pd(mat.matrix_[1][2]);
@@ -1506,7 +1498,7 @@
   accumulator = _mm_add_pd(accumulator, temp3);
   _mm_store_pd(&matrix_[1][2], accumulator);
 
-  // Third row.
+  // Third column.
   other_matrix_first_param = _mm_set1_pd(mat.matrix_[2][0]);
   other_matrix_second_param = _mm_set1_pd(mat.matrix_[2][1]);
   other_matrix_third_param = _mm_set1_pd(mat.matrix_[2][2]);
@@ -1534,7 +1526,7 @@
   accumulator = _mm_add_pd(accumulator, temp3);
   _mm_store_pd(&matrix_[2][2], accumulator);
 
-  // Fourth row.
+  // Fourth column.
   other_matrix_first_param = _mm_set1_pd(mat.matrix_[3][0]);
   other_matrix_second_param = _mm_set1_pd(mat.matrix_[3][1]);
   other_matrix_third_param = _mm_set1_pd(mat.matrix_[3][2]);
diff --git a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h
index 54377d98..76e3e94 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h
+++ b/third_party/WebKit/Source/platform/transforms/TransformationMatrix.h
@@ -50,13 +50,26 @@
 #define TRANSFORMATION_MATRIX_USE_X86_64_SSE2
 #endif
 
-// TransformationMatrix must not be allocated on Oilpan's heap since
-// Oilpan doesn't (yet) have an ability to allocate the TransformationMatrix
-// with 16-byte alignment. PartitionAlloc has the ability.
 class PLATFORM_EXPORT TransformationMatrix {
+  // TransformationMatrix must not be allocated on Oilpan's heap since
+  // Oilpan doesn't (yet) have an ability to allocate the TransformationMatrix
+  // with 16-byte alignment. PartitionAlloc has the ability.
   USING_FAST_MALLOC(TransformationMatrix);
 
  public:
+// Throughout this class, we will be speaking in column vector convention.
+// i.e. Applying a transform T to point P is T * P.
+// The elements of the matrix and the vector looks like:
+// | scale_x  skew_y_x skew_z_x translate_x |   | x |
+// | skew_x_y scale_y  skew_z_y translate_y | * | y |
+// | skew_x_z skew_y_z scale_z  translate_z |   | z |
+// | persp_x  persp_y  persp_z  persp_w     |   | w |
+// Internally the matrix is stored as a 2-dimensional array in col-major order.
+// In other words, this is the layout of the matrix:
+// | matrix_[0][0] matrix_[1][0] matrix_[2][0] matrix_[3][0] |
+// | matrix_[0][1] matrix_[1][1] matrix_[2][1] matrix_[3][1] |
+// | matrix_[0][2] matrix_[1][2] matrix_[2][2] matrix_[3][2] |
+// | matrix_[0][3] matrix_[1][3] matrix_[2][3] matrix_[3][3] |
 #if defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2)
   typedef WTF_ALIGNED(double, Matrix4[4][4], 16);
 #else
@@ -252,6 +265,11 @@
 
   void TransformBox(FloatBox&) const;
 
+  // Important: These indices are spoken in col-major order. i.e.:
+  // | M11() M21() M31() M41() |
+  // | M12() M22() M32() M42() |
+  // | M13() M23() M33() M43() |
+  // | M14() M24() M34() M44() |
   double M11() const { return matrix_[0][0]; }
   void SetM11(double f) { matrix_[0][0] = f; }
   double M12() const { return matrix_[0][1]; }
@@ -322,9 +340,12 @@
   TransformationMatrix& Translate(double tx, double ty);
   TransformationMatrix& Translate3d(double tx, double ty, double tz);
 
-  // translation added with a post-multiply
-  TransformationMatrix& TranslateRight(double tx, double ty);
-  TransformationMatrix& TranslateRight3d(double tx, double ty, double tz);
+  // Append translation after existing operations. i.e.
+  // TransformationMatrix t2 = t1;
+  // t2.PostTranslate(x, y);
+  // t2.MapPoint(p) == t1.MapPoint(p) + FloatPoint(x, y)
+  TransformationMatrix& PostTranslate(double tx, double ty);
+  TransformationMatrix& PostTranslate3d(double tx, double ty, double tz);
 
   TransformationMatrix& Skew(double angle_x, double angle_y);
   TransformationMatrix& SkewX(double angle) { return Skew(angle, 0); }
diff --git a/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp b/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp
index a896126..97ea309 100644
--- a/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp
+++ b/third_party/WebKit/Source/platform/transforms/TransformationMatrixTest.cpp
@@ -94,6 +94,162 @@
   EXPECT_EQ(expected_atimes_b, a);
 }
 
+TEST(TransformationMatrixTest, BasicOperations) {
+  // Just some arbitrary matrix that introduces no rounding, and is unlikely
+  // to commute with other operations.
+  TransformationMatrix m(2.f, 3.f, 5.f, 0.f, 7.f, 11.f, 13.f, 0.f, 17.f, 19.f,
+                         23.f, 0.f, 29.f, 31.f, 37.f, 1.f);
+
+  FloatPoint3D p(41.f, 43.f, 47.f);
+
+  EXPECT_EQ(FloatPoint3D(1211.f, 1520.f, 1882.f), m.MapPoint(p));
+
+  {
+    TransformationMatrix n;
+    n.Scale(2.f);
+    EXPECT_EQ(FloatPoint3D(82.f, 86.f, 47.f), n.MapPoint(p));
+
+    TransformationMatrix mn = m;
+    mn.Scale(2.f);
+    EXPECT_EQ(mn.MapPoint(p), m.MapPoint(n.MapPoint(p)));
+  }
+
+  {
+    TransformationMatrix n;
+    n.ScaleNonUniform(2.f, 3.f);
+    EXPECT_EQ(FloatPoint3D(82.f, 129.f, 47.f), n.MapPoint(p));
+
+    TransformationMatrix mn = m;
+    mn.ScaleNonUniform(2.f, 3.f);
+    EXPECT_EQ(mn.MapPoint(p), m.MapPoint(n.MapPoint(p)));
+  }
+
+  {
+    TransformationMatrix n;
+    n.Scale3d(2.f, 3.f, 4.f);
+    EXPECT_EQ(FloatPoint3D(82.f, 129.f, 188.f), n.MapPoint(p));
+
+    TransformationMatrix mn = m;
+    mn.Scale3d(2.f, 3.f, 4.f);
+    EXPECT_EQ(mn.MapPoint(p), m.MapPoint(n.MapPoint(p)));
+  }
+
+  {
+    TransformationMatrix n;
+    n.Rotate(90.f);
+    EXPECT_FLOAT_EQ(0.f,
+                    (FloatPoint3D(-43.f, 41.f, 47.f) - n.MapPoint(p)).length());
+
+    TransformationMatrix mn = m;
+    mn.Rotate(90.f);
+    EXPECT_FLOAT_EQ(0.f, (mn.MapPoint(p) - m.MapPoint(n.MapPoint(p))).length());
+  }
+
+  {
+    TransformationMatrix n;
+    n.Rotate3d(10.f, 10.f, 10.f, 120.f);
+    EXPECT_FLOAT_EQ(0.f,
+                    (FloatPoint3D(47.f, 41.f, 43.f) - n.MapPoint(p)).length());
+
+    TransformationMatrix mn = m;
+    mn.Rotate3d(10.f, 10.f, 10.f, 120.f);
+    EXPECT_FLOAT_EQ(0.f, (mn.MapPoint(p) - m.MapPoint(n.MapPoint(p))).length());
+  }
+
+  {
+    TransformationMatrix n;
+    n.Translate(5.f, 6.f);
+    EXPECT_EQ(FloatPoint3D(46.f, 49.f, 47.f), n.MapPoint(p));
+
+    TransformationMatrix mn = m;
+    mn.Translate(5.f, 6.f);
+    EXPECT_EQ(mn.MapPoint(p), m.MapPoint(n.MapPoint(p)));
+  }
+
+  {
+    TransformationMatrix n;
+    n.Translate3d(5.f, 6.f, 7.f);
+    EXPECT_EQ(FloatPoint3D(46.f, 49.f, 54.f), n.MapPoint(p));
+
+    TransformationMatrix mn = m;
+    mn.Translate3d(5.f, 6.f, 7.f);
+    EXPECT_EQ(mn.MapPoint(p), m.MapPoint(n.MapPoint(p)));
+  }
+
+  {
+    TransformationMatrix nm = m;
+    nm.PostTranslate(5.f, 6.f);
+    EXPECT_EQ(nm.MapPoint(p), m.MapPoint(p) + FloatPoint3D(5.f, 6.f, 0.f));
+  }
+
+  {
+    TransformationMatrix nm = m;
+    nm.PostTranslate3d(5.f, 6.f, 7.f);
+    EXPECT_EQ(nm.MapPoint(p), m.MapPoint(p) + FloatPoint3D(5.f, 6.f, 7.f));
+  }
+
+  {
+    TransformationMatrix n;
+    n.Skew(45.f, -45.f);
+    EXPECT_FLOAT_EQ(0.f,
+                    (FloatPoint3D(84.f, 2.f, 47.f) - n.MapPoint(p)).length());
+
+    TransformationMatrix mn = m;
+    mn.Skew(45.f, -45.f);
+    EXPECT_FLOAT_EQ(0.f, (mn.MapPoint(p) - m.MapPoint(n.MapPoint(p))).length());
+  }
+
+  {
+    TransformationMatrix n;
+    n.SkewX(45.f);
+    EXPECT_FLOAT_EQ(0.f,
+                    (FloatPoint3D(84.f, 43.f, 47.f) - n.MapPoint(p)).length());
+
+    TransformationMatrix mn = m;
+    mn.SkewX(45.f);
+    EXPECT_FLOAT_EQ(0.f, (mn.MapPoint(p) - m.MapPoint(n.MapPoint(p))).length());
+  }
+
+  {
+    TransformationMatrix n;
+    n.SkewY(45.f);
+    EXPECT_FLOAT_EQ(0.f,
+                    (FloatPoint3D(41.f, 84.f, 47.f) - n.MapPoint(p)).length());
+
+    TransformationMatrix mn = m;
+    mn.SkewY(45.f);
+    EXPECT_FLOAT_EQ(0.f, (mn.MapPoint(p) - m.MapPoint(n.MapPoint(p))).length());
+  }
+
+  {
+    TransformationMatrix n;
+    n.ApplyPerspective(94.f);
+    EXPECT_FLOAT_EQ(0.f,
+                    (FloatPoint3D(82.f, 86.f, 94.f) - n.MapPoint(p)).length());
+
+    TransformationMatrix mn = m;
+    mn.ApplyPerspective(94.f);
+    EXPECT_FLOAT_EQ(0.f, (mn.MapPoint(p) - m.MapPoint(n.MapPoint(p))).length());
+  }
+
+  {
+    FloatPoint3D origin(5.f, 6.f, 7.f);
+    TransformationMatrix n = m;
+    n.ApplyTransformOrigin(origin);
+    EXPECT_EQ(m.MapPoint(p - origin) + origin, n.MapPoint(p));
+  }
+
+  {
+    TransformationMatrix n = m;
+    n.Zoom(2.f);
+    FloatPoint3D expectation = p;
+    expectation.Scale(0.5f, 0.5f, 0.5f);
+    expectation = m.MapPoint(expectation);
+    expectation.Scale(2.f, 2.f, 2.f);
+    EXPECT_EQ(expectation, n.MapPoint(p));
+  }
+}
+
 TEST(TransformationMatrixTest, ToString) {
   TransformationMatrix zeros(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
   EXPECT_EQ("[0,0,0,0,\n0,0,0,0,\n0,0,0,0,\n0,0,0,0] (degenerate)",
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
index 18452fb..49eee785 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git.py
@@ -66,57 +66,61 @@
         self.checkout_root = self.find_checkout_root(self.cwd)
 
     def _init_executable_name(self):
-        # FIXME: This is a hack and should be removed.
+        """Sets the executable name on Windows.
+
+        The Win port uses the depot_tools package, which contains a number
+        of development tools, including Python and git. Instead of using a
+        real git executable, depot_tools indirects via a batch file, called
+        "git.bat". This batch file is used because it allows depot_tools to
+        auto-update the real git executable, which is contained in a
+        subdirectory.
+
+        FIXME: This is a hack and should be resolved in a different way if
+        possible.
+        """
         try:
             self._executive.run_command(['git', 'help'])
         except OSError:
             try:
                 self._executive.run_command(['git.bat', 'help'])
-                # The Win port uses the depot_tools package, which contains a number
-                # of development tools, including Python and git. Instead of using a
-                # real git executable, depot_tools indirects via a batch file, called
-                # "git.bat". This batch file allows depot_tools to auto-update the real
-                # git executable, which is contained in a subdirectory.
                 _log.debug('Engaging git.bat Windows hack.')
                 self.executable_name = 'git.bat'
             except OSError:
                 _log.debug('Failed to engage git.bat Windows hack.')
 
-    def _run_git(self,
-                 command_args,
-                 cwd=None,
-                 input=None,  # pylint: disable=redefined-builtin
-                 timeout_seconds=None,
-                 decode_output=True,
-                 return_exit_code=False):
+    def run(self, command_args, cwd=None, stdin=None, decode_output=True, return_exit_code=False):
+        """Invokes git with the given args."""
         full_command_args = [self.executable_name] + command_args
         cwd = cwd or self.checkout_root
         return self._executive.run_command(
             full_command_args,
             cwd=cwd,
-            input=input,
-            timeout_seconds=timeout_seconds,
+            input=stdin,
             return_exit_code=return_exit_code,
             decode_output=decode_output)
 
-    # SCM always returns repository relative path, but sometimes we need
-    # absolute paths to pass to rm, etc.
     def absolute_path(self, repository_relative_path):
+        """Converts repository-relative paths to absolute paths."""
         return self._filesystem.join(self.checkout_root, repository_relative_path)
 
     @classmethod
     def in_working_directory(cls, path, executive=None):
         try:
             executive = executive or Executive()
-            return executive.run_command([cls.executable_name, 'rev-parse', '--is-inside-work-tree'],
-                                         cwd=path, error_handler=Executive.ignore_error).rstrip() == 'true'
+            return executive.run_command(
+                [cls.executable_name, 'rev-parse', '--is-inside-work-tree'],
+                cwd=path, error_handler=Executive.ignore_error).rstrip() == 'true'
         except OSError:
-            # The Windows bots seem to through a WindowsError when git isn't installed.
+            # The Windows bots seem to throw a WindowsError when git isn't installed.
+            # TODO(qyearsley): This might be because the git executable name
+            # isn't initialized yet; maybe this would be fixed by using the
+            # _init_executable_name hack above.
+            _log.warn('Got OSError when running Git.in_working_directory.')
             return False
 
     def find_checkout_root(self, path):
         # "git rev-parse --show-cdup" would be another way to get to the root
-        checkout_root = self._run_git(['rev-parse', '--show-toplevel'], cwd=(path or './')).strip()
+        checkout_root = self.run(['rev-parse', '--show-toplevel'], cwd=(path or './')).strip()
         if not self._filesystem.isabs(checkout_root):  # Sometimes git returns relative paths
             checkout_root = self._filesystem.join(path, checkout_root)
         return checkout_root
@@ -132,10 +136,7 @@
             [cls.executable_name, 'config', '--get-all', key], error_handler=Executive.ignore_error, cwd=cwd).rstrip('\n')
 
     def _discard_local_commits(self):
-        self._run_git(['reset', '--hard', self._remote_branch_ref()])
-
-    def _local_commits(self, ref='HEAD'):
-        return self._run_git(['log', '--pretty=oneline', ref + '...' + self._remote_branch_ref()]).splitlines()
+        self.run(['reset', '--hard', self._remote_branch_ref()])
 
     def _rebase_in_progress(self):
         return self._filesystem.exists(self.absolute_path(self._filesystem.join('.git', 'rebase-apply')))
@@ -145,14 +146,14 @@
         command = ['diff', 'HEAD', '--no-renames', '--name-only']
         if pathspec:
             command.extend(['--', pathspec])
-        return self._run_git(command) != ''
+        return self.run(command) != ''
 
     def _discard_working_directory_changes(self):
-        # Could run git clean here too, but that wouldn't match subversion
-        self._run_git(['reset', 'HEAD', '--hard'])
-        # Aborting rebase even though this does not match subversion
+        # TODO(qyearsley): Could run git clean here too; this wasn't done
+        # before in order to match svn, but this is no longer a concern.
+        self.run(['reset', 'HEAD', '--hard'])
         if self._rebase_in_progress():
-            self._run_git(['rebase', '--abort'])
+            self.run(['rebase', '--abort'])
 
     def unstaged_changes(self):
         """Lists files with unstaged changes, including untracked files.
@@ -163,7 +164,7 @@
         """
         # `git status -z` is a version of `git status -s`, that's recommended
         # for machine parsing. Lines are terminated with NUL rather than LF.
-        change_lines = self._run_git(['status', '-z', '--untracked-files=all']).rstrip('\x00')
+        change_lines = self.run(['status', '-z', '--untracked-files=all']).rstrip('\x00')
         if not change_lines:
             return {}  # No changes.
         unstaged_changes = {}
@@ -176,16 +177,16 @@
         return unstaged_changes
 
     def add_list(self, paths, return_exit_code=False):
-        return self._run_git(['add'] + paths, return_exit_code=return_exit_code)
+        return self.run(['add'] + paths, return_exit_code=return_exit_code)
 
     def delete_list(self, paths):
-        return self._run_git(['rm', '-f'] + paths)
+        return self.run(['rm', '-f'] + paths)
 
     def move(self, origin, destination):
-        return self._run_git(['mv', '-f', origin, destination])
+        return self.run(['mv', '-f', origin, destination])
 
     def exists(self, path):
-        return_code = self._run_git(['show', 'HEAD:%s' % path], return_exit_code=True, decode_output=False)
+        return_code = self.run(['show', 'HEAD:%s' % path], return_exit_code=True, decode_output=False)
         return return_code != self.ERROR_FILE_IS_MISSING
 
     def _branch_from_ref(self, ref):
@@ -193,7 +194,7 @@
 
     def current_branch(self):
         """Returns the name of the current branch, or empty string if HEAD is detached."""
-        ref = self._run_git(['rev-parse', '--symbolic-full-name', 'HEAD']).strip()
+        ref = self.run(['rev-parse', '--symbolic-full-name', 'HEAD']).strip()
         if ref == 'HEAD':
             # HEAD is detached; return an empty string.
             return ''
@@ -204,7 +205,7 @@
         branch_name = self.current_branch()
         if not branch_name:
             # HEAD is detached; use commit SHA instead.
-            return self._run_git(['rev-parse', 'HEAD']).strip()
+            return self.run(['rev-parse', 'HEAD']).strip()
         return branch_name
 
     def _upstream_branch(self):
@@ -244,7 +245,7 @@
     def _run_status_and_extract_filenames(self, status_command, status_regexp):
         filenames = []
         # We run with cwd=self.checkout_root so that returned-paths are root-relative.
-        for line in self._run_git(status_command, cwd=self.checkout_root).splitlines():
+        for line in self.run(status_command, cwd=self.checkout_root).splitlines():
             match = re.search(status_regexp, line)
             if not match:
                 continue
@@ -263,6 +264,7 @@
 
     @staticmethod
     def supports_local_commits():
+        # TODO(qyearsley): Remove this.
         return True
 
     def display_name(self):
@@ -271,7 +273,7 @@
     def most_recent_log_matching(self, grep_str, path):
         # We use '--grep=' + foo rather than '--grep', foo because
         # git 1.7.0.4 (and earlier) didn't support the separate arg.
-        return self._run_git(['log', '-1', '--grep=' + grep_str, '--date=iso', self.find_checkout_root(path)])
+        return self.run(['log', '-1', '--grep=' + grep_str, '--date=iso', self.find_checkout_root(path)])
 
     def _commit_position_from_git_log(self, git_log):
         match = re.search(r"^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+)\}", git_log, re.MULTILINE)
@@ -305,6 +307,7 @@
 
     def create_patch(self, git_commit=None, changed_files=None):
         """Returns a byte array (str()) representing the patch file.
+
         Patch files are effectively binary since they may contain
         files of multiple different encodings.
         """
@@ -325,7 +328,7 @@
         command += [self._merge_base(git_commit), '--']
         if changed_files:
             command += changed_files
-        return self._run_git(command, decode_output=False, cwd=self.checkout_root)
+        return self.run(command, decode_output=False, cwd=self.checkout_root)
 
     def _patch_order(self):
         # Put code changes at the top of the patch and layout tests
@@ -342,24 +345,24 @@
         return self._commit_position_from_git_log(git_log)
 
     def checkout_branch(self, name):
-        self._run_git(['checkout', '-q', name])
+        self.run(['checkout', '-q', name])
 
     def create_clean_branch(self, name):
-        self._run_git(['checkout', '-q', '-b', name, self._remote_branch_ref()])
+        self.run(['checkout', '-q', '-b', name, self._remote_branch_ref()])
 
     def blame(self, path):
-        return self._run_git(['blame', '--show-email', path])
+        return self.run(['blame', '--show-email', path])
 
     # Git-specific methods:
     def _branch_ref_exists(self, branch_ref):
-        return self._run_git(['show-ref', '--quiet', '--verify', branch_ref], return_exit_code=True) == 0
+        return self.run(['show-ref', '--quiet', '--verify', branch_ref], return_exit_code=True) == 0
 
     def delete_branch(self, branch_name):
         if self._branch_ref_exists('refs/heads/' + branch_name):
-            self._run_git(['branch', '-D', branch_name])
+            self.run(['branch', '-D', branch_name])
 
     def _remote_merge_base(self):
-        return self._run_git(['merge-base', self._remote_branch_ref(), 'HEAD']).strip()
+        return self.run(['merge-base', self._remote_branch_ref(), 'HEAD']).strip()
 
     def _remote_branch_ref(self):
         # Use references so that we can avoid collisions, e.g. we don't want to operate on refs/heads/trunk if it exists.
@@ -370,45 +373,33 @@
 
     def commit_locally_with_message(self, message):
         command = ['commit', '--all', '-F', '-']
-        self._run_git(command, input=message)
-
-    def pull(self, timeout_seconds=None):
-        self._run_git(['pull'], timeout_seconds=timeout_seconds)
+        self.run(command, stdin=message)
 
     def latest_git_commit(self):
-        return self._run_git(['log', '-1', '--format=%H']).strip()
+        return self.run(['log', '-1', '--format=%H']).strip()
 
     def git_commits_since(self, commit):
-        return self._run_git(['log', commit + '..master', '--format=%H', '--reverse']).split()
+        return self.run(['log', commit + '..master', '--format=%H', '--reverse']).split()
 
     def git_commit_detail(self, commit, format=None):  # pylint: disable=redefined-builtin
         args = ['log', '-1', commit]
         if format:
             args.append('--format=' + format)
-        return self._run_git(args)
+        return self.run(args)
 
     def affected_files(self, commit):
-        output = self._run_git(['log', '-1', '--format=', '--name-only', commit])
+        output = self.run(['log', '-1', '--format=', '--name-only', commit])
         return output.strip().split('\n')
 
     def _branch_tracking_remote_master(self):
-        origin_info = self._run_git(['remote', 'show', 'origin', '-n'])
+        origin_info = self.run(['remote', 'show', 'origin', '-n'])
         match = re.search(r"^\s*(?P<branch_name>\S+)\s+merges with remote master$", origin_info, re.MULTILINE)
         if not match:
             raise ScriptError(message='Unable to find local branch tracking origin/master.')
         branch = str(match.group('branch_name'))
-        return self._branch_from_ref(self._run_git(['rev-parse', '--symbolic-full-name', branch]).strip())
-
-    def is_cleanly_tracking_remote_master(self):
-        if self.has_working_directory_changes():
-            return False
-        if self.current_branch() != self._branch_tracking_remote_master():
-            return False
-        if len(self._local_commits(self._branch_tracking_remote_master())) > 0:
-            return False
-        return True
+        return self._branch_from_ref(self.run(['rev-parse', '--symbolic-full-name', branch]).strip())
 
     def ensure_cleanly_tracking_remote_master(self):
         self._discard_working_directory_changes()
-        self._run_git(['checkout', '-q', self._branch_tracking_remote_master()])
+        self.run(['checkout', '-q', self._branch_tracking_remote_master()])
         self._discard_local_commits()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_unittest.py
index 07f4895..87ce53c 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/git_unittest.py
@@ -198,8 +198,7 @@
     def _assert_timestamp_of_revision(self, canned_git_output, expected):
         git = self.make_git()
         git.find_checkout_root = lambda path: ''
-        # Modifying protected method. pylint: disable=protected-access
-        git._run_git = lambda args: canned_git_output
+        git.run = lambda args: canned_git_output
         self.assertEqual(git.timestamp_of_revision('some-path', '12345'), expected)
 
     def test_timestamp_of_revision_utc(self):
@@ -222,8 +221,7 @@
             'M  d/modified-staged.txt',
             'A  d/added-staged.txt',
         ]
-        # pylint: disable=protected-access
-        git._run_git = lambda args: '\x00'.join(status_lines) + '\x00'
+        git.run = lambda args: '\x00'.join(status_lines) + '\x00'
         self.assertEqual(
             git.unstaged_changes(),
             {
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py
index eeef1f69..7ef8fd40 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py
@@ -77,8 +77,6 @@
             return 1
 
         if builders_with_no_results and not options.fill_missing:
-            # TODO(qyearsley): Support trying to continue as long as there are
-            # some results from some builder; see http://crbug.com/673966.
             _log.error('The following builders have no results:')
             for builder in builders_with_no_results:
                 _log.error('  %s', builder)
@@ -86,13 +84,15 @@
 
         _log.debug('Getting results for issue %d.', issue_number)
         builds_to_results = self._fetch_results(builds)
-        if builds_to_results is None:
+        if not options.fill_missing and len(builds_to_results) < len(builds):
             return 1
 
         test_baseline_set = TestBaselineSet(tool)
         if args:
             for test in args:
                 for build in builds:
+                    if not builds_to_results.get(build):
+                        continue
                     test_baseline_set.add(test, build)
         else:
             test_baseline_set = self._make_test_baseline_set(
@@ -160,10 +160,10 @@
             results_url = buildbot.results_url(build.builder_name, build.build_number)
             layout_test_results = buildbot.fetch_results(build)
             if layout_test_results is None:
-                _log.error('Failed to fetch results for: %s', build)
-                _log.error('Results were expected to exist at:\n%s/results.html', results_url)
-                _log.error('If the job failed, you could retry by running:\ngit cl try -b %s', build.builder_name)
-                return None
+                _log.info('Failed to fetch results for %s', build)
+                _log.info('Results URL: %s/results.html', results_url)
+                _log.info('Retry job by running: git cl try -b %s', build.builder_name)
+                continue
             results[build] = layout_test_results
         return results
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py
index 7a205dd6d..0a4de89 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py
@@ -324,11 +324,24 @@
         return_code = self.command.execute(self.command_options(), [], self.tool)
         self.assertEqual(return_code, 1)
         self.assertLog([
-            'ERROR: Failed to fetch results for: Build(builder_name=\'MOCK Try Win\', build_number=5000)\n',
-            'ERROR: Results were expected to exist at:\n'
-            'https://storage.googleapis.com/chromium-layout-test-archives/MOCK_Try_Win/5000/layout-test-results/results.html\n',
-            'ERROR: If the job failed, you could retry by running:\n'
-            'git cl try -b MOCK Try Win\n'
+            'INFO: Failed to fetch results for Build(builder_name=\'MOCK Try Win\', build_number=5000)\n',
+            'INFO: Results URL: https://storage.googleapis.com/chromium-layout-test-archives'
+            '/MOCK_Try_Win/5000/layout-test-results/results.html\n',
+            'INFO: Retry job by running: git cl try -b MOCK Try Win\n'
+        ])
+
+    def test_continues_with_missing_results_when_filling_results(self):
+        self.tool.buildbot.set_results(Build('MOCK Try Win', 5000), None)
+        return_code = self.command.execute(self.command_options(fill_missing=True), ['fast/dom/prototype-taco.html'], self.tool)
+        self.assertEqual(return_code, 0)
+        self.assertLog([
+            'INFO: Failed to fetch results for Build(builder_name=\'MOCK Try Win\', build_number=5000)\n',
+            'INFO: Results URL: https://storage.googleapis.com/chromium-layout-test-archives'
+            '/MOCK_Try_Win/5000/layout-test-results/results.html\n',
+            'INFO: Retry job by running: git cl try -b MOCK Try Win\n',
+            'INFO: For fast/dom/prototype-taco.html:\n',
+            'INFO: Using Build(builder_name=\'MOCK Try Mac\', build_number=4000) to supply results for test-win-win7.\n',
+            'INFO: Rebaselining fast/dom/prototype-taco.html\n'
         ])
 
     def test_bails_when_there_are_unstaged_baselines(self):
diff --git a/third_party/WebKit/public/blink_image_resources.grd b/third_party/WebKit/public/blink_image_resources.grd
index adcb7f4f..16f6574 100644
--- a/third_party/WebKit/public/blink_image_resources.grd
+++ b/third_party/WebKit/public/blink_image_resources.grd
@@ -25,6 +25,8 @@
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_OVERLAY_CAST_BUTTON_OFF" file="blink/mediaplayer_overlay_cast_off.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_OVERLAY_CAST_BUTTON_ON" file="blink/mediaplayer_overlay_cast_on.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON" file="blink/mediaplayer_overlay_play.png" />
+      <structure type="chrome_scaled_image" name="IDR_MEDIA_REMOTING_CAST_ICON"
+      file="blink/mediaremoting_cast.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_TRACKSELECTION_CHECKMARK" file="blink/mediaplayer_trackselection_checkmark.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_CLOSEDCAPTIONS_ICON" file="blink/mediaplayer_closedcaptions_icon.png" />
       <structure type="chrome_scaled_image" name="IDR_MEDIAPLAYER_OVERFLOW_MENU_ICON" file="blink/mediaplayer_overflow_menu.png" />
diff --git a/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png b/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png
new file mode 100644
index 0000000..6188c7af
--- /dev/null
+++ b/third_party/WebKit/public/default_100_percent/blink/mediaremoting_cast.png
Binary files differ
diff --git a/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png b/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png
new file mode 100644
index 0000000..377c4e4
--- /dev/null
+++ b/third_party/WebKit/public/default_200_percent/blink/mediaremoting_cast.png
Binary files differ
diff --git a/third_party/WebKit/public/platform/WebLocalizedString.h b/third_party/WebKit/public/platform/WebLocalizedString.h
index 25cbf453..9ae231a 100644
--- a/third_party/WebKit/public/platform/WebLocalizedString.h
+++ b/third_party/WebKit/public/platform/WebLocalizedString.h
@@ -104,6 +104,8 @@
     kFileButtonChooseMultipleFilesLabel,
     kFileButtonNoFileSelectedLabel,
     kInputElementAltText,
+    kMediaRemotingDisableText,
+    kMediaRemotingCastText,
     kMissingPluginText,
     kMultipleFileUploadText,
     kOtherColorLabel,
diff --git a/third_party/WebKit/public/platform/WebMediaPlayerClient.h b/third_party/WebKit/public/platform/WebMediaPlayerClient.h
index 301fad67..35d5db5 100644
--- a/third_party/WebKit/public/platform/WebMediaPlayerClient.h
+++ b/third_party/WebKit/public/platform/WebMediaPlayerClient.h
@@ -116,6 +116,10 @@
   // Returns the selected video track id (or an empty id if there's none).
   virtual WebMediaPlayer::TrackId GetSelectedVideoTrackId() = 0;
 
+  // Informs that media starts/stops being rendered and played back remotely.
+  virtual void MediaRemotingStarted() {}
+  virtual void MediaRemotingStopped() {}
+
  protected:
   ~WebMediaPlayerClient() {}
 };
diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp
index d65f1769..e38e522a 100644
--- a/third_party/closure_compiler/compiled_resources2.gyp
+++ b/third_party/closure_compiler/compiled_resources2.gyp
@@ -33,7 +33,6 @@
         '<(DEPTH)/chrome/browser/resources/offline_pages/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/settings/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/uber/compiled_resources2.gyp:*',
-        '<(DEPTH)/chrome/browser/resources/vr_shell/compiled_resources2.gyp:*',
         '<(DEPTH)/chrome/browser/resources/webapks/compiled_resources2.gyp:*',
         '<(DEPTH)/ui/file_manager/compiled_resources2.gyp:*',
         '<(DEPTH)/ui/webui/resources/cr_elements/compiled_resources2.gyp:*',
diff --git a/tools/grit/grit/testdata/substitute_tmpl.grd b/tools/grit/grit/testdata/substitute_tmpl.grd
new file mode 100644
index 0000000..be7b6017
--- /dev/null
+++ b/tools/grit/grit/testdata/substitute_tmpl.grd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
+<grit
+    base_dir="."
+    source_lang_id="en"
+    tc_project="GoogleDesktopWindowsClient"
+    latest_public_release="0"
+    current_release="1"
+    enc_check="möl">
+  <outputs>
+    <output filename="resource.h" type="rc_header" />
+    <output filename="en_${name}_resources.rc" type="rc_all" lang="en" />
+    <output filename="sv_${name}_resources.rc" type="rc_all" lang="sv" />
+  </outputs>
+  <translations>
+    <file path="substitute.xmb" lang="sv" />
+  </translations>
+  <release seq="1" allow_pseudo="false">
+    <messages first_id="8192">
+      <message name="IDS_COPYRIGHT_GOOGLE_LONG" sub_variable="true" desc="Gadget copyright notice.  Needs to be updated every year.">
+        Copyright 2008 Google Inc. All Rights Reserved.
+      </message>
+      <message name="IDS_NEWS_PANEL_COPYRIGHT">
+        Google Desktop News gadget
+[IDS_COPYRIGHT_GOOGLE_LONG]
+View news that is personalized based on the articles you read.
+
+For example, if you read lots of sports news, you'll see more sports articles. If you read technology news less often, you'll see fewer of those articles.
+      </message>
+    </messages>
+  </release>
+</grit>
diff --git a/tools/grit/grit/tool/build.py b/tools/grit/grit/tool/build.py
index cab2b37..d2c9ff16 100755
--- a/tools/grit/grit/tool/build.py
+++ b/tools/grit/grit/tool/build.py
@@ -352,7 +352,7 @@
     else:
       for output in self.res.GetOutputFiles():
         output.output_filename = os.path.abspath(os.path.join(
-          self.output_directory, output.GetFilename()))
+          self.output_directory, output.GetOutputFilename()))
 
     # If there are whitelisted names, tag the tree once up front, this way
     # while looping through the actual output, it is just an attribute check.
@@ -360,7 +360,7 @@
       self.AddWhitelistTags(self.res, self.whitelist_names)
 
     for output in self.res.GetOutputFiles():
-      self.VerboseOut('Creating %s...' % output.GetFilename())
+      self.VerboseOut('Creating %s...' % output.GetOutputFilename())
 
       # Microsoft's RC compiler can only deal with single-byte or double-byte
       # files (no UTF-8), so we make all RC files UTF-16 to support all
@@ -451,7 +451,8 @@
     # Compare the absolute path names, sorted.
     asserted = sorted([os.path.abspath(i) for i in assert_output_files])
     actual = sorted([
-        os.path.abspath(os.path.join(self.output_directory, i.GetFilename()))
+        os.path.abspath(os.path.join(self.output_directory,
+                                     i.GetOutputFilename()))
         for i in self.res.GetOutputFiles()])
 
     if asserted != actual:
@@ -519,7 +520,7 @@
       # Get the first output file relative to the depdir.
       outputs = self.res.GetOutputFiles()
       output_file = os.path.join(self.output_directory,
-                                 outputs[0].GetFilename())
+                                 outputs[0].GetOutputFilename())
 
     output_file = os.path.relpath(output_file, depdir)
     # The path prefix to prepend to dependencies in the depfile.
diff --git a/tools/grit/grit/tool/build_unittest.py b/tools/grit/grit/tool/build_unittest.py
index 952eff9..1750bfc 100755
--- a/tools/grit/grit/tool/build_unittest.py
+++ b/tools/grit/grit/tool/build_unittest.py
@@ -114,6 +114,36 @@
             '-a', os.path.abspath(
                 os.path.join(output_dir, 'resource.h'))]))
 
+  def testAssertTemplateOutputs(self):
+    output_dir = tempfile.mkdtemp()
+    class DummyOpts(object):
+      def __init__(self):
+        self.input = util.PathFromRoot('grit/testdata/substitute_tmpl.grd')
+        self.verbose = False
+        self.extra_verbose = False
+
+    # Incomplete output file list should fail.
+    builder_fail = build.RcBuilder()
+    self.failUnlessEqual(2,
+        builder_fail.Run(DummyOpts(), [
+            '-o', output_dir,
+            '-E', 'name=foo',
+            '-a', os.path.abspath(
+                os.path.join(output_dir, 'en_foo_resources.rc'))]))
+
+    # Complete output file list should succeed.
+    builder_ok = build.RcBuilder()
+    self.failUnlessEqual(0,
+        builder_ok.Run(DummyOpts(), [
+            '-o', output_dir,
+            '-E', 'name=foo',
+            '-a', os.path.abspath(
+                os.path.join(output_dir, 'en_foo_resources.rc')),
+            '-a', os.path.abspath(
+                os.path.join(output_dir, 'sv_foo_resources.rc')),
+            '-a', os.path.abspath(
+                os.path.join(output_dir, 'resource.h'))]))
+
   def _verifyWhitelistedOutput(self,
                                filename,
                                whitelisted_ids,
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index fa2bc62..a5bcff4c 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -7518,6 +7518,9 @@
 </histogram>
 
 <histogram name="Clipboard.ConstructedHasher" enum="BooleanSuccess">
+  <obsolete>
+    Launched briefly in M-59 dev, then refactoring made obsolete.
+  </obsolete>
   <owner>mpearson@chromium.org</owner>
   <summary>
     Whether Android's Clipboard.java successfully constructed a hasher to hash
@@ -41796,6 +41799,38 @@
   </summary>
 </histogram>
 
+<histogram base="true"
+    name="NewTabPage.ContentSuggestions.TimeUntilFirstSoftTrigger" units="ms">
+  <owner>jkrcal@chromium.org</owner>
+  <summary>
+    Android: The time since the last fetch, recorded upon the first soft fetch
+    trigger. The first soft trigger does not necessarily cause a fetch (if it
+    comes before the end of the respective scheduling interval). This metric is
+    recorded at most once (per lifetime of a Chrome instance) after each fetch.
+    This is used to understand how changing scheduling intervals will impact
+    traffic of background fetches.
+  </summary>
+</histogram>
+
+<histogram base="true"
+    name="NewTabPage.ContentSuggestions.TimeUntilPersistentFetch" units="ms">
+  <owner>jkrcal@chromium.org</owner>
+  <summary>
+    Android: The time since the last fetch, recorded upon a persistent fetch.
+    This is used to understand what are the real persistent fetching intervals
+    in the wild.
+  </summary>
+</histogram>
+
+<histogram base="true" name="NewTabPage.ContentSuggestions.TimeUntilSoftFetch"
+    units="ms">
+  <owner>jkrcal@chromium.org</owner>
+  <summary>
+    Android: The time since the last fetch, recorded upon a soft fetch. This is
+    used to understand what are the real soft fetching intervals in the wild.
+  </summary>
+</histogram>
+
 <histogram name="NewTabPage.ContentSuggestions.UIUpdateResult"
     enum="ContentSuggestionsUIUpdateResult">
   <obsolete>
@@ -48705,7 +48740,7 @@
   </summary>
 </histogram>
 
-<histogram name="PaymentRequest.CanMakePayment.Usage" enum="Boolean">
+<histogram name="PaymentRequest.CanMakePayment.Usage" enum="CanMakePaymentUsage">
   <owner>sebsg@chromium.org</owner>
   <summary>
     Whether the merchant used the CanMakePayment method during a Payment
@@ -48788,6 +48823,14 @@
   </summary>
 </histogram>
 
+<histogram name="PaymentRequest.CheckoutFunnel.SkippedShow"
+    enum="BooleanSkipped">
+  <owner>sebsg@chromium.org</owner>
+  <summary>
+    When the Payment Request UI gets skipped to go directly to the payment app.
+  </summary>
+</histogram>
+
 <histogram name="PaymentRequest.NumberOfSelectionAdds">
   <owner>sebsg@chromium.org</owner>
   <summary>
@@ -85135,6 +85178,11 @@
   <int value="23" label="Too many RenderPassDrawQuads."/>
 </enum>
 
+<enum name="CanMakePaymentUsage" type="int">
+  <int value="0" lable="Used"/>
+  <int value="1" lable="Not Used"/>
+</enum>
+
 <enum name="CanvasContextType" type="int">
   <int value="0" label="2d"/>
   <int value="1" label="(obsolete) webkit-3d"/>
@@ -101998,6 +102046,7 @@
   <int value="880510010" label="enable-permissions-bubbles"/>
   <int value="884106779" label="supervised-user-safesites"/>
   <int value="887011602" label="enable-spelling-auto-correct"/>
+  <int value="902608487" label="AutofillUpstreamRequestCvcIfMissing:enabled"/>
   <int value="903267263" label="disable-offline-pages"/>
   <int value="908523940" label="PassiveEventListenersDueToFling:disabled"/>
   <int value="909439558" label="disable-device-discovery"/>
@@ -102145,6 +102194,7 @@
   <int value="1416592483" label="ash-enable-mirrored-screen"/>
   <int value="1418054870" label="SpecialLocale:enabled"/>
   <int value="1421620678" label="simple-clear-browsing-data-support-string"/>
+  <int value="1435018419" label="AutofillUpstreamRequestCvcIfMissing:disabled"/>
   <int value="1441897340" label="AndroidSpellCheckerNonLowEnd:enabled"/>
   <int value="1442798825" label="enable-quic"/>
   <int value="1442830837" label="MemoryAblation:disabled"/>
@@ -125590,6 +125640,17 @@
   <affected-histogram name="Setup.Install.LzmaUnPackStatus"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="UserClasses" separator=".">
+  <suffix name="RareNTPUser" label="Rare NTP user"/>
+  <suffix name="ActiveNTPUser" label="Active NTP user"/>
+  <suffix name="ActiveSuggestionsConsumer" label="Active suggestions consumer"/>
+  <affected-histogram
+      name="NewTabPage.ContentSuggestions.TimeUntilFirstSoftTrigger"/>
+  <affected-histogram
+      name="NewTabPage.ContentSuggestions.TimeUntilPersistentFetch"/>
+  <affected-histogram name="NewTabPage.ContentSuggestions.TimeUntilSoftFetch"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="UserScriptRunLocation" separator=".">
   <suffix name="DocumentStart" label="Scripts with run_at: document_start."/>
   <suffix name="DocumentEnd" label="Scripts with run_at: document_end."/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index e83eafe9..541f1f6 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -20,6 +20,139 @@
   </metric>
 </event>
 
+<event name="Autofill.DeveloperEngagement">
+  <owner>csashi@google.com</owner>
+  <summary>
+    Recorded when we parse a form to log whether developer has used autocomplete
+    markup or UPI-VPA hints.
+  </summary>
+  <metric name="DeveloperEngagement"/>
+</event>
+
+<event name="Autofill.FormSubmitted">
+  <owner>csashi@google.com</owner>
+  <summary>
+    Recorded when user submits a form.
+  </summary>
+  <metric name="AutofillFormSubmittedState">
+    <summary>
+      Whether form's fields were all autofilled, some fields were autofilled, or
+      none of the field were autofilled. See |AutofillFormSubmittedState|.
+    </summary>
+  </metric>
+  <metric name="MillisecondsSinceFormLoaded">
+    <summary>
+      Time since form parse.
+    </summary>
+  </metric>
+</event>
+
+<event name="Autofill.InteractedWithForm">
+  <owner>csashi@google.com</owner>
+  <summary>
+    Recorded when we parse a form to log form metadata and autofill settings
+    that apply to all subsequent events for this form.
+  </summary>
+  <metric name="IsForCreditCard">
+    <summary>
+      True for credit card forms, false for address/profile forms.
+    </summary>
+  </metric>
+  <metric name="LocalRecordTypeCount">
+    <summary>
+      Number of local credit cards or local autofill profiles.
+    </summary>
+  </metric>
+  <metric name="ServerRecordTypeCount">
+    <summary>
+      Number of masked and full server credit cards or server autofill profiles.
+    </summary>
+  </metric>
+</event>
+
+<event name="Autofill.SuggestionsShown">
+  <owner>csashi@google.com</owner>
+  <metric name="MillisecondsSinceFormLoaded">
+    <summary>
+      Time since form parse.
+    </summary>
+  </metric>
+</event>
+
+<event name="Autofill.SelectedMaskedServerCard">
+  <owner>csashi@google.com</owner>
+  <metric name="MillisecondsSinceFormLoaded">
+    <summary>
+      Time since form parse.
+    </summary>
+  </metric>
+</event>
+
+<event name="Autofill.SuggestionFilled">
+  <owner>csashi@google.com</owner>
+  <summary>
+    Recorded when user selects a suggestion and we fill the form with that
+    suggestion.
+  </summary>
+  <metric name="MillisecondsSinceFormLoaded">
+    <summary>
+      Time since form parse.
+    </summary>
+  </metric>
+  <metric name="RecordType">
+    <summary>
+      Whether the suggestion was from a local card/autofill profile or from a
+      server card/autofill profile.
+    </summary>
+  </metric>
+</event>
+
+<event name="Autofill.TextFieldDidChange">
+  <owner>csashi@google.com</owner>
+  <summary>
+    Recorded when user edits a text field. The text field may have been
+    autofilled.
+  </summary>
+  <metric name="FieldTypeGroup">
+    <summary>
+      Field's |FieldTypeGroup|. See |AutofillType.group()|.
+    </summary>
+  </metric>
+  <metric name="HeuristicType">
+    <summary>
+      Field's |ServerFieldType| based on heuristics. See
+      |AutofillField.heuristic_type()|.
+    </summary>
+  </metric>
+  <metric name="HtmlFieldMode">
+    <summary>
+      Whether the field's autocomplete hint specified 'billing' or 'shipping'.
+      See |AutofillField.html_mode()|.
+    </summary>
+  </metric>
+  <metric name="HtmlFieldType">
+    <summary>
+      Field's autocomplete field type hint. See |AutofillField.html_type()|.
+    </summary>
+  </metric>
+  <metric name="IsAutofilled">
+    <summary>
+      True whether field was autofilled. See |AutofillField.is_autofilled|.
+    </summary>
+  </metric>
+  <metric name="MillisecondsSinceFormLoaded">
+    <summary>
+      Time since form parse.
+    </summary>
+  </metric>
+  <metric name="ServerType">
+    <summary>
+      Field's |ServerFieldType| returned by server. See
+      |AutofillField.server_type()|.
+    </summary>
+  </metric>
+</event>
+
 <event name="PageLoad">
   <owner>bmcquade@chromium.org</owner>
   <summary>
diff --git a/tools/perf/page_sets/tough_video_cases.py b/tools/perf/page_sets/tough_video_cases.py
index 96b3d07..6ff629b15 100644
--- a/tools/perf/page_sets/tough_video_cases.py
+++ b/tools/perf/page_sets/tough_video_cases.py
@@ -20,7 +20,6 @@
     'audio_video',
     'audio_only',
     'video_only',
-    'looping_audio',
     # Other filter tags:
     'is_50fps',
     'is_4k',
@@ -36,14 +35,6 @@
     super(ToughVideoCasesPage, self).__init__(
         url=url, page_set=page_set, tags=tags)
 
-  def LoopMixedAudio(self, action_runner):
-    action_runner.PlayMedia(selector='#background_audio',
-                            playing_event_timeout_in_seconds=60)
-    action_runner.LoopMedia(loop_count=50, selector='#mixed_audio')
-
-  def LoopSingleAudio(self, action_runner):
-    action_runner.LoopMedia(loop_count=50, selector='#single_audio')
-
   def PlayAction(self, action_runner):
     # Play the media until it has finished or it times out.
     action_runner.PlayMedia(playing_event_timeout_in_seconds=60,
@@ -449,36 +440,6 @@
     self.SeekBeforeAndAfterPlayhead(action_runner)
 
 
-class Page28(ToughVideoCasesPage):
-
-  # This page tests looping a single audio track.
-  def __init__(self, page_set):
-    super(Page28, self).__init__(
-      url='file://tough_video_cases/audio_playback.html?id=single_audio',
-      page_set=page_set,
-      tags=['pcm', 'looping_audio'])
-
-    self.skip_basic_metrics = True
-
-  def RunPageInteractions(self, action_runner):
-    self.LoopSingleAudio(action_runner)
-
-
-class Page29(ToughVideoCasesPage):
-
-  # This page tests looping an audio track and playing another in the
-  # background.
-  def __init__(self, page_set):
-    super(Page29, self).__init__(
-      url='file://tough_video_cases/audio_playback.html?id=mixed_audio',
-      page_set=page_set,
-      tags=['pcm', 'looping_audio'])
-
-    self.skip_basic_metrics = True
-
-  def RunPageInteractions(self, action_runner):
-    self.LoopMixedAudio(action_runner)
-
 class Page30(ToughVideoCasesPage):
 
   def __init__(self, page_set):
@@ -631,7 +592,8 @@
 
 class ToughVideoCasesPageSet(story.StorySet):
   """
-  Description: Video Stack Perf benchmark that report time_to_play.
+  Description: Video Stack Perf pages that report time_to_play and many other
+  media-specific and generic metrics.
   """
   def __init__(self):
     super(ToughVideoCasesPageSet, self).__init__(
@@ -671,8 +633,7 @@
 
 class ToughVideoCasesExtraPageSet(story.StorySet):
   """
-  Description: Video Stack Perf benchmarks that report seek time and audio
-  avg_loop_time.
+  Description: Video Stack Perf pages that only report seek time.
   """
   def __init__(self):
     super(ToughVideoCasesExtraPageSet, self).__init__(
@@ -687,8 +648,6 @@
     self.AddStory(Page25(self))
     self.AddStory(Page26(self))
     self.AddStory(Page27(self))
-    self.AddStory(Page28(self))
-    self.AddStory(Page29(self))
     self.AddStory(Page31(self))
     self.AddStory(Page33(self))
     self.AddStory(Page35(self))
diff --git a/tools/perf/page_sets/tough_video_cases/audio_playback.html b/tools/perf/page_sets/tough_video_cases/audio_playback.html
deleted file mode 100644
index c5ccbc8..0000000
--- a/tools/perf/page_sets/tough_video_cases/audio_playback.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-  <script>
-    function addAudio(id, file) {
-      var audio = document.createElement('audio');
-      audio.src = file;
-      audio.loop = true;
-      audio.id = id;
-      document.body.appendChild(audio);
-    }
-
-    function getIDFromURL() {
-      var query = window.location.search;
-      return query.substring(query.lastIndexOf("id=") + 3);
-    }
-
-    addAudio('background_audio', 'pink_noise_20s.wav');
-    // Main audio file is identified by an ID passed in the page-set.
-    addAudio(getIDFromURL(), 'pink_noise_140ms.wav');
-  </script>
-  </body>
-</html>
\ No newline at end of file
diff --git a/tools/perf/page_sets/tough_video_cases/pink_noise_140ms.wav.sha1 b/tools/perf/page_sets/tough_video_cases/pink_noise_140ms.wav.sha1
deleted file mode 100644
index 839f387..0000000
--- a/tools/perf/page_sets/tough_video_cases/pink_noise_140ms.wav.sha1
+++ /dev/null
@@ -1 +0,0 @@
-16c54ce40621b7d4410554206529759607c16d70
\ No newline at end of file
diff --git a/tools/perf/page_sets/tough_video_cases/pink_noise_20s.wav.sha1 b/tools/perf/page_sets/tough_video_cases/pink_noise_20s.wav.sha1
deleted file mode 100644
index 0f9a50b1..0000000
--- a/tools/perf/page_sets/tough_video_cases/pink_noise_20s.wav.sha1
+++ /dev/null
@@ -1 +0,0 @@
-2f6874496d8dd0a7e13e60542c7143a245fea8ef
\ No newline at end of file
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 22deece..749a638 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -234,14 +234,12 @@
 
 junit_binary("ui_junit_tests") {
   java_files = [
-    "junit/src/org/chromium/ui/base/ClipboardTest.java",
     "junit/src/org/chromium/ui/base/SelectFileDialogTest.java",
     "junit/src/org/chromium/ui/text/SpanApplierTest.java",
   ]
   deps = [
     ":ui_java",
     "//base:base_java",
-    "//base:base_java_test_support",
   ]
 }
 
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
index abfdf2e..0f3eb25 100644
--- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java
+++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -5,23 +5,23 @@
 package org.chromium.ui.base;
 
 import android.content.ClipData;
+import android.content.ClipDescription;
 import android.content.ClipboardManager;
 import android.content.Context;
+import android.text.Html;
+import android.text.Spanned;
+import android.text.style.CharacterStyle;
+import android.text.style.ParagraphStyle;
+import android.text.style.UpdateAppearance;
 
 import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.SuppressFBWarnings;
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.ui.R;
 import org.chromium.ui.widget.Toast;
 
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
 /**
  * Simple proxy that provides C++ code with an access pathway to the Android clipboard.
  */
@@ -29,25 +29,12 @@
 public class Clipboard implements ClipboardManager.OnPrimaryClipChangedListener {
     private static Clipboard sInstance;
 
-    private static final String TAG = "Clipboard";
-
     // Necessary for coercing clipboard contents to text if they require
     // access to network resources, etceteras (e.g., URI in clipboard)
     private final Context mContext;
 
     private final ClipboardManager mClipboardManager;
 
-    // A message hasher that's used to hash clipboard contents so we can tell
-    // when a clipboard changes without storing the full contents.
-    private MessageDigest mMd5Hasher;
-    // The hash of the current clipboard.
-    // TODO(mpearson): unsuppress this warning once saving and restoring
-    // the hash from prefs is added.
-    @SuppressFBWarnings("URF_UNREAD_FIELD")
-    private byte[] mClipboardMd5;
-    // The time when the clipboard was last updated.  Set to 0 if unknown.
-    private long mClipboardChangeTime;
-
     /**
      * Get the singleton Clipboard instance (creating it if needed).
      */
@@ -65,19 +52,6 @@
                 (ClipboardManager) ContextUtils.getApplicationContext().getSystemService(
                         Context.CLIPBOARD_SERVICE);
         mClipboardManager.addPrimaryClipChangedListener(this);
-        try {
-            mMd5Hasher = MessageDigest.getInstance("MD5");
-            mClipboardMd5 = weakMd5Hash();
-        } catch (NoSuchAlgorithmException e) {
-            Log.e(TAG,
-                    "Unable to construct MD5 MessageDigest: %s; assume "
-                            + "clipboard last update time is start of epoch.",
-                    e);
-            mMd5Hasher = null;
-            mClipboardMd5 = new byte[] {};
-        }
-        RecordHistogram.recordBooleanHistogram("Clipboard.ConstructedHasher", mMd5Hasher != null);
-        mClipboardChangeTime = 0;
     }
 
     /**
@@ -98,7 +72,7 @@
      */
     @SuppressWarnings("javadoc")
     @CalledByNative
-    private String getCoercedText() {
+    public String getCoercedText() {
         // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see
         // crbug.com/654802 and b/31501780)
         try {
@@ -111,6 +85,18 @@
         }
     }
 
+    // TODO(ctzsm): Remove this method after Android API is updated
+    private boolean hasStyleSpan(Spanned spanned) {
+        Class<?>[] styleClasses = {
+                CharacterStyle.class, ParagraphStyle.class, UpdateAppearance.class};
+        for (Class<?> clazz : styleClasses) {
+            if (spanned.nextSpanTransition(-1, spanned.length(), clazz) < spanned.length()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Gets the HTML text of top item on the primary clip on the Android clipboard.
      *
@@ -118,29 +104,26 @@
      *         text or no entries on the primary clip.
      */
     @CalledByNative
-    private String getHTMLText() {
+    public String getHTMLText() {
         // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see
         // crbug/654802 and b/31501780)
         try {
-            return mClipboardManager.getPrimaryClip().getItemAt(0).getHtmlText();
+            ClipData clipData = mClipboardManager.getPrimaryClip();
+            ClipDescription description = clipData.getDescription();
+            if (description.hasMimeType(ClipDescription.MIMETYPE_TEXT_HTML)) {
+                return clipData.getItemAt(0).getHtmlText();
+            }
+
+            if (description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
+                Spanned spanned = (Spanned) clipData.getItemAt(0).getText();
+                if (hasStyleSpan(spanned)) {
+                    return Html.toHtml(spanned);
+                }
+            }
         } catch (Exception e) {
             return null;
         }
-    }
-
-    /**
-     * Gets the time the clipboard content last changed.
-     *
-     * This is calculated according to the device's clock.  E.g., it continues
-     * increasing when the device is suspended.  Likewise, it can be in the
-     * future if the user's clock updated after this information was recorded.
-     *
-     * @return a Java long recording the last changed time in milliseconds since
-     * epoch, or 0 if the time could not be determined.
-     */
-    @CalledByNative
-    public long getClipboardContentChangeTimeInMillis() {
-        return mClipboardChangeTime;
+        return null;
     }
 
     /**
@@ -179,7 +162,7 @@
         setPrimaryClipNoException(ClipData.newPlainText(null, null));
     }
 
-    private void setPrimaryClipNoException(ClipData clip) {
+    public void setPrimaryClipNoException(ClipData clip) {
         try {
             mClipboardManager.setPrimaryClip(clip);
         } catch (Exception ex) {
@@ -190,35 +173,17 @@
     }
 
     /**
-     * Updates mClipboardMd5 and mClipboardChangeTime when the clipboard updates.
+     * Tells the C++ Clipboard that the clipboard has changed.
      *
      * Implements OnPrimaryClipChangedListener to listen for clipboard updates.
      */
     @Override
     public void onPrimaryClipChanged() {
-        if (mMd5Hasher == null) return;
         RecordUserAction.record("MobileClipboardChanged");
-        mClipboardMd5 = weakMd5Hash();
-        // Always update the clipboard change time even if the clipboard
-        // content hasn't changed.  This is because if the user put something
-        // in the clipboard recently (even if it was not necessary because it
-        // was already there), that content should be considered recent.
-        mClipboardChangeTime = System.currentTimeMillis();
+        long nativeClipboardAndroid = nativeInit();
+        if (nativeClipboardAndroid != 0) nativeOnPrimaryClipChanged(nativeClipboardAndroid);
     }
 
-    /**
-     * Returns a weak hash of getCoercedText().
-     *
-     * @return a Java byte[] with the weak hash.
-     */
-    private byte[] weakMd5Hash() {
-        if (getCoercedText() == null) {
-            return new byte[] {};
-        }
-        // Compute a hash consisting of the first 4 bytes of the MD5 hash of
-        // getCoercedText().  This value is used to detect clipboard content
-        // change. Keeping only 4 bytes is a privacy requirement to introduce
-        // collision and allow deniability of having copied a given string.
-        return Arrays.copyOfRange(mMd5Hasher.digest(getCoercedText().getBytes()), 0, 4);
-    }
+    private native long nativeInit();
+    private native void nativeOnPrimaryClipChanged(long nativeClipboardAndroid);
 }
diff --git a/ui/android/junit/src/org/chromium/ui/base/ClipboardTest.java b/ui/android/junit/src/org/chromium/ui/base/ClipboardTest.java
deleted file mode 100644
index a4bd9666..0000000
--- a/ui/android/junit/src/org/chromium/ui/base/ClipboardTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.ui.base;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.metrics.RecordUserAction;
-import org.chromium.testing.local.LocalRobolectricTestRunner;
-
-/**
- * Tests logic in the Clipboard class.
- */
-@RunWith(LocalRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class ClipboardTest {
-    @BeforeClass
-    public static void beforeClass() {
-        RecordHistogram.setDisabledForTests(true);
-        RecordUserAction.setDisabledForTests(true);
-    }
-
-    @AfterClass
-    public static void afterClass() {
-        RecordHistogram.setDisabledForTests(false);
-        RecordUserAction.setDisabledForTests(false);
-    }
-
-    @Test
-    public void testGetClipboardContentChangeTimeInMillis() {
-        ContextUtils.initApplicationContext(RuntimeEnvironment.application);
-        // Upon launch, the clipboard should be at start of epoch, i.e., ancient.
-        Clipboard clipboard = Clipboard.getInstance();
-        assertEquals(0, clipboard.getClipboardContentChangeTimeInMillis());
-        // After updating the clipboard, it should have a new time.
-        clipboard.onPrimaryClipChanged();
-        assertTrue(clipboard.getClipboardContentChangeTimeInMillis() > 0);
-    }
-}
diff --git a/ui/base/android/ui_base_jni_registrar.cc b/ui/base/android/ui_base_jni_registrar.cc
index e86f51adc1..26343df 100644
--- a/ui/base/android/ui_base_jni_registrar.cc
+++ b/ui/base/android/ui_base_jni_registrar.cc
@@ -7,13 +7,15 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_registrar.h"
 #include "base/macros.h"
+#include "ui/base/clipboard/clipboard_android.h"
 #include "ui/base/l10n/l10n_util_android.h"
 
 namespace ui {
 namespace android {
 
 static base::android::RegistrationMethod kUiRegisteredMethods[] = {
-  { "LocalizationUtils", l10n_util::RegisterLocalizationUtil },
+    {"LocalizationUtils", l10n_util::RegisterLocalizationUtil},
+    {"ClipboardAndroid", ui::RegisterClipboardAndroid},
 };
 
 bool RegisterJni(JNIEnv* env) {
diff --git a/ui/base/clipboard/clipboard.cc b/ui/base/clipboard/clipboard.cc
index 6c98121..c8c0c38d 100644
--- a/ui/base/clipboard/clipboard.cc
+++ b/ui/base/clipboard/clipboard.cc
@@ -86,10 +86,12 @@
     clipboard_map->erase(it);
 }
 
-base::Time Clipboard::GetClipboardLastModifiedTime() const {
+base::Time Clipboard::GetLastModifiedTime() const {
   return base::Time();
 }
 
+void Clipboard::ClearLastModifiedTime() {}
+
 void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) {
   // Ignore writes with empty parameters.
   for (const auto& param : params) {
diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h
index 5d27f2c..dd18ad5 100644
--- a/ui/base/clipboard/clipboard.h
+++ b/ui/base/clipboard/clipboard.h
@@ -207,7 +207,10 @@
 
   // Returns an estimate of the time the clipboard was last updated.  If the
   // time is unknown, returns Time::Time().
-  virtual base::Time GetClipboardLastModifiedTime() const;
+  virtual base::Time GetLastModifiedTime() const;
+
+  // Resets the clipboard last modified time to Time::Time().
+  virtual void ClearLastModifiedTime();
 
   // Gets the FormatType corresponding to an arbitrary format string,
   // registering it with the system if needed. Due to Windows/Linux
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc
index 8f35282a..1761d6c 100644
--- a/ui/base/clipboard/clipboard_android.cc
+++ b/ui/base/clipboard/clipboard_android.cc
@@ -8,10 +8,12 @@
 
 #include "base/android/context_utils.h"
 #include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
 #include "base/lazy_instance.h"
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
+#include "base/time/time.h"
 #include "jni/Clipboard_jni.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/geometry/size.h"
@@ -37,6 +39,7 @@
 namespace ui {
 
 namespace {
+
 // Various formats we support.
 const char kURLFormat[] = "url";
 const char kPlainTextFormat[] = "text";
@@ -50,25 +53,36 @@
  public:
   ClipboardMap();
   std::string Get(const std::string& format);
-  int64_t GetLastClipboardChangeTimeInMillis();
+  uint64_t GetSequenceNumber() const;
+  base::Time GetLastModifiedTime() const;
+  void ClearLastModifiedTime();
   bool HasFormat(const std::string& format);
+  void OnPrimaryClipboardChanged();
   void Set(const std::string& format, const std::string& data);
   void CommitToAndroidClipboard();
   void Clear();
 
  private:
+  enum class MapState {
+    kOutOfDate,
+    kUpToDate,
+    kPreparingCommit,
+  };
+
   void UpdateFromAndroidClipboard();
   std::map<std::string, std::string> map_;
+  MapState map_state_;
   base::Lock lock_;
 
-  int64_t last_clipboard_change_time_ms_;
+  uint64_t sequence_number_;
+  base::Time last_modified_time_;
 
   // Java class and methods for the Android ClipboardManager.
   ScopedJavaGlobalRef<jobject> clipboard_manager_;
 };
 base::LazyInstance<ClipboardMap>::Leaky g_map = LAZY_INSTANCE_INITIALIZER;
 
-ClipboardMap::ClipboardMap() {
+ClipboardMap::ClipboardMap() : map_state_(MapState::kOutOfDate) {
   clipboard_manager_.Reset(Java_Clipboard_getInstance(AttachCurrentThread()));
   DCHECK(clipboard_manager_.obj());
 }
@@ -80,10 +94,16 @@
   return it == map_.end() ? std::string() : it->second;
 }
 
-int64_t ClipboardMap::GetLastClipboardChangeTimeInMillis() {
-  base::AutoLock lock(lock_);
-  UpdateFromAndroidClipboard();
-  return last_clipboard_change_time_ms_;
+uint64_t ClipboardMap::GetSequenceNumber() const {
+  return sequence_number_;
+}
+
+base::Time ClipboardMap::GetLastModifiedTime() const {
+  return last_modified_time_;
+}
+
+void ClipboardMap::ClearLastModifiedTime() {
+  last_modified_time_ = base::Time();
 }
 
 bool ClipboardMap::HasFormat(const std::string& format) {
@@ -92,9 +112,16 @@
   return base::ContainsKey(map_, format);
 }
 
+void ClipboardMap::OnPrimaryClipboardChanged() {
+  sequence_number_++;
+  last_modified_time_ = base::Time::Now();
+  map_state_ = MapState::kOutOfDate;
+}
+
 void ClipboardMap::Set(const std::string& format, const std::string& data) {
   base::AutoLock lock(lock_);
   map_[format] = data;
+  map_state_ = MapState::kPreparingCommit;
 }
 
 void ClipboardMap::CommitToAndroidClipboard() {
@@ -122,6 +149,9 @@
     Java_Clipboard_clear(env, clipboard_manager_);
     NOTIMPLEMENTED();
   }
+  map_state_ = MapState::kUpToDate;
+  sequence_number_++;
+  last_modified_time_ = base::Time::Now();
 }
 
 void ClipboardMap::Clear() {
@@ -129,6 +159,9 @@
   base::AutoLock lock(lock_);
   map_.clear();
   Java_Clipboard_clear(env, clipboard_manager_);
+  map_state_ = MapState::kUpToDate;
+  sequence_number_++;
+  last_modified_time_ = base::Time::Now();
 }
 
 // Add a key:jstr pair to map, but only if jstr is not null, and also
@@ -144,38 +177,24 @@
   }
 }
 
-// Return true if all the key-value pairs in map1 are also in map2.
-bool MapIsSubset(const std::map<std::string, std::string>& map1,
-                 const std::map<std::string, std::string>& map2) {
-  for (const auto& val : map1) {
-    auto iter = map2.find(val.first);
-    if (iter == map2.end() || iter->second != val.second)
-      return false;
-  }
-  return true;
-}
-
 void ClipboardMap::UpdateFromAndroidClipboard() {
-  // Fetch the current Android clipboard state. Replace our state with
-  // the Android state if the Android state has been changed.
+  DCHECK_NE(MapState::kPreparingCommit, map_state_);
+  if (map_state_ == MapState::kUpToDate)
+    return;
+
+  // Fetch the current Android clipboard state.
   lock_.AssertAcquired();
   JNIEnv* env = AttachCurrentThread();
 
-  std::map<std::string, std::string> android_clipboard_state;
-
   ScopedJavaLocalRef<jstring> jtext =
       Java_Clipboard_getCoercedText(env, clipboard_manager_);
   ScopedJavaLocalRef<jstring> jhtml =
       Java_Clipboard_getHTMLText(env, clipboard_manager_);
 
-  AddMapEntry(env, &android_clipboard_state, kPlainTextFormat, jtext);
-  AddMapEntry(env, &android_clipboard_state, kHTMLFormat, jhtml);
-  last_clipboard_change_time_ms_ =
-      Java_Clipboard_getClipboardContentChangeTimeInMillis(env,
-                                                           clipboard_manager_);
+  AddMapEntry(env, &map_, kPlainTextFormat, jtext);
+  AddMapEntry(env, &map_, kHTMLFormat, jhtml);
 
-  if (!MapIsSubset(android_clipboard_state, map_))
-    android_clipboard_state.swap(map_);
+  map_state_ = MapState::kUpToDate;
 }
 
 }  // namespace
@@ -277,6 +296,13 @@
 }
 
 // ClipboardAndroid implementation.
+
+void ClipboardAndroid::OnPrimaryClipChanged(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& obj) {
+  g_map.Get().OnPrimaryClipboardChanged();
+}
+
 ClipboardAndroid::ClipboardAndroid() {
   DCHECK(CalledOnValidThread());
 }
@@ -289,10 +315,7 @@
 
 uint64_t ClipboardAndroid::GetSequenceNumber(ClipboardType /* type */) const {
   DCHECK(CalledOnValidThread());
-  // TODO: implement this. For now this interface will advertise
-  // that the clipboard never changes. That's fine as long as we
-  // don't rely on this signal.
-  return 0;
+  return g_map.Get().GetSequenceNumber();
 }
 
 bool ClipboardAndroid::IsFormatAvailable(const Clipboard::FormatType& format,
@@ -414,10 +437,14 @@
   *result = g_map.Get().Get(format.ToString());
 }
 
-base::Time ClipboardAndroid::GetClipboardLastModifiedTime() const {
+base::Time ClipboardAndroid::GetLastModifiedTime() const {
   DCHECK(CalledOnValidThread());
-  return base::Time::FromJavaTime(
-      g_map.Get().GetLastClipboardChangeTimeInMillis());
+  return g_map.Get().GetLastModifiedTime();
+}
+
+void ClipboardAndroid::ClearLastModifiedTime() {
+  DCHECK(CalledOnValidThread());
+  g_map.Get().ClearLastModifiedTime();
 }
 
 // Main entry point used to write several values in the clipboard.
@@ -485,4 +512,14 @@
   g_map.Get().Set(format.ToString(), std::string(data_data, data_len));
 }
 
+bool RegisterClipboardAndroid(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+// Returns a pointer to the current ClipboardAndroid object.
+static jlong Init(JNIEnv* env,
+                  const base::android::JavaParamRef<jobject>& obj) {
+  return reinterpret_cast<intptr_t>(Clipboard::GetForCurrentThread());
+}
+
 } // namespace ui
diff --git a/ui/base/clipboard/clipboard_android.h b/ui/base/clipboard/clipboard_android.h
index a41550a2..8589e9c 100644
--- a/ui/base/clipboard/clipboard_android.h
+++ b/ui/base/clipboard/clipboard_android.h
@@ -11,11 +11,19 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "base/android/scoped_java_ref.h"
 #include "base/macros.h"
+#include "base/time/time.h"
 
 namespace ui {
 
 class ClipboardAndroid : public Clipboard {
+ public:
+  // Called by Java when the Java Clipboard is notified that the clipboard has
+  // changed.
+  void OnPrimaryClipChanged(JNIEnv* env,
+                            const base::android::JavaParamRef<jobject>& obj);
+
  private:
   friend class Clipboard;
 
@@ -45,7 +53,8 @@
                       base::string16* result) const override;
   void ReadBookmark(base::string16* title, std::string* url) const override;
   void ReadData(const FormatType& format, std::string* result) const override;
-  base::Time GetClipboardLastModifiedTime() const override;
+  base::Time GetLastModifiedTime() const override;
+  void ClearLastModifiedTime() override;
   void WriteObjects(ClipboardType type, const ObjectMap& objects) override;
   void WriteText(const char* text_data, size_t text_len) override;
   void WriteHTML(const char* markup_data,
@@ -66,6 +75,9 @@
   DISALLOW_COPY_AND_ASSIGN(ClipboardAndroid);
 };
 
+// Registers the ClipboardAndroid native method.
+bool RegisterClipboardAndroid(JNIEnv* env);
+
 }  // namespace ui
 
 #endif  // UI_BASE_CLIPBOARD_CLIPBOARD_ANDROID_H_
diff --git a/ui/base/test/test_clipboard.cc b/ui/base/test/test_clipboard.cc
index 7bceec1..1fdb268d 100644
--- a/ui/base/test/test_clipboard.cc
+++ b/ui/base/test/test_clipboard.cc
@@ -26,7 +26,7 @@
   return clipboard;
 }
 
-void TestClipboard::SetClipboardLastModifiedTime(const base::Time& time) {
+void TestClipboard::SetLastModifiedTime(const base::Time& time) {
   last_modified_time_ = time;
 }
 
@@ -130,10 +130,14 @@
     *result = it->second;
 }
 
-base::Time TestClipboard::GetClipboardLastModifiedTime() const {
+base::Time TestClipboard::GetLastModifiedTime() const {
   return last_modified_time_;
 }
 
+void TestClipboard::ClearLastModifiedTime() {
+  last_modified_time_ = base::Time();
+}
+
 void TestClipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) {
   Clear(type);
   default_store_type_ = type;
diff --git a/ui/base/test/test_clipboard.h b/ui/base/test/test_clipboard.h
index 7bf88a24..a574adba 100644
--- a/ui/base/test/test_clipboard.h
+++ b/ui/base/test/test_clipboard.h
@@ -26,8 +26,8 @@
   // Clipboard::DestroyClipboardForCurrentThread() on the same thread.
   static Clipboard* CreateForCurrentThread();
 
-  // Sets the time to be returned by GetClipboardLastModifiedTime();
-  void SetClipboardLastModifiedTime(const base::Time& time);
+  // Sets the time to be returned by GetLastModifiedTime();
+  void SetLastModifiedTime(const base::Time& time);
 
   // Clipboard overrides.
   void OnPreShutdown() override;
@@ -52,7 +52,8 @@
                       base::string16* result) const override;
   void ReadBookmark(base::string16* title, std::string* url) const override;
   void ReadData(const FormatType& format, std::string* result) const override;
-  base::Time GetClipboardLastModifiedTime() const override;
+  base::Time GetLastModifiedTime() const override;
+  void ClearLastModifiedTime() override;
   void WriteObjects(ClipboardType type, const ObjectMap& objects) override;
   void WriteText(const char* text_data, size_t text_len) override;
   void WriteHTML(const char* markup_data,
diff --git a/ui/chromeos/resources/default_100_percent/print_notification/print_job_waiting.png b/ui/chromeos/resources/default_100_percent/print_notification/print_job_waiting.png
deleted file mode 100644
index 324b684..0000000
--- a/ui/chromeos/resources/default_100_percent/print_notification/print_job_waiting.png
+++ /dev/null
Binary files differ
diff --git a/ui/chromeos/resources/default_200_percent/print_notification/print_job_waiting.png b/ui/chromeos/resources/default_200_percent/print_notification/print_job_waiting.png
deleted file mode 100644
index 03debe6..0000000
--- a/ui/chromeos/resources/default_200_percent/print_notification/print_job_waiting.png
+++ /dev/null
Binary files differ
diff --git a/ui/chromeos/resources/ui_chromeos_resources.grd b/ui/chromeos/resources/ui_chromeos_resources.grd
index 688c7922..3695229 100644
--- a/ui/chromeos/resources/ui_chromeos_resources.grd
+++ b/ui/chromeos/resources/ui_chromeos_resources.grd
@@ -60,7 +60,6 @@
       <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_PAUSE" file="print_notification/pause.png" />
       <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_PLAY" file="print_notification/play.png" />
       <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_HELP" file="print_notification/help.png" />
-      <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_WAITING" file="print_notification/print_job_waiting.png" />
       <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_PRINTING" file="print_notification/print_job_printing.png" />
       <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_DONE" file="print_notification/print_job_done.png" />
       <structure type="chrome_scaled_image" name="IDR_PRINT_NOTIFICATION_ERROR" file="print_notification/print_job_error.png" />
diff --git a/ui/display/manager/chromeos/display_configurator.h b/ui/display/manager/chromeos/display_configurator.h
index d6cd968..8519bd11 100644
--- a/ui/display/manager/chromeos/display_configurator.h
+++ b/ui/display/manager/chromeos/display_configurator.h
@@ -153,7 +153,7 @@
 
   // The delay to perform configuration after RRNotify. See the comment for
   // |configure_timer_|.
-  static const int kConfigureDelayMs = 500;
+  static const int kConfigureDelayMs = 1000;
 
   // The delay to perform configuration after waking up from suspend when in
   // multi display mode. Should be bigger than |kConfigureDelayMs|. Generally
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc
index 6b34dedc..0a7bd13 100644
--- a/ui/display/manager/display_manager.cc
+++ b/ui/display/manager/display_manager.cc
@@ -377,27 +377,37 @@
         display_property_changed = true;
       } else {
         display_modes_[display_id] = *iter;
-        if (info.bounds_in_native().size() != display_mode->size())
+        if (info.bounds_in_native().size() != display_mode->size()) {
+          // If resolution changes, then we can break right here. No need to
+          // continue to fill |display_info_list|, since we won't be
+          // synchronously updating the displays here.
           resolution_changed = true;
+          break;
+        }
         if (info.device_scale_factor() != display_mode->device_scale_factor()) {
           info.set_device_scale_factor(display_mode->device_scale_factor());
           display_property_changed = true;
         }
       }
     }
-    display_info_list.push_back(info);
+    display_info_list.emplace_back(info);
   }
-  if (display_property_changed) {
+
+  if (display_property_changed && !resolution_changed) {
+    // We shouldn't synchronously update the displays here if the resolution
+    // changed. This should happen asynchronously when configuration is
+    // triggered.
     AddMirrorDisplayInfoIfAny(&display_info_list);
     UpdateDisplaysWith(display_info_list);
   }
-  if (resolution_changed && IsInUnifiedMode()) {
+
+  if (resolution_changed && IsInUnifiedMode())
     ReconfigureDisplays();
 #if defined(OS_CHROMEOS)
-  } else if (resolution_changed && configure_displays_) {
+  else if (resolution_changed && configure_displays_)
     delegate_->display_configurator()->OnConfigurationChanged();
-#endif
-  }
+#endif  // defined(OS_CHROMEOS)
+
   return resolution_changed || display_property_changed;
 }
 
diff --git a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
index ce75522..c77bdf4 100644
--- a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
+++ b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
@@ -5,7 +5,6 @@
 #import "ui/views/controls/scrollbar/cocoa_scroll_bar.h"
 
 #import "base/mac/sdk_forward_declarations.h"
-#include "cc/paint/paint_shader.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/effects/SkGradientShader.h"
 #include "ui/compositor/layer.h"
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
index c98c75a..3e9fc20 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
@@ -48,6 +48,9 @@
   /** @private {?IntersectionObserver} */
   intersectionObserver_: null,
 
+  /** @private {?MutationObserver} */
+  mutationObserver_: null,
+
   /** @override */
   ready: function() {
     // If the active history entry changes (i.e. user clicks back button),
@@ -63,39 +66,68 @@
 
   /** @override */
   attached: function() {
-    if (this.showScrollBorders) {
-      var bodyContainer = this.$$('.body-container');
+    if (!this.showScrollBorders)
+      return;
 
-      var bottomMarker = this.$.bodyBottomMarker;
-      var topMarker = this.$.bodyTopMarker;
+    this.mutationObserver_ = new MutationObserver(function() {
+      if (this.open) {
+        this.addIntersectionObserver_();
+      } else {
+        this.removeIntersectionObserver_();
+      }
+    }.bind(this));
 
-      var callback = function(entries) {
-        assert(entries.length <= 2);
-        for (var i = 0; i < entries.length; i++) {
-          var target = entries[i].target;
-          assert(target == bottomMarker || target == topMarker);
-
-          var classToToggle =
-              target == bottomMarker ? 'bottom-scrollable' : 'top-scrollable';
-
-          bodyContainer.classList.toggle(
-              classToToggle, entries[i].intersectionRatio == 0);
-        }
-      };
-
-      this.intersectionObserver_ = new IntersectionObserver(
-          callback,
-          /** @type {IntersectionObserverInit} */ ({
-            root: bodyContainer,
-            threshold: 0,
-          }));
-      this.intersectionObserver_.observe(bottomMarker);
-      this.intersectionObserver_.observe(topMarker);
-    }
+    this.mutationObserver_.observe(this, {
+      attributes: true,
+      attributeFilter: ['open'],
+    });
   },
 
   /** @override */
   detached: function() {
+    this.removeIntersectionObserver_();
+    if (this.mutationObserver_) {
+      this.mutationObserver_.disconnect();
+      this.mutationObserver_ = null;
+    }
+  },
+
+  /** @private */
+  addIntersectionObserver_: function() {
+    if (this.intersectionObserver_)
+      return;
+
+    var bodyContainer = this.$$('.body-container');
+
+    var bottomMarker = this.$.bodyBottomMarker;
+    var topMarker = this.$.bodyTopMarker;
+
+    var callback = function(entries) {
+      assert(entries.length <= 2);
+      for (var i = 0; i < entries.length; i++) {
+        var target = entries[i].target;
+        assert(target == bottomMarker || target == topMarker);
+
+        var classToToggle =
+            target == bottomMarker ? 'bottom-scrollable' : 'top-scrollable';
+
+        bodyContainer.classList.toggle(
+            classToToggle, entries[i].intersectionRatio == 0);
+      }
+    };
+
+    this.intersectionObserver_ = new IntersectionObserver(
+        callback,
+        /** @type {IntersectionObserverInit} */ ({
+          root: bodyContainer,
+          threshold: 0,
+        }));
+    this.intersectionObserver_.observe(bottomMarker);
+    this.intersectionObserver_.observe(topMarker);
+  },
+
+  /** @private */
+  removeIntersectionObserver_: function() {
     if (this.intersectionObserver_) {
       this.intersectionObserver_.disconnect();
       this.intersectionObserver_ = null;