diff --git a/civicrm.php b/civicrm.php
index 67ac8a2bcec4b59e840cf3d9f396c0740efc9769..b9fd38823484de27e857cc107aaec3422abd8351 100644
--- a/civicrm.php
+++ b/civicrm.php
@@ -2,7 +2,7 @@
 /**
  * Plugin Name: CiviCRM
  * Description: CiviCRM - Growing and Sustaining Relationships
- * Version: 5.66.0
+ * Version: 5.66.1
  * Requires at least: 4.9
  * Requires PHP:      7.3
  * Author: CiviCRM LLC
@@ -36,7 +36,7 @@ if (!defined('ABSPATH')) {
 }
 
 // Set version here: changing it forces Javascript and CSS to reload.
-define('CIVICRM_PLUGIN_VERSION', '5.66.0');
+define('CIVICRM_PLUGIN_VERSION', '5.66.1');
 
 // Store reference to this file.
 if (!defined('CIVICRM_PLUGIN_FILE')) {
diff --git a/civicrm/CRM/Campaign/Page/SurveyType.php b/civicrm/CRM/Campaign/Page/SurveyType.php
index d1e972df52a73b6f2a68f07a843fad44c968a73b..b72daac2d8f5420df8c779c97527f2bbdeee1d41 100644
--- a/civicrm/CRM/Campaign/Page/SurveyType.php
+++ b/civicrm/CRM/Campaign/Page/SurveyType.php
@@ -92,22 +92,26 @@ class CRM_Campaign_Page_SurveyType extends CRM_Core_Page_Basic {
           'url' => 'civicrm/admin/campaign/surveyType',
           'qs' => 'action=update&id=%%id%%&reset=1',
           'title' => ts('Edit %1', [1 => $this->_gName]),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::UPDATE),
         ],
         CRM_Core_Action::DISABLE => [
           'name' => ts('Disable'),
           'ref' => 'crm-enable-disable',
           'title' => ts('Disable %1', [1 => $this->_gName]),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::DISABLE),
         ],
         CRM_Core_Action::ENABLE => [
           'name' => ts('Enable'),
           'ref' => 'crm-enable-disable',
           'title' => ts('Enable %1', [1 => $this->_gName]),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::ENABLE),
         ],
         CRM_Core_Action::DELETE => [
           'name' => ts('Delete'),
           'url' => 'civicrm/admin/campaign/surveyType',
           'qs' => 'action=delete&id=%%id%%',
           'title' => ts('Delete %1 Type', [1 => $this->_gName]),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::DELETE),
         ],
       ];
     }
diff --git a/civicrm/CRM/Contribute/Page/ManagePremiums.php b/civicrm/CRM/Contribute/Page/ManagePremiums.php
index f1b2b7c86ae6e4895edc6f66914d4f6a13c0cb90..0c08a37687d28e8eea7a22ddb00217da081953f8 100644
--- a/civicrm/CRM/Contribute/Page/ManagePremiums.php
+++ b/civicrm/CRM/Contribute/Page/ManagePremiums.php
@@ -53,28 +53,33 @@ class CRM_Contribute_Page_ManagePremiums extends CRM_Core_Page_Basic {
           'url' => 'civicrm/admin/contribute/managePremiums',
           'qs' => 'action=update&id=%%id%%&reset=1',
           'title' => ts('Edit Premium'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::UPDATE),
         ],
         CRM_Core_Action::PREVIEW => [
           'name' => ts('Preview'),
           'url' => 'civicrm/admin/contribute/managePremiums',
           'qs' => 'action=preview&id=%%id%%',
           'title' => ts('Preview Premium'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::PREVIEW),
         ],
         CRM_Core_Action::DISABLE => [
           'name' => ts('Disable'),
           'ref' => 'crm-enable-disable',
           'title' => ts('Disable Premium'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::DISABLE),
         ],
         CRM_Core_Action::ENABLE => [
           'name' => ts('Enable'),
           'ref' => 'crm-enable-disable',
           'title' => ts('Enable Premium'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::ENABLE),
         ],
         CRM_Core_Action::DELETE => [
           'name' => ts('Delete'),
           'url' => 'civicrm/admin/contribute/managePremiums',
           'qs' => 'action=delete&id=%%id%%',
           'title' => ts('Delete Premium'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::DELETE),
         ],
       ];
     }
@@ -125,7 +130,7 @@ class CRM_Contribute_Page_ManagePremiums extends CRM_Core_Page_Basic {
         $action -= CRM_Core_Action::DISABLE;
       }
 
-      $premiums[$dao->id]['action'] = CRM_Core_Action::formLink(self::links(),
+      $premiums[$dao->id]['action'] = CRM_Core_Action::formLink($this->links(),
         $action,
         ['id' => $dao->id],
         ts('more'),
diff --git a/civicrm/CRM/Core/DAO/ActionSchedule.php b/civicrm/CRM/Core/DAO/ActionSchedule.php
index f75590e0648baa0d2bde4f3fcf435416b3d62658..1f00ac68b866c436f6de51dfde74f8782bc86d24 100644
--- a/civicrm/CRM/Core/DAO/ActionSchedule.php
+++ b/civicrm/CRM/Core/DAO/ActionSchedule.php
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Core/ActionSchedule.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:7cd61559377e23d6ad4c833616f22a12)
+ * (GenCodeChecksum:e6121895aa480e9b4fdbf171b01b91dc)
  */
 
 /**
@@ -57,10 +57,10 @@ class CRM_Core_DAO_ActionSchedule extends CRM_Core_DAO {
   public $id;
 
   /**
-   * Name of the action(reminder)
+   * Name of the scheduled action
    *
    * @var string
-   *   (SQL type: varchar(64))
+   *   (SQL type: varchar(128))
    *   Note that values will be retrieved from the database as a string.
    */
   public $name;
