Compare commits

...

8 Commits

Author SHA1 Message Date
philippe44
c9455f70ff Update CHANGELOG 2023-10-25 22:47:14 -07:00
philippe44
b5b76480e4 Merge branch 'master-v4.3' of https://github.com/sle118/squeezelite-esp32 into master-v4.3 2023-10-25 22:45:37 -07:00
philippe44
e6744deab8 fix vorbis not closing properly - release 2023-10-25 22:45:26 -07:00
github-actions
94baf86989 Update prebuilt objects [skip actions] 2023-10-25 01:48:05 +00:00
philippe44
0c856a37c1 well, fix 16 bits as well... 2023-10-24 16:27:27 -07:00
philippe44
d5f28375ce fix SPDIF miscount 2023-10-24 13:39:56 -07:00
philippe44
7ea5a93647 backport webUI changes as well (-disable) 2023-10-23 17:15:02 -07:00
philippe44
ca38a14420 cspot fixes backport 2023-10-23 17:09:50 -07:00
30 changed files with 168 additions and 122 deletions

View File

@@ -1,3 +1,10 @@
2023-10-25
- fix vorbis code close
2023-10-23
- fix Spotify track insertion
- [WEB] Allow running without LMS with option "Audio/Disable Squeezelite"
2023-10.07 2023-10.07
- catchup with official cspot - catchup with official cspot

View File

