Index: branches/5.2.x/core/admin_templates/languages/email_message_edit.tpl
===================================================================
diff -u -N -r14244 -r15222
--- branches/5.2.x/core/admin_templates/languages/email_message_edit.tpl (.../email_message_edit.tpl) (revision 14244)
+++ branches/5.2.x/core/admin_templates/languages/email_message_edit.tpl (.../email_message_edit.tpl) (revision 15222)
@@ -67,13 +67,14 @@
-
+
-
+
-
+
+
Index: branches/5.2.x/core/units/email_events/email_events_event_handler.php
===================================================================
diff -u -N -r15215 -r15222
--- branches/5.2.x/core/units/email_events/email_events_event_handler.php (.../email_events_event_handler.php) (revision 15215)
+++ branches/5.2.x/core/units/email_events/email_events_event_handler.php (.../email_events_event_handler.php) (revision 15222)
@@ -1,6 +1,6 @@
SetDBField('Headers', $this->Application->ConfigValue('Smtp_DefaultHeaders'));
+ $this->setRequired($event);
}
/**
@@ -152,17 +153,17 @@
*/
function OnFrontOnly($event)
{
- if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
+ if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
- return ;
+ return;
}
$ids = implode(',', $this->StoreSelectedIDs($event));
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
- $sql = 'UPDATE '.$table_name.'
+ $sql = 'UPDATE ' . $table_name . '
SET FrontEndOnly = 1
- WHERE EventId IN ('.$ids.')';
+ WHERE EventId IN (' . $ids . ')';
$this->Conn->Query($sql);
$this->clearSelectedIDs($event);
@@ -225,58 +226,58 @@
function OnProcessEmailQueue($event)
{
$deliver_count = $event->getEventParam('deliver_count');
- if ($deliver_count === false) {
+ if ( $deliver_count === false ) {
$deliver_count = $this->Application->ConfigValue('MailingListSendPerStep');
- if ($deliver_count === false) {
+ if ( $deliver_count === false ) {
$deliver_count = 10; // 10 emails per script run (if not specified directly)
}
}
$processing_type = $this->Application->GetVar('type');
- if ($processing_type = 'return_progress') {
+ if ( $processing_type = 'return_progress' ) {
$email_queue_progress = $this->Application->RecallVar('email_queue_progress');
- if ($email_queue_progress === false) {
+ if ( $email_queue_progress === false ) {
$emails_sent = 0;
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'EmailQueue
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')';
$total_emails = $this->Conn->GetOne($sql);
- $this->Application->StoreVar('email_queue_progress', $emails_sent.':'.$total_emails);
+ $this->Application->StoreVar('email_queue_progress', $emails_sent . ':' . $total_emails);
}
else {
list ($emails_sent, $total_emails) = explode(':', $email_queue_progress);
}
}
$sql = 'SELECT *
- FROM '.TABLE_PREFIX.'EmailQueue
+ FROM ' . TABLE_PREFIX . 'EmailQueue
WHERE (SendRetries < 5) AND (LastSendRetry < ' . strtotime('-2 hours') . ')
LIMIT 0,' . $deliver_count;
$messages = $this->Conn->Query($sql);
$message_count = count($messages);
- if (!$message_count) {
+ if ( !$message_count ) {
// no messages left to send in queue
- if ($processing_type = 'return_progress') {
+ if ( $processing_type = 'return_progress' ) {
$this->Application->RemoveVar('email_queue_progress');
$this->Application->Redirect($this->Application->GetVar('finish_template'));
}
- return ;
+ return;
}
$mailing_list_helper = $this->Application->recallObject('MailingListHelper');
/* @var $mailing_list_helper MailingListHelper */
$mailing_list_helper->processQueue($messages);
- if ($processing_type = 'return_progress') {
+ if ( $processing_type = 'return_progress' ) {
$emails_sent += $message_count;
- if ($emails_sent >= $total_emails) {
+ if ( $emails_sent >= $total_emails ) {
$this->Application->RemoveVar('email_queue_progress');
$this->Application->Redirect($this->Application->GetVar('finish_template'));
}
- $this->Application->StoreVar('email_queue_progress', $emails_sent.':'.$total_emails);
+ $this->Application->StoreVar('email_queue_progress', $emails_sent . ':' . $total_emails);
$event->status = kEvent::erSTOP;
echo ($emails_sent / $total_emails) * 100;
}
@@ -296,7 +297,7 @@
$options = Array ();
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
- if ($module_name == 'In-Portal') {
+ if ( $module_name == 'In-Portal' ) {
continue;
}
@@ -307,7 +308,7 @@
$fields['Module']['options'] = $options;
$this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
- if ($this->Application->GetVar('regional')) {
+ if ( $this->Application->GetVar('regional') ) {
$this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true);
}
}
@@ -342,8 +343,8 @@
$object = $event->getObject();
/* @var $object kDBItem */
- if (!$this->Application->isDebugMode(false)) {
- if ($object->GetDBField('AllowChangingRecipient')) {
+ if ( !$this->Application->isDebugMode(false) ) {
+ if ( $object->GetDBField('AllowChangingRecipient') ) {
$object->SetDBField('RecipientType', EmailEvent::RECIPIENT_TYPE_TO);
}
else {
@@ -365,6 +366,8 @@
$xml = $minput_helper->prepareMInputXML($records, Array ('Tag', 'Replacement'));
$object->SetDBField('ReplacementTagsXML', $xml);
+
+ $this->setRequired($event);
}
/**
@@ -381,28 +384,28 @@
$this->_validateEmailTemplate($object);
// validate sender and recipient addresses
- if ($object->GetDBField('CustomSender')) {
+ if ( $object->GetDBField('CustomSender') ) {
$this->_validateAddress($event, 'Sender');
}
$this->_validateAddress($event, 'Recipient');
- if (!$this->Application->isDebugMode(false)) {
+ if ( !$this->Application->isDebugMode(false) ) {
// only allow to enable/disable event while in debug mode
$to_restore = Array ('Enabled', 'AllowChangingSender', 'AllowChangingRecipient');
- if (!$object->GetOriginalField('AllowChangingSender')) {
+ if ( !$object->GetOriginalField('AllowChangingSender') ) {
$to_restore = array_merge($to_restore, Array ('CustomSender', 'SenderName', 'SenderAddressType', 'SenderAddress'));
}
- if (!$object->GetOriginalField('AllowChangingRecipient')) {
- $to_restore = array_merge($to_restore, Array ('CustomRecipient'/*, 'Recipients'*/));
+ if ( !$object->GetOriginalField('AllowChangingRecipient') ) {
+ $to_restore = array_merge($to_restore, Array ('CustomRecipient' /*, 'Recipients'*/));
}
// prevent specific fields from editing
foreach ($to_restore as $restore_field) {
$original_value = $object->GetOriginalField($restore_field);
- if ($object->GetDBField($restore_field) != $original_value) {
+ if ( $object->GetDBField($restore_field) != $original_value ) {
$object->SetDBField($restore_field, $original_value);
}
}
@@ -414,10 +417,10 @@
/* @var $minput_helper MInputHelper */
$replacement_tags = Array ();
- $records = $minput_helper->parseMInputXML( $object->GetDBField('ReplacementTagsXML') );
+ $records = $minput_helper->parseMInputXML($object->GetDBField('ReplacementTagsXML'));
foreach ($records as $record) {
- $replacement_tags[ trim($record['Tag']) ] = trim($record['Replacement']);
+ $replacement_tags[trim($record['Tag'])] = trim($record['Replacement']);
}
$object->SetDBField('ReplacementTags', $replacement_tags ? serialize($replacement_tags) : NULL);
@@ -427,18 +430,38 @@
$object->SetDBField('LastChanged_date', TIMENOW);
$object->SetDBField('LastChanged_time', TIMENOW);
}
+
+ $this->setRequired($event);
}
/**
+ * Dynamically changes required fields
+ *
+ * @param kEvent $event
+ * @return void
+ * @access protected
+ */
+ protected function setRequired(kEvent $event)
+ {
+ $object = $event->getObject();
+ /* @var $object kDBItem */
+
+ $language_prefix = 'l' . $this->Application->GetVar('m_lang') . '_';
+
+ $object->setRequired($language_prefix . 'HtmlBody', !$object->GetField('PlainTextBody'));
+ $object->setRequired($language_prefix . 'PlainTextBody', !$object->GetField('HtmlBody'));
+ }
+
+ /**
* Checks, that at least one of phrase's translations was changed
*
* @param kDBItem $object
* @return bool
*/
- function translationChanged(&$object)
+ function translationChanged($object)
{
- $changed_fields = array_keys( $object->GetChangedFields() );
- $translation_fields = Array ('Subject', 'Body');
+ $changed_fields = array_keys($object->GetChangedFields());
+ $translation_fields = Array ('Subject', 'HtmlBody', 'PlainTextBody');
foreach ($changed_fields as $changed_field) {
$changed_field = preg_replace('/^l[\d]+_/', '', $changed_field);
@@ -466,14 +489,14 @@
$object->setRequired($field_prefix . 'Address', $address_type > 0);
$address = $object->GetDBField($field_prefix . 'Address');
- if (!$address) {
+ if ( !$address ) {
// don't validate against empty address
- return ;
+ return;
}
switch ($address_type) {
case EmailEvent::ADDRESS_TYPE_EMAIL:
- if (!preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $address)) {
+ if ( !preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $address) ) {
$object->SetError($field_prefix . 'Address', 'invalid_email');
}
break;
@@ -482,7 +505,7 @@
$sql = 'SELECT PortalUserId
FROM ' . TABLE_PREFIX . 'Users
WHERE Username = ' . $this->Conn->qstr($address);
- if (!$this->Conn->GetOne($sql)) {
+ if ( !$this->Conn->GetOne($sql) ) {
$object->SetError($field_prefix . 'Address', 'invalid_user');
}
break;
@@ -491,7 +514,7 @@
$sql = 'SELECT GroupId
FROM ' . TABLE_PREFIX . 'UserGroups
WHERE Name = ' . $this->Conn->qstr($address);
- if (!$this->Conn->GetOne($sql)) {
+ if ( !$this->Conn->GetOne($sql) ) {
$object->SetError($field_prefix . 'Address', 'invalid_group');
}
break;
@@ -589,21 +612,26 @@
/**
* Validates subject and body fields of Email template
+ *
* @param kDBItem $object
+ * @return void
+ * @access protected
*/
- function _validateEmailTemplate(&$object)
+ protected function _validateEmailTemplate($object)
{
$this->parseField($object, 'Subject');
- $this->parseField($object, 'Body');
+ $this->parseField($object, 'HtmlBody');
+ $this->parseField($object, 'PlainTextBody');
}
/**
* Parses contents of given object field and sets error, when invalid in-portal tags found
* @param kDBItem $object
* @param string $field
* @return void
+ * @access protected
*/
- function parseField(&$object, $field)
+ protected function parseField($object, $field)
{
$this->Application->InitParser();
Index: branches/5.2.x/core/kernel/utility/email.php
===================================================================
diff -u -N -r15215 -r15222
--- branches/5.2.x/core/kernel/utility/email.php (.../email.php) (revision 15215)
+++ branches/5.2.x/core/kernel/utility/email.php (.../email.php) (revision 15222)
@@ -1,6 +1,6 @@
emailEvent->GetDBField('MessageType') == 'html';
- $message_body = $this->_getMessageBody($is_html);
+ $html_message_body = $this->_getMessageBody(true);
+ $plain_message_body = $this->_getMessageBody(false);
- if ( $message_body === false ) {
+ if ( $html_message_body === false && $plain_message_body === false ) {
+ trigger_error('Message template is empty (maybe after parsing).', E_USER_WARNING);
+
return false;
}
- $this->sender->CreateTextHtmlPart($message_body, $is_html);
+ if ( $html_message_body !== false ) {
+ $this->sender->CreateTextHtmlPart($html_message_body, true);
+ }
+
+ if ( $plain_message_body !== false ) {
+ $this->sender->CreateTextHtmlPart($plain_message_body, false);
+ }
+
$this->_changeLanguage(true);
// 3. set log
@@ -682,15 +691,14 @@
$design_key = $is_html ? 'html' : 'text';
if ( !isset($design_templates[$design_key]) ) {
- $primary_language_id = $this->Application->GetDefaultLanguageId();
+ $footer_email = $this->Application->recallObject('emailevents.footer', null, Array ('skip_autoload' => true));
+ /* @var $footer_email kDBItem */
- $sql = 'SELECT IF(l' . $this->params['language_id'] . '_Body <> "", l' . $this->params['language_id'] . '_Body, l' . $primary_language_id . '_Body)
- FROM ' . $this->emailEvent->TableName . '
- WHERE Event = "COMMON.FOOTER"';
- $footer = $this->Conn->GetOne($sql);
+ $footer_email->Load('COMMON.FOOTER', 'Event');
+ $footer = $footer_email->GetField($is_html ? 'HtmlBody' : 'PlainTextBody');
- if ( !$is_html ) {
- $footer = $this->sender->ConvertToText($footer);
+ if ( !$is_html && !$footer ) {
+ $footer = $this->sender->ConvertToText($footer_email->GetField('HtmlBody'));
}
$design_templates[$design_key] = '$body';
@@ -710,25 +718,22 @@
* @return bool|string
* @access protected
*/
- protected function _getMessageBody($is_html = true)
+ protected function _getMessageBody($is_html = false)
{
- $message_body = $this->emailEvent->GetField('Body');
+ $message_body = $this->emailEvent->GetField($is_html ? 'HtmlBody' : 'PlainTextBody');
- if ( !trim($message_body) ) {
- trigger_error('Message template is empty', E_USER_WARNING);
-
- return false;
+ if ( !trim($message_body) && !$is_html ) {
+ // no plain text part available -> make it from html part then
+ $message_body = $this->sender->ConvertToText($this->emailEvent->GetField('HtmlBody'));
}
- $message_body = $this->_applyMessageDesign($message_body, $is_html);
-
if ( !trim($message_body) ) {
- trigger_error('Message template is empty after parsing', E_USER_WARNING);
-
return false;
}
- return $message_body;
+ $message_body = $this->_applyMessageDesign($message_body, $is_html);
+
+ return trim($message_body) ? $message_body : false;
}
/**
Index: branches/5.2.x/core/admin_templates/regional/email_messages_edit.tpl
===================================================================
diff -u -N -r14572 -r15222
--- branches/5.2.x/core/admin_templates/regional/email_messages_edit.tpl (.../email_messages_edit.tpl) (revision 14572)
+++ branches/5.2.x/core/admin_templates/regional/email_messages_edit.tpl (.../email_messages_edit.tpl) (revision 15222)
@@ -21,19 +21,19 @@
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
-
+
a_toolbar.AddButton( new ToolBarButton('prev', '', function() {
go_to_id('emailevents', '');
}
));
-
+
a_toolbar.AddButton( new ToolBarButton('next', '', function() {
go_to_id('emailevents', '');
}
));
-
+
a_toolbar.Render();
-
+
a_toolbar.HideButton('prev');
a_toolbar.HideButton('next');
@@ -64,11 +64,11 @@
-
-
+
+
Index: branches/5.2.x/core/install/upgrades.php
===================================================================
diff -u -N -r15176 -r15222
--- branches/5.2.x/core/install/upgrades.php (.../upgrades.php) (revision 15176)
+++ branches/5.2.x/core/install/upgrades.php (.../upgrades.php) (revision 15222)
@@ -1,6 +1,6 @@
Application->recallObject('EmailMessageHelper');
/* @var $email_message_helper EmailMessageHelper */
-
foreach ($languages as $language_id) {
$sql = 'SELECT EmailMessageId, Template, EventId
FROM ' . TABLE_PREFIX . 'EmailMessage
WHERE LanguageId = ' . $language_id;
$translations = $this->Conn->Query($sql, 'EventId');
foreach ($translations as $event_id => $translation_data) {
- $parsed = $email_message_helper->parseTemplate($translation_data['Template']);
+ $parsed = $email_message_helper->parseTemplate($translation_data['Template'], 'html');
$fields_hash = Array (
'l' . $language_id . '_Subject' => $parsed['Subject'],
- 'l' . $language_id . '_Body' => $parsed['Body'],
+ 'l' . $language_id . '_Body' => $parsed['HtmlBody'],
);
- if ($parsed['Headers']) {
+ if ( $parsed['Headers'] ) {
$fields_hash['Headers'] = $parsed['Headers'];
}
@@ -2022,4 +2021,64 @@
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'PageContent', 'PageId = ' . $page_id);
}
}
+
+ /**
+ * Update to 5.2.0-B3; Introduces separate field for plain-text e-mail event translations
+ *
+ * @param string $mode when called mode {before, after)
+ */
+ public function Upgrade_5_2_0_B3($mode)
+ {
+ if ( $mode == 'before' ) {
+ $this->_renameTables('to');
+ }
+
+ if ( $mode == 'after' ) {
+ $id_field = $this->Application->getUnitOption('emailevents', 'IDField');
+ $table_name = $this->Application->getUnitOption('emailevents', 'TableName');
+ $fields = $this->Conn->Query('DESCRIBE ' . $table_name, 'Field');
+
+ if ( !isset($fields['l1_Body']) ) {
+ // column dropped - nothing to convert anymore
+ return;
+ }
+
+ $ml_helper = $this->Application->recallObject('kMultiLanguageHelper');
+ /* @var $ml_helper kMultiLanguageHelper */
+
+ $languages = $ml_helper->getLanguages();
+ $ml_helper->createFields('emailevents');
+
+ $sql = 'SELECT *
+ FROM ' . $table_name;
+ $email_events = $this->Conn->Query($sql);
+
+ // 1. move data to new columns
+ foreach ($email_events as $email_event) {
+ $fields_hash = Array ();
+ $translation_field = $email_event['MessageType'] == 'html' ? 'HtmlBody' : 'PlainTextBody';
+
+ foreach ($languages as $language_id) {
+ $fields_hash['l' . $language_id . '_' . $translation_field] = $email_event['l' . $language_id . '_Body'];
+ }
+
+ if ( $fields_hash ) {
+ $this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' = ' . $email_event[$id_field]);
+ }
+ }
+
+ // 2. drop old columns
+ $drops = Array ('DROP COLUMN MessageType');
+
+ foreach ($languages as $language_id) {
+ $lang_field = 'l' . $language_id . '_Body';
+
+ if ( isset($fields[$lang_field]) ) {
+ $drops[] = 'DROP COLUMN ' . $lang_field;
+ }
+ }
+
+ $this->Conn->Query('ALTER TABLE ' . $table_name . ' ' . implode(', ', $drops));
+ }
+ }
}
\ No newline at end of file
Index: branches/5.2.x/core/units/helpers/language_import_helper.php
===================================================================
diff -u -N -r15158 -r15222
--- branches/5.2.x/core/units/helpers/language_import_helper.php (.../language_import_helper.php) (revision 15158)
+++ branches/5.2.x/core/units/helpers/language_import_helper.php (.../language_import_helper.php) (revision 15222)
@@ -1,6 +1,6 @@
node. There are
-* two more nodes PHRASES and EVENTS for phrase and email event translations.
-*
-* v2
-* ==========
-* All data, that will end up in Language table is now attributes of LANGUAGE node
-* and is name exactly as field name, that will be used to store that data.
-*
-* v4
-* ==========
-* Hint & Column translation added to each phrase translation
-*/
+ * Language pack format version description
+ *
+ * v1
+ * ==========
+ * All language properties are separate nodes inside node. There are
+ * two more nodes PHRASES and EVENTS for phrase and email event translations.
+ *
+ * v2
+ * ==========
+ * All data, that will end up in Language table is now attributes of LANGUAGE node
+ * and is name exactly as field name, that will be used to store that data.
+ *
+ * v4
+ * ==========
+ * Hint & Column translation added to each phrase translation
+ *
+ * v5
+ * ==========
+ * Use separate xml nodes for subject, headers, html & plain translations
+ *
+ */
defined('FULL_PATH') or die('restricted access!');
@@ -101,6 +106,7 @@
var $_exportLimits = Array (
'phrases' => false,
'emailevents' => false,
+ 'country-state' => false,
);
/**
@@ -115,7 +121,7 @@
*
* @var int
*/
- var $_latestVersion = 4;
+ var $_latestVersion = 5;
/**
* Prefix-based serial numbers, that should be changed after import is finished
@@ -223,9 +229,6 @@
$export_fields = $this->_getExportFields();
- $email_message_helper = $this->Application->recallObject('EmailMessageHelper');
- /* @var $email_message_helper EmailMessageHelper */
-
// get languages
$sql = 'SELECT *
FROM ' . $this->Application->getUnitOption('lang','TableName') . '
@@ -271,25 +274,36 @@
ORDER BY `Event`, `Type`';
$events = $this->Conn->Query($sql, 'EventId');
- if (in_array('Core', $module_ids)) {
+ if ( in_array('Core', $module_ids) ) {
+ if ($this->_exportLimits['country-state']) {
+ $escaped_countries = $this->Conn->qstrArray($this->_exportLimits['country-state']);
+ $limit_where = '`IsoCode` IN (' . implode(',', $escaped_countries) . ')';
+ }
+ else {
+ $limit_where = 'TRUE';
+ }
+
+ $country_table = $this->Application->getUnitOption('country-state', 'TableName');
+
// countries
$sql = 'SELECT *
- FROM ' . $this->Application->getUnitOption('country-state', 'TableName') . '
- WHERE Type = ' . DESTINATION_TYPE_COUNTRY . '
+ FROM ' . $country_table . '
+ WHERE Type = ' . DESTINATION_TYPE_COUNTRY . ' AND ' . $limit_where . '
ORDER BY `IsoCode`';
$countries = $this->Conn->Query($sql, 'CountryStateId');
// states
- $sql = 'SELECT *
- FROM ' . $this->Application->getUnitOption('country-state', 'TableName') . '
- WHERE Type = ' . DESTINATION_TYPE_STATE . '
- ORDER BY `IsoCode`';
+ $sql = 'SELECT state.*
+ FROM ' . $country_table . ' state
+ JOIN ' . $country_table . ' country ON country.CountryStateId = state.StateCountryId
+ WHERE state.Type = ' . DESTINATION_TYPE_STATE . ' AND ' . str_replace('`IsoCode`', 'country.`IsoCode`', $limit_where) . '
+ ORDER BY state.`IsoCode`';
$states = $this->Conn->Query($sql, 'CountryStateId');
foreach ($states as $state_id => $state_data) {
$country_id = $state_data['StateCountryId'];
- if (!array_key_exists('States', $countries[$country_id])) {
+ if ( !array_key_exists('States', $countries[$country_id]) ) {
$countries[$country_id]['States'] = Array ();
}
@@ -364,30 +378,33 @@
if ($events) {
$ret .= "\t\t" . '' . "\n";
- foreach ($events as $event_id => $event) {
+ foreach ($events as $event_data) {
$fields_hash = Array (
- 'Headers' => $event['Headers'],
- 'Subject' => $event['l' . $language_id . '_Subject'],
- 'Body' => $event['l' . $language_id . '_Body'],
+ 'HEADERS' => $event_data['Headers'],
+ 'SUBJECT' => $event_data['l' . $language_id . '_Subject'],
+ 'HTMLBODY' => $event_data['l' . $language_id . '_HtmlBody'],
+ 'PLAINTEXTBODY' => $event_data['l' . $language_id . '_PlainTextBody'],
);
- $template = $email_message_helper->buildTemplate($fields_hash);
+ $data = '';
- if (!$template) {
- // email event is not translated on given language
- continue;
+ foreach ($fields_hash as $xml_node => $xml_content) {
+ if ( $xml_content ) {
+ $data .= "\t\t\t\t" . '<' . $xml_node . '>' . $this->_exportConvert($xml_content) . '' . $xml_node . '>' . "\n";
+ }
}
- $data = $this->_exportEncoding == 'base64' ? base64_encode($template) : '';
- $ret .= "\t\t\t" . '' . $data . ''."\n";
+ if ( $data ) {
+ $ret .= "\t\t\t" . '' . "\n" . $data . "\t\t\t" . '' . "\n";
+ }
}
$ret .= "\t\t" . '' . "\n";
}
if (in_array('Core', $module_ids) && $countries) {
$ret .= "\t\t" . '' . "\n";
- foreach ($countries as $country_id => $country_data) {
+ foreach ($countries as $country_data) {
$translation = $country_data['l' . $language_id . '_Name'];
if (!$translation) {
@@ -433,6 +450,18 @@
}
/**
+ * Converts string before placing into export file
+ *
+ * @param string $string
+ * @return string
+ * @access protected
+ */
+ protected function _exportConvert($string)
+ {
+ return $this->_exportEncoding == 'base64' ? base64_encode($string) : '';
+ }
+
+ /**
* Sets language pack encoding (not charset) used during export
*
* @param string $encoding
@@ -890,36 +919,39 @@
foreach ($events as $event_node) {
/* @var $event_node SimpleXMLElement */
+ $message_type = (string)$event_node['MessageType'];
$event_id = $this->_getEventId((string)$event_node['Event'], (int)$event_node['Type']);
if ( !$event_id ) {
continue;
}
- if ( $language_encoding == 'plain' ) {
- $template = rtrim($event_node);
- }
- else {
- $template = base64_decode($event_node);
- }
-
- $parsed = $email_message_helper->parseTemplate($template);
-
$fields_hash = Array (
'EventId' => $event_id,
'Event' => (string)$event_node['Event'],
'Type' => (int)$event_node['Type'],
- 'MessageType' => (string)$event_node['MessageType'],
);
+ if ( $message_type == '' ) {
+ $parsed = $email_message_helper->parseTemplate($event_node, '');
+ $parsed = array_map($language_encoding == 'plain' ? 'rtrim' : 'base64_decode', $parsed);
+
+ }
+ else {
+ $template = $language_encoding == 'plain' ? rtrim($event_node) : base64_decode($event_node);
+ $parsed = $email_message_helper->parseTemplate($template, $message_type);
+ }
+
if ( array_key_exists($event_id, $other_translations) ) {
$other_translations[$event_id]['l' . $language_id . '_Subject'] = $parsed['Subject'];
- $other_translations[$event_id]['l' . $language_id . '_Body'] = $parsed['Body'];
+ $other_translations[$event_id]['l' . $language_id . '_HtmlBody'] = $parsed['HtmlBody'];
+ $other_translations[$event_id]['l' . $language_id . '_PlainTextBody'] = $parsed['PlainTextBody'];
}
else {
$other_translations[$event_id] = Array (
'l' . $language_id . '_Subject' => $parsed['Subject'],
- 'l' . $language_id . '_Body' => $parsed['Body'],
+ 'l' . $language_id . '_HtmlBody' => $parsed['HtmlBody'],
+ 'l' . $language_id . '_PlainTextBody' => $parsed['PlainTextBody'],
);
}
Index: branches/5.2.x/core/units/phrases/phrases_config.php
===================================================================
diff -u -N -r15116 -r15222
--- branches/5.2.x/core/units/phrases/phrases_config.php (.../phrases_config.php) (revision 15116)
+++ branches/5.2.x/core/units/phrases/phrases_config.php (.../phrases_config.php) (revision 15222)
@@ -1,6 +1,6 @@
Array ('type' => 'string', 'default' => ''),
'ExportEmailEvents' => Array ('type' => 'string', 'default' => ''),
+ 'ExportCountries' => Array ('type' => 'string', 'default' => ''),
+ 'ExportDataTypes' => Array (
+ 'type' => 'string',
+ 'formatter' => 'kOptionsFormatter', 'options' => Array ('phrases' => 'la_opt_Phrases', 'emailevents' => 'la_opt_EmailEvents', 'country-state' => 'la_opt_Countries'), 'use_phrases' => 1, 'multiple' => 1,
+ 'default' => '|phrases|emailevents|country-state|'
+ ),
),
'Grids' => Array (
Index: branches/5.2.x/core/admin_templates/regional/languages_export.tpl
===================================================================
diff -u -N -r15116 -r15222
--- branches/5.2.x/core/admin_templates/regional/languages_export.tpl (.../languages_export.tpl) (revision 15116)
+++ branches/5.2.x/core/admin_templates/regional/languages_export.tpl (.../languages_export.tpl) (revision 15222)
@@ -32,6 +32,7 @@
+
@@ -47,6 +48,7 @@
+
@@ -116,6 +118,7 @@
+
Index: branches/5.2.x/core/units/phrases/phrases_event_handler.php
===================================================================
diff -u -N -r15145 -r15222
--- branches/5.2.x/core/units/phrases/phrases_event_handler.php (.../phrases_event_handler.php) (revision 15145)
+++ branches/5.2.x/core/units/phrases/phrases_event_handler.php (.../phrases_event_handler.php) (revision 15222)
@@ -1,6 +1,6 @@
Special == 'import' || $event->Special == 'export' ) {
$this->RemoveRequiredFields($object);
- $object->setRequired(Array ('LangFile', 'PhraseType', 'Module'));
+ $object->setRequired(Array ('ExportDataTypes', 'LangFile', 'PhraseType', 'Module'));
// allow multiple phrase types to be selected during import/export
$object->SetFieldOption('PhraseType', 'type', 'string');
@@ -167,6 +167,12 @@
if ( $event->Special == 'export' || $event->Special == 'import' ) {
$object->SetDBField('PhraseType', '|0|1|2|');
$object->SetDBField('Module', '|' . implode('|', array_keys($this->Application->ModuleInfo)) . '|');
+
+ $export_mode = $this->Application->GetVar('export_mode');
+
+ if ( $export_mode != 'lang' ) {
+ $object->SetDBField('ExportDataTypes', '|' . $export_mode . '|');
+ }
}
}
Index: branches/5.2.x/core/units/languages/languages_event_handler.php
===================================================================
diff -u -N -r15145 -r15222
--- branches/5.2.x/core/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 15145)
+++ branches/5.2.x/core/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 15222)
@@ -1,6 +1,6 @@
Application->getUnitOption('emailevents', 'TableName') . '
SET
l' . $dst_language . '_Subject = l' . $src_language . '_Subject,
- l' . $dst_language . '_Body = l' . $src_language . '_Body';
+ l' . $dst_language . '_HtmlBody = l' . $src_language . '_HtmlBody,
+ l' . $dst_language . '_PlainTextBody = l' . $src_language . '_PlainTextBody';
$this->Conn->Query($sql);
}
@@ -549,15 +550,26 @@
$language_import_helper->setExportEncoding('plain');
}
+ $data_types = Array (
+ 'phrases' => 'ExportPhrases',
+ 'emailevents' => 'ExportEmailEvents',
+ 'country-state' => 'ExportCountries'
+ );
+
$export_mode = $this->Application->GetVar('export_mode');
+ $allowed_data_types = explode('|', substr($field_values['ExportDataTypes'], 1, -1));
if ( $export_mode == $event->Prefix ) {
- $language_import_helper->setExportLimit('phrases', $field_values['ExportPhrases']);
- $language_import_helper->setExportLimit('emailevents', $field_values['ExportEmailEvents']);
+ foreach ($data_types as $prefix => $export_limit_field) {
+ $export_limit = in_array($prefix, $allowed_data_types) ? $field_values[$export_limit_field] : '-';
+ $language_import_helper->setExportLimit($prefix, $export_limit);
+ }
}
else {
- $language_import_helper->setExportLimit($export_mode);
- $language_import_helper->setExportLimit($export_mode == 'phrases' ? 'emailevents' : 'phrases', '-');
+ foreach ($data_types as $prefix => $export_limit_field) {
+ $export_limit = in_array($prefix, $allowed_data_types) ? null : '-';
+ $language_import_helper->setExportLimit($prefix, $export_limit);
+ }
}
$lang_ids = explode(',', $this->Application->RecallVar('export_language_ids'));
@@ -621,7 +633,8 @@
// clean EmailEvents table
$fields_hash = Array (
'l' . $object->GetID() . '_Subject' => NULL,
- 'l' . $object->GetID() . '_Body' => NULL,
+ 'l' . $object->GetID() . '_HtmlBody' => NULL,
+ 'l' . $object->GetID() . '_PlainTextBody' => NULL,
);
$this->Conn->doUpdate($fields_hash, $this->Application->getUnitOption('emailevents', 'TableName'), 1);
Index: branches/5.2.x/core/admin_templates/languages/email_message_settings.tpl
===================================================================
diff -u -N -r14941 -r15222
--- branches/5.2.x/core/admin_templates/languages/email_message_settings.tpl (.../email_message_settings.tpl) (revision 14941)
+++ branches/5.2.x/core/admin_templates/languages/email_message_settings.tpl (.../email_message_settings.tpl) (revision 15222)
@@ -92,15 +92,14 @@
-
+
-
Index: branches/5.2.x/core/units/email_events/email_events_config.php
===================================================================
diff -u -N -r15116 -r15222
--- branches/5.2.x/core/units/email_events/email_events_config.php (.../email_events_config.php) (revision 15116)
+++ branches/5.2.x/core/units/email_events/email_events_config.php (.../email_events_config.php) (revision 15222)
@@ -1,6 +1,6 @@
1, 'default' => null
),
- 'Body' => Array (
+ 'HtmlBody' => Array (
'type' => 'string',
'formatter' => 'kMultiLanguage', 'db_type' => 'longtext',
'error_msgs' => Array ('parsing_error' => '!la_error_ParsingError!'),
- 'required' => 1, 'default' => null
+ 'default' => null
),
- 'MessageType' => Array (
+ 'PlainTextBody' => Array (
'type' => 'string',
- 'formatter' => 'kOptionsFormatter', 'options' => Array ('text' => 'la_Text', 'html' => 'la_Html'), 'use_phrases' => 1,
- 'not_null' => 1, 'required' => 1, 'default' => 'text'
+ 'formatter' => 'kMultiLanguage', 'db_type' => 'longtext',
+ 'error_msgs' => Array ('parsing_error' => '!la_error_ParsingError!'),
+ 'default' => null
),
'Enabled' => Array (
Index: branches/5.2.x/core/units/helpers/email_message_helper.php
===================================================================
diff -u -N -r14748 -r15222
--- branches/5.2.x/core/units/helpers/email_message_helper.php (.../email_message_helper.php) (revision 14748)
+++ branches/5.2.x/core/units/helpers/email_message_helper.php (.../email_message_helper.php) (revision 15222)
@@ -1,6 +1,6 @@
'', 'Headers' => '', 'HtmlBody' => '', 'PlainTextBody' => '');
+
+ if ( $message_type == '' ) {
+ // this is v5+ e-mail event text as xml node
+ foreach ($ret as $field => $value) {
+ $node_name = strtoupper($field);
+ $ret[$field] = (string)$text->$node_name;
+ }
+
+ return $ret;
+ }
+
$line_id = 1;
- $ret = Array ('Subject' => '', 'Headers' => '', 'Body' => '');
$headers = Array();
$lines = explode("\n", $text); // "\n" is lost in process
foreach ($lines as $line_id => $line) {
- if (strlen(trim($line)) == 0 || ($line == '.')) {
+ if ( strlen(trim($line)) == 0 || ($line == '.') ) {
break;
}
$parts = explode(':', $line, 2);
- if (strtolower($parts[0]) == 'subject') {
+
+ if ( strtolower($parts[0]) == 'subject' ) {
$ret['Subject'] = trim($parts[1]);
}
else {
@@ -48,7 +61,7 @@
$lines = array_slice($lines, $line_id + 1);
// add "\n", that was lost before
- $ret['Body'] = implode("\n", $lines);
+ $ret[$message_type == 'html' ? 'HtmlBody' : 'PlainTextBody'] = implode("\n", $lines);
return $ret;
}
Index: branches/5.2.x/admin/system_presets/simple/email_events_emailevents.php
===================================================================
diff -u -N -r15116 -r15222
--- branches/5.2.x/admin/system_presets/simple/email_events_emailevents.php (.../email_events_emailevents.php) (revision 15116)
+++ branches/5.2.x/admin/system_presets/simple/email_events_emailevents.php (.../email_events_emailevents.php) (revision 15222)
@@ -28,7 +28,7 @@
$hidden_fields = Array (
/*'EventId', 'Event', 'ReplacementTags', 'AllowChangingSender', 'CustomSender',
'SenderName', 'SenderAddressType', 'SenderAddress', 'AllowChangingRecipient',
- 'CustomRecipient', 'Recipients', 'Subject', 'Body', 'Headers', 'MessageType',
+ 'CustomRecipient', 'Recipients', 'Subject', 'HtmlBody', 'PlainTextBody', 'Headers',
'Enabled', 'FrontEndOnly', 'Module', 'Description', 'Type'*/
);
@@ -42,7 +42,7 @@
$required_fields = Array (
/*'EventId',*/ 'Event', /*'ReplacementTags', 'AllowChangingSender', 'CustomSender',
'SenderName', 'SenderAddressType', 'SenderAddress', 'AllowChangingRecipient',
- 'CustomRecipient', 'Recipients',*/ 'Subject', 'Body', /*'Headers',*/ 'MessageType',
+ 'CustomRecipient', 'Recipients',*/ 'Subject', /*'HtmlBody', 'PlainTextBody', 'Headers',*/
/*'Enabled', 'FrontEndOnly',*/ 'Module', /*'Description',*/ 'Type'
);
Index: branches/5.2.x/core/install/english.lang
===================================================================
diff -u -N -r15110 -r15222
--- branches/5.2.x/core/install/english.lang (.../english.lang) (revision 15110)
+++ branches/5.2.x/core/install/english.lang (.../english.lang) (revision 15222)
@@ -1,4 +1,4 @@
-
+
QWN0aXZl
@@ -397,6 +397,8 @@
RXZlbnQ=
RXhwaXJl
RXhwb3J0IGNvbHVtbnM=
+ RXhwb3J0IFNwZWNpZmllZCBDb3VudHJpZXM=
+ RGF0YSBUeXBlcyB0byBFeHBvcnQ=
RXhwb3J0IFNwZWNpZmllZCBFbWFpbCBFdmVudHM=
RXhwb3J0IEZpbGVuYW1l
RXhwb3J0IGZvcm1hdA==
@@ -758,6 +760,7 @@
Q29tbWE=
Q29tbWVudCBUZXh0
Q29va2llcw==
+ Q291bnRyaWVz
Q291bnRyeQ==
Q3JlYXRlZCBPbg==
Q3VycmVudCBEb21haW4=
@@ -773,6 +776,7 @@
RWRpdG9yJ3MgUGljaw==
RS1tYWls
RS1tYWlsIEJvZHk=
+ RS1tYWlsIEV2ZW50cw==
RS1tYWlsIFN1YmplY3Q=
RXZlcnlvbmU=
RXhhY3Q=
@@ -802,6 +806,7 @@
UGFydGlhbGx5IFByb2Nlc3NlZA==
UGVuZGluZw==
UGhvbmU=
+ TGFiZWxz
UG9wdXAgV2luZG93
UHJvY2Vzc2Vk
UHVibGlzaGVk
@@ -1580,44 +1585,158 @@
VmFsaWQ=
- U3ViamVjdDogTmV3IENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIC0gQWRkZWQKCllvdXIgc3VnZ2VzdGVkIGNhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGhhcyBiZWVuIGFkZGVkLg==
- U3ViamVjdDogTmV3IENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIFN1Ym1pdHRlZCBieSBVc2VycwoKQSBjYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBhZGRlZC4=
- U3ViamVjdDogU3VnZ2VzdGVkIENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIFBlbmRpbmcKClRoZSBjYXRlZ29yeSB5b3Ugc3VnZ2VzdGVkICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIHBlbmRpbmcgZm9yIGFkbWluaXN0cmF0aXZlIGFwcHJvdmFsLg0KDQpUaGFuayB5b3Uh
- U3ViamVjdDogU3VnZ2VzdGVkIENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIFBlbmRpbmcKCkEgY2F0ZWdvcnkgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaGFzIGJlZW4gYWRkZWQsIHBlbmRpbmcgeW91ciBjb25maXJtYXRpb24uICBQbGVhc2UgcmV2aWV3IHRoZSBjYXRlZ29yeSBhbmQgYXBwcm92ZSBvciBkZW55IGl0Lg==
- U3ViamVjdDogQSBjYXRlZ29yeSBoYXMgYmVlbiBhcHByb3ZlZAoKWW91ciBzdWdnZXN0ZWQgY2F0ZWdvcnkgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaGFzIGJlZW4gYXBwcm92ZWQu
- U3ViamVjdDogWW91ciBDYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBEZW5pZWQKCllvdXIgY2F0ZWdvcnkgc3VnZ2VzdGlvbiAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBkZW5pZWQu
- U3ViamVjdDogQ29tbW9uIEZvb3RlciBUZW1wbGF0ZQoKPGJyLz48YnIvPg0KDQpTaW5jZXJlbHksPGJyLz48YnIvPg0KDQpXZWJzaXRlIGFkbWluaXN0cmF0aW9uLg==
- U3ViamVjdDogTmV3IEVtYWlsIFJFUExZIFJlY2VpdmVkIGluICJGZWVkYmFjayBNYW5hZ2VyIiAoPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRmllbGQgbmFtZT0iRm9ybVN1Ym1pc3Npb25JZCIvPikKCk5ldyBFbWFpbCBSRVBMWSBSZWNlaXZlZCBpbiAmcXVvdDtGZWVkYmFjayBNYW5hZ2VyJnF1b3Q7LjxiciAvPg0KPGJyIC8+DQpPcmlnaW5hbCBGZWVkYmFja0lkOiA8aW5wMjpmb3Jtc3Vicy4taXRlbV9GaWVsZCBuYW1lPSJGb3JtU3VibWlzc2lvbklkIi8+IDxiciAvPg0KT3JpZ2luYWwgU3ViamVjdDogPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRm9ybUZpZWxkIHJvbGU9InN1YmplY3QiLz4gPGJyIC8+DQo8YnIgLz4NClBsZWFzZSBwcm9jZWVkIHRvIHRoZSBBZG1pbiBDb25zb2xlIGluIG9yZGVyIHRvIHJldmlldyBhbmQgcmVwbHkgdG8gdGhlIHVzZXIu
- U3ViamVjdDogTmV3IEVtYWlsIC0gRGVsaXZlcnkgRmFpbHVyZSBSZWNlaXZlZCBpbiAiRmVlZGJhY2sgTWFuYWdlciIgKDxpbnAyOmZvcm1zdWJzLi1pdGVtX0ZpZWxkIG5hbWU9IkZvcm1TdWJtaXNzaW9uSWQiLz4pCgpOZXcgRW1haWwgRGVsaXZlcnkgRmFpbHVyZSBSZWNlaXZlZCBpbiAmcXVvdDtGZWVkYmFjayBNYW5hZ2VyJnF1b3Q7LjxiciAvPg0KPGJyIC8+DQpPcmlnaW5hbCBGZWVkYmFja0lkOiA8aW5wMjpmb3Jtc3Vicy4taXRlbV9GaWVsZCBuYW1lPSJGb3JtU3VibWlzc2lvbklkIi8+IDxiciAvPg0KT3JpZ2luYWwgU3ViamVjdDogPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRm9ybUZpZWxkIHJvbGU9InN1YmplY3QiLz4gPGJyIC8+DQo8YnIgLz4NClBsZWFzZSBwcm9jZWVkIHRvIHRoZSBBZG1pbiBDb25zb2xlIGluIG9yZGVyIHRvIHJldmlldyBhbmQgcmVwbHkgdG8gdGhlIHVzZXIu
- U3ViamVjdDogPGlucDI6bV9QYXJhbSBuYW1lPSJzdWJqZWN0Ii8+ICN2ZXJpZnk8aW5wMjpzdWJtaXNzaW9uLWxvZ19GaWVsZCBuYW1lPSJWZXJpZnlDb2RlIi8+Cgo8aW5wMjptX1BhcmFtIG5hbWU9Im1lc3NhZ2UiLz4=
- U3ViamVjdDogVGhhbmsgWW91IGZvciBDb250YWN0aW5nIFVzIQoKPHA+VGhhbmsgeW91IGZvciBjb250YWN0aW5nIHVzLiBXZSdsbCBiZSBpbiB0b3VjaCB3aXRoIHlvdSBzaG9ydGx5ITwvcD4=
- U3ViamVjdDogTmV3IGZvcm0gc3VibWlzc2lvbgoKPHA+Rm9ybSBoYXMgYmVlbiBzdWJtaXR0ZWQuIFBsZWFzZSBwcm9jZWVkIHRvIHRoZSBBZG1pbiBDb25zb2xlIHRvIHJldmlldyB0aGUgc3VibWlzc2lvbiE8L3A+
- U3ViamVjdDogUm9vdCBSZXNldCBQYXNzd29yZAoKWW91ciBuZXcgcGFzc3dvcmQgaXM6IDxpbnAyOm1fUGFyYW0gbmFtZT0icGFzc3dvcmQiLz4=
- U3ViamVjdDogSW4tcG9ydGFsIHJlZ2lzdHJhdGlvbgoKRGVhciA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIgLz4gPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJMYXN0TmFtZSIgLz4sDQoNClRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9CYXNlVXJsLz4uIFlvdXIgcmVnaXN0cmF0aW9uIGlzIG5vdyBhY3RpdmUuDQo8aW5wMjptX2lmIGNoZWNrPSJ1LnJlZ2lzdGVyX0ZpZWxkIiBuYW1lPSJFbWFpbCI+DQo8YnIvPjxici8+DQpQbGVhc2UgY2xpY2sgaGVyZSB0byB2ZXJpZnkgeW91ciBFLW1haWwgYWRkcmVzczoNCjxhIGhyZWY9IjxpbnAyOnUucmVnaXN0ZXJfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+Ij48aW5wMjp1LnJlZ2lzdGVyX0NvbmZpcm1QYXNzd29yZExpbmsgdD0icGxhdGZvcm0vbXlfYWNjb3VudC92ZXJpZnlfZW1haWwiIG5vX2FtcD0iMSIvPjwvYT48YnIvPjxici8+DQo8L2lucDI6bV9pZj4=
- U3ViamVjdDogTmV3IFVzZXIgUmVnaXN0cmF0aW9uICg8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KQoKQSBuZXcgdXNlciAiPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSdVc2VybmFtZScvPiIgaGFzIGJlZW4gYWRkZWQu
- U3ViamVjdDogTmV3IHVzZXIgaGFzIGJlZW4gY3JlYXRlZAoKRGVhciA8aW5wMjp1X0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIvPiwNCg0KQSBuZXcgdXNlciBoYXMgYmVlbiBjcmVhdGVkIGFuZCBhc3NpZ25lZCB0byB5b3UNCg0KTm93IHlvdSBjYW4gbG9naW4gdXNpbmcgdGhlIGZvbGxvd2luZyBjcmVkZW50aWFsczoNCg0KPGlucDI6bV9pZiBjaGVjaz0idV9GaWVsZCIgbmFtZT0iVXNlcm5hbWUiPlVzZXJuYW1lOiA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+PGlucDI6bV9lbHNlLz5FLW1haWw6IDxpbnAyOnVfRmllbGQgbmFtZT0iRW1haWwiLz48L2lucDI6bV9pZj4gDQpQYXNzd29yZDogPGlucDI6dV9GaWVsZCBuYW1lPSJQYXNzd29yZF9wbGFpbiIvPiANCg==
- U3ViamVjdDogTmV3IFVzZXIgUmVnaXN0cmF0aW9uICg8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+PGlucDI6bV9pZiBjaGVjaz0ibV9HZXRDb25maWciIG5hbWU9IlVzZXJfQWxsb3dfTmV3IiBlcXVhbHNfdG89IjQiPiAtIEFjdGl2YXRpb24gRW1haWw8L2lucDI6bV9pZj4pCgpEZWFyIDxpbnAyOnUucmVnaXN0ZXJfRmllbGQgbmFtZT0iRmlyc3ROYW1lIiAvPiA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9Ikxhc3ROYW1lIiAvPiw8YnIgLz4NCjxiciAvPg0KPGlucDI6bV9pZiBjaGVjaz0ibV9HZXRDb25maWciIG5hbWU9IlVzZXJfQWxsb3dfTmV3IiBlcXVhbHNfdG89IjQiPg0KCVRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPiB3ZWJzaXRlLiBUbyBhY3RpdmF0ZSB5b3VyIHJlZ2lzdHJhdGlvbiBwbGVhc2UgZm9sbG93IGxpbmsgYmVsb3cuIDxpbnAyOnUucmVnaXN0ZXJfQWN0aXZhdGlvbkxpbmsgdGVtcGxhdGU9InBsYXRmb3JtL2xvZ2luL2FjdGl2YXRlX2NvbmZpcm0iLz4NCjxpbnAyOm1fZWxzZS8+DQoJVGhhbmsgeW91IGZvciByZWdpc3RlcmluZyBvbiA8aW5wMjptX0xpbmsgdGVtcGxhdGU9ImluZGV4Ii8+IHdlYnNpdGUuIFlvdXIgcmVnaXN0cmF0aW9uIHdpbGwgYmUgYWN0aXZlIGFmdGVyIGFwcHJvdmFsLiANCgkNCgk8aW5wMjptX2lmIGNoZWNrPSJ1LnJlZ2lzdGVyX0ZpZWxkIiBuYW1lPSJFbWFpbCI+DQoJCTxici8+PGJyLz4NCgkJUGxlYXNlIGNsaWNrIGhlcmUgdG8gdmVyaWZ5IHlvdXIgRS1tYWlsIGFkZHJlc3M6DQoJCTxhIGhyZWY9IjxpbnAyOnUucmVnaXN0ZXJfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+Ij48aW5wMjp1LnJlZ2lzdGVyX0NvbmZpcm1QYXNzd29yZExpbmsgdD0icGxhdGZvcm0vbXlfYWNjb3VudC92ZXJpZnlfZW1haWwiIG5vX2FtcD0iMSIvPjwvYT48YnIvPjxici8+DQoJPC9pbnAyOm1faWY+DQo8L2lucDI6bV9pZj4=
- U3ViamVjdDogTmV3IFVzZXIgUmVnaXN0ZXJlZAoKQSBuZXcgdXNlciAiPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIHJlZ2lzdGVyZWQgYW5kIGlzIHBlbmRpbmcgYWRtaW5pc3RyYXRpdmUgYXBwcm92YWwu
- U3ViamVjdDogWW91ciBBY2NvdW50IGlzIEFjdGl2ZQoKV2VsY29tZSB0byA8aW5wMjptX0Jhc2VVcmwvPiENCg0KWW91ciB1c2VyIHJlZ2lzdHJhdGlvbiBoYXMgYmVlbiBhcHByb3ZlZC4gWW91ciB1c2VyIG5hbWUgaXM6ICI8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+Ii4=
- U3ViamVjdDogTmV3IFVzZXIgQWNjb3VudCAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgd2FzIEFwcHJvdmVkCgpVc2VyICI8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+IiBoYXMgYmVlbiBhcHByb3ZlZC4=
- U3ViamVjdDogWW91ciBSZWdpc3RyYXRpb24gaGFzIGJlZW4gRGVuaWVkCgpZb3VyIHJlZ2lzdHJhdGlvbiBvbiA8YSBocmVmPSI8aW5wMjptX0Jhc2VVcmwvPiI+PGlucDI6bV9CYXNlVXJsLz48L2E+IHdlYnNpdGUgaGFzIGJlZW4gZGVuaWVkLg==
- U3ViamVjdDogVXNlciBSZWdpc3RyYXRpb24gZm9yICAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gRGVuaWVkCgpVc2VyICI8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+IiBoYXMgYmVlbiBkZW5pZWQu
- U3ViamVjdDogQ2hhbmdlZCBFLW1haWwgUm9sbGJhY2sKCkhlbGxvLDxici8+PGJyLz4NCg0KSXQgc2VlbXMgdGhhdCB5b3UgaGF2ZSBjaGFuZ2VkIGUtbWFpbCBpbiB5b3VyIEluLXBvcnRhbCBhY2NvdW50LiBZb3UgbWF5IHVuZG8gdGhpcyBjaGFuZ2UgYnkgY2xpY2tpbmcgb24gdGhlIGxpbmsgYmVsb3c6PGJyLz48YnIvPg0KDQo8YSBocmVmPSI8aW5wMjp1X1VuZG9FbWFpbENoYW5nZUxpbmsgdGVtcGxhdGU9InBsYXRmb3JtL215X2FjY291bnQvcmVzdG9yZV9lbWFpbCIvPiI+PGlucDI6dV9VbmRvRW1haWxDaGFuZ2VMaW5rIHRlbXBsYXRlPSJwbGF0Zm9ybS9teV9hY2NvdW50L3Jlc3RvcmVfZW1haWwiLz48L2E+PGJyLz48YnIvPg0KDQpJZiB5b3UgYmVsaWV2ZSB5b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGVtYWlsIGluIGVycm9yLCBwbGVhc2UgaWdub3JlIHRoaXMgZW1haWwuIFlvdXIgYWNjb3VudCB3aWxsIGJlIGxpbmtlZCB0byBhbm90aGVyIGUtbWFpbCB1bmxlc3MgeW91IGhhdmUgY2xpY2tlZCBvbiB0aGUgYWJvdmUgbGluay4=
- U3ViamVjdDogQ2hhbmdlZCBFLW1haWwgVmVyaWZpY2F0aW9uCgpIZWxsbyw8YnIvPjxici8+DQoNCkl0IHNlZW1zIHRoYXQgeW91IGhhdmUgY2hhbmdlZCBlLW1haWwgaW4geW91ciBJbi1wb3J0YWwgYWNjb3VudC4gUGxlYXNlIHZlcmlmeSB0aGlzIG5ldyBlLW1haWwgYnkgY2xpY2tpbmcgb24gdGhlIGxpbmsgYmVsb3c6PGJyLz48YnIvPg0KDQo8YSBocmVmPSI8aW5wMjp1X0NvbmZpcm1QYXNzd29yZExpbmsgdD0icGxhdGZvcm0vbXlfYWNjb3VudC92ZXJpZnlfZW1haWwiIG5vX2FtcD0iMSIvPiI+PGlucDI6dV9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz48L2E+PGJyLz48YnIvPg0KDQpJZiB5b3UgYmVsaWV2ZSB5b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGVtYWlsIGluIGVycm9yLCBwbGVhc2UgaWdub3JlIHRoaXMgZW1haWwuIFlvdXIgZW1haWwgd2lsbCBub3QgZ2V0IHZlcmlmaWVkIHN0YXR1cyB1bmxlc3MgeW91IGhhdmUgY2xpY2tlZCBvbiB0aGUgYWJvdmUgbGluay4NCg==
- U3ViamVjdDogTWVtYmVyc2hpcCBFeHBpcmF0aW9uIE5vdGljZQoKWW91ciBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fQmFzZVVybC8+IHdlYnNpdGUgd2lsbCBzb29uIGV4cGlyZS4=
- U3ViamVjdDogTWVtYmVyc2hpcCBFeHBpcmF0aW9uIE5vdGljZSBmb3IgIjxpbnAyOnVfRmllbGQgbmFtZT0iVXNlcm5hbWUiLz4iIFNlbnQKClVzZXIgPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiBtZW1iZXJzaGlwIHdpbGwgZXhwaXJlIHNvb24u
- U3ViamVjdDogWW91ciBNZW1iZXJzaGlwIEV4cGlyZWQKCllvdXIgbWVtYmVyc2hpcCBvbiA8aW5wMjptX0Jhc2VVcmwvPiB3ZWJzaXRlIGhhcyBleHBpcmVkLg==
- U3ViamVjdDogVXNlcidzIE1lbWJlcnNoaXAgRXhwaXJlZCAgKCA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KQoKVXNlcidzICg8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KSBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fQmFzZVVybC8+IHdlYnNpdGUgaGFzIGV4cGlyZWQu
- U3ViamVjdDogTmV3IHBhc3N3b3JkIGdlbmVyYXRlZAoKRGVhciA8aW5wMjp1X0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIvPiwNCg0KQSBuZXcgcGFzc3dvcmQgaGFzIGJlZW4gZ2VuZXJhdGVkIGZvciB5b3VyIHVzZXIuDQoNCk5vdyB5b3UgY2FuIGxvZ2luIHVzaW5nIHRoZSBmb2xsb3dpbmcgY3JlZGVudGlhbHM6DQoNCjxpbnAyOm1faWYgY2hlY2s9InVfRmllbGQiIG5hbWU9IlVzZXJuYW1lIj5Vc2VybmFtZTogPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPjxpbnAyOm1fZWxzZS8+RS1tYWlsOiA8aW5wMjp1X0ZpZWxkIG5hbWU9IkVtYWlsIi8+PC9pbnAyOm1faWY+IA0KUGFzc3dvcmQ6IDxpbnAyOnVfRmllbGQgbmFtZT0iUGFzc3dvcmRfcGxhaW4iLz4g
- U3ViamVjdDogUmVzZXQgUGFzc3dvcmQgQ29uZmlybWF0aW9uCgpIZWxsbyw8YnIvPjxici8+DQoNCkl0IHNlZW1zIHRoYXQgeW91IGhhdmUgcmVxdWVzdGVkIGEgcGFzc3dvcmQgcmVzZXQgZm9yIHlvdXIgSW4tcG9ydGFsIGFjY291bnQuIElmIHlvdSB3b3VsZCBsaWtlIHRvIHByb2NlZWQgYW5kIGNoYW5nZSB0aGUgcGFzc3dvcmQsIHBsZWFzZSBjbGljayBvbiB0aGUgbGluayBiZWxvdzo8YnIvPjxici8+DQoNCjxhIGhyZWY9IjxpbnAyOnVfQ29uZmlybVBhc3N3b3JkTGluayBub19hbXA9IjEiLz4iPjxpbnAyOnVfQ29uZmlybVBhc3N3b3JkTGluayBub19hbXA9IjEiLz48L2E+PGJyLz48YnIvPg0KDQpZb3Ugd2lsbCByZWNlaXZlIGEgc2Vjb25kIGVtYWlsIHdpdGggeW91ciBuZXcgcGFzc3dvcmQgc2hvcnRseS48YnIvPjxici8+DQoNCklmIHlvdSBiZWxpZXZlIHlvdSBoYXZlIHJlY2VpdmVkIHRoaXMgZW1haWwgaW4gZXJyb3IsIHBsZWFzZSBpZ25vcmUgdGhpcyBlbWFpbC4gWW91ciBwYXNzd29yZCB3aWxsIG5vdCBiZSBjaGFuZ2VkIHVubGVzcyB5b3UgaGF2ZSBjbGlja2VkIG9uIHRoZSBhYm92ZSBsaW5rLg0K
- U3ViamVjdDogU3Vic2NyaWJlZCB0byBhIE1haWxpbmcgTGlzdCBvbiA8aW5wMjptX0Jhc2VVcmwvPgoKWW91IGhhdmUgc3Vic2NyaWJlZCB0byBhIG1haWxpbmcgbGlzdCBvbiA8aW5wMjptX0Jhc2VVcmwvPiB3ZWJzaXRlLg==
- U3ViamVjdDogTmV3IFVzZXIgaGFzIFN1YnNjcmliZWQgdG8gYSBNYWxsaW5nIExpc3QKCk5ldyB1c2VyIDxpbnAyOnVfRmllbGQgbmFtZT0iRW1haWwiLz4gaGFzIHN1YnNjcmliZWQgdG8gYSBtYWlsaW5nIGxpc3Qgb24gPGEgaHJlZj0iPGlucDI6bV9CYXNlVXJsLz4iPjxpbnAyOm1fQmFzZVVybC8+PC9hPiB3ZWJzaXRlLg==
- U3ViamVjdDogQ2hlY2sgb3V0IHRoaXMgV2Vic2l0ZQoKSGVsbG8sPC9icj48L2JyPg0KDQpUaGlzIG1lc3NhZ2UgaGFzIGJlZW4gc2VudCB0byB5b3UgZnJvbSBvbmUgb2YgeW91ciBmcmllbmRzLjwvYnI+PC9icj4NCkNoZWNrIG91dCB0aGlzIHNpdGU6IDxhIGhyZWY9IjxpbnAyOm1fQmFzZVVybC8+Ij48aW5wMjptX0Jhc2VVcmwvPjwvYT4h
- U3ViamVjdDogV2Vic2l0ZSBTdWdnZXN0ZWQgdG8gYSBGcmllbmQKCkEgdmlzaXRvciBzdWdnZXN0ZWQgPGEgaHJlZj0iPGlucDI6bV9CYXNlVXJsLz4iPjxpbnAyOm1fQmFzZVVybC8+PC9hPiB3ZWJzaXRlIHRvIGEgZnJpZW5kLg==
- U3ViamVjdDogWW91IGhhdmUgYmVlbiB1bnN1YnNjcmliZWQKCllvdSBoYXZlIHN1Y2Nlc3NmdWxseSB1bnN1YnNjcmliZWQgZnJvbSB0aGUgbWFpbGluZyBsaXN0IG9uIDxhIGhyZWY9IjxpbnAyOm1fQmFzZVVybCAvPiI+PGlucDI6bV9CYXNlVXJsIC8+PC9hPiB3ZWJzaXRlLg==
- U3ViamVjdDogVXNlciBVbnN1YnNyaWJlZCBmcm9tIE1haWxpbmcgTGlzdAoKQSB1c2VyICI8aW5wMjp1X0ZpZWxkIG5hbWU9IkVtYWlsIi8+IiBoYXMgdW5zdWJzY3JpYmVkIGZyb20gdGhlIG1haWxpbmcgbGlzdCBvbiA8YSBocmVmPSI8aW5wMjptX0Jhc2VVcmwvPiI+PGlucDI6bV9CYXNlVXJsLz48L2E+Lg==
- U3ViamVjdDogVXNlciBSZWdpc3RyYXRpb24gaXMgVmFsaWRhdGVkCgpXZWxjb21lIHRvIEluLXBvcnRhbCE8YnIvPjxici8+DQoNCllvdXIgdXNlciByZWdpc3RyYXRpb24gaGFzIGJlZW4gYXBwcm92ZWQuIFlvdSBjYW4gbG9naW4gbm93IDxhIGhyZWY9IjxpbnAyOm1fQmFzZVVybC8+Ij48aW5wMjptX0Jhc2VVcmwvPjwvYT4gdXNpbmcgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjo8YnIvPjxici8+DQoNCj09PT09PT09PT09PT09PT09PTxici8+DQpVc2VybmFtZTogIjxpbnAyOnVfRmllbGQgbmFtZT0iVXNlcm5hbWUiLz4iPGJyLz4NClBhc3N3b3JkOiAiPGlucDI6dV9GaWVsZCBuYW1lPSJQYXNzd29yZF9wbGFpbiIvPiI8YnIvPg0KPT09PT09PT09PT09PT09PT09PGJyLz48YnIvPg0K
- U3ViamVjdDogTmV3IFVzZXIgUmVnaXN0cmF0aW9uIGlzIFZhbGlkYXRlZAoKVXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gdmFsaWRhdGVkLg==
+
+ TmV3IENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIC0gQWRkZWQ=
+ WW91ciBzdWdnZXN0ZWQgY2F0ZWdvcnkgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaGFzIGJlZW4gYWRkZWQu
+
+
+ TmV3IENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIFN1Ym1pdHRlZCBieSBVc2Vycw==
+ QSBjYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBhZGRlZC4=
+
+
+ U3VnZ2VzdGVkIENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIFBlbmRpbmc=
+ VGhlIGNhdGVnb3J5IHlvdSBzdWdnZXN0ZWQgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaXMgcGVuZGluZyBmb3IgYWRtaW5pc3RyYXRpdmUgYXBwcm92YWwuDQoNClRoYW5rIHlvdSE=
+
+
+ U3VnZ2VzdGVkIENhdGVnb3J5ICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGlzIFBlbmRpbmc=
+ QSBjYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBhZGRlZCwgcGVuZGluZyB5b3VyIGNvbmZpcm1hdGlvbi4gIFBsZWFzZSByZXZpZXcgdGhlIGNhdGVnb3J5IGFuZCBhcHByb3ZlIG9yIGRlbnkgaXQu
+
+
+ QSBjYXRlZ29yeSBoYXMgYmVlbiBhcHByb3ZlZA==
+ WW91ciBzdWdnZXN0ZWQgY2F0ZWdvcnkgIjxpbnAyOmNfRmllbGQgbmFtZT0iTmFtZSIvPiIgaGFzIGJlZW4gYXBwcm92ZWQu
+
+
+ WW91ciBDYXRlZ29yeSAiPGlucDI6Y19GaWVsZCBuYW1lPSJOYW1lIi8+IiBoYXMgYmVlbiBEZW5pZWQ=
+ WW91ciBjYXRlZ29yeSBzdWdnZXN0aW9uICI8aW5wMjpjX0ZpZWxkIG5hbWU9Ik5hbWUiLz4iIGhhcyBiZWVuIGRlbmllZC4=
+
+
+ Q29tbW9uIEZvb3RlciBUZW1wbGF0ZQ==
+ PGJyLz48YnIvPg0KDQpTaW5jZXJlbHksPGJyLz48YnIvPg0KDQpXZWJzaXRlIGFkbWluaXN0cmF0aW9uLg==
+
+
+ TmV3IEVtYWlsIFJFUExZIFJlY2VpdmVkIGluICJGZWVkYmFjayBNYW5hZ2VyIiAoPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRmllbGQgbmFtZT0iRm9ybVN1Ym1pc3Npb25JZCIvPik=
+ TmV3IEVtYWlsIFJFUExZIFJlY2VpdmVkIGluICZxdW90O0ZlZWRiYWNrIE1hbmFnZXImcXVvdDsuPGJyIC8+DQo8YnIgLz4NCk9yaWdpbmFsIEZlZWRiYWNrSWQ6IDxpbnAyOmZvcm1zdWJzLi1pdGVtX0ZpZWxkIG5hbWU9IkZvcm1TdWJtaXNzaW9uSWQiLz4gPGJyIC8+DQpPcmlnaW5hbCBTdWJqZWN0OiA8aW5wMjpmb3Jtc3Vicy4taXRlbV9Gb3JtRmllbGQgcm9sZT0ic3ViamVjdCIvPiA8YnIgLz4NCjxiciAvPg0KUGxlYXNlIHByb2NlZWQgdG8gdGhlIEFkbWluIENvbnNvbGUgaW4gb3JkZXIgdG8gcmV2aWV3IGFuZCByZXBseSB0byB0aGUgdXNlci4=
+
+
+ TmV3IEVtYWlsIC0gRGVsaXZlcnkgRmFpbHVyZSBSZWNlaXZlZCBpbiAiRmVlZGJhY2sgTWFuYWdlciIgKDxpbnAyOmZvcm1zdWJzLi1pdGVtX0ZpZWxkIG5hbWU9IkZvcm1TdWJtaXNzaW9uSWQiLz4p
+ TmV3IEVtYWlsIERlbGl2ZXJ5IEZhaWx1cmUgUmVjZWl2ZWQgaW4gJnF1b3Q7RmVlZGJhY2sgTWFuYWdlciZxdW90Oy48YnIgLz4NCjxiciAvPg0KT3JpZ2luYWwgRmVlZGJhY2tJZDogPGlucDI6Zm9ybXN1YnMuLWl0ZW1fRmllbGQgbmFtZT0iRm9ybVN1Ym1pc3Npb25JZCIvPiA8YnIgLz4NCk9yaWdpbmFsIFN1YmplY3Q6IDxpbnAyOmZvcm1zdWJzLi1pdGVtX0Zvcm1GaWVsZCByb2xlPSJzdWJqZWN0Ii8+IDxiciAvPg0KPGJyIC8+DQpQbGVhc2UgcHJvY2VlZCB0byB0aGUgQWRtaW4gQ29uc29sZSBpbiBvcmRlciB0byByZXZpZXcgYW5kIHJlcGx5IHRvIHRoZSB1c2VyLg==
+
+
+ PGlucDI6bV9QYXJhbSBuYW1lPSJzdWJqZWN0Ii8+ICN2ZXJpZnk8aW5wMjpzdWJtaXNzaW9uLWxvZ19GaWVsZCBuYW1lPSJWZXJpZnlDb2RlIi8+
+ PGlucDI6bV9QYXJhbSBuYW1lPSJtZXNzYWdlIi8+
+
+
+ VGhhbmsgWW91IGZvciBDb250YWN0aW5nIFVzIQ==
+ PHA+VGhhbmsgeW91IGZvciBjb250YWN0aW5nIHVzLiBXZSdsbCBiZSBpbiB0b3VjaCB3aXRoIHlvdSBzaG9ydGx5ITwvcD4=
+
+
+ TmV3IGZvcm0gc3VibWlzc2lvbg==
+ PHA+Rm9ybSBoYXMgYmVlbiBzdWJtaXR0ZWQuIFBsZWFzZSBwcm9jZWVkIHRvIHRoZSBBZG1pbiBDb25zb2xlIHRvIHJldmlldyB0aGUgc3VibWlzc2lvbiE8L3A+
+
+
+ Um9vdCBSZXNldCBQYXNzd29yZA==
+ WW91ciBuZXcgcGFzc3dvcmQgaXM6IDxpbnAyOm1fUGFyYW0gbmFtZT0icGFzc3dvcmQiLz4=
+
+
+ SW4tcG9ydGFsIHJlZ2lzdHJhdGlvbg==
+ RGVhciA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIgLz4gPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJMYXN0TmFtZSIgLz4sDQoNClRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9CYXNlVXJsLz4uIFlvdXIgcmVnaXN0cmF0aW9uIGlzIG5vdyBhY3RpdmUuDQo8aW5wMjptX2lmIGNoZWNrPSJ1LnJlZ2lzdGVyX0ZpZWxkIiBuYW1lPSJFbWFpbCI+DQo8YnIvPjxici8+DQpQbGVhc2UgY2xpY2sgaGVyZSB0byB2ZXJpZnkgeW91ciBFLW1haWwgYWRkcmVzczoNCjxhIGhyZWY9IjxpbnAyOnUucmVnaXN0ZXJfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+Ij48aW5wMjp1LnJlZ2lzdGVyX0NvbmZpcm1QYXNzd29yZExpbmsgdD0icGxhdGZvcm0vbXlfYWNjb3VudC92ZXJpZnlfZW1haWwiIG5vX2FtcD0iMSIvPjwvYT48YnIvPjxici8+DQo8L2lucDI6bV9pZj4=
+
+
+ TmV3IFVzZXIgUmVnaXN0cmF0aW9uICg8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KQ==
+ QSBuZXcgdXNlciAiPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSdVc2VybmFtZScvPiIgaGFzIGJlZW4gYWRkZWQu
+
+
+ TmV3IHVzZXIgaGFzIGJlZW4gY3JlYXRlZA==
+ RGVhciA8aW5wMjp1X0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIvPiwNCg0KQSBuZXcgdXNlciBoYXMgYmVlbiBjcmVhdGVkIGFuZCBhc3NpZ25lZCB0byB5b3UNCg0KTm93IHlvdSBjYW4gbG9naW4gdXNpbmcgdGhlIGZvbGxvd2luZyBjcmVkZW50aWFsczoNCg0KPGlucDI6bV9pZiBjaGVjaz0idV9GaWVsZCIgbmFtZT0iVXNlcm5hbWUiPlVzZXJuYW1lOiA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+PGlucDI6bV9lbHNlLz5FLW1haWw6IDxpbnAyOnVfRmllbGQgbmFtZT0iRW1haWwiLz48L2lucDI6bV9pZj4gDQpQYXNzd29yZDogPGlucDI6dV9GaWVsZCBuYW1lPSJQYXNzd29yZF9wbGFpbiIvPiANCg==
+
+
+ TmV3IFVzZXIgUmVnaXN0cmF0aW9uICg8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+PGlucDI6bV9pZiBjaGVjaz0ibV9HZXRDb25maWciIG5hbWU9IlVzZXJfQWxsb3dfTmV3IiBlcXVhbHNfdG89IjQiPiAtIEFjdGl2YXRpb24gRW1haWw8L2lucDI6bV9pZj4p
+ RGVhciA8aW5wMjp1LnJlZ2lzdGVyX0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIgLz4gPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJMYXN0TmFtZSIgLz4sPGJyIC8+DQo8YnIgLz4NCjxpbnAyOm1faWYgY2hlY2s9Im1fR2V0Q29uZmlnIiBuYW1lPSJVc2VyX0FsbG93X05ldyIgZXF1YWxzX3RvPSI0Ij4NCglUaGFuayB5b3UgZm9yIHJlZ2lzdGVyaW5nIG9uIDxpbnAyOm1fTGluayB0ZW1wbGF0ZT0iaW5kZXgiLz4gd2Vic2l0ZS4gVG8gYWN0aXZhdGUgeW91ciByZWdpc3RyYXRpb24gcGxlYXNlIGZvbGxvdyBsaW5rIGJlbG93LiA8aW5wMjp1LnJlZ2lzdGVyX0FjdGl2YXRpb25MaW5rIHRlbXBsYXRlPSJwbGF0Zm9ybS9sb2dpbi9hY3RpdmF0ZV9jb25maXJtIi8+DQo8aW5wMjptX2Vsc2UvPg0KCVRoYW5rIHlvdSBmb3IgcmVnaXN0ZXJpbmcgb24gPGlucDI6bV9MaW5rIHRlbXBsYXRlPSJpbmRleCIvPiB3ZWJzaXRlLiBZb3VyIHJlZ2lzdHJhdGlvbiB3aWxsIGJlIGFjdGl2ZSBhZnRlciBhcHByb3ZhbC4gDQoJDQoJPGlucDI6bV9pZiBjaGVjaz0idS5yZWdpc3Rlcl9GaWVsZCIgbmFtZT0iRW1haWwiPg0KCQk8YnIvPjxici8+DQoJCVBsZWFzZSBjbGljayBoZXJlIHRvIHZlcmlmeSB5b3VyIEUtbWFpbCBhZGRyZXNzOg0KCQk8YSBocmVmPSI8aW5wMjp1LnJlZ2lzdGVyX0NvbmZpcm1QYXNzd29yZExpbmsgdD0icGxhdGZvcm0vbXlfYWNjb3VudC92ZXJpZnlfZW1haWwiIG5vX2FtcD0iMSIvPiI+PGlucDI6dS5yZWdpc3Rlcl9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz48L2E+PGJyLz48YnIvPg0KCTwvaW5wMjptX2lmPg0KPC9pbnAyOm1faWY+
+
+
+ TmV3IFVzZXIgUmVnaXN0ZXJlZA==
+ QSBuZXcgdXNlciAiPGlucDI6dS5yZWdpc3Rlcl9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIHJlZ2lzdGVyZWQgYW5kIGlzIHBlbmRpbmcgYWRtaW5pc3RyYXRpdmUgYXBwcm92YWwu
+
+
+ WW91ciBBY2NvdW50IGlzIEFjdGl2ZQ==
+ V2VsY29tZSB0byA8aW5wMjptX0Jhc2VVcmwvPiENCg0KWW91ciB1c2VyIHJlZ2lzdHJhdGlvbiBoYXMgYmVlbiBhcHByb3ZlZC4gWW91ciB1c2VyIG5hbWUgaXM6ICI8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+Ii4=
+
+
+ TmV3IFVzZXIgQWNjb3VudCAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgd2FzIEFwcHJvdmVk
+ VXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gYXBwcm92ZWQu
+
+
+ WW91ciBSZWdpc3RyYXRpb24gaGFzIGJlZW4gRGVuaWVk
+ WW91ciByZWdpc3RyYXRpb24gb24gPGEgaHJlZj0iPGlucDI6bV9CYXNlVXJsLz4iPjxpbnAyOm1fQmFzZVVybC8+PC9hPiB3ZWJzaXRlIGhhcyBiZWVuIGRlbmllZC4=
+
+
+ VXNlciBSZWdpc3RyYXRpb24gZm9yICAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gRGVuaWVk
+ VXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gZGVuaWVkLg==
+
+
+ Q2hhbmdlZCBFLW1haWwgUm9sbGJhY2s=
+ SGVsbG8sPGJyLz48YnIvPg0KDQpJdCBzZWVtcyB0aGF0IHlvdSBoYXZlIGNoYW5nZWQgZS1tYWlsIGluIHlvdXIgSW4tcG9ydGFsIGFjY291bnQuIFlvdSBtYXkgdW5kbyB0aGlzIGNoYW5nZSBieSBjbGlja2luZyBvbiB0aGUgbGluayBiZWxvdzo8YnIvPjxici8+DQoNCjxhIGhyZWY9IjxpbnAyOnVfVW5kb0VtYWlsQ2hhbmdlTGluayB0ZW1wbGF0ZT0icGxhdGZvcm0vbXlfYWNjb3VudC9yZXN0b3JlX2VtYWlsIi8+Ij48aW5wMjp1X1VuZG9FbWFpbENoYW5nZUxpbmsgdGVtcGxhdGU9InBsYXRmb3JtL215X2FjY291bnQvcmVzdG9yZV9lbWFpbCIvPjwvYT48YnIvPjxici8+DQoNCklmIHlvdSBiZWxpZXZlIHlvdSBoYXZlIHJlY2VpdmVkIHRoaXMgZW1haWwgaW4gZXJyb3IsIHBsZWFzZSBpZ25vcmUgdGhpcyBlbWFpbC4gWW91ciBhY2NvdW50IHdpbGwgYmUgbGlua2VkIHRvIGFub3RoZXIgZS1tYWlsIHVubGVzcyB5b3UgaGF2ZSBjbGlja2VkIG9uIHRoZSBhYm92ZSBsaW5rLg==
+
+
+ Q2hhbmdlZCBFLW1haWwgVmVyaWZpY2F0aW9u
+ SGVsbG8sPGJyLz48YnIvPg0KDQpJdCBzZWVtcyB0aGF0IHlvdSBoYXZlIGNoYW5nZWQgZS1tYWlsIGluIHlvdXIgSW4tcG9ydGFsIGFjY291bnQuIFBsZWFzZSB2ZXJpZnkgdGhpcyBuZXcgZS1tYWlsIGJ5IGNsaWNraW5nIG9uIHRoZSBsaW5rIGJlbG93Ojxici8+PGJyLz4NCg0KPGEgaHJlZj0iPGlucDI6dV9Db25maXJtUGFzc3dvcmRMaW5rIHQ9InBsYXRmb3JtL215X2FjY291bnQvdmVyaWZ5X2VtYWlsIiBub19hbXA9IjEiLz4iPjxpbnAyOnVfQ29uZmlybVBhc3N3b3JkTGluayB0PSJwbGF0Zm9ybS9teV9hY2NvdW50L3ZlcmlmeV9lbWFpbCIgbm9fYW1wPSIxIi8+PC9hPjxici8+PGJyLz4NCg0KSWYgeW91IGJlbGlldmUgeW91IGhhdmUgcmVjZWl2ZWQgdGhpcyBlbWFpbCBpbiBlcnJvciwgcGxlYXNlIGlnbm9yZSB0aGlzIGVtYWlsLiBZb3VyIGVtYWlsIHdpbGwgbm90IGdldCB2ZXJpZmllZCBzdGF0dXMgdW5sZXNzIHlvdSBoYXZlIGNsaWNrZWQgb24gdGhlIGFib3ZlIGxpbmsuDQo=
+
+
+ TWVtYmVyc2hpcCBFeHBpcmF0aW9uIE5vdGljZQ==
+ WW91ciBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fQmFzZVVybC8+IHdlYnNpdGUgd2lsbCBzb29uIGV4cGlyZS4=
+
+
+ TWVtYmVyc2hpcCBFeHBpcmF0aW9uIE5vdGljZSBmb3IgIjxpbnAyOnVfRmllbGQgbmFtZT0iVXNlcm5hbWUiLz4iIFNlbnQ=
+ VXNlciA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+IG1lbWJlcnNoaXAgd2lsbCBleHBpcmUgc29vbi4=
+
+
+ WW91ciBNZW1iZXJzaGlwIEV4cGlyZWQ=
+ WW91ciBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fQmFzZVVybC8+IHdlYnNpdGUgaGFzIGV4cGlyZWQu
+
+
+ VXNlcidzIE1lbWJlcnNoaXAgRXhwaXJlZCAgKCA8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KQ==
+ VXNlcidzICg8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+KSBtZW1iZXJzaGlwIG9uIDxpbnAyOm1fQmFzZVVybC8+IHdlYnNpdGUgaGFzIGV4cGlyZWQu
+
+
+ TmV3IHBhc3N3b3JkIGdlbmVyYXRlZA==
+ RGVhciA8aW5wMjp1X0ZpZWxkIG5hbWU9IkZpcnN0TmFtZSIvPiwNCg0KQSBuZXcgcGFzc3dvcmQgaGFzIGJlZW4gZ2VuZXJhdGVkIGZvciB5b3VyIHVzZXIuDQoNCk5vdyB5b3UgY2FuIGxvZ2luIHVzaW5nIHRoZSBmb2xsb3dpbmcgY3JlZGVudGlhbHM6DQoNCjxpbnAyOm1faWYgY2hlY2s9InVfRmllbGQiIG5hbWU9IlVzZXJuYW1lIj5Vc2VybmFtZTogPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPjxpbnAyOm1fZWxzZS8+RS1tYWlsOiA8aW5wMjp1X0ZpZWxkIG5hbWU9IkVtYWlsIi8+PC9pbnAyOm1faWY+IA0KUGFzc3dvcmQ6IDxpbnAyOnVfRmllbGQgbmFtZT0iUGFzc3dvcmRfcGxhaW4iLz4g
+
+
+ UmVzZXQgUGFzc3dvcmQgQ29uZmlybWF0aW9u
+ SGVsbG8sPGJyLz48YnIvPg0KDQpJdCBzZWVtcyB0aGF0IHlvdSBoYXZlIHJlcXVlc3RlZCBhIHBhc3N3b3JkIHJlc2V0IGZvciB5b3VyIEluLXBvcnRhbCBhY2NvdW50LiBJZiB5b3Ugd291bGQgbGlrZSB0byBwcm9jZWVkIGFuZCBjaGFuZ2UgdGhlIHBhc3N3b3JkLCBwbGVhc2UgY2xpY2sgb24gdGhlIGxpbmsgYmVsb3c6PGJyLz48YnIvPg0KDQo8YSBocmVmPSI8aW5wMjp1X0NvbmZpcm1QYXNzd29yZExpbmsgbm9fYW1wPSIxIi8+Ij48aW5wMjp1X0NvbmZpcm1QYXNzd29yZExpbmsgbm9fYW1wPSIxIi8+PC9hPjxici8+PGJyLz4NCg0KWW91IHdpbGwgcmVjZWl2ZSBhIHNlY29uZCBlbWFpbCB3aXRoIHlvdXIgbmV3IHBhc3N3b3JkIHNob3J0bHkuPGJyLz48YnIvPg0KDQpJZiB5b3UgYmVsaWV2ZSB5b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGVtYWlsIGluIGVycm9yLCBwbGVhc2UgaWdub3JlIHRoaXMgZW1haWwuIFlvdXIgcGFzc3dvcmQgd2lsbCBub3QgYmUgY2hhbmdlZCB1bmxlc3MgeW91IGhhdmUgY2xpY2tlZCBvbiB0aGUgYWJvdmUgbGluay4NCg==
+
+
+ U3Vic2NyaWJlZCB0byBhIE1haWxpbmcgTGlzdCBvbiA8aW5wMjptX0Jhc2VVcmwvPg==
+ WW91IGhhdmUgc3Vic2NyaWJlZCB0byBhIG1haWxpbmcgbGlzdCBvbiA8aW5wMjptX0Jhc2VVcmwvPiB3ZWJzaXRlLg==
+
+
+ TmV3IFVzZXIgaGFzIFN1YnNjcmliZWQgdG8gYSBNYWxsaW5nIExpc3Q=
+ TmV3IHVzZXIgPGlucDI6dV9GaWVsZCBuYW1lPSJFbWFpbCIvPiBoYXMgc3Vic2NyaWJlZCB0byBhIG1haWxpbmcgbGlzdCBvbiA8YSBocmVmPSI8aW5wMjptX0Jhc2VVcmwvPiI+PGlucDI6bV9CYXNlVXJsLz48L2E+IHdlYnNpdGUu
+
+
+ Q2hlY2sgb3V0IHRoaXMgV2Vic2l0ZQ==
+ SGVsbG8sPC9icj48L2JyPg0KDQpUaGlzIG1lc3NhZ2UgaGFzIGJlZW4gc2VudCB0byB5b3UgZnJvbSBvbmUgb2YgeW91ciBmcmllbmRzLjwvYnI+PC9icj4NCkNoZWNrIG91dCB0aGlzIHNpdGU6IDxhIGhyZWY9IjxpbnAyOm1fQmFzZVVybC8+Ij48aW5wMjptX0Jhc2VVcmwvPjwvYT4h
+
+
+ V2Vic2l0ZSBTdWdnZXN0ZWQgdG8gYSBGcmllbmQ=
+ QSB2aXNpdG9yIHN1Z2dlc3RlZCA8YSBocmVmPSI8aW5wMjptX0Jhc2VVcmwvPiI+PGlucDI6bV9CYXNlVXJsLz48L2E+IHdlYnNpdGUgdG8gYSBmcmllbmQu
+
+
+ WW91IGhhdmUgYmVlbiB1bnN1YnNjcmliZWQ=
+ WW91IGhhdmUgc3VjY2Vzc2Z1bGx5IHVuc3Vic2NyaWJlZCBmcm9tIHRoZSBtYWlsaW5nIGxpc3Qgb24gPGEgaHJlZj0iPGlucDI6bV9CYXNlVXJsIC8+Ij48aW5wMjptX0Jhc2VVcmwgLz48L2E+IHdlYnNpdGUu
+
+
+ VXNlciBVbnN1YnNyaWJlZCBmcm9tIE1haWxpbmcgTGlzdA==
+ QSB1c2VyICI8aW5wMjp1X0ZpZWxkIG5hbWU9IkVtYWlsIi8+IiBoYXMgdW5zdWJzY3JpYmVkIGZyb20gdGhlIG1haWxpbmcgbGlzdCBvbiA8YSBocmVmPSI8aW5wMjptX0Jhc2VVcmwvPiI+PGlucDI6bV9CYXNlVXJsLz48L2E+Lg==
+
+
+ VXNlciBSZWdpc3RyYXRpb24gaXMgVmFsaWRhdGVk
+ V2VsY29tZSB0byBJbi1wb3J0YWwhPGJyLz48YnIvPg0KDQpZb3VyIHVzZXIgcmVnaXN0cmF0aW9uIGhhcyBiZWVuIGFwcHJvdmVkLiBZb3UgY2FuIGxvZ2luIG5vdyA8YSBocmVmPSI8aW5wMjptX0Jhc2VVcmwvPiI+PGlucDI6bV9CYXNlVXJsLz48L2E+IHVzaW5nIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb246PGJyLz48YnIvPg0KDQo9PT09PT09PT09PT09PT09PT08YnIvPg0KVXNlcm5hbWU6ICI8aW5wMjp1X0ZpZWxkIG5hbWU9IlVzZXJuYW1lIi8+Ijxici8+DQpQYXNzd29yZDogIjxpbnAyOnVfRmllbGQgbmFtZT0iUGFzc3dvcmRfcGxhaW4iLz4iPGJyLz4NCj09PT09PT09PT09PT09PT09PTxici8+PGJyLz4NCg==
+
+
+ TmV3IFVzZXIgUmVnaXN0cmF0aW9uIGlzIFZhbGlkYXRlZA==
+ VXNlciAiPGlucDI6dV9GaWVsZCBuYW1lPSJVc2VybmFtZSIvPiIgaGFzIGJlZW4gdmFsaWRhdGVkLg==
+