From e89ec060acdf5709d6d6ffab674da568604c2e74 Mon Sep 17 00:00:00 2001
From: Chris Gross <gross.364@osu.edu>
Date: Mon, 14 Jan 2019 11:38:21 -0500
Subject: [PATCH] 7.x-1.10 Release Candidate 3

---
 profiles/wcm_base/CHANGELOG.txt               |   5 +
 .../modules/contrib/admin_menu/PATCHES.txt    |   4 +
 .../modules/contrib/admin_menu/admin_menu.inc |   2 +-
 .../wcm_base/modules/contrib/apps/PATCHES.txt |   4 +
 .../modules/contrib/apps/apps.profile.inc     |   2 +-
 .../contrib/defaultcontent/PATCHES.txt        |   1 +
 .../defaultcontent/defaultcontent.info        |   1 +
 .../defaultcontent/defaultcontent.module      |   5 +-
 .../modules/contrib/libraries/CHANGELOG.txt   |  23 +-
 .../contrib/libraries/css/libraries.admin.css |   3 +
 .../contrib/libraries/libraries.admin.inc     | 141 ++++++++++--
 .../contrib/libraries/libraries.api.php       |   2 +
 .../contrib/libraries/libraries.drush.inc     |  80 +++++--
 .../modules/contrib/libraries/libraries.info  |   7 +-
 .../contrib/libraries/libraries.install       |  10 +
 .../contrib/libraries/libraries.module        | 148 +++++++++++-
 .../contrib/libraries/libraries.theme.inc     |  36 +++
 .../tests/LibrariesAdminWebTest.test          |  27 ++-
 .../example_info_file.libraries.info          |   7 +-
 .../libraries_test_module.info                |   7 +-
 .../libraries_test_theme.info                 |   7 +-
 .../panels_breadcrumbs.info                   |   7 +-
 .../panels_breadcrumbs.module                 | 108 +++++----
 .../modules/contrib/search_api/CHANGELOG.txt  |  22 ++
 .../search_api_facetapi.info                  |   6 +-
 .../contrib/search_api_views/README.txt       |  15 ++
 .../includes/handler_filter_date.inc          |  47 +++-
 .../includes/handler_filter_numeric.inc       | 217 ++++++++++++++++++
 .../includes/handler_filter_options.inc       |   1 +
 .../includes/plugin_cache.inc                 |  11 +-
 .../includes/plugin_content_cache.inc         | 146 ++++++++++++
 .../search_api_views/search_api_views.info    |   8 +-
 .../search_api_views.views.inc                |  13 ++
 .../includes/callback_add_aggregation.inc     |   8 +-
 .../contrib/search_api/search_api.admin.inc   |  49 +++-
 .../contrib/search_api/search_api.drush.inc   |  80 +++++++
 .../contrib/search_api/search_api.info        |   6 +-
 .../contrib/search_api/search_api.install     |  45 ++++
 .../contrib/search_api/search_api.module      | 127 +++++++++-
 .../search_api/tests/search_api_test.info     |   6 +-
 .../search_api/tests/search_api_test_2.info   |   6 +-
 .../contrib/search_api_db/CHANGELOG.txt       |  11 +
 .../contrib/search_api_db/search_api_db.info  |   7 +-
 .../search_api_db/search_api_db.install       |  10 +-
 .../modules/contrib/search_api_db/service.inc |  84 ++++---
 .../modules/contrib/uuid/uuid.features.inc    |   1 +
 .../wcm_base/modules/contrib/uuid/uuid.info   |   6 +-
 .../contrib/uuid/uuid_path/uuid_path.info     |   6 +-
 .../uuid_services/uuid_services.admin.inc     |   8 +
 .../uuid/uuid_services/uuid_services.info     |  12 +-
 .../uuid/uuid_services/uuid_services.install  |  14 ++
 .../uuid/uuid_services/uuid_services.module   |  23 +-
 .../uuid_services_example.info                |   6 +-
 .../modules/custom/news_client/README.md      |   9 +
 .../panopoly/panopoly_admin/CHANGELOG.txt     |   8 +
 .../panopoly_admin/panopoly_admin.info        |   6 +-
 .../panopoly_admin/panopoly_admin.make        |   1 +
 .../panopoly/panopoly_core/CHANGELOG.txt      |  18 ++
 .../panopoly/panopoly_core/panopoly_core.info |   6 +-
 .../panopoly/panopoly_core/panopoly_core.make |  16 +-
 .../panopoly_core/panopoly_core.profile.inc   |   4 +-
 .../panopoly/panopoly_magic/CHANGELOG.txt     |   9 +
 .../panopoly_magic/panopoly_magic.info        |   6 +-
 .../panopoly_magic/panopoly_magic.module      |  16 +-
 .../panopoly/panopoly_pages/CHANGELOG.txt     |   8 +
 .../panopoly_pages/panopoly_pages.info        |   6 +-
 .../panopoly/panopoly_search/CHANGELOG.txt    |   8 +
 .../panopoly_search/panopoly_search.info      |   6 +-
 .../panopoly_search/panopoly_search.make      |   4 +-
 .../panopoly/panopoly_test/CHANGELOG.txt      |   8 +
 .../panopoly/panopoly_test/panopoly_test.info |   6 +-
 .../panopoly/panopoly_theme/CHANGELOG.txt     |   8 +
 .../panopoly_theme/panopoly_theme.info        |   6 +-
 .../panopoly/panopoly_widgets/CHANGELOG.txt   |  11 +
 ...nopoly_widgets.features.field_instance.inc |   8 +-
 .../panopoly_widgets/panopoly_widgets.info    |   6 +-
 .../panopoly_widgets/panopoly_widgets.install |  54 +++++
 .../panopoly_widgets/panopoly_widgets.make    |   4 +-
 .../panopoly_widgets.spotlight.inc            |  26 ++-
 .../fieldable-panels-pane.preprocess.inc      |   4 +-
 .../wcm_omega/preprocess/page.preprocess.inc  |   8 +-
 profiles/wcm_base/wcm_base.make               |  16 +-
 82 files changed, 1646 insertions(+), 288 deletions(-)
 create mode 100644 profiles/wcm_base/modules/contrib/admin_menu/PATCHES.txt
 create mode 100644 profiles/wcm_base/modules/contrib/apps/PATCHES.txt
 create mode 100644 profiles/wcm_base/modules/contrib/libraries/css/libraries.admin.css
 create mode 100644 profiles/wcm_base/modules/contrib/libraries/libraries.theme.inc
 create mode 100644 profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_numeric.inc
 create mode 100644 profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_content_cache.inc
 create mode 100644 profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.install

diff --git a/profiles/wcm_base/CHANGELOG.txt b/profiles/wcm_base/CHANGELOG.txt
index 647c98fa..3c7aed04 100644
--- a/profiles/wcm_base/CHANGELOG.txt
+++ b/profiles/wcm_base/CHANGELOG.txt
@@ -1,3 +1,8 @@
+WCM Base 7.x-1.10-rc3, 2019-01-14
+---------------------------------
+- WCM Base: Updated Panopoly to 1.58.
+- WCM Omega: Updated FPP preprocess for PHP 7.1 compatability.
+
 WCM Base 7.x-1.10-rc2, 2019-01-02
 ---------------------------------
 - WCM Base: Added SMTP module patch for webform email attachments.