@@ -187,7 +187,7 @@ bck=<gpio>,ws=<gpio>,do=<gpio>[,mck=0|1|2][,mute=<gpio>[:0|1][,model=TAS57xx|TAS
``` ```
if "model" is not set or is not recognized, then default "I2S" is used. The option "mck" is used for some codecs that require a master clock (although they should not). By default GPIO0 is used as MCLK and only recent builds (post mid-2023) can use 1 or 2. Also be aware that this cannot coexit with RMII Ethernet (see ethernet section below). I2C parameters are optional and only needed if your DAC requires an I2C control (See 'dac_controlset' below). Note that "i2c" parameters are decimal, hex notation is not allowed. if "model" is not set or is not recognized, then default "I2S" is used. The option "mck" is used for some codecs that require a master clock (although they should not). By default GPIO0 is used as MCLK and only recent builds (post mid-2023) can use 1 or 2. Also be aware that this cannot coexit with RMII Ethernet (see ethernet section below). I2C parameters are optional and only needed if your DAC requires an I2C control (See 'dac_controlset' below). Note that "i2c" parameters are decimal, hex notation is not allowed.
So far, TAS57xx, TAS5713, AC101, WM8978 and ES8388 are recognized models where the proper init sequence/volume/power controls are sent. For other codecs that might require an I2C commands, please use the parameter "dac_controlset" that allows definition of simple commands to be sent over i2c for init, power, speakder and headset on and off using a JSON syntax: So far, TAS57xx, TAS5713, AC101, WM8978 and ES8388 are recognized models where the proper init sequence/volume/power controls are sent. For other codecs that might require an I2C commands, please use the parameter "dac_controlset" that allows definition of simple commands to be sent over i2c for init, power, speaker and headset on and off using a JSON syntax:
```json ```json
{ <command>: [ {"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"}, ... {{"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"} ], { <command>: [ {"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"}, ... {{"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"} ],
<command>: [ {"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"}, ... {{"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"} ], <command>: [ {"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"}, ... {{"reg":<register>,"val":<value>,"mode":<nothing>|"or"|"and"} ],
@@ -197,6 +197,8 @@ Where `<command>` is one of init, poweron, poweroff, speakeron, speakeroff, head
This is standard JSON notation, so if you are not familiar with it, Google is your best friend. Be aware that the '...' means you can have as many entries as you want, it's not part of the syntax. Every section is optional, but it does not make sense to set i2c in the 'dac_config' parameter and not setting anything here. The parameter 'mode' allows to *or* the register with the value or to *and* it. Don't set 'mode' if you simply want to write. The 'val parameter can be an array [v1, v2,...] to write a serie of bytes in a single i2c burst (in that case 'mode' is ignored). **Note that all values must be decimal**. You can use a validator like [this](https://jsonlint.com) to verify your syntax This is standard JSON notation, so if you are not familiar with it, Google is your best friend. Be aware that the '...' means you can have as many entries as you want, it's not part of the syntax. Every section is optional, but it does not make sense to set i2c in the 'dac_config' parameter and not setting anything here. The parameter 'mode' allows to *or* the register with the value or to *and* it. Don't set 'mode' if you simply want to write. The 'val parameter can be an array [v1, v2,...] to write a serie of bytes in a single i2c burst (in that case 'mode' is ignored). **Note that all values must be decimal**. You can use a validator like [this](https://jsonlint.com) to verify your syntax
The 'power' command is used when powering on/off the DAC after the idle period (see -C option of squeezelite) and the 'speaker/headset' commands are sent when switching between speakers and headsets (see headset jack detection).
NB: For named configurations ((SqueezeAMP, Muse ... all except I2S), all this is ignored. For know codecs, the built-in sequences can be overwritten using dac_controlset NB: For named configurations ((SqueezeAMP, Muse ... all except I2S), all this is ignored. For know codecs, the built-in sequences can be overwritten using dac_controlset
**Please note that you can not use the same GPIO or port as the I2C.** **Please note that you can not use the same GPIO or port as the I2C.**
@@ -275,7 +277,7 @@ GPIO can be set to GND provide or Vcc at boot. This is convenient to power devic
The `<amp>` parameter can use used to assign a GPIO that will be set to active level (default 1) when playback starts. It will be reset when squeezelite becomes idle. The idle timeout is set on the squeezelite command line through `-C <timeout>` The `<amp>` parameter can use used to assign a GPIO that will be set to active level (default 1) when playback starts. It will be reset when squeezelite becomes idle. The idle timeout is set on the squeezelite command line through `-C <timeout>`
The `<power>` parameter can use used to assign a GPIO that will be set to active level (default 1) when player is powered on and reset when powered off The `<power>` parameter can use used to assign a GPIO that will be set to active level (default 1) when player is powered on and reset when powered off (in LMS, does not apply to AirPlay, Spotify or BT).
If you have an audio jack that supports insertion (use :0 or :1 to set the level when inserted), you can specify which GPIO it's connected to. Using the parameter jack_mutes_amp allows to mute the amp when headset (e.g.) is inserted. If you have an audio jack that supports insertion (use :0 or :1 to set the level when inserted), you can specify which GPIO it's connected to. Using the parameter jack_mutes_amp allows to mute the amp when headset (e.g.) is inserted.

View File

@@ -53,6 +53,7 @@ private:
std::atomic<states> state; std::atomic<states> state;
std::string credentials; std::string credentials;
bool zeroConf; bool zeroConf;
std::atomic<bool> flushed = false, notify = true;
int startOffset, volume = 0, bitrate = 160; int startOffset, volume = 0, bitrate = 160;
httpd_handle_t serverHandle; httpd_handle_t serverHandle;
@@ -60,6 +61,7 @@ private:
cspot_cmd_cb_t cmdHandler; cspot_cmd_cb_t cmdHandler;
cspot_data_cb_t dataHandler; cspot_data_cb_t dataHandler;
std::string lastTrackId; std::string lastTrackId;
cspot::TrackInfo trackInfo;
std::shared_ptr<cspot::LoginBlob> blob; std::shared_ptr<cspot::LoginBlob> blob;
std::unique_ptr<cspot::SpircHandler> spirc; std::unique_ptr<cspot::SpircHandler> spirc;
@@ -206,11 +208,13 @@ void cspotPlayer::eventHandler(std::unique_ptr<cspot::SpircHandler::Event> event
trackStatus = TRACK_INIT; trackStatus = TRACK_INIT;
// memorize position for when track's beginning will be detected // memorize position for when track's beginning will be detected
startOffset = std::get<int>(event->data); startOffset = std::get<int>(event->data);
notify = !flushed;
flushed = false;
// Spotify servers do not send volume at connection // Spotify servers do not send volume at connection
spirc->setRemoteVolume(volume); spirc->setRemoteVolume(volume);
cmdHandler(CSPOT_START, 44100); cmdHandler(CSPOT_START, 44100);
CSPOT_LOG(info, "(re)start playing"); CSPOT_LOG(info, "(re)start playing at %d", startOffset);
break; break;
} }
case cspot::SpircHandler::EventType::PLAY_PAUSE: { case cspot::SpircHandler::EventType::PLAY_PAUSE: {
@@ -219,16 +223,14 @@ void cspotPlayer::eventHandler(std::unique_ptr<cspot::SpircHandler::Event> event
break; break;
} }
case cspot::SpircHandler::EventType::TRACK_INFO: { case cspot::SpircHandler::EventType::TRACK_INFO: {
auto trackInfo = std::get<cspot::TrackInfo>(event->data); trackInfo = std::get<cspot::TrackInfo>(event->data);
cmdHandler(CSPOT_TRACK_INFO, trackInfo.duration, startOffset, trackInfo.artist.c_str(),
trackInfo.album.c_str(), trackInfo.name.c_str(), trackInfo.imageUrl.c_str());
spirc->updatePositionMs(startOffset);
startOffset = 0;
break; break;
} }
case cspot::SpircHandler::EventType::FLUSH:
flushed = true;
__attribute__ ((fallthrough));
case cspot::SpircHandler::EventType::NEXT: case cspot::SpircHandler::EventType::NEXT:
case cspot::SpircHandler::EventType::PREV: case cspot::SpircHandler::EventType::PREV: {
case cspot::SpircHandler::EventType::FLUSH: {
cmdHandler(CSPOT_FLUSH); cmdHandler(CSPOT_FLUSH);
break; break;
} }
@@ -411,8 +413,13 @@ void cspotPlayer::runTask() {
uint32_t started; uint32_t started;
cmdHandler(CSPOT_QUERY_STARTED, &started); cmdHandler(CSPOT_QUERY_STARTED, &started);
if (started) { if (started) {
CSPOT_LOG(info, "next track's audio has reached DAC"); CSPOT_LOG(info, "next track's audio has reached DAC (offset %d)", startOffset);
spirc->notifyAudioReachedPlayback(); if (notify) spirc->notifyAudioReachedPlayback();
else notify = true;
cmdHandler(CSPOT_TRACK_INFO, trackInfo.duration, startOffset, trackInfo.artist.c_str(),
trackInfo.album.c_str(), trackInfo.name.c_str(), trackInfo.imageUrl.c_str());
spirc->updatePositionMs(startOffset);
startOffset = 0;
trackStatus = TRACK_STREAM; trackStatus = TRACK_STREAM;
} }
} else if (trackStatus == TRACK_END) { } else if (trackStatus == TRACK_END) {

View File

@@ -204,8 +204,13 @@ void SpircHandler::handleFrame(std::vector<uint8_t>& data) {
CSPOT_LOG(debug, "Got replace frame"); CSPOT_LOG(debug, "Got replace frame");
playbackState->syncWithRemote(); playbackState->syncWithRemote();
trackQueue->updateTracks(playbackState->remoteFrame.state.position_ms, // 1st track is the current one, but update the position
false); trackQueue->updateTracks(
playbackState->remoteFrame.state.position_ms +
ctx->timeProvider->getSyncedTimestamp() -
playbackState->innerFrame.state.position_measured_at,
false);
this->notify(); this->notify();
sendEvent(EventType::FLUSH); sendEvent(EventType::FLUSH);

View File

@@ -744,7 +744,7 @@ static void IRAM_ATTR spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst) {
// we assume frame == 0 as well... // we assume frame == 0 as well...
if (!src) { if (!src) {
count = 192; count = 0;
vu = VUCP24[0]; vu = VUCP24[0];
} }
@@ -757,7 +757,7 @@ static void IRAM_ATTR spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst) {
if (!count--) { if (!count--) {
*dst++ = (vu << 24) | (PREAMBLE_B << 16) | 0xCCCC; *dst++ = (vu << 24) | (PREAMBLE_B << 16) | 0xCCCC;
count = 192; count = 191;
} else { } else {
*dst++ = (vu << 24) | (PREAMBLE_M << 16) | 0xCCCC; *dst++ = (vu << 24) | (PREAMBLE_M << 16) | 0xCCCC;
} }
@@ -771,7 +771,7 @@ static void IRAM_ATTR spdif_convert(ISAMPLE_T *src, size_t frames, u32_t *dst) {
if (!count--) { if (!count--) {
*dst++ = (vu << 24) | (PREAMBLE_B << 16) | aux; *dst++ = (vu << 24) | (PREAMBLE_B << 16) | aux;
count = 192; count = 191;
} else { } else {
*dst++ = (vu << 24) | (PREAMBLE_M << 16) | aux; *dst++ = (vu << 24) | (PREAMBLE_M << 16) | aux;
} }

View File

@@ -396,7 +396,6 @@ static decode_state vorbis_decode(void) {
} }
static void vorbis_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) { static void vorbis_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
LOG_INFO("OPENING CODEC");
if (v->opened) { if (v->opened) {
OV(&go, block_clear, &v->block); OV(&go, block_clear, &v->block);
OV(&go, info_clear, &v->info); OV(&go, info_clear, &v->info);
@@ -413,8 +412,6 @@ static void vorbis_open(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
} }
static void vorbis_close() { static void vorbis_close() {
return;
LOG_INFO("CLOSING CODEC");
if (v->opened) { if (v->opened) {
OV(&go, block_clear, &v->block); OV(&go, block_clear, &v->block);
OV(&go, info_clear, &v->info); OV(&go, info_clear, &v->info);

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -64,6 +64,8 @@ declare function getStatus(): {};
declare function getStatus(): {}; declare function getStatus(): {};
declare function getStatus(): {}; declare function getStatus(): {};
declare function getStatus(): {}; declare function getStatus(): {};
declare function getStatus(): {};
declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string; declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string; declare function getRadioButton(entry: any): string;
declare function getRadioButton(entry: any): string; declare function getRadioButton(entry: any): string;
@@ -196,6 +198,7 @@ declare function pushStatus(): void;
declare function pushStatus(): void; declare function pushStatus(): void;
declare function pushStatus(): void; declare function pushStatus(): void;
declare function pushStatus(): void; declare function pushStatus(): void;
declare function pushStatus(): void;
declare let sd: {}; declare let sd: {};
declare let rf: boolean; declare let rf: boolean;
declare function refreshStatus(): void; declare function refreshStatus(): void;

View File

@@ -331,8 +331,7 @@
<div class="form-check"> <div class="form-check">
<label class="form-check-label"> <label class="form-check-label">
<input class="form-check-input" type="checkbox" id="disable-squeezelite" <input class="form-check-input" type="checkbox" id="disable-squeezelite" value="" >
value="" checked="">
Disable Squeezelite Disable Squeezelite
</label> </label>
</div> </div>

View File

@@ -923,10 +923,10 @@ window.saveAutoexec1 = function (apply) {
}; };
data.config = { data.config = {
autoexec1: { value: commandLine, type: 33 }, autoexec1: { value: commandLine, type: 33 },
autoexec: { // autoexec: {
value: $('#disable-squeezelite').prop('checked') ? '0' : '1', // value: $('#disable-squeezelite').prop('checked') ? '0' : '1',
type: 33, // type: 33,
}, // },
}; };
$.ajax({ $.ajax({
@@ -1216,6 +1216,28 @@ $(document).ready(function () {
} }
}); });
$('#disable-squeezelite').on('click', function () {
// this.checked = this.checked ? 1 : 0;
// $('#disable-squeezelite').prop('checked')
if (this.checked) {
// Store the current value before overwriting it
const currentValue = $('#cmd_opt_s').val();
$('#cmd_opt_s').data('originalValue', currentValue);
// Overwrite the value with '-disable'
$('#cmd_opt_s').val('-disable');
} else {
// Retrieve the original value
const originalValue = $('#cmd_opt_s').data('originalValue');
// Restore the original value if it exists, otherwise set it to an empty string
$('#cmd_opt_s').val(originalValue ? originalValue : '');
}
});
$('input#show-nvs').on('click', function () { $('input#show-nvs').on('click', function () {
this.checked = this.checked ? 1 : 0; this.checked = this.checked ? 1 : 0;
Cookies.set("show-nvs", this.checked ? 'Y' : 'N'); Cookies.set("show-nvs", this.checked ? 'Y' : 'N');
@@ -2199,13 +2221,7 @@ function getConfig() {
.sort() .sort()
.forEach(function (key) { .forEach(function (key) {
let val = data[key].value; let val = data[key].value;
if (key === 'autoexec') { if (key === 'autoexec1') {
if (data.autoexec.value === '0') {
$('#disable-squeezelite')[0].checked = true;
} else {
$('#disable-squeezelite')[0].checked = false;
}
} else if (key === 'autoexec1') {
/* call new function to parse the squeezelite options */ /* call new function to parse the squeezelite options */
processSqueezeliteCommandLine(val); processSqueezeliteCommandLine(val);
} else if (key === 'host_name') { } else if (key === 'host_name') {
@@ -2294,6 +2310,7 @@ function processSqueezeliteCommandLine(val) {
commandBTSinkName= parsed.otherOptions.btname; commandBTSinkName= parsed.otherOptions.btname;
} }
handleTemplateTypeRadio('bt'); handleTemplateTypeRadio('bt');
} }
Object.keys(parsed.options).forEach(function (key) { Object.keys(parsed.options).forEach(function (key) {
const option = parsed.options[key]; const option = parsed.options[key];
@@ -2312,6 +2329,17 @@ function processSqueezeliteCommandLine(val) {
$('#resample_i').prop('checked', true); $('#resample_i').prop('checked', true);
} }
} }
if (parsed.options.hasOwnProperty('s')) {
// parse -u v[:i] and check the appropriate radio button with id #resample_v
if(parsed.options.s === '-disable'){
$('#disable-squeezelite')[0].checked = true;
}
else {
$('#disable-squeezelite')[0].checked = false;
}
}
} }

View File

@@ -1,5 +1,5 @@
target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.1ab179394339385e0a02.css.gz BINARY) target_add_binary_data( __idf_wifi-manager webapp/dist/css/index.1ab179394339385e0a02.css.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY) target_add_binary_data( __idf_wifi-manager webapp/dist/favicon-32x32.png BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY) target_add_binary_data( __idf_wifi-manager webapp/dist/index.html.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.b02584.bundle.js.gz BINARY) target_add_binary_data( __idf_wifi-manager webapp/dist/js/index.775de9.bundle.js.gz BINARY)
target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.b02584.bundle.js.gz BINARY) target_add_binary_data( __idf_wifi-manager webapp/dist/js/node_vendors.775de9.bundle.js.gz BINARY)

View File

@@ -6,29 +6,29 @@ extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_s
extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end"); extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start"); extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end"); extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
extern const uint8_t _index_b02584_bundle_js_gz_start[] asm("_binary_index_b02584_bundle_js_gz_start"); extern const uint8_t _index_775de9_bundle_js_gz_start[] asm("_binary_index_775de9_bundle_js_gz_start");
extern const uint8_t _index_b02584_bundle_js_gz_end[] asm("_binary_index_b02584_bundle_js_gz_end"); extern const uint8_t _index_775de9_bundle_js_gz_end[] asm("_binary_index_775de9_bundle_js_gz_end");
extern const uint8_t _node_vendors_b02584_bundle_js_gz_start[] asm("_binary_node_vendors_b02584_bundle_js_gz_start"); extern const uint8_t _node_vendors_775de9_bundle_js_gz_start[] asm("_binary_node_vendors_775de9_bundle_js_gz_start");
extern const uint8_t _node_vendors_b02584_bundle_js_gz_end[] asm("_binary_node_vendors_b02584_bundle_js_gz_end"); extern const uint8_t _node_vendors_775de9_bundle_js_gz_end[] asm("_binary_node_vendors_775de9_bundle_js_gz_end");
const char * resource_lookups[] = { const char * resource_lookups[] = {
"/css/index.1ab179394339385e0a02.css.gz", "/css/index.1ab179394339385e0a02.css.gz",
"/favicon-32x32.png", "/favicon-32x32.png",
"/index.html.gz", "/index.html.gz",
"/js/index.b02584.bundle.js.gz", "/js/index.775de9.bundle.js.gz",
"/js/node_vendors.b02584.bundle.js.gz", "/js/node_vendors.775de9.bundle.js.gz",
"" ""
}; };
const uint8_t * resource_map_start[] = { const uint8_t * resource_map_start[] = {
_index_1ab179394339385e0a02_css_gz_start, _index_1ab179394339385e0a02_css_gz_start,
_favicon_32x32_png_start, _favicon_32x32_png_start,
_index_html_gz_start, _index_html_gz_start,
_index_b02584_bundle_js_gz_start, _index_775de9_bundle_js_gz_start,
_node_vendors_b02584_bundle_js_gz_start _node_vendors_775de9_bundle_js_gz_start
}; };
const uint8_t * resource_map_end[] = { const uint8_t * resource_map_end[] = {
_index_1ab179394339385e0a02_css_gz_end, _index_1ab179394339385e0a02_css_gz_end,
_favicon_32x32_png_end, _favicon_32x32_png_end,
_index_html_gz_end, _index_html_gz_end,
_index_b02584_bundle_js_gz_end, _index_775de9_bundle_js_gz_end,
_node_vendors_b02584_bundle_js_gz_end _node_vendors_775de9_bundle_js_gz_end
}; };

View File

@@ -1,6 +1,6 @@
/*********************************** /***********************************
webpack_headers webpack_headers
dist/css/index.1ab179394339385e0a02.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.b02584.bundle.js.gz,dist/js/node_vendors.b02584.bundle.js.gz dist/css/index.1ab179394339385e0a02.css.gz,dist/favicon-32x32.png,dist/index.html.gz,dist/js/index.775de9.bundle.js.gz,dist/js/node_vendors.775de9.bundle.js.gz
***********************************/ ***********************************/
#pragma once #pragma once
#include <inttypes.h> #include <inttypes.h>

Binary file not shown.

View File

@@ -144,18 +144,18 @@ LxoOkcXsNb/12jOV3iQSDfXDI41AgtFc694KCOjlg+UKizpemE53T5/cq37OqChP
qnlPyb6PYIhua/kgbH84ltba1xEDQ9i4UYfOMiJNZEzEdSfQ498= qnlPyb6PYIhua/kgbH84ltba1xEDQ9i4UYfOMiJNZEzEdSfQ498=
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIIXzCCB0egAwIBAgIQBKU3dDawNcfrgz6Dj4jGVjANBgkqhkiG9w0BAQsFADA8 MIIIOzCCByOgAwIBAgIQDMnYcxFdn1+HZt0ULgDEwTANBgkqhkiG9w0BAQsFADA8
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
UlNBIDIwNDggTTAxMB4XDTIzMDcxMDAwMDAwMFoXDTI0MDYyMTIzNTk1OVowGzEZ UlNBIDIwNDggTTAxMB4XDTIzMTAxMDAwMDAwMFoXDTI0MDcxMDIzNTk1OVowGzEZ
MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMhVo8GFFI8V3qJuBvo9Mcp9O2FkASu1No2kmnXcZn6rqV5Z9Rdz ADCCAQoCggEBANbrGvFbxrAM6TKussVOuHpCNsZX1V+jR6TAfzrO8VQWqiz+DCq+
DSTMBkgBz1UNxyOJ4HujSSjgqrDJ0Fv2uZ+xUfwh8wsZagpoMp6D53nOqzZxwmzi LlGFT2is2kRxY+hv2NswgK+Ie4SUdypQDrJ+mKFadmM2UOqIcFepA4EIUESAXZHg
rs7iGbBHZ0TvROel/zUEayjwm1CpEhM6fPGArITcAUcBZ0kaDLrStyijuqaQQasP lHJAv5460i6gp9Lh6imN3jGjC1Ax0rgrfBZA+uzIy8dorBEptIj/YpE4wD4WPHnk
cnjcsTili+vWk4VhPNXKg9lkwQaWmcj/iUENx2l4Fqe6e93CmlqhYPMyf4lH2oiz Y+wCDfMZdm6b6hqsrOkbqBWHH2zSH8TWfnYRguGe3NkLpM4pBNa2lTb1GBeZtm/W
MX7WZdR1w2bMIP/+J1AAuoll2y0CF60/7w+NidmpGQyujOUV2YPFYhJc0mLRyY0c TB3dEAaxcGCu+WQbicI6BxkbzklgxKTHZ2Lc3mL8P5Ca1yWQG3asdUxw0SIkCZVd
btSo589TxMmhGbKwMywKQbXLueAC/CK0fUUCAwEAAaOCBXwwggV4MB8GA1UdIwQY aCzQxqtLlXSxpe4xK2KjOfq2ZM+MZhq/tR0CAwEAAaOCBVgwggVUMB8GA1UdIwQY
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBSP/UslcNwoVtOJhOQj MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBQi0miDsNb3pJw4EouH
scAlxpUVVjCCAqwGA1UdEQSCAqMwggKfghBzMy5hbWF6b25hd3MuY29tghIqLnMz AR3hoCAaqzCCAokGA1UdEQSCAoAwggJ8ghBzMy5hbWF6b25hd3MuY29tghIqLnMz
LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou
czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h
@@ -164,29 +164,28 @@ LWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLiouczMtY29udHJvbC5k
dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh
bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50 bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz
dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIhKi5zMy51cy1lYXN0LTEudnBj dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYInKi5zMy1kZXByZWNhdGVkLnVz
ZS5hbWF6b25hd3MuY29tgicqLnMzLWRlcHJlY2F0ZWQudXMtZWFzdC0xLmFtYXpv LWVhc3QtMS5hbWF6b25hd3MuY29tgiVzMy1kZXByZWNhdGVkLnVzLWVhc3QtMS5h
bmF3cy5jb22CJXMzLWRlcHJlY2F0ZWQudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22C bWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0xLmFtYXpvbmF3cy5jb22CHSouczMt
G3MzLWV4dGVybmFsLTEuYW1hem9uYXdzLmNvbYIdKi5zMy1leHRlcm5hbC0xLmFt ZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0yLmFtYXpvbmF3
YXpvbmF3cy5jb22CG3MzLWV4dGVybmFsLTIuYW1hem9uYXdzLmNvbYIdKi5zMy1l cy5jb22CHSouczMtZXh0ZXJuYWwtMi5hbWF6b25hd3MuY29tMBMGA1UdIAQMMAow
eHRlcm5hbC0yLmFtYXpvbmF3cy5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW CAYGZ4EMAQIBMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8v KwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0wMS5hbWF6
Y3JsLnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5jcmwwEwYDVR0gBAwwCjAI b250cnVzdC5jb20vcjJtMDEuY3JsMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw
BgZngQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2Nz AYYhaHR0cDovL29jc3AucjJtMDEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC
cC5yMm0wMS5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQu hipodHRwOi8vY3J0LnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5jZXIwDAYD
cjJtMDEuYW1hem9udHJ1c3QuY29tL3IybTAxLmNlcjAMBgNVHRMBAf8EAjAAMIIB VR0TAQH/BAIwADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYA7s3QZNXbGs7F
fgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdwDuzdBk1dsazsVct520zROiModGfLzs XLedtM0TojKHRny87N7DUUhZRnEftZsAAAGLG2S5PwAABAMARzBFAiEAxOJvK1tq
3sNRSFlGcR+1mwAAAYlCAMrQAAAEAwBIMEYCIQCJhWcUFTgBlQtPboTv0HorPNkz gzf5d6NPN4PZui5PhQePCg1bH/fVMd7T5ekCIHeOglhFW5BC0TNeHY+cfUOvDONT
l+/o8Fr1hFYfs+8bIQIhAOaCRLr5774k0iflsslqBMmubN3NC+mImezWIaMHPP26 DV4fAVcaWsBXErw9AHUASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMA
AHUA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGJQgDK8gAABAMA AAGLG2S5LwAABAMARjBEAiBYu16xOFIzUE9aMrB1vrFkTsMC3veucw9k0Hv4qO2v
RjBEAiBalCI6KSCFXMTY15CgLEHtqeE/vyihg8FWthX4JgPcFwIgWkI//yF+tqBi XAIgTTMRV9sq+ytuTU53XdoKLF33qeUZHGqop7O7xoFEENMAdgDatr9rP7W2Ip+b
Gs3sHuuGvG4v7rytkUM4Dli6sWAYXsYAdgA7U3d1Pi25gE6LMFsG/kA7Z9hPw/TH wrtca+hwkXFsu1GEhTS9pD0wSNf7qwAAAYsbZLlmAAAEAwBHMEUCIQCD6n2r6DVx
vQANLXJv4frUFwAAAYlCAMsyAAAEAwBHMEUCIQDfn+j2sutaXvO5yZ86z6OFgq1u UMUgtfPRi3ieJdlObPzsrc0aGVhl6gCP5QIgbzkLqEOfJ7bozTgYzUO8ZDvAd0te
WhNwM2MnEHfGhO+yCAIgLYi8SX6hZRGRZFxIrV1ekcRSk+9yN8oHNfOQOuGQQOEw cdpZv182ZEQ974wwDQYJKoZIhvcNAQELBQADggEBAHEAZnHOPS7CoRXWTqWbQu5V
DQYJKoZIhvcNAQELBQADggEBAIprc7vYrAerkphosDZ2frlk9gYBnlgTYT0wJXLC 8x2uFNl5jjsbSH68xnviW24ShllvFyHH1iD2R3ov/3Ri8T8TJ0bA14u+3D/iPZk1
4ZTnlhXuMbL5gYmM8T1suPv5p2JphVFEsSS8PlmdQX45mPAlk8lHjHSZJRgL/r1Y BgX2/YdL/0/CptgISLhBtugBk2+MsRry6i7hhbf4/pIyL1uWHUeDuYrW882Xw1ul
7wWYjKB3oHl5N/5UZTtDTtfxtjd/3Vts6citxzhVwGxH+fQspligvb1Sgy8/ojjV uD1wyC1z2CqXZWy0WL0zMV6Yfp/eFnCJ9tj0NoullHGhgk9RTU3qULwuAQmzMqS7
lSz+QwpK2PrxRwvWPt0XImPj+5xPi8MOhRCh32Edtqy5fQkZiG/mYEvMMpq73kv0 XlhmgdzVPDq3s8qCawHDU6yDdT5FAO3SJ23Dj2efM7enBzq0jryfEZn9vTCRJfKI
uWbcjMFN2XbSOSYkjjseVoTBly65MAxFyAFAdg9HMJeJ5hbegpl4PARhgdL8sG3h yCZT56FgMdEqvmQutAV5UCiL1acK8YU2zUQSxuWn+AyDivV4JSOYw8ho1yZrZZI=
jEenWaFiCjwQ4iCPFeGk+vumNkL1c5OaLFZwhoZQ+KLkAQc=
-----END CERTIFICATE----- -----END CERTIFICATE-----

BIN
server_certs/r2m01.cer.31 Normal file

Binary file not shown.

View File

@@ -1,16 +1,16 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIIXzCCB0egAwIBAgIQBKU3dDawNcfrgz6Dj4jGVjANBgkqhkiG9w0BAQsFADA8 MIIIOzCCByOgAwIBAgIQDMnYcxFdn1+HZt0ULgDEwTANBgkqhkiG9w0BAQsFADA8
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
UlNBIDIwNDggTTAxMB4XDTIzMDcxMDAwMDAwMFoXDTI0MDYyMTIzNTk1OVowGzEZ UlNBIDIwNDggTTAxMB4XDTIzMTAxMDAwMDAwMFoXDTI0MDcxMDIzNTk1OVowGzEZ
MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP MBcGA1UEAxMQczMuYW1hem9uYXdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMhVo8GFFI8V3qJuBvo9Mcp9O2FkASu1No2kmnXcZn6rqV5Z9Rdz ADCCAQoCggEBANbrGvFbxrAM6TKussVOuHpCNsZX1V+jR6TAfzrO8VQWqiz+DCq+
DSTMBkgBz1UNxyOJ4HujSSjgqrDJ0Fv2uZ+xUfwh8wsZagpoMp6D53nOqzZxwmzi LlGFT2is2kRxY+hv2NswgK+Ie4SUdypQDrJ+mKFadmM2UOqIcFepA4EIUESAXZHg
rs7iGbBHZ0TvROel/zUEayjwm1CpEhM6fPGArITcAUcBZ0kaDLrStyijuqaQQasP lHJAv5460i6gp9Lh6imN3jGjC1Ax0rgrfBZA+uzIy8dorBEptIj/YpE4wD4WPHnk
cnjcsTili+vWk4VhPNXKg9lkwQaWmcj/iUENx2l4Fqe6e93CmlqhYPMyf4lH2oiz Y+wCDfMZdm6b6hqsrOkbqBWHH2zSH8TWfnYRguGe3NkLpM4pBNa2lTb1GBeZtm/W
MX7WZdR1w2bMIP/+J1AAuoll2y0CF60/7w+NidmpGQyujOUV2YPFYhJc0mLRyY0c TB3dEAaxcGCu+WQbicI6BxkbzklgxKTHZ2Lc3mL8P5Ca1yWQG3asdUxw0SIkCZVd
btSo589TxMmhGbKwMywKQbXLueAC/CK0fUUCAwEAAaOCBXwwggV4MB8GA1UdIwQY aCzQxqtLlXSxpe4xK2KjOfq2ZM+MZhq/tR0CAwEAAaOCBVgwggVUMB8GA1UdIwQY
MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBSP/UslcNwoVtOJhOQj MBaAFIG4DmOKiRIY5fo7O1CVn+blkBOFMB0GA1UdDgQWBBQi0miDsNb3pJw4EouH
scAlxpUVVjCCAqwGA1UdEQSCAqMwggKfghBzMy5hbWF6b25hd3MuY29tghIqLnMz AR3hoCAaqzCCAokGA1UdEQSCAoAwggJ8ghBzMy5hbWF6b25hd3MuY29tghIqLnMz
LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h LmFtYXpvbmF3cy5jb22CJiouczMuZHVhbHN0YWNrLnVzLWVhc3QtMS5hbWF6b25h
d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou d3MuY29tgiRzMy5kdWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CHCou
czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h czMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CGnMzLnVzLWVhc3QtMS5hbWF6b25h
@@ -19,29 +19,28 @@ LWNvbnRyb2wudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLiouczMtY29udHJvbC5k
dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh dWFsc3RhY2sudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22CLHMzLWNvbnRyb2wuZHVh
bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50 bHN0YWNrLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgigqLnMzLWFjY2Vzc3BvaW50
LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz LnVzLWVhc3QtMS5hbWF6b25hd3MuY29tgjIqLnMzLWFjY2Vzc3BvaW50LmR1YWxz
dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYIhKi5zMy51cy1lYXN0LTEudnBj dGFjay51cy1lYXN0LTEuYW1hem9uYXdzLmNvbYInKi5zMy1kZXByZWNhdGVkLnVz
ZS5hbWF6b25hd3MuY29tgicqLnMzLWRlcHJlY2F0ZWQudXMtZWFzdC0xLmFtYXpv LWVhc3QtMS5hbWF6b25hd3MuY29tgiVzMy1kZXByZWNhdGVkLnVzLWVhc3QtMS5h
bmF3cy5jb22CJXMzLWRlcHJlY2F0ZWQudXMtZWFzdC0xLmFtYXpvbmF3cy5jb22C bWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0xLmFtYXpvbmF3cy5jb22CHSouczMt
G3MzLWV4dGVybmFsLTEuYW1hem9uYXdzLmNvbYIdKi5zMy1leHRlcm5hbC0xLmFt ZXh0ZXJuYWwtMS5hbWF6b25hd3MuY29tghtzMy1leHRlcm5hbC0yLmFtYXpvbmF3
YXpvbmF3cy5jb22CG3MzLWV4dGVybmFsLTIuYW1hem9uYXdzLmNvbYIdKi5zMy1l cy5jb22CHSouczMtZXh0ZXJuYWwtMi5hbWF6b25hd3MuY29tMBMGA1UdIAQMMAow
eHRlcm5hbC0yLmFtYXpvbmF3cy5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW CAYGZ4EMAQIBMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8v KwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0wMS5hbWF6
Y3JsLnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5jcmwwEwYDVR0gBAwwCjAI b250cnVzdC5jb20vcjJtMDEuY3JsMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw
BgZngQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2Nz AYYhaHR0cDovL29jc3AucjJtMDEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC
cC5yMm0wMS5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQu hipodHRwOi8vY3J0LnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5jZXIwDAYD
cjJtMDEuYW1hem9udHJ1c3QuY29tL3IybTAxLmNlcjAMBgNVHRMBAf8EAjAAMIIB VR0TAQH/BAIwADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYA7s3QZNXbGs7F
fgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdwDuzdBk1dsazsVct520zROiModGfLzs XLedtM0TojKHRny87N7DUUhZRnEftZsAAAGLG2S5PwAABAMARzBFAiEAxOJvK1tq
3sNRSFlGcR+1mwAAAYlCAMrQAAAEAwBIMEYCIQCJhWcUFTgBlQtPboTv0HorPNkz gzf5d6NPN4PZui5PhQePCg1bH/fVMd7T5ekCIHeOglhFW5BC0TNeHY+cfUOvDONT
l+/o8Fr1hFYfs+8bIQIhAOaCRLr5774k0iflsslqBMmubN3NC+mImezWIaMHPP26 DV4fAVcaWsBXErw9AHUASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMA
AHUA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGJQgDK8gAABAMA AAGLG2S5LwAABAMARjBEAiBYu16xOFIzUE9aMrB1vrFkTsMC3veucw9k0Hv4qO2v
RjBEAiBalCI6KSCFXMTY15CgLEHtqeE/vyihg8FWthX4JgPcFwIgWkI//yF+tqBi XAIgTTMRV9sq+ytuTU53XdoKLF33qeUZHGqop7O7xoFEENMAdgDatr9rP7W2Ip+b
Gs3sHuuGvG4v7rytkUM4Dli6sWAYXsYAdgA7U3d1Pi25gE6LMFsG/kA7Z9hPw/TH wrtca+hwkXFsu1GEhTS9pD0wSNf7qwAAAYsbZLlmAAAEAwBHMEUCIQCD6n2r6DVx
vQANLXJv4frUFwAAAYlCAMsyAAAEAwBHMEUCIQDfn+j2sutaXvO5yZ86z6OFgq1u UMUgtfPRi3ieJdlObPzsrc0aGVhl6gCP5QIgbzkLqEOfJ7bozTgYzUO8ZDvAd0te
WhNwM2MnEHfGhO+yCAIgLYi8SX6hZRGRZFxIrV1ekcRSk+9yN8oHNfOQOuGQQOEw cdpZv182ZEQ974wwDQYJKoZIhvcNAQELBQADggEBAHEAZnHOPS7CoRXWTqWbQu5V
DQYJKoZIhvcNAQELBQADggEBAIprc7vYrAerkphosDZ2frlk9gYBnlgTYT0wJXLC 8x2uFNl5jjsbSH68xnviW24ShllvFyHH1iD2R3ov/3Ri8T8TJ0bA14u+3D/iPZk1
4ZTnlhXuMbL5gYmM8T1suPv5p2JphVFEsSS8PlmdQX45mPAlk8lHjHSZJRgL/r1Y BgX2/YdL/0/CptgISLhBtugBk2+MsRry6i7hhbf4/pIyL1uWHUeDuYrW882Xw1ul
7wWYjKB3oHl5N/5UZTtDTtfxtjd/3Vts6citxzhVwGxH+fQspligvb1Sgy8/ojjV uD1wyC1z2CqXZWy0WL0zMV6Yfp/eFnCJ9tj0NoullHGhgk9RTU3qULwuAQmzMqS7
lSz+QwpK2PrxRwvWPt0XImPj+5xPi8MOhRCh32Edtqy5fQkZiG/mYEvMMpq73kv0 XlhmgdzVPDq3s8qCawHDU6yDdT5FAO3SJ23Dj2efM7enBzq0jryfEZn9vTCRJfKI
uWbcjMFN2XbSOSYkjjseVoTBly65MAxFyAFAdg9HMJeJ5hbegpl4PARhgdL8sG3h yCZT56FgMdEqvmQutAV5UCiL1acK8YU2zUQSxuWn+AyDivV4JSOYw8ho1yZrZZI=
jEenWaFiCjwQ4iCPFeGk+vumNkL1c5OaLFZwhoZQ+KLkAQc=
-----END CERTIFICATE----- -----END CERTIFICATE-----