@@ -491,10 +491,10 @@ class CRM_Core_DAO_ActionSchedule extends CRM_Core_DAO {
           'name' => 'name',
           'type' => CRM_Utils_Type::T_STRING,
           'title' => ts('Name'),
-          'description' => ts('Name of the action(reminder)'),
+          'description' => ts('Name of the scheduled action'),
           'required' => TRUE,
-          'maxlength' => 64,
-          'size' => CRM_Utils_Type::BIG,
+          'maxlength' => 128,
+          'size' => CRM_Utils_Type::HUGE,
           'usage' => [
             'import' => FALSE,
             'export' => FALSE,
diff --git a/civicrm/CRM/Group/Form/Edit.php b/civicrm/CRM/Group/Form/Edit.php
index 772cda0786c567ab17e99e6c79b1704198b2f1e7..22e419ea1468eaf348b02ce0123bae00cb0d8262 100644
--- a/civicrm/CRM/Group/Form/Edit.php
+++ b/civicrm/CRM/Group/Form/Edit.php
@@ -201,6 +201,8 @@ class CRM_Group_Form_Edit extends CRM_Core_Form {
       }
     }
 
+    $parentGroupIds = explode(',', $this->_groupValues['parents']);
+    $defaults['parents'] = $parentGroupIds;
     if (empty($defaults['parents'])) {
       $defaults['parents'] = CRM_Core_BAO_Domain::getGroupId();
     }
@@ -254,15 +256,9 @@ class CRM_Group_Form_Edit extends CRM_Core_Form {
     //build custom data
     CRM_Custom_Form_CustomData::buildQuickForm($this);
 
-    $doParentCheck = FALSE;
-    if (CRM_Core_Permission::isMultisiteEnabled()) {
-      $doParentCheck = !($this->_id && CRM_Core_BAO_Domain::isDomainGroup($this->_id));
-    }
-
     $options = [
       'selfObj' => $this,
       'parentGroups' => $parentGroups,
-      'doParentCheck' => $doParentCheck,
     ];
     $this->addFormRule(['CRM_Group_Form_Edit', 'formRule'], $options);
   }
@@ -281,29 +277,8 @@ class CRM_Group_Form_Edit extends CRM_Core_Form {
   public static function formRule($fields, $fileParams, $options) {
     $errors = [];
 
-    $doParentCheck = $options['doParentCheck'];
     $self = &$options['selfObj'];
 
-    if ($doParentCheck) {
-      $parentGroups = $options['parentGroups'];
-
-      $grpRemove = 0;
-      foreach ($fields as $key => $val) {
-        if (substr($key, 0, 20) == 'remove_parent_group_') {
-          $grpRemove++;
-        }
-      }
-
-      $grpAdd = 0;
-      if (!empty($fields['parents'])) {
-        $grpAdd++;
-      }
-
-      if ((count($parentGroups) >= 1) && (($grpRemove - $grpAdd) >= count($parentGroups))) {
-        $errors['parents'] = ts('Make sure at least one parent group is set.');
-      }
-    }
-
     // do check for both name and title uniqueness
     if (!empty($fields['title'])) {
       $title = trim($fields['title']);
@@ -402,9 +377,6 @@ WHERE  title = %1
         $parentGroups[$parentGroupId] = $groupNames[$parentGroupId];
         if (array_key_exists($parentGroupId, $groupNames)) {
           $parentGroupElements[$parentGroupId] = $groupNames[$parentGroupId];
-          $form->addElement('checkbox', "remove_parent_group_$parentGroupId",
-            $groupNames[$parentGroupId]
-          );
         }
       }
     }
@@ -412,6 +384,10 @@ WHERE  title = %1
 
     if (isset($form->_id)) {
       $potentialParentGroupIds = CRM_Contact_BAO_GroupNestingCache::getPotentialCandidates($form->_id, $groupNames);
+      // put back current groups because they are selected by default
+      if (!empty($parentGroupIds)) {
+        $potentialParentGroupIds = array_merge($potentialParentGroupIds, $parentGroupIds);
+      }
     }
     else {
       $potentialParentGroupIds = array_keys($groupNames);
@@ -431,7 +407,7 @@ WHERE  title = %1
       else {
         $required = FALSE;
       }
-      $form->add('select', 'parents', ts('Add Parent'), $parentGroupSelectValues, $required, ['class' => 'crm-select2', 'multiple' => TRUE]);
+      $form->add('select', 'parents', ts('Parents'), $parentGroupSelectValues, $required, ['class' => 'crm-select2', 'multiple' => TRUE]);
     }
 
     return $parentGroups;
diff --git a/civicrm/CRM/PCP/Page/PCP.php b/civicrm/CRM/PCP/Page/PCP.php
index 2fb8c5f822c6abc02ed4da4ee7df219c7a8a4d83..d18e6354d3d89a29681c7fee784b2ba0697cc675 100644
--- a/civicrm/CRM/PCP/Page/PCP.php
+++ b/civicrm/CRM/PCP/Page/PCP.php
@@ -54,18 +54,21 @@ class CRM_PCP_Page_PCP extends CRM_Core_Page_Basic {
           'url' => 'civicrm/pcp/info',
           'qs' => 'action=update&reset=1&id=%%id%%&context=dashboard',
           'title' => ts('Edit Personal Campaign Page'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::UPDATE),
         ],
         CRM_Core_Action::RENEW => [
           'name' => ts('Approve'),
           'url' => 'civicrm/admin/pcp',
           'qs' => 'action=renew&id=%%id%%',
           'title' => ts('Approve Personal Campaign Page'),
+          'weight' => 30,
         ],
         CRM_Core_Action::REVERT => [
           'name' => ts('Reject'),
           'url' => 'civicrm/admin/pcp',
           'qs' => 'action=revert&id=%%id%%',
           'title' => ts('Reject Personal Campaign Page'),
+          'weight' => 30,
         ],
         CRM_Core_Action::DELETE => [
           'name' => ts('Delete'),
@@ -73,18 +76,21 @@ class CRM_PCP_Page_PCP extends CRM_Core_Page_Basic {
           'qs' => 'action=delete&id=%%id%%',
           'extra' => 'onclick = "return confirm(\'' . $deleteExtra . '\');"',
           'title' => ts('Delete Personal Campaign Page'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::DELETE),
         ],
         CRM_Core_Action::ENABLE => [
           'name' => ts('Enable'),
           'url' => 'civicrm/admin/pcp',
           'qs' => 'action=enable&id=%%id%%',
           'title' => ts('Enable'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::ENABLE),
         ],
         CRM_Core_Action::DISABLE => [
           'name' => ts('Disable'),
           'url' => 'civicrm/admin/pcp',
           'qs' => 'action=disable&id=%%id%%',
           'title' => ts('Disable'),
+          'weight' => CRM_Core_Action::getWeight(CRM_Core_Action::DISABLE),
         ],
       ];
     }
@@ -296,7 +302,7 @@ class CRM_PCP_Page_PCP extends CRM_Core_Page_Basic {
         'page_title' => $title,
         'page_url' => $pageUrl,
         'page_type' => $page_type,
-        'action' => CRM_Core_Action::formLink(self::links(), $action,
+        'action' => CRM_Core_Action::formLink($this->links(), $action,
           ['id' => $pcp->id], ts('more'), FALSE, 'contributionpage.pcp.list', 'PCP', $pcp->id
         ),
         'title' => $pcp->title,
diff --git a/civicrm/CRM/Pledge/Form/Pledge.php b/civicrm/CRM/Pledge/Form/Pledge.php
index 1da913341f8464becafb9207b514a9a0985c4c71..0cdaa8453e485e0140511802c4bc3930f548fb49 100644
--- a/civicrm/CRM/Pledge/Form/Pledge.php
+++ b/civicrm/CRM/Pledge/Form/Pledge.php
@@ -41,7 +41,7 @@ class CRM_Pledge_Form_Pledge extends CRM_Core_Form {
    * The Pledge values if an existing pledge.
    * @var array
    */
-  public $_values;
+  public $_values = [];
 
   /**
    * The Pledge frequency Units.
diff --git a/civicrm/CRM/Upgrade/Incremental/php/FiveSixtySix.php b/civicrm/CRM/Upgrade/Incremental/php/FiveSixtySix.php
index 55c6d1df36d07c0cd1717415d21a2f9a5b4e3cc7..b9213c11362201d1391c39fe1190b0ef2729f18e 100644
--- a/civicrm/CRM/Upgrade/Incremental/php/FiveSixtySix.php
+++ b/civicrm/CRM/Upgrade/Incremental/php/FiveSixtySix.php
@@ -35,12 +35,12 @@ class CRM_Upgrade_Incremental_php_FiveSixtySix extends CRM_Upgrade_Incremental_B
    *   The version number matching this function name
    */
   public function upgrade_5_66_alpha1($rev): void {
+    // Increase column length before the upgrade sql writes to it
+    $this->addTask('Increase ActionSchedule.name length', 'alterColumn', 'civicrm_action_schedule', 'name', "varchar(128) COMMENT 'Name of the scheduled action'");
     $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
+    // These run after the sql file
     $this->addTask('Make Contribution.tax_amount required', 'alterColumn', 'civicrm_contribution', 'tax_amount', "decimal(20,2) DEFAULT 0 NOT NULL COMMENT 'Total tax amount of this contribution.'");
     $this->addTask('Make LineItem.tax_amount required', 'alterColumn', 'civicrm_line_item', 'tax_amount', "decimal(20,2) DEFAULT 0 NOT NULL COMMENT 'tax of each item'");
-    // These run after the sql file
-    $this->addTask('Make Discount.entity_table required', 'alterColumn', 'civicrm_discount', 'entity_table', "varchar(64) NOT NULL COMMENT 'Name of the action(reminder)'");
-    $this->addTask('Make ActionSchedule.name required', 'alterColumn', 'civicrm_action_schedule', 'name', "varchar(64) NOT NULL COMMENT 'physical tablename for entity being joined to discount, e.g. civicrm_event'");
     $this->addTask(ts('Create index %1', [1 => 'civicrm_action_schedule.UI_name']), 'addIndex', 'civicrm_action_schedule', 'name', 'UI');
     $this->addTask('Add fields to civicrm_mail_settings to allow more flexibility for email to activity', 'addMailSettingsFields');
     $this->addTask('Move serialized contents of civicrm_survey.recontact_interval into civicrm_option_value.filter', 'migrateRecontactInterval');
@@ -83,6 +83,17 @@ class CRM_Upgrade_Incremental_php_FiveSixtySix extends CRM_Upgrade_Incremental_B
     }
   }
 
+  /**
+   * Upgrade step; adds tasks including 'runSql'.
+   *
+   * @param string $rev
+   *   The version number matching this function name
+   */
+  public function upgrade_5_66_1($rev): void {
+    $this->addTask('Make ActionSchedule.name required', 'alterColumn', 'civicrm_action_schedule', 'name', "varchar(128) NOT NULL COMMENT 'Name of the scheduled action'");
+    $this->addTask('Make Discount.entity_table required', 'alterColumn', 'civicrm_discount', 'entity_table', "varchar(64) NOT NULL COMMENT 'physical tablename for entity being joined to discount, e.g. civicrm_event'");
+  }
+
   /**
    * Add fields to civicrm_mail_settings to allow more flexibility for email to activity
    *
diff --git a/civicrm/CRM/Utils/Check/Component/Env.php b/civicrm/CRM/Utils/Check/Component/Env.php
index 2ac6246f6f2f483a747db2e1ab019ab8153c6405..f0a88a71624ae612c9e892e4ea6bab6da85e1708 100644
--- a/civicrm/CRM/Utils/Check/Component/Env.php
+++ b/civicrm/CRM/Utils/Check/Component/Env.php
@@ -1106,4 +1106,25 @@ class CRM_Utils_Check_Component_Env extends CRM_Utils_Check_Component {
     return $messages;
   }
 
+  public function checkAngularModuleSettings() {
+    $messages = [];
+    $modules = Civi::container()->get('angular')->getModules();
+    foreach ($modules as $name => $module) {
+      if (!empty($module['settings'])) {
+        $messages[] = new CRM_Utils_Check_Message(
+          __FUNCTION__ . $name,
+          ts('The Angular file "%1" from extension "%2" must be updated to use "settingsFactory" instead of "settings". <a %3>Developer info...</a>', [
+            1 => $name,
+            2 => $module['ext'],
+            3 => 'target="_blank" href="https://github.com/civicrm/civicrm-core/pull/19052"',
+          ]),
+          ts('Unsupported Angular Setting'),
+          \Psr\Log\LogLevel::WARNING,
+          'fa-code'
+        );
+      }
+    }
+    return $messages;
+  }
+
 }
diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php
index 1061837a5032761808defe2e44eb9181c863ab2a..1a3333f03bb86ae1ad8e491abd7b78bd1c4882ce 100644
--- a/civicrm/civicrm-version.php
+++ b/civicrm/civicrm-version.php
@@ -1,7 +1,7 @@
 <?php
 /** @deprecated */
 function civicrmVersion( ) {
-  return array( 'version'  => '5.66.0',
+  return array( 'version'  => '5.66.1',
                 'cms'      => 'Wordpress',
                 'revision' => '' );
 }
diff --git a/civicrm/ext/afform/admin/info.xml b/civicrm/ext/afform/admin/info.xml
index 6f162974e3bd3156d4fb2689cf0538329237dac4..f9b40e90d49183b2b616a0ed03f85290428490cd 100644
--- a/civicrm/ext/afform/admin/info.xml
+++ b/civicrm/ext/afform/admin/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>beta</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/afform/core/info.xml b/civicrm/ext/afform/core/info.xml
index ac7f14d9e07ad56a4732edcdd0eef2beb9b6919f..acc750a5ab79440391207dc910e0984eb5dab7a8 100644
--- a/civicrm/ext/afform/core/info.xml
+++ b/civicrm/ext/afform/core/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>beta</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/afform/html/info.xml b/civicrm/ext/afform/html/info.xml
index ac068d7dae188f2f9d724077ab137025d336aae3..50979fcff2c4080c9c4c183838f5b0944f9e4e6f 100644
--- a/civicrm/ext/afform/html/info.xml
+++ b/civicrm/ext/afform/html/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/afform/mock/info.xml b/civicrm/ext/afform/mock/info.xml
index cf63a6fe963d0537287938932b37e3c4428ec3b5..38d69a11785cbcfec7b5baa060f3d1a93e061fc4 100644
--- a/civicrm/ext/afform/mock/info.xml
+++ b/civicrm/ext/afform/mock/info.xml
@@ -12,7 +12,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-09</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/authx/info.xml b/civicrm/ext/authx/info.xml
index 165c0c6d42c5d255b4b927bd0341431de0e6a06a..d3bf7288cdca1e104c9a0e69247cc1c21e40c521 100644
--- a/civicrm/ext/authx/info.xml
+++ b/civicrm/ext/authx/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-02-11</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/civi_campaign/info.xml b/civicrm/ext/civi_campaign/info.xml
index b74ddd14cbe64d995fde69885839355258512caf..0a86a04066ace1a09d4af8a302e67f63689bb9e5 100644
--- a/civicrm/ext/civi_campaign/info.xml
+++ b/civicrm/ext/civi_campaign/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_case/info.xml b/civicrm/ext/civi_case/info.xml
index 8f9e6ffb85a6121b5db79961e81ee5c87afec0c5..bbc88fb659ceb435c575cf593eedbdd1b8a495d8 100644
--- a/civicrm/ext/civi_case/info.xml
+++ b/civicrm/ext/civi_case/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_contribute/info.xml b/civicrm/ext/civi_contribute/info.xml
index f131a68c9b2dced54384b108525fa669338ea9a5..5b6ab728e86c5318100b49e653a2e070a97823eb 100644
--- a/civicrm/ext/civi_contribute/info.xml
+++ b/civicrm/ext/civi_contribute/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_event/info.xml b/civicrm/ext/civi_event/info.xml
index 564772fd0b245dea8cac29c993148b858483b10b..984878d3b5ffa61bf70f5b873b75be34fefb4bcf 100644
--- a/civicrm/ext/civi_event/info.xml
+++ b/civicrm/ext/civi_event/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_mail/info.xml b/civicrm/ext/civi_mail/info.xml
index 4e2a06f0c1acd6becbee19c2deb14c5fe06f3428..dc6316020b4644bf0400373017b7cc53d91b2345 100644
--- a/civicrm/ext/civi_mail/info.xml
+++ b/civicrm/ext/civi_mail/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_member/info.xml b/civicrm/ext/civi_member/info.xml
index 67fe69e55102281eb7141fcb4118251fe717a6a6..25eadccc8013ed2e07e8e56de1e70a8b46f7c1b4 100644
--- a/civicrm/ext/civi_member/info.xml
+++ b/civicrm/ext/civi_member/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_pledge/info.xml b/civicrm/ext/civi_pledge/info.xml
index 0a75749d04e52371cf3bcb59a6eb4adfaacd06d9..ed6c5f765f59ddd00b18a65a58a89da626803b01 100644
--- a/civicrm/ext/civi_pledge/info.xml
+++ b/civicrm/ext/civi_pledge/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civi_report/info.xml b/civicrm/ext/civi_report/info.xml
index c633d0bbbcb71401345651c1da3c6dd653088f54..06951c26c340bb031496c667ea0b35458054cc2a 100644
--- a/civicrm/ext/civi_report/info.xml
+++ b/civicrm/ext/civi_report/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-04-08</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>component</tag>
diff --git a/civicrm/ext/civicrm_admin_ui/info.xml b/civicrm/ext/civicrm_admin_ui/info.xml
index 9a5a0f17c032e2dd59e55c844d13f3feab4d9c75..7b05026e9723ee39f7b5da75d05c80d2a9f7c46e 100644
--- a/civicrm/ext/civicrm_admin_ui/info.xml
+++ b/civicrm/ext/civicrm_admin_ui/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2022-01-02</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>beta</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/civicrm_search_ui/info.xml b/civicrm/ext/civicrm_search_ui/info.xml
index b2de1e81632f158e15fb535d76f42f8502577afc..edf4ca236dc0d998a73858ecfd119724e8e72d0c 100644
--- a/civicrm/ext/civicrm_search_ui/info.xml
+++ b/civicrm/ext/civicrm_search_ui/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-07-17</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>alpha</develStage>
   <requires>
     <ext>org.civicrm.search_kit</ext>
diff --git a/civicrm/ext/civigrant/info.xml b/civicrm/ext/civigrant/info.xml
index acd004a2103f2f9065fa9a106310dd1d7546c185..d1eabd63a437a4850f122fb815ea5343d39498f4 100644
--- a/civicrm/ext/civigrant/info.xml
+++ b/civicrm/ext/civigrant/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-11-11</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/civiimport/info.xml b/civicrm/ext/civiimport/info.xml
index 3c03e8532ffb3415217e6f1e442b59027a830cb3..df1e58e2f4cb2468c536d160b2577b40be372e29 100644
--- a/civicrm/ext/civiimport/info.xml
+++ b/civicrm/ext/civiimport/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2022-08-11</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/ckeditor4/info.xml b/civicrm/ext/ckeditor4/info.xml
index 3dbe6e83b674ad6abf0cfd4b5b8a95aef1c5820d..8a3b581f6f62ece431ba5a5033d9234ac62ea6a8 100644
--- a/civicrm/ext/ckeditor4/info.xml
+++ b/civicrm/ext/ckeditor4/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">https://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-05-23</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/contributioncancelactions/info.xml b/civicrm/ext/contributioncancelactions/info.xml
index 2bf04dbb951d12ccb4020a815c480f470a8974fe..f145dc7b32c8c10607febad68522c70f6e6bb822 100644
--- a/civicrm/ext/contributioncancelactions/info.xml
+++ b/civicrm/ext/contributioncancelactions/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-10-12</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/elavon/info.xml b/civicrm/ext/elavon/info.xml
index 64fd0cfdb4bc0b14aafad77edc61562f41764f47..03d168d21971bfd052b80e8f6001ff43045546bf 100644
--- a/civicrm/ext/elavon/info.xml
+++ b/civicrm/ext/elavon/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2022-08-05</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/eventcart/info.xml b/civicrm/ext/eventcart/info.xml
index df2f2c851c6c20da88ced9b4b8fa2d2e70bb54d8..6c961ee51ca8921c3ea9fc6e4e1bec443a7e4615 100644
--- a/civicrm/ext/eventcart/info.xml
+++ b/civicrm/ext/eventcart/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-08-03</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/ewaysingle/info.xml b/civicrm/ext/ewaysingle/info.xml
index 0cdc9dc8351fc38c21fa1f3fdbe2c684398fe230..9ea3a4993d03472d78dd13f492042040e3e2db33 100644
--- a/civicrm/ext/ewaysingle/info.xml
+++ b/civicrm/ext/ewaysingle/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-10-07</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/financialacls/financialacls.php b/civicrm/ext/financialacls/financialacls.php
index 0e079fe4010b8fa259ba8ce2d279f73c7b01841f..1e01fade9485876a0359cafd2e58ada13dfbbfce 100644
--- a/civicrm/ext/financialacls/financialacls.php
+++ b/civicrm/ext/financialacls/financialacls.php
@@ -391,6 +391,9 @@ function financialacls_civicrm_alterMenu(array &$menu): void {
  * Implements hook_civicrm_links()
  */
 function financialacls_civicrm_links(string $op, ?string $objectName, $objectID, array &$links, ?int &$mask, array &$values) {
+  if (!financialacls_is_acl_limiting_enabled()) {
+    return;
+  }
   if ($objectName === 'MembershipType') {
     $financialType = CRM_Core_PseudoConstant::getName('CRM_Member_BAO_MembershipType', 'financial_type_id', CRM_Member_BAO_MembershipType::getMembershipType($objectID)['financial_type_id']);
     $hasEditPermission = CRM_Core_Permission::check('edit contributions of type ' . $financialType);
diff --git a/civicrm/ext/financialacls/info.xml b/civicrm/ext/financialacls/info.xml
index acb01d084718428d15a385b5b4367cc8089b5141..57e58fa7fb2e76a0354910d651beb28ecb7c6066 100644
--- a/civicrm/ext/financialacls/info.xml
+++ b/civicrm/ext/financialacls/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-08-27</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/flexmailer/info.xml b/civicrm/ext/flexmailer/info.xml
index 04de8f7c41af6f79be2aff68c8817d333ede46ef..178eb9a67baaf9b4cd192a28c5fd433e4783789e 100644
--- a/civicrm/ext/flexmailer/info.xml
+++ b/civicrm/ext/flexmailer/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-08-05</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <comments>
     FlexMailer is an email delivery engine which replaces the internal guts
diff --git a/civicrm/ext/greenwich/info.xml b/civicrm/ext/greenwich/info.xml
index 47d165987d8095c7b06e9fb434befeb1e16d734f..319d7627bc29436fe5b9f179e454809516163f4f 100644
--- a/civicrm/ext/greenwich/info.xml
+++ b/civicrm/ext/greenwich/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-07-21</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/iatspayments/CRM/Core/Payment/iATSServiceACHEFT.php b/civicrm/ext/iatspayments/CRM/Core/Payment/iATSServiceACHEFT.php
index 4c1765deab63695ef5542ca70dd72cf278268567..b4962ae38bdc0408957a3ccec56dd8da7770af9c 100644
--- a/civicrm/ext/iatspayments/CRM/Core/Payment/iATSServiceACHEFT.php
+++ b/civicrm/ext/iatspayments/CRM/Core/Payment/iATSServiceACHEFT.php
@@ -73,6 +73,10 @@ class CRM_Core_Payment_iATSServiceACHEFT extends CRM_Core_Payment_iATSService {
 
   protected function getDirectDebitFormFields() {
     $fields = parent::getDirectDebitFormFields();
+    if ($fields[0] == 'account_holder') {
+      array_shift($fields);
+      $fields[] = 'account_holder';
+    }
     $fields[] = 'bank_account_type';
     // print_r($fields); die();
     return $fields;
@@ -95,6 +99,8 @@ class CRM_Core_Payment_iATSServiceACHEFT extends CRM_Core_Payment_iATSService {
       'is_required' => TRUE,
       'attributes' => ['CHECKING' => 'Chequing', 'SAVING' => 'Savings'],
     ];
+    // Modify the label of Account Number to match our CAD Cheque
+    $metadata['bank_account_number']['title'] = ts('Account No.');
     return $metadata;
   }
 
@@ -173,14 +179,14 @@ class CRM_Core_Payment_iATSServiceACHEFT extends CRM_Core_Payment_iATSService {
    * North American interbank system is consistent across US and Canada.
    */
   protected function buildForm_CAD(&$form) {
-    $form->addElement('text', 'cad_bank_number', ts('Bank Number (3 digits)'));
-    $form->addRule('cad_bank_number', ts('%1 is a required field.', array(1 => ts('Bank Number'))), 'required');
-    $form->addRule('cad_bank_number', ts('%1 must contain only digits.', array(1 => ts('Bank Number'))), 'numeric');
-    $form->addRule('cad_bank_number', ts('%1 must be of length 3.', array(1 => ts('Bank Number'))), 'rangelength', array(3, 3));
+    $form->addElement('text', 'cad_bank_number', ts('Bank No. (3 digits)'));
+    $form->addRule('cad_bank_number', ts('%1 is a required field.', array(1 => ts('Bank No.'))), 'required');
+    $form->addRule('cad_bank_number', ts('%1 must contain only digits.', array(1 => ts('Bank No.'))), 'numeric');
+    $form->addRule('cad_bank_number', ts('%1 must be of length 3.', array(1 => ts('Bank No.'))), 'rangelength', array(3, 3));
     $form->addElement('text', 'cad_transit_number', ts('Transit Number (5 digits)'));
-    $form->addRule('cad_transit_number', ts('%1 is a required field.', array(1 => ts('Transit Number'))), 'required');
-    $form->addRule('cad_transit_number', ts('%1 must contain only digits.', array(1 => ts('Transit Number'))), 'numeric');
-    $form->addRule('cad_transit_number', ts('%1 must be of length 5.', array(1 => ts('Transit Number'))), 'rangelength', array(5, 5));
+    $form->addRule('cad_transit_number', ts('%1 is a required field.', array(1 => ts('Transit No.'))), 'required');
+    $form->addRule('cad_transit_number', ts('%1 must contain only digits.', array(1 => ts('Transit No.'))), 'numeric');
+    $form->addRule('cad_transit_number', ts('%1 must be of length 5.', array(1 => ts('Transit No.'))), 'rangelength', array(5, 5));
     /* minor customization of labels + make them required  */
     /* $element = $form->getElement('account_holder');
     $element->setLabel(ts('Name of Account Holder'));
diff --git a/civicrm/ext/iatspayments/CRM/Iats/Form/Report/Recur.php b/civicrm/ext/iatspayments/CRM/Iats/Form/Report/Recur.php
index bb98151201387304fff7d7f261dc6114674c3a65..9da4e294f22cc79b2eb6414bc9f83523f659aa9b 100644
--- a/civicrm/ext/iatspayments/CRM/Iats/Form/Report/Recur.php
+++ b/civicrm/ext/iatspayments/CRM/Iats/Form/Report/Recur.php
@@ -285,6 +285,7 @@ class CRM_Iats_Form_Report_Recur extends CRM_Report_Form {
             'title' => ts('Frequency Unit'),
             'operatorType' => CRM_Report_Form::OP_MULTISELECT,
             'options' => CRM_Core_OptionGroup::values('recur_frequency_units'),
+	    'type' => CRM_Utils_Type::T_STRING,	  
           ),
           'next_sched_contribution_date' => array(
             'title' => ts('Next Scheduled Contribution Date'),
diff --git a/civicrm/ext/iatspayments/CRM/Iats/Transaction.php b/civicrm/ext/iatspayments/CRM/Iats/Transaction.php
index f0a84aebc3f55d377b2aa158a6dc6faea5e7303e..54f2e7ca56a66833c991e8e4f744f285454fe65b 100644
--- a/civicrm/ext/iatspayments/CRM/Iats/Transaction.php
+++ b/civicrm/ext/iatspayments/CRM/Iats/Transaction.php
@@ -362,7 +362,7 @@ class CRM_Iats_Transaction {
           $result['message'] = $result['auth_response'] = empty($data['authResponse']) ? '' : trim($data['authResponse']);
         }
         else {
-          $result['message'] = $result['result']['errorMessages'];
+          $result['message'] = implode(',', $result['result']['errorMessages']);
         }
         /* in case of critical failure set the series to pending */
         switch ($result['auth_code']) {
@@ -448,7 +448,8 @@ class CRM_Iats_Transaction {
         $key = ''; // date('YmdHis');
       }
       else {
-        $display = strftime('%B %e, %Y', $start_date);
+        // display of the future date option to the user
+        $display = CRM_Utils_Date::customFormatTs($start_date,Civi::settings()->get('dateformatFull'));
       }
       $start_dates[$key] = $display;
       $start_date += (24 * 60 * 60);
diff --git a/civicrm/ext/iatspayments/CRM/Iats/Upgrader.php b/civicrm/ext/iatspayments/CRM/Iats/Upgrader.php
index fd9e8417a0a2d3300da7b28acb473ac8f2365193..a23d9ea874136b789b4c16de98d52dd18d882a9d 100644
--- a/civicrm/ext/iatspayments/CRM/Iats/Upgrader.php
+++ b/civicrm/ext/iatspayments/CRM/Iats/Upgrader.php
@@ -3,7 +3,7 @@
 /**
  * Collection of upgrade steps
  */
-class CRM_Iats_Upgrader extends CRM_Iats_Upgrader_Base {
+class CRM_Iats_Upgrader extends CRM_Extension_Upgrader_Base {
 
   // By convention, functions that look like "function upgrade_NNNN()" are
   // upgrade tasks. They are executed in order (like Drupal's hook_update_N).
diff --git a/civicrm/ext/iatspayments/CRM/Iats/Upgrader/Base.php b/civicrm/ext/iatspayments/CRM/Iats/Upgrader/Base.php
deleted file mode 100644
index 289598c08e5eb7bc2eb411b8debc2db315ac37e5..0000000000000000000000000000000000000000
--- a/civicrm/ext/iatspayments/CRM/Iats/Upgrader/Base.php
+++ /dev/null
@@ -1,396 +0,0 @@
-<?php
-
-// AUTO-GENERATED FILE -- Civix may overwrite any changes made to this file
-use CRM_Iats_ExtensionUtil as E;
-
-/**
- * Base class which provides helpers to execute upgrade logic
- */
-class CRM_Iats_Upgrader_Base {
-
-  /**
-   * @var CRM_Iats_Upgrader_Base
-   */
-  public static $instance;
-
-  /**
-   * @var CRM_Queue_TaskContext
-   */
-  protected $ctx;
-
-  /**
-   * @var string
-   *   eg 'com.example.myextension'
-   */
-  protected $extensionName;
-
-  /**
-   * @var string
-   *   full path to the extension's source tree
-   */
-  protected $extensionDir;
-
-  /**
-   * @var array
-   *   sorted numerically
-   */
-  private $revisions;
-
-  /**
-   * @var bool
-   *   Flag to clean up extension revision data in civicrm_setting
-   */
-  private $revisionStorageIsDeprecated = FALSE;
-
-  /**
-   * Obtain a reference to the active upgrade handler.
-   */
-  public static function instance() {
-    if (!self::$instance) {
-      self::$instance = new CRM_Iats_Upgrader(
-        'com.iatspayments.civicrm',
-        E::path()
-      );
-    }
-    return self::$instance;
-  }
-
-  /**
-   * Adapter that lets you add normal (non-static) member functions to the queue.
-   *
-   * Note: Each upgrader instance should only be associated with one
-   * task-context; otherwise, this will be non-reentrant.
-   *
-   * ```
-   * CRM_Iats_Upgrader_Base::_queueAdapter($ctx, 'methodName', 'arg1', 'arg2');
-   * ```
-   */
-  public static function _queueAdapter() {
-    $instance = self::instance();
-    $args = func_get_args();
-    $instance->ctx = array_shift($args);
-    $instance->queue = $instance->ctx->queue;
-    $method = array_shift($args);
-    return call_user_func_array([$instance, $method], $args);
-  }
-
-  /**
-   * CRM_Iats_Upgrader_Base constructor.
-   *
-   * @param $extensionName
-   * @param $extensionDir
-   */
-  public function __construct($extensionName, $extensionDir) {
-    $this->extensionName = $extensionName;
-    $this->extensionDir = $extensionDir;
-  }
-
-  // ******** Task helpers ********
-
-  /**
-   * Run a CustomData file.
-   *
-   * @param string $relativePath
-   *   the CustomData XML file path (relative to this extension's dir)
-   * @return bool
-   */
-  public function executeCustomDataFile($relativePath) {
-    $xml_file = $this->extensionDir . '/' . $relativePath;
-    return $this->executeCustomDataFileByAbsPath($xml_file);
-  }
-
-  /**
-   * Run a CustomData file
-   *
-   * @param string $xml_file
-   *   the CustomData XML file path (absolute path)
-   *
-   * @return bool
-   */
-  protected function executeCustomDataFileByAbsPath($xml_file) {
-    $import = new CRM_Utils_Migrate_Import();
-    $import->run($xml_file);
-    return TRUE;
-  }
-
-  /**
-   * Run a SQL file.
-   *
-   * @param string $relativePath
-   *   the SQL file path (relative to this extension's dir)
-   *
-   * @return bool
-   */
-  public function executeSqlFile($relativePath) {
-    CRM_Utils_File::sourceSQLFile(
-      CIVICRM_DSN,
-      $this->extensionDir . DIRECTORY_SEPARATOR . $relativePath
-    );
-    return TRUE;
-  }
-
-  /**
-   * Run the sql commands in the specified file.
-   *
-   * @param string $tplFile
-   *   The SQL file path (relative to this extension's dir).
-   *   Ex: "sql/mydata.mysql.tpl".
-   *
-   * @return bool
-   * @throws \CRM_Core_Exception
-   */
-  public function executeSqlTemplate($tplFile) {
-    // Assign multilingual variable to Smarty.
-    $upgrade = new CRM_Upgrade_Form();
-
-    $tplFile = CRM_Utils_File::isAbsolute($tplFile) ? $tplFile : $this->extensionDir . DIRECTORY_SEPARATOR . $tplFile;
-    $smarty = CRM_Core_Smarty::singleton();
-    $smarty->assign('domainID', CRM_Core_Config::domainID());
-    CRM_Utils_File::sourceSQLFile(
-      CIVICRM_DSN, $smarty->fetch($tplFile), NULL, TRUE
-    );
-    return TRUE;
-  }
-
-  /**
-   * Run one SQL query.
-   *
-   * This is just a wrapper for CRM_Core_DAO::executeSql, but it
-   * provides syntactic sugar for queueing several tasks that
-   * run different queries
-   *
-   * @return bool
-   */
-  public function executeSql($query, $params = []) {
-    // FIXME verify that we raise an exception on error
-    CRM_Core_DAO::executeQuery($query, $params);
-    return TRUE;
-  }
-
-  /**
-   * Syntactic sugar for enqueuing a task which calls a function in this class.
-   *
-   * The task is weighted so that it is processed
-   * as part of the currently-pending revision.
-   *
-   * After passing the $funcName, you can also pass parameters that will go to
-   * the function. Note that all params must be serializable.
-   */
-  public function addTask($title) {
-    $args = func_get_args();
-    $title = array_shift($args);
-    $task = new CRM_Queue_Task(
-      [get_class($this), '_queueAdapter'],
-      $args,
-      $title
-    );
-    return $this->queue->createItem($task, ['weight' => -1]);
-  }
-
-  // ******** Revision-tracking helpers ********
-
-  /**
-   * Determine if there are any pending revisions.
-   *
-   * @return bool
-   */
-  public function hasPendingRevisions() {
-    $revisions = $this->getRevisions();
-    $currentRevision = $this->getCurrentRevision();
-
-    if (empty($revisions)) {
-      return FALSE;
-    }
-    if (empty($currentRevision)) {
-      return TRUE;
-    }
-
-    return ($currentRevision < max($revisions));
-  }
-
-  /**
-   * Add any pending revisions to the queue.
-   *
-   * @param CRM_Queue_Queue $queue
-   */
-  public function enqueuePendingRevisions(CRM_Queue_Queue $queue) {
-    $this->queue = $queue;
-
-    $currentRevision = $this->getCurrentRevision();
-    foreach ($this->getRevisions() as $revision) {
-      if ($revision > $currentRevision) {
-        $title = E::ts('Upgrade %1 to revision %2', [
-          1 => $this->extensionName,
-          2 => $revision,
-        ]);
-
-        // note: don't use addTask() because it sets weight=-1
-
-        $task = new CRM_Queue_Task(
-          [get_class($this), '_queueAdapter'],
-          ['upgrade_' . $revision],
-          $title
-        );
-        $this->queue->createItem($task);
-
-        $task = new CRM_Queue_Task(
-          [get_class($this), '_queueAdapter'],
-          ['setCurrentRevision', $revision],
-          $title
-        );
-        $this->queue->createItem($task);
-      }
-    }
-  }
-
-  /**
-   * Get a list of revisions.
-   *
-   * @return array
-   *   revisionNumbers sorted numerically
-   */
-  public function getRevisions() {
-    if (!is_array($this->revisions)) {
-      $this->revisions = [];
-
-      $clazz = new ReflectionClass(get_class($this));
-      $methods = $clazz->getMethods();
-      foreach ($methods as $method) {
-        if (preg_match('/^upgrade_(.*)/', $method->name, $matches)) {
-          $this->revisions[] = $matches[1];
-        }
-      }
-      sort($this->revisions, SORT_NUMERIC);
-    }
-
-    return $this->revisions;
-  }
-
-  public function getCurrentRevision() {
-    $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName);
-    if (!$revision) {
-      $revision = $this->getCurrentRevisionDeprecated();
-    }
-    return $revision;
-  }
-
-  private function getCurrentRevisionDeprecated() {
-    $key = $this->extensionName . ':version';
-    if ($revision = \Civi::settings()->get($key)) {
-      $this->revisionStorageIsDeprecated = TRUE;
-    }
-    return $revision;
-  }
-
-  public function setCurrentRevision($revision) {
-    CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision);
-    // clean up legacy schema version store (CRM-19252)
-    $this->deleteDeprecatedRevision();
-    return TRUE;
-  }
-
-  private function deleteDeprecatedRevision() {
-    if ($this->revisionStorageIsDeprecated) {
-      $setting = new CRM_Core_BAO_Setting();
-      $setting->name = $this->extensionName . ':version';
-      $setting->delete();
-      CRM_Core_Error::debug_log_message("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n");
-    }
-  }
-
-  // ******** Hook delegates ********
-
-  /**
-   * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install
-   */
-  public function onInstall() {
-    $files = glob($this->extensionDir . '/sql/*_install.sql');
-    if (is_array($files)) {
-      foreach ($files as $file) {
-        CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file);
-      }
-    }
-    $files = glob($this->extensionDir . '/sql/*_install.mysql.tpl');
-    if (is_array($files)) {
-      foreach ($files as $file) {
-        $this->executeSqlTemplate($file);
-      }
-    }
-    $files = glob($this->extensionDir . '/xml/*_install.xml');
-    if (is_array($files)) {
-      foreach ($files as $file) {
-        $this->executeCustomDataFileByAbsPath($file);
-      }
-    }
-    if (is_callable([$this, 'install'])) {
-      $this->install();
-    }
-  }
-
-  /**
-   * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall
-   */
-  public function onPostInstall() {
-    $revisions = $this->getRevisions();
-    if (!empty($revisions)) {
-      $this->setCurrentRevision(max($revisions));
-    }
-    if (is_callable([$this, 'postInstall'])) {
-      $this->postInstall();
-    }
-  }
-
-  /**
-   * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall
-   */
-  public function onUninstall() {
-    $files = glob($this->extensionDir . '/sql/*_uninstall.mysql.tpl');
-    if (is_array($files)) {
-      foreach ($files as $file) {
-        $this->executeSqlTemplate($file);
-      }
-    }
-    if (is_callable([$this, 'uninstall'])) {
-      $this->uninstall();
-    }
-    $files = glob($this->extensionDir . '/sql/*_uninstall.sql');
-    if (is_array($files)) {
-      foreach ($files as $file) {
-        CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file);
-      }
-    }
-  }
-
-  /**
-   * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable
-   */
-  public function onEnable() {
-    // stub for possible future use
-    if (is_callable([$this, 'enable'])) {
-      $this->enable();
-    }
-  }
-
-  /**
-   * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable
-   */
-  public function onDisable() {
-    // stub for possible future use
-    if (is_callable([$this, 'disable'])) {
-      $this->disable();
-    }
-  }
-
-  public function onUpgrade($op, CRM_Queue_Queue $queue = NULL) {
-    switch ($op) {
-      case 'check':
-        return [$this->hasPendingRevisions()];
-
-      case 'enqueue':
-        return $this->enqueuePendingRevisions($queue);
-
-      default:
-    }
-  }
-
-}
diff --git a/civicrm/ext/iatspayments/api/v3/Job/Iatsrecurringcontributions.php b/civicrm/ext/iatspayments/api/v3/Job/Iatsrecurringcontributions.php
index aeb3a49ec6874fd29bf38cca99ac009c14839f6c..5fb7c271dd5b71e5769b4548078c9b68b7dab681 100644
--- a/civicrm/ext/iatspayments/api/v3/Job/Iatsrecurringcontributions.php
+++ b/civicrm/ext/iatspayments/api/v3/Job/Iatsrecurringcontributions.php
@@ -36,6 +36,14 @@ function _civicrm_api3_job_Iatsrecurringcontributions_spec(&$spec) {
     'title' => 'Ignore memberships',
     'api.required' => 0,
   );
+  $spec['stale_limit'] = array(
+    'title' => 'Limit stale schedules, in days',
+    'api.required' => 0,
+  );
+  $spec['failsafe_limit'] = array(
+    'title' => 'Number of stale schedules to halt at',
+    'api.required' => 0,
+  );
 }
 
 /**
@@ -62,6 +70,12 @@ function civicrm_api3_job_Iatsrecurringcontributions($params) {
   if (empty($paymentProcessors)) {
     return;
   }
+  // stale_limit restricts processing of schedules by next_sched_contribution_date no further in the past than this number of days, defaulting to 7.
+  $stale_limit = empty($params['stale_limit']) ? 7 : (integer) $params['stale_limit'];
+  unset($params['stale_limit']);
+  // failsafe_limit restricts all processing of schedules if the number of stale schedules exceeds this number. Defaults to 0 = ignore.
+  $failsafe_limit = empty($params['failsafe_limit']) ? 0 : (integer) $params['failsafe_limit'];
+  unset($params['failsafe_limit']);
   // use catchup mode to calculate next scheduled contribution based on current value rather than current date
   $catchup = !empty($params['catchup']);
   unset($params['catchup']);
@@ -73,8 +87,8 @@ function civicrm_api3_job_Iatsrecurringcontributions($params) {
   // do my calculations based on yyyymmddhhmmss representation of the time
   // not sure about time-zone issues.
   $dtCurrentDay    = date("Ymd", mktime(0, 0, 0, date("m"), date("d"), date("Y")));
-  $dtCurrentDayStart = $dtCurrentDay . "000000";
   $dtCurrentDayEnd   = $dtCurrentDay . "235959";
+  $stale_date = date('Y-m-d', strtotime('-'.$stale_limit.' days')). ' 00:00:00';
   $expiry_limit = date('ym');
   // TODO: before triggering payments, do some housekeeping of the civicrm_contribution_recur records?
   // Now we're ready to trigger payments
@@ -102,178 +116,230 @@ function civicrm_api3_job_Iatsrecurringcontributions($params) {
   $recurringContributions = civicrm_api3('ContributionRecur', 'get',  $get);
   //CRM_Core_Error::debug_var('Recurring contributions get params', $get);
   //CRM_Core_Error::debug_var('Recurring contributions to be generated for', $recurringContributions['values']);
+  // Do some initialization before we start processing the schedules, including getting some error handling settings
+  $failsafeFlag = FALSE;
   $counter = 0;
   $error_count  = 0;
   $output  = [];
+  // flag failsafe behaviour if failsafe_limit is set and we have more than that many stale schedules
+  if ($failsafe_limit) {
+    $get['next_sched_contribution_date'] = ['<' => $stale_date];
+    $staleRecurringContributions = civicrm_api3('ContributionRecur', 'get',  $get);
+    $failsafeFlag = ($failsafe_limit < $staleRecurringContributions['count']);
+    $output[] = "Failsafe Analysis: stale date $stale_date, limit $failsafe_limit, count ".$staleRecurringContributions['count'];
+    $output[] = "Failsafe Decision: ". ($failsafeFlag ? 'Flagged': 'Clear');
+  }
   $settings = Civi::settings()->get('iats_settings');
   $receipt_recurring = $settings['receipt_recurring'] ?? null;
   $email_failure_report = empty($settings['email_recurring_failure_report']) ? '' : $settings['email_recurring_failure_report'];
+  $email_failure_contribution_receipt = empty($settings['email_failure_contribution_receipt']) ? FALSE : TRUE;
+  list($emailFromName, $emailFromEmail) = CRM_Core_BAO_Domain::getNameAndEmail();
   // By default, after 3 failures move the next scheduled contribution date forward.
   $failure_threshhold = empty($settings['recurring_failure_threshhold']) ? 3 : (int) $settings['recurring_failure_threshhold'];
   $failure_report_text = '';
-  foreach($recurringContributions['values'] as $recurringContribution) {
-    // Strategy: create the contribution record with status = 2 (= pending), try the payment, and update the status to 1 if successful
-    //           also, advance the next scheduled payment before the payment attempt and pull it back if we know it fails.
-    $contribution_recur_id    = $recurringContribution['id'];
-    $contact_id = $recurringContribution['contact_id'];
-    $total_amount = $recurringContribution['amount'];
-    $is_test = $recurringContribution['is_test'];
-    $payment_processor_id = $recurringContribution['payment_processor_id'];
-    // Try to get a contribution template for this contribution series - if none matches (e.g. if a donation amount has been changed), we'll just be naive about it.
-    $contribution_template = CRM_Iats_Transaction::getContributionTemplate(['contribution_recur_id' => $contribution_recur_id, 'total_amount' => $total_amount, 'is_test' => $is_test]);
-    // CRM_Core_Error::debug_var('Contribution Template', $contribution_template);
-    // generate my invoice id like CiviCRM does
-    $hash = md5(uniqid(rand(), TRUE));
-    $paymentProcessor = $paymentProcessors[$payment_processor_id];
-    $paymentClass = substr($paymentProcessor['class_name'],8);
-    $source = E::ts('iATS Payments (%1) Recurring Contribution ( id = %2 )', [
-      1 => $paymentClass,
-      2 => $contribution_recur_id,
-    ]);
-    $receive_ts = $catchup ? strtotime($recurringContribution['next_sched_contribution_date']) : time();
-    // i.e. now or whenever it was supposed to run if in catchup mode.
-    $receive_date = date("YmdHis", $receive_ts);
-    // Check if we already have an error.
-    $errors = array();
-    if (!empty($recurringContribution['payment_token_id'])) {
-      try {
-        $payment_token = civicrm_api3('PaymentToken', 'getsingle', array('id' => $recurringContribution['payment_token_id']));
-        if (empty($payment_token['token'])) {
-          $errors[] = E::ts('Recur id %1 is missing a payment token.', array(1 => $contribution_recur_id));
-        }
-      }
-      catch (Exception $e) {
-        $errors[] = E::ts('Unexpected error getting a payment token for recurring schedule id %1', array(1 => $contribution_recur_id));
-        CRM_Core_Error::debug_var('Unexpected error getting payment token', $e);
-        $payment_token = array();
+  if ($failsafeFlag) {
+    $error_count = $staleRecurringContributions['count'];
+    $failure_report_text = 'Alert: failsafe behaviour triggered due to too many stale schedules';
+    $output[] = $failure_report_text;
+  }
+  else {
+    CRM_Core_Error::debug_var('recurring Contributions', $recurringContributions['values']);
+    foreach($recurringContributions['values'] as $recurringContribution) {
+      // Strategy: create the contribution record with status = 2 (= pending), try the payment, and update the status to 1 if successful
+      //           also, advance the next scheduled payment before the payment attempt and pull it back if we know it fails.
+      $contribution_recur_id    = $recurringContribution['id'];
+      $contact_id = $recurringContribution['contact_id'];
+      // But first, check if the next scheduled contribution date is too far in the past, in which case I'll just notify an administrator and skip it.
+      if ($recurringContribution['next_sched_contribution_date'] < $stale_date) {
+        $failure_text = ts(
+          'Stale recurring contribution schedule for contact id %1, recurring schedule id %2, %3',
+          array(
+            1 => $contact_id,
+            2 => $contribution_recur_id,
+            3 => $recurringContribution['next_sched_contribution_date']
+          )
+        );
+        $output[] = $failure_text;
+        $failure_report_text .= "\n".$failure_text;
+        ++$error_count;
+        continue;
       }
-    }
-    else {
-      $errors[] = E::ts('Unexpected error, no payment token for recurring schedule id %1', array(1 => $contribution_recur_id));
-    }
-    if (count($errors)) {
-      $source .= ' Errors: ' . implode(' ', $errors);
-    }
-    $contribution = array(
-      'version'        => 3,
-      'contact_id'       => $contact_id,
-      'receive_date'       => $receive_date,
-      'total_amount'       => $total_amount,
-      'payment_instrument_id'  => $recurringContribution['payment_instrument_id'],
-      'contribution_recur_id'  => $contribution_recur_id,
-      'invoice_id'       => $hash,
-      'source'         => $source,
-      'contribution_status_id' => 'Pending', /* initialize as pending, so we can run completetransaction after taking the money */
-      'currency'  => $recurringContribution['currency'],
-      'payment_processor'   => $payment_processor_id,
-      'is_test'        => $is_test, /* propagate the is_test value from the recurring record */
-      'financial_type_id' => $recurringContribution['financial_type_id'],
-      'is_email_receipt' => (($receipt_recurring < 2) ? $receipt_recurring : $recurringContribution['is_email_receipt']),
-    );
-    $get_from_template = ['contribution_campaign_id', 'amount_level', 'original_contribution_id'];
-    foreach ($get_from_template as $field) {
-      if (isset($contribution_template[$field])) {
-        $contribution[$field] = is_array($contribution_template[$field]) ? implode(', ', $contribution_template[$field]) : $contribution_template[$field];
+      $total_amount = $recurringContribution['amount'];
+      $is_test = $recurringContribution['is_test'];
+      $payment_processor_id = $recurringContribution['payment_processor_id'];
+      // Try to get a contribution template for this contribution series - if none matches (e.g. if a donation amount has been changed), we'll just be naive about it.
+      $contribution_template = CRM_Iats_Transaction::getContributionTemplate(['contribution_recur_id' => $contribution_recur_id, 'total_amount' => $total_amount, 'is_test' => $is_test]);
+      // CRM_Core_Error::debug_var('Contribution Template', $contribution_template);
+      // generate my invoice id like CiviCRM does
+      $hash = md5(uniqid(rand(), TRUE));
+      $paymentProcessor = $paymentProcessors[$payment_processor_id];
+      $paymentClass = substr($paymentProcessor['class_name'],8);
+      $source = E::ts('iATS Payments (%1) Recurring Contribution ( id = %2 )', [
+        1 => $paymentClass,
+        2 => $contribution_recur_id,
+      ]);
+      $receive_ts = $catchup ? strtotime($recurringContribution['next_sched_contribution_date']) : time();
+      // i.e. now or whenever it was supposed to run if in catchup mode.
+      $receive_date = date("YmdHis", $receive_ts);
+      // Check if we already have an error.
+      $errors = array();
+      if (!empty($recurringContribution['payment_token_id'])) {
+        try {
+          $payment_token = civicrm_api3('PaymentToken', 'getsingle', array('id' => $recurringContribution['payment_token_id']));
+          if (empty($payment_token['token'])) {
+            $errors[] = E::ts('Recur id %1 is missing a payment token.', array(1 => $contribution_recur_id));
+          }
+        }
+        catch (Exception $e) {
+          $errors[] = E::ts('Unexpected error getting a payment token for recurring schedule id %1', array(1 => $contribution_recur_id));
+          CRM_Core_Error::debug_var('Unexpected error getting payment token', $e);
+          $payment_token = array();
+        }
       }
-    }
-    // if we have a created a pending contribution record due to a future start time, then recycle that CiviCRM contribution record now.
-    // Note that the date and amount both could have changed.
-    // The key is to only match if we find a single pending contribution, with a NULL transaction id, for this recurring schedule.
-    // We'll need to pay attention later that we may or may not already have a contribution id.
-    try {
-      $pending_contribution = civicrm_api3('Contribution', 'getsingle', array(
-        'return' => array('id'),
-        'trxn_id' => array('IS NULL' => 1),
-        'contribution_recur_id' => $contribution_recur_id,
-        'contribution_status_id' => "Pending",
-      ));
-      if (!empty($pending_contribution['id'])) {
-        $contribution['id'] = $pending_contribution['id'];
+      else {
+        $errors[] = E::ts('Unexpected error, no payment token for recurring schedule id %1', array(1 => $contribution_recur_id));
       }
-    }
-    catch (Exception $e) {
-      // ignore, we'll proceed normally without a contribution id
-    }
-    // If I'm not recycling a contribution record and my original has line_items, then I'll add them to the contribution creation array.
-    // Note: if the amount of a matched pending contribution has changed, then we need to remove the line items from the contribution.
-    if (empty($contribution['id']) && !empty($contribution_template['line_items'])) {
-      $contribution['skipLineItem'] = 1;
-      $contribution['api.line_item.create'] = $contribution_template['line_items'];
-    }
-    if (count($errors)) {
-      ++$error_count;
-      ++$counter;
-      /* create a failed contribution record, don't bother talking to iats */
-      $contribution['contribution_status_id'] = 4;
-      $contributionResult = civicrm_api('contribution', 'create', $contribution);
-      if ($contributionResult['is_error']) {
-        $errors[] = $contributionResult['error_message'];
+      if (count($errors)) {
+        $source .= ' Errors: ' . implode(' ', $errors);
       }
-      if ($email_failure_report) {
-        $failure_report_text .= "\n Unexpected Errors: " . implode(' ', $errors);
+      $contribution = array(
+        'version'        => 3,
+        'contact_id'       => $contact_id,
+        'receive_date'       => $receive_date,
+        'total_amount'       => $total_amount,
+        'payment_instrument_id'  => $recurringContribution['payment_instrument_id'],
+        'contribution_recur_id'  => $contribution_recur_id,
+        'invoice_id'       => $hash,
+        'source'         => $source,
+        'contribution_status_id' => 'Pending', /* initialize as pending, so we can run completetransaction after taking the money */
+        'currency'  => $recurringContribution['currency'],
+        'payment_processor'   => $payment_processor_id,
+        'is_test'        => $is_test, /* propagate the is_test value from the recurring record */
+        'financial_type_id' => $recurringContribution['financial_type_id'],
+        'is_email_receipt' => (($receipt_recurring < 2) ? $receipt_recurring : $recurringContribution['is_email_receipt']),
+      );
+      $get_from_template = ['contribution_campaign_id', 'amount_level', 'original_contribution_id'];
+      foreach ($get_from_template as $field) {
+        if (isset($contribution_template[$field])) {
+          $contribution[$field] = is_array($contribution_template[$field]) ? implode(', ', $contribution_template[$field]) : $contribution_template[$field];
+        }
       }
-      continue;
-    }
-    // Else: no errors in the setup, continue.
-    // If our template contribution is a membership payment, make this one also.
-    if ($domemberships && !empty($contribution_template['contribution_id'])) {
+      // if we have a created a pending contribution record due to a future start time, then recycle that CiviCRM contribution record now.
+      // Note that the date and amount both could have changed.
+      // The key is to only match if we find a single pending contribution, with a NULL transaction id, for this recurring schedule.
+      // We'll need to pay attention later that we may or may not already have a contribution id.
       try {
-        $membership_payment = civicrm_api('MembershipPayment', 'getsingle', array('version' => 3, 'contribution_id' => $contribution_template['contribution_id']));
-        if (!empty($membership_payment['membership_id'])) {
-          // a slightly hacky was of passing this information in, membership_id
-          // isn't normally a property of a contribution.
-          $contribution['membership_id'] = $membership_payment['membership_id'];
+        $pending_contribution = civicrm_api3('Contribution', 'getsingle', array(
+          'return' => array('id'),
+          'trxn_id' => array('IS NULL' => 1),
+          'contribution_recur_id' => $contribution_recur_id,
+          'contribution_status_id' => "Pending",
+        ));
+        if (!empty($pending_contribution['id'])) {
+          $contribution['id'] = $pending_contribution['id'];
         }
       }
       catch (Exception $e) {
-        // ignore, if will fail correctly if there is no membership payment.
+        // ignore, we'll proceed normally without a contribution id
       }
-    }
-    // So far so, good ... now use my utility function process_contribution_payment to
-    // create the pending contribution and try to get the money, and then do one of:
-    // update the contribution to failed, leave as pending for server failure, complete the transaction,
-    // or update a pending ach/eft with it's transaction id.
-    // Assemble an array of recurring information so that process_contribution_payment can update the recurring record.
-    // But first: calculate next collection date now so that in case of server failure on return from a payment request I don't try to take money again.
-    // The next collection date is based on receive_ts, "recieve timestamp" (note effect of catchup mode, above)
-    $next_collection_date = date('Y-m-d H:i:s', strtotime('+'.$recurringContribution['frequency_interval'].' '.$recurringContribution['frequency_unit'], $receive_ts));
-    // Note: keep track of the currently defined "next_sched_contribution_date" as "current_sched_contribution_date" in case of confirmed transient card failures.
-    $contribution_recur_update = array('id' => $contribution['contribution_recur_id'], 'next_sched_contribution_date' => $next_collection_date, 'failure_count' => $recurringContribution['failure_count'], 'failure_threshold' => $failure_threshhold, 'current_sched_contribution_date' => $recurringContribution['next_sched_contribution_date']);
-    // process the payment and update the contribution and recurring contribution records:
-    $result = CRM_Iats_Transaction::process_contribution_payment($contribution, $paymentProcessor, $payment_token, $contribution_recur_update);
-    // append result message to report if I'm going to mail out a failures
-    // report
-    if ($email_failure_report && !$result['result']['success']) {
-      $failure_report_text .= "\n".$result['message'];
-    }
-    $output[] = $result['message'];
-    $result = civicrm_api('activity', 'create',
-      array(
-        'version'       => 3,
-        'activity_type_id'  => 6,
-        'source_contact_id'   => $contact_id,
-        'source_record_id' => $contribution['id'],
-        'assignee_contact_id' => $contact_id,
-        'subject'       => ts('Attempted iATS Payments (%1) Recurring Contribution for %2', array(1 => $paymentClass, 2 => $total_amount)),
-        'status_id'       => 2,
-        'activity_date_time'  => date("YmdHis"),
-      )
-    );
-    if ($result['is_error']) {
-      $output[] = ts(
-        'An error occurred while creating activity record for contact id %1: %2',
+      // If I'm not recycling a contribution record and my original has line_items, then I'll add them to the contribution creation array.
+      // Note: if the amount of a matched pending contribution has changed, then we need to remove the line items from the contribution.
+      if (empty($contribution['id']) && !empty($contribution_template['line_items'])) {
+        $contribution['skipLineItem'] = 1;
+        $contribution['api.line_item.create'] = $contribution_template['line_items'];
+      }
+      if (count($errors)) {
+        ++$error_count;
+        ++$counter;
+        /* create a failed contribution record, don't bother talking to iats */
+        $contribution['contribution_status_id'] = 4;
+        $contributionResult = civicrm_api('contribution', 'create', $contribution);
+        if ($contributionResult['is_error']) {
+          $errors[] = $contributionResult['error_message'];
+        }
+        if ($email_failure_report) {
+          $failure_report_text .= "\n Unexpected Errors: " . implode(' ', $errors);
+        }
+        continue;
+      }
+      // Else: no errors in the setup, continue.
+      // If the most recent contribution in the sequence is a membership payment, make this one also.
+      // Note that we don't use the template_contribution for this purpose, so that
+      // we can support changing membership amounts.
+      if ($domemberships) {
+        // retrieve the most recent previous contribution to check for a membership payment
+        $latest_contribution = CRM_Iats_Transaction::getContributionTemplate(['contribution_recur_id' => $contribution_recur_id, 'is_test' => $is_test]);
+        try {
+          $membership_payment = civicrm_api('MembershipPayment', 'getsingle', array('version' => 3, 'contribution_id' => $latest_contribution['contribution_id']));
+          if (!empty($membership_payment['membership_id'])) {
+            // a slightly hacky was of passing this information in, membership_id
+            // isn't normally a property of a contribution.
+            $contribution['membership_id'] = $membership_payment['membership_id'];
+          }
+        }
+        catch (Exception $e) {
+          // ignore, if will fail correctly if there is no membership payment.
+        }
+      }
+      // So far so, good ... now use my utility function process_contribution_payment to
+      // create the pending contribution and try to get the money, and then do one of:
+      // update the contribution to failed, leave as pending for server failure, complete the transaction,
+      // or update a pending ach/eft with it's transaction id.
+      // Assemble an array of recurring information so that process_contribution_payment can update the recurring record.
+      // But first: calculate next collection date now so that in case of server failure on return from a payment request I don't try to take money again.
+      // The next collection date is based on receive_ts, "recieve timestamp" (note effect of catchup mode, above)
+      $next_collection_date = date('Y-m-d H:i:s', strtotime('+'.$recurringContribution['frequency_interval'].' '.$recurringContribution['frequency_unit'], $receive_ts));
+      // Note: keep track of the currently defined "next_sched_contribution_date" as "current_sched_contribution_date" in case of confirmed transient card failures.
+      $contribution_recur_update = array('id' => $contribution['contribution_recur_id'], 'next_sched_contribution_date' => $next_collection_date, 'failure_count' => $recurringContribution['failure_count'], 'failure_threshold' => $failure_threshhold, 'current_sched_contribution_date' => $recurringContribution['next_sched_contribution_date']);
+      // process the payment and update the contribution and recurring contribution records:
+      $result = CRM_Iats_Transaction::process_contribution_payment($contribution, $paymentProcessor, $payment_token, $contribution_recur_update);
+      // in case of failure:
+      // 1. append result message to report if I'm going to mail out a failures
+      // 2. send a failure receipt/confirmation if that's configured
+      if (!$result['result']['success']) {
+        if ($email_failure_report) {
+          $failure_report_text .= "\n".$result['message'];
+	}
+        // Send receipt with error message if a contribution fails and is set $email_failure_contribution_receipt
+        if ($email_failure_contribution_receipt) {
+          civicrm_api3('Contribution', 'sendconfirmation', [
+            'id' => $contribution['id'],
+            'receipt_from_name' => empty($emailFromName) ? ts('Admin') : $emailFromName,
+            'receipt_from_email' => $emailFromEmail,
+            'receipt_text' => ts('It seems something is not quite right with your recurring contribution payment. Please see details below.') . '<hr><br>' . $result['message'],
+            'bcc_receipt' => !empty($email_failure_report)? $email_failure_report: $fromEmail,
+          ]);
+        }
+      }
+      $output[] = $result['message'];
+      $result = civicrm_api('activity', 'create',
         array(
-          1 => $contact_id,
-          2 => $result['error_message'],
+          'version'       => 3,
+          'activity_type_id'  => 6,
+          'source_contact_id'   => $contact_id,
+          'source_record_id' => $contribution['id'],
+          'assignee_contact_id' => $contact_id,
+          'subject'       => ts('Attempted iATS Payments (%1) Recurring Contribution for %2', array(1 => $paymentClass, 2 => $total_amount)),
+          'status_id'       => 2,
+          'activity_date_time'  => date("YmdHis"),
         )
       );
-      ++$error_count;
-    }
-    else {
-      $output[] = ts('Created activity record for contact id %1', array(1 => $contact_id));
+      if ($result['is_error']) {
+        $output[] = ts(
+          'An error occurred while creating activity record for contact id %1: %2',
+          array(
+            1 => $contact_id,
+            2 => $result['error_message'],
+          )
+        );
+        ++$error_count;
+      }
+      else {
+        $output[] = ts('Created activity record for contact id %1', array(1 => $contact_id));
+      }
+      ++$counter;
     }
-    ++$counter;
-  }
+  } // end else failsafeFlag is false
 
   // Now update the end_dates and status for non-open-ended contribution series if they are complete (so that the recurring contribution status will show correctly)
   // This is a simplified version of what we did before the processing.
@@ -300,12 +366,11 @@ function civicrm_api3_job_Iatsrecurringcontributions($params) {
   }
   */
   $lock->release();
-  // If errors ..
+  // If errors, mail a report if so configured
   if ((strlen($failure_report_text) > 0) && $email_failure_report) {
-    list($fromName, $fromEmail) = CRM_Core_BAO_Domain::getNameAndEmail();
     $mailparams = array(
-      'from' => $fromName . ' <' . $fromEmail . '> ',
-      'toName' => empty($fromName) ? ts('System Administrator') : $fromName,
+      'from' => $emailFromName . ' <' . $emailFromEmail . '> ',
+      'toName' => empty($emailFromName) ? ts('System Administrator') : $emailFromName,
       'toEmail' => $email_failure_report,
       'bcc' =>  !empty($bcc_email_failure_report) ?  $bcc_email_failure_report : '',
       'subject' => ts('iATS Recurring Payment job failure report: ' . date('c')),
@@ -315,19 +380,7 @@ function civicrm_api3_job_Iatsrecurringcontributions($params) {
     CRM_Utils_Mail::send($mailparams);
   }
 
-  // Send receipt with error message if [recurring only?] contribution fails   $email_failure_contribution_receipt
-  // CRM_Core_Error::debug_var('Contribution', $contribution);
-  // CRM_Core_Error::debug_var('iATS response message', $failure_report_text);
-    if ((strlen($failure_report_text) > 0) && $email_failure_contribution_receipt) {
-        return civicrm_api3('Contribution', 'sendconfirmation', [
-        'id' => $contribution['id'],
-        'receipt_from_name' => empty($fromName) ? ts('Admin') : $fromName,
-        'receipt_from_email' => $fromEmail,
-        'receipt_text' => ts('It seems something is not quite right with your recurring contribution payment. Please see details below.') . '<hr><br>' . $failure_report_text,
-        'bcc_receipt' => !empty($email_failure_report)? $email_failure_report: $fromEmail,
-        ]);
-    }
-  // If errors ..
+  // If errors, return with an error.
   if ($error_count > 0) {
     return civicrm_api3_create_error(
       ts("Completed, but with %1 errors. %2 records processed.",
diff --git a/civicrm/ext/iatspayments/iats.civix.php b/civicrm/ext/iatspayments/iats.civix.php
index 575aa5a5b9fcddc926ae3d2561403d9d4402ba88..d6ef5fc125fd000da166aab37bb7ebed2a2b0634 100644
--- a/civicrm/ext/iatspayments/iats.civix.php
+++ b/civicrm/ext/iatspayments/iats.civix.php
@@ -24,7 +24,7 @@ class CRM_Iats_ExtensionUtil {
    *   Translated text.
    * @see ts
    */
-  public static function ts($text, $params = []) {
+  public static function ts($text, $params = []): string {
     if (!array_key_exists('domain', $params)) {
       $params['domain'] = [self::LONG_NAME, NULL];
     }
@@ -41,7 +41,7 @@ class CRM_Iats_ExtensionUtil {
    *   Ex: 'http://example.org/sites/default/ext/org.example.foo'.
    *   Ex: 'http://example.org/sites/default/ext/org.example.foo/css/foo.css'.
    */
-  public static function url($file = NULL) {
+  public static function url($file = NULL): string {
     if ($file === NULL) {
       return rtrim(CRM_Core_Resources::singleton()->getUrl(self::LONG_NAME), '/');
     }
@@ -84,40 +84,17 @@ use CRM_Iats_ExtensionUtil as E;
  *
  * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config
  */
-function _iats_civix_civicrm_config(&$config = NULL) {
+function _iats_civix_civicrm_config($config = NULL) {
   static $configured = FALSE;
   if ($configured) {
     return;
   }
   $configured = TRUE;
 
-  $template =& CRM_Core_Smarty::singleton();
-
-  $extRoot = dirname(__FILE__) . DIRECTORY_SEPARATOR;
-  $extDir = $extRoot . 'templates';
-
-  if (is_array($template->template_dir)) {
-    array_unshift($template->template_dir, $extDir);
-  }
-  else {
-    $template->template_dir = [$extDir, $template->template_dir];
-  }
-
+  $extRoot = __DIR__ . DIRECTORY_SEPARATOR;
   $include_path = $extRoot . PATH_SEPARATOR . get_include_path();
   set_include_path($include_path);
-}
-
-/**
- * (Delegated) Implements hook_civicrm_xmlMenu().
- *
- * @param $files array(string)
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_xmlMenu
- */
-function _iats_civix_civicrm_xmlMenu(&$files) {
-  foreach (_iats_civix_glob(__DIR__ . '/xml/Menu/*.xml') as $file) {
-    $files[] = $file;
-  }
+  // Based on <compatibility>, this does not currently require mixin/polyfill.php.
 }
 
 /**
@@ -127,35 +104,7 @@ function _iats_civix_civicrm_xmlMenu(&$files) {
  */
 function _iats_civix_civicrm_install() {
   _iats_civix_civicrm_config();
-  if ($upgrader = _iats_civix_upgrader()) {
-    $upgrader->onInstall();
-  }
-}
-
-/**
- * Implements hook_civicrm_postInstall().
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall
- */
-function _iats_civix_civicrm_postInstall() {
-  _iats_civix_civicrm_config();
-  if ($upgrader = _iats_civix_upgrader()) {
-    if (is_callable([$upgrader, 'onPostInstall'])) {
-      $upgrader->onPostInstall();
-    }
-  }
-}
-
-/**
- * Implements hook_civicrm_uninstall().
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall
- */
-function _iats_civix_civicrm_uninstall() {
-  _iats_civix_civicrm_config();
-  if ($upgrader = _iats_civix_upgrader()) {
-    $upgrader->onUninstall();
-  }
+  // Based on <compatibility>, this does not currently require mixin/polyfill.php.
 }
 
 /**
@@ -163,186 +112,9 @@ function _iats_civix_civicrm_uninstall() {
  *
  * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable
  */
-function _iats_civix_civicrm_enable() {
-  _iats_civix_civicrm_config();
-  if ($upgrader = _iats_civix_upgrader()) {
-    if (is_callable([$upgrader, 'onEnable'])) {
-      $upgrader->onEnable();
-    }
-  }
-}
-
-/**
- * (Delegated) Implements hook_civicrm_disable().
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable
- * @return mixed
- */
-function _iats_civix_civicrm_disable() {
+function _iats_civix_civicrm_enable(): void {
   _iats_civix_civicrm_config();
-  if ($upgrader = _iats_civix_upgrader()) {
-    if (is_callable([$upgrader, 'onDisable'])) {
-      $upgrader->onDisable();
-    }
-  }
-}
-
-/**
- * (Delegated) Implements hook_civicrm_upgrade().
- *
- * @param $op string, the type of operation being performed; 'check' or 'enqueue'
- * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks
- *
- * @return mixed
- *   based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending)
- *   for 'enqueue', returns void
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade
- */
-function _iats_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
-  if ($upgrader = _iats_civix_upgrader()) {
-    return $upgrader->onUpgrade($op, $queue);
-  }
-}
-
-/**
- * @return CRM_Iats_Upgrader
- */
-function _iats_civix_upgrader() {
-  if (!file_exists(__DIR__ . '/CRM/Iats/Upgrader.php')) {
-    return NULL;
-  }
-  else {
-    return CRM_Iats_Upgrader_Base::instance();
-  }
-}
-
-/**
- * Search directory tree for files which match a glob pattern.
- *
- * Note: Dot-directories (like "..", ".git", or ".svn") will be ignored.
- *
- * @param string $dir base dir
- * @param string $pattern , glob pattern, eg "*.txt"
- *
- * @return array
- */
-function _iats_civix_find_files($dir, $pattern) {
-  return CRM_Utils_File::findFiles($dir, $pattern);
-}
-
-/**
- * (Delegated) Implements hook_civicrm_managed().
- *
- * Find any *.mgd.php files, merge their content, and return.
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed
- */
-function _iats_civix_civicrm_managed(&$entities) {
-  $mgdFiles = _iats_civix_find_files(__DIR__, '*.mgd.php');
-  sort($mgdFiles);
-  foreach ($mgdFiles as $file) {
-    $es = include $file;
-    foreach ($es as $e) {
-      if (empty($e['module'])) {
-        $e['module'] = E::LONG_NAME;
-      }
-      if (empty($e['params']['version'])) {
-        $e['params']['version'] = '3';
-      }
-      $entities[] = $e;
-    }
-  }
-}
-
-/**
- * (Delegated) Implements hook_civicrm_caseTypes().
- *
- * Find any and return any files matching "xml/case/*.xml"
- *
- * Note: This hook only runs in CiviCRM 4.4+.
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_caseTypes
- */
-function _iats_civix_civicrm_caseTypes(&$caseTypes) {
-  if (!is_dir(__DIR__ . '/xml/case')) {
-    return;
-  }
-
-  foreach (_iats_civix_glob(__DIR__ . '/xml/case/*.xml') as $file) {
-    $name = preg_replace('/\.xml$/', '', basename($file));
-    if ($name != CRM_Case_XMLProcessor::mungeCaseType($name)) {
-      $errorMessage = sprintf("Case-type file name is malformed (%s vs %s)", $name, CRM_Case_XMLProcessor::mungeCaseType($name));
-      throw new CRM_Core_Exception($errorMessage);
-    }
-    $caseTypes[$name] = [
-      'module' => E::LONG_NAME,
-      'name' => $name,
-      'file' => $file,
-    ];
-  }
-}
-
-/**
- * (Delegated) Implements hook_civicrm_angularModules().
- *
- * Find any and return any files matching "ang/*.ang.php"
- *
- * Note: This hook only runs in CiviCRM 4.5+.
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_angularModules
- */
-function _iats_civix_civicrm_angularModules(&$angularModules) {
-  if (!is_dir(__DIR__ . '/ang')) {
-    return;
-  }
-
-  $files = _iats_civix_glob(__DIR__ . '/ang/*.ang.php');
-  foreach ($files as $file) {
-    $name = preg_replace(':\.ang\.php$:', '', basename($file));
-    $module = include $file;
-    if (empty($module['ext'])) {
-      $module['ext'] = E::LONG_NAME;
-    }
-    $angularModules[$name] = $module;
-  }
-}
-
-/**
- * (Delegated) Implements hook_civicrm_themes().
- *
- * Find any and return any files matching "*.theme.php"
- */
-function _iats_civix_civicrm_themes(&$themes) {
-  $files = _iats_civix_glob(__DIR__ . '/*.theme.php');
-  foreach ($files as $file) {
-    $themeMeta = include $file;
-    if (empty($themeMeta['name'])) {
-      $themeMeta['name'] = preg_replace(':\.theme\.php$:', '', basename($file));
-    }
-    if (empty($themeMeta['ext'])) {
-      $themeMeta['ext'] = E::LONG_NAME;
-    }
-    $themes[$themeMeta['name']] = $themeMeta;
-  }
-}
-
-/**
- * Glob wrapper which is guaranteed to return an array.
- *
- * The documentation for glob() says, "On some systems it is impossible to
- * distinguish between empty match and an error." Anecdotally, the return
- * result for an empty match is sometimes array() and sometimes FALSE.
- * This wrapper provides consistency.
- *
- * @link http://php.net/glob
- * @param string $pattern
- *
- * @return array
- */
-function _iats_civix_glob($pattern) {
-  $result = glob($pattern);
-  return is_array($result) ? $result : [];
+  // Based on <compatibility>, this does not currently require mixin/polyfill.php.
 }
 
 /**
@@ -361,8 +133,8 @@ function _iats_civix_insert_navigation_menu(&$menu, $path, $item) {
   if (empty($path)) {
     $menu[] = [
       'attributes' => array_merge([
-        'label'      => CRM_Utils_Array::value('name', $item),
-        'active'     => 1,
+        'label' => $item['name'] ?? NULL,
+        'active' => 1,
       ], $item),
     ];
     return TRUE;
@@ -426,26 +198,3 @@ function _iats_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $parentID) {
     }
   }
 }
-
-/**
- * (Delegated) Implements hook_civicrm_alterSettingsFolders().
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterSettingsFolders
- */
-function _iats_civix_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
-  $settingsDir = __DIR__ . DIRECTORY_SEPARATOR . 'settings';
-  if (!in_array($settingsDir, $metaDataFolders) && is_dir($settingsDir)) {
-    $metaDataFolders[] = $settingsDir;
-  }
-}
-
-/**
- * (Delegated) Implements hook_civicrm_entityTypes().
- *
- * Find any *.entityType.php files, merge their content, and return.
- *
- * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes
- */
-function _iats_civix_civicrm_entityTypes(&$entityTypes) {
-  $entityTypes = array_merge($entityTypes, []);
-}
diff --git a/civicrm/ext/iatspayments/iats.php b/civicrm/ext/iatspayments/iats.php
index 23b32e0d73ac11f5cb0315770b4c12517a472027..0316e6cd1c6c3b51136ffc1eb2e24d7afa2f15de 100644
--- a/civicrm/ext/iatspayments/iats.php
+++ b/civicrm/ext/iatspayments/iats.php
@@ -37,15 +37,6 @@ function iats_civicrm_config(&$config) {
   _iats_civix_civicrm_config($config);
 }
 
-/**
- * Implements hook_civicrm_xmlMenu().
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu
- */
-function iats_civicrm_xmlMenu(&$files) {
-  _iats_civix_civicrm_xmlMenu($files);
-}
-
 /**
  * Implements hook_civicrm_install().
  *
@@ -60,24 +51,6 @@ function iats_civicrm_install() {
   _iats_civix_civicrm_install();
 }
 
-/**
- * Implements hook_civicrm_postInstall().
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall
- */
-function iats_civicrm_postInstall() {
-  _iats_civix_civicrm_postInstall();
-}
-
-/**
- * Implements hook_civicrm_uninstall().
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
- */
-function iats_civicrm_uninstall() {
-  _iats_civix_civicrm_uninstall();
-}
-
 /**
  * Implements hook_civicrm_enable().
  *
@@ -91,83 +64,6 @@ function iats_civicrm_enable() {
   _iats_civix_civicrm_enable();
 }
 
-/**
- * Implements hook_civicrm_disable().
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
- */
-function iats_civicrm_disable() {
-  _iats_civix_civicrm_disable();
-}
-
-/**
- * Implements hook_civicrm_upgrade().
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
- */
-function iats_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
-  return _iats_civix_civicrm_upgrade($op, $queue);
-}
-
-/**
- * Implements hook_civicrm_managed().
- *
- * Generate a list of entities to create/deactivate/delete when this module
- * is installed, disabled, uninstalled.
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
- */
-function iats_civicrm_managed(&$entities) {
-  _iats_civix_civicrm_managed($entities);
-}
-
-/**
- * Implements hook_civicrm_caseTypes().
- *
- * Generate a list of case-types.
- *
- * Note: This hook only runs in CiviCRM 4.4+.
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
- */
-function iats_civicrm_caseTypes(&$caseTypes) {
-  _iats_civix_civicrm_caseTypes($caseTypes);
-}
-
-/**
- * Implements hook_civicrm_angularModules().
- *
- * Generate a list of Angular modules.
- *
- * Note: This hook only runs in CiviCRM 4.5+. It may
- * use features only available in v4.6+.
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_angularModules
- */
-function iats_civicrm_angularModules(&$angularModules) {
-  _iats_civix_civicrm_angularModules($angularModules);
-}
-
-/**
- * Implements hook_civicrm_alterSettingsFolders().
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders
- */
-function iats_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
-  _iats_civix_civicrm_alterSettingsFolders($metaDataFolders);
-}
-
-/**
- * Implements hook_civicrm_entityTypes().
- *
- * Declare entity types provided by this module.
- *
- * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_entityTypes
- */
-function iats_civicrm_entityTypes(&$entityTypes) {
-  _iats_civix_civicrm_entityTypes($entityTypes);
-}
-
 // --- Functions below this ship commented out. Uncomment as required. ---
 
 /**
@@ -175,9 +71,8 @@ function iats_civicrm_entityTypes(&$entityTypes) {
  *
  * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_preProcess
  *
-function iats_civicrm_preProcess($formName, &$form) {
 
-} // */
+ // */
 
 /**
  * Implements hook_civicrm_navigationMenu().
@@ -334,7 +229,6 @@ function iats_civicrm_buildForm($formName, &$form) {
   // Else echo $fname;.
 }
 
-
 /**
  * Modifications to a (public/frontend) contribution financial forms for iATS
  * procesors.
@@ -591,7 +485,6 @@ function _iats_filter_payment_processors($class, $processors = array(), $params
   return $list;
 }
 
-
 /**
  * Internal utility function: return a list of the payment processors attached
  * to a contribution form of variable class
diff --git a/civicrm/ext/iatspayments/info.xml b/civicrm/ext/iatspayments/info.xml
index 3b438833530179326c3d6dfd380553aaed1e4319..2e219693bf921e848ba2931e94a8a3dbd93ca9fd 100644
--- a/civicrm/ext/iatspayments/info.xml
+++ b/civicrm/ext/iatspayments/info.xml
@@ -9,7 +9,7 @@
     <url desc="Support">https://github.com/iATSPayments/com.iatspayments.civicrm/issues?state=open</url>
     <url desc="Installation Instructions">https://github.com/iATSPayments/com.iatspayments.civicrm</url>
     <url desc="Documentation">https://github.com/iATSPayments/com.iatspayments.civicrm</url>
-    <url desc="Release Notes">https://github.com/iATSPayments/com.iatspayments.civicrm/blob/master/release-notes/1.7.5.md</url>
+    <url desc="Release Notes">https://github.com/iATSPayments/com.iatspayments.civicrm/blob/master/release-notes/1.8.0.md</url>
     <url desc="Getting Started">https://www.semper-it.com/civicamp-iats-payments-slides</url>
   </urls>
   <license>AGPL-3.0</license>
@@ -17,14 +17,25 @@
     <author>Alan Dixon</author>
     <email>iats@blackflysolutions.ca</email>
   </maintainer>
-  <releaseDate>2023-03-08</releaseDate>
-  <version>1.7.5</version>
+  <releaseDate>2023-10-20</releaseDate>
+  <version>1.8.0</version>
   <develStage>stable</develStage>
   <compatibility>
-    <ver>5.49</ver>
+    <ver>5.63</ver>
   </compatibility>
-  <comments>A recommended 1.7.x maintenance release, see release notes above for details.</comments>
+  <comments>A recommended 1.x maintenance release, see release notes above for details.</comments>
   <civix>
     <namespace>CRM/Iats</namespace>
+    <format>23.02.1</format>
   </civix>
+  <mixins>
+    <mixin>menu-xml@1.0.0</mixin>
+    <mixin>mgd-php@1.0.0</mixin>
+    <mixin>smarty-v2@1.0.1</mixin>
+  </mixins>
+  <classloader>
+    <psr0 prefix="CRM_" path="."/>
+    <psr4 prefix="Civi\" path="Civi"/>
+  </classloader>
+  <upgrader>CRM_Iats_Upgrader</upgrader>
 </extension>
diff --git a/civicrm/ext/iatspayments/js/dd_cad.js b/civicrm/ext/iatspayments/js/dd_cad.js
index f412abd38bff0b0c19475d65cd112df3a81eb863..4a39987f13bd13c76d45d864338599ab1ec07cc9 100644
--- a/civicrm/ext/iatspayments/js/dd_cad.js
+++ b/civicrm/ext/iatspayments/js/dd_cad.js
@@ -22,7 +22,7 @@ CRM.$(function ($) {
   $('#cad_bank_number').blur(function(eventObj) {
     var myCount = onlyNumbers($(this));
     if ((myCount > 0) && (myCount != 3)) {
-      $(this).crmError(ts('Your Bank Number requires three digits, use a leading "0" if necessary')); 
+      $(this).crmError(ts('Your Bank No. requires three digits, use a leading "0" if necessary'));
     }
     switch($(this).val()) {
       case '001': $('#bank_name').val('Bank of Montreal'); break;
@@ -49,7 +49,7 @@ CRM.$(function ($) {
   $('#cad_transit_number').blur(function(eventObj) {
     var myCount = onlyNumbers($(this));
     if ((myCount > 0) && (myCount != 5)) {
-      $(this).crmError(ts('Your Bank Transit Number requires exactly five digits')); 
+      $(this).crmError(ts('Your Transit No. requires exactly five digits'));
     }
     iatsSetBankIdenficationNumber();
   });
diff --git a/civicrm/ext/iatspayments/mixin/smarty-v2@1.0.1.mixin.php b/civicrm/ext/iatspayments/mixin/smarty-v2@1.0.1.mixin.php
new file mode 100644
index 0000000000000000000000000000000000000000..5972dbdc57ffd6badbb1eb84f628700ea9727b09
--- /dev/null
+++ b/civicrm/ext/iatspayments/mixin/smarty-v2@1.0.1.mixin.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Auto-register "templates/" folder.
+ *
+ * @mixinName smarty-v2
+ * @mixinVersion 1.0.1
+ * @since 5.59
+ *
+ * @param CRM_Extension_MixInfo $mixInfo
+ *   On newer deployments, this will be an instance of MixInfo. On older deployments, Civix may polyfill with a work-a-like.
+ * @param \CRM_Extension_BootCache $bootCache
+ *   On newer deployments, this will be an instance of MixInfo. On older deployments, Civix may polyfill with a work-a-like.
+ */
+return function ($mixInfo, $bootCache) {
+  $dir = $mixInfo->getPath('templates');
+  if (!file_exists($dir)) {
+    return;
+  }
+
+  $register = function() use ($dir) {
+    // This implementation has a theoretical edge-case bug on older versions of CiviCRM where a template could
+    // be registered more than once.
+    CRM_Core_Smarty::singleton()->addTemplateDir($dir);
+  };
+
+  // Let's figure out what environment we're in -- so that we know the best way to call $register().
+
+  if (!empty($GLOBALS['_CIVIX_MIXIN_POLYFILL'])) {
+    // Polyfill Loader (v<=5.45): We're already in the middle of firing `hook_config`.
+    if ($mixInfo->isActive()) {
+      $register();
+    }
+    return;
+  }
+
+  if (CRM_Extension_System::singleton()->getManager()->extensionIsBeingInstalledOrEnabled($mixInfo->longName)) {
+    // New Install, Standard Loader: The extension has just been enabled, and we're now setting it up.
+    // System has already booted. New templates may be needed for upcoming installation steps.
+    $register();
+    return;
+  }
+
+  // Typical Pageview, Standard Loader: Defer the actual registration for a moment -- to ensure that Smarty is online.
+  \Civi::dispatcher()->addListener('hook_civicrm_config', function() use ($mixInfo, $register) {
+    if ($mixInfo->isActive()) {
+      $register();
+    }
+  });
+
+};
diff --git a/civicrm/ext/iatspayments/release-notes/1.8.0.md b/civicrm/ext/iatspayments/release-notes/1.8.0.md
new file mode 100644
index 0000000000000000000000000000000000000000..4ecd896772b80b6df7de84d031e59ba450390b77
--- /dev/null
+++ b/civicrm/ext/iatspayments/release-notes/1.8.0.md
@@ -0,0 +1,23 @@
+# iATS CiviCRM Extension 1.8.0
+
+Oct 20, 2023
+
+This release is a maintenance release for the 1.x series. 
+
+It is recommended for all CiviCRM installs on 5.63+ and above. 
+
+Note that as of this release, we've started using sematic versioning.
+
+This release covers 8 issues and improvements since Mar 2023.
+
+1. 'failsafe' behaviour to avoid unplanned recurring charges (issue 424, thanks Nancy Annigson)
+2. civix update (thanks eileen and tim)
+3. Handle change to recurring membership amount (issue 417, thanks to elisseck)
+4. Improve the useability of the ACH form (issue 426, thanks to shaneonabike)
+5. Civix upgrade (thanks eileen)
+6. strftime deprecation (thanks seamus)
+7. fix filtering by frequency unit in iats recurring report (thanks karin)
+8. update to latest smart-v2 mixin (thanks seamus)
+
+Documentation of the new 'failsafe' and 'stale schedules' features and configuration are here:
+https://github.com/iATSPayments/com.iatspayments.civicrm/wiki/Recurring-Contribution-Job#stale-schedules
diff --git a/civicrm/ext/legacycustomsearches/info.xml b/civicrm/ext/legacycustomsearches/info.xml
index 9eb71cb67e7056b9e3f7ad64aa7f956e9425720e..0afd6c034f82ea8f4fab409d8efc7d5925489aac 100644
--- a/civicrm/ext/legacycustomsearches/info.xml
+++ b/civicrm/ext/legacycustomsearches/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-07-25</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/message_admin/info.xml b/civicrm/ext/message_admin/info.xml
index ce9e985a6c7f392a3db657f61b7affa9f0f66f2c..fe2b0021a3a97d5f523ee31a6f7ba5e8a3965a50 100644
--- a/civicrm/ext/message_admin/info.xml
+++ b/civicrm/ext/message_admin/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-06-12</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/oauth-client/info.xml b/civicrm/ext/oauth-client/info.xml
index d4904961d62ec8ac5a343bf7fa08c48911db520e..a0c9e95d2ecbe1c27700f6f4df721961b00523e6 100644
--- a/civicrm/ext/oauth-client/info.xml
+++ b/civicrm/ext/oauth-client/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-10-23</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/payflowpro/info.xml b/civicrm/ext/payflowpro/info.xml
index fda22e8534f1ffd6bd4cb4d1971b6cea5df618d8..a362f4efeb4236d1761858491450299a2828250f 100644
--- a/civicrm/ext/payflowpro/info.xml
+++ b/civicrm/ext/payflowpro/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-04-13</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/recaptcha/info.xml b/civicrm/ext/recaptcha/info.xml
index 35665f9481776a849a1f456464daac46dfcde027..4846fb992663b55e10e44fb2645c68f2f1aa7b8c 100644
--- a/civicrm/ext/recaptcha/info.xml
+++ b/civicrm/ext/recaptcha/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-04-03</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/scheduled_communications/info.xml b/civicrm/ext/scheduled_communications/info.xml
index f4ee882a24d4306b4537de1185556aff6a0ff2fc..d45698b4e96673f7fad0fea24cf2768eb4bb6abd 100644
--- a/civicrm/ext/scheduled_communications/info.xml
+++ b/civicrm/ext/scheduled_communications/info.xml
@@ -13,7 +13,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2023-09-04</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>beta</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/ext/search_kit/info.xml b/civicrm/ext/search_kit/info.xml
index ce63c544b42f245877e27247dbafc5d5a1e8799a..51cce096093570bed4dae4fbca63e0551dcda03f 100644
--- a/civicrm/ext/search_kit/info.xml
+++ b/civicrm/ext/search_kit/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2021-01-06</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>stable</develStage>
   <tags>
     <tag>mgmt:required</tag>
diff --git a/civicrm/ext/sequentialcreditnotes/info.xml b/civicrm/ext/sequentialcreditnotes/info.xml
index 45722d5a618d8bb2eba33d09827fbc493fc407a0..9e34a120fa10343ad1b8ef19e2d9c40ced9d546e 100644
--- a/civicrm/ext/sequentialcreditnotes/info.xml
+++ b/civicrm/ext/sequentialcreditnotes/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2020-01-28</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <tags>
     <tag>mgmt:hidden</tag>
   </tags>
diff --git a/civicrm/ext/standaloneusers/info.xml b/civicrm/ext/standaloneusers/info.xml
index f27435bdd899c36ed991c28cd78c9b30fd7f990a..14dd54e4dd9d06034a415e7b5eca3685fba99f81 100644
--- a/civicrm/ext/standaloneusers/info.xml
+++ b/civicrm/ext/standaloneusers/info.xml
@@ -15,7 +15,7 @@
     <url desc="Licensing">http://www.gnu.org/licenses/agpl-3.0.html</url>
   </urls>
   <releaseDate>2022-11-11</releaseDate>
-  <version>5.66.0</version>
+  <version>5.66.1</version>
   <develStage>alpha</develStage>
   <compatibility>
     <ver>5.66</ver>
diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md
index a4ba38a48dfb31682fa78d3a3ad925a5a31c243a..9cb4496743bc7e7dc34d6f516ea424ddde8033c8 100644
--- a/civicrm/release-notes.md
+++ b/civicrm/release-notes.md
@@ -15,6 +15,15 @@ Other resources for identifying changes are:
     * https://github.com/civicrm/civicrm-joomla
     * https://github.com/civicrm/civicrm-wordpress
 
+## CiviCRM 5.66.1
+
+Released October 25, 2023
+
+- **[Synopsis](release-notes/5.66.1.md#synopsis)**
+- **[Bugs resolved](release-notes/5.66.1.md#bugs)**
+- **[Credits](release-notes/5.66.1.md#credits)**
+- **[Feedback](release-notes/5.66.1.md#feedback)**
+
 ## CiviCRM 5.66.0
 
 Released October 4, 2023
diff --git a/civicrm/release-notes/5.66.1.md b/civicrm/release-notes/5.66.1.md
new file mode 100644
index 0000000000000000000000000000000000000000..0304828e21ce3d4e85877d6814a583f185b6667d
--- /dev/null
+++ b/civicrm/release-notes/5.66.1.md
@@ -0,0 +1,45 @@
+# CiviCRM 5.66.1
+
+Released October 25, 2023
+
+- **[Synopsis](#synopsis)**
+- **[Bugs resolved](#bugs)**
+- **[Credits](#credits)**
+- **[Feedback](#feedback)**
+
+## <a name="synopsis"></a>Synopsis
+
+| *Does this version...?*                                         |          |
+| --------------------------------------------------------------- | -------- |
+| **Change the database schema?**                                 | **yes**  |
+| Alter the API?                                                  | no       |
+| Require attention to configuration options?                     | no       |
+| **Fix problems installing or upgrading to a previous version?** | **yes**  |
+| Introduce features?                                             | no       |
+| **Fix bugs?**                                                   | **yes**  |
+| Fix security vulnerabilities?                                   | no       |
+
+## <a name="bugs"></a>Bugs resolved
+
+* **_CiviEvent_: Custom data not displayed to administrator. May lead to overwrite/loss. ([dev/core#4706](https://lab.civicrm.org/dev/core/-/issues/4706): [#27868](https://github.com/civicrm/civicrm-core/pull/27868))**
+* **_CiviPledge_: Error when deleting pledge ([#27878](https://github.com/civicrm/civicrm-core/pull/27878))**
+* **_Financial ACLs_: Administative links for "Membership Type" may be hidden ([#27771](https://github.com/civicrm/civicrm-core/pull/27771))**
+* **_Groups_: "Parent" property not displayed to administrator. May lead to overwrite/loss. ([dev/core#4703](https://lab.civicrm.org/dev/core/-/issues/4703): [#27858](https://github.com/civicrm/civicrm-core/pull/27858))**
+* **_Link Weights_: Fix new warnings about hyperlink weights for "Premiums", "Surveys", "PCP" ([#27788](https://github.com/civicrm/civicrm-core/pull/27788), [#27780](https://github.com/civicrm/civicrm-core/pull/27780), [#27728](https://github.com/civicrm/civicrm-core/pull/27728))**
+* **_Status Check_: Add warning about deprecated notation in Angular modules ([#27798](https://github.com/civicrm/civicrm-core/pull/27798))**
+* **_Upgrader_: Fix upgrade for "Scheduled Reminders" with long/duplicate names. Fix transposed descriptions. ([dev/core#4696](https://lab.civicrm.org/dev/core/-/issues/4696): [#27913](https://github.com/civicrm/civicrm-core/pull/27913))**
+
+## <a name="credits"></a>Credits
+
+This release was developed by the following authors and reviewers:
+
+Wikimedia Foundation - Eileen McNaughton; MJW Consulting - Matthew Wire; Megaphone
+Technology Consulting - Jon Goldberg, Brienne Kordis; Lemniscus - Noah Miller; Greenleaf
+Advancement - Guy Iaccarino; Fuzion - Jitendra Purohit; CiviDesk - Yashodha Chaku; CiviCRM
+- Coleman Watts, Tim Otten; Agileware - Justin Freeman
+
+## <a name="feedback"></a>Feedback
+
+These release notes are edited by Tim Otten and Andie Hunt.  If you'd like to
+provide feedback on them, please login to https://chat.civicrm.org/civicrm and
+contact `@agh1`.
diff --git a/civicrm/sql/civicrm.mysql b/civicrm/sql/civicrm.mysql
index fdc591ae7b4ff0a0b203dfaf1b1c66c89801ba01..f57131a64e6f3e20aacc1d447ff721ab255f2100 100644
--- a/civicrm/sql/civicrm.mysql
+++ b/civicrm/sql/civicrm.mysql
@@ -2895,7 +2895,7 @@ ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ROW_FORMA
 -- *******************************************************/
 CREATE TABLE `civicrm_action_schedule` (
   `id` int unsigned NOT NULL AUTO_INCREMENT,
-  `name` varchar(64) NOT NULL COMMENT 'Name of the action(reminder)',
+  `name` varchar(128) NOT NULL COMMENT 'Name of the scheduled action',
   `title` varchar(64) COMMENT 'Title of the action(reminder)',
   `recipient` varchar(64) COMMENT 'Recipient',
   `limit_to` int COMMENT 'Is this the recipient criteria limited to OR in addition to?',
diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql
index da6d3c4e8d5bf1ddac1c2c27d3ba683c8aa7ba5d..c7e9f4e8785849781f5e1f7ed462904b862e8f8f 100644
--- a/civicrm/sql/civicrm_data.mysql
+++ b/civicrm/sql/civicrm_data.mysql
@@ -23701,4 +23701,4 @@ INSERT INTO `civicrm_report_instance`
     ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`)
 VALUES
     (  @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}');
-UPDATE civicrm_domain SET version = '5.66.0';
+UPDATE civicrm_domain SET version = '5.66.1';
diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql
index e0cb5a53a47f78905241acacde85480cc2f0e15c..f3392fa2e025a503f415721bbabf894463766f51 100644
--- a/civicrm/sql/civicrm_generated.mysql
+++ b/civicrm/sql/civicrm_generated.mysql
@@ -2972,7 +2972,7 @@ UNLOCK TABLES;
 LOCK TABLES `civicrm_domain` WRITE;
 /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
 INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES
- (1,'Default Domain Name',NULL,'5.66.0',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+ (1,'Default Domain Name',NULL,'5.66.1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
 /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
 UNLOCK TABLES;
 
diff --git a/civicrm/templates/CRM/Contribute/Form/ManagePremiums.tpl b/civicrm/templates/CRM/Contribute/Form/ManagePremiums.tpl
index b32fd20a7a3059388930d4f4da59d001f70fcce8..610fba0b40f32787f37aae547d0dfb6302f26520 100644
--- a/civicrm/templates/CRM/Contribute/Form/ManagePremiums.tpl
+++ b/civicrm/templates/CRM/Contribute/Form/ManagePremiums.tpl
@@ -73,12 +73,12 @@
      <span class="description">{ts}The market value of this premium (e.g. retail price). For tax-deductible contributions, this amount will be used to set the non-deductible amount in the contribution record and receipt.{/ts}</span>
        </td>
     </tr>
-    <tr class="crm-contribution-form-block-cost">
-       <td class="label">{$form.cost.label}</td>
-       <td class="html-adjust">{$form.cost.html}<br />
-        <span class="description">{ts}You may optionally record the actual cost of this premium to your organization. This may be useful when evaluating net return for this incentive.{/ts}</span>
-       </td>
-    </tr>
+      <tr class="crm-contribution-form-block-cost">
+         <td class="label">{$form.cost.label}</td>
+         <td class="html-adjust">{$form.cost.html}<br />
+          <span class="description">{ts}You may optionally record the actual cost of this premium to your organization. This may be useful when evaluating net return for this incentive.{/ts}</span>
+         </td>
+      </tr>
      <tr class="crm-contribution-form-block-financial_type">
        <td class="label">{$form.financial_type_id.label}</td>
        <td class="html-adjust">
diff --git a/civicrm/templates/CRM/Event/Form/ManageEvent/EventInfo.tpl b/civicrm/templates/CRM/Event/Form/ManageEvent/EventInfo.tpl
index 3415737f7aa16cf87232d78cb51686e5562bb772..a76f4914f8d3a9b1f5fe085fcb834f69cc4ffd6a 100644
--- a/civicrm/templates/CRM/Event/Form/ManageEvent/EventInfo.tpl
+++ b/civicrm/templates/CRM/Event/Form/ManageEvent/EventInfo.tpl
@@ -123,7 +123,7 @@
       </tr>
     {/if}
   </table>
-  {include file="CRM/common/customDataBlock.tpl"}
+  {include file="CRM/common/customDataBlock.tpl" entityID=$eventID}
   <div class="crm-submit-buttons">
     {include file="CRM/common/formButtons.tpl" location="bottom"}
   </div>
diff --git a/civicrm/templates/CRM/Group/Form/GroupsCommon.tpl b/civicrm/templates/CRM/Group/Form/GroupsCommon.tpl
index 3b5e5f0080e8292145105d6c7fc34a4b1b117e60..590afb4f44dbea6d0d8fd6edb8f3c498f411bddb 100644
--- a/civicrm/templates/CRM/Group/Form/GroupsCommon.tpl
+++ b/civicrm/templates/CRM/Group/Form/GroupsCommon.tpl
@@ -7,30 +7,12 @@
  | and copyright information, see https://civicrm.org/licensing       |
  +--------------------------------------------------------------------+
 *}
-{*CRM-14190*}
-{if $parent_groups|@count > 0 || !empty($form.parents.html)}
-  <h3>{ts}Parent Groups{/ts} {help id="id-group-parent" file="CRM/Group/Page/Group.hlp"}</h3>
-  {if $parent_groups|@count > 0}
-    <table class="form-layout-compressed">
-      <tr>
-        <td><label>{ts}Remove Parent?{/ts}</label></td>
-      </tr>
-      {foreach from=$parent_groups item=cgroup key=group_id}
-        {assign var="element_name" value="remove_parent_group_"|cat:$group_id}
-        <tr>
-          <td>&nbsp;&nbsp;{$form.$element_name.html}&nbsp;{$form.$element_name.label}</td>
-        </tr>
-      {/foreach}
-    </table>
-    <br />
-  {/if}
-  <table class="form-layout-compressed">
-    <tr class="crm-group-form-block-parents">
-      <td class="label">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{$form.parents.label}</td>
-      <td>{$form.parents.html|crmAddClass:huge}</td>
-    </tr>
-  </table>
-{/if}
+<table class="form-layout-compressed">
+  <tr class="crm-group-form-block-parents">
+    <td class="label">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{$form.parents.label}</td>
+    <td>{$form.parents.html|crmAddClass:huge}</td>
+  </tr>
+</table>
 {if array_key_exists('organization_id', $form)}
   <h3>{ts}Associated Organization{/ts} {help id="id-group-organization" file="CRM/Group/Page/Group.hlp"}</h3>
   <table class="form-layout-compressed">
diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php
index 3076282fe462a9ed034db491178f0071ebf29e92..2630f3125a555cb811dcdfe62b6f79b6f79cc80c 100644
--- a/civicrm/vendor/autoload.php
+++ b/civicrm/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInit16492df646fda411676597428dd1551a::getLoader();
+return ComposerAutoloaderInitf48a3eb1b6a31014eb65f25a1523d02d::getLoader();
diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php
index c6ea2241104e1264d7a2fb6d9b820424b37a6b89..ae82a91375d6c8b550d5ae9cc82bbe9ddc9e8579 100644
--- a/civicrm/vendor/composer/autoload_real.php
+++ b/civicrm/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit16492df646fda411676597428dd1551a
+class ComposerAutoloaderInitf48a3eb1b6a31014eb65f25a1523d02d
 {
     private static $loader;
 
@@ -24,9 +24,9 @@ class ComposerAutoloaderInit16492df646fda411676597428dd1551a
 
         require __DIR__ . '/platform_check.php';
 
-        spl_autoload_register(array('ComposerAutoloaderInit16492df646fda411676597428dd1551a', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInitf48a3eb1b6a31014eb65f25a1523d02d', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
-        spl_autoload_unregister(array('ComposerAutoloaderInit16492df646fda411676597428dd1551a', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInitf48a3eb1b6a31014eb65f25a1523d02d', 'loadClassLoader'));
 
         $includePaths = require __DIR__ . '/include_paths.php';
         $includePaths[] = get_include_path();
@@ -36,7 +36,7 @@ class ComposerAutoloaderInit16492df646fda411676597428dd1551a
         if ($useStaticLoader) {
             require __DIR__ . '/autoload_static.php';
 
-            call_user_func(\Composer\Autoload\ComposerStaticInit16492df646fda411676597428dd1551a::getInitializer($loader));
+            call_user_func(\Composer\Autoload\ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::getInitializer($loader));
         } else {
             $map = require __DIR__ . '/autoload_namespaces.php';
             foreach ($map as $namespace => $path) {
@@ -57,12 +57,12 @@ class ComposerAutoloaderInit16492df646fda411676597428dd1551a
         $loader->register(true);
 
         if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInit16492df646fda411676597428dd1551a::$files;
+            $includeFiles = Composer\Autoload\ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequire16492df646fda411676597428dd1551a($fileIdentifier, $file);
+            composerRequiref48a3eb1b6a31014eb65f25a1523d02d($fileIdentifier, $file);
         }
 
         return $loader;
@@ -74,7 +74,7 @@ class ComposerAutoloaderInit16492df646fda411676597428dd1551a
  * @param string $file
  * @return void
  */
-function composerRequire16492df646fda411676597428dd1551a($fileIdentifier, $file)
+function composerRequiref48a3eb1b6a31014eb65f25a1523d02d($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php
index d50a44363394f8ef3a070fad51aa9657ee7f92c9..c4531706893f8999332aabc343cf216e4f223fae 100644
--- a/civicrm/vendor/composer/autoload_static.php
+++ b/civicrm/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInit16492df646fda411676597428dd1551a
+class ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d
 {
     public static $files = array (
         'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
@@ -729,11 +729,11 @@ class ComposerStaticInit16492df646fda411676597428dd1551a
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInit16492df646fda411676597428dd1551a::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInit16492df646fda411676597428dd1551a::$prefixDirsPsr4;
-            $loader->prefixesPsr0 = ComposerStaticInit16492df646fda411676597428dd1551a::$prefixesPsr0;
-            $loader->fallbackDirsPsr0 = ComposerStaticInit16492df646fda411676597428dd1551a::$fallbackDirsPsr0;
-            $loader->classMap = ComposerStaticInit16492df646fda411676597428dd1551a::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::$prefixDirsPsr4;
+            $loader->prefixesPsr0 = ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::$prefixesPsr0;
+            $loader->fallbackDirsPsr0 = ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::$fallbackDirsPsr0;
+            $loader->classMap = ComposerStaticInitf48a3eb1b6a31014eb65f25a1523d02d::$classMap;
 
         }, null, ClassLoader::class);
     }
diff --git a/civicrm/vendor/composer/installed.php b/civicrm/vendor/composer/installed.php
index cd561f72c783f38babfbd9852a42b885da15fb70..094118da2e1cc6de7374f9f9dbada50e6e390689 100644
--- a/civicrm/vendor/composer/installed.php
+++ b/civicrm/vendor/composer/installed.php
@@ -5,7 +5,7 @@
         'type' => 'library',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
-        'reference' => '5159715422a59556294d10cc056b5a335a6cf9ba',
+        'reference' => '730acb17b7895fc1d07541827562e79b6f2eb933',
         'name' => 'civicrm/civicrm-core',
         'dev' => true,
     ),
@@ -43,7 +43,7 @@
             'type' => 'library',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
-            'reference' => '5159715422a59556294d10cc056b5a335a6cf9ba',
+            'reference' => '730acb17b7895fc1d07541827562e79b6f2eb933',
             'dev_requirement' => false,
         ),
         'civicrm/civicrm-cxn-rpc' => array(
diff --git a/civicrm/xml/schema/Core/ActionSchedule.xml b/civicrm/xml/schema/Core/ActionSchedule.xml
index 9063c21e40a2269c08eac482d056dd76f062698f..c9b31a49582a2de1718007e119eb2f57bed615b0 100644
--- a/civicrm/xml/schema/Core/ActionSchedule.xml
+++ b/civicrm/xml/schema/Core/ActionSchedule.xml
@@ -36,8 +36,8 @@
     <html>
       <type>Text</type>
     </html>
-    <length>64</length>
-    <comment>Name of the action(reminder)</comment>
+    <length>128</length>
+    <comment>Name of the scheduled action</comment>
     <add>3.4</add>
   </field>
   <index>
diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml
index 1e590fb8c7c8409cd2d7b1337aeae6b97d414257..6cdf70e90aa757a8c4f9a8f266ca2aaa5e06ba3d 100644
--- a/civicrm/xml/version.xml
+++ b/civicrm/xml/version.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="iso-8859-1" ?>
 <version>
-  <version_no>5.66.0</version_no>
+  <version_no>5.66.1</version_no>
 </version>