diff --git a/profiles/wcm_base/modules/contrib/admin_menu/PATCHES.txt b/profiles/wcm_base/modules/contrib/admin_menu/PATCHES.txt
new file mode 100644
index 00000000..fc460af5
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/admin_menu/PATCHES.txt
@@ -0,0 +1,4 @@
+The following patches have been applied to this project:
+- https://www.drupal.org/files/issues/admin-menu-2929025-each-function-deprecated-php-7.2.patch
+
+This file was automatically generated by Drush Make (http://drupal.org/project/drush).
diff --git a/profiles/wcm_base/modules/contrib/admin_menu/admin_menu.inc b/profiles/wcm_base/modules/contrib/admin_menu/admin_menu.inc
index 2eab789b..e6169df7 100644
--- a/profiles/wcm_base/modules/contrib/admin_menu/admin_menu.inc
+++ b/profiles/wcm_base/modules/contrib/admin_menu/admin_menu.inc
@@ -204,7 +204,7 @@ function admin_menu_merge_tree(array &$tree, array $tree_dynamic, array $expand_
         foreach ($load_functions as $index => $function) {
           if ($function) {
             if (is_array($function)) {
-              list($function,) = each($function);
+              $function = key($function);
             }
             // Add the loader function name minus "_load".
             $placeholder = '%' . substr($function, 0, -5);
diff --git a/profiles/wcm_base/modules/contrib/apps/PATCHES.txt b/profiles/wcm_base/modules/contrib/apps/PATCHES.txt
new file mode 100644
index 00000000..b8df8029
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/apps/PATCHES.txt
@@ -0,0 +1,4 @@
+The following patches have been applied to this project:
+- https://www.drupal.org/files/issues/apps-php7-compat-2945929.patch
+
+This file was automatically generated by Drush Make (http://drupal.org/project/drush).
diff --git a/profiles/wcm_base/modules/contrib/apps/apps.profile.inc b/profiles/wcm_base/modules/contrib/apps/apps.profile.inc
index 78376f71..91d23a3b 100644
--- a/profiles/wcm_base/modules/contrib/apps/apps.profile.inc
+++ b/profiles/wcm_base/modules/contrib/apps/apps.profile.inc
@@ -509,7 +509,7 @@ function apps_profile_check_dependencies($module_list) {
   // Create an associative array with weights as values.
   $module_list = array_flip(array_values($module_list));
 
-  while (list($module) = each($module_list)) {
+  foreach ($module_list as $module => $info) {
     if (!isset($module_data[$module])) {
       // This module is not found in the filesystem, abort.
       return FALSE;
diff --git a/profiles/wcm_base/modules/contrib/defaultcontent/PATCHES.txt b/profiles/wcm_base/modules/contrib/defaultcontent/PATCHES.txt
index 0d26fb08..f4435d04 100644
--- a/profiles/wcm_base/modules/contrib/defaultcontent/PATCHES.txt
+++ b/profiles/wcm_base/modules/contrib/defaultcontent/PATCHES.txt
@@ -1,5 +1,6 @@
 The following patches have been applied to this project:
 - http://drupal.org/files/1754428-allow-node-export-alter.patch
 - http://drupal.org/files/1757782-cannot-import-menu-hierarchy-8.patch
+- https://www.drupal.org/files/issues/defaultcontent-php7-compat-2946138.patch
 
 This file was automatically generated by Drush Make (http://drupal.org/project/drush).
diff --git a/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.info b/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.info
index e18aaa6f..ef9fb68b 100644
--- a/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.info
+++ b/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.info
@@ -2,6 +2,7 @@ name = Default Content
 description = Allows import/export of default content.
 core = 7.x
 package = Features
+php = 5.3
 dependencies[] = features
 dependencies[] = ctools
 dependencies[] = menu
diff --git a/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.module b/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.module
index 93e1e8e5..d295e7ae 100644
--- a/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.module
+++ b/profiles/wcm_base/modules/contrib/defaultcontent/defaultcontent.module
@@ -428,7 +428,10 @@ function defaultcontent_get_alter_plugins($use = FALSE) {
   }
 
   if ($use) {
-    usort($plugins, create_function('$a, $b', "return \$a['$use weight'] - \$b['$use weight'];"));
+    usort($plugins, function ($a, $b) use ($use) {
+      $weight_key = $use . ' weight';
+      return $a[$weight_key] - $b[$weight_key];
+    });
   }
 
   return $plugins;
diff --git a/profiles/wcm_base/modules/contrib/libraries/CHANGELOG.txt b/profiles/wcm_base/modules/contrib/libraries/CHANGELOG.txt
index 33fa5e8a..bec30401 100644
--- a/profiles/wcm_base/modules/contrib/libraries/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/contrib/libraries/CHANGELOG.txt
@@ -1,4 +1,21 @@
 
+Libraries 7.x-2.5, 2018-10-5
+-----------------------------
+#2815965 by plach, Manav, tstoeckler, Proteo: Base theme is not loaded when checking for theme library info
+#2999116 by Anghelu, joshbrown81: Finds no library after update
+
+Libraries 7.x-2.4, 2018-09-10
+-----------------------------
+#2779591 by mark_fullmer, cglauren, improved PHP 7.x.x support.
+#2699799 by flaviovs, hanoii: Support reading version from package.json.
+#2816781 by joelstein: Add a 'access library reports' permission.
+#2823735 by amanaplan, tstoeckler: Add admin_menu cache clear integration.
+#2745763 by Albert Volkman, tstoeckler: Allow downloading all libraries at once.
+#2310753 by tstoeckler: Avoid libraries_get_libraries() scanning the root.
+#2341955 by sadashiv, tstoeckler: Clear library cache on library report.
+#819610 by tstoeckler: Show variants and dependencies in the UI.
+#2724925 by ron_s, tstoeckler: Separate installed from uninstalled libraries.
+
 Libraries 7.x-2.3, 2016-05-12
 -----------------------------
 #1884246 by BR0kEN, tstoeckler et al: Allow downloading libraries via Drush.
@@ -94,17 +111,11 @@ by sun: Fixed testbot breaks upon .info file without .module file.
 #719896 by tstoeckler, sun: Added starting point for hook_libraries_info().
 
 
-Libraries 7.x-1.x, xxxx-xx-xx
------------------------------
-
 Libraries 7.x-1.0, 2010-01-27
 -----------------------------
 #743522 by sun: Ported to D7.
 
 
-Libraries 6.x-1.x, xxxx-xx-xx
------------------------------
-
 Libraries 6.x-1.0, 2010-01-27
 -----------------------------
 #1028744 by tstoeckler: Code clean-up.
diff --git a/profiles/wcm_base/modules/contrib/libraries/css/libraries.admin.css b/profiles/wcm_base/modules/contrib/libraries/css/libraries.admin.css
new file mode 100644
index 00000000..f344ff0c
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/libraries/css/libraries.admin.css
@@ -0,0 +1,3 @@
+.libraries-table {
+  margin-bottom: 2em;
+}
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.admin.inc b/profiles/wcm_base/modules/contrib/libraries/libraries.admin.inc
index 8d9e0fbd..29ddec14 100644
--- a/profiles/wcm_base/modules/contrib/libraries/libraries.admin.inc
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.admin.inc
@@ -20,41 +20,112 @@
  *   The form array for the overview form.
  */
 function libraries_admin_overview(array $form, array &$form_state) {
-  $header = array(t('Name'), t('Status'), t('Installed version'), t('Provider'), t('Links'));
-  $rows = array();
-
-  $libraries = libraries_detect();
-  uasort($libraries, 'libraries_admin_sort_title');
-
-  foreach ($libraries as $machine_name => $library) {
+  // Only show variants for installed libraries.
+  $header_installed = array(t('Name'), t('Version'), t('Variants'), t('Dependencies'), t('Provider'), t('Links'));
+  // Only show status for libraries with an error.
+  $header_error = array(t('Name'), t('Status'), t('Version'), t('Dependencies'), t('Provider'), t('Links'));
+  // For unregistered libraries the only information we can show is the path.
+  $header_unregistered = array(t('Name'), t('Path'));
+
+  $rows_installed = array();
+  $rows_error = array();
+  $rows_unregistered = array();
+
+  // Registered libraries: we prefer to use libraries_detect() since it provides
+  // library metadata.
+  $libraries_registered = libraries_detect();
+  uasort($libraries_registered, 'libraries_admin_sort_title');
+
+  // Unregistered libraries: modules can depend on Libraries API without sharing
+  // metadata by using libraries_get_path(). Libraries can also be placed in the
+  // filesystem that are incorrectly installed, a wrong version, or a standalone
+  // not connected to any module. In these cases, libraries_get_libraries()
+  // provides a full library list. Libraries found by libraries_get_libraries(),
+  // but not identified by libraries_detect, are displayed in a separate table.
+  $libraries_unregistered = libraries_get_libraries();
+  natcasesort($libraries_unregistered);
+
+  foreach ($libraries_registered as $machine_name => $library) {
     $actions = array();
+    $row = array();
 
     if ($library['vendor url']) {
-      $actions[] = l('Homepage', $library['vendor url']);
+      $actions[] = l(t('Homepage'), $library['vendor url']);
     }
     if ($library['download url']) {
-      $actions[] = l('Download', $library['download url']);
+      $actions[] = l(t('Download'), $library['download url']);
+    }
+
+    $row['data'][] = l($library['name'], 'admin/reports/libraries/' . $machine_name);
+    // Only show status for libraries with an error. See above.
+    if (!$library['installed']) {
+      $row['data'][] = drupal_ucfirst($library['error']);
+    }
+    $row['data'][] = isset($library['version']) ? $library['version'] : '';
+    if ($library['installed']) {
+      $row['data'][] = implode(', ', array_keys($library['variants']));
+    }
+    $row['data'][] = libraries_admin_get_dependencies($library);
+    $row['data'][] = libraries_admin_get_provider_with_type($library);
+    $row['data'][] = implode(' | ', $actions);
+    $row['class'] = $library['installed'] ? array('ok') : array('warning');
+
+    if ($library['installed']) {
+      $rows_installed[] = $row;
     }
+    else {
+      $rows_error[] = $row;
+    }
+
+    // Filter registered libraries from unregistered libraries.
+    unset($libraries_unregistered[$library['machine name']]);
+  }
+
+  // Build table of registered libraries with installed status.
+  $form['libraries']['installed'] = array(
+    '#theme' => 'libraries_table_with_title',
+    '#title' => t('Installed'),
+    '#header' => $header_installed,
+    '#rows' => $rows_installed,
+    '#description' => t('These libraries are registered and installed correctly.'),
+    '#empty' => t('There are currently no libraries that are registered and installed.'),
+  );
+
+  // Build table of registered libraries with error status.
+  $form['libraries']['error'] = array(
+    '#theme' => 'libraries_table_with_title',
+    '#title' => t('Uninstalled'),
+    '#header' => $header_error,
+    '#rows' => $rows_error,
+    '#description' => t('These libraries are registered but not installed. They may not need to be installed in case a module or theme provides optional integration with a library.'),
+    '#empty' => t('There are currently no libraries that are registered but not installed.'),
+  );
 
-    $rows[] = array(
+  // Build table of unregistered libraries.
+  foreach ($libraries_unregistered as $name => $path) {
+    $rows_unregistered[] = array(
       'data' => array(
-        l($library['name'], 'admin/reports/libraries/' . $machine_name),
-        ($library['installed'] ? t('OK') : drupal_ucfirst($library['error'])),
-        (isset($library['version']) ? $library['version'] : ''),
-        libraries_admin_get_provider_with_type($library),
-        implode(' | ', $actions),
+        $name,
+        $path,
       ),
-      'class' => ($library['installed'] ? array('ok') : array('error')),
     );
   }
-
-  $form['libraries']['list'] = array(
-    '#theme' => 'table',
-    '#header' => $header,
-    '#rows' => $rows,
-    '#empty' => t('There are currently no libraries installed'),
+  $form['libraries']['unregistered'] = array(
+    '#theme' => 'libraries_table_with_title',
+    '#title' => t('Unregistered'),
+    '#header' => $header_unregistered,
+    '#rows' => $rows_unregistered,
+    '#description' => t('These libraries were found in the filesystem but there is no metadata about them.'),
+    // Do not show the table at all, if there are no unregistered libraries.
+    '#access' => (bool) $libraries_unregistered,
   );
 
+  // Clear the cached library information so that the library can be loaded if
+  // it was just downloaded. Because these instructions use libraries_detect()
+  // directly, they will never use the cached information, but this avoids the
+  // overview showing a library as installed but it not being loadable.
+  libraries_cache_clear();
+
   return $form;
 }
 
@@ -99,11 +170,11 @@ function libraries_admin_library_status_form(array $form, array &$form_state, $l
         break;
 
       case 'missing dependency':
-        $form['instructions']['instruction']['#markup'] = t('There a missing dependency in your configuration that prevent this library to work properly.') . '<br>';
+        $form['instructions']['instruction']['#markup'] = t('There is a missing dependency in your configuration that prevents this library from working properly.') . '<br>';
         break;
 
       case 'incompatible dependency':
-        $form['instructions']['instruction']['#markup'] = t('There an incompatible dependency in your configuration that prevent this library to work properly.') . '<br>';
+        $form['instructions']['instruction']['#markup'] = t('There is an incompatible dependency in your configuration that prevents this library from working properly.') . '<br>';
         break;
     }
   }
@@ -483,6 +554,28 @@ function libraries_admin_sort_title(array $a, array $b) {
   return strnatcasecmp($a['name'], $b['name']);
 }
 
+/**
+ * Returns the library's dependencies, if any.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return string
+ *   The dependencies.
+ */
+function libraries_admin_get_dependencies($library) {
+  $dependencies = array();
+  foreach ($library['dependencies'] as $dependency_name) {
+    if ($dependency = libraries_info($dependency_name)) {
+      $dependencies[] = $dependency['name'];
+    }
+    else {
+      $dependencies[] = $dependency_name;
+    }
+  }
+  return implode(', ', $dependencies);
+}
+
 /**
  * Returns the library's provider.
  *
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.api.php b/profiles/wcm_base/modules/contrib/libraries/libraries.api.php
index 71e90e0c..fe0c2418 100644
--- a/profiles/wcm_base/modules/contrib/libraries/libraries.api.php
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.api.php
@@ -47,6 +47,8 @@
  *     Unless 'version' is declared or libraries_get_version() is being used as
  *     a version callback, 'version callback' must be declared. In the latter
  *     case, however, 'version arguments' must be declared in the specified way.
+ *     For libraries that provide a package.json file, use
+ *     'libraries_get_package_json_version' as the version callback.
  *   - version arguments: (optional) A list of arguments to pass to the version
  *     callback. Version arguments can be declared either as an associative
  *     array whose keys are the argument names or as an indexed array without
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.drush.inc b/profiles/wcm_base/modules/contrib/libraries/libraries.drush.inc
index 32587135..550b7af5 100644
--- a/profiles/wcm_base/modules/contrib/libraries/libraries.drush.inc
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.drush.inc
@@ -23,7 +23,9 @@ function libraries_drush_command() {
     'arguments' => array(
       'libraries' => 'A comma delimited list of library machine names.',
     ),
-    'required-arguments' => TRUE,
+    'options' => array(
+      'all' => 'Download all registered libraries.',
+    ),
   );
 
   return $items;
@@ -42,10 +44,7 @@ function libraries_drush_cache_clear(array &$types) {
  * Clears the library cache.
  */
 function libraries_drush_invalidate_cache() {
-  // @see drupal_flush_all_caches()
-  foreach (libraries_flush_caches() as $table) {
-    cache_clear_all('*', $table, TRUE);
-  }
+  libraries_cache_clear();
 }
 
 /**
@@ -109,28 +108,61 @@ function drush_libraries_list() {
 function drush_libraries_download() {
   drush_command_include('pm-download');
 
-  $libraries = libraries_info();
+  $all_libraries = libraries_detect();
 
-  // @todo Consider supporting downloading all downloadable libraries.
-  // @todo Consider offering a selection if no library is specified.
-  foreach (pm_parse_arguments(func_get_args(), FALSE) as $machine_name) {
-    if (!isset($libraries[$machine_name])) {
-      $message = dt("The !library library is not registered with Libraries API.\n", array('!library' => $machine_name));
-      $message .= dt("Provide an info file for it or implement hook_libraries_info().\n");
-      $message .= dt("See hook_libraries_info() for more information.\n");
-      drush_set_error('DRUSH_LIBRARY_UKNOWN', $message);
-      continue;
+  // Prepare a list of names of downloadable libraries.
+  $downloadable_names = array();
+  foreach ($all_libraries as $machine_name => $library) {
+    // Skip libraries that are already installed.
+    // @todo Allow (optionally) re-downloading installing libraries.
+    if (!empty($library['download file url']) && !$library['installed']) {
+      $downloadable_names[] = $machine_name;
     }
-    $library = $libraries[$machine_name];
+  }
 
-    if (empty($library['download file url'])) {
-      $message = dt("The !library library cannot be downloaded.\n", array('!library' => $machine_name));
-      $message .= dt("Libraries need to specify a download file URL to support being downloaded via Drush.\n");
-      $message .= dt("See hook_libraries_info() for more information.\n");
-      drush_set_error('DRUSH_LIBRARY_NOT_DOWNLOADABLE', $message);
-      continue;
+  // Gather a list of libraries to download. If '--all' was specified, that
+  // takes precedence over any other arguments. Otherwise and if no arguments
+  // are specified, we present a choice of all downloadable libraries.
+  if (drush_get_option('all', FALSE) && $downloadable_names) {
+    $machine_names = $downloadable_names;
+  }
+  elseif (pm_parse_arguments(func_get_args(), FALSE)) {
+    $machine_names = array();
+    foreach (pm_parse_arguments(func_get_args(), FALSE) as $machine_name) {
+      // If there was an error with with one of the libraries, continue to try
+      // to install any remaining libraries.
+      if (!isset($all_libraries[$machine_name])) {
+        $message = dt("The !library library is not registered with Libraries API.\n", array('!library' => $machine_name));
+        $message .= dt("Provide an info file for it or implement hook_libraries_info().\n");
+        $message .= dt("See hook_libraries_info() for more information.\n");
+        drush_set_error('DRUSH_LIBRARY_UKNOWN', $message);
+        continue;
+      }
+      if (empty($all_libraries[$machine_name]['download file url'])) {
+        $message = dt("The !library library cannot be downloaded.\n", array('!library' => $machine_name));
+        $message .= dt("Libraries need to specify a download file URL to support being downloaded via Drush.\n");
+        $message .= dt("See hook_libraries_info() for more information.\n");
+        drush_set_error('DRUSH_LIBRARY_NOT_DOWNLOADABLE', $message);
+        continue;
+      }
+      $machine_names[] = $machine_name;
+    }
+  }
+  elseif ($downloadable_names) {
+    $machine_names = drush_choice_multiple(drupal_map_assoc($downloadable_names), FALSE, 'Select which libraries to download.');
+    // If the operation was cancelled by the user, or if no libraries were
+    // selected, bail out without any further error message.
+    if (!$machine_names) {
+      return;
     }
-    $download_url = $library['download file url'];
+  }
+  else {
+    drush_log(dt('There are no registered, uninstalled libraries that can be downloaded.'), 'warning');
+    return;
+  }
+
+  foreach ($machine_names as $machine_name) {
+    $download_url = $all_libraries[$machine_name]['download file url'];
 
     drush_log(dt('Downloading library !name ...', array('!name' => $machine_name)));
 
@@ -205,7 +237,7 @@ function drush_libraries_download() {
         drush_delete_dir($install_location, TRUE);
       }
       else {
-        drush_log(dt("Skip installation of !project to !dest.", array('!project' => $library['machine name'], '!dest' => $install_location)), 'warning');
+        drush_log(dt("Skip installation of !project to !dest.", array('!project' => $machine_name, '!dest' => $install_location)), 'warning');
         continue;
       }
     }
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.info b/profiles/wcm_base/modules/contrib/libraries/libraries.info
index dcd2d486..e721cb4c 100644
--- a/profiles/wcm_base/modules/contrib/libraries/libraries.info
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.info
@@ -8,9 +8,8 @@ files[] = tests/LibrariesLoadWebTest.test
 files[] = tests/LibrariesUnitTest.test
 files[] = tests/LibrariesWebTestBase.test
 
-; Information added by Drupal.org packaging script on 2016-05-12
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-05
+version = "7.x-2.5"
 core = "7.x"
 project = "libraries"
-datestamp = "1463077450"
-
+datestamp = "1538770685"
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.install b/profiles/wcm_base/modules/contrib/libraries/libraries.install
index ebc4087b..e8c795ff 100644
--- a/profiles/wcm_base/modules/contrib/libraries/libraries.install
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.install
@@ -34,3 +34,13 @@ function libraries_update_7201() {
   // during the 7.x-2.x cycle.
   registry_rebuild();
 }
+
+/**
+ * Grant the "View library reports" permission to roles with the "View site reports" permission.
+ */
+function libraries_update_7202() {
+  $rids = array_keys(user_roles(FALSE, 'access site reports'));
+  foreach ($rids as $rid) {
+    _update_7000_user_role_grant_permissions($rid, array('access library reports'), 'libraries');
+  }
+}
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.module b/profiles/wcm_base/modules/contrib/libraries/libraries.module
index 48275250..480289cd 100644
--- a/profiles/wcm_base/modules/contrib/libraries/libraries.module
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.module
@@ -25,6 +25,29 @@ function libraries_flush_caches() {
   }
 }
 
+/**
+ * Implements hook_admin_menu_cache_info().
+ */
+function libraries_admin_menu_cache_info() {
+  $caches['libraries'] = array(
+    'title' => t('Libraries'),
+    'callback' => 'libraries_cache_clear',
+  );
+  return $caches;
+}
+
+/**
+ * Clears the cached library information.
+ */
+function libraries_cache_clear() {
+  foreach (libraries_flush_caches() as $bin) {
+    // Using the wildcard argument leads to DrupalDatabaseCache::clear()
+    // truncating the libraries cache table which is more performant that
+    // deleting the rows.
+    cache_clear_all('*', $bin, TRUE);
+  }
+}
+
 /**
  * Gets the path of a library.
  *
@@ -56,6 +79,52 @@ function libraries_get_path($name, $base_path = FALSE) {
   return $path;
 }
 
+/**
+ * Returns all enabled themes.
+ *
+ * Themes are sorted so that base themes always precede their child themes.
+ *
+ * @return array
+ *   An associative array of theme objects keyed by theme name.
+ */
+function libraries_get_enabled_themes() {
+  $themes = array();
+  foreach (list_themes() as $name => $theme) {
+    if ($theme->status) {
+      $themes[$name] = $theme;
+    }
+  }
+
+  return libraries_sort_themes($themes);
+}
+
+/**
+ * Sort a themes array.
+ *
+ * @param array $themes
+ *   Array of themes as objects, keyed by theme name.
+ * @param string $base
+ *   A base theme (internal use only).
+ *
+ * @return array
+ *   A similar array to $themes, but sorted in such a way that subthemes are
+ *   always located after its base theme.
+ */
+function libraries_sort_themes($themes, $base = '') {
+  $output = array();
+  foreach ($themes as $name => $theme) {
+    if (!isset($theme->base_theme) || $theme->base_theme == $base) {
+      $output[$name] = $theme;
+      unset($themes[$name]);
+      $subthemes = libraries_sort_themes($themes, $name);
+      foreach ($subthemes as $sub_name => $subtheme) {
+        $output[$sub_name] = $subtheme;
+      }
+    }
+  }
+  return $output;
+}
+
 /**
  * Returns an array of library directories.
  *
@@ -77,6 +146,13 @@ function libraries_get_libraries() {
   $profile = drupal_get_path('profile', drupal_get_profile());
   $config = conf_path();
 
+  // $config and $profile should never be empty in a proper Drupal setup.
+  // However, we should never search into the root filesystem under any
+  // circumstances, so just bail out in that case.
+  if (!$profile && !$config) {
+    return array();
+  }
+
   // Similar to 'modules' and 'themes' directories in the root directory,
   // certain distributions may want to place libraries into a 'libraries'
   // directory in Drupal's root directory.
@@ -358,10 +434,12 @@ function &libraries_info($name = NULL) {
       }
     }
 
-    // Gather information from hook_libraries_info() in enabled themes.
+    // Gather information from hook_libraries_info() in enabled themes. Themes
+    // are sorted to ensure that a base theme's template.php is included before
+    // its children's ones.
     $themes = array();
-    foreach (list_themes() as $theme_name => $theme_info) {
-      if ($theme_info->status && file_exists(drupal_get_path('theme', $theme_name) . '/template.php')) {
+    foreach (libraries_get_enabled_themes() as $theme_name => $theme_info) {
+      if (file_exists(drupal_get_path('theme', $theme_name) . '/template.php')) {
         // Collect a list of viable themes for re-use when calling the alter
         // hook.
         $themes[] = $theme_name;
@@ -546,7 +624,7 @@ function libraries_detect($name = NULL) {
       $library['version'] = call_user_func_array($library['version callback'], array_merge(array($library), $library['version arguments']));
     }
     else {
-      $library['version'] = call_user_func($library['version callback'], $library, $library['version arguments']);
+      $library['version'] = call_user_func_array($library['version callback'], array(&$library, $library['version arguments']));
     }
     if (empty($library['version'])) {
       $library['error'] = 'not detected';
@@ -887,16 +965,56 @@ function libraries_get_version($library, $options) {
   fclose($file);
 }
 
+/**
+ * Gets the version information from a library's package.json file.
+ *
+ * @param $library
+ *   An associative array containing all information about the library.
+ * @param $options
+ *   This callback expects no option.
+ * @return
+ *   A string containing the version of the library.
+ *
+ * @see libraries_get_path()
+ */
+function libraries_get_package_json_version($library, $options) {
+  $file = DRUPAL_ROOT . '/' . $library['library path'] . '/package.json';
+  if (!file_exists($file)) {
+    return;
+  }
+
+  $content = file_get_contents($file);
+  if (!$content) {
+    return;
+  }
+
+  $data = drupal_json_decode($content);
+  if (isset($data['version'])) {
+    return $data['version'];
+  }
+}
+
 /**
  * Implements hook_help().
  */
 function libraries_help($path, $arg) {
   switch ($path) {
     case 'admin/reports/libraries':
-      return t('Click on a library for a status report or detailed installation instructions in case the library is not installed correctly.');
+      return t('Click on a library for a status report or detailed installation instructions.');
   }
 }
 
+/**
+ * Implements hook_permission().
+ */
+function libraries_permission() {
+  return array(
+    'access library reports' => array(
+      'title' => t('View library reports'),
+    ),
+  );
+}
+
 /**
  * Implements hook_menu().
  */
@@ -907,7 +1025,7 @@ function libraries_menu() {
     'description' => 'An overview of libraries installed on this site.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('libraries_admin_overview'),
-    'access arguments' => array('access site reports'),
+    'access arguments' => array('access library reports'),
     'file' => 'libraries.admin.inc'
   );
   $items['admin/reports/libraries/%libraries_ui'] = array(
@@ -915,7 +1033,7 @@ function libraries_menu() {
     'description' => 'Status overview for a single library',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('libraries_admin_library_status_form', 3),
-    'access arguments' => array('access site reports'),
+    'access arguments' => array('access library reports'),
     'file' => 'libraries.admin.inc'
   );
   return $items;
@@ -944,3 +1062,19 @@ function libraries_menu() {
 function libraries_ui_load($name) {
   return libraries_detect($name);
 }
+
+/**
+ * Implements hook_theme().
+ */
+function libraries_theme($existing, $type, $theme, $path) {
+  // Because we extend the 'table' theme function, fetch the respective
+  // variables dynamically.
+  $common_theme = drupal_common_theme();
+  $variables = $common_theme['table']['variables'] + array('title' => '', 'description' => '');
+  return array(
+    'libraries_table_with_title' => array(
+      'variables' => $variables,
+      'file' => 'libraries.theme.inc',
+    ),
+  );
+}
diff --git a/profiles/wcm_base/modules/contrib/libraries/libraries.theme.inc b/profiles/wcm_base/modules/contrib/libraries/libraries.theme.inc
new file mode 100644
index 00000000..ff3ed719
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/libraries/libraries.theme.inc
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Provides theme and preprocess functions for Libraries API.
+ */
+
+/**
+ * Prepare variables for theming a table with a title.
+ * 
+ * @param array $variables
+ *   An array of theme variables, passed by reference.
+ */
+function template_preprocess_libraries_table_with_title(&$variables) {
+  drupal_add_css(drupal_get_path('module', 'libraries') . '/css/libraries.admin.css');
+
+  $variables['attributes'] += array('class' => array());
+  $variables['attributes']['class'][] = 'libraries-table';
+}
+
+/**
+ * Returns HTML for a table with a title.
+ * 
+ * @param array $variables
+ *   An array theme variables.
+ * 
+ * @return string
+ *   The HTML output for this table with a title.
+ */
+function theme_libraries_table_with_title(array $variables) {
+  $output = '';
+  $output .= '<h2>' . $variables['title'] . '</h2>';
+  $output .= '<div class="description">' . $variables['description'] . '</div>';
+  $output .= theme_table($variables);
+  return $output;
+}
diff --git a/profiles/wcm_base/modules/contrib/libraries/tests/LibrariesAdminWebTest.test b/profiles/wcm_base/modules/contrib/libraries/tests/LibrariesAdminWebTest.test
index a4d2188b..87c9de0e 100644
--- a/profiles/wcm_base/modules/contrib/libraries/tests/LibrariesAdminWebTest.test
+++ b/profiles/wcm_base/modules/contrib/libraries/tests/LibrariesAdminWebTest.test
@@ -40,8 +40,20 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
    * Tests the libraries report at /admin/reports/libraries.
    */
   public function testLibrariesReportOverview() {
-    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries');
-    $this->assertRaw('Libraries');
+    $this->getWithPermissions(array('access library reports'), 'admin/reports/libraries');
+    // Assert the page title and table titles show up.
+    $this->assertText('Libraries');
+    $this->assertRaw('<h2>Installed</h2>');
+    $this->assertRaw('<h2>Uninstalled</h2>');
+
+    // Make sure the table headings show up.
+    $this->assertText('Name');
+    $this->assertText('Status');
+    $this->assertText('Version');
+    $this->assertText('Variants');
+    $this->assertText('Dependencies');
+    $this->assertText('Provider');
+    $this->assertText('Links');
 
     // Make sure that all the libraries are listed.
     $libraries = libraries_info();
@@ -51,8 +63,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
       $this->assertLinkByHref('admin/reports/libraries/' . $library['machine name']);
     }
 
-    // Make sure that all possible statuses are displayed.
-    $this->assertText('OK');
+    // Make sure that all possible error statuses are displayed.
     $this->assertText('Not found');
     $this->assertText('Not detected');
     $this->assertText('Not supported');
@@ -73,7 +84,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
    * Tests the libraries report for an installed library.
    */
   public function testLibrariesReportInstalled() {
-    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_files');
+    $this->getWithPermissions(array('access library reports'), 'admin/reports/libraries/example_files');
     $this->assertRaw('Status report for library <em class="placeholder">Example files</em>');
     $this->assertRaw('The <em class="placeholder">Example files</em> library is installed correctly.');
     // Check that the information in the status report is displayed.
@@ -88,7 +99,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
    * Tests the libraries report for a missing library.
    */
   public function testLibrariesReportMissing() {
-    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_missing');
+    $this->getWithPermissions(array('access library reports'), 'admin/reports/libraries/example_missing');
     $this->assertRaw('Status report for library <em class="placeholder">Example missing</em>');
     $this->assertRaw('The <em class="placeholder">Example missing</em> library could not be found.');
     // Check that the download link is being displayed.
@@ -100,7 +111,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
    * Tests the libraries report for a missing library.
    */
   public function testLibrariesReportNotDetected() {
-    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_undetected_version');
+    $this->getWithPermissions(array('access library reports'), 'admin/reports/libraries/example_undetected_version');
     $this->assertRaw('Status report for library <em class="placeholder">Example undetected version</em>');
     $this->assertRaw('The version of the <em class="placeholder">Example undetected version</em> library could not be detected.');
   }
@@ -109,7 +120,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
    * Tests the libraries report for a missing library.
    */
   public function testLibrariesReportNotSupported() {
-    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_unsupported_version');
+    $this->getWithPermissions(array('access library reports'), 'admin/reports/libraries/example_unsupported_version');
     $this->assertRaw('Status report for library <em class="placeholder">Example unsupported version</em>');
     $this->assertRaw('The installed version <em class="placeholder">1</em> of the <em class="placeholder">Example unsupported version</em> library is not supported.');
     // Check that the download link is being displayed.
diff --git a/profiles/wcm_base/modules/contrib/libraries/tests/libraries/example_info_file.libraries.info b/profiles/wcm_base/modules/contrib/libraries/tests/libraries/example_info_file.libraries.info
index 11152731..83ba8a83 100644
--- a/profiles/wcm_base/modules/contrib/libraries/tests/libraries/example_info_file.libraries.info
+++ b/profiles/wcm_base/modules/contrib/libraries/tests/libraries/example_info_file.libraries.info
@@ -2,9 +2,8 @@
 name = Example info file
 
 
-; Information added by Drupal.org packaging script on 2016-05-12
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-05
+version = "7.x-2.5"
 core = "7.x"
 project = "libraries"
-datestamp = "1463077450"
-
+datestamp = "1538770685"
diff --git a/profiles/wcm_base/modules/contrib/libraries/tests/modules/libraries_test_module/libraries_test_module.info b/profiles/wcm_base/modules/contrib/libraries/tests/modules/libraries_test_module/libraries_test_module.info
index 7ad319a2..756d6a8f 100644
--- a/profiles/wcm_base/modules/contrib/libraries/tests/modules/libraries_test_module/libraries_test_module.info
+++ b/profiles/wcm_base/modules/contrib/libraries/tests/modules/libraries_test_module/libraries_test_module.info
@@ -5,9 +5,8 @@ package = Testing
 dependencies[] = libraries
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2016-05-12
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-05
+version = "7.x-2.5"
 core = "7.x"
 project = "libraries"
-datestamp = "1463077450"
-
+datestamp = "1538770685"
diff --git a/profiles/wcm_base/modules/contrib/libraries/tests/themes/libraries_test_theme/libraries_test_theme.info b/profiles/wcm_base/modules/contrib/libraries/tests/themes/libraries_test_theme/libraries_test_theme.info
index 255d1040..194954e7 100644
--- a/profiles/wcm_base/modules/contrib/libraries/tests/themes/libraries_test_theme/libraries_test_theme.info
+++ b/profiles/wcm_base/modules/contrib/libraries/tests/themes/libraries_test_theme/libraries_test_theme.info
@@ -3,9 +3,8 @@ description = Tests that themes can provide and alter library information.
 core = 7.x
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2016-05-12
-version = "7.x-2.3"
+; Information added by Drupal.org packaging script on 2018-10-05
+version = "7.x-2.5"
 core = "7.x"
 project = "libraries"
-datestamp = "1463077450"
-
+datestamp = "1538770685"
diff --git a/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.info b/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.info
index 87032aca..bca184fd 100644
--- a/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.info
+++ b/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.info
@@ -5,9 +5,8 @@ package = Panels
 dependencies[] = ctools
 dependencies[] = page_manager
 dependencies[] = panels
-; Information added by Drupal.org packaging script on 2014-09-12
-version = "7.x-2.2"
+; Information added by Drupal.org packaging script on 2018-08-27
+version = "7.x-2.3"
 core = "7.x"
 project = "panels_breadcrumbs"
-datestamp = "1410481728"
-
+datestamp = "1535382184"
diff --git a/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.module b/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.module
index d009364c..04939dc0 100644
--- a/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.module
+++ b/profiles/wcm_base/modules/contrib/panels_breadcrumbs/panels_breadcrumbs.module
@@ -18,7 +18,7 @@ function panels_breadcrumbs_page_manager_variant_operations_alter(&$operations,
   // Use this obnoxious construct to safely insert our item.
   reset($operations['children']);
   $children_operations = array();
-  while (list($key, $value) = each($operations['children'])) {
+  foreach ($operations['children'] as $key => $value) {
     $children_operations[$key] = $value;
     if ($key == 'context') {
       $children_operations['breadcrumb'] = array(
@@ -156,62 +156,74 @@ function panels_breadcrumbs_partial_configuration_form($conf, $contexts) {
  *   FALSE if the breadcrumb could not be built with the given configuration.
  */
 function panels_breadcrumbs_build_breadcrumb($conf, $contexts, $override = FALSE) {
-  $breadcrumbs = array();
-
-  // If no titles or paths are defined, bail out.
-  if (!isset($conf['panels_breadcrumbs_titles']) || !isset($conf['panels_breadcrumbs_paths'])) {
-    return;
-  }
-
-  // Look for placeholder tokens in paths and convert them for this display
-  $titles = $conf['panels_breadcrumbs_titles'];
-  $paths = ctools_context_keyword_substitute($conf['panels_breadcrumbs_paths'], array(), $contexts);
+  $breadcrumbs = &drupal_static(__FUNCTION__);
+
+  if (empty($breadcrumbs)) {
+    // If no titles or paths are defined, bail out.
+    if (!isset($conf['panels_breadcrumbs_titles']) || !isset($conf['panels_breadcrumbs_paths'])) {
+      // Do not store anything in the static $breadcrumbs variable, in order to
+      // allow a possible fallback with another breadcrumb configuration.
+      return;
+    }
 
-  // Break titles and paths into arrays and remove empty keys
-  $titles = array_filter(array_map('trim', explode(PHP_EOL, $titles)), 'strlen');
-  $paths = array_filter(array_map('trim', explode(PHP_EOL, $paths)), 'strlen');
+    // The configuration is active and is the first triggered, so we don't allow
+    // another breadcrumb configuration to override it by setting the static
+    // variable.
+    $breadcrumbs = array();
+
+    // Look for placeholder tokens in paths and convert them for this display
+    $titles = $conf['panels_breadcrumbs_titles'];
+    $paths = ctools_context_keyword_substitute($conf['panels_breadcrumbs_paths'], array(), $contexts);
+
+    // Break titles and paths into arrays and remove empty keys
+    $titles = array_filter(array_map('trim', explode("\n", $titles)), 'strlen');
+    $paths = array_filter(array_map('trim', explode("\n", $paths)), 'strlen');
+
+    // We add in path as although it is not used to render breadcrumbs, it is
+    // required by user_menu_breadcrumb_alter().
+    $default_breadcrumb_info = array(
+      'title' => '',
+      'href' => '',
+      'localized_options' => array(),
+      'path' => '',
+    );
 
-  $default_breadcrumb_info = array(
-    'title' => '',
-    'href' => '',
-    'localized_options' => array(),
-  );
+    $breadcrumbs_info = array();
 
-  $breadcrumbs_info = array();
+    // Set the first crumb to home
+    if (!isset($conf['panels_breadcrumbs_home']) || $conf['panels_breadcrumbs_home'] == TRUE) {
+      $breadcrumbs_info[] = array('title' => t('Home'), 'href' => '<front>') + $default_breadcrumb_info;
+    }
 
-  // Set the first crumb to home
-  if (!isset($conf['panels_breadcrumbs_home']) || $conf['panels_breadcrumbs_home'] == TRUE) {
-    $breadcrumbs_info[] = array('title' => t('Home'), 'href' => '<front>') + $default_breadcrumb_info;
-  }
+    // Iterate through all crumbs and add them to the breadcrumb
+    foreach ($titles as $key => $title) {
 
-  // Iterate through all crumbs and add them to the breadcrumb
-  foreach ($titles as $key => $title) {
+      // Translate the title and convert existing placeholder tokens afterwards.
+      $translated_title = t($title);
+      $translated_title = ctools_context_keyword_substitute($translated_title, array(), $contexts);
 
-    // Translate the title and convert existing placeholder tokens afterwards.
-    $translated_title = t($title);
-    $translated_title = ctools_context_keyword_substitute($translated_title, array(), $contexts);
+      if (empty($translated_title)) {
+        continue;
+      }
 
-    if (empty($translated_title)) {
-      continue;
+      $translated_title = html_entity_decode(trim($translated_title), ENT_QUOTES, 'UTF-8');
+      $path = empty($paths[$key]) ? '<none>' : trim($paths[$key]);
+      $breadcrumbs_info[] = array('title' => $translated_title, 'href' => $path) + $default_breadcrumb_info;
     }
 
-    $translated_title = html_entity_decode(trim($translated_title), ENT_QUOTES, 'UTF-8');
-    $path = empty($paths[$key]) ? '<none>' : trim($paths[$key]);
-    $breadcrumbs_info[] = array('title' => $translated_title, 'href' => $path) + $default_breadcrumb_info;
-  }
-
-  // Allow other modules to intercept and operate changes in the breadcrumb
-  $breadcrumb_info_end = end($breadcrumbs_info);
-  drupal_alter('menu_breadcrumb', $breadcrumbs_info, $breadcrumb_info_end);
-
-  // Finally, render the breadcrumb
-  foreach ($breadcrumbs_info as $crumb) {
-    if (isset($crumb['href']) && $crumb['href'] == '<none>') {
-      $crumb['localized_options'] += array('attributes' => array(), 'html' => TRUE);
-      $breadcrumbs[] = '<span ' . drupal_attributes($crumb['localized_options']['attributes']) . '>' . ($crumb['localized_options']['html'] ? $crumb['title'] : check_plain($crumb['title'])) . '</span>';
-    }
-    else {
-      $breadcrumbs[] = l($crumb['title'], $crumb['href'], $crumb['localized_options']);
+    // Allow other modules to intercept and operate changes in the breadcrumb
+    $breadcrumb_info_end = end($breadcrumbs_info);
+    drupal_alter('menu_breadcrumb', $breadcrumbs_info, $breadcrumb_info_end);
+
+    // Finally, render the breadcrumb
+    foreach ($breadcrumbs_info as $crumb) {
+      if (isset($crumb['href']) && $crumb['href'] == '<none>') {
+        $crumb['localized_options'] += array('attributes' => array(), 'html' => TRUE);
+        $breadcrumbs[] = '<span ' . drupal_attributes($crumb['localized_options']['attributes']) . '>' . ($crumb['localized_options']['html'] ? $crumb['title'] : check_plain($crumb['title'])) . '</span>';
+      }
+      else {
+        $breadcrumbs[] = l($crumb['title'], $crumb['href'], $crumb['localized_options']);
+      }
     }
   }
 
diff --git a/profiles/wcm_base/modules/contrib/search_api/CHANGELOG.txt b/profiles/wcm_base/modules/contrib/search_api/CHANGELOG.txt
index 24c120fe..1b61a9a1 100644
--- a/profiles/wcm_base/modules/contrib/search_api/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/contrib/search_api/CHANGELOG.txt
@@ -1,3 +1,25 @@
+Search API 1.25 (2018-09-17):
+-----------------------------
+- #2408727 by swim, drunken monkey: Added a batch operation for executing
+  pending tasks.
+- #2325917 by guillaumev, drunken monkey: Added a Views cache plugin based on
+  Views Content Cache.
+- #2989578 by KarlShea, drunken monkey: Fixed Views exposed form fields for
+  "not between" operator.
+- #2982167 by osopolar, drunken monkey: Added a Drush command for re-indexing
+  specific entities.
+- #1783746 by das-peter, sammys, SpadXIII, drunken monkey, ruloweb, KarlShea,
+  heshanlk, Anas_maw, pinkonomy, Damien Tournoud, rudiedirkx: Added support
+  for the "(not) between" operator.
+- #2408727 by drunken monkey, OliverColeman: Fixed out-of-memory errors when
+  executing pending tasks.
+-  Issue #2948820 by capysara, drunken monkey: Added a link to the "need to
+  reindex" message on the Filters tab.
+- #2828883 by JorgenSandstrom, drunken monkey: Fixed property type for
+  string-typed aggregated fields.
+- #2949899 by drunken monkey, DamienMcKenna: Added a warning against using
+  particular processors with Solr servers to the "Workflow" tab.
+
 Search API 1.24 (2018-04-05):
 -----------------------------
 - #2958201 by jcnventura, drunken monkey: Reverted issue #2566529: Added
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_facetapi/search_api_facetapi.info b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_facetapi/search_api_facetapi.info
index 9c80f6e6..2fd1c653 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_facetapi/search_api_facetapi.info
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_facetapi/search_api_facetapi.info
@@ -9,8 +9,8 @@ files[] = plugins/facetapi/adapter.inc
 files[] = plugins/facetapi/query_type_term.inc
 files[] = plugins/facetapi/query_type_date.inc
 
-; Information added by Drupal.org packaging script on 2018-04-05
-version = "7.x-1.24"
+; Information added by Drupal.org packaging script on 2018-09-17
+version = "7.x-1.25"
 core = "7.x"
 project = "search_api"
-datestamp = "1522913891"
+datestamp = "1537171099"
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/README.txt b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/README.txt
index b36a7b55..50cfce1c 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/README.txt
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/README.txt
@@ -40,6 +40,21 @@ in that position. If the query is sorted in this way, then the
 random sort, as an associative array with any of the following keys:
 - seed: A numeric seed value to use for the random sort.
 
+"BETWEEN operator" feature
+--------------------------
+This module defines the "BETWEEN operator" feature (feature key:
+"search_api_between") that adds the "BETWEEN" and "NOT BETWEEN" filter
+operators to search queries. If your search server supports this feature, you
+can use the "Is between" and "Is not between" operators when adding Views
+filters for numeric, string or date types.
+
+For developers:
+A service class that wants to support this feature has to accept "BETWEEN" and
+"NOT BETWEEN" as additional $operator values in query conditions. The value in
+both cases is an array with the keys 0 and 1, with the value under key 0 being
+the lower and the value under key 1 being the upper bound for the range in which
+the field's value should ("BETWEEN") or should not ("NOT BETWEEN") be.
+
 "Facets block" display
 ----------------------
 Most features should be clear to users of Views. However, the module also
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_date.inc b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_date.inc
index c7897245..1259aa0b 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_date.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_date.inc
@@ -6,9 +6,9 @@
  */
 
 /**
- * Views filter handler base class for handling all "normal" cases.
+ * Views filter handler base class for handling date fields.
  */
-class SearchApiViewsHandlerFilterDate extends SearchApiViewsHandlerFilter {
+class SearchApiViewsHandlerFilterDate extends SearchApiViewsHandlerFilterNumeric {
 
   /**
    * Add a "widget type" option.
@@ -88,9 +88,22 @@ class SearchApiViewsHandlerFilterDate extends SearchApiViewsHandlerFilter {
   public function value_form(&$form, &$form_state) {
     parent::value_form($form, $form_state);
 
+    $is_date_popup = ($this->options['widget_type'] == 'date_popup' && module_exists('date_popup'));
+
+    // If the operator is between
+    if ($this->operator == 'between') {
+      if ($is_date_popup) {
+        $form['value']['min']['#type'] = 'date_popup';
+        $form['value']['min']['#date_format'] =  $this->options['date_popup_format'];
+        $form['value']['min']['#date_year_range'] = $this->options['year_range'];
+        $form['value']['max']['#type'] = 'date_popup';
+        $form['value']['max']['#date_format'] =  $this->options['date_popup_format'];
+        $form['value']['max']['#date_year_range'] = $this->options['year_range'];
+      }
+    }
     // If we are using the date popup widget, overwrite the settings of the form
     // according to what date_popup expects.
-    if ($this->options['widget_type'] == 'date_popup' && module_exists('date_popup')) {
+    elseif ($is_date_popup) {
       $form['value']['#type'] = 'date_popup';
       $form['value']['#date_format'] =  $this->options['date_popup_format'];
       $form['value']['#date_year_range'] = $this->options['year_range'];
@@ -115,11 +128,31 @@ class SearchApiViewsHandlerFilterDate extends SearchApiViewsHandlerFilter {
     elseif ($this->operator === 'not empty') {
       $this->query->condition($this->real_field, NULL, '<>', $this->options['group']);
     }
-    else {
-      while (is_array($this->value)) {
-        $this->value = $this->value ? reset($this->value) : NULL;
+    elseif (in_array($this->operator, array('between', 'not between'), TRUE)) {
+      $min = isset($this->value[0]['min']) ? $this->value[0]['min'] : '';
+      if ($min !== '') {
+        $min = is_numeric($min) ? $min : strtotime($min, REQUEST_TIME);
+      }
+      $max = isset($this->value[0]['max']) ? $this->value[0]['max'] : '';
+      if ($max !== '') {
+        $max = is_numeric($max) ? $max : strtotime($max, REQUEST_TIME);
       }
-      $v = is_numeric($this->value) ? $this->value : strtotime($this->value, REQUEST_TIME);
+
+      if (is_numeric($min) && is_numeric($max)) {
+        $this->query->condition($this->real_field, array($min, $max), strtoupper($this->operator), $this->options['group']);
+      }
+      elseif (is_numeric($min)) {
+        $operator = $this->operator === 'between' ? '>=' : '<';
+        $this->query->condition($this->real_field, $min, $operator, $this->options['group']);
+      }
+      elseif (is_numeric($max)) {
+        $operator = $this->operator === 'between' ? '<=' : '>';
+        $this->query->condition($this->real_field, $min, $operator, $this->options['group']);
+      }
+    }
+    else {
+      $value = isset($this->value[0]) ? $this->value[0]['value'] : $this->value['value'];
+      $v = is_numeric($value) ? $value : strtotime($value, REQUEST_TIME);
       if ($v !== FALSE) {
         $this->query->condition($this->real_field, $v, $this->operator, $this->options['group']);
       }
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_numeric.inc b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_numeric.inc
new file mode 100644
index 00000000..f29a3e6e
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_numeric.inc
@@ -0,0 +1,217 @@
+<?php
+
+/**
+ * @file
+ * Contains SearchApiViewsHandlerFilterNumeric.
+ */
+
+/**
+ * Views filter handler class for handling numeric and "string" fields.
+ */
+class SearchApiViewsHandlerFilterNumeric extends SearchApiViewsHandlerFilter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function option_definition() {
+    $options = parent::option_definition();
+    $options['value'] = array(
+      'contains' => array(
+        'value' => array('default' => ''),
+        'min' => array('default' => ''),
+        'max' => array('default' => ''),
+      ),
+    );
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function operator_options() {
+    $operators = parent::operator_options();
+
+    $index = search_api_index_load(substr($this->table, 17));
+    $server = NULL;
+    try {
+      if ($index) {
+        $server = $index->server();
+      }
+    }
+    catch (SearchApiException $e) {
+      // Ignore.
+    }
+    if ($server && $server->supportsFeature('search_api_between')) {
+      $operators += array(
+        'between' => t('Is between'),
+        'not between' => t('Is not between'),
+      );
+    }
+
+    return $operators;
+  }
+
+  /**
+   * Provides a form for setting the filter value.
+   *
+   * Heavily borrowed from views_handler_filter_numeric.
+   *
+   * @see views_handler_filter_numeric::value_form()
+   */
+  public function value_form(&$form, &$form_state) {
+    $form['value']['#tree'] = TRUE;
+
+    $single_field_operators = $this->operator_options();
+    unset(
+      $single_field_operators['empty'],
+      $single_field_operators['not empty'],
+      $single_field_operators['between'],
+      $single_field_operators['not between']
+    );
+    $between_operators = array('between', 'not between');
+
+    // We have to make some choices when creating this as an exposed
+    // filter form. For example, if the operator is locked and thus
+    // not rendered, we can't render dependencies; instead we only
+    // render the form items we need.
+    $which = 'all';
+    $source = NULL;
+    if (!empty($form['operator'])) {
+      $source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator';
+    }
+
+    $identifier = NULL;
+    if (!empty($form_state['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+      if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
+        // Exposed and locked.
+        $which = in_array($this->operator, $between_operators) ? 'minmax' : 'value';
+      }
+      else {
+        $source = 'edit-' . drupal_html_id($this->options['expose']['operator_id']);
+      }
+    }
+
+    // Hide the value box if the operator is 'empty' or 'not empty'.
+    // Radios share the same selector so we have to add some dummy selector.
+    if ($which == 'all') {
+      $form['value']['value'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('Value') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['value'],
+        '#dependency' => array($source => array_keys($single_field_operators)),
+      );
+      if ($identifier && !isset($form_state['input'][$identifier]['value'])) {
+        $form_state['input'][$identifier]['value'] = $this->value['value'];
+      }
+    }
+    elseif ($which == 'value') {
+      // When exposed we drop the value-value and just do value if
+      // the operator is locked.
+      $form['value'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('Value') : '',
+        '#size' => 30,
+        '#default_value' => isset($this->value['value']) ? $this->value['value'] : '',
+      );
+      if ($identifier && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = isset($this->value['value']) ? $this->value['value'] : '';
+      }
+    }
+
+    if ($which == 'all' || $which == 'minmax') {
+      $form['value']['min'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('Min') : '',
+        '#size' => 30,
+        '#default_value' => $this->value['min'],
+      );
+      $form['value']['max'] = array(
+        '#type' => 'textfield',
+        '#title' => empty($form_state['exposed']) ? t('And max') : t('And'),
+        '#size' => 30,
+        '#default_value' => $this->value['max'],
+      );
+
+      if ($which == 'all') {
+        $form['value']['min']['#dependency'] = array($source => $between_operators);
+        $form['value']['max']['#dependency'] = array($source => $between_operators);
+      }
+
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min'])) {
+        $form_state['input'][$identifier]['min'] = $this->value['min'];
+      }
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max'])) {
+        $form_state['input'][$identifier]['max'] = $this->value['max'];
+      }
+
+      if (!isset($form['value']['value'])) {
+        // Ensure there is something in the 'value'.
+        $form['value']['value'] = array(
+          '#type' => 'value',
+          '#value' => NULL,
+        );
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function admin_summary() {
+    if (!empty($this->options['exposed'])) {
+      return t('exposed');
+    }
+
+    if ($this->operator === 'empty') {
+      return t('is empty');
+    }
+    if ($this->operator === 'not empty') {
+      return t('is not empty');
+    }
+
+    $value = isset($this->value[0]) ? $this->value[0] : $this->value;
+
+    if (in_array($this->operator, array('between', 'not between'), TRUE)) {
+      // This is of course wrong for translation purposes, but copied from
+      // views_handler_filter_numeric::admin_summary() so probably still better
+      // to re-use this than to do it correctly.
+      $operator = $this->operator === 'between' ? t('between') : t('not between');
+      $vars = array(
+        '@min' => (string) $value['min'],
+        '@max' => (string) $value['max'],
+      );
+      return $operator . ' ' . t('@min and @max', $vars);
+    }
+
+    return check_plain((string) $this->operator) . ' ' . check_plain((string) $value['value']);
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    if (in_array($this->operator, array('between', 'not between'), TRUE)) {
+      $min = isset($this->value[0]['min']) ? $this->value[0]['min'] : '';
+      $max = isset($this->value[0]['max']) ? $this->value[0]['max'] : '';
+      if ($min !== '' && $max !== '') {
+        $this->query->condition($this->real_field, array($min, $max), strtoupper($this->operator), $this->options['group']);
+      }
+      elseif ($min !== '') {
+        $operator = $this->operator === 'between' ? '>=' : '<';
+        $this->query->condition($this->real_field, $min, $operator, $this->options['group']);
+      }
+      elseif ($max !== '') {
+        $operator = $this->operator === 'between' ? '<=' : '>';
+        $this->query->condition($this->real_field, $min, $operator, $this->options['group']);
+      }
+    }
+    else {
+      parent::query();
+    }
+  }
+
+}
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_options.inc b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_options.inc
index 3040fb0f..2184fc85 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_options.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/handler_filter_options.inc
@@ -121,6 +121,7 @@ class SearchApiViewsHandlerFilterOptions extends SearchApiViewsHandlerFilter {
    */
   public function option_definition() {
     $options = parent::option_definition();
+    $options['value'] = array('default' => '');
     $options['expose']['contains']['reduce'] = array('default' => FALSE);
     return $options;
   }
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_cache.inc b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_cache.inc
index c6bd41d4..c63aed5e 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_cache.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_cache.inc
@@ -35,11 +35,16 @@ class SearchApiViewsCache extends views_plugin_cache_time {
     }
 
     $cid = $this->get_results_key();
+    $results = NULL;
+    $query_plugin = $this->view->query;
+    if ($query_plugin instanceof SearchApiViewsQuery) {
+      $results = $query_plugin->getSearchApiResults();
+    }
     $data = array(
       'result' => $this->view->result,
       'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0,
       'current_page' => $this->view->get_current_page(),
-      'search_api results' => $this->view->query->getSearchApiResults(),
+      'search_api results' => $results,
     );
     cache_set($cid, $data, $this->table, $this->cache_set_expire($type));
   }
@@ -80,7 +85,7 @@ class SearchApiViewsCache extends views_plugin_cache_time {
    * Overrides views_plugin_cache::get_cache_key().
    *
    * Use the Search API query as the main source for the key. Note that in
-   * Views < 3.8, this function does not exist.
+   * Views < 3.8, this method does not exist.
    */
   public function get_cache_key($key_data = array()) {
     global $user;
@@ -121,7 +126,7 @@ class SearchApiViewsCache extends views_plugin_cache_time {
   }
 
   /**
-   * Get the Search API query object associated with the current view.
+   * Retrieves the Search API query object associated with the current view.
    *
    * @return SearchApiQueryInterface|null
    *   The Search API query object associated with the current view; or NULL if
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_content_cache.inc b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_content_cache.inc
new file mode 100644
index 00000000..555fe89a
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/includes/plugin_content_cache.inc
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * @file
+ * Contains the SearchApiViewsContentCache class.
+ */
+
+/**
+ * Plugin class for caching Search API views, with additional invalidation.
+ */
+class SearchApiViewsContentCache extends views_content_cache_plugin_cache {
+
+  /**
+   * Static cache for get_results_key().
+   *
+   * @var string
+   */
+  protected $_results_key = NULL;
+
+  /**
+   * Static cache for getSearchApiQuery().
+   *
+   * @var SearchApiQueryInterface
+   */
+  protected $search_api_query = NULL;
+
+  /**
+   * Overrides views_plugin_cache::cache_set().
+   *
+   * Also stores Search API's internal search results.
+   */
+  public function cache_set($type) {
+    if ($type != 'results') {
+      return parent::cache_set($type);
+    }
+
+    $cid = $this->get_results_key();
+    $results = NULL;
+    $query_plugin = $this->view->query;
+    if ($query_plugin instanceof SearchApiViewsQuery) {
+      $results = $query_plugin->getSearchApiResults();
+    }
+    $data = array(
+      'result' => $this->view->result,
+      'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0,
+      'current_page' => $this->view->get_current_page(),
+      'search_api results' => $results,
+    );
+    cache_set($cid, $data, $this->table, $this->cache_set_expire($type));
+  }
+
+  /**
+   * Overrides views_plugin_cache::cache_get().
+   *
+   * Additionally stores successfully retrieved results with
+   * search_api_current_search().
+   */
+  public function cache_get($type) {
+    if ($type != 'results') {
+      return parent::cache_get($type);
+    }
+
+    // Values to set: $view->result, $view->total_rows, $view->execute_time,
+    // $view->current_page.
+    if ($cache = cache_get($this->get_results_key(), $this->table)) {
+      $cutoff = $this->cache_expire($type);
+      if (!$cutoff || $cache->created > $cutoff) {
+        $this->view->result = $cache->data['result'];
+        $this->view->total_rows = $cache->data['total_rows'];
+        $this->view->set_current_page($cache->data['current_page']);
+        $this->view->execute_time = 0;
+
+        // Trick Search API into believing a search happened, to make facetting
+        // et al. work.
+        $query = $this->getSearchApiQuery();
+        search_api_current_search($query->getOption('search id'), $query, $cache->data['search_api results']);
+
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Overrides views_plugin_cache::get_cache_key().
+   *
+   * Use the Search API query as the main source for the key. Note that in
+   * Views < 3.8, this method does not exist.
+   */
+  public function get_cache_key($key_data = array()) {
+    global $user;
+
+    if (!isset($this->_results_key)) {
+      $query = $this->getSearchApiQuery();
+      $query->preExecute();
+      $key_data += array(
+        'query' => $query,
+        'roles' => array_keys($user->roles),
+        'super-user' => $user->uid == 1, // special caching for super user.
+        'language' => $GLOBALS['language']->language,
+        'base_url' => $GLOBALS['base_url'],
+        'offset' => $this->view->get_current_page() . '*' . $this->view->get_items_per_page() . '+' . $this->view->get_offset(),
+      );
+      // Not sure what gets passed in exposed_info, so better include it. All
+      // other parameters used in the parent method are already reflected in the
+      // Search API query object we use.
+      if (isset($_GET['exposed_info'])) {
+        $key_data['exposed_info'] = $_GET['exposed_info'];
+      }
+    }
+    $key = drupal_hash_base64(serialize($key_data));
+    return $key;
+  }
+
+  /**
+   * Overrides views_plugin_cache::get_results_key().
+   *
+   * This is unnecessary for Views >= 3.8.
+   */
+  public function get_results_key() {
+    if (!isset($this->_results_key)) {
+      $this->_results_key = $this->view->name . ':' . $this->display->id . ':results:' . $this->get_cache_key();
+    }
+
+    return $this->_results_key;
+  }
+
+  /**
+   * Retrieves the Search API query object associated with the current view.
+   *
+   * @return SearchApiQueryInterface|null
+   *   The Search API query object associated with the current view; or NULL if
+   *   there is none.
+   */
+  protected function getSearchApiQuery() {
+    if (!isset($this->search_api_query)) {
+      $this->search_api_query = FALSE;
+      if (isset($this->view->query) && $this->view->query instanceof SearchApiViewsQuery) {
+        $this->search_api_query = $this->view->query->getSearchApiQuery();
+      }
+    }
+
+    return $this->search_api_query ? $this->search_api_query : NULL;
+  }
+
+}
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.info b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.info
index 82c2f8f3..ee66b2fb 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.info
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.info
@@ -19,16 +19,18 @@ files[] = includes/handler_filter_date.inc
 files[] = includes/handler_filter_entity.inc
 files[] = includes/handler_filter_fulltext.inc
 files[] = includes/handler_filter_language.inc
+files[] = includes/handler_filter_numeric.inc
 files[] = includes/handler_filter_options.inc
 files[] = includes/handler_filter_taxonomy_term.inc
 files[] = includes/handler_filter_text.inc
 files[] = includes/handler_filter_user.inc
 files[] = includes/handler_sort.inc
 files[] = includes/plugin_cache.inc
+files[] = includes/plugin_content_cache.inc
 files[] = includes/query.inc
 
-; Information added by Drupal.org packaging script on 2018-04-05
-version = "7.x-1.24"
+; Information added by Drupal.org packaging script on 2018-09-17
+version = "7.x-1.25"
 core = "7.x"
 project = "search_api"
-datestamp = "1522913891"
+datestamp = "1537171099"
diff --git a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.views.inc b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.views.inc
index ff52d692..cc1cf4e5 100644
--- a/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.views.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/contrib/search_api_views/search_api_views.views.inc
@@ -219,6 +219,9 @@ function _search_api_views_add_handlers($id, array $field, EntityMetadataWrapper
       $table[$id]['filter']['vocabulary'] = $vocabulary;
     }
   }
+  elseif (in_array($inner_type, array('integer', 'decimal', 'duration', 'string'))) {
+    $table[$id]['filter']['handler'] = 'SearchApiViewsHandlerFilterNumeric';
+  }
   else {
     $table[$id]['filter']['handler'] = 'SearchApiViewsHandlerFilter';
   }
@@ -285,6 +288,16 @@ function search_api_views_views_plugins() {
     );
   }
 
+  if (module_exists('views_content_cache')) {
+    $ret['cache']['search_api_views_content_cache'] = array(
+      'title' => t('Search-specific content-based'),
+      'help' => t("Cache Search API views based on content updates. (Requires Views Content Cache)"),
+      'base' => $bases,
+      'handler' => 'SearchApiViewsContentCache',
+      'uses options' => TRUE,
+    );
+  }
+
   return $ret;
 }
 
diff --git a/profiles/wcm_base/modules/contrib/search_api/includes/callback_add_aggregation.inc b/profiles/wcm_base/modules/contrib/search_api/includes/callback_add_aggregation.inc
index 2e744f60..55ed611c 100644
--- a/profiles/wcm_base/modules/contrib/search_api/includes/callback_add_aggregation.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/includes/callback_add_aggregation.inc
@@ -328,10 +328,10 @@ class SearchApiAlterAddAggregation extends SearchApiAbstractAlterCallback {
           'count' => 'integer',
           'max' => 'integer',
           'min' => 'integer',
-          'first' => 'string',
-          'first_char' => 'string',
-          'last' => 'string',
-          'list' => 'list<string>',
+          'first' => 'token',
+          'first_char' => 'token',
+          'last' => 'token',
+          'list' => 'list<token>',
         );
       case 'description':
         return array(
diff --git a/profiles/wcm_base/modules/contrib/search_api/search_api.admin.inc b/profiles/wcm_base/modules/contrib/search_api/search_api.admin.inc
index 3afbaa78..89680dbf 100644
--- a/profiles/wcm_base/modules/contrib/search_api/search_api.admin.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/search_api.admin.inc
@@ -528,7 +528,7 @@ function theme_search_api_server(array $variables) {
 }
 
 /**
- * Form constructor for completely clearing a server.
+ * Form constructor for server operations.
  *
  * @param SearchApiServer $server
  *   The server for which the form is displayed.
@@ -543,15 +543,39 @@ function search_api_server_status_form(array $form, array &$form_state, SearchAp
   $form['clear'] = array(
     '#type' => 'submit',
     '#value' => t('Delete all indexed data on this server'),
+    '#submit' => array('search_api_server_status_form_clear_submit')
   );
 
+  $count = $server->enabled ? search_api_server_tasks_count($server) : 0;
+  if ($count) {
+    $message = format_plural($count, '@count pending task must be executed before indexing.', '@count pending tasks must be executed before indexing.');
+    drupal_set_message($message, 'warning', FALSE);
+    $form['execute_pending_tasks'] = array(
+      '#type' => 'submit',
+      '#value' => t('Execute all pending tasks on this server'),
+      '#submit' => array('search_api_server_status_form_execute_pending_tasks_submit')
+    );
+  }
+
   return $form;
 }
 
 /**
-* Form submission handler for search_api_server_status_form().
-*/
-function search_api_server_status_form_submit(array $form, array &$form_state) {
+ * Form submission handler for search_api_server_status_form().
+ *
+ * Used for the "Execute all pending tasks" button.
+ */
+function search_api_server_status_form_execute_pending_tasks_submit($form, &$form_state) {
+  $server_id = $form_state['server']->machine_name;
+  $form_state['redirect'] = "admin/config/search/search_api/server/$server_id/execute-tasks";
+}
+
+/**
+ * Form submission handler for search_api_server_status_form().
+ *
+ * Used for the "Delete all indexed data" button.
+ */
+function search_api_server_status_form_clear_submit(array $form, array &$form_state) {
   $server_id = $form_state['server']->machine_name;
   $form_state['redirect'] = "admin/config/search/search_api/server/$server_id/clear";
 }
@@ -1566,10 +1590,13 @@ function search_api_admin_index_workflow(array $form, array &$form_state, Search
   $form['processors'] = array(
     '#type' => 'fieldset',
     '#title' => t('Processors'),
-    '#description' => t('Select processors which will pre- and post-process data at index and search time, and their order. ' .
-        'Most processors will only influence fulltext fields, but refer to their individual descriptions for details regarding their effect.'),
+    '#description' => '<p>' . t("Select processors which will pre- and post-process data at index and search time, and their order. Most processors will only influence fulltext fields, but refer to their individual descriptions for details regarding their effect.<br />Also, some processors shouldn't be used with more advanced search engines (like Solr or Elasticsearch), since the search engine already provides this functionality.") . '</p>',
     '#collapsible' => TRUE,
   );
+  if ($index->server) {
+    $form['processors']['#description'] .= '<p>' . t("Check the <a href='@server-url'>server's</a> service class description for details.",
+        array('@server-url' => url('admin/config/search/search_api/server/' . $index->server . '/edit'))) . '</p>';
+  }
 
   // Processor status.
   $form['processors']['status'] = array(
@@ -1696,6 +1723,7 @@ function search_api_admin_index_workflow_submit(array $form, array &$form_state)
   unset($values['callbacks']['settings']);
   unset($values['processors']['settings']);
   $index = $form_state['index'];
+  $index_path = 'admin/config/search/search_api/index/' . $index->machine_name;
 
   $options = empty($index->options) ? array() : $index->options;
 
@@ -1761,13 +1789,14 @@ function search_api_admin_index_workflow_submit(array $form, array &$form_state)
 
     $index->save();
     $index->reindex();
-    drupal_set_message(t("The indexing workflow was successfully edited. All content was scheduled for re-indexing so the new settings can take effect."));
+    $vars = array('@url' => url($index_path));
+    drupal_set_message(t('The indexing workflow was successfully edited. All content was scheduled for <a href="@url">re-indexing</a> so the new settings can take effect.', $vars));
   }
   else {
     drupal_set_message(t('No values were changed.'));
   }
 
-  $form_state['redirect'] = 'admin/config/search/search_api/index/' . $index->machine_name . '/workflow';
+  $form_state['redirect'] = $index_path . '/workflow';
 }
 
 /**
@@ -1822,8 +1851,8 @@ function search_api_admin_index_fields(array $form, array &$form_state, SearchAp
         'In any case, fields of type "Fulltext" will always be fulltext-searchable.</p>'),
   );
   if ($index->server) {
-    $form['description']['#description'] .= '<p>' . t('Check the <a href="@server-url">' . "server's</a> service class description for details.",
-        array('@server-url' => url('admin/config/search/search_api/server/' . $index->server))) . '</p>';
+    $form['description']['#description'] .= '<p>' . t("Check the <a href='@server-url'>server's</a> service class description for details.",
+        array('@server-url' => url('admin/config/search/search_api/server/' . $index->server . '/edit'))) . '</p>';
   }
   foreach ($fields as $key => $info) {
     $form['fields'][$key]['title']['#markup'] = check_plain($info['name']);
diff --git a/profiles/wcm_base/modules/contrib/search_api/search_api.drush.inc b/profiles/wcm_base/modules/contrib/search_api/search_api.drush.inc
index 61957b9a..8c995b17 100644
--- a/profiles/wcm_base/modules/contrib/search_api/search_api.drush.inc
+++ b/profiles/wcm_base/modules/contrib/search_api/search_api.drush.inc
@@ -95,6 +95,18 @@ function search_api_drush_command() {
     'aliases' => array('sapi-r'),
   );
 
+  $items['search-api-reindex-items'] = array(
+    'description' => 'Force re-indexing of one or more specific items.',
+    'examples' => array(
+      'drush search-api-reindex-items node 12,34,56' => dt('Schedule the nodes with ID 12, 34 and 56 for re-indexing.'),
+    ),
+    'arguments' => array(
+      'entity_type' => dt('The entity type whose items should be re-indexed.'),
+      'entities' => dt('The entities of the given entity type to be re-indexed.'),
+    ),
+    'aliases' => array('sapi-ri'),
+  );
+
   $items['search-api-clear'] = array(
     'description' => 'Clear one or all search indexes and mark them for re-indexing.',
     'examples' => array(
@@ -109,6 +121,19 @@ function search_api_drush_command() {
     'aliases' => array('sapi-c'),
   );
 
+  $items['search-api-execute-tasks'] = array(
+    'description' => 'Execute all pending tasks or all for a given server.',
+    'examples' => array(
+      'drush search-api-execute-tasks my_solr_server' => dt('Execute all pending tasks on !server', array('!server' => 'my_solr_server')),
+      'drush sapi-et my_solr_server' => dt('Execute all pending tasks on !server', array('!server' => 'my_solr_server')),
+      'drush sapi-et' => dt('Execute all pending tasks on all servers.')
+    ),
+    'arguments' => array(
+      'server_id' => dt('The numeric ID or machine name of a server to execute tasks on.'),
+    ),
+    'aliases' => array('sapi-et')
+  );
+
   $items['search-api-set-index-server'] = array(
     'description' => 'Set the search server used by a given index.',
     'examples' => array(
@@ -448,6 +473,33 @@ function drush_search_api_reindex($index_id = NULL) {
   }
 }
 
+/**
+ * Marks the given entities as needing to be re-indexed.
+ */
+function drush_search_api_reindex_items($entity_type, $entities) {
+  if (search_api_drush_static(__FUNCTION__)) {
+    return;
+  }
+
+  // Validate list of entity ids.
+  if (!empty($entities) && !preg_match('#^[0-9]*(,[0-9]*)*$#', $entities)) {
+    drush_log(dt('Entities should be a single numeric entity ID or a list with the numeric entity IDs separated by comma.'), 'error');
+    return;
+  }
+
+  $ids = explode(',', $entities);
+
+  if (!empty($ids)) {
+    search_api_track_item_change($entity_type, $ids);
+
+    $combined_ids = array();
+    foreach ($ids as $id) {
+      $combined_ids[] = $entity_type . '/' . $id;
+    }
+    search_api_track_item_change('multiple', $combined_ids);
+  }
+}
+
 /**
  * Clear an index.
  */
@@ -466,6 +518,34 @@ function drush_search_api_clear($index_id = NULL) {
   }
 }
 
+/**
+ * Execute all pending tasks or all for a given server.
+ */
+function drush_search_api_execute_tasks($server_id = NULL) {
+  if (search_api_drush_static(__FUNCTION__)) {
+    return;
+  }
+
+  // Attempt to load the associated server.
+  $server = NULL;
+  if ($server_id) {
+    $servers = search_api_drush_get_server($server_id);
+    if (!$servers) {
+      return;
+    }
+    $server = reset($servers);
+  }
+
+  // Process batch op with drush.
+  try {
+    search_api_execute_pending_tasks($server);
+    drush_log(dt('!server tasks have been successfully executed.', array('!server' => $server->machine_name ? $server->machine_name : 'All')), 'ok');
+  }
+  catch (SearchApiException $e) {
+    drush_log($e->getMessage(), 'error');
+  }
+}
+
 /**
  * Set the server for a given index.
  */
diff --git a/profiles/wcm_base/modules/contrib/search_api/search_api.info b/profiles/wcm_base/modules/contrib/search_api/search_api.info
index 1c85bdad..201c3db4 100644
--- a/profiles/wcm_base/modules/contrib/search_api/search_api.info
+++ b/profiles/wcm_base/modules/contrib/search_api/search_api.info
@@ -38,8 +38,8 @@ files[] = includes/service.inc
 
 configure = admin/config/search/search_api
 
-; Information added by Drupal.org packaging script on 2018-04-05
-version = "7.x-1.24"
+; Information added by Drupal.org packaging script on 2018-09-17
+version = "7.x-1.25"
 core = "7.x"
 project = "search_api"
-datestamp = "1522913891"
+datestamp = "1537171099"
diff --git a/profiles/wcm_base/modules/contrib/search_api/search_api.install b/profiles/wcm_base/modules/contrib/search_api/search_api.install
index 5dc26895..61f686d7 100644
--- a/profiles/wcm_base/modules/contrib/search_api/search_api.install
+++ b/profiles/wcm_base/modules/contrib/search_api/search_api.install
@@ -264,6 +264,51 @@ function search_api_schema() {
   return $schema;
 }
 
+/**
+ * Implements hook_requirements().
+ */
+function search_api_requirements($phase) {
+  $requirements = array();
+
+  if ($phase == 'runtime') {
+    // Check whether at least one server has pending tasks.
+    if (search_api_server_tasks_count()) {
+      $items = array();
+
+      $conditions = array('enabled' => TRUE);
+      foreach (search_api_server_load_multiple(FALSE, $conditions) as $server) {
+        $count = search_api_server_tasks_count($server);
+        if ($count) {
+          $args = array(
+            '@name' => $server->name,
+          );
+          $text = format_plural($count, '@name has @count pending task.', '@name has @count pending tasks.', $args);
+          $items[] = l($text, "admin/config/search/search_api/server/{$server->machine_name}/execute-tasks");
+        }
+      }
+
+      if ($items) {
+        $text = t('There are pending tasks for the following servers:');
+        $text .= theme('item_list', array(
+          'type' => 'ul',
+          'items' => $items,
+        ));
+        if (count($items) > 1) {
+          $label = t('Execute pending tasks on all servers');
+          $text .= l($label, 'admin/config/search/search_api/execute-tasks');
+        }
+        $requirements['search_api_pending_tasks'] = array(
+          'title' => t('Search API'),
+          'value' => $text,
+          'severity' => REQUIREMENT_WARNING,
+        );
+      }
+    }
+  }
+
+  return $requirements;
+}
+
 /**
  * Implements hook_install().
  *
diff --git a/profiles/wcm_base/modules/contrib/search_api/search_api.module b/profiles/wcm_base/modules/contrib/search_api/search_api.module
index 8fe3e2a7..a509302c 100644
--- a/profiles/wcm_base/modules/contrib/search_api/search_api.module
+++ b/profiles/wcm_base/modules/contrib/search_api/search_api.module
@@ -72,6 +72,15 @@ function search_api_menu() {
     'type' => MENU_LOCAL_TASK,
     'context' => MENU_CONTEXT_INLINE | MENU_CONTEXT_PAGE,
   );
+  $items[$pre . '/server/%search_api_server/execute-tasks'] = array(
+    'title' => 'Execute pending tasks',
+    'description' => 'Attempt to process pending tasks for a given server.',
+    'page callback' => 'search_api_execute_pending_tasks',
+    'page arguments' => array(5),
+    'access callback' => 'search_api_access_execute_tasks_batch',
+    'access arguments' => array(5),
+    'type' => MENU_CALLBACK,
+  );
   $items[$pre . '/server/%search_api_server/disable'] = array(
     'title' => 'Disable',
     'description' => 'Disable index.',
@@ -98,6 +107,13 @@ function search_api_menu() {
     'context' => MENU_CONTEXT_INLINE,
     'weight' => 10,
   );
+  $items[$pre . '/execute-tasks'] = array(
+    'title' => 'Execute pending tasks',
+    'description' => 'Attempt to process pending server tasks.',
+    'page callback' => 'search_api_execute_pending_tasks',
+    'access callback' => 'search_api_access_execute_tasks_batch',
+    'type' => MENU_LOCAL_ACTION,
+  );
   $items[$pre . '/index/%search_api_index'] = array(
     'title' => 'View index',
     'title callback' => 'search_api_admin_item_title',
@@ -1409,6 +1425,10 @@ function search_api_server_tasks_check(SearchApiServer $server = NULL) {
   // Sometimes the order of tasks might be important, so make sure to order by
   // the task ID (which should be in order of insertion).
   $select->orderBy('t.id');
+  // Only retrieve and execute 100 tasks at once, to avoid running out of memory
+  // or time. We just can't do anything else until all tasks have been resolved,
+  // but at least we shouldn't crash sites, or keep piling up tasks, that way.
+  $select->range(0, 100);
   $tasks = $select->execute();
 
   $executed_tasks = array();
@@ -1465,11 +1485,116 @@ function search_api_server_tasks_check(SearchApiServer $server = NULL) {
   if (!$executed_tasks) {
     return TRUE;
   }
-  // Otherwise, delete the executed tasks and check if new tasks were created.
+  // Otherwise, delete the executed tasks and check if new tasks were created
+  // (or if we didn't even fetch all due to the 100 tasks limit).
   search_api_server_tasks_delete($executed_tasks);
   return $count_query->execute()->fetchField() === 0;
 }
 
+/**
+ * Provides a batch wrapper for search_api_server_tasks_check().
+ *
+ * @param SearchApiServer|null $server
+ *   (optional) The server whose tasks should be executed, or NULL to execute
+ *   tasks for all servers.
+ */
+function search_api_execute_pending_tasks(SearchApiServer $server = NULL) {
+  batch_set(array(
+    'title' => t('Processing pending tasks'),
+    'operations' => array(
+      array(
+        'search_api_execute_pending_tasks_batch',
+        array(
+          $server,
+        ),
+      ),
+    ),
+    'finished' => 'search_api_execute_pending_tasks_finished'
+  ));
+  if ($server) {
+    $path = 'admin/config/search/search_api/server/' . $server->machine_name;
+  }
+  else {
+    $path = 'admin/config/search/search_api';
+  }
+
+  if (function_exists('drush_backend_batch_process')) {
+    drush_backend_batch_process();
+  }
+  else {
+    batch_process($path);
+  }
+}
+
+/**
+ * Executes pending server tasks as part of a batch operation.
+ */
+function search_api_execute_pending_tasks_batch(SearchApiServer $server = NULL, &$context) {
+  if (!isset($context['results']['total'])) {
+    $context['results']['total'] = search_api_server_tasks_count($server);
+  }
+  $total = $context['results']['total'];
+
+  search_api_server_tasks_check($server);
+
+  $remaining = search_api_server_tasks_count($server);
+  $executed = max($total - $remaining, 0);
+
+  $args['@remaining'] = $remaining;
+  $context['message'] = format_plural($executed, 'Successfully executed @count task, @remaining remaining.', 'Successfully executed @count tasks, @remaining remaining.', $args);
+  $context['finished'] = $executed / $total;
+}
+
+/**
+ * Batch finish callback for pending server tasks.
+ */
+function search_api_execute_pending_tasks_finished($success, $results, $operations) {
+  if ($success) {
+    // Clear the previous warning.
+    drupal_get_messages('warning');
+
+    // Alert user to the number of tasks executed.
+    drupal_set_message(format_plural($results['total'], 'Successfully executed @count task.', 'Successfully executed @count tasks.'));
+  }
+}
+
+/**
+ * Return the number of pending tasks.
+ *
+ * @param SearchApiServer|null $server
+ *   (optional) The server for which tasks should be counted, or NULL to count
+ *   for all enabled servers.
+ *
+ * @return int
+ *   The number of pending tasks for the server, or in total.
+ */
+function search_api_server_tasks_count(SearchApiServer $server = NULL) {
+  $query = db_select('search_api_task', 't')
+    ->fields('t');
+
+  if ($server) {
+    $query->condition('server_id', $server->machine_name);
+  }
+  else {
+    $query->join('search_api_server', 's', 's.machine_name = t.server_id');
+    $query->condition('s.enabled', 1);
+  }
+
+  return $query->countQuery()->execute()->fetchField();
+}
+
+/**
+ * Access callback: Checks whether a user can execute pending tasks.
+ *
+ * @param SearchApiServer|null $server
+ *   (optional) The server for which tasks would be executed.
+ */
+function search_api_access_execute_tasks_batch(SearchApiServer $server = NULL) {
+  return user_access('administer search_api')
+      && search_api_server_tasks_count($server)
+      && (!$server || $server->enabled);
+}
+
 /**
  * Adds an entry into a server's list of pending tasks.
  *
diff --git a/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test.info b/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test.info
index 5286e5eb..e3a3695d 100644
--- a/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test.info
+++ b/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test.info
@@ -10,8 +10,8 @@ files[] = search_api_test.module
 
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2018-04-05
-version = "7.x-1.24"
+; Information added by Drupal.org packaging script on 2018-09-17
+version = "7.x-1.25"
 core = "7.x"
 project = "search_api"
-datestamp = "1522913891"
+datestamp = "1537171099"
diff --git a/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test_2.info b/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test_2.info
index 72d47e90..e84483ed 100644
--- a/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test_2.info
+++ b/profiles/wcm_base/modules/contrib/search_api/tests/search_api_test_2.info
@@ -9,8 +9,8 @@ files[] = search_api_test_service_2.module
 
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2018-04-05
-version = "7.x-1.24"
+; Information added by Drupal.org packaging script on 2018-09-17
+version = "7.x-1.25"
 core = "7.x"
 project = "search_api"
-datestamp = "1522913891"
+datestamp = "1537171099"
diff --git a/profiles/wcm_base/modules/contrib/search_api_db/CHANGELOG.txt b/profiles/wcm_base/modules/contrib/search_api_db/CHANGELOG.txt
index 4b30f594..da676895 100644
--- a/profiles/wcm_base/modules/contrib/search_api_db/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/contrib/search_api_db/CHANGELOG.txt
@@ -1,3 +1,14 @@
+Search API Database Search 1.7 (2018-09-17):
+--------------------------------------------
+- #2982443 by KarlShea, drunken monkey: Added support for the "(not) between"
+  operators.
+- #2855634 by drunken monkey, SpadXIII, levmyshkin, chris.jichen: Fixed update
+  #7107.
+- #2940278 by james.williams, drunken monkey: Fixed indexing of decimal values
+  as boolean.
+- #2897548 by drunken monkey: Fixed sorting on MySQL 5.7.
+- #2879881 by drunken monkey: Fixed preprocessing of autocomplete keys.
+
 Search API Database Search 1.6 (2017-02-23):
 --------------------------------------------
 - #2840261 by alan-ps, drunken monkey: Fixed usage of outdated hash functions.
diff --git a/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.info b/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.info
index df593332..3a2bd848 100644
--- a/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.info
+++ b/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.info
@@ -6,9 +6,8 @@ package = Search
 
 files[] = search_api_db.test
 files[] = service.inc
-; Information added by Drupal.org packaging script on 2017-02-23
-version = "7.x-1.6"
+; Information added by Drupal.org packaging script on 2018-09-17
+version = "7.x-1.7"
 core = "7.x"
 project = "search_api_db"
-datestamp = "1487844786"
-
+datestamp = "1537173484"
diff --git a/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.install b/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.install
index 0202a0bf..02b6a77d 100644
--- a/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.install
+++ b/profiles/wcm_base/modules/contrib/search_api_db/search_api_db.install
@@ -289,6 +289,9 @@ function search_api_db_update_7107() {
     $options = unserialize($options);
 
     if (!empty($options['indexes'])) {
+      list($key, $target) = explode(':', $options['database'], 2);
+      $connection = Database::getConnection($target, $key);
+
       foreach ($options['indexes'] as $index_id => $fields) {
         $text_table = NULL;
 
@@ -296,7 +299,7 @@ function search_api_db_update_7107() {
           if (search_api_is_text_type($field['type'])) {
             $text_table = $field['table'];
             if (strlen($field_id) > 255) {
-              db_update($text_table)
+              $connection->update($text_table)
                 ->fields(array('field_name' => drupal_hash_base64($field_id)))
                 ->condition('field_name', md5($field_id))
                 ->execute();
@@ -305,8 +308,9 @@ function search_api_db_update_7107() {
         }
 
         // If there is a text table for this index, update its description.
-        if ($text_table) {
-          db_change_field($text_table, 'field_name', 'field_name', $spec);
+        if ($text_table && db_table_exists($text_table)) {
+          $connection->schema()
+            ->changeField($text_table, 'field_name', 'field_name', $spec);
         }
       }
     }
diff --git a/profiles/wcm_base/modules/contrib/search_api_db/service.inc b/profiles/wcm_base/modules/contrib/search_api_db/service.inc
index 609e5d4f..b98d5b79 100644
--- a/profiles/wcm_base/modules/contrib/search_api_db/service.inc
+++ b/profiles/wcm_base/modules/contrib/search_api_db/service.inc
@@ -174,6 +174,7 @@ class SearchApiDbService extends SearchApiAbstractService {
   public function supportsFeature($feature) {
     $supported = array(
       'search_api_autocomplete' => TRUE,
+      'search_api_between' => TRUE,
       'search_api_facets' => TRUE,
       'search_api_facets_operator_or' => TRUE,
       'search_api_random_sort' => TRUE,
@@ -1112,6 +1113,11 @@ class SearchApiDbService extends SearchApiAbstractService {
         return 0 + $value;
 
       case 'boolean':
+        // Numeric strings need to be converted to a numeric type before
+        // converting to a boolean, as strings like '0.00' evaluate to TRUE.
+        if (is_string($value) && is_numeric($value)) {
+          $value = 0 + $value;
+        }
         return $value ? 1 : 0;
 
       case 'date':
@@ -1686,57 +1692,63 @@ class SearchApiDbService extends SearchApiAbstractService {
         }
       }
       else {
-        if (!isset($fields[$f[0]])) {
-          throw new SearchApiException(t('Unknown field in filter clause: @field.', array('@field' => $f[0])));
-        }
-        $field = $fields[$f[0]];
-        $not_equals = $f[2] == '<>' || $f[2] == '!=';
-        $text_type = search_api_is_text_type($field['type']);
+        list ($field, $value, $operator) = $f;
+        if (!isset($fields[$field])) {
+          throw new SearchApiException(t('Unknown field in filter clause: @field.', array('@field' => $field)));
+        }
+        $field_info = $fields[$field];
+        $not_between = $operator === 'NOT BETWEEN';
+        $not_equals = $not_between || $operator === '<>' || $operator === '!=';
+        $text_type = search_api_is_text_type($field_info['type']);
         // If the field is in its own table, we have to check for NULL values in
         // a special way (i.e., check for missing entries in that table).
-        if ($f[1] === NULL && ($field['column'] === 'value' || $text_type)) {
-          $query = $this->connection->select($field['table'], 't')
+        if ($value === NULL && ($field_info['column'] === 'value' || $text_type)) {
+          $query = $this->connection->select($field_info['table'], 't')
             ->fields('t', array('item_id'));
           if ($text_type) {
-            $query->condition('t.field_name', $f[0]);
+            $query->condition('t.field_name', $field);
           }
           $cond->condition('t.item_id', $query, $not_equals ? 'IN' : 'NOT IN');
           continue;
         }
         if ($text_type) {
-          $keys = $this->prepareKeys($f[1]);
+          $keys = $this->prepareKeys($value);
           if (!isset($keys)) {
             continue;
           }
-          $query = $this->createKeysQuery($keys, array($f[0] => $field), $fields);
+          $query = $this->createKeysQuery($keys, array($field => $field_info), $fields);
           // We only want the item IDs, so we use the keys query as a nested query.
           $query = $this->connection->select($query, 't')->fields('t', array('item_id'));
           $cond->condition('t.item_id', $query, $not_equals ? 'NOT IN' : 'IN');
         }
         else {
-          $new_join = search_api_is_list_type($field['type'])
+          $new_join = search_api_is_list_type($field_info['type'])
               && ($filter->getConjunction() == 'AND'
-                  || empty($first_join[$f[0]]));
-          if ($new_join || empty($tables[$f[0]])) {
-            $tables[$f[0]] = $this->getTableAlias($field, $db_query, $new_join);
-            $first_join[$f[0]] = TRUE;
+                  || empty($first_join[$field]));
+          if ($new_join || empty($tables[$field])) {
+            $tables[$field] = $this->getTableAlias($field_info, $db_query, $new_join);
+            $first_join[$field] = TRUE;
           }
-          $column = $tables[$f[0]] . '.' . $field['column'];
-          if ($f[1] === NULL) {
-            $method = ($f[2] == '=') ? 'isNull' : 'isNotNull';
+          $column = $tables[$field] . '.' . $field_info['column'];
+          if ($value === NULL) {
+            $method = ($operator == '=') ? 'isNull' : 'isNotNull';
             $cond->$method($column);
           }
-          elseif ($not_equals && search_api_is_list_type($field['type'])) {
+          elseif ($not_equals && search_api_is_list_type($field_info['type'])) {
             // The situation is more complicated for multi-valued fields, since
             // we must make sure that results are excluded if ANY of the field's
             // values equals the one given in this condition.
-            $query = $this->connection->select($field['table'], 't')
+            $sub_operator = ($not_between) ? 'BETWEEN' : '=';
+            $query = $this->connection->select($field_info['table'], 't')
               ->fields('t', array('item_id'))
-              ->condition($field['column'], $f[1]);
+              ->condition($field_info['column'], $value, $sub_operator);
             $cond->condition('t.item_id', $query, 'NOT IN');
           }
+          elseif ($not_between) {
+            $cond->where("$column NOT BETWEEN {$value[0]} AND {$value[1]}");
+          }
           else {
-            $cond->condition($column, $f[1], $f[2]);
+            $cond->condition($column, $value, $operator);
           }
         }
       }
@@ -1854,7 +1866,7 @@ class SearchApiDbService extends SearchApiAbstractService {
         $alias = $this->getTableAlias($field, $db_query);
         $db_query->orderBy($alias . '.' . $fields[$field_name]['column'], $order);
         // PostgreSQL automatically adds a field to the SELECT list when sorting
-        // on it. Therefore, if we have aggregrations present we also have to
+        // on it. Therefore, if we have aggregations present we also have to
         // add the field to the GROUP BY (since Drupal won't do it for us).
         // However, if no aggregations are present, a GROUP BY would lead to
         // another error. Therefore, we only add it if there is already a GROUP
@@ -1862,6 +1874,13 @@ class SearchApiDbService extends SearchApiAbstractService {
         if ($db_query->getGroupBy()) {
           $db_query->groupBy($alias . '.' . $fields[$field_name]['column']);
         }
+        // For SELECT DISTINCT queries in combination with an ORDER BY clause,
+        // MySQL 5.7 and higher require that the ORDER BY expressions are part
+        // of the field list. Ensure that all fields used for sorting are part
+        // of the select list.
+        if (empty($db_fields[$fields[$field_name]['column']])) {
+          $db_query->addField($alias, $fields[$field_name]['column']);
+        }
       }
     }
     else {
@@ -2085,8 +2104,21 @@ class SearchApiDbService extends SearchApiAbstractService {
 
     // Decide which methods we want to use.
     if ($incomplete_key && $settings['suggest_suffix']) {
-      $passes[] = 1;
-      $incomplete_like = $this->connection->escapeLike($incomplete_key) . '%';
+      $processed_key = $this->splitKeys($incomplete_key);
+      if ($processed_key) {
+        // In case the $incomplete_key turned out to be more than one word, add
+        // all but the last one to the user input.
+        if (is_array($processed_key)) {
+          unset($processed_key['#conjunction']);
+          $incomplete_key = array_pop($processed_key);
+          if ($processed_key) {
+            $user_input .= ' ' . implode(' ', $processed_key);
+          }
+          $processed_key = $incomplete_key;
+        }
+        $passes[] = 1;
+        $incomplete_like = $this->connection->escapeLike($processed_key) . '%';
+      }
     }
     if ($settings['suggest_words']
         && (!$incomplete_key || strlen($incomplete_key) >= $this->options['min_chars'])) {
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid.features.inc b/profiles/wcm_base/modules/contrib/uuid/uuid.features.inc
index 03b7d55b..93b418ef 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid.features.inc
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid.features.inc
@@ -168,6 +168,7 @@ function uuid_entities_rebuild($module_name = '', $op = 'rebuild') {
     foreach ($entities as $plan_name => $entities) {
       // Let other modules do things before default entities are created.
       module_invoke_all("uuid_entities_pre_$op", $plan_name);
+      drupal_alter("uuid_entities_pre_$op", $entities, $plan_name);
       foreach ($entities as $entity) {
         entity_uuid_save($entity->__metadata['type'], $entity);
       }
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid.info b/profiles/wcm_base/modules/contrib/uuid/uuid.info
index bd1e8735..cefaf291 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid.info
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid.info
@@ -7,8 +7,8 @@ files[] = uuid.test
 dependencies[] = node
 dependencies[] = user
 
-; Information added by Drupal.org packaging script on 2018-07-03
-version = "7.x-1.1"
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 project = "uuid"
-datestamp = "1530614937"
+datestamp = "1531990689"
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid_path/uuid_path.info b/profiles/wcm_base/modules/contrib/uuid/uuid_path/uuid_path.info
index 0f4fa2ba..77ad15c3 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid_path/uuid_path.info
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid_path/uuid_path.info
@@ -5,8 +5,8 @@ package = UUID
 dependencies[] = uuid
 
 
-; Information added by Drupal.org packaging script on 2018-07-03
-version = "7.x-1.1"
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 project = "uuid"
-datestamp = "1530614937"
+datestamp = "1531990689"
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.admin.inc b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.admin.inc
index d9afe29b..28e447cf 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.admin.inc
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.admin.inc
@@ -18,5 +18,13 @@ function uuid_services_settings() {
     '#description' => t('Check this box to automatically provide Services integration for all entity types with UUID support.'),
     '#default_value' => variable_get('uuid_services_support_all_entity_types', FALSE),
   );
+  $form['uuid_services_allowed_media_mimes'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Allowed Media Mime type'),
+    '#default_value' => variable_get('uuid_services_allowed_media_mimes', UUID_SERVICES_DEFAULT_ALLOWED_MEDIA_MIMES),
+    '#cols' => 40,
+    '#rows' => 5,
+    '#description' => t("Enter one mime type per line you wish to allow in the system without extension. Example mime type '<em>video/brightcove</em>'."),
+  );
   return system_settings_form($form);
 }
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.info b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.info
index 911f2965..dd1ae423 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.info
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.info
@@ -7,8 +7,14 @@ dependencies[] = services
 dependencies[] = uuid
 dependencies[] = entity
 
-; Information added by Drupal.org packaging script on 2018-07-03
-version = "7.x-1.1"
+test_dependencies[] = services
+test_dependencies[] = entity
+test_dependencies[] = file
+test_dependencies[] = field
+test_dependencies[] = file_entity
+
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 project = "uuid"
-datestamp = "1530614937"
+datestamp = "1531990689"
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.install b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.install
new file mode 100644
index 00000000..1dfeb6cc
--- /dev/null
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.install
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * @file
+ * UUID module installation functions.
+ */
+
+/**
+ * Implements hook_uninstall().
+ */
+function uuid_services_uninstall() {
+  variable_del('uuid_services_support_all_entity_types');
+  variable_del('uuid_services_allowed_media_mimes');
+}
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.module b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.module
index a43160c8..5a0e6289 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.module
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid_services/uuid_services.module
@@ -5,6 +5,14 @@
  * UUID Services module functions.
  */
 
+/**
+ * Defines defaults for UUID_SERVICES_ALLOWED_MEDIA_MIMES.
+ */
+define('UUID_SERVICES_DEFAULT_ALLOWED_MEDIA_MIMES',
+'video/brightcove
+video/youtube'
+);
+
 /**
  * Implements hook_menu().
  */
@@ -147,12 +155,19 @@ function _uuid_services_entity_update($entity_type, $uuid, $entity) {
       $entity = (object) $entity;
     }
     $entity->uuid_services = TRUE;
+    // Check that the mime type is whitelisted.
+    $valid_media_mimes = variable_get('uuid_services_allowed_media_mimes', UUID_SERVICES_DEFAULT_ALLOWED_MEDIA_MIMES);
+
     // Sanitize file user input.
     if ($entity_type == 'file') {
-      $entity->filename = _services_file_check_name_extension($entity->filename);
-      $entity->uri = _services_file_check_destination_uri($entity->uri);
-      if (!empty($entity->filepath)) {
-        $entity->filepath = _services_file_check_destination($entity->filepath);
+      // We have to make sure to whitelist mime types, to avoid the video files
+      // getting converted into text files, when deployed from one env to other.
+      if (!in_array($entity->filemime, preg_split('/\r?\n/', $valid_media_mimes))) {
+        $entity->filename = _services_file_check_name_extension($entity->filename);
+        $entity->uri = _services_file_check_destination_uri($entity->uri);
+        if (!empty($entity->filepath)) {
+          $entity->filepath = _services_file_check_destination($entity->filepath);
+        }
       }
     }
     entity_uuid_save($entity_type, $entity);
diff --git a/profiles/wcm_base/modules/contrib/uuid/uuid_services_example/uuid_services_example.info b/profiles/wcm_base/modules/contrib/uuid/uuid_services_example/uuid_services_example.info
index 65cd2df1..5874051f 100644
--- a/profiles/wcm_base/modules/contrib/uuid/uuid_services_example/uuid_services_example.info
+++ b/profiles/wcm_base/modules/contrib/uuid/uuid_services_example/uuid_services_example.info
@@ -11,8 +11,8 @@ features[ctools][] = services:services:3
 features[features_api][] = api:2
 features[services_endpoint][] = uuid_services_example
 
-; Information added by Drupal.org packaging script on 2018-07-03
-version = "7.x-1.1"
+; Information added by Drupal.org packaging script on 2018-07-19
+version = "7.x-1.2"
 core = "7.x"
 project = "uuid"
-datestamp = "1530614937"
+datestamp = "1531990689"
diff --git a/profiles/wcm_base/modules/custom/news_client/README.md b/profiles/wcm_base/modules/custom/news_client/README.md
index 6e9424e4..38815543 100644
--- a/profiles/wcm_base/modules/custom/news_client/README.md
+++ b/profiles/wcm_base/modules/custom/news_client/README.md
@@ -74,3 +74,12 @@ At admin/config/services/news_client/import there are two tools.
 ## Purge
 
 The button at admin/config/services/news_client/purge is the nuclear option for dealing with the cache. It will obliterate everything. It will probably only help in extreme circumstances and its use should be avoided...
+
+## Tokens
+
+News Client defines several tokens that can be used wherever necessary:
+
+* **[node:news_client_body_summary]** Resolves to the summary of the current body of the News Client Cached Article.
+* **[node:news_client_featured_image_url]** Resolves to the URL of the featured image in the News Client Cached Article.
+* **[node:news_client_featured_image_alt]** Resolves to the alt text for the featured image in the News Client Cached Article.
+
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_admin/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_admin/CHANGELOG.txt
index 6cc41fb0..d90a041d 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_admin/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_admin/CHANGELOG.txt
@@ -1,3 +1,11 @@
+7.x-1.58, 2018-12-11
+-------------------
+- Patch admin_menu to remove PHP 7 deprecation warning.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - No changes since last release.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.info b/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.info
index 398e14bf..f19dc6c2 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.info
@@ -37,8 +37,8 @@ features[page_manager_pages][] = panopoly_admin_layout_library
 features[page_manager_pages][] = panopoly_admin_page_library
 features[page_manager_pages][] = panopoly_admin_pane_library
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_admin"
-datestamp = "1539206885"
+datestamp = "1544590687"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.make b/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.make
index d644c0aa..181d0616 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.make
+++ b/profiles/wcm_base/modules/panopoly/panopoly_admin/panopoly_admin.make
@@ -42,6 +42,7 @@ projects[breakpoints][subdir] = contrib
 
 projects[admin_menu][version] = 3.0-rc5
 projects[admin_menu][subdir] = contrib
+projects[admin_menu][patch][2929025] = https://www.drupal.org/files/issues/admin-menu-2929025-each-function-deprecated-php-7.2.patch
 
 ; jQuery Update was moved to Panopoly Core, but is left in Panopoly Admin's
 ; .make file to retain a stable 1.x branch of Panopoly. See the following URL
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_core/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_core/CHANGELOG.txt
index c8c82cd0..517e8552 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_core/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_core/CHANGELOG.txt
@@ -1,3 +1,21 @@
+7.x-1.58, 2018-12-11
+-------------------
+- Patch defaultcontent module to remove PHP7 deprecation warning.
+- Allow overriding "more" text on Views-based widgets.
+- Update uuid module to 1.2.
+- Patch panels breadcrumb module to remove deprecation notice in PHP 7.2.
+- Patch/update views bulk operations to remove deprecation warnings in PHP 7.2.
+- Patch features to remove deprecation warning in PHP 7.2.
+- Upgrade & patch migrate module to make it compatible with PHP 7.
+- Patch Views for PHP 7.1 issue.
+- Patch apps to remove PHP 7 deprecation warning.
+- Update libraries module to resolve deprecation warning for PHP 7.
+- Out-of-date dependency processing in panopoly_core.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - No changes since last release.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.info b/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.info
index 662d1075..4600bfa4 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.info
@@ -82,8 +82,8 @@ features_exclude[variable][panelizer_taxonomy_term:panopoly_categories_allowed_t
 features_exclude[variable][panelizer_defaults_taxonomy_term_panopoly_categories] = panelizer_defaults_taxonomy_term_panopoly_categories
 features_exclude[variable][pathauto_taxonomy_term_panopoly_categories_pattern] = pathauto_taxonomy_term_panopoly_categories_pattern
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_core"
-datestamp = "1539206899"
+datestamp = "1544590701"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.make b/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.make
index 6472558d..27a1e999 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.make
+++ b/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.make
@@ -7,13 +7,14 @@ core = 7.x
 
 projects[ctools][version] = 1.14
 projects[ctools][subdir] = contrib
+projects[ctools][patch][1000146] = https://www.drupal.org/files/issues/2018-03-26/views_panes-more_link_text-1000146-28.patch
 
 projects[panels][version] = 3.9
 projects[panels][subdir] = contrib
 projects[panels][patch][1570120] = https://www.drupal.org/files/issues/move-image-1570120-31.patch
 projects[panels][patch][2897658] = https://www.drupal.org/files/issues/panels-menu-block-ipe-2897658-3.patch
 
-projects[panels_breadcrumbs][version] = 2.2
+projects[panels_breadcrumbs][version] = 2.3
 projects[panels_breadcrumbs][subdir] = contrib
 
 projects[panelizer][version] = 3.4
@@ -36,6 +37,8 @@ projects[fape][subdir] = contrib
 projects[views][version] = 3.20
 projects[views][subdir] = contrib
 projects[views][patch][2037469] = https://www.drupal.org/files/issues/views-exposed-sorts-2037469-26.patch
+projects[views][patch][2885660] = https://www.drupal.org/files/issues/2018-06-28/2885660-13.patch
+projects[views][patch][2977851] = https://www.drupal.org/files/issues/2018-06-06/2977851-views-php72-count-2.patch
 
 projects[views_autocomplete_filters][version] = 1.2
 projects[views_autocomplete_filters][subdir] = contrib
@@ -43,7 +46,7 @@ projects[views_autocomplete_filters][patch][2374709] = http://www.drupal.org/fil
 projects[views_autocomplete_filters][patch][2317351] = http://www.drupal.org/files/issues/views_autocomplete_filters-content-pane-2317351-4.patch
 projects[views_autocomplete_filters][patch][2404893] = https://www.drupal.org/files/issues/2404893-grammar_correction-11.patch
 
-projects[views_bulk_operations][version] = 3.4
+projects[views_bulk_operations][version] = 3.5
 projects[views_bulk_operations][subdir] = contrib
 
 ; The Usual Suspects
@@ -57,7 +60,7 @@ projects[token][subdir] = contrib
 projects[entity][version] = 1.9
 projects[entity][subdir] = contrib
 
-projects[libraries][version] = 2.3
+projects[libraries][version] = 2.5
 projects[libraries][subdir] = contrib
 
 projects[transliteration][version] = 3.2
@@ -82,9 +85,11 @@ projects[link][patch][2666912] = https://www.drupal.org/files/issues/revert-url-
 
 projects[apps][version] = 1.1
 projects[apps][subdir] = contrib
+projects[apps][patch][2945929] = https://www.drupal.org/files/issues/apps-php7-compat-2945929.patch
 
 projects[features][version] = 2.10
 projects[features][subdir] = contrib
+projects[features][patch][2931464] = "https://www.drupal.org/files/issues/features-create_function-is-deprecated-2931464-5.patch"
 
 projects[strongarm][version] = 2.0
 projects[strongarm][subdir] = contrib
@@ -97,8 +102,9 @@ projects[defaultcontent][version] = 1.0-alpha9
 projects[defaultcontent][subdir] = contrib
 projects[defaultcontent][patch][1754428] = http://drupal.org/files/1754428-allow-node-export-alter.patch
 projects[defaultcontent][patch][1757782] = http://drupal.org/files/1757782-cannot-import-menu-hierarchy-8.patch
+projects[defaultcontent][patch][2946138] = https://www.drupal.org/files/issues/defaultcontent-php7-compat-2946138.patch
 
-projects[migrate][version] = "2.9"
+projects[migrate][version] = "2.11"
 projects[migrate][type] = "module"
 projects[migrate][subdir] = "contrib"
 
@@ -122,5 +128,5 @@ projects[distro_update][subdir] = contrib
 projects[features_override][version] = 2.0-rc3
 projects[features_override][subdir] = contrib
 
-projects[uuid][version] = 1.1
+projects[uuid][version] = 1.2
 projects[uuid][subdir] = contrib
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.profile.inc b/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.profile.inc
index aa919e45..f064b346 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.profile.inc
+++ b/profiles/wcm_base/modules/panopoly/panopoly_core/panopoly_core.profile.inc
@@ -26,8 +26,8 @@ function panopoly_core_install_load_profile(&$install_state) {
     $module_info = drupal_parse_info_file(drupal_get_path('module', $module) . '/' . $module . '.info');
     if (!empty($module_info['dependencies'])) {
       foreach ($module_info['dependencies'] as $dependency) {
-        $parts = explode(' (', $dependency, 2);
-        $dependencies[] = array_shift($parts);
+        $parts = drupal_parse_dependency($dependency);
+        $dependencies[] = $parts['name'];
       }
     }
   }
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_magic/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_magic/CHANGELOG.txt
index 569e8162..a197e9dd 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_magic/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_magic/CHANGELOG.txt
@@ -1,3 +1,12 @@
+7.x-1.58, 2018-12-11
+-------------------
+- Allow overriding "more" text on Views-based widgets.
+- Swap order of "Save" and "Update Preview" buttons when in manual preview mode.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - PHP notices when previewing widgets.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.info b/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.info
index 5f27405d..36cbb348 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.info
@@ -15,8 +15,8 @@ stylesheets[all][] = css/panopoly-modal.css
 features[features_api][] = api:2
 files[] = plugins/views/panopoly_magic_plugin_display_panel_pane.inc
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_magic"
-datestamp = "1539206939"
+datestamp = "1544590743"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.module b/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.module
index fd5b5536..cd98ac64 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.module
+++ b/profiles/wcm_base/modules/panopoly/panopoly_magic/panopoly_magic.module
@@ -492,6 +492,7 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) {
         '#type' => 'button',
         '#value' => t('Update Preview'),
         '#attributes' => $preview_attributes,
+        '#weight' => -100,
         '#ajax' => array(
           'callback' => 'panopoly_magic_ajax_update_preview',
           'wrapper' => 'panopoly-form-widget-preview',
@@ -904,8 +905,19 @@ function panopoly_magic_form_views_content_views_panes_content_type_edit_form_al
     $form['exposed']['more_link']['#parents'] = array('more_link');
     unset($form['more_link']);
   }
-  
-    
+
+  // Add an option to the more link text if views allows this to happen
+  if (!empty($form['more_text'])) {
+    $form['exposed']['more_text'] = $form['more_text'];
+    $form['exposed']['more_text']['#parents'] = array('more_text');
+    unset($form['more_text']);
+    $form['exposed']['more_text']['#states'] = array(
+      'visible' => array(
+        ':input[name="more_link"]' => array('checked' => TRUE),
+      ),
+    );
+  }
+
   // Update the field settings for pagers
   if (!empty($form['use_pager']) && !empty($form['pager_id'])) {
     $form['use_pager']['#prefix'] = '<div class="form-item container-inline">';
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_pages/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_pages/CHANGELOG.txt
index a53f624a..0040e704 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_pages/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_pages/CHANGELOG.txt
@@ -1,3 +1,11 @@
+7.x-1.58, 2018-12-11
+-------------------
+- No changes since last release.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - No changes since last release.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_pages/panopoly_pages.info b/profiles/wcm_base/modules/panopoly/panopoly_pages/panopoly_pages.info
index 572414b1..8e6f1755 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_pages/panopoly_pages.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_pages/panopoly_pages.info
@@ -81,8 +81,8 @@ features_exclude[variable][pathauto_node_panopoly_landing_page_pattern] = pathau
 features_exclude[variable][pathauto_node_panopoly_page_pattern] = pathauto_node_panopoly_page_pattern
 features_exclude[variable][pathauto_taxonomy_term_panopoly_categories_pattern] = pathauto_taxonomy_term_panopoly_categories_pattern
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_pages"
-datestamp = "1539206950"
+datestamp = "1544590755"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_search/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_search/CHANGELOG.txt
index f46d2f5a..1b2e6271 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_search/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_search/CHANGELOG.txt
@@ -1,3 +1,11 @@
+7.x-1.58, 2018-12-11
+-------------------
+- Update search_api to 1.25 and search_api_db to 1.7.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - Update to search_api_solr 1.14 for SA-CONTRIB-2018-065.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.info b/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.info
index ea7d6a50..586a2159 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.info
@@ -54,8 +54,8 @@ features[variable][] = search_cron_limit
 features[views_view][] = panopoly_database_search
 features[views_view][] = panopoly_search
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_search"
-datestamp = "1539206962"
+datestamp = "1544590768"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.make b/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.make
index 74110952..69efd15b 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.make
+++ b/profiles/wcm_base/modules/panopoly/panopoly_search/panopoly_search.make
@@ -8,13 +8,13 @@ core = 7.x
 projects[facetapi][version] = 1.5
 projects[facetapi][subdir] = contrib
 
-projects[search_api][version] = 1.24
+projects[search_api][version] = 1.25
 projects[search_api][subdir] = contrib
 
 projects[search_api_solr][version] = 1.14
 projects[search_api_solr][subdir] = contrib
 
-projects[search_api_db][version] = 1.6
+projects[search_api_db][version] = 1.7
 projects[search_api_db][subdir] = contrib
 
 ; Solr PHP Client Library
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_test/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_test/CHANGELOG.txt
index 322e9070..d05a5ed9 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_test/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_test/CHANGELOG.txt
@@ -1,3 +1,11 @@
+7.x-1.58, 2018-12-11
+-------------------
+- No changes since last release.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - No changes since last release.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_test/panopoly_test.info b/profiles/wcm_base/modules/panopoly/panopoly_test/panopoly_test.info
index ca0e1535..ac0cc919 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_test/panopoly_test.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_test/panopoly_test.info
@@ -99,8 +99,8 @@ features_exclude[dependencies][panopoly_pages] = panopoly_pages
 features_exclude[dependencies][panelizer] = panelizer
 hidden = 1
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_test"
-datestamp = "1539206981"
+datestamp = "1544590782"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_theme/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_theme/CHANGELOG.txt
index a02debcc..a1048d20 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_theme/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_theme/CHANGELOG.txt
@@ -1,3 +1,11 @@
+7.x-1.58, 2018-12-11
+-------------------
+- No changes since last release.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - No changes since last release.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_theme/panopoly_theme.info b/profiles/wcm_base/modules/panopoly/panopoly_theme/panopoly_theme.info
index 25f09c99..879dcac2 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_theme/panopoly_theme.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_theme/panopoly_theme.info
@@ -11,8 +11,8 @@ stylesheets[all][] = css/panopoly-accordian.css
 stylesheets[all][] = css/panopoly-layouts.css
 features[features_api][] = api:2
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_theme"
-datestamp = "1539207184"
+datestamp = "1544590793"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_widgets/CHANGELOG.txt b/profiles/wcm_base/modules/panopoly/panopoly_widgets/CHANGELOG.txt
index fde4d11a..621a7f19 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_widgets/CHANGELOG.txt
+++ b/profiles/wcm_base/modules/panopoly/panopoly_widgets/CHANGELOG.txt
@@ -1,3 +1,14 @@
+7.x-1.58, 2018-12-11
+-------------------
+- File entity overwriting slide title on spotlight widgets.
+- Normalize "Slide duration" for Spotlight widgets.
+- Update Media to 2.21.
+- Update file_entity to 2.22.
+
+7.x-1.57, 2018-10-18
+-------------------
+- No changes since last release.
+
 7.x-1.56, 2018-10-10
 -------------------
 - No changes since last release.
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.features.field_instance.inc b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.features.field_instance.inc
index 57ea2cd8..c1f5ec1a 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.features.field_instance.inc
+++ b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.features.field_instance.inc
@@ -387,7 +387,11 @@ function panopoly_widgets_field_default_field_instances() {
   // 'fieldable_panels_pane-spotlight-field_basic_spotlight_duration'.
   $field_instances['fieldable_panels_pane-spotlight-field_basic_spotlight_duration'] = array(
     'bundle' => 'spotlight',
-    'default_value' => NULL,
+    'default_value' => array(
+      0 => array(
+        'value' => 5,
+      ),
+    ),
     'deleted' => 0,
     'description' => '',
     'display' => array(
@@ -401,7 +405,7 @@ function panopoly_widgets_field_default_field_instances() {
     'entity_type' => 'fieldable_panels_pane',
     'field_name' => 'field_basic_spotlight_duration',
     'label' => 'Slide Duration',
-    'required' => 0,
+    'required' => 1,
     'settings' => array(
       'max' => 60,
       'min' => 1,
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.info b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.info
index 91b7b9ba..338c8eaf 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.info
+++ b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.info
@@ -125,8 +125,8 @@ features[linkit_profiles][] = content_fields
 features[views_view][] = panopoly_widgets_general_content
 features_exclude[dependencies][linkit] = linkit
 
-; Information added by Drupal.org packaging script on 2018-10-10
-version = "7.x-1.56"
+; Information added by Drupal.org packaging script on 2018-12-12
+version = "7.x-1.58"
 core = "7.x"
 project = "panopoly_widgets"
-datestamp = "1539207784"
+datestamp = "1544590822"
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.install b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.install
index 7465dc06..1536a95e 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.install
+++ b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.install
@@ -485,3 +485,57 @@ function panopoly_widgets_update_7022() {
     }
   }
 }
+
+/**
+ * Make sure that "Slide duration" on Spotlight widgets always has a value.
+ */
+function panopoly_widgets_update_7023(&$sandbox) {
+  if (!isset($sandbox['fpids'])) {
+    $query = new EntityFieldQuery();
+    $query
+      ->entityCondition('entity_type', 'fieldable_panels_pane')
+      ->entityCondition('bundle', 'spotlight');
+    $result = $query->execute();
+    if (isset($result['fieldable_panels_pane'])) {
+      $sandbox['fpids'] = array_keys($result['fieldable_panels_pane']);
+    }
+  }
+  else {
+    $count = 10;
+    while (!empty($sandbox['fpids']) && $count >= 0) {
+      $fpp = fieldable_panels_panes_load(array_shift($sandbox['fpids']));
+      $wrapper = entity_metadata_wrapper('fieldable_panels_pane', $fpp);
+      if (!$wrapper->field_basic_spotlight_duration->value()) {
+        $wrapper->field_basic_spotlight_duration->set(variable_get('panopoly_widgets_spotlight_rotation_time', 5));
+        $wrapper->save();
+      }
+    }
+  }
+
+  $sandbox['#finished'] = empty($sandbox['fpids']);
+
+  if ($sandbox['#finished']) {
+    variable_del('panopoly_widgets_spotlight_rotation_time');
+  }
+}
+
+/**
+ * Update field instance settings for duration fields on Spotlight widgets.
+ */
+function panopoly_widgets_update_7024() {
+  // Remove legacy field if it's still around.
+  if ($instance_info = field_info_instance('fieldable_panels_pane', 'field_spotlight_rotation_time', 'spotlight')) {
+    field_delete_instance($instance_info);
+  }
+
+  // Make the default value 5 and mark as required.
+  if ($instance_info = field_info_instance('fieldable_panels_pane', 'field_basic_spotlight_duration', 'spotlight')) {
+    $instance_info['default_value'] = array(
+      0 => array(
+        'value' => 5,
+      ),
+    );
+    $instance_info['required'] = 1;
+    field_update_instance($instance_info);
+  }
+}
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.make b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.make
index 29e83641..25bad686 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.make
+++ b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.make
@@ -20,10 +20,10 @@ projects[menu_block][subdir] = contrib
 
 ; Panopoly - Contrib - Files & Media
 
-projects[file_entity][version] = 2.21
+projects[file_entity][version] = 2.22
 projects[file_entity][subdir] = contrib
 
-projects[media][version] = 2.19
+projects[media][version] = 2.21
 projects[media][subdir] = contrib
 
 projects[media_youtube][version] = 3.7
diff --git a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.spotlight.inc b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.spotlight.inc
index fb50364f..ec4fffab 100644
--- a/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.spotlight.inc
+++ b/profiles/wcm_base/modules/panopoly/panopoly_widgets/panopoly_widgets.spotlight.inc
@@ -159,7 +159,7 @@ function panopoly_widgets_field_formatter_view($entity_type, $entity, $field, $i
     $duration = $duration_field['value'];
   }
   if (empty($duration)) {
-    $duration = variable_get('panopoly_widgets_spotlight_rotation_time', 4);
+    $duration = variable_get('panopoly_widgets_spotlight_rotation_time', 5);
   }
 
   $pager_style = 'full'; // Default to the Full pager if field isn't filled out (i.e., legacy data).
@@ -208,6 +208,12 @@ function panopoly_widgets_field_formatter_view($entity_type, $entity, $field, $i
 
   // Assemble the spotlight items (rendered in panopoly_spotlight_wrapper())
   foreach ($items as $delta => $item_data) {
+    if (isset($item_data['field_title'])) {
+      $item_data['title'] = $item_data['field_title'];
+    }
+    if (isset($item_data['field_alt'])) {
+      $item_data['alt'] = $item_data['field_alt'];
+    }
     $element[0]['slides'][] = array(
       '#theme' => 'panopoly_spotlight_view',
       '#items' => $item_data,
@@ -235,7 +241,7 @@ function panopoly_widgets_field_widget_form(&$form, &$form_state, $field, $insta
     $element['title'] = array(
       '#title' => t('Title'),
       '#type' => 'textfield',
-      '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL,
+      '#default_value' => isset($items[$delta]['field_title']) ? $items[$delta]['field_title'] : NULL,
     );
 
     $element['link'] = array(
@@ -283,7 +289,7 @@ function panopoly_widgets_field_widget_form(&$form, &$form_state, $field, $insta
     $element['alt'] = array(
       '#title' => t('Alt text'),
       '#type' => 'textfield',
-      '#default_value' => isset($items[$delta]['alt']) ? $items[$delta]['alt'] : NULL,
+      '#default_value' => isset($items[$delta]['field_alt']) ? $items[$delta]['field_alt'] : NULL,
     );
 
     $element['description'] = array(
@@ -327,6 +333,12 @@ function panopoly_widgets_field_presave($entity_type, $entity, $field, $instance
           $item['fid'] = $fid;
         }
       }
+      if (isset($item['field_title'])) {
+        $item['title'] = $item['field_title'];
+      }
+      if (isset($item['field_alt'])) {
+        $item['alt'] = $item['field_alt'];
+      }
     }
     image_field_presave($entity_type, $entity, $field, $instance, $langcode, $items);
   }
@@ -338,11 +350,13 @@ function panopoly_widgets_field_presave($entity_type, $entity, $field, $instance
 function panopoly_widgets_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
   $entity_items_copy = $items;
   image_field_load($entity_type, $entities, $field, $instances, $langcode, $items, $age);
-  // image_field_load() will overwrite 'title' with the image title. Here we
-  // return it to the item title.
+  // Both image_field_load() and file_entity_entity_load() will overwrite the
+  // 'title' and 'alt' with the one from the file. Here we save the originals
+  // for later.
   foreach ($entity_items_copy as $entity_id => $items_copy) {
     foreach ($items_copy as $delta => $item) {
-      $items[$entity_id][$delta]['title'] = $item['title'];
+      $items[$entity_id][$delta]['field_title'] = $item['title'];
+      $items[$entity_id][$delta]['field_alt'] = $item['alt'];
     }
   }
 }
diff --git a/profiles/wcm_base/themes/wcm_omega/preprocess/fieldable-panels-pane.preprocess.inc b/profiles/wcm_base/themes/wcm_omega/preprocess/fieldable-panels-pane.preprocess.inc
index aa66d361..65d6032b 100644
--- a/profiles/wcm_base/themes/wcm_omega/preprocess/fieldable-panels-pane.preprocess.inc
+++ b/profiles/wcm_base/themes/wcm_omega/preprocess/fieldable-panels-pane.preprocess.inc
@@ -60,8 +60,8 @@ function wcm_omega_preprocess_fieldable_panels_pane(&$vars) {
 
   // Image panes
   elseif ($type == 'image') {
-    if (!empty($vars['content']['field_basic_image_image'])) {
-      $vars['content']['field_basic_image_image'][0]['#path']['path'] = !empty($vars['elements']['#fieldable_panels_pane']->field_ocio_link) ? $vars['elements']['#fieldable_panels_pane']->field_ocio_link['und'][0]['display_url'] : NULL;
+    if (!empty($vars['content']['field_basic_image_image']) && !empty($vars['elements']['#fieldable_panels_pane']->field_ocio_link)) {
+      $vars['content']['field_basic_image_image'][0]['#path'] = array('path' => $vars['elements']['#fieldable_panels_pane']->field_ocio_link['und'][0]['display_url']);
     }
   }
 }
diff --git a/profiles/wcm_base/themes/wcm_omega/preprocess/page.preprocess.inc b/profiles/wcm_base/themes/wcm_omega/preprocess/page.preprocess.inc
index 7960fb8a..8d3ac908 100644
--- a/profiles/wcm_base/themes/wcm_omega/preprocess/page.preprocess.inc
+++ b/profiles/wcm_base/themes/wcm_omega/preprocess/page.preprocess.inc
@@ -11,7 +11,7 @@ function wcm_omega_preprocess_page(&$vars) {
   $vars['main_classes'] = join(' ', $classes);
 
 
-	//render landing page top and bottom banner images in regions outside of 'content'
+  //render landing page top and bottom banner images in regions outside of 'content'
   $vars['landing_page'] = isset($vars['node']) && $vars['node']->type == 'ocio_landing_page';
 
   if ($vars['landing_page']) {
@@ -36,9 +36,9 @@ function wcm_omega_preprocess_page(&$vars) {
         $top_banner_text['#label_display'] = 'hidden';
 
         $top_banner_url = field_view_field('node', $vars['node'], 'field_banner_image_text_link');
-					if (!empty($top_banner_url)) {
-						$top_banner_text[0]['#markup'] = l($top_banner_text['#items'][0]['value'], $top_banner_url['#items'][0]['url']);
-					}
+          if (!empty($top_banner_url)) {
+            $top_banner_text[0]['#markup'] = l($top_banner_text['#items'][0]['value'], $top_banner_url['#items'][0]['url']);
+          }
 
         $vars['page']['hero']['top_banner']['#markup'] .= drupal_render($top_banner_text);
       }
diff --git a/profiles/wcm_base/wcm_base.make b/profiles/wcm_base/wcm_base.make
index 418b3974..f0d12313 100644
--- a/profiles/wcm_base/wcm_base.make
+++ b/profiles/wcm_base/wcm_base.make
@@ -485,31 +485,31 @@ libraries[ocio_modernizr][download][branch] = 7.x-1.x
 
 ; The Panopoly Foundation
 
-projects[panopoly_core][version] = 1.56
+projects[panopoly_core][version] = 1.58
 projects[panopoly_core][subdir] = panopoly
 
-projects[panopoly_theme][version] = 1.56
+projects[panopoly_theme][version] = 1.58
 projects[panopoly_theme][subdir] = panopoly
 
-projects[panopoly_magic][version] = 1.56
+projects[panopoly_magic][version] = 1.58
 projects[panopoly_magic][subdir] = panopoly
 
-projects[panopoly_widgets][version] = 1.56
+projects[panopoly_widgets][version] = 1.58
 projects[panopoly_widgets][subdir] = panopoly
 
-projects[panopoly_admin][version] = 1.56
+projects[panopoly_admin][version] = 1.58
 projects[panopoly_admin][subdir] = panopoly
 
 
 ; The Panopoly Toolset
 
-projects[panopoly_pages][version] = 1.56
+projects[panopoly_pages][version] = 1.58
 projects[panopoly_pages][subdir] = panopoly
 
-projects[panopoly_search][version] = 1.56
+projects[panopoly_search][version] = 1.58
 projects[panopoly_search][subdir] = panopoly
 
 ; For running the automated tests.
 
-projects[panopoly_test][version] = 1.56
+projects[panopoly_test][version] = 1.58
 projects[panopoly_test][subdir] = panopoly
-- 
GitLab