You are on page 1of 842

self.

killChild();

// XXX need to wait a little bit for the restart to work?


setTimeout(function() {
self.trySpawn();
self.resume();
}, 1000);
};

// Print version
Interface.prototype.version = function() {
if (!this.requireConnection()) return;

var self = this;

this.pause();
this.client.reqVersion(function(err, v) {
if (err) {
self.error(err);
} else {
self.print(v);
}
self.resume();
});
};

// List source code


Interface.prototype.list = function(delta) {
if (!this.requireConnection()) return;

delta || (delta = 5);

var self = this,


client = this.client,
from = client.currentSourceLine - delta + 1,
to = client.currentSourceLine + delta + 1;

self.pause();
client.reqSource(from, to, function(err, res) {
if (err || !res) {
self.error('You can\'t list source code right now');
self.resume();
return;
}

var lines = res.source.split('\n');


for (var i = 0; i < lines.length; i++) {
var lineno = res.fromLine + i + 1;
if (lineno < from || lineno > to) continue;

var current = lineno == 1 + client.currentSourceLine,


breakpoint = client.breakpoints.some(function(bp) {
return bp.script === client.currentScript &&
bp.line == lineno;
});

if (lineno == 1) {
// The first line needs to have the module wrapper filtered out of
// it.
var wrapper = require('module').wrapper[0];
lines[i] = lines[i].slice(wrapper.length);

client.currentSourceColumn -= wrapper.length;
}

// Highlight executing statement


var line;
if (current) {
line = SourceUnderline(lines[i],
client.currentSourceColumn,
self.repl);
} else {
line = lines[i];
}

self.print(leftPad(lineno, breakpoint && '*') + ' ' + line);


}
self.resume();
});
};

// Print backtrace
Interface.prototype.backtrace = function() {
if (!this.requireConnection()) return;

var self = this,


client = this.client;

self.pause();
client.fullTrace(function(err, bt) {
if (err) {
self.error('Can\'t request backtrace now');
self.resume();
return;
}

if (bt.totalFrames == 0) {
self.print('(empty stack)');
} else {
var trace = [],
firstFrameNative = bt.frames[0].script.isNative;

for (var i = 0; i < bt.frames.length; i++) {


var frame = bt.frames[i];
if (!firstFrameNative && frame.script.isNative) break;

var text = '#' + i + ' ';


if (frame.func.inferredName && frame.func.inferredName.length > 0) {
text += frame.func.inferredName + ' ';
}
text += path.basename(frame.script.name) + ':';
text += (frame.line + 1) + ':' + (frame.column + 1);

trace.push(text);
}

self.print(trace.join('\n'));
}

self.resume();
});
};

// First argument tells if it should display internal node scripts or not


// (available only for internal debugger's functions)
Interface.prototype.scripts = function() {
if (!this.requireConnection()) return;

var client = this.client,


displayNatives = arguments[0] || false,
scripts = [];

this.pause();
for (var id in client.scripts) {
var script = client.scripts[id];
if (typeof script == 'object' && script.name) {
if (displayNatives ||
script.name == client.currentScript ||
!script.isNative) {
scripts.push(
(script.name == client.currentScript ? '* ' : ' ') +
id + ': ' +
path.basename(script.name)
);
}
}
}
this.print(scripts.join('\n'));
this.resume();
};

// Continue execution of script


Interface.prototype.cont = function() {
if (!this.requireConnection()) return;
this.pause();

var self = this;


this.client.reqContinue(function(err) {
if (err) self.error(err);
self.resume();
});
};

// Step commands generator


Interface.stepGenerator = function(type, count) {
return function() {
if (!this.requireConnection()) return;

var self = this;

self.pause();
self.client.step(type, count, function(err, res) {
if (err) self.error(err);
self.resume();
});
};
};

// Jump to next command


Interface.prototype.next = Interface.stepGenerator('next', 1);

// Step in
Interface.prototype.step = Interface.stepGenerator('in', 1);

// Step out
Interface.prototype.out = Interface.stepGenerator('out', 1);

// Watch
Interface.prototype.watch = function(expr) {
this._watchers.push(expr);
};

// Unwatch
Interface.prototype.unwatch = function(expr) {
var index = this._watchers.indexOf(expr);

// Unwatch by expression
// or
// Unwatch by watcher number
this._watchers.splice(index !== -1 ? index : +expr, 1);
};

// List watchers
Interface.prototype.watchers = function() {
var self = this,
verbose = arguments[0] || false,
callback = arguments[1] || function() {},
waiting = this._watchers.length,
values = [];

this.pause();

if (!waiting) {
this.resume();

return callback();
}

this._watchers.forEach(function(watcher, i) {
self.debugEval(watcher, null, null, function(err, value) {
values[i] = err ? '<error>' : value;
wait();
});
});

function wait() {
if (--waiting === 0) {
if (verbose) self.print('Watchers:');
self._watchers.forEach(function(watcher, i) {
self.print(leftPad(i, ' ') + ': ' + watcher + ' = ' +
JSON.stringify(values[i]));
});

if (verbose) self.print('');

self.resume();

callback(null);
}
}
};

// Break on exception
Interface.prototype.breakOnException = function breakOnException() {
if (!this.requireConnection()) return;

var self = this;

// Break on exceptions
this.pause();
this.client.reqSetExceptionBreak('all', function(err, res) {
self.resume();
});
};

// Add breakpoint
Interface.prototype.setBreakpoint = function(script, line,
condition, silent) {
if (!this.requireConnection()) return;

var self = this,


scriptId,
ambiguous;

// setBreakpoint() should insert breakpoint on current line


if (script === undefined) {
script = this.client.currentScript;
line = this.client.currentSourceLine + 1;
}

// setBreakpoint(line-number) should insert breakpoint in current script


if (line === undefined && typeof script === 'number') {
line = script;
script = this.client.currentScript;
}

if (/\(\)$/.test(script)) {
// setBreakpoint('functionname()');
var req = {
type: 'function',
target: script.replace(/\(\)$/, ''),
condition: condition
};
} else {
// setBreakpoint('scriptname')
if (script != +script && !this.client.scripts[script]) {
var scripts = this.client.scripts;
Object.keys(scripts).forEach(function(id) {
if (scripts[id] && scripts[id].name.indexOf(script) !== -1) {
if (scriptId) {
ambiguous = true;
}
scriptId = id;
}
});
} else {
scriptId = script;
}

if (!scriptId) return this.error('Script : ' + script + ' not found');


if (ambiguous) return this.error('Script name is ambiguous');
if (line <= 0) return this.error('Line should be a positive value');

var req = {
type: 'scriptId',
target: scriptId,
line: line - 1,
condition: condition
};
}

self.pause();
self.client.setBreakpoint(req, function(err, res) {
if (err) {
if (!silent) {
self.error(err);
}
} else {
if (!silent) {
self.list(5);
}

// Try load scriptId and line from response


if (!scriptId) {
scriptId = res.script_id;
line = res.line;
}

// If we finally have one - remember this breakpoint


if (scriptId) {
self.client.breakpoints.push({
id: res.breakpoint,
scriptId: scriptId,
script: (self.client.scripts[scriptId] || {}).name,
line: line,
condition: condition
});
}

}
self.resume();
});
};

// Clear breakpoint
Interface.prototype.clearBreakpoint = function(script, line) {
if (!this.requireConnection()) return;

var ambiguous,
breakpoint,
index;

this.client.breakpoints.some(function(bp, i) {
if (bp.scriptId === script || bp.script.indexOf(script) !== -1) {
if (index !== undefined) {
ambiguous = true;
}
if (bp.line === line) {
index = i;
breakpoint = bp.id;
return true;
}
}
});

if (ambiguous) return this.error('Script name is ambiguous');

if (breakpoint === undefined) {


return this.error('Script : ' + script + ' not found');
}

var self = this,


req = {
breakpoint: breakpoint
};

self.pause();
self.client.clearBreakpoint(req, function(err, res) {
if (err) {
self.error(err);
} else {
self.client.breakpoints.splice(index, 1);
self.list(5);
}
self.resume();
});
};

// Show breakpoints
Interface.prototype.breakpoints = function() {
if (!this.requireConnection()) return;

this.pause();
var self = this;
this.client.listbreakpoints(function(err, res) {
if (err) {
self.error(err);
} else {
self.print(res);
self.resume();
}
});
};
// Pause child process
Interface.prototype.pause_ = function() {
if (!this.requireConnection()) return;

var self = this,


cmd = 'process._debugPause();';

this.pause();
this.client.reqFrameEval(cmd, NO_FRAME, function(err, res) {
if (err) {
self.error(err);
} else {
self.resume();
}
});
};

// Kill child process


Interface.prototype.kill = function() {
if (!this.child) return;
this.killChild();
};

// Activate debug repl


Interface.prototype.repl = function() {
if (!this.requireConnection()) return;

var self = this;

self.print('Press Ctrl + C to leave debug repl');

// Don't display any default messages


var listeners = this.repl.rli.listeners('SIGINT').slice(0);
this.repl.rli.removeAllListeners('SIGINT');

// Exit debug repl on Ctrl + C


this.repl.rli.once('SIGINT', function() {
// Restore all listeners
process.nextTick(function() {
listeners.forEach(function(listener) {
self.repl.rli.on('SIGINT', listener);
});
});

// Exit debug repl


self.exitRepl();
});

// Set new
this.repl.eval = this.debugEval.bind(this);
this.repl.context = {};

// Swap history
this.history.control = this.repl.rli.history;
this.repl.rli.history = this.history.debug;
this.repl.prompt = '> ';
this.repl.rli.setPrompt('> ');
this.repl.displayPrompt();
};

// Exit debug repl


Interface.prototype.exitRepl = function() {
// Restore eval
this.repl.eval = this.controlEval.bind(this);

// Swap history
this.history.debug = this.repl.rli.history;
this.repl.rli.history = this.history.control;

this.repl.context = this.context;
this.repl.prompt = 'debug> ';
this.repl.rli.setPrompt('debug> ');
this.repl.displayPrompt();
};

// Quit
Interface.prototype.quit = function() {
this.killChild();
process.exit(0);
};

// Kills child process


Interface.prototype.killChild = function() {
if (this.child) {
this.child.kill();
this.child = null;
}

if (this.client) {
// Save breakpoints
this.breakpoints = this.client.breakpoints;

this.client.destroy();
this.client = null;
}
};

// Spawns child process (and restores breakpoints)


Interface.prototype.trySpawn = function(cb) {
var self = this,
breakpoints = this.breakpoints || [],
port = exports.port,
host = 'localhost';

this.killChild();

if (this.args.length === 2) {
var match = this.args[1].match(/^([^:]+):(\d+)$/);
if (match) {
// Connecting to remote debugger
// `node debug localhost:5858`
host = match[1];
port = parseInt(match[2], 10);
this.child = {
kill: function() {
// TODO Do we really need to handle it?
}
};
}
} else if (this.args.length === 3) {
// `node debug -p pid`
if (this.args[1] === '-p' && /^\d+$/.test(this.args[2])) {
this.child = {
kill: function() {
// TODO Do we really need to handle it?
}
};
process._debugProcess(parseInt(this.args[2], 10));
} else {
var match = this.args[1].match(/^--port=(\d+)$/);
if (match) {
// Start debugger on custom port
// `node debug --port=5858 app.js`
port = parseInt(match[1], 10);
this.args.splice(0, 2, '--debug-brk=' + port);
}
}
}

if (!this.child) {
this.child = spawn(process.execPath, this.args);

this.child.stdout.on('data', this.childPrint.bind(this));
this.child.stderr.on('data', this.childPrint.bind(this));
}

this.pause();

var client = self.client = new Client(),


connectionAttempts = 0;

client.once('ready', function() {
self.stdout.write(' ok\n');

// Restore breakpoints
breakpoints.forEach(function(bp) {
self.setBreakpoint(bp.scriptId, bp.line, bp.condition, true);
});

client.on('close', function() {
self.pause();
self.print('program terminated');
self.resume();
self.client = null;
self.killChild();
});
if (cb) cb();
self.resume();
});

client.on('unhandledResponse', function(res) {
self.pause();
self.print('\nunhandled res:' + JSON.stringify(res));
self.resume();
});

client.on('break', function(res) {
self.handleBreak(res.body);
});

client.on('exception', function(res) {
self.handleBreak(res.body);
});

client.on('error', connectError);
function connectError() {
// If it's failed to connect 4 times then don't catch the next error
if (connectionAttempts >= 10) {
client.removeListener('error', connectError);
}
setTimeout(attemptConnect, 500);
}

function attemptConnect() {
++connectionAttempts;
self.stdout.write('.');
client.connect(port, host);
}

setTimeout(function() {
self.print('connecting..', true);
attemptConnect();
}, 50);
};
#######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function init(list) {
list._idleNext = list;
list._idlePrev = list;
}
exports.init = init;

// show the most idle item


function peek(list) {
if (list._idlePrev == list) return null;
return list._idlePrev;
}
exports.peek = peek;

// remove the most idle item from the list


function shift(list) {
var first = list._idlePrev;
remove(first);
return first;
}
exports.shift = shift;

// remove a item from its list


function remove(item) {
if (item._idleNext) {
item._idleNext._idlePrev = item._idlePrev;
}

if (item._idlePrev) {
item._idlePrev._idleNext = item._idleNext;
}

item._idleNext = null;
item._idlePrev = null;
}
exports.remove = remove;

// remove a item from its list and place at the end.


function append(list, item) {
remove(item);
item._idleNext = list._idleNext;
list._idleNext._idlePrev = item;
item._idlePrev = list;
list._idleNext = item;
}
exports.append = append;

function isEmpty(list) {
return list._idleNext === list;
}
exports.isEmpty = isEmpty;
#// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
//
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
//
// Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// UTILITY
var util = require('util');
var pSlice = Array.prototype.slice;

// 1. The assert module provides functions that throw


// AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface.

var assert = module.exports = ok;

// 2. The AssertionError is defined in assert.


// new assert.AssertionError({ message: message,
// actual: actual,
// expected: expected })

assert.AssertionError = function AssertionError(options) {


this.name = 'AssertionError';
this.message = options.message;
this.actual = options.actual;
this.expected = options.expected;
this.operator = options.operator;
var stackStartFunction = options.stackStartFunction || fail;

if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction);
}
};

// assert.AssertionError instanceof Error


util.inherits(assert.AssertionError, Error);

function replacer(key, value) {


if (value === undefined) {
return '' + value;
}
if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
return value.toString();
}
if (typeof value === 'function' || value instanceof RegExp) {
return value.toString();
}
return value;
}

function truncate(s, n) {
if (typeof s == 'string') {
return s.length < n ? s : s.slice(0, n);
} else {
return s;
}
}

assert.AssertionError.prototype.toString = function() {
if (this.message) {
return [this.name + ':', this.message].join(' ');
} else {
return [
this.name + ':',
truncate(JSON.stringify(this.actual, replacer), 128),
this.operator,
truncate(JSON.stringify(this.expected, replacer), 128)
].join(' ');
}
};

// At present only the three keys mentioned above are used and
// understood by the spec. Implementations or sub modules can pass
// other keys to the AssertionError's constructor - they will be
// ignored.

// 3. All of the following functions must throw an AssertionError


// when a corresponding condition is not met, with a message that
// may be undefined if not provided. All assertion methods provide
// both the actual and expected values to the assertion error for
// display purposes.

function fail(actual, expected, message, operator, stackStartFunction) {


throw new assert.AssertionError({
message: message,
actual: actual,
expected: expected,
operator: operator,
stackStartFunction: stackStartFunction
});
}

// EXTENSION! allows for well behaved errors defined elsewhere.


assert.fail = fail;

// 4. Pure assertion tests whether a value is truthy, as determined


// by !!guard.
// assert.ok(guard, message_opt);
// This statement is equivalent to assert.equal(true, !!guard,
// message_opt);. To test strictly for the value true, use
// assert.strictEqual(true, guard, message_opt);.

function ok(value, message) {


if (!!!value) fail(value, true, message, '==', assert.ok);
}
assert.ok = ok;

// 5. The equality assertion tests shallow, coercive equality with


// ==.
// assert.equal(actual, expected, message_opt);

assert.equal = function equal(actual, expected, message) {


if (actual != expected) fail(actual, expected, message, '==', assert.equal);
};

// 6. The non-equality assertion tests for whether two objects are not equal
// with != assert.notEqual(actual, expected, message_opt);

assert.notEqual = function notEqual(actual, expected, message) {


if (actual == expected) {
fail(actual, expected, message, '!=', assert.notEqual);
}
};

// 7. The equivalence assertion tests a deep equality relation.


// assert.deepEqual(actual, expected, message_opt);

assert.deepEqual = function deepEqual(actual, expected, message) {


if (!_deepEqual(actual, expected)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};

function _deepEqual(actual, expected) {


// 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) {
return true;

} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {


if (actual.length != expected.length) return false;

for (var i = 0; i < actual.length; i++) {


if (actual[i] !== expected[i]) return false;
}

return true;

// 7.2. If the expected value is a Date object, the actual value is


// equivalent if it is also a Date object that refers to the same time.
} else if (actual instanceof Date && expected instanceof Date) {
return actual.getTime() === expected.getTime();

// 7.3 If the expected value is a RegExp object, the actual value is


// equivalent if it is also a RegExp object with the same source and
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
} else if (actual instanceof RegExp && expected instanceof RegExp) {
return actual.source === expected.source &&
actual.global === expected.global &&
actual.multiline === expected.multiline &&
actual.lastIndex === expected.lastIndex &&
actual.ignoreCase === expected.ignoreCase;

// 7.4. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==.
} else if (typeof actual != 'object' && typeof expected != 'object') {
return actual == expected;

// 7.5 For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified
// with Object.prototype.hasOwnProperty.call), the same set of keys
// (although not necessarily the same order), equivalent values for every
// corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays.
} else {
return objEquiv(actual, expected);
}
}

function isUndefinedOrNull(value) {
return value === null || value === undefined;
}

function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]';
}

function objEquiv(a, b) {
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
return false;
// an identical 'prototype' property.
if (a.prototype !== b.prototype) return false;
//~~~I've managed to break Object.keys through screwy arguments passing.
// Converting to array solves the problem.
if (isArguments(a)) {
if (!isArguments(b)) {
return false;
}
a = pSlice.call(a);
b = pSlice.call(b);
return _deepEqual(a, b);
}
try {
var ka = Object.keys(a),
kb = Object.keys(b),
key, i;
} catch (e) {//happens when one is a string literal and the other isn't
return false;
}
// having the same number of owned properties (keys incorporates
// hasOwnProperty)
if (ka.length != kb.length)
return false;
//the same set of keys (although not necessarily the same order),
ka.sort();
kb.sort();
//~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] != kb[i])
return false;
}
//equivalent values for every corresponding key, and
//~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) {
key = ka[i];
if (!_deepEqual(a[key], b[key])) return false;
}
return true;
}

// 8. The non-equivalence assertion tests for any deep inequality.


// assert.notDeepEqual(actual, expected, message_opt);

assert.notDeepEqual = function notDeepEqual(actual, expected, message) {


if (_deepEqual(actual, expected)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
}
};

// 9. The strict equality assertion tests strict equality, as determined by ===.


// assert.strictEqual(actual, expected, message_opt);

assert.strictEqual = function strictEqual(actual, expected, message) {


if (actual !== expected) {
fail(actual, expected, message, '===', assert.strictEqual);
}
};

// 10. The strict non-equality assertion tests for strict inequality, as


// determined by !==. assert.notStrictEqual(actual, expected, message_opt);

assert.notStrictEqual = function notStrictEqual(actual, expected, message) {


if (actual === expected) {
fail(actual, expected, message, '!==', assert.notStrictEqual);
}
};

function expectedException(actual, expected) {


if (!actual || !expected) {
return false;
}

if (expected instanceof RegExp) {


return expected.test(actual);
} else if (actual instanceof expected) {
return true;
} else if (expected.call({}, actual) === true) {
return true;
}

return false;
}

function _throws(shouldThrow, block, expected, message) {


var actual;

if (typeof expected === 'string') {


message = expected;
expected = null;
}

try {
block();
} catch (e) {
actual = e;
}

message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +


(message ? ' ' + message : '.');

if (shouldThrow && !actual) {


fail(actual, expected, 'Missing expected exception' + message);
}

if (!shouldThrow && expectedException(actual, expected)) {


fail(actual, expected, 'Got unwanted exception' + message);
}

if ((shouldThrow && actual && expected &&


!expectedException(actual, expected)) || (!shouldThrow && actual)) {
throw actual;
}
}

// 11. Expected to throw an error:


// assert.throws(block, Error_opt, message_opt);

assert.throws = function(block, /*optional*/error, /*optional*/message) {


_throws.apply(this, [true].concat(pSlice.call(arguments)));
};

// EXTENSION! This is annoying to write outside this module.


assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments)));
};

assert.ifError = function(err) { if (err) {throw err;}};


#####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var SlowBuffer = process.binding('buffer').SlowBuffer;


var assert = require('assert');
exports.INSPECT_MAX_BYTES = 50;

// Make SlowBuffer inherit from Buffer.


// This is an exception to the rule that __proto__ is not allowed in core.
SlowBuffer.prototype.__proto__ = Buffer.prototype;

function toHex(n) {
if (n < 16) return '0' + n.toString(16);
return n.toString(16);
}

SlowBuffer.prototype.hexSlice = function(start, end) {


var len = this.length;

if (!start || start < 0) start = 0;


if (!end || end < 0 || end > len) end = len;

var out = '';


for (var i = start; i < end; i++) {
out += toHex(this[i]);
}
return out;
};

SlowBuffer.prototype.toString = function(encoding, start, end) {


encoding = String(encoding || 'utf8').toLowerCase();
start = +start || 0;
if (typeof end == 'undefined') end = this.length;

// Fastpath empty strings


if (+end == start) {
return '';
}

switch (encoding) {
case 'hex':
return this.hexSlice(start, end);

case 'utf8':
case 'utf-8':
return this.utf8Slice(start, end);

case 'ascii':
return this.asciiSlice(start, end);

case 'binary':
return this.binarySlice(start, end);

case 'base64':
return this.base64Slice(start, end);

case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return this.ucs2Slice(start, end);

default:
throw new Error('Unknown encoding');
}
};

SlowBuffer.prototype.hexWrite = function(string, offset, length) {


offset = +offset || 0;
var remaining = this.length - offset;
if (!length) {
length = remaining;
} else {
length = +length;
if (length > remaining) {
length = remaining;
}
}

// must be an even number of digits


var strLen = string.length;
if (strLen % 2) {
throw new Error('Invalid hex string');
}
if (length > strLen / 2) {
length = strLen / 2;
}
for (var i = 0; i < length; i++) {
var byte = parseInt(string.substr(i * 2, 2), 16);
if (isNaN(byte)) throw new Error('Invalid hex string');
this[offset + i] = byte;
}
SlowBuffer._charsWritten = i * 2;
return i;
};

SlowBuffer.prototype.write = function(string, offset, length, encoding) {


// Support both (string, offset, length, encoding)
// and the legacy (string, encoding, offset, length)
if (isFinite(offset)) {
if (!isFinite(length)) {
encoding = length;
length = undefined;
}
} else { // legacy
var swap = encoding;
encoding = offset;
offset = length;
length = swap;
}

offset = +offset || 0;
var remaining = this.length - offset;
if (!length) {
length = remaining;
} else {
length = +length;
if (length > remaining) {
length = remaining;
}
}
encoding = String(encoding || 'utf8').toLowerCase();

switch (encoding) {
case 'hex':
return this.hexWrite(string, offset, length);

case 'utf8':
case 'utf-8':
return this.utf8Write(string, offset, length);

case 'ascii':
return this.asciiWrite(string, offset, length);

case 'binary':
return this.binaryWrite(string, offset, length);

case 'base64':
return this.base64Write(string, offset, length);

case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return this.ucs2Write(string, offset, length);

default:
throw new Error('Unknown encoding');
}
};

// slice(start, end)
SlowBuffer.prototype.slice = function(start, end) {
if (end === undefined) end = this.length;

if (end > this.length) {


throw new Error('oob');
}
if (start > end) {
throw new Error('oob');
}

return new Buffer(this, end - start, +start);


};

function coerce(length) {
// Coerce length to a number (possibly NaN), round up
// in case it's fractional (e.g. 123.456). Since NaN
// comparisons are always false, use to return zero.
length = Math.ceil(+length);
return length > 0 ? length : 0;
}
var zeroBuffer = new SlowBuffer(0);

// Buffer
function Buffer(subject, encoding, offset) {
if (!(this instanceof Buffer)) {
return new Buffer(subject, encoding, offset);
}

var type;

// Are we slicing?
if (typeof offset === 'number') {
if (!Buffer.isBuffer(subject)) {
throw new Error('First argument must be a Buffer when slicing');
}

this.length = coerce(encoding);
this.parent = subject.parent ? subject.parent : subject;
this.offset = offset;
} else {
// Find the length
switch (type = typeof subject) {
case 'number':
this.length = coerce(subject);
break;

case 'string':
this.length = Buffer.byteLength(subject, encoding);
break;

case 'object': // Assume object is an array


this.length = coerce(subject.length);
break;

default:
throw new Error('First argument needs to be a number, ' +
'array or string.');
}

if (this.length > Buffer.poolSize) {


// Big buffer, just alloc one.
this.parent = new SlowBuffer(this.length);
this.offset = 0;

} else if (this.length > 0) {


// Small buffer.
if (!pool || pool.length - pool.used < this.length) allocPool();
this.parent = pool;
this.offset = pool.used;
pool.used += this.length;
if (pool.used & 7) pool.used = (pool.used + 8) & ~7;

} else {
// Zero-length buffer
this.parent = zeroBuffer;
this.offset = 0;
}

// Treat array-ish objects as a byte array.


if (isArrayIsh(subject)) {
for (var i = 0; i < this.length; i++) {
this.parent[i + this.offset] = subject[i];
}
} else if (type == 'string') {
// We are a string
this.length = this.write(subject, 0, encoding);
}
}

SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length);


}

function isArrayIsh(subject) {
return Array.isArray(subject) || Buffer.isBuffer(subject) ||
subject && typeof subject === 'object' &&
typeof subject.length === 'number';
}

exports.SlowBuffer = SlowBuffer;
exports.Buffer = Buffer;

Buffer.poolSize = 8 * 1024;
var pool;

function allocPool() {
pool = new SlowBuffer(Buffer.poolSize);
pool.used = 0;
}

// Static methods
Buffer.isBuffer = function isBuffer(b) {
return b instanceof Buffer;
};

// Inspect
Buffer.prototype.inspect = function inspect() {
var out = [],
len = this.length,
name = this.constructor.name;

for (var i = 0; i < len; i++) {


out[i] = toHex(this[i]);
if (i == exports.INSPECT_MAX_BYTES) {
out[i + 1] = '...';
break;
}
}

return '<' + name + ' ' + out.join(' ') + '>';


};

Buffer.prototype.get = function get(i) {


if (i < 0 || i >= this.length) throw new Error('oob');
return this.parent[this.offset + i];
};
Buffer.prototype.set = function set(i, v) {
if (i < 0 || i >= this.length) throw new Error('oob');
return this.parent[this.offset + i] = v;
};

// write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8')


Buffer.prototype.write = function(string, offset, length, encoding) {
// Support both (string, offset, length, encoding)
// and the legacy (string, encoding, offset, length)
if (isFinite(offset)) {
if (!isFinite(length)) {
encoding = length;
length = undefined;
}
} else { // legacy
var swap = encoding;
encoding = offset;
offset = length;
length = swap;
}

offset = +offset || 0;
var remaining = this.length - offset;
if (!length) {
length = remaining;
} else {
length = +length;
if (length > remaining) {
length = remaining;
}
}
encoding = String(encoding || 'utf8').toLowerCase();

var ret;
switch (encoding) {
case 'hex':
ret = this.parent.hexWrite(string, this.offset + offset, length);
break;

case 'utf8':
case 'utf-8':
ret = this.parent.utf8Write(string, this.offset + offset, length);
break;

case 'ascii':
ret = this.parent.asciiWrite(string, this.offset + offset, length);
break;

case 'binary':
ret = this.parent.binaryWrite(string, this.offset + offset, length);
break;

case 'base64':
// Warning: maxLength not taken into account in base64Write
ret = this.parent.base64Write(string, this.offset + offset, length);
break;
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
ret = this.parent.ucs2Write(string, this.offset + offset, length);
break;

default:
throw new Error('Unknown encoding');
}

Buffer._charsWritten = SlowBuffer._charsWritten;

return ret;
};

// toString(encoding, start=0, end=buffer.length)


Buffer.prototype.toString = function(encoding, start, end) {
encoding = String(encoding || 'utf8').toLowerCase();

if (typeof start == 'undefined' || start < 0) {


start = 0;
} else if (start > this.length) {
start = this.length;
}

if (typeof end == 'undefined' || end > this.length) {


end = this.length;
} else if (end < 0) {
end = 0;
}

start = start + this.offset;


end = end + this.offset;

switch (encoding) {
case 'hex':
return this.parent.hexSlice(start, end);

case 'utf8':
case 'utf-8':
return this.parent.utf8Slice(start, end);

case 'ascii':
return this.parent.asciiSlice(start, end);

case 'binary':
return this.parent.binarySlice(start, end);

case 'base64':
return this.parent.base64Slice(start, end);

case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return this.parent.ucs2Slice(start, end);
default:
throw new Error('Unknown encoding');
}
};

// byteLength
Buffer.byteLength = SlowBuffer.byteLength;

// fill(value, start=0, end=buffer.length)


Buffer.prototype.fill = function fill(value, start, end) {
value || (value = 0);
start || (start = 0);
end || (end = this.length);

if (typeof value === 'string') {


value = value.charCodeAt(0);
}
if (!(typeof value === 'number') || isNaN(value)) {
throw new Error('value is not a number');
}

if (end < start) throw new Error('end < start');

// Fill 0 bytes; we're done


if (end === start) return 0;
if (this.length == 0) return 0;

if (start < 0 || start >= this.length) {


throw new Error('start out of bounds');
}

if (end < 0 || end > this.length) {


throw new Error('end out of bounds');
}

return this.parent.fill(value,
start + this.offset,
end + this.offset);
};

Buffer.concat = function(list, length) {


if (!Array.isArray(list)) {
throw new Error('Usage: Buffer.concat(list, [length])');
}

if (list.length === 0) {
return new Buffer(0);
} else if (list.length === 1) {
return list[0];
}

if (typeof length !== 'number') {


length = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
length += buf.length;
}
}

var buffer = new Buffer(length);


var pos = 0;
for (var i = 0; i < list.length; i++) {
var buf = list[i];
buf.copy(buffer, pos);
pos += buf.length;
}
return buffer;
};

// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)


Buffer.prototype.copy = function(target, target_start, start, end) {
var source = this;
start || (start = 0);
end || (end = this.length);
target_start || (target_start = 0);

if (end < start) throw new Error('sourceEnd < sourceStart');

// Copy 0 bytes; we're done


if (end === start) return 0;
if (target.length == 0 || source.length == 0) return 0;

if (target_start < 0 || target_start >= target.length) {


throw new Error('targetStart out of bounds');
}

if (start < 0 || start >= source.length) {


throw new Error('sourceStart out of bounds');
}

if (end < 0 || end > source.length) {


throw new Error('sourceEnd out of bounds');
}

// Are we oob?
if (end > this.length) {
end = this.length;
}

if (target.length - target_start < end - start) {


end = target.length - target_start + start;
}

return this.parent.copy(target.parent || target,


target_start + (target.offset || 0),
start + this.offset,
end + this.offset);
};

// slice(start, end)
Buffer.prototype.slice = function(start, end) {
if (end === undefined) end = this.length;
if (end > this.length) throw new Error('oob');
if (start > end) throw new Error('oob');
if (start < 0) throw new Error('start out of bounds');
return new Buffer(this.parent, end - start, +start + this.offset);
};

// Legacy methods for backwards compatibility.

Buffer.prototype.utf8Slice = function(start, end) {


return this.toString('utf8', start, end);
};

Buffer.prototype.binarySlice = function(start, end) {


return this.toString('binary', start, end);
};

Buffer.prototype.asciiSlice = function(start, end) {


return this.toString('ascii', start, end);
};

Buffer.prototype.utf8Write = function(string, offset) {


return this.write(string, offset, 'utf8');
};

Buffer.prototype.binaryWrite = function(string, offset) {


return this.write(string, offset, 'binary');
};

Buffer.prototype.asciiWrite = function(string, offset) {


return this.write(string, offset, 'ascii');
};

Buffer.prototype.readUInt8 = function(offset, noAssert) {


var buffer = this;

if (!noAssert) {
assert.ok(offset !== undefined && offset !== null,
'missing offset');

assert.ok(offset < buffer.length,


'Trying to read beyond buffer length');
}

return buffer[offset];
};

function readUInt16(buffer, offset, isBigEndian, noAssert) {


var val = 0;

if (!noAssert) {
assert.ok(typeof (isBigEndian) === 'boolean',
'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');
assert.ok(offset + 1 < buffer.length,
'Trying to read beyond buffer length');
}

if (isBigEndian) {
val = buffer[offset] << 8;
val |= buffer[offset + 1];
} else {
val = buffer[offset];
val |= buffer[offset + 1] << 8;
}

return val;
}

Buffer.prototype.readUInt16LE = function(offset, noAssert) {


return readUInt16(this, offset, false, noAssert);
};

Buffer.prototype.readUInt16BE = function(offset, noAssert) {


return readUInt16(this, offset, true, noAssert);
};

function readUInt32(buffer, offset, isBigEndian, noAssert) {


var val = 0;

if (!noAssert) {
assert.ok(typeof (isBigEndian) === 'boolean',
'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 3 < buffer.length,


'Trying to read beyond buffer length');
}

if (isBigEndian) {
val = buffer[offset + 1] << 16;
val |= buffer[offset + 2] << 8;
val |= buffer[offset + 3];
val = val + (buffer[offset] << 24 >>> 0);
} else {
val = buffer[offset + 2] << 16;
val |= buffer[offset + 1] << 8;
val |= buffer[offset];
val = val + (buffer[offset + 3] << 24 >>> 0);
}

return val;
}

Buffer.prototype.readUInt32LE = function(offset, noAssert) {


return readUInt32(this, offset, false, noAssert);
};

Buffer.prototype.readUInt32BE = function(offset, noAssert) {


return readUInt32(this, offset, true, noAssert);
};

/*
* Signed integer types, yay team! A reminder on how two's complement actually
* works. The first bit is the signed bit, i.e. tells us whether or not the
* number should be positive or negative. If the two's complement value is
* positive, then we're done, as it's equivalent to the unsigned representation.
*
* Now if the number is positive, you're pretty much done, you can just leverage
* the unsigned translations and return those. Unfortunately, negative numbers
* aren't quite that straightforward.
*
* At first glance, one might be inclined to use the traditional formula to
* translate binary numbers between the positive and negative values in two's
* complement. (Though it doesn't quite work for the most negative value)
* Mainly:
* - invert all the bits
* - add one to the result
*
* Of course, this doesn't quite work in Javascript. Take for example the value
* of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
* course, Javascript will do the following:
*
* > ~0xff80
* -65409
*
* Whoh there, Javascript, that's not quite right. But wait, according to
* Javascript that's perfectly correct. When Javascript ends up seeing the
* constant 0xff80, it has no notion that it is actually a signed number. It
* assumes that we've input the unsigned value 0xff80. Thus, when it does the
* binary negation, it casts it into a signed value, (positive 0xff80). Then
* when you perform binary negation on that, it turns it into a negative number.
*
* Instead, we're going to have to use the following general formula, that works
* in a rather Javascript friendly way. I'm glad we don't support this kind of
* weird numbering scheme in the kernel.
*
* (BIT-MAX - (unsigned)val + 1) * -1
*
* The astute observer, may think that this doesn't make sense for 8-bit numbers
* (really it isn't necessary for them). However, when you get 16-bit numbers,
* you do. Let's go back to our prior example and see how this will look:
*
* (0xffff - 0xff80 + 1) * -1
* (0x007f + 1) * -1
* (0x0080) * -1
*/
Buffer.prototype.readInt8 = function(offset, noAssert) {
var buffer = this;
var neg;

if (!noAssert) {
assert.ok(offset !== undefined && offset !== null,
'missing offset');

assert.ok(offset < buffer.length,


'Trying to read beyond buffer length');
}
neg = buffer[offset] & 0x80;
if (!neg) {
return (buffer[offset]);
}

return ((0xff - buffer[offset] + 1) * -1);


};

function readInt16(buffer, offset, isBigEndian, noAssert) {


var neg, val;

if (!noAssert) {
assert.ok(typeof (isBigEndian) === 'boolean',
'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 1 < buffer.length,


'Trying to read beyond buffer length');
}

val = readUInt16(buffer, offset, isBigEndian, noAssert);


neg = val & 0x8000;
if (!neg) {
return val;
}

return (0xffff - val + 1) * -1;


}

Buffer.prototype.readInt16LE = function(offset, noAssert) {


return readInt16(this, offset, false, noAssert);
};

Buffer.prototype.readInt16BE = function(offset, noAssert) {


return readInt16(this, offset, true, noAssert);
};

function readInt32(buffer, offset, isBigEndian, noAssert) {


var neg, val;

if (!noAssert) {
assert.ok(typeof (isBigEndian) === 'boolean',
'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 3 < buffer.length,


'Trying to read beyond buffer length');
}

val = readUInt32(buffer, offset, isBigEndian, noAssert);


neg = val & 0x80000000;
if (!neg) {
return (val);
}
return (0xffffffff - val + 1) * -1;
}

Buffer.prototype.readInt32LE = function(offset, noAssert) {


return readInt32(this, offset, false, noAssert);
};

Buffer.prototype.readInt32BE = function(offset, noAssert) {


return readInt32(this, offset, true, noAssert);
};

function readFloat(buffer, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(typeof (isBigEndian) === 'boolean',
'missing or invalid endian');

assert.ok(offset + 3 < buffer.length,


'Trying to read beyond buffer length');
}

return require('buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,


23, 4);
}

Buffer.prototype.readFloatLE = function(offset, noAssert) {


return readFloat(this, offset, false, noAssert);
};

Buffer.prototype.readFloatBE = function(offset, noAssert) {


return readFloat(this, offset, true, noAssert);
};

function readDouble(buffer, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(typeof (isBigEndian) === 'boolean',
'missing or invalid endian');

assert.ok(offset + 7 < buffer.length,


'Trying to read beyond buffer length');
}

return require('buffer_ieee754').readIEEE754(buffer, offset, isBigEndian,


52, 8);
}

Buffer.prototype.readDoubleLE = function(offset, noAssert) {


return readDouble(this, offset, false, noAssert);
};

Buffer.prototype.readDoubleBE = function(offset, noAssert) {


return readDouble(this, offset, true, noAssert);
};

/*
* We have to make sure that the value is a valid integer. This means that it is
* non-negative. It has no fractional component and that it does not exceed the
* maximum allowed value.
*
* value The number to check for validity
*
* max The maximum value
*/
function verifuint(value, max) {
assert.ok(typeof (value) == 'number',
'cannot write a non-number as a number');

assert.ok(value >= 0,
'specified a negative value for writing an unsigned value');

assert.ok(value <= max, 'value is larger than maximum value for type');

assert.ok(Math.floor(value) === value, 'value has a fractional component');


}

Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {


var buffer = this;

if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset < buffer.length,


'trying to write beyond buffer length');

verifuint(value, 0xff);
}

buffer[offset] = value;
};

function writeUInt16(buffer, value, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(typeof (isBigEndian) === 'boolean',


'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 1 < buffer.length,


'trying to write beyond buffer length');

verifuint(value, 0xffff);
}

if (isBigEndian) {
buffer[offset] = (value & 0xff00) >>> 8;
buffer[offset + 1] = value & 0x00ff;
} else {
buffer[offset + 1] = (value & 0xff00) >>> 8;
buffer[offset] = value & 0x00ff;
}
}

Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {


writeUInt16(this, value, offset, false, noAssert);
};

Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {


writeUInt16(this, value, offset, true, noAssert);
};

function writeUInt32(buffer, value, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(typeof (isBigEndian) === 'boolean',


'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 3 < buffer.length,


'trying to write beyond buffer length');

verifuint(value, 0xffffffff);
}

if (isBigEndian) {
buffer[offset] = (value >>> 24) & 0xff;
buffer[offset + 1] = (value >>> 16) & 0xff;
buffer[offset + 2] = (value >>> 8) & 0xff;
buffer[offset + 3] = value & 0xff;
} else {
buffer[offset + 3] = (value >>> 24) & 0xff;
buffer[offset + 2] = (value >>> 16) & 0xff;
buffer[offset + 1] = (value >>> 8) & 0xff;
buffer[offset] = value & 0xff;
}
}

Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {


writeUInt32(this, value, offset, false, noAssert);
};

Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {


writeUInt32(this, value, offset, true, noAssert);
};

/*
* We now move onto our friends in the signed number category. Unlike unsigned
* numbers, we're going to have to worry a bit more about how we put values into
* arrays. Since we are only worrying about signed 32-bit values, we're in
* slightly better shape. Unfortunately, we really can't do our favorite binary
* & in this system. It really seems to do the wrong thing. For example:
*
* > -32 & 0xff
* 224
*
* What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
* this aren't treated as a signed number. Ultimately a bad thing.
*
* What we're going to want to do is basically create the unsigned equivalent of
* our representation and pass that off to the wuint* functions. To do that
* we're going to do the following:
*
* - if the value is positive
* we can pass it directly off to the equivalent wuint
* - if the value is negative
* we do the following computation:
* mb + val + 1, where
* mb is the maximum unsigned value in that byte size
* val is the Javascript negative integer
*
*
* As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
* you do out the computations:
*
* 0xffff - 128 + 1
* 0xffff - 127
* 0xff80
*
* You can then encode this value as the signed version. This is really rather
* hacky, but it should work and get the job done which is our goal here.
*/

/*
* A series of checks to make sure we actually have a signed 32-bit number
*/
function verifsint(value, max, min) {
assert.ok(typeof (value) == 'number',
'cannot write a non-number as a number');

assert.ok(value <= max, 'value larger than maximum allowed value');

assert.ok(value >= min, 'value smaller than minimum allowed value');

assert.ok(Math.floor(value) === value, 'value has a fractional component');


}

function verifIEEE754(value, max, min) {


assert.ok(typeof (value) == 'number',
'cannot write a non-number as a number');

assert.ok(value <= max, 'value larger than maximum allowed value');

assert.ok(value >= min, 'value smaller than minimum allowed value');


}

Buffer.prototype.writeInt8 = function(value, offset, noAssert) {


var buffer = this;

if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset < buffer.length,


'Trying to write beyond buffer length');

verifsint(value, 0x7f, -0x80);


}

if (value >= 0) {
buffer.writeUInt8(value, offset, noAssert);
} else {
buffer.writeUInt8(0xff + value + 1, offset, noAssert);
}
};

function writeInt16(buffer, value, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(typeof (isBigEndian) === 'boolean',


'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 1 < buffer.length,


'Trying to write beyond buffer length');

verifsint(value, 0x7fff, -0x8000);


}

if (value >= 0) {
writeUInt16(buffer, value, offset, isBigEndian, noAssert);
} else {
writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert);
}
}

Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {


writeInt16(this, value, offset, false, noAssert);
};

Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {


writeInt16(this, value, offset, true, noAssert);
};

function writeInt32(buffer, value, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(typeof (isBigEndian) === 'boolean',


'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 3 < buffer.length,


'Trying to write beyond buffer length');

verifsint(value, 0x7fffffff, -0x80000000);


}

if (value >= 0) {
writeUInt32(buffer, value, offset, isBigEndian, noAssert);
} else {
writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert);
}
}

Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {


writeInt32(this, value, offset, false, noAssert);
};

Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {


writeInt32(this, value, offset, true, noAssert);
};

function writeFloat(buffer, value, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(typeof (isBigEndian) === 'boolean',


'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');

assert.ok(offset + 3 < buffer.length,


'Trying to write beyond buffer length');

verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38);


}

require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,


23, 4);
}

Buffer.prototype.writeFloatLE = function(value, offset, noAssert) {


writeFloat(this, value, offset, false, noAssert);
};

Buffer.prototype.writeFloatBE = function(value, offset, noAssert) {


writeFloat(this, value, offset, true, noAssert);
};

function writeDouble(buffer, value, offset, isBigEndian, noAssert) {


if (!noAssert) {
assert.ok(value !== undefined && value !== null,
'missing value');

assert.ok(typeof (isBigEndian) === 'boolean',


'missing or invalid endian');

assert.ok(offset !== undefined && offset !== null,


'missing offset');
assert.ok(offset + 7 < buffer.length,
'Trying to write beyond buffer length');

verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308);


}

require('buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian,


52, 8);
}

Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {


writeDouble(this, value, offset, false, noAssert);
};

Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {


writeDouble(this, value, offset, true, noAssert);
};
#######// Copyright (c) 2008, Fair Oaks Labs, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
// Modifications to writeIEEE754 to support negative zeroes made by Brian White

exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) {


var e, m,
eLen = nBytes * 8 - mLen - 1,
eMax = (1 << eLen) - 1,
eBias = eMax >> 1,
nBits = -7,
i = isBE ? 0 : (nBytes - 1),
d = isBE ? 1 : -1,
s = buffer[offset + i];
i += d;

e = s & ((1 << (-nBits)) - 1);


s >>= (-nBits);
nBits += eLen;
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8);

m = e & ((1 << (-nBits)) - 1);


e >>= (-nBits);
nBits += mLen;
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8);

if (e === 0) {
e = 1 - eBias;
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity);
} else {
m = m + Math.pow(2, mLen);
e = e - eBias;
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
};

exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) {


var e, m, c,
eLen = nBytes * 8 - mLen - 1,
eMax = (1 << eLen) - 1,
eBias = eMax >> 1,
rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
i = isBE ? (nBytes - 1) : 0,
d = isBE ? -1 : 1,
s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;

value = Math.abs(value);

if (isNaN(value) || value === Infinity) {


m = isNaN(value) ? 1 : 0;
e = eMax;
} else {
e = Math.floor(Math.log(value) / Math.LN2);
if (value * (c = Math.pow(2, -e)) < 1) {
e--;
c *= 2;
}
if (e + eBias >= 1) {
value += rt / c;
} else {
value += rt * Math.pow(2, 1 - eBias);
}
if (value * c >= 2) {
e++;
c /= 2;
}

if (e + eBias >= eMax) {


m = 0;
e = eMax;
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen);
e = e + eBias;
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
e = 0;
}
}

for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8);

e = (e << mLen) | m;
eLen += mLen;
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8);

buffer[offset + i - d] |= s * 128;
};
#####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var EventEmitter = require('events').EventEmitter;


var net = require('net');
var Process = process.binding('process_wrap').Process;
var util = require('util');
var constants; // if (!constants) constants = process.binding('constants');

var handleWraps = {};

function handleWrapGetter(name, callback) {


var cons;

Object.defineProperty(handleWraps, name, {
get: function() {
if (cons !== undefined) return cons;
return cons = callback();
}
});
}

handleWrapGetter('Pipe', function() {
return process.binding('pipe_wrap').Pipe;
});
handleWrapGetter('TTY', function() {
return process.binding('tty_wrap').TTY;
});

handleWrapGetter('TCP', function() {
return process.binding('tcp_wrap').TCP;
});

handleWrapGetter('UDP', function() {
return process.binding('udp_wrap').UDP;
});

// constructors for lazy loading


function createPipe(ipc) {
return new handleWraps.Pipe(ipc);
}

function createSocket(pipe, readable) {


var s = new net.Socket({ handle: pipe });

if (readable) {
s.writable = false;
s.readable = true;
s.resume();
} else {
s.writable = true;
s.readable = false;
}

return s;
}

// this object contain function to convert TCP objects to native handle objects
// and back again.
var handleConversion = {
'net.Native': {
simultaneousAccepts: true,

send: function(message, handle) {


return handle;
},

got: function(message, handle, emit) {


emit(handle);
}
},

'net.Server': {
simultaneousAccepts: true,

send: function(message, server) {


return server._handle;
},

got: function(message, handle, emit) {


var self = this;
var server = new net.Server();
server.listen(handle, function() {
emit(server);
});
}
},

'net.Socket': {
send: function(message, socket) {
// pause socket so no data is lost, will be resumed later
socket.pause();

// if the socket wsa created by net.Server


if (socket.server) {
// the slave should keep track of the socket
message.key = socket.server._connectionKey;

var firstTime = !this._channel.sockets.send[message.key];

// add socket to connections list


var socketList = getSocketList('send', this, message.key);
socketList.add(socket);

// the server should no longer expose a .connection property


// and when asked to close it should query the socket status from slaves
if (firstTime) {
socket.server._setupSlave(socketList);
}
}

// remove handle from socket object, it will be closed when the socket
// has been send
var handle = socket._handle;
handle.onread = function() {};
socket._handle = null;

return handle;
},

got: function(message, handle, emit) {


var socket = new net.Socket({handle: handle});
socket.readable = socket.writable = true;
socket.pause();

// if the socket was created by net.Server we will track the socket


if (message.key) {

// add socket to connections list


var socketList = getSocketList('got', this, message.key);
socketList.add(socket);
}

emit(socket);
socket.resume();
}
}
};

// This object keep track of the socket there are sended


function SocketListSend(slave, key) {
EventEmitter.call(this);

var self = this;

this.key = key;
this.list = [];
this.slave = slave;

slave.once('disconnect', function() {
self.flush();
});

this.slave.on('internalMessage', function(msg) {
if (msg.cmd !== 'NODE_SOCKET_CLOSED' || msg.key !== self.key) return;
self.flush();
});
}
util.inherits(SocketListSend, EventEmitter);

SocketListSend.prototype.add = function(socket) {
this.list.push(socket);
};

SocketListSend.prototype.flush = function() {
var list = this.list;
this.list = [];

list.forEach(function(socket) {
socket.destroy();
});
};

SocketListSend.prototype.update = function() {
if (this.slave.connected === false) return;

this.slave.send({
cmd: 'NODE_SOCKET_FETCH',
key: this.key
});
};

// This object keep track of the socket there are received


function SocketListReceive(slave, key) {
EventEmitter.call(this);

var self = this;

this.key = key;
this.list = [];
this.slave = slave;

slave.on('internalMessage', function(msg) {
if (msg.cmd !== 'NODE_SOCKET_FETCH' || msg.key !== self.key) return;

if (self.list.length === 0) {
self.flush();
return;
}
self.on('itemRemoved', function removeMe() {
if (self.list.length !== 0) return;
self.removeListener('itemRemoved', removeMe);
self.flush();
});
});
}
util.inherits(SocketListReceive, EventEmitter);

SocketListReceive.prototype.flush = function() {
this.list = [];

if (this.slave.connected) {
this.slave.send({
cmd: 'NODE_SOCKET_CLOSED',
key: this.key
});
}
};

SocketListReceive.prototype.add = function(socket) {
var self = this;
this.list.push(socket);

socket.on('close', function() {
self.list.splice(self.list.indexOf(socket), 1);
self.emit('itemRemoved');
});
};

function getSocketList(type, slave, key) {


var sockets = slave._channel.sockets[type];
var socketList = sockets[key];
if (!socketList) {
var Construct = type === 'send' ? SocketListSend : SocketListReceive;
socketList = sockets[key] = new Construct(slave, key);
}
return socketList;
}

function handleMessage(target, message, handle) {


//Filter out internal messages
//if cmd property begin with "_NODE"
if (message !== null &&
typeof message === 'object' &&
typeof message.cmd === 'string' &&
message.cmd.indexOf('NODE_') === 0) {
target.emit('internalMessage', message, handle);
}
//Non-internal message
else {
target.emit('message', message, handle);
}
}

function setupChannel(target, channel) {


target._channel = channel;
var jsonBuffer = '';
channel.buffering = false;
channel.onread = function(pool, offset, length, recvHandle) {
if (pool) {
jsonBuffer += pool.toString('ascii', offset, offset + length);

var i, start = 0;

//Linebreak is used as a message end sign


while ((i = jsonBuffer.indexOf('\n', start)) >= 0) {
var json = jsonBuffer.slice(start, i);
var message = JSON.parse(json);

handleMessage(target, message, recvHandle);

start = i + 1;
}
jsonBuffer = jsonBuffer.slice(start);
this.buffering = jsonBuffer.length !== 0;

} else {
this.buffering = false;
target.disconnect();
channel.onread = nop;
channel.close();
maybeClose(target);
}
};

// object where socket lists will live


channel.sockets = { got: {}, send: {} };

// handlers will go through this


target.on('internalMessage', function(message, handle) {
if (message.cmd !== 'NODE_HANDLE') return;

var obj = handleConversion[message.type];

// Update simultaneous accepts on Windows


if (process.platform === 'win32') {
handle._simultaneousAccepts = false;
net._setSimultaneousAccepts(handle);
}

// Convert handle object


obj.got.call(this, message, handle, function(handle) {
handleMessage(target, message.msg, handle);
});
});

target.send = function(message, handle) {


if (typeof message === 'undefined') {
throw new TypeError('message cannot be undefined');
}

if (!this.connected) {
this.emit('error', new Error('channel closed'));
return;
}
// package messages with a handle object
if (handle) {
// this message will be handled by an internalMessage event handler
message = {
cmd: 'NODE_HANDLE',
type: 'net.',
msg: message
};

switch (handle.constructor.name) {
case 'Socket':
message.type += 'Socket'; break;
case 'Server':
message.type += 'Server'; break;
case 'Pipe':
case 'TCP':
message.type += 'Native'; break;
}

var obj = handleConversion[message.type];

// convert TCP object to native handle object


handle = handleConversion[message.type].send.apply(target, arguments);

// Update simultaneous accepts on Windows


if (obj.simultaneousAccepts) {
net._setSimultaneousAccepts(handle);
}
}

var string = JSON.stringify(message) + '\n';


var writeReq = channel.writeUtf8String(string, handle);

// Close the Socket handle after sending it


if (message && message.type === 'net.Socket') {
handle.close();
}

if (!writeReq) {
var er = errnoException(errno, 'write', 'cannot write to IPC channel.');
this.emit('error', er);
}

writeReq.oncomplete = nop;

/* If the master is > 2 read() calls behind, please stop sending. */


return channel.writeQueueSize < (65536 * 2);
};

target.connected = true;
target.disconnect = function() {
if (!this.connected) {
this.emit('error', new Error('IPC channel is already disconnected'));
return;
}

// do not allow messages to be written


this.connected = false;
this._channel = null;

var fired = false;


function finish() {
if (fired) return;
fired = true;

channel.close();
target.emit('disconnect');
}

// If a message is being read, then wait for it to complete.


if (channel.buffering) {
this.once('message', finish);
this.once('internalMessage', finish);

return;
}

finish();
};

channel.readStart();
}

function nop() { }

exports.fork = function(modulePath /*, args, options*/) {


var path = require('path');
var nodePath = process.execPath;
if (process.platform == 'darwin') {
// Usually process.execPath is in Helper.app, need to find node in the
// main app's Resources.
nodePath = path.join(process.execPath, '..', '..', '..', '..', '..',
'Resources', 'node')
} else if (process.platform == 'win32') {
nodePath = path.join(nodePath, '../node.exe');
} else {
nodePath = path.join(nodePath, '../node');
}

// Get options and args arguments.


var options, args, execArgv;
if (Array.isArray(arguments[1])) {
args = arguments[1];
options = util._extend({}, arguments[2]);
} else {
args = [];
options = util._extend({}, arguments[1]);
}

// Prepare arguments for fork:


execArgv = options.execArgv || process.execArgv;
args = execArgv.concat([modulePath], args);

// Leave stdin open for the IPC channel. stdout and stderr should be the
// same as the parent's if silent isn't set.
options.stdio = options.silent ? ['pipe', 'pipe', 'pipe', 'ipc'] :
[0, 1, 2, 'ipc'];

return spawn(nodePath, args, options);


};

exports._forkChild = function(fd) {
// set process.send()
var p = createPipe(true);
p.open(fd);
setupChannel(process, p);
};

exports.exec = function(command /*, options, callback */) {


var file, args, options, callback;

if (typeof arguments[1] === 'function') {


options = undefined;
callback = arguments[1];
} else {
options = arguments[1];
callback = arguments[2];
}

if (process.platform === 'win32') {


file = 'cmd.exe';
args = ['/s', '/c', '"' + command + '"'];
// Make a shallow copy before patching so we don't clobber the user's
// options object.
options = util._extend({}, options);
options.windowsVerbatimArguments = true;
} else {
file = '/bin/sh';
args = ['-c', command];
}
return exports.execFile(file, args, options, callback);
};

exports.execFile = function(file /* args, options, callback */) {


var args, optionArg, callback;
var options = {
encoding: 'utf8',
timeout: 0,
maxBuffer: 200 * 1024,
killSignal: 'SIGTERM',
cwd: null,
env: null
};

// Parse the parameters.

if (typeof arguments[arguments.length - 1] === 'function') {


callback = arguments[arguments.length - 1];
}

if (Array.isArray(arguments[1])) {
args = arguments[1];
options = util._extend(options, arguments[2]);
} else {
args = [];
options = util._extend(options, arguments[1]);
}

var child = spawn(file, args, {


cwd: options.cwd,
env: options.env,
windowsVerbatimArguments: !!options.windowsVerbatimArguments
});

var stdout = '';


var stderr = '';
var killed = false;
var exited = false;
var timeoutId;

var err;

function exithandler(code, signal) {


if (exited) return;
exited = true;

if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}

if (!callback) return;

if (err) {
callback(err, stdout, stderr);
} else if (code === 0 && signal === null) {
callback(null, stdout, stderr);
} else {
var e = new Error('Command failed: ' + stderr);
e.killed = child.killed || killed;
e.code = code;
e.signal = signal;
callback(e, stdout, stderr);
}
}

function errorhandler(e) {
err = e;
child.stdout.destroy();
child.stderr.destroy();
exithandler();
}

function kill() {
child.stdout.destroy();
child.stderr.destroy();

killed = true;
try {
child.kill(options.killSignal);
} catch (e) {
err = e;
exithandler();
}
}

if (options.timeout > 0) {
timeoutId = setTimeout(function() {
kill();
timeoutId = null;
}, options.timeout);
}

child.stdout.setEncoding(options.encoding);
child.stderr.setEncoding(options.encoding);

child.stdout.addListener('data', function(chunk) {
stdout += chunk;
if (stdout.length > options.maxBuffer) {
err = new Error('maxBuffer exceeded.');
kill();
}
});

child.stderr.addListener('data', function(chunk) {
stderr += chunk;
if (stderr.length > options.maxBuffer) {
err = new Error('maxBuffer exceeded.');
kill();
}
});

child.addListener('close', exithandler);
child.addListener('error', errorhandler);

return child;
};

var spawn = exports.spawn = function(file, args, options) {


args = args ? args.slice(0) : [];
args.unshift(file);

var env = (options ? options.env : null) || process.env;


var envPairs = [];
for (var key in env) {
envPairs.push(key + '=' + env[key]);
}

var child = new ChildProcess();


if (options && options.customFds && !options.stdio) {
options.stdio = options.customFds.map(function(fd) {
return fd === -1 ? 'pipe' : fd;
});
}

child.spawn({
file: file,
args: args,
cwd: options ? options.cwd : null,
windowsVerbatimArguments: !!(options && options.windowsVerbatimArguments),
detached: !!(options && options.detached),
envPairs: envPairs,
stdio: options ? options.stdio : null,
uid: options ? options.uid : null,
gid: options ? options.gid : null
});

return child;
};

function maybeClose(subprocess) {
subprocess._closesGot++;

if (subprocess._closesGot == subprocess._closesNeeded) {
subprocess.emit('close', subprocess.exitCode, subprocess.signalCode);
}
}

function ChildProcess() {
EventEmitter.call(this);

var self = this;

this._closesNeeded = 1;
this._closesGot = 0;

this.signalCode = null;
this.exitCode = null;
this.killed = false;

this._handle = new Process();


this._handle.owner = this;

this._handle.onexit = function(exitCode, signalCode) {


//
// follow 0.4.x behaviour:
//
// - normally terminated processes don't touch this.signalCode
// - signaled processes don't touch this.exitCode
//
if (signalCode) {
self.signalCode = signalCode;
} else {
self.exitCode = exitCode;
}

if (self.stdin) {
self.stdin.destroy();
}

self._handle.close();
self._handle = null;

self.emit('exit', self.exitCode, self.signalCode);

maybeClose(self);
};
}
util.inherits(ChildProcess, EventEmitter);

function getHandleWrapType(stream) {
if (stream instanceof handleWraps.Pipe) return 'pipe';
if (stream instanceof handleWraps.TTY) return 'tty';
if (stream instanceof handleWraps.TCP) return 'tcp';
if (stream instanceof handleWraps.UDP) return 'udp';

return false;
}

ChildProcess.prototype.spawn = function(options) {
var self = this,
ipc,
ipcFd,
// If no `stdio` option was given - use default
stdio = options.stdio || 'pipe';

// Replace shortcut with an array


if (typeof stdio === 'string') {
switch (stdio) {
case 'ignore': stdio = ['ignore', 'ignore', 'ignore']; break;
case 'pipe': stdio = ['pipe', 'pipe', 'pipe']; break;
case 'inherit': stdio = [0, 1, 2]; break;
default: throw new TypeError('Incorrect value of stdio option: ' + stdio);
}
} else if (!Array.isArray(stdio)) {
throw new TypeError('Incorrect value of stdio option: ' + stdio);
}

// At least 3 stdio will be created


// Don't concat() a new Array() because it would be sparse, and
// stdio.reduce() would skip the sparse elements of stdio.
// See http://stackoverflow.com/a/5501711/3561
while (stdio.length < 3) stdio.push(undefined);

// Translate stdio into C++-readable form


// (i.e. PipeWraps or fds)
stdio = stdio.reduce(function(acc, stdio, i) {
function cleanup() {
acc.filter(function(stdio) {
return stdio.type === 'pipe' || stdio.type === 'ipc';
}).forEach(function(stdio) {
stdio.handle.close();
});
}

// Defaults
if (stdio === undefined || stdio === null) {
stdio = i < 3 ? 'pipe' : 'ignore';
}

if (stdio === 'ignore') {


acc.push({type: 'ignore'});
} else if (stdio === 'pipe' || typeof stdio === 'number' && stdio < 0) {
acc.push({type: 'pipe', handle: createPipe()});
} else if (stdio === 'ipc') {
if (ipc !== undefined) {
// Cleanup previously created pipes
cleanup();
throw Error('Child process can have only one IPC pipe');
}

ipc = createPipe(true);
ipcFd = i;

acc.push({ type: 'pipe', handle: ipc, ipc: true });


} else if (typeof stdio === 'number' || typeof stdio.fd === 'number') {
acc.push({ type: 'fd', fd: stdio.fd || stdio });
} else if (getHandleWrapType(stdio) || getHandleWrapType(stdio.handle) ||
getHandleWrapType(stdio._handle)) {
var handle = getHandleWrapType(stdio) ?
stdio :
getHandleWrapType(stdio.handle) ? stdio.handle : stdio._handle;

acc.push({
type: 'wrap',
wrapType: getHandleWrapType(handle),
handle: handle
});
} else {
// Cleanup
cleanup();
throw new TypeError('Incorrect value for stdio stream: ' + stdio);
}

return acc;
}, []);

options.stdio = stdio;

if (ipc !== undefined) {


// Let child process know about opened IPC channel
options.envPairs = options.envPairs || [];
options.envPairs.push('NODE_CHANNEL_FD=' + ipcFd);
}

var r = this._handle.spawn(options);

if (r) {
// Close all opened fds on error
stdio.forEach(function(stdio) {
if (stdio.type === 'pipe') {
stdio.handle.close();
}
});

this._handle.close();
this._handle = null;
throw errnoException(errno, 'spawn');
}

this.pid = this._handle.pid;
stdio.forEach(function(stdio, i) {
if (stdio.type === 'ignore') return;

if (stdio.ipc) {
self._closesNeeded++;
return;
}

if (stdio.handle) {
// when i === 0 - we're dealing with stdin
// (which is the only one writable pipe)
stdio.socket = createSocket(stdio.handle, i > 0);

if (i > 0) {
self._closesNeeded++;
stdio.socket.on('close', function() {
maybeClose(self);
});
}
}
});

this.stdin = stdio.length >= 1 && stdio[0].socket !== undefined ?


stdio[0].socket : null;
this.stdout = stdio.length >= 2 && stdio[1].socket !== undefined ?
stdio[1].socket : null;
this.stderr = stdio.length >= 3 && stdio[2].socket !== undefined ?
stdio[2].socket : null;

this.stdio = stdio.map(function(stdio) {
return stdio.socket === undefined ? null : stdio.socket;
});

// Add .send() method and start listening for IPC data


if (ipc !== undefined) setupChannel(this, ipc);

return r;
};

function errnoException(errorno, syscall, errmsg) {


// TODO make this more compatible with ErrnoException from src/node.cc
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.
var message = syscall + ' ' + errorno;
if (errmsg) {
message += ' - ' + errmsg;
}
var e = new Error(message);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}

ChildProcess.prototype.kill = function(sig) {
var signal;

if (!constants) {
constants = process.binding('constants');
}

if (sig === 0) {
signal = 0;
} else if (!sig) {
signal = constants['SIGTERM'];
} else {
signal = constants[sig];
}

if (signal === undefined) {


throw new Error('Unknown signal: ' + sig);
}

if (this._handle) {
var r = this._handle.kill(signal);
if (r == 0) {
/* Success. */
this.killed = true;
return true;
} else if (errno == 'ESRCH') {
/* Already dead. */
} else if (errno == 'EINVAL' || errno == 'ENOSYS') {
/* The underlying platform doesn't support this signal. */
throw errnoException(errno, 'kill');
} else {
/* Other error, almost certainly EPERM. */
this.emit('error', errnoException(errno, 'kill'));
}
}

/* Kill didn't succeed. */


return false;
};

ChildProcess.prototype.ref = function() {
if (this._handle) this._handle.ref();
};

ChildProcess.prototype.unref = function() {
if (this._handle) this._handle.unref();
};
#// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util');

exports.log = function() {
process.stdout.write(util.format.apply(this, arguments) + '\n');
};

exports.info = exports.log;

exports.warn = function() {
process.stderr.write(util.format.apply(this, arguments) + '\n');
};

exports.error = exports.warn;

exports.dir = function(object) {
process.stdout.write(util.inspect(object) + '\n');
};

var times = {};


exports.time = function(label) {
times[label] = Date.now();
};

exports.timeEnd = function(label) {
var time = times[label];
if (!time) {
throw new Error('No such label: ' + label);
}
var duration = Date.now() - time;
exports.log('%s: %dms', label, duration);
};

exports.trace = function(label) {
// TODO probably can to do this better with V8's debug object once that is
// exposed.
var err = new Error;
err.name = 'Trace';
err.message = label || '';
Error.captureStackTrace(err, arguments.callee);
console.error(err.stack);
};

exports.assert = function(expression) {
if (!expression) {
var arr = Array.prototype.slice.call(arguments, 1);
require('assert').ok(false, util.format.apply(this, arr));
}
};
######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

module.exports = process.binding('constants');
###// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

try {
var binding = process.binding('crypto');
var SecureContext = binding.SecureContext;
var Hmac = binding.Hmac;
var Hash = binding.Hash;
var Cipher = binding.Cipher;
var Decipher = binding.Decipher;
var Sign = binding.Sign;
var Verify = binding.Verify;
var DiffieHellman = binding.DiffieHellman;
var DiffieHellmanGroup = binding.DiffieHellmanGroup;
var PBKDF2 = binding.PBKDF2;
var randomBytes = binding.randomBytes;
var pseudoRandomBytes = binding.pseudoRandomBytes;
var crypto = true;
} catch (e) {

var crypto = false;


}

function Credentials(secureProtocol, flags, context) {


if (!(this instanceof Credentials)) {
return new Credentials(secureProtocol);
}

if (!crypto) {
throw new Error('node.js not compiled with openssl crypto support.');
}

if (context) {
this.context = context;
} else {
this.context = new SecureContext();

if (secureProtocol) {
this.context.init(secureProtocol);
} else {
this.context.init();
}
}

if (flags) this.context.setOptions(flags);
}

exports.Credentials = Credentials;

exports.createCredentials = function(options, context) {


if (!options) options = {};

var c = new Credentials(options.secureProtocol,


options.secureOptions,
context);

if (context) return c;

if (options.key) {
if (options.passphrase) {
c.context.setKey(options.key, options.passphrase);
} else {
c.context.setKey(options.key);
}
}

if (options.cert) c.context.setCert(options.cert);

if (options.ciphers) c.context.setCiphers(options.ciphers);

if (options.ca) {
if (Array.isArray(options.ca)) {
for (var i = 0, len = options.ca.length; i < len; i++) {
c.context.addCACert(options.ca[i]);
}
} else {
c.context.addCACert(options.ca);
}
} else {
c.context.addRootCerts();
}

if (options.crl) {
if (Array.isArray(options.crl)) {
for (var i = 0, len = options.crl.length; i < len; i++) {
c.context.addCRL(options.crl[i]);
}
} else {
c.context.addCRL(options.crl);
}
}

if (options.sessionIdContext) {
c.context.setSessionIdContext(options.sessionIdContext);
}

if (options.pfx) {
if (options.passphrase) {
c.context.loadPKCS12(options.pfx, options.passphrase);
} else {
c.context.loadPKCS12(options.pfx);
}
}

return c;
};

exports.Hash = Hash;
exports.createHash = function(hash) {
return new Hash(hash);
};

exports.Hmac = Hmac;
exports.createHmac = function(hmac, key) {
return (new Hmac).init(hmac, key);
};

exports.Cipher = Cipher;
exports.createCipher = function(cipher, password) {
return (new Cipher).init(cipher, password);
};

exports.createCipheriv = function(cipher, key, iv) {


return (new Cipher).initiv(cipher, key, iv);
};
exports.Decipher = Decipher;
exports.createDecipher = function(cipher, password) {
return (new Decipher).init(cipher, password);
};

exports.createDecipheriv = function(cipher, key, iv) {


return (new Decipher).initiv(cipher, key, iv);
};

exports.Sign = Sign;
exports.createSign = function(algorithm) {
return (new Sign).init(algorithm);
};

exports.Verify = Verify;
exports.createVerify = function(algorithm) {
return (new Verify).init(algorithm);
};

exports.DiffieHellman = DiffieHellman;
exports.createDiffieHellman = function(size_or_key, enc) {
if (!size_or_key) {
return new DiffieHellman();
} else if (!enc) {
return new DiffieHellman(size_or_key);
} else {
return new DiffieHellman(size_or_key, enc);
}

};
exports.getDiffieHellman = function(group_name) {
return new DiffieHellmanGroup(group_name);
};

exports.pbkdf2 = PBKDF2;

exports.randomBytes = randomBytes;
exports.pseudoRandomBytes = pseudoRandomBytes;

exports.rng = randomBytes;
exports.prng = pseudoRandomBytes;
#######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var assert = require('assert');


var fork = require('child_process').fork;
var net = require('net');
var EventEmitter = require('events').EventEmitter;
var util = require('util');

function isObject(o) {
return (typeof o === 'object' && o !== null);
}

var debug;
if (process.env.NODE_DEBUG && /cluster/.test(process.env.NODE_DEBUG)) {
debug = function(x) {
var prefix = process.pid + ',' +
(process.env.NODE_UNIQUE_ID ? 'Worker' : 'Master');
console.error(prefix, x);
};
} else {
debug = function() { };
}

// cluster object:
function Cluster() {
EventEmitter.call(this);
}

util.inherits(Cluster, EventEmitter);

var cluster = module.exports = new Cluster();

// Used in the master:


var masterStarted = false;
var ids = 0;
var serverHandlers = {};

// Used in the worker:


var serverListeners = {};
var queryIds = 0;
var queryCallbacks = {};

// Define isWorker and isMaster


cluster.isWorker = 'NODE_UNIQUE_ID' in process.env;
cluster.isMaster = ! cluster.isWorker;

// The worker object is only used in a worker


cluster.worker = cluster.isWorker ? {} : null;
// The workers array is only used in the master
cluster.workers = cluster.isMaster ? {} : null;

// Settings object
var settings = cluster.settings = {};

// Simple function to call a function on each worker


function eachWorker(cb) {
// Go through all workers
for (var id in cluster.workers) {
if (cluster.workers.hasOwnProperty(id)) {
cb(cluster.workers[id]);
}
}
}

// Extremely simple progress tracker


function ProgressTracker(missing, callback) {
this.missing = missing;
this.callback = callback;
}
ProgressTracker.prototype.done = function() {
this.missing -= 1;
this.check();
};
ProgressTracker.prototype.check = function() {
if (this.missing === 0) this.callback();
};

cluster.setupMaster = function(options) {
// This can only be called from the master.
assert(cluster.isMaster);

// Don't allow this function to run more than once


if (masterStarted) return;
masterStarted = true;

// Get filename and arguments


options = options || {};

// Set settings object


settings = cluster.settings = {
exec: options.exec || process.argv[1],
execArgv: options.execArgv || process.execArgv,
args: options.args || process.argv.slice(2),
silent: options.silent || false
};

// emit setup event


cluster.emit('setup');
};

// Check if a message is internal only


var INTERNAL_PREFIX = 'NODE_CLUSTER_';
function isInternalMessage(message) {
return (isObject(message) &&
typeof message.cmd === 'string' &&
message.cmd.indexOf(INTERNAL_PREFIX) === 0);
}

// Modify message object to be internal


function internalMessage(inMessage) {
var outMessage = util._extend({}, inMessage);

// Add internal prefix to cmd


outMessage.cmd = INTERNAL_PREFIX + (outMessage.cmd || '');
return outMessage;
}

// Handle callback messages


function handleResponse(outMessage, outHandle, inMessage, inHandle, worker) {

// The message there will be sent


var message = internalMessage(outMessage);

// callback id - will be undefined if not set


message._queryEcho = inMessage._requestEcho;

// Call callback if a query echo is received


if (inMessage._queryEcho) {
queryCallbacks[inMessage._queryEcho](inMessage.content, inHandle);
delete queryCallbacks[inMessage._queryEcho];
}

// Send if outWrap contains something useful


if (!(outMessage === undefined && message._queryEcho === undefined)) {
sendInternalMessage(worker, message, outHandle);
}
}

// Handle messages from both master and workers


var messageHandler = {};
function handleMessage(worker, inMessage, inHandle) {

// Remove internal prefix


var message = util._extend({}, inMessage);
message.cmd = inMessage.cmd.substr(INTERNAL_PREFIX.length);

var respondUsed = false;


function respond(outMessage, outHandler) {
respondUsed = true;
handleResponse(outMessage, outHandler, inMessage, inHandle, worker);
}

// Run handler if it exists


if (messageHandler[message.cmd]) {
messageHandler[message.cmd](message, worker, respond);
}

// Send respond if it hasn't been called yet


if (respondUsed === false) {
respond();
}
}

// Messages to the master will be handled using these methods


if (cluster.isMaster) {

// Handle online messages from workers


messageHandler.online = function(message, worker) {
worker.state = 'online';
debug('Worker ' + worker.process.pid + ' online');
worker.emit('online');
cluster.emit('online', worker);
};

// Handle queryServer messages from workers


messageHandler.queryServer = function(message, worker, send) {

// This sequence of information is unique to the connection


// but not to the worker
var args = [message.address,
message.port,
message.addressType,
message.fd];
var key = args.join(':');
var handler;

if (serverHandlers.hasOwnProperty(key)) {
handler = serverHandlers[key];
} else {
handler = serverHandlers[key] = net._createServerHandle.apply(net, args);
}

// echo callback with the fd handler associated with it


send({}, handler);
};

// Handle listening messages from workers


messageHandler.listening = function(message, worker) {

worker.state = 'listening';

// Emit listening, now that we know the worker is listening


worker.emit('listening', {
address: message.address,
port: message.port,
addressType: message.addressType,
fd: message.fd
});
cluster.emit('listening', worker, {
address: message.address,
port: message.port,
addressType: message.addressType,
fd: message.fd
});
};

// Handle suicide messages from workers


messageHandler.suicide = function(message, worker) {
worker.suicide = true;
};

// Messages to a worker will be handled using these methods


else if (cluster.isWorker) {

// Handle worker.disconnect from master


messageHandler.disconnect = function(message, worker) {
worker.disconnect();
};
}
function toDecInt(value) {
value = parseInt(value, 10);
return isNaN(value) ? null : value;
}

// Create a worker object, that works both for master and worker
function Worker(customEnv) {
if (!(this instanceof Worker)) return new Worker();
EventEmitter.call(this);

var self = this;


var env = process.env;

// Assign a unique id, default null


this.id = cluster.isMaster ? ++ids : toDecInt(env.NODE_UNIQUE_ID);

// XXX: Legacy. Remove in 0.9


this.workerID = this.uniqueID = this.id;

// Assign state
this.state = 'none';

// Create or get process


if (cluster.isMaster) {

// Create env object


// first: copy and add id property
var envCopy = util._extend({}, env);
envCopy['NODE_UNIQUE_ID'] = this.id;
// second: extend envCopy with the env argument
if (isObject(customEnv)) {
envCopy = util._extend(envCopy, customEnv);
}

// fork worker
this.process = fork(settings.exec, settings.args, {
'env': envCopy,
'silent': settings.silent,
'execArgv': settings.execArgv
});
} else {
this.process = process;
}

if (cluster.isMaster) {
// Save worker in the cluster.workers array
cluster.workers[this.id] = this;

// Emit a fork event, on next tick


// There is no worker.fork event since this has no real purpose
process.nextTick(function() {
cluster.emit('fork', self);
});
}

// handle internalMessage, exit and disconnect event


this.process.on('internalMessage', handleMessage.bind(null, this));
this.process.once('exit', function(exitCode, signalCode) {
prepareExit(self, 'dead');
self.emit('exit', exitCode, signalCode);
cluster.emit('exit', self, exitCode, signalCode);
});
this.process.once('disconnect', function() {
prepareExit(self, 'disconnected');
self.emit('disconnect');
cluster.emit('disconnect', self);
});

// relay message and error


this.process.on('message', this.emit.bind(this, 'message'));
this.process.on('error', this.emit.bind(this, 'error'));

}
util.inherits(Worker, EventEmitter);
cluster.Worker = Worker;

function prepareExit(worker, state) {

// set state to disconnect


worker.state = state;

// Make suicide a boolean


worker.suicide = !!worker.suicide;

// Remove from workers in the master


if (cluster.isMaster) {
delete cluster.workers[worker.id];
}
}

// Send internal message


function sendInternalMessage(worker, message/*, handler, callback*/) {

// Exist callback
var callback = arguments[arguments.length - 1];
if (typeof callback !== 'function') {
callback = undefined;
}

// exist handler
var handler = arguments[2] !== callback ? arguments[2] : undefined;

if (!isInternalMessage(message)) {
message = internalMessage(message);
}

// Store callback for later


if (callback) {
message._requestEcho = worker.id + ':' + (++queryIds);
queryCallbacks[message._requestEcho] = callback;
}

worker.send(message, handler);
}

// Send message to worker or master


Worker.prototype.send = function() {

// You could also just use process.send in a worker


this.process.send.apply(this.process, arguments);
};

// Kill the worker without restarting


Worker.prototype.destroy = function() {
var self = this;

this.suicide = true;

if (cluster.isMaster) {
// Disconnect IPC channel
// this way the worker won't need to propagate suicide state to master
if (self.process.connected) {
self.process.once('disconnect', function() {
self.process.kill();
});
self.process.disconnect();
} else {
self.process.kill();
}

} else {
// Channel is open
if (this.process.connected) {

// Inform master to suicide and then kill


sendInternalMessage(this, {cmd: 'suicide'}, function() {
process.exit(0);
});

// When channel is closed, terminate the process


this.process.once('disconnect', function() {
process.exit(0);
});
} else {
process.exit(0);
}
}
};

// The .disconnect function will close all servers


// and then disconnect the IPC channel.
if (cluster.isMaster) {
// Used in master
Worker.prototype.disconnect = function() {
this.suicide = true;

sendInternalMessage(this, {cmd: 'disconnect'});


};

} else {
// Used in workers
Worker.prototype.disconnect = function() {
var self = this;

this.suicide = true;
// keep track of open servers
var servers = Object.keys(serverListeners).length;
var progress = new ProgressTracker(servers, function() {
// There are no more servers open so we will close the IPC channel.
// Closing the IPC channel will emit a disconnect event
// in both master and worker on the process object.
// This event will be handled by prepareExit.
self.process.disconnect();
});

// depending on where this function was called from (master or worker)


// The suicide state has already been set,
// but it doesn't really matter if we set it again.
sendInternalMessage(this, {cmd: 'suicide'}, function() {
// in case there are no servers
progress.check();

// closing all servers gracefully


var server;
for (var key in serverListeners) {
server = serverListeners[key];

// in case the server is closed we won't close it again


if (server._handle === null) {
progress.done();
continue;
}

server.on('close', progress.done.bind(progress));
server.close();
}
});

};
}

// Fork a new worker


cluster.fork = function(env) {
// This can only be called from the master.
assert(cluster.isMaster);

// Make sure that the master has been initialized


cluster.setupMaster();

return (new cluster.Worker(env));


};

// execute .disconnect on all workers and close handlers when done


cluster.disconnect = function(callback) {
// This can only be called from the master.
assert(cluster.isMaster);

// Close all TCP handlers when all workers are disconnected


var workers = Object.keys(cluster.workers).length;
var progress = new ProgressTracker(workers, function() {
for (var key in serverHandlers) {
serverHandlers[key].close();
delete serverHandlers[key];
}

// call callback when done


if (callback) callback();
});

// begin disconnecting all workers


eachWorker(function(worker) {
worker.once('disconnect', progress.done.bind(progress));
worker.disconnect();
});

// in case there weren't any workers


progress.check();
};

// Internal function. Called from src/node.js when worker process starts.


cluster._setupWorker = function() {

// Get worker class


var worker = cluster.worker = new Worker();

// we will terminate the worker


// when the worker is disconnected from the parent accidentally
process.once('disconnect', function() {
if (worker.suicide !== true) {
process.exit(0);
}
});

// Tell master that the worker is online


worker.state = 'online';
sendInternalMessage(worker, { cmd: 'online' });
};

// Internal function. Called by lib/net.js when attempting to bind a server.


cluster._getServer = function(tcpSelf, address, port, addressType, fd, cb) {
// This can only be called from a worker.
assert(cluster.isWorker);

// Store tcp instance for later use


var key = [address, port, addressType, fd].join(':');
serverListeners[key] = tcpSelf;

// Send a listening message to the master


tcpSelf.once('listening', function() {
cluster.worker.state = 'listening';
sendInternalMessage(cluster.worker, {
cmd: 'listening',
address: address,
port: port,
addressType: addressType,
fd: fd
});
});

// Request the fd handler from the master process


var message = {
cmd: 'queryServer',
address: address,
port: port,
addressType: addressType,
fd: fd
};

// The callback will be stored until the master has responded


sendInternalMessage(cluster.worker, message, function(msg, handle) {
cb(handle);
});

};
#######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util');


var events = require('events');

var UDP = process.binding('udp_wrap').UDP;

// lazily loaded
var dns = null;
var net = null;

// no-op callback
function noop() {
}

function isIP(address) {
if (!net)
net = require('net');

return net.isIP(address);
}

function lookup(address, family, callback) {


// implicit 'bind before send' needs to run on the same tick
var matchedFamily = isIP(address);
if (matchedFamily)
return callback(null, address, matchedFamily);

if (!dns)
dns = require('dns');

return dns.lookup(address, family, callback);


}

function lookup4(address, callback) {


return lookup(address || '0.0.0.0', 4, callback);
}

function lookup6(address, callback) {


return lookup(address || '::0', 6, callback);
}

function newHandle(type) {
if (type == 'udp4') {
var handle = new UDP;
handle.lookup = lookup4;
return handle;
}

if (type == 'udp6') {
var handle = new UDP;
handle.lookup = lookup6;
handle.bind = handle.bind6;
handle.send = handle.send6;
return handle;
}

if (type == 'unix_dgram')
throw new Error('unix_dgram sockets are not supported any more.');

throw new Error('Bad socket type specified. Valid types are: udp4, udp6');
}

function Socket(type, listener) {


events.EventEmitter.call(this);

var handle = newHandle(type);


handle.owner = this;

this._handle = handle;
this._receiving = false;
this._bound = false;
this.type = type;
this.fd = null; // compatibility hack

if (typeof listener === 'function')


this.on('message', listener);
}
util.inherits(Socket, events.EventEmitter);
exports.Socket = Socket;
exports.createSocket = function(type, listener) {
return new Socket(type, listener);
};

Socket.prototype.bind = function(port, address) {


var self = this;

self._healthCheck();

// resolve address first


self._handle.lookup(address, function(err, ip) {
if (!err) {
if (self._handle.bind(ip, port || 0, /*flags=*/0)) {
err = errnoException(errno, 'bind');
}
else {
self._bound = true;
self._startReceiving();
self.emit('listening');
}
}

if (err) {
// caller may not have had a chance yet to register its
// error event listener so defer the error to the next tick
process.nextTick(function() {
self.emit('error', err);
});
}
});
};

// thin wrapper around `send`, here for compatibility with dgram_legacy.js


Socket.prototype.sendto = function(buffer,
offset,
length,
port,
address,
callback) {
if (typeof offset !== 'number' || typeof length !== 'number')
throw new Error('send takes offset and length as args 2 and 3');

if (typeof address !== 'string')


throw new Error(this.type + ' sockets must send to port, address');

this.send(buffer, offset, length, port, address, callback);


};

Socket.prototype.send = function(buffer,
offset,
length,
port,
address,
callback) {
var self = this;

if (!Buffer.isBuffer(buffer))
throw new TypeError('First argument must be a buffer object.');

if (offset >= buffer.length)


throw new Error('Offset into buffer too large');

if (offset + length > buffer.length)


throw new Error('Offset + length beyond buffer length');

callback = callback || noop;

self._healthCheck();
self._startReceiving();

self._handle.lookup(address, function(err, ip) {


if (err) {
if (callback) callback(err);
self.emit('error', err);
}
else if (self._handle) {
var req = self._handle.send(buffer, offset, length, port, ip);
if (req) {
req.oncomplete = afterSend;
req.cb = callback;
}
else {
// don't emit as error, dgram_legacy.js compatibility
var err = errnoException(errno, 'send');
process.nextTick(function() {
callback(err);
});
}
}
});
};

function afterSend(status, handle, req, buffer) {


var self = handle.owner;

// CHECKME socket's been closed by user, don't call callback?


if (handle !== self._handle)
void(0);

if (req.cb)
req.cb(null, buffer.length); // compatibility with dgram_legacy.js
}

Socket.prototype.close = function() {
this._healthCheck();
this._stopReceiving();
this._handle.close();
this._handle = null;
this.emit('close');
};
Socket.prototype.address = function() {
this._healthCheck();

var address = this._handle.getsockname();


if (!address)
throw errnoException(errno, 'getsockname');

return address;
};

Socket.prototype.setBroadcast = function(arg) {
if (this._handle.setBroadcast((arg) ? 1 : 0)) {
throw errnoException(errno, 'setBroadcast');
}
};

Socket.prototype.setTTL = function(arg) {
if (typeof arg !== 'number') {
throw new TypeError('Argument must be a number');
}

if (this._handle.setTTL(arg)) {
throw errnoException(errno, 'setTTL');
}

return arg;
};

Socket.prototype.setMulticastTTL = function(arg) {
if (typeof arg !== 'number') {
throw new TypeError('Argument must be a number');
}

if (this._handle.setMulticastTTL(arg)) {
throw errnoException(errno, 'setMulticastTTL');
}

return arg;
};

Socket.prototype.setMulticastLoopback = function(arg) {
arg = arg ? 1 : 0;

if (this._handle.setMulticastLoopback(arg)) {
throw errnoException(errno, 'setMulticastLoopback');
}

return arg; // 0.4 compatibility


};

Socket.prototype.addMembership = function(multicastAddress,
interfaceAddress) {
this._healthCheck();
if (!multicastAddress) {
throw new Error('multicast address must be specified');
}

if (this._handle.addMembership(multicastAddress, interfaceAddress)) {
throw new errnoException(errno, 'addMembership');
}
};

Socket.prototype.dropMembership = function(multicastAddress,
interfaceAddress) {
this._healthCheck();

if (!multicastAddress) {
throw new Error('multicast address must be specified');
}

if (this._handle.dropMembership(multicastAddress, interfaceAddress)) {
throw new errnoException(errno, 'dropMembership');
}
};

Socket.prototype._healthCheck = function() {
if (!this._handle)
throw new Error('Not running'); // error message from dgram_legacy.js
};

Socket.prototype._startReceiving = function() {
if (this._receiving)
return;

if (!this._bound) {
this.bind(); // bind to random port

// sanity check
if (!this._bound)
throw new Error('implicit bind failed');
}

this._handle.onmessage = onMessage;
this._handle.recvStart();
this._receiving = true;
this.fd = -42; // compatibility hack
};

Socket.prototype._stopReceiving = function() {
if (!this._receiving)
return;

// Black hole messages coming in when reading is stopped. Libuv might do


// this, but node applications (e.g. test/simple/test-dgram-pingpong) may
// not expect it.
this._handle.onmessage = noop;
this._handle.recvStop();
this._receiving = false;
this.fd = null; // compatibility hack
};

function onMessage(handle, slab, start, len, rinfo) {


var self = handle.owner;
if (!slab) return self.emit('error', errnoException(errno, 'recvmsg'));
rinfo.size = len; // compatibility
self.emit('message', slab.slice(start, start + len), rinfo);
}

// TODO share with net_uv and others


function errnoException(errorno, syscall) {
var e = new Error(syscall + ' ' + errorno);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}
#####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// 'Software'), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var cares = process.binding('cares_wrap'),


net = require('net'),
isIp = net.isIP;

function errnoException(errorno, syscall) {


// TODO make this more compatible with ErrnoException from src/node.cc
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.

// For backwards compatibility. libuv returns ENOENT on NXDOMAIN.


if (errorno == 'ENOENT') {
errorno = 'ENOTFOUND';
}

var e = new Error(syscall + ' ' + errorno);


e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}

// c-ares invokes a callback either synchronously or asynchronously,


// but the dns API should always invoke a callback asynchronously.
//
// This function makes sure that the callback is invoked asynchronously.
// It returns a function that invokes the callback within nextTick().
//
// To avoid invoking unnecessary nextTick(), `immediately` property of
// returned function should be set to true after c-ares returned.
//
// Usage:
//
// function someAPI(callback) {
// callback = makeAsync(callback);
// channel.someAPI(..., callback);
// callback.immediately = true;
// }
function makeAsync(callback) {
if (typeof callback !== 'function') {
return callback;
}
return function asyncCallback() {
if (asyncCallback.immediately) {
// The API already returned, we can invoke the callback immediately.
callback.apply(null, arguments);
} else {
var args = arguments;
process.nextTick(function() {
callback.apply(null, args);
});
}
};
}

// Easy DNS A/AAAA look up


// lookup(domain, [family,] callback)
exports.lookup = function(domain, family, callback) {
// parse arguments
if (arguments.length === 2) {
callback = family;
family = 0;
} else if (!family) {
family = 0;
} else {
family = +family;
if (family !== 4 && family !== 6) {
throw new Error('invalid argument: `family` must be 4 or 6');
}
}
callback = makeAsync(callback);

if (!domain) {
callback(null, null, family === 6 ? 6 : 4);
return {};
}

// Hack required for Windows because Win7 removed the


// localhost entry from c:\WINDOWS\system32\drivers\etc\hosts
// See http://daniel.haxx.se/blog/2011/02/21/localhost-hack-on-windows/
// TODO Remove this once c-ares handles this problem.
if (process.platform == 'win32' && domain == 'localhost') {
callback(null, '127.0.0.1', 4);
return {};
}

var matchedFamily = net.isIP(domain);


if (matchedFamily) {
callback(null, domain, matchedFamily);
return {};
}

function onanswer(addresses) {
if (addresses) {
if (family) {
callback(null, addresses[0], family);
} else {
callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
}
} else {
callback(errnoException(errno, 'getaddrinfo'));
}
}

var wrap = cares.getaddrinfo(domain, family);

if (!wrap) {
throw errnoException(errno, 'getaddrinfo');
}

wrap.oncomplete = onanswer;

callback.immediately = true;
return wrap;
};

function resolver(bindingName) {
var binding = cares[bindingName];

return function query(name, callback) {


function onanswer(status, result) {
if (!status) {
callback(null, result);
} else {
callback(errnoException(errno, bindingName));
}
}

callback = makeAsync(callback);
var wrap = binding(name, onanswer);
if (!wrap) {
throw errnoException(errno, bindingName);
}

callback.immediately = true;
return wrap;
}
}

var resolveMap = {};


exports.resolve4 = resolveMap.A = resolver('queryA');
exports.resolve6 = resolveMap.AAAA = resolver('queryAaaa');
exports.resolveCname = resolveMap.CNAME = resolver('queryCname');
exports.resolveMx = resolveMap.MX = resolver('queryMx');
exports.resolveNs = resolveMap.NS = resolver('queryNs');
exports.resolveTxt = resolveMap.TXT = resolver('queryTxt');
exports.resolveSrv = resolveMap.SRV = resolver('querySrv');
exports.reverse = resolveMap.PTR = resolver('getHostByAddr');

exports.resolve = function(domain, type_, callback_) {


var resolver, callback;
if (typeof type_ == 'string') {
resolver = resolveMap[type_];
callback = callback_;
} else {
resolver = exports.resolve4;
callback = type_;
}

if (typeof resolver === 'function') {


return resolver(domain, callback);
} else {
throw new Error('Unknown type "' + type + '"');
}
};

// ERROR CODES
exports.NODATA = 'ENODATA';
exports.FORMERR = 'EFORMERR';
exports.SERVFAIL = 'ESERVFAIL';
exports.NOTFOUND = 'ENOTFOUND';
exports.NOTIMP = 'ENOTIMP';
exports.REFUSED = 'EREFUSED';
exports.BADQUERY = 'EBADQUERY';
exports.ADNAME = 'EADNAME';
exports.BADFAMILY = 'EBADFAMILY';
exports.BADRESP = 'EBADRESP';
exports.CONNREFUSED = 'ECONNREFUSED';
exports.TIMEOUT = 'ETIMEOUT';
exports.EOF = 'EOF';
exports.FILE = 'EFILE';
exports.NOMEM = 'ENOMEM';
exports.DESTRUCTION = 'EDESTRUCTION';
exports.BADSTR = 'EBADSTR';
exports.BADFLAGS = 'EBADFLAGS';
exports.NONAME = 'ENONAME';
exports.BADHINTS = 'EBADHINTS';
exports.NOTINITIALIZED = 'ENOTINITIALIZED';
exports.LOADIPHLPAPI = 'ELOADIPHLPAPI';
exports.ADDRGETNETWORKPARAMS = 'EADDRGETNETWORKPARAMS';
exports.CANCELLED = 'ECANCELLED';
#######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util');


var events = require('events');
var EventEmitter = events.EventEmitter;
var inherits = util.inherits;

// methods that are called when trying to shut down expliclitly bound EEs
var endMethods = ['end', 'abort', 'destroy', 'destroySoon'];

// communicate with events module, but don't require that


// module to have to load this one, since this module has
// a few side effects.
events.usingDomains = true;

exports.Domain = Domain;

exports.create = exports.createDomain = function(cb) {


return new Domain(cb);
};

// it's possible to enter one domain while already inside


// another one. the stack is each entered domain.
var stack = [];
exports._stack = stack;
// the active domain is always the one that we're currently in.
exports.active = null;

// loading this file the first time sets up the global


// uncaughtException handler.
process.on('uncaughtException', uncaughtHandler);

function uncaughtHandler(er) {
// if there's an active domain, then handle this there.
// Note that if this error emission throws, then it'll just crash.
if (exports.active && !exports.active._disposed) {
util._extend(er, {
domain: exports.active,
domain_thrown: true
});
exports.active.emit('error', er);
if (exports.active) exports.active.exit();
} else if (process.listeners('uncaughtException').length === 1) {
// if there are other handlers, then they'll take care of it.
// but if not, then we need to crash now.
throw er;
}
}

inherits(Domain, EventEmitter);

function Domain() {
EventEmitter.apply(this);

this.members = [];
}

Domain.prototype.enter = function() {
if (this._disposed) return;

// note that this might be a no-op, but we still need


// to push it onto the stack so that we can pop it later.
exports.active = process.domain = this;
stack.push(this);
};

Domain.prototype.exit = function() {
if (this._disposed) return;

// exit all domains until this one.


var d;
do {
d = stack.pop();
} while (d && d !== this);

exports.active = stack[stack.length - 1];


process.domain = exports.active;
};

// note: this works for timers as well.


Domain.prototype.add = function(ee) {
// disposed domains can't be used for new things.
if (this._disposed) return;

// already added to this domain.


if (ee.domain === this) return;

// has a domain already - remove it first.


if (ee.domain) {
ee.domain.remove(ee);
}

// check for circular Domain->Domain links.


// This causes bad insanity!
//
// For example:
// var d = domain.create();
// var e = domain.create();
// d.add(e);
// e.add(d);
// e.emit('error', er); // RangeError, stack overflow!
if (this.domain && (ee instanceof Domain)) {
for (var d = this.domain; d; d = d.domain) {
if (ee === d) return;
}
}

ee.domain = this;
this.members.push(ee);
};

Domain.prototype.remove = function(ee) {
ee.domain = null;
var index = this.members.indexOf(ee);
if (index !== -1) {
this.members.splice(index, 1);
}
};

Domain.prototype.run = function(fn) {
return this.bind(fn)();
};

Domain.prototype.intercept = function(cb) {
return this.bind(cb, true);
};

Domain.prototype.bind = function(cb, interceptError) {


// if cb throws, catch it here.
var self = this;
var b = function() {
// disposing turns functions into no-ops
if (self._disposed) return;

if (this instanceof Domain) {


return cb.apply(this, arguments);
}

// only intercept first-arg errors if explicitly requested.


if (interceptError && arguments[0] &&
(arguments[0] instanceof Error)) {
var er = arguments[0];
util._extend(er, {
domain_bound: cb,
domain_thrown: false,
domain: self
});
self.emit('error', er);
return;
}

// remove first-arg if intercept as assumed to be the error-arg


if (interceptError) {
var len = arguments.length;
var args;
switch (len) {
case 0:
case 1:
// no args that we care about.
args = [];
break;
case 2:
// optimization for most common case: cb(er, data)
args = [arguments[1]];
break;
default:
// slower for less common case: cb(er, foo, bar, baz, ...)
args = new Array(len - 1);
for (var i = 1; i < len; i++) {
args[i - 1] = arguments[i];
}
break;
}
self.enter();
var ret = cb.apply(this, args);
self.exit();
return ret;
}

self.enter();
var ret = cb.apply(this, arguments);
self.exit();
return ret;
};
b.domain = this;
return b;
};

Domain.prototype.dispose = function() {
if (this._disposed) return;

// if we're the active domain, then get out now.


this.exit();

this.emit('dispose');

// remove error handlers.


this.removeAllListeners();
this.on('error', function() {});

// try to kill all the members.


// XXX There should be more consistent ways
// to shut down things!
this.members.forEach(function(m) {
// if it's a timeout or interval, cancel it.
clearTimeout(m);

// drop all event listeners.


if (m instanceof EventEmitter) {
m.removeAllListeners();
// swallow errors
m.on('error', function() {});
}
// Be careful!
// By definition, we're likely in error-ridden territory here,
// so it's quite possible that calling some of these methods
// might cause additional exceptions to be thrown.
endMethods.forEach(function(method) {
if (typeof m[method] === 'function') {
try {
m[method]();
} catch (er) {}
}
});

});

// remove from parent domain, if there is one.


if (this.domain) this.domain.remove(this);

// kill the references so that they can be properly gc'ed.


this.members.length = 0;

// finally, mark this domain as 'no longer relevant'


// so that it can't be entered or activated.
this._disposed = true;
};
##// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var isArray = Array.isArray;


var domain;

function EventEmitter() {
this.domain = null;
if (exports.usingDomains) {
// if there is an active domain, then attach to it.
domain = domain || require('domain');
if (domain.active && !(this instanceof domain.Domain)) {
this.domain = domain.active;
}
}
this._events = this._events || null;
this._maxListeners = this._maxListeners || defaultMaxListeners;
}
exports.EventEmitter = EventEmitter;

// By default EventEmitters will print a warning if more than


// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
if (!this._events) this._events = {};
this._maxListeners = n;
};

// non-global reference, for speed.


var PROCESS;

EventEmitter.prototype.emit = function() {
var type = arguments[0];
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
(isArray(this._events.error) && !this._events.error.length))
{
if (this.domain) {
var er = arguments[1];
er.domain_emitter = this;
er.domain = this.domain;
er.domain_thrown = false;
this.domain.emit('error', er);
return false;
}

if (arguments[1] instanceof Error) {


throw arguments[1]; // Unhandled 'error' event
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}

if (!this._events) return false;


var handler = this._events[type];
if (!handler) return false;

if (typeof handler == 'function') {


if (this.domain) {
PROCESS = PROCESS || process;
if (this !== PROCESS) {
this.domain.enter();
}
}
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
handler.apply(this, args);
}
if (this.domain && this !== PROCESS) {
this.domain.exit();
}
return true;

} else if (isArray(handler)) {
if (this.domain) {
PROCESS = PROCESS || process;
if (this !== PROCESS) {
this.domain.enter();
}
}
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];

var listeners = handler.slice();


for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i].apply(this, args);
}
if (this.domain && this !== PROCESS) {
this.domain.exit();
}
return true;

} else {
return false;
}
};

EventEmitter.prototype.addListener = function(type, listener) {


if ('function' !== typeof listener) {
throw new Error('addListener only takes instances of Function');
}

if (!this._events) this._events = {};

// To avoid recursion in the case that type == "newListeners"! Before


// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, typeof listener.listener === 'function' ?
listener.listener : listener);

if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {

// If we've already got an array, just append.


this._events[type].push(listener);

} else {
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];

// Check for listener leak


if (isArray(this._events[type]) && !this._events[type].warned) {
var m;
m = this._maxListeners;

if (m && m > 0 && this._events[type].length > m) {


this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}

return this;
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.once = function(type, listener) {


if ('function' !== typeof listener) {
throw new Error('.once only takes instances of Function');
}

var self = this;


function g() {
self.removeListener(type, g);
listener.apply(this, arguments);
};

g.listener = listener;
self.on(type, g);

return this;
};

EventEmitter.prototype.removeListener = function(type, listener) {


if ('function' !== typeof listener) {
throw new Error('removeListener only takes instances of Function');
}

// does not use listeners(), so no side effect of creating _events[type]


if (!this._events || !this._events[type]) return this;

var list = this._events[type];

if (isArray(list)) {
var position = -1;
for (var i = 0, length = list.length; i < length; i++) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener))
{
position = i;
break;
}
}

if (position < 0) return this;


list.splice(position, 1);
if (list.length == 0)
delete this._events[type];
} else if (list === listener ||
(list.listener && list.listener === listener))
{
delete this._events[type];
}

return this;
};

EventEmitter.prototype.removeAllListeners = function(type) {
if (arguments.length === 0) {
this._events = {};
return this;
}

// does not use listeners(), so no side effect of creating _events[type]


if (type && this._events && this._events[type]) this._events[type] = null;
return this;
};

EventEmitter.prototype.listeners = function(type) {
if (!this._events) this._events = {};
if (!this._events[type]) this._events[type] = [];
if (!isArray(this._events[type])) {
this._events[type] = [this._events[type]];
}
return this._events[type];
};
#// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// This is a free list to avoid creating so many of the same object.


exports.FreeList = function(name, max, constructor) {
this.name = name;
this.constructor = constructor;
this.max = max;
this.list = [];
};

exports.FreeList.prototype.alloc = function() {
//debug("alloc " + this.name + " " + this.list.length);
return this.list.length ? this.list.shift() :
this.constructor.apply(this, arguments);
};

exports.FreeList.prototype.free = function(obj) {
//debug("free " + this.name + " " + this.list.length);
if (this.list.length < this.max) {
this.list.push(obj);
}
};
####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// Maintainers, keep in mind that octal literals are not allowed


// in strict mode. Use the decimal value and add a comment with
// the octal value. Example:
//
// var mode = 438; /* mode=0666 */

var util = require('util');


var pathModule = require('path');

var binding = process.binding('fs');


var constants = process.binding('constants');
var fs = exports;
var Stream = require('stream').Stream;
var EventEmitter = require('events').EventEmitter;

var kMinPoolSpace = 128;


var kPoolSize = 40 * 1024;

var O_APPEND = constants.O_APPEND || 0;


var O_CREAT = constants.O_CREAT || 0;
var O_DIRECTORY = constants.O_DIRECTORY || 0;
var O_EXCL = constants.O_EXCL || 0;
var O_NOCTTY = constants.O_NOCTTY || 0;
var O_NOFOLLOW = constants.O_NOFOLLOW || 0;
var O_RDONLY = constants.O_RDONLY || 0;
var O_RDWR = constants.O_RDWR || 0;
var O_SYMLINK = constants.O_SYMLINK || 0;
var O_SYNC = constants.O_SYNC || 0;
var O_TRUNC = constants.O_TRUNC || 0;
var O_WRONLY = constants.O_WRONLY || 0;

var isWindows = process.platform === 'win32';

fs.Stats = binding.Stats;

fs.Stats.prototype._checkModeProperty = function(property) {
return ((this.mode & constants.S_IFMT) === property);
};

fs.Stats.prototype.isDirectory = function() {
return this._checkModeProperty(constants.S_IFDIR);
};

fs.Stats.prototype.isFile = function() {
return this._checkModeProperty(constants.S_IFREG);
};

fs.Stats.prototype.isBlockDevice = function() {
return this._checkModeProperty(constants.S_IFBLK);
};

fs.Stats.prototype.isCharacterDevice = function() {
return this._checkModeProperty(constants.S_IFCHR);
};

fs.Stats.prototype.isSymbolicLink = function() {
return this._checkModeProperty(constants.S_IFLNK);
};

fs.Stats.prototype.isFIFO = function() {
return this._checkModeProperty(constants.S_IFIFO);
};

fs.Stats.prototype.isSocket = function() {
return this._checkModeProperty(constants.S_IFSOCK);
};

fs.exists = function(path, callback) {


binding.stat(pathModule._makeLong(path), function(err, stats) {
if (callback) callback(err ? false : true);
});
};

fs.existsSync = function(path) {
try {
binding.stat(pathModule._makeLong(path));
return true;
} catch (e) {
return false;
}
};

fs.readFile = function(path, encoding_) {


var encoding = typeof(encoding_) === 'string' ? encoding_ : null;
var callback = arguments[arguments.length - 1];
if (typeof(callback) !== 'function') callback = function() {};

// first, stat the file, so we know the size.


var size;
var buffer; // single buffer with file data
var buffers; // list for when size is unknown
var pos = 0;
var fd;

fs.open(path, constants.O_RDONLY, 438 /*=0666*/, function(er, fd_) {


if (er) return callback(er);
fd = fd_;

fs.fstat(fd, function(er, st) {


if (er) return callback(er);
size = st.size;
if (size === 0) {
// the kernel lies about many files.
// Go ahead and try to read some bytes.
buffers = [];
return read();
}

buffer = new Buffer(size);


read();
});
});

function read() {
if (size === 0) {
buffer = new Buffer(8192);
fs.read(fd, buffer, 0, 8192, -1, afterRead);
} else {
fs.read(fd, buffer, pos, size - pos, -1, afterRead);
}
}

function afterRead(er, bytesRead) {


if (er) {
return fs.close(fd, function(er2) {
return callback(er);
});
}

if (bytesRead === 0) {
return close();
}

pos += bytesRead;
if (size !== 0) {
if (pos === size) close();
else read();
} else {
// unknown size, just read until we don't get bytes.
buffers.push(buffer.slice(0, bytesRead));
read();
}
}

function close() {
fs.close(fd, function(er) {
if (size === 0) {
// collected the data into the buffers list.
buffer = Buffer.concat(buffers, pos);
} else if (pos < size) {
buffer = buffer.slice(0, pos);
}

if (encoding) buffer = buffer.toString(encoding);


return callback(er, buffer);
});
}
};

fs.readFileSync = function(path, encoding) {


var fd = fs.openSync(path, constants.O_RDONLY, 438 /*=0666*/);

var size;
var threw = true;
try {
size = fs.fstatSync(fd).size;
threw = false;
} finally {
if (threw) fs.closeSync(fd);
}

var pos = 0;
var buffer; // single buffer with file data
var buffers; // list for when size is unknown

if (size === 0) {
buffers = [];
} else {
buffer = new Buffer(size);
}

var done = false;


while (!done) {
var threw = true;
try {
if (size !== 0) {
var bytesRead = fs.readSync(fd, buffer, pos, size - pos);
} else {
// the kernel lies about many files.
// Go ahead and try to read some bytes.
buffer = new Buffer(8192);
var bytesRead = fs.readSync(fd, buffer, 0, 8192);
if (bytesRead) {
buffers.push(buffer.slice(0, bytesRead));
}
}
threw = false;
} finally {
if (threw) fs.closeSync(fd);
}

pos += bytesRead;
done = (bytesRead === 0) || (size !== 0 && pos >= size);
}

fs.closeSync(fd);

if (size === 0) {
// data was collected into the buffers list.
buffer = Buffer.concat(buffers, pos);
} else if (pos < size) {
buffer = buffer.slice(0, pos);
}

if (encoding) buffer = buffer.toString(encoding);


return buffer;
};

// Used by binding.open and friends


function stringToFlags(flag) {
// Only mess with strings
if (typeof flag !== 'string') {
return flag;
}

// O_EXCL is mandated by POSIX, Windows supports it too.


// Let's add a check anyway, just in case.
if (!O_EXCL && ~flag.indexOf('x')) {
throw errnoException('ENOSYS', 'fs.open(O_EXCL)');
}

switch (flag) {
case 'r' : return O_RDONLY;
case 'rs' : return O_RDONLY | O_SYNC;
case 'r+' : return O_RDWR;
case 'rs+' : return O_RDWR | O_SYNC;

case 'w' : return O_TRUNC | O_CREAT | O_WRONLY;


case 'wx' : // fall through
case 'xw' : return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL;

case 'w+' : return O_TRUNC | O_CREAT | O_RDWR;


case 'wx+': // fall through
case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL;

case 'a' : return O_APPEND | O_CREAT | O_WRONLY;


case 'ax' : // fall through
case 'xa' : return O_APPEND | O_CREAT | O_WRONLY | O_EXCL;

case 'a+' : return O_APPEND | O_CREAT | O_RDWR;


case 'ax+': // fall through
case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL;
}

throw new Error('Unknown file open flag: ' + flag);


}

// exported but hidden, only used by test/simple/test-fs-open-flags.js


Object.defineProperty(exports, '_stringToFlags', {
enumerable: false,
value: stringToFlags
});

// Ensure that callbacks run in the global context. Only use this function
// for callbacks that are passed to the binding layer, callbacks that are
// invoked from JS already run in the proper scope.
function makeCallback(cb) {
if (typeof cb !== 'function') {
// faster than returning a ref to a global no-op function
return function() {};
}

return function() {
return cb.apply(null, arguments);
};
}

// Yes, the follow could be easily DRYed up but I provide the explicit
// list to make the arguments clear.

fs.close = function(fd, callback) {


binding.close(fd, makeCallback(callback));
};

fs.closeSync = function(fd) {
return binding.close(fd);
};

function modeNum(m, def) {


switch (typeof m) {
case 'number': return m;
case 'string': return parseInt(m, 8);
default:
if (def) {
return modeNum(def);
} else {
return undefined;
}
}
}

fs.open = function(path, flags, mode, callback) {


callback = makeCallback(arguments[arguments.length - 1]);
mode = modeNum(mode, 438 /*=0666*/);
binding.open(pathModule._makeLong(path),
stringToFlags(flags),
mode,
callback);
};

fs.openSync = function(path, flags, mode) {


mode = modeNum(mode, 438 /*=0666*/);
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
};

fs.read = function(fd, buffer, offset, length, position, callback) {


if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, length, position, encoding, callback)
var cb = arguments[4],
encoding = arguments[3];
position = arguments[2];
length = arguments[1];
buffer = new Buffer(length);
offset = 0;

callback = function(err, bytesRead) {


if (!cb) return;

var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : '';

(cb)(err, str, bytesRead);


};
}

function wrapper(err, bytesRead) {


// Retain a reference to buffer so that it can't be GC'ed too soon.
callback && callback(err, bytesRead || 0, buffer);
}

binding.read(fd, buffer, offset, length, position, wrapper);


};

fs.readSync = function(fd, buffer, offset, length, position) {


var legacy = false;
if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, length, position, encoding, callback)
legacy = true;
var encoding = arguments[3];
position = arguments[2];
length = arguments[1];
buffer = new Buffer(length);

offset = 0;
}

var r = binding.read(fd, buffer, offset, length, position);


if (!legacy) {
return r;
}

var str = (r > 0) ? buffer.toString(encoding, 0, r) : '';


return [str, r];
};

fs.write = function(fd, buffer, offset, length, position, callback) {


if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, data, position, encoding, callback)
callback = arguments[4];
position = arguments[2];

buffer = new Buffer('' + arguments[1], arguments[3]);


offset = 0;
length = buffer.length;
}

if (!length) {
if (typeof callback == 'function') {
process.nextTick(function() {
callback(undefined, 0);
});
}
return;
}

function wrapper(err, written) {


// Retain a reference to buffer so that it can't be GC'ed too soon.
callback && callback(err, written || 0, buffer);
}

binding.write(fd, buffer, offset, length, position, wrapper);


};

fs.writeSync = function(fd, buffer, offset, length, position) {


if (!Buffer.isBuffer(buffer)) {
// legacy string interface (fd, data, position, encoding)
position = arguments[2];

buffer = new Buffer('' + arguments[1], arguments[3]);


offset = 0;
length = buffer.length;
}
if (!length) return 0;

return binding.write(fd, buffer, offset, length, position);


};

fs.rename = function(oldPath, newPath, callback) {


binding.rename(pathModule._makeLong(oldPath),
pathModule._makeLong(newPath),
makeCallback(callback));
};

fs.renameSync = function(oldPath, newPath) {


return binding.rename(pathModule._makeLong(oldPath),
pathModule._makeLong(newPath));
};

fs.truncate = function(fd, len, callback) {


binding.truncate(fd, len, makeCallback(callback));
};
fs.truncateSync = function(fd, len) {
return binding.truncate(fd, len);
};

fs.rmdir = function(path, callback) {


binding.rmdir(pathModule._makeLong(path), makeCallback(callback));
};

fs.rmdirSync = function(path) {
return binding.rmdir(pathModule._makeLong(path));
};

fs.fdatasync = function(fd, callback) {


binding.fdatasync(fd, makeCallback(callback));
};

fs.fdatasyncSync = function(fd) {
return binding.fdatasync(fd);
};

fs.fsync = function(fd, callback) {


binding.fsync(fd, makeCallback(callback));
};

fs.fsyncSync = function(fd) {
return binding.fsync(fd);
};

fs.mkdir = function(path, mode, callback) {


if (typeof mode === 'function') callback = mode;
binding.mkdir(pathModule._makeLong(path),
modeNum(mode, 511 /*=0777*/),
makeCallback(callback));
};

fs.mkdirSync = function(path, mode) {


return binding.mkdir(pathModule._makeLong(path),
modeNum(mode, 511 /*=0777*/));
};

fs.sendfile = function(outFd, inFd, inOffset, length, callback) {


binding.sendfile(outFd, inFd, inOffset, length, makeCallback(callback));
};

fs.sendfileSync = function(outFd, inFd, inOffset, length) {


return binding.sendfile(outFd, inFd, inOffset, length);
};

fs.readdir = function(path, callback) {


binding.readdir(pathModule._makeLong(path), makeCallback(callback));
};

fs.readdirSync = function(path) {
return binding.readdir(pathModule._makeLong(path));
};

fs.fstat = function(fd, callback) {


binding.fstat(fd, makeCallback(callback));
};
fs.lstat = function(path, callback) {
binding.lstat(pathModule._makeLong(path), makeCallback(callback));
};

fs.stat = function(path, callback) {


binding.stat(pathModule._makeLong(path), makeCallback(callback));
};

fs.fstatSync = function(fd) {
return binding.fstat(fd);
};

fs.lstatSync = function(path) {
return binding.lstat(pathModule._makeLong(path));
};

fs.statSync = function(path) {
return binding.stat(pathModule._makeLong(path));
};

fs.statSyncNoException = function(path) {
return binding.statNoException(pathModule._makeLong(path));
};

fs.readlink = function(path, callback) {


binding.readlink(pathModule._makeLong(path), makeCallback(callback));
};

fs.readlinkSync = function(path) {
return binding.readlink(pathModule._makeLong(path));
};

function preprocessSymlinkDestination(path, type) {


if (!isWindows) {
// No preprocessing is needed on Unix.
return path;
} else if (type === 'junction') {
// Junctions paths need to be absolute and \\?\-prefixed.
return pathModule._makeLong(path);
} else {
// Windows symlinks don't tolerate forward slashes.
return ('' + path).replace(/\//g, '\\');
}
}

fs.symlink = function(destination, path, type_, callback) {


var type = (typeof type_ === 'string' ? type_ : null);
var callback = makeCallback(arguments[arguments.length - 1]);

binding.symlink(preprocessSymlinkDestination(destination, type),
pathModule._makeLong(path),
type,
callback);
};

fs.symlinkSync = function(destination, path, type) {


type = (typeof type === 'string' ? type : null);
return binding.symlink(preprocessSymlinkDestination(destination, type),
pathModule._makeLong(path),
type);
};

fs.link = function(srcpath, dstpath, callback) {


binding.link(pathModule._makeLong(srcpath),
pathModule._makeLong(dstpath),
makeCallback(callback));
};

fs.linkSync = function(srcpath, dstpath) {


return binding.link(pathModule._makeLong(srcpath),
pathModule._makeLong(dstpath));
};

fs.unlink = function(path, callback) {


binding.unlink(pathModule._makeLong(path), makeCallback(callback));
};

fs.unlinkSync = function(path) {
return binding.unlink(pathModule._makeLong(path));
};

fs.fchmod = function(fd, mode, callback) {


binding.fchmod(fd, modeNum(mode), makeCallback(callback));
};

fs.fchmodSync = function(fd, mode) {


return binding.fchmod(fd, modeNum(mode));
};

if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchmod = function(path, mode, callback) {
callback = callback || (function() {});
fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
if (err) {
callback(err);
return;
}
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
fs.fchmod(fd, mode, function(err) {
fs.close(fd, function(err2) {
callback(err || err2);
});
});
});
};

fs.lchmodSync = function(path, mode) {


var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);

// prefer to return the chmod error, if one occurs,


// but still try to close, and report closing errors if they occur.
var err, err2;
try {
var ret = fs.fchmodSync(fd, mode);
} catch (er) {
err = er;
}
try {
fs.closeSync(fd);
} catch (er) {
err2 = er;
}
if (err || err2) throw (err || err2);
return ret;
};
}

fs.chmod = function(path, mode, callback) {


binding.chmod(pathModule._makeLong(path),
modeNum(mode),
makeCallback(callback));
};

fs.chmodSync = function(path, mode) {


return binding.chmod(pathModule._makeLong(path), modeNum(mode));
};

if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchown = function(path, uid, gid, callback) {
callback = callback || (function() {});
fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function(err, fd) {
if (err) {
callback(err);
return;
}
fs.fchown(fd, uid, gid, callback);
});
};

fs.lchownSync = function(path, uid, gid) {


var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK);
return fs.fchownSync(fd, uid, gid);
};
}

fs.fchown = function(fd, uid, gid, callback) {


binding.fchown(fd, uid, gid, makeCallback(callback));
};

fs.fchownSync = function(fd, uid, gid) {


return binding.fchown(fd, uid, gid);
};

fs.chown = function(path, uid, gid, callback) {


binding.chown(pathModule._makeLong(path), uid, gid, makeCallback(callback));
};

fs.chownSync = function(path, uid, gid) {


return binding.chown(pathModule._makeLong(path), uid, gid);
};

// converts Date or number to a fractional UNIX timestamp


function toUnixTimestamp(time) {
if (typeof time == 'number') {
return time;
}
if (time instanceof Date) {
// convert to 123.456 UNIX timestamp
return time.getTime() / 1000;
}
throw new Error('Cannot parse time: ' + time);
}

// exported for unit tests, not for public consumption


fs._toUnixTimestamp = toUnixTimestamp;

fs.utimes = function(path, atime, mtime, callback) {


binding.utimes(pathModule._makeLong(path),
toUnixTimestamp(atime),
toUnixTimestamp(mtime),
makeCallback(callback));
};

fs.utimesSync = function(path, atime, mtime) {


atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.utimes(pathModule._makeLong(path), atime, mtime);
};

fs.futimes = function(fd, atime, mtime, callback) {


atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.futimes(fd, atime, mtime, makeCallback(callback));
};

fs.futimesSync = function(fd, atime, mtime) {


atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.futimes(fd, atime, mtime);
};

function writeAll(fd, buffer, offset, length, position, callback) {


var callback_ = arguments[arguments.length - 1];
callback = (typeof(callback_) == 'function' ? callback_ : null);

// write(fd, buffer, offset, length, position, callback)


fs.write(fd, buffer, offset, length, position, function(writeErr, written) {
if (writeErr) {
fs.close(fd, function() {
if (callback) callback(writeErr);
});
} else {
if (written === length) {
fs.close(fd, callback);
} else {
offset += written;
length -= written;
position += written;
writeAll(fd, buffer, offset, length, position, callback);
}
}
});
}

fs.writeFile = function(path, data, encoding_, callback) {


var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8');
var callback_ = arguments[arguments.length - 1];
callback = (typeof(callback_) == 'function' ? callback_ : null);
fs.open(path, 'w', 438 /*=0666*/, function(openErr, fd) {
if (openErr) {
if (callback) callback(openErr);
} else {
var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data,
encoding);
writeAll(fd, buffer, 0, buffer.length, 0, callback);
}
});
};

fs.writeFileSync = function(path, data, encoding) {


var fd = fs.openSync(path, 'w');
if (!Buffer.isBuffer(data)) {
data = new Buffer('' + data, encoding || 'utf8');
}
var written = 0;
var length = data.length;
try {
while (written < length) {
written += fs.writeSync(fd, data, written, length - written, written);
}
} finally {
fs.closeSync(fd);
}
};

fs.appendFile = function(path, data, encoding_, callback) {


var encoding = (typeof(encoding_) == 'string' ? encoding_ : 'utf8');
var callback_ = arguments[arguments.length - 1];
callback = (typeof(callback_) == 'function' ? callback_ : null);

fs.open(path, 'a', 438 /*=0666*/, function(err, fd) {


if (err) return callback(err);
var buffer = Buffer.isBuffer(data) ? data : new Buffer('' + data, encoding);
writeAll(fd, buffer, 0, buffer.length, null, callback);
});
};

fs.appendFileSync = function(path, data, encoding) {


var fd = fs.openSync(path, 'a');
if (!Buffer.isBuffer(data)) {
data = new Buffer('' + data, encoding || 'utf8');
}
var written = 0;
var position = null;
var length = data.length;

try {
while (written < length) {
written += fs.writeSync(fd, data, written, length - written, position);
position += written; // XXX not safe with multiple concurrent writers?
}
} finally {
fs.closeSync(fd);
}
};

function errnoException(errorno, syscall) {


// TODO make this more compatible with ErrnoException from src/node.cc
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.
var e = new Error(syscall + ' ' + errorno);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}

function FSWatcher() {
EventEmitter.call(this);

var self = this;


var FSEvent = process.binding('fs_event_wrap').FSEvent;
this._handle = new FSEvent();
this._handle.owner = this;

this._handle.onchange = function(status, event, filename) {


if (status) {
self._handle.close();
self.emit('error', errnoException(errno, 'watch'));
} else {
self.emit('change', event, filename);
}
};
}
util.inherits(FSWatcher, EventEmitter);

FSWatcher.prototype.start = function(filename, persistent) {


var r = this._handle.start(pathModule._makeLong(filename), persistent);

if (r) {
this._handle.close();
throw errnoException(errno, 'watch');
}
};

FSWatcher.prototype.close = function() {
this._handle.close();
};

fs.watch = function(filename) {
var watcher;
var options;
var listener;

if ('object' == typeof arguments[1]) {


options = arguments[1];
listener = arguments[2];
} else {
options = {};
listener = arguments[1];
}

if (options.persistent === undefined) options.persistent = true;

watcher = new FSWatcher();


watcher.start(filename, options.persistent);

if (listener) {
watcher.addListener('change', listener);
}

return watcher;
};

// Stat Change Watchers

function StatWatcher() {
EventEmitter.call(this);

var self = this;


this._handle = new binding.StatWatcher();

// uv_fs_poll is a little more powerful than ev_stat but we curb it for


// the sake of backwards compatibility
var oldStatus = -1;

this._handle.onchange = function(current, previous, newStatus) {


if (oldStatus === -1 &&
newStatus === -1 &&
current.nlink === previous.nlink) return;

oldStatus = newStatus;
self.emit('change', current, previous);
};

this._handle.onstop = function() {
self.emit('stop');
};
}
util.inherits(StatWatcher, EventEmitter);

StatWatcher.prototype.start = function(filename, persistent, interval) {


this._handle.start(pathModule._makeLong(filename), persistent, interval);
};

StatWatcher.prototype.stop = function() {
this._handle.stop();
};

var statWatchers = {};


function inStatWatchers(filename) {
return Object.prototype.hasOwnProperty.call(statWatchers, filename) &&
statWatchers[filename];
}
fs.watchFile = function(filename) {
var stat;
var listener;

var options = {
// Poll interval in milliseconds. 5007 is what libev used to use. It's
// a little on the slow side but let's stick with it for now to keep
// behavioral changes to a minimum.
interval: 5007,
persistent: true
};

if ('object' == typeof arguments[1]) {


options = util._extend(options, arguments[1]);
listener = arguments[2];
} else {
listener = arguments[1];
}

if (!listener) {
throw new Error('watchFile requires a listener function');
}

if (inStatWatchers(filename)) {
stat = statWatchers[filename];
} else {
stat = statWatchers[filename] = new StatWatcher();
stat.start(filename, options.persistent, options.interval);
}
stat.addListener('change', listener);
return stat;
};

fs.unwatchFile = function(filename, listener) {


if (!inStatWatchers(filename)) return;

var stat = statWatchers[filename];

if (typeof listener === 'function') {


stat.removeListener('change', listener);
} else {
stat.removeAllListeners('change');
}

if (stat.listeners('change').length === 0) {
stat.stop();
statWatchers[filename] = undefined;
}
};

// Realpath
// Not using realpath(2) because it's bad.
// See: http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html

var normalize = pathModule.normalize;

// Regexp that finds the next partion of a (partial) path


// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
if (isWindows) {
var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
} else {
var nextPartRe = /(.*?)(?:[\/]+|$)/g;
}

// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
if (isWindows) {
var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
} else {
var splitRootRe = /^[\/]*/;
}

fs.realpathSync = function realpathSync(p, cache) {


// make p is absolute
p = pathModule.resolve(p);

if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {


return cache[p];
}

var original = p,
seenLinks = {},
knownHard = {};

// current character position in p


var pos;
// the partial path so far, including a trailing slash if any
var current;
// the partial path without a trailing slash (except when pointing at a root)
var base;
// the partial path scanned in the previous round, with slash
var previous;

start();

function start() {
// Skip over roots
var m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
previous = '';

// On windows, check that the root exists. On unix there is no need.


if (isWindows && !knownHard[base]) {
fs.lstatSync(base);
knownHard[base] = true;
}
}

// walk down the path, swapping out linked pathparts for their real
// values
// NB: p.length changes.
while (pos < p.length) {
// find the next part
nextPartRe.lastIndex = pos;
var result = nextPartRe.exec(p);
previous = current;
current += result[0];
base = previous + result[1];
pos = nextPartRe.lastIndex;

// continue if not a symlink


if (knownHard[base] || (cache && cache[base] === base)) {
continue;
}

var resolvedLink;
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
// some known symbolic link. no need to stat again.
resolvedLink = cache[base];
} else {
var stat = fs.lstatSync(base);
if (!stat.isSymbolicLink()) {
knownHard[base] = true;
if (cache) cache[base] = base;
continue;
}

// read the link if it wasn't read before


// dev/ino always return 0 on windows, so skip the check.
var linkTarget = null;
if (!isWindows) {
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
if (seenLinks.hasOwnProperty(id)) {
linkTarget = seenLinks[id];
}
}
if (linkTarget === null) {
fs.statSync(base);
linkTarget = fs.readlinkSync(base);
}
resolvedLink = pathModule.resolve(previous, linkTarget);
// track this, if given a cache.
if (cache) cache[base] = resolvedLink;
if (!isWindows) seenLinks[id] = linkTarget;
}

// resolve the link, then start over


p = pathModule.resolve(resolvedLink, p.slice(pos));
start();
}

if (cache) cache[original] = p;

return p;
};

fs.realpath = function realpath(p, cache, cb) {


if (typeof cb !== 'function') {
cb = cache;
cache = null;
}

// make p is absolute
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return process.nextTick(cb.bind(null, null, cache[p]));
}

var original = p,
seenLinks = {},
knownHard = {};

// current character position in p


var pos;
// the partial path so far, including a trailing slash if any
var current;
// the partial path without a trailing slash (except when pointing at a root)
var base;
// the partial path scanned in the previous round, with slash
var previous;

start();

function start() {
// Skip over roots
var m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
previous = '';

// On windows, check that the root exists. On unix there is no need.


if (isWindows && !knownHard[base]) {
fs.lstat(base, function(err) {
if (err) return cb(err);
knownHard[base] = true;
LOOP();
});
} else {
process.nextTick(LOOP);
}
}

// walk down the path, swapping out linked pathparts for their real
// values
function LOOP() {
// stop if scanned past end of path
if (pos >= p.length) {
if (cache) cache[original] = p;
return cb(null, p);
}

// find the next part


nextPartRe.lastIndex = pos;
var result = nextPartRe.exec(p);
previous = current;
current += result[0];
base = previous + result[1];
pos = nextPartRe.lastIndex;

// continue if not a symlink


if (knownHard[base] || (cache && cache[base] === base)) {
return process.nextTick(LOOP);
}

if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {


// known symbolic link. no need to stat again.
return gotResolvedLink(cache[base]);
}

return fs.lstat(base, gotStat);


}

function gotStat(err, stat) {


if (err) return cb(err);

// if not a symlink, skip to the next path part


if (!stat.isSymbolicLink()) {
knownHard[base] = true;
if (cache) cache[base] = base;
return process.nextTick(LOOP);
}

// stat & read the link if not read before


// call gotTarget as soon as the link target is known
// dev/ino always return 0 on windows, so skip the check.
if (!isWindows) {
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
if (seenLinks.hasOwnProperty(id)) {
return gotTarget(null, seenLinks[id], base);
}
}
fs.stat(base, function(err) {
if (err) return cb(err);

fs.readlink(base, function(err, target) {


if (!isWindows) seenLinks[id] = target;
gotTarget(err, target);
});
});
}

function gotTarget(err, target, base) {


if (err) return cb(err);

var resolvedLink = pathModule.resolve(previous, target);


if (cache) cache[base] = resolvedLink;
gotResolvedLink(resolvedLink);
}

function gotResolvedLink(resolvedLink) {
// resolve the link, then start over
p = pathModule.resolve(resolvedLink, p.slice(pos));
start();
}
};

var pool;
function allocNewPool() {
pool = new Buffer(kPoolSize);
pool.used = 0;
}

fs.createReadStream = function(path, options) {


return new ReadStream(path, options);
};

var ReadStream = fs.ReadStream = function(path, options) {


if (!(this instanceof ReadStream)) return new ReadStream(path, options);

Stream.call(this);

var self = this;

this.path = path;
this.fd = null;
this.readable = true;
this.paused = false;

this.flags = 'r';
this.mode = 438; /*=0666*/
this.bufferSize = 64 * 1024;

options = options || {};

// Mixin options into this


var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}

if (this.encoding) this.setEncoding(this.encoding);

if (this.start !== undefined) {


if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.end === undefined) {
this.end = Infinity;
} else if ('number' !== typeof this.end) {
throw TypeError('end must be a Number');
}

if (this.start > this.end) {


throw new Error('start must be <= end');
}

this.pos = this.start;
}

if (this.fd !== null) {


process.nextTick(function() {
self._read();
});
return;
}

fs.open(this.path, this.flags, this.mode, function(err, fd) {


if (err) {
self.emit('error', err);
self.readable = false;
return;
}

self.fd = fd;
self.emit('open', fd);
self._read();
});
};
util.inherits(ReadStream, Stream);

fs.FileReadStream = fs.ReadStream; // support the legacy name

ReadStream.prototype.setEncoding = function(encoding) {
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder(encoding);
};

ReadStream.prototype._read = function() {
var self = this;
if (!this.readable || this.paused || this.reading) return;

this.reading = true;

if (!pool || pool.length - pool.used < kMinPoolSpace) {


// discard the old pool. Can't add to the free list because
// users might have refernces to slices on it.
pool = null;
allocNewPool();
}

// Grab another reference to the pool in the case that while we're in the
// thread pool another read() finishes up the pool, and allocates a new
// one.
var thisPool = pool;
var toRead = Math.min(pool.length - pool.used, ~~this.bufferSize);
var start = pool.used;

if (this.pos !== undefined) {


toRead = Math.min(this.end - this.pos + 1, toRead);
}

function afterRead(err, bytesRead) {


self.reading = false;
if (err) {
fs.close(self.fd, function() {
self.fd = null;
self.emit('error', err);
self.readable = false;
});
return;
}
if (bytesRead === 0) {
self.emit('end');
self.destroy();
return;
}

var b = thisPool.slice(start, start + bytesRead);

// Possible optimizition here?


// Reclaim some bytes if bytesRead < toRead?
// Would need to ensure that pool === thisPool.

// do not emit events if the stream is paused


if (self.paused) {
self.buffer = b;
return;
}

// do not emit events anymore after we declared the stream unreadable


if (!self.readable) return;

self._emitData(b);
self._read();
}

fs.read(this.fd, pool, pool.used, toRead, this.pos, afterRead);

if (this.pos !== undefined) {


this.pos += toRead;
}
pool.used += toRead;
};

ReadStream.prototype._emitData = function(d) {
if (this._decoder) {
var string = this._decoder.write(d);
if (string.length) this.emit('data', string);
} else {
this.emit('data', d);
}
};

ReadStream.prototype.destroy = function(cb) {
var self = this;

if (!this.readable) {
if (cb) process.nextTick(function() { cb(null); });
return;
}
this.readable = false;

function close() {
fs.close(self.fd, function(err) {
if (err) {
if (cb) cb(err);
self.emit('error', err);
return;
}

if (cb) cb(null);
self.emit('close');
});
}

if (this.fd === null) {


this.addListener('open', close);
} else {
close();
}
};

ReadStream.prototype.pause = function() {
this.paused = true;
};

ReadStream.prototype.resume = function() {
this.paused = false;

if (this.buffer) {
var buffer = this.buffer;
this.buffer = null;
this._emitData(buffer);
}

// hasn't opened yet.


if (null == this.fd) return;

this._read();
};

fs.createWriteStream = function(path, options) {


return new WriteStream(path, options);
};

var WriteStream = fs.WriteStream = function(path, options) {


if (!(this instanceof WriteStream)) return new WriteStream(path, options);

Stream.call(this);

this.path = path;
this.fd = null;
this.writable = true;

this.flags = 'w';
this.encoding = 'binary';
this.mode = 438; /*=0666*/
this.bytesWritten = 0;

options = options || {};

// Mixin options into this


var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}

if (this.start !== undefined) {


if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.start < 0) {
throw new Error('start must be >= zero');
}

this.pos = this.start;
}

this.busy = false;
this._queue = [];

if (this.fd === null) {


this._open = fs.open;
this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
this.flush();
}
};
util.inherits(WriteStream, Stream);

fs.FileWriteStream = fs.WriteStream; // support the legacy name

WriteStream.prototype.flush = function() {
if (this.busy) return;
var self = this;

var args = this._queue.shift();


if (!args) {
if (this.drainable) { this.emit('drain'); }
return;
}

this.busy = true;

var method = args.shift(),


cb = args.pop();

args.push(function(err) {
self.busy = false;

if (err) {
self.writable = false;

function emit() {
self.fd = null;
if (cb) cb(err);
self.emit('error', err);
}

if (self.fd === null) {


emit();
} else {
fs.close(self.fd, emit);
}

return;
}

if (method == fs.write) {
self.bytesWritten += arguments[1];
if (cb) {
// write callback
cb(null, arguments[1]);
}

} else if (method === self._open) {


// save reference for file pointer
self.fd = arguments[1];
self.emit('open', self.fd);

} else if (method === fs.close) {


// stop flushing after close
if (cb) {
cb(null);
}
self.emit('close');
return;
}

self.flush();
});

// Inject the file pointer


if (method !== self._open) {
args.unshift(this.fd);
}

method.apply(this, args);
};

WriteStream.prototype.write = function(data) {
if (!this.writable) {
this.emit('error', new Error('stream not writable'));
return false;
}

this.drainable = true;

var cb;
if (typeof(arguments[arguments.length - 1]) == 'function') {
cb = arguments[arguments.length - 1];
}

if (!Buffer.isBuffer(data)) {
var encoding = 'utf8';
if (typeof(arguments[1]) == 'string') encoding = arguments[1];
data = new Buffer('' + data, encoding);
}

this._queue.push([fs.write, data, 0, data.length, this.pos, cb]);


if (this.pos !== undefined) {
this.pos += data.length;
}

this.flush();

return false;
};

WriteStream.prototype.end = function(data, encoding, cb) {


if (typeof(data) === 'function') {
cb = data;
} else if (typeof(encoding) === 'function') {
cb = encoding;
this.write(data);
} else if (arguments.length > 0) {
this.write(data, encoding);
}
this.writable = false;
this._queue.push([fs.close, cb]);
this.flush();
};

WriteStream.prototype.destroy = function(cb) {
var self = this;

if (!this.writable) {
if (cb) process.nextTick(function() { cb(null); });
return;
}
this.writable = false;

function close() {
fs.close(self.fd, function(err) {
if (err) {
if (cb) { cb(err); }
self.emit('error', err);
return;
}

if (cb) { cb(null); }
self.emit('close');
});
}

if (this.fd === null) {


this.addListener('open', close);
} else {
close();
}
};

// There is no shutdown() for files.


WriteStream.prototype.destroySoon = WriteStream.prototype.end;

// SyncWriteStream is internal. DO NOT USE.


// Temporary hack for process.stdout and process.stderr when piped to files.
function SyncWriteStream(fd) {
Stream.call(this);

this.fd = fd;
this.writable = true;
this.readable = false;
}

util.inherits(SyncWriteStream, Stream);

// Export
fs.SyncWriteStream = SyncWriteStream;

SyncWriteStream.prototype.write = function(data, arg1, arg2) {


var encoding, cb;

// parse arguments
if (arg1) {
if (typeof arg1 === 'string') {
encoding = arg1;
cb = arg2;
} else if (typeof arg1 === 'function') {
cb = arg1;
} else {
throw new Error('bad arg');
}
}

// Change strings to buffers. SLOW


if (typeof data == 'string') {
data = new Buffer(data, encoding);
}

fs.writeSync(this.fd, data, 0, data.length);

if (cb) {
process.nextTick(cb);
}

return true;
};

SyncWriteStream.prototype.end = function(data, arg1, arg2) {


if (data) {
this.write(data, arg1, arg2);
}
this.destroy();
};

SyncWriteStream.prototype.destroy = function() {
fs.closeSync(this.fd);
this.fd = null;
this.emit('close');
return true;
};
SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy;
######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var util = require('util');


var net = require('net');
var Stream = require('stream');
var url = require('url');
var EventEmitter = require('events').EventEmitter;
var FreeList = require('freelist').FreeList;
var HTTPParser = process.binding('http_parser').HTTPParser;
var assert = require('assert').ok;
var END_OF_FILE = {};

var debug;
if (process.env.NODE_DEBUG && /http/.test(process.env.NODE_DEBUG)) {
debug = function(x) { console.error('HTTP: %s', x); };
} else {
debug = function() { };
}

// Only called in the slow case where slow means


// that the request headers were either fragmented
// across multiple TCP packets or too large to be
// processed in a single run. This method is also
// called to process trailing HTTP headers.
function parserOnHeaders(headers, url) {
// Once we exceeded headers limit - stop collecting them
if (this.maxHeaderPairs <= 0 ||
this._headers.length < this.maxHeaderPairs) {
this._headers = this._headers.concat(headers);
}
this._url += url;
}

// info.headers and info.url are set only if .onHeaders()


// has not been called for this request.
//
// info.url is not set for response parsers but that's not
// applicable here since all our parsers are request parsers.
function parserOnHeadersComplete(info) {
var parser = this;
var headers = info.headers;
var url = info.url;

if (!headers) {
headers = parser._headers;
parser._headers = [];
}

if (!url) {
url = parser._url;
parser._url = '';
}

parser.incoming = new IncomingMessage(parser.socket);


parser.incoming.httpVersionMajor = info.versionMajor;
parser.incoming.httpVersionMinor = info.versionMinor;
parser.incoming.httpVersion = info.versionMajor + '.' + info.versionMinor;
parser.incoming.url = url;

var n = headers.length;

// If parser.maxHeaderPairs <= 0 - assume that there're no limit


if (parser.maxHeaderPairs > 0) {
n = Math.min(n, parser.maxHeaderPairs);
}

for (var i = 0; i < n; i += 2) {


var k = headers[i];
var v = headers[i + 1];
parser.incoming._addHeaderLine(k, v);
}

if (info.method) {
// server only
parser.incoming.method = info.method;
} else {
// client only
parser.incoming.statusCode = info.statusCode;
// CHECKME dead code? we're always a request parser
}

parser.incoming.upgrade = info.upgrade;

var skipBody = false; // response to HEAD or CONNECT

if (!info.upgrade) {
// For upgraded connections and CONNECT method request,
// we'll emit this after parser.execute
// so that we can capture the first part of the new protocol
skipBody = parser.onIncoming(parser.incoming, info.shouldKeepAlive);
}

return skipBody;
}
function parserOnBody(b, start, len) {
var parser = this;
var slice = b.slice(start, start + len);
if (parser.incoming._paused || parser.incoming._pendings.length) {
parser.incoming._pendings.push(slice);
} else {
parser.incoming._emitData(slice);
}
}

function parserOnMessageComplete() {
var parser = this;
parser.incoming.complete = true;

// Emit any trailing headers.


var headers = parser._headers;
if (headers) {
for (var i = 0, n = headers.length; i < n; i += 2) {
var k = headers[i];
var v = headers[i + 1];
parser.incoming._addHeaderLine(k, v);
}
parser._headers = [];
parser._url = '';
}

if (!parser.incoming.upgrade) {
// For upgraded connections, also emit this after parser.execute
if (parser.incoming._paused || parser.incoming._pendings.length) {
parser.incoming._pendings.push(END_OF_FILE);
} else {
parser.incoming.readable = false;
parser.incoming._emitEnd();
}
}

if (parser.socket.readable) {
// force to read the next incoming message
parser.socket.resume();
}
}

var parsers = new FreeList('parsers', 1000, function() {


var parser = new HTTPParser(HTTPParser.REQUEST);

parser._headers = [];
parser._url = '';

// Only called in the slow case where slow means


// that the request headers were either fragmented
// across multiple TCP packets or too large to be
// processed in a single run. This method is also
// called to process trailing HTTP headers.
parser.onHeaders = parserOnHeaders;
parser.onHeadersComplete = parserOnHeadersComplete;
parser.onBody = parserOnBody;
parser.onMessageComplete = parserOnMessageComplete;
return parser;
});
exports.parsers = parsers;

var CRLF = '\r\n';


var STATUS_CODES = exports.STATUS_CODES = {
100 : 'Continue',
101 : 'Switching Protocols',
102 : 'Processing', // RFC 2518, obsoleted by RFC 4918
200 : 'OK',
201 : 'Created',
202 : 'Accepted',
203 : 'Non-Authoritative Information',
204 : 'No Content',
205 : 'Reset Content',
206 : 'Partial Content',
207 : 'Multi-Status', // RFC 4918
300 : 'Multiple Choices',
301 : 'Moved Permanently',
302 : 'Moved Temporarily',
303 : 'See Other',
304 : 'Not Modified',
305 : 'Use Proxy',
307 : 'Temporary Redirect',
400 : 'Bad Request',
401 : 'Unauthorized',
402 : 'Payment Required',
403 : 'Forbidden',
404 : 'Not Found',
405 : 'Method Not Allowed',
406 : 'Not Acceptable',
407 : 'Proxy Authentication Required',
408 : 'Request Time-out',
409 : 'Conflict',
410 : 'Gone',
411 : 'Length Required',
412 : 'Precondition Failed',
413 : 'Request Entity Too Large',
414 : 'Request-URI Too Large',
415 : 'Unsupported Media Type',
416 : 'Requested Range Not Satisfiable',
417 : 'Expectation Failed',
418 : 'I\'m a teapot', // RFC 2324
422 : 'Unprocessable Entity', // RFC 4918
423 : 'Locked', // RFC 4918
424 : 'Failed Dependency', // RFC 4918
425 : 'Unordered Collection', // RFC 4918
426 : 'Upgrade Required', // RFC 2817
428 : 'Precondition Required', // RFC 6585
429 : 'Too Many Requests', // RFC 6585
431 : 'Request Header Fields Too Large',// RFC 6585
500 : 'Internal Server Error',
501 : 'Not Implemented',
502 : 'Bad Gateway',
503 : 'Service Unavailable',
504 : 'Gateway Time-out',
505 : 'HTTP Version not supported',
506 : 'Variant Also Negotiates', // RFC 2295
507 : 'Insufficient Storage', // RFC 4918
509 : 'Bandwidth Limit Exceeded',
510 : 'Not Extended', // RFC 2774
511 : 'Network Authentication Required' // RFC 6585
};

var connectionExpression = /Connection/i;


var transferEncodingExpression = /Transfer-Encoding/i;
var closeExpression = /close/i;
var chunkExpression = /chunk/i;
var contentLengthExpression = /Content-Length/i;
var dateExpression = /Date/i;
var expectExpression = /Expect/i;
var continueExpression = /100-continue/i;

var dateCache;
function utcDate() {
if (!dateCache) {
var d = new Date();
dateCache = d.toUTCString();
setTimeout(function() {
dateCache = undefined;
}, 1000 - d.getMilliseconds());
}
return dateCache;
}

/* Abstract base class for ServerRequest and ClientResponse. */


function IncomingMessage(socket) {
Stream.call(this);

// TODO Remove one of these eventually.


this.socket = socket;
this.connection = socket;

this.httpVersion = null;
this.complete = false;
this.headers = {};
this.trailers = {};

this.readable = true;

this._paused = false;
this._pendings = [];

this._endEmitted = false;

// request (server) only


this.url = '';

this.method = null;

// response (client) only


this.statusCode = null;
this.client = this.socket;
}
util.inherits(IncomingMessage, Stream);
exports.IncomingMessage = IncomingMessage;

IncomingMessage.prototype.destroy = function(error) {
this.socket.destroy(error);
};

IncomingMessage.prototype.setEncoding = function(encoding) {
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder(encoding);
};

IncomingMessage.prototype.pause = function() {
this._paused = true;
this.socket.pause();
};

IncomingMessage.prototype.resume = function() {
this._paused = false;
if (this.socket) {
this.socket.resume();
}

this._emitPending();
};

IncomingMessage.prototype._emitPending = function(callback) {
if (this._pendings.length) {
var self = this;
process.nextTick(function() {
while (!self._paused && self._pendings.length) {
var chunk = self._pendings.shift();
if (chunk !== END_OF_FILE) {
assert(Buffer.isBuffer(chunk));
self._emitData(chunk);
} else {
assert(self._pendings.length === 0);
self.readable = false;
self._emitEnd();
}
}

if (callback) {
callback();
}
});
} else if (callback) {
callback();
}
};

IncomingMessage.prototype._emitData = function(d) {
if (this._decoder) {
var string = this._decoder.write(d);
if (string.length) {
this.emit('data', string);
}
} else {
this.emit('data', d);
}
};

IncomingMessage.prototype._emitEnd = function() {
if (!this._endEmitted) {
this.emit('end');
}

this._endEmitted = true;
};

// Add the given (field, value) pair to the message


//
// Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
// same header with a ', ' if the header in question supports specification of
// multiple values this way. If not, we declare the first instance the winner
// and drop the second. Extended header fields (those beginning with 'x-') are
// always joined.
IncomingMessage.prototype._addHeaderLine = function(field, value) {
var dest = this.complete ? this.trailers : this.headers;

field = field.toLowerCase();
switch (field) {
// Array headers:
case 'set-cookie':
if (field in dest) {
dest[field].push(value);
} else {
dest[field] = [value];
}
break;

// Comma separate. Maybe make these arrays?


case 'accept':
case 'accept-charset':
case 'accept-encoding':
case 'accept-language':
case 'connection':
case 'cookie':
case 'pragma':
case 'link':
case 'www-authenticate':
case 'proxy-authenticate':
case 'sec-websocket-extensions':
case 'sec-websocket-protocol':
if (field in dest) {
dest[field] += ', ' + value;
} else {
dest[field] = value;
}
break;

default:
if (field.slice(0, 2) == 'x-') {
// except for x-
if (field in dest) {
dest[field] += ', ' + value;
} else {
dest[field] = value;
}
} else {
// drop duplicates
if (!(field in dest)) dest[field] = value;
}
break;
}
};

function OutgoingMessage() {
Stream.call(this);

this.output = [];
this.outputEncodings = [];

this.writable = true;

this._last = false;
this.chunkedEncoding = false;
this.shouldKeepAlive = true;
this.useChunkedEncodingByDefault = true;
this.sendDate = false;

this._hasBody = true;
this._trailer = '';

this.finished = false;
this._hangupClose = false;
}
util.inherits(OutgoingMessage, Stream);

exports.OutgoingMessage = OutgoingMessage;

OutgoingMessage.prototype.destroy = function(error) {
this.socket.destroy(error);
};

// This abstract either writing directly to the socket or buffering it.


OutgoingMessage.prototype._send = function(data, encoding) {
// This is a shameful hack to get the headers and first body chunk onto
// the same packet. Future versions of Node are going to take care of
// this at a lower level and in a more general way.
if (!this._headerSent) {
if (typeof data === 'string') {
data = this._header + data;
} else {
this.output.unshift(this._header);
this.outputEncodings.unshift('ascii');
}
this._headerSent = true;
}
return this._writeRaw(data, encoding);
};

OutgoingMessage.prototype._writeRaw = function(data, encoding) {


if (data.length === 0) {
return true;
}

if (this.connection &&
this.connection._httpMessage === this &&
this.connection.writable &&
!this.connection.destroyed) {
// There might be pending data in the this.output buffer.
while (this.output.length) {
if (!this.connection.writable) {
this._buffer(data, encoding);
return false;
}
var c = this.output.shift();
var e = this.outputEncodings.shift();
this.connection.write(c, e);
}

// Directly write to socket.


return this.connection.write(data, encoding);
} else if (this.connection && this.connection.destroyed) {
// The socket was destroyed. If we're still trying to write to it,
// then something bad happened, but it could be just that we haven't
// gotten the 'close' event yet.
//
// In v0.10 and later, this isn't a problem, since ECONNRESET isn't
// ignored in the first place. We'll probably emit 'close' on the
// next tick, but just in case it's not coming, set a timeout that
// will emit it for us.
if (!this._hangupClose) {
this._hangupClose = true;
var socket = this.socket;
var timer = setTimeout(function() {
socket.emit('close');
});
socket.once('close', function() {
clearTimeout(timer);
});
}
return false;
} else {
// buffer, as long as we're not destroyed.
this._buffer(data, encoding);
return false;
}
};
OutgoingMessage.prototype._buffer = function(data, encoding) {
if (data.length === 0) return;

var length = this.output.length;

if (length === 0 || typeof data != 'string') {


this.output.push(data);
this.outputEncodings.push(encoding);
return false;
}

var lastEncoding = this.outputEncodings[length - 1];


var lastData = this.output[length - 1];

if ((encoding && lastEncoding === encoding) ||


(!encoding && data.constructor === lastData.constructor)) {
this.output[length - 1] = lastData + data;
return false;
}

this.output.push(data);
this.outputEncodings.push(encoding);

return false;
};

OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {


var sentConnectionHeader = false;
var sentContentLengthHeader = false;
var sentTransferEncodingHeader = false;
var sentDateHeader = false;
var sentExpect = false;

// firstLine in the case of request is: 'GET /index.html HTTP/1.1\r\n'


// in the case of response it is: 'HTTP/1.1 200 OK\r\n'
var messageHeader = firstLine;
var field, value;
var self = this;

function store(field, value) {


// Protect against response splitting. The if statement is there to
// minimize the performance impact in the common case.
if (/[\r\n]/.test(value))
value = value.replace(/[\r\n]+[ \t]*/g, '');

messageHeader += field + ': ' + value + CRLF;

if (connectionExpression.test(field)) {
sentConnectionHeader = true;
if (closeExpression.test(value)) {
self._last = true;
} else {
self.shouldKeepAlive = true;
}

} else if (transferEncodingExpression.test(field)) {
sentTransferEncodingHeader = true;
if (chunkExpression.test(value)) self.chunkedEncoding = true;

} else if (contentLengthExpression.test(field)) {
sentContentLengthHeader = true;
} else if (dateExpression.test(field)) {
sentDateHeader = true;
} else if (expectExpression.test(field)) {
sentExpect = true;
}
}

if (headers) {
var keys = Object.keys(headers);
var isArray = (Array.isArray(headers));
var field, value;

for (var i = 0, l = keys.length; i < l; i++) {


var key = keys[i];
if (isArray) {
field = headers[key][0];
value = headers[key][1];
} else {
field = key;
value = headers[key];
}

if (Array.isArray(value)) {
for (var j = 0; j < value.length; j++) {
store(field, value[j]);
}
} else {
store(field, value);
}
}
}

// Date header
if (this.sendDate == true && sentDateHeader == false) {
messageHeader += 'Date: ' + utcDate() + CRLF;
}

// keep-alive logic
if (sentConnectionHeader === false) {
var shouldSendKeepAlive = this.shouldKeepAlive &&
(sentContentLengthHeader ||
this.useChunkedEncodingByDefault ||
this.agent);
if (shouldSendKeepAlive) {
messageHeader += 'Connection: keep-alive\r\n';
} else {
this._last = true;
messageHeader += 'Connection: close\r\n';
}
}

if (sentContentLengthHeader == false && sentTransferEncodingHeader == false) {


if (this._hasBody) {
if (this.useChunkedEncodingByDefault) {
messageHeader += 'Transfer-Encoding: chunked\r\n';
this.chunkedEncoding = true;
} else {
this._last = true;
}
} else {
// Make sure we don't end the 0\r\n\r\n at the end of the message.
this.chunkedEncoding = false;
}
}

this._header = messageHeader + CRLF;


this._headerSent = false;

// wait until the first body chunk, or close(), is sent to flush,


// UNLESS we're sending Expect: 100-continue.
if (sentExpect) this._send('');
};

OutgoingMessage.prototype.setHeader = function(name, value) {


if (arguments.length < 2) {
throw new Error('`name` and `value` are required for setHeader().');
}

if (this._header) {
throw new Error('Can\'t set headers after they are sent.');
}

var key = name.toLowerCase();


this._headers = this._headers || {};
this._headerNames = this._headerNames || {};
this._headers[key] = value;
this._headerNames[key] = name;
};

OutgoingMessage.prototype.getHeader = function(name) {
if (arguments.length < 1) {
throw new Error('`name` is required for getHeader().');
}

if (!this._headers) return;

var key = name.toLowerCase();


return this._headers[key];
};

OutgoingMessage.prototype.removeHeader = function(name) {
if (arguments.length < 1) {
throw new Error('`name` is required for removeHeader().');
}

if (this._header) {
throw new Error('Can\'t remove headers after they are sent.');
}

if (!this._headers) return;
var key = name.toLowerCase();
delete this._headers[key];
delete this._headerNames[key];
};

OutgoingMessage.prototype._renderHeaders = function() {
if (this._header) {
throw new Error('Can\'t render headers after they are sent to the client.');
}

if (!this._headers) return {};

var headers = {};


var keys = Object.keys(this._headers);
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
headers[this._headerNames[key]] = this._headers[key];
}
return headers;
};

OutgoingMessage.prototype.write = function(chunk, encoding) {


if (!this._header) {
this._implicitHeader();
}

if (!this._hasBody) {
debug('This type of response MUST NOT have a body. ' +
'Ignoring write() calls.');
return true;
}

if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk)) {


throw new TypeError('first argument must be a string or Buffer');
}

if (chunk.length === 0) return false;

var len, ret;


if (this.chunkedEncoding) {
if (typeof(chunk) === 'string') {
len = Buffer.byteLength(chunk, encoding);
chunk = len.toString(16) + CRLF + chunk + CRLF;
ret = this._send(chunk, encoding);
} else {
// buffer
len = chunk.length;
this._send(len.toString(16) + CRLF);
this._send(chunk);
ret = this._send(CRLF);
}
} else {
ret = this._send(chunk, encoding);
}

debug('write ret = ' + ret);


return ret;
};

OutgoingMessage.prototype.addTrailers = function(headers) {
this._trailer = '';
var keys = Object.keys(headers);
var isArray = (Array.isArray(headers));
var field, value;
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
if (isArray) {
field = headers[key][0];
value = headers[key][1];
} else {
field = key;
value = headers[key];
}

this._trailer += field + ': ' + value + CRLF;


}
};

var zero_chunk_buf = new Buffer('\r\n0\r\n');


var crlf_buf = new Buffer('\r\n');

OutgoingMessage.prototype.end = function(data, encoding) {


if (this.finished) {
return false;
}
if (!this._header) {
this._implicitHeader();
}

if (data && !this._hasBody) {


debug('This type of response MUST NOT have a body. ' +
'Ignoring data passed to end().');
data = false;
}

var ret;

var hot = this._headerSent === false &&


(data && data.length > 0) &&
this.output.length === 0 &&
this.connection &&
this.connection.writable &&
this.connection._httpMessage === this;

if (hot) {
// Hot path. They're doing
// res.writeHead();
// res.end(blah);
// HACKY.

if (typeof data === 'string') {


if (this.chunkedEncoding) {
var l = Buffer.byteLength(data, encoding).toString(16);
ret = this.connection.write(this._header + l + CRLF +
data + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
} else {
ret = this.connection.write(this._header + data, encoding);
}
} else if (Buffer.isBuffer(data)) {
if (this.chunkedEncoding) {
var chunk_size = data.length.toString(16);

// Skip expensive Buffer.byteLength() calls; only ISO-8859-1 characters


// are allowed in HTTP headers. Therefore:
//
// this._header.length == Buffer.byteLength(this._header.length)
// this._trailer.length == Buffer.byteLength(this._trailer.length)
//
var header_len = this._header.length;
var chunk_size_len = chunk_size.length;
var data_len = data.length;
var trailer_len = this._trailer.length;

var len = header_len +


chunk_size_len +
2 + // '\r\n'.length
data_len +
5 + // '\r\n0\r\n'.length
trailer_len +
2; // '\r\n'.length

var buf = new Buffer(len);


var off = 0;

buf.write(this._header, off, header_len, 'ascii');


off += header_len;

buf.write(chunk_size, off, chunk_size_len, 'ascii');


off += chunk_size_len;

crlf_buf.copy(buf, off);
off += 2;

data.copy(buf, off);
off += data_len;

zero_chunk_buf.copy(buf, off);
off += 5;

if (trailer_len > 0) {
buf.write(this._trailer, off, trailer_len, 'ascii');
off += trailer_len;
}

crlf_buf.copy(buf, off);

ret = this.connection.write(buf);
} else {
var header_len = this._header.length;
var buf = new Buffer(header_len + data.length);
buf.write(this._header, 0, header_len, 'ascii');
data.copy(buf, header_len);
ret = this.connection.write(buf);
}
} else {
throw new TypeError('first argument must be a string or Buffer');
}
this._headerSent = true;

} else if (data) {
// Normal body write.
ret = this.write(data, encoding);
}

if (!hot) {
if (this.chunkedEncoding) {
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
} else {
// Force a flush, HACK.
ret = this._send('');
}
}

this.finished = true;

// There is the first message on the outgoing queue, and we've sent
// everything to the socket.
debug('outgoing message end.');
if (this.output.length === 0 && this.connection._httpMessage === this) {
this._finish();
}

return ret;
};

OutgoingMessage.prototype._finish = function() {
assert(this.connection);
if (this instanceof ServerResponse) {
;
} else {
assert(this instanceof ClientRequest);
;
}
this.emit('finish');
};

OutgoingMessage.prototype._flush = function() {
// This logic is probably a bit confusing. Let me explain a bit:
//
// In both HTTP servers and clients it is possible to queue up several
// outgoing messages. This is easiest to imagine in the case of a client.
// Take the following situation:
//
// req1 = client.request('GET', '/');
// req2 = client.request('POST', '/');
//
// When the user does
//
// req2.write('hello world\n');
//
// it's possible that the first request has not been completely flushed to
// the socket yet. Thus the outgoing messages need to be prepared to queue
// up data internally before sending it on further to the socket's queue.
//
// This function, outgoingFlush(), is called by both the Server and Client
// to attempt to flush any pending messages out to the socket.

if (!this.socket) return;

var ret;
while (this.output.length) {

if (!this.socket.writable) return; // XXX Necessary?

var data = this.output.shift();


var encoding = this.outputEncodings.shift();

ret = this.socket.write(data, encoding);


}

if (this.finished) {
// This is a queue to the server or client to bring in the next this.
this._finish();
} else if (ret) {
// This is necessary to prevent https from breaking
this.emit('drain');
}
};

function ServerResponse(req) {
OutgoingMessage.call(this);

if (req.method === 'HEAD') this._hasBody = false;

this.sendDate = true;

if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {


this.useChunkedEncodingByDefault = chunkExpression.test(req.headers.te);
this.shouldKeepAlive = false;
}
}
util.inherits(ServerResponse, OutgoingMessage);

exports.ServerResponse = ServerResponse;

ServerResponse.prototype.statusCode = 200;

function onServerResponseClose() {
// EventEmitter.emit makes a copy of the 'close' listeners array before
// calling the listeners. detachSocket() unregisters onServerResponseClose
// but if detachSocket() is called, directly or indirectly, by a 'close'
// listener, onServerResponseClose is still in that copy of the listeners
// array. That is, in the example below, b still gets called even though
// it's been removed by a:
//
// var obj = new events.EventEmitter;
// obj.on('event', a);
// obj.on('event', b);
// function a() { obj.removeListener('event', b) }
// function b() { throw "BAM!" }
// obj.emit('event'); // throws
//
// Ergo, we need to deal with stale 'close' events and handle the case
// where the ServerResponse object has already been deconstructed.
// Fortunately, that requires only a single if check. :-)
if (this._httpMessage) this._httpMessage.emit('close');
}

ServerResponse.prototype.assignSocket = function(socket) {
assert(!socket._httpMessage);
socket._httpMessage = this;
socket.on('close', onServerResponseClose);
this.socket = socket;
this.connection = socket;
this._flush();
};

ServerResponse.prototype.detachSocket = function(socket) {
assert(socket._httpMessage == this);
socket.removeListener('close', onServerResponseClose);
socket._httpMessage = null;
this.socket = this.connection = null;
};

ServerResponse.prototype.writeContinue = function() {
this._writeRaw('HTTP/1.1 100 Continue' + CRLF + CRLF, 'ascii');
this._sent100 = true;
};

ServerResponse.prototype._implicitHeader = function() {
this.writeHead(this.statusCode);
};

ServerResponse.prototype.writeHead = function(statusCode) {
var reasonPhrase, headers, headerIndex;

if (typeof arguments[1] == 'string') {


reasonPhrase = arguments[1];
headerIndex = 2;
} else {
reasonPhrase = STATUS_CODES[statusCode] || 'unknown';
headerIndex = 1;
}
this.statusCode = statusCode;

var obj = arguments[headerIndex];

if (obj && this._headers) {


// Slow-case: when progressive API and header fields are passed.
headers = this._renderHeaders();
if (Array.isArray(obj)) {
// handle array case
// TODO: remove when array is no longer accepted
var field;
for (var i = 0, len = obj.length; i < len; ++i) {
field = obj[i][0];
if (field in headers) {
obj.push([field, headers[field]]);
}
}
headers = obj;

} else {
// handle object case
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
if (k) headers[k] = obj[k];
}
}
} else if (this._headers) {
// only progressive api is used
headers = this._renderHeaders();
} else {
// only writeHead() called
headers = obj;
}

var statusLine = 'HTTP/1.1 ' + statusCode.toString() + ' ' +


reasonPhrase + CRLF;

if (statusCode === 204 || statusCode === 304 ||


(100 <= statusCode && statusCode <= 199)) {
// RFC 2616, 10.2.5:
// The 204 response MUST NOT include a message-body, and thus is always
// terminated by the first empty line after the header fields.
// RFC 2616, 10.3.5:
// The 304 response MUST NOT contain a message-body, and thus is always
// terminated by the first empty line after the header fields.
// RFC 2616, 10.1 Informational 1xx:
// This class of status code indicates a provisional response,
// consisting only of the Status-Line and optional headers, and is
// terminated by an empty line.
this._hasBody = false;
}

// don't keep alive connections where the client expects 100 Continue
// but we sent a final status; they may put extra bytes on the wire.
if (this._expect_continue && ! this._sent100) {
this.shouldKeepAlive = false;
}

this._storeHeader(statusLine, headers);
};

ServerResponse.prototype.writeHeader = function() {
this.writeHead.apply(this, arguments);
};
// New Agent code.

// The largest departure from the previous implementation is that


// an Agent instance holds connections for a variable number of host:ports.
// Surprisingly, this is still API compatible as far as third parties are
// concerned. The only code that really notices the difference is the
// request object.

// Another departure is that all code related to HTTP parsing is in


// ClientRequest.onSocket(). The Agent is now *strictly*
// concerned with managing a connection pool.

function Agent(options) {
EventEmitter.call(this);

var self = this;


self.options = options || {};
self.requests = {};
self.sockets = {};
self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets;
self.on('free', function(socket, host, port, localAddress) {
var name = host + ':' + port;
if (localAddress) {
name += ':' + localAddress;
}

if (!socket.destroyed &&
self.requests[name] && self.requests[name].length) {
self.requests[name].shift().onSocket(socket);
if (self.requests[name].length === 0) {
// don't leak
delete self.requests[name];
}
} else {
// If there are no pending requests just destroy the
// socket and it will get removed from the pool. This
// gets us out of timeout issues and allows us to
// default to Connection:keep-alive.
socket.destroy();
}
});
self.createConnection = net.createConnection;
}
util.inherits(Agent, EventEmitter);
exports.Agent = Agent;

Agent.defaultMaxSockets = 5;

Agent.prototype.defaultPort = 80;
Agent.prototype.addRequest = function(req, host, port, localAddress) {
var name = host + ':' + port;
if (localAddress) {
name += ':' + localAddress;
}
if (!this.sockets[name]) {
this.sockets[name] = [];
}
if (this.sockets[name].length < this.maxSockets) {
// If we are under maxSockets create a new one.
req.onSocket(this.createSocket(name, host, port, localAddress, req));
} else {
// We are over limit so we'll add it to the queue.
if (!this.requests[name]) {
this.requests[name] = [];
}
this.requests[name].push(req);
}
};
Agent.prototype.createSocket = function(name, host, port, localAddress, req) {
var self = this;
var options = util._extend({}, self.options);
options.port = port;
options.host = host;
options.localAddress = localAddress;

options.servername = host;
if (req) {
var hostHeader = req.getHeader('host');
if (hostHeader) {
options.servername = hostHeader.replace(/:.*$/, '');
}
}

var s = self.createConnection(options);
if (!self.sockets[name]) {
self.sockets[name] = [];
}
this.sockets[name].push(s);
var onFree = function() {
self.emit('free', s, host, port, localAddress);
}
s.on('free', onFree);
var onClose = function(err) {
// This is the only place where sockets get removed from the Agent.
// If you want to remove a socket from the pool, just close it.
// All socket errors end in a close event anyway.
self.removeSocket(s, name, host, port, localAddress);
}
s.on('close', onClose);
var onRemove = function() {
// We need this function for cases like HTTP 'upgrade'
// (defined by WebSockets) where we need to remove a socket from the pool
// because it'll be locked up indefinitely
self.removeSocket(s, name, host, port, localAddress);
s.removeListener('close', onClose);
s.removeListener('free', onFree);
s.removeListener('agentRemove', onRemove);
}
s.on('agentRemove', onRemove);
return s;
};
Agent.prototype.removeSocket = function(s, name, host, port, localAddress) {
if (this.sockets[name]) {
var index = this.sockets[name].indexOf(s);
if (index !== -1) {
this.sockets[name].splice(index, 1);
if (this.sockets[name].length === 0) {
// don't leak
delete this.sockets[name];
}
}
}
if (this.requests[name] && this.requests[name].length) {
var req = this.requests[name][0];
// If we have pending requests and a socket gets closed a new one
this.createSocket(name, host, port, localAddress, req).emit('free');
}
};

var globalAgent = new Agent();


exports.globalAgent = globalAgent;

function ClientRequest(options, cb) {


var self = this;
OutgoingMessage.call(self);

self.agent = options.agent === undefined ? globalAgent : options.agent;

var defaultPort = options.defaultPort || 80;

var port = options.port || defaultPort;


var host = options.hostname || options.host || 'localhost';

if (options.setHost === undefined) {


var setHost = true;
}

self.socketPath = options.socketPath;

var method = self.method = (options.method || 'GET').toUpperCase();


self.path = options.path || '/';
if (cb) {
self.once('response', cb);
}

if (!Array.isArray(options.headers)) {
if (options.headers) {
var keys = Object.keys(options.headers);
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
self.setHeader(key, options.headers[key]);
}
}
if (host && !this.getHeader('host') && setHost) {
var hostHeader = host;
if (port && +port !== defaultPort) {
hostHeader += ':' + port;
}
this.setHeader('Host', hostHeader);
}
}

if (options.auth && !this.getHeader('Authorization')) {


//basic auth
this.setHeader('Authorization', 'Basic ' +
new Buffer(options.auth).toString('base64'));
}

if (method === 'GET' || method === 'HEAD' || method === 'CONNECT') {


self.useChunkedEncodingByDefault = false;
} else {
self.useChunkedEncodingByDefault = true;
}

if (Array.isArray(options.headers)) {
self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
options.headers);
} else if (self.getHeader('expect')) {
self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
self._renderHeaders());
}
if (self.socketPath) {
self._last = true;
self.shouldKeepAlive = false;
if (options.createConnection) {
self.onSocket(options.createConnection(self.socketPath));
} else {
self.onSocket(net.createConnection(self.socketPath));
}
} else if (self.agent) {
// If there is an agent we should default to Connection:keep-alive.
self._last = false;
self.shouldKeepAlive = true;
self.agent.addRequest(self, host, port, options.localAddress);
} else {
// No agent, default to Connection:close.
self._last = true;
self.shouldKeepAlive = false;
if (options.createConnection) {
options.port = port;
options.host = host;
var conn = options.createConnection(options);
} else {
var conn = net.createConnection({
port: port,
host: host,
localAddress: options.localAddress
});
}
self.onSocket(conn);
}

self._deferToConnect(null, null, function() {


self._flush();
self = null;
});

}
util.inherits(ClientRequest, OutgoingMessage);

exports.ClientRequest = ClientRequest;

ClientRequest.prototype._implicitHeader = function() {
this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n',
this._renderHeaders());
};

ClientRequest.prototype.abort = function() {
if (this.socket) {
// in-progress
this.socket.destroy();
} else {
// haven't been assigned a socket yet.
// this could be more efficient, it could
// remove itself from the pending requests
this._deferToConnect('destroy', []);
}
};

function createHangUpError() {
var error = new Error('socket hang up');
error.code = 'ECONNRESET';
return error;
}

// Free the parser and also break any links that it


// might have to any other things.
// TODO: All parser data should be attached to a
// single object, so that it can be easily cleaned
// up by doing `parser.data = {}`, which should
// be done in FreeList.free. `parsers.free(parser)`
// should be all that is needed.
function freeParser(parser, req) {
if (parser) {
parser._headers = [];
parser.onIncoming = null;
if (parser.socket) {
parser.socket.onend = null;
parser.socket.ondata = null;
parser.socket.parser = null;
}
parser.socket = null;
parser.incoming = null;
parsers.free(parser);
parser = null;
}
if (req) {
req.parser = null;
}
}

function socketCloseListener() {
var socket = this;
var parser = socket.parser;
var req = socket._httpMessage;
debug('HTTP socket close');
req.emit('close');
if (req.res && req.res.readable) {
// Socket closed before we emitted 'end' below.
req.res.emit('aborted');
var res = req.res;
req.res._emitPending(function() {
res._emitEnd();
res.emit('close');
res = null;
});
} else if (!req.res && !req._hadError) {
// This socket error fired before we started to
// receive a response. The error needs to
// fire on the request.
req.emit('error', createHangUpError());
req._hadError = true;
}

// Too bad. That output wasn't getting written.


// This is pretty terrible that it doesn't raise an error.
// Fixed better in v0.10
if (req.output)
req.output.length = 0;
if (req.outputEncodings)
req.outputEncodings.length = 0;

if (parser) {
parser.finish();
freeParser(parser, req);
}
}

function socketErrorListener(err) {
var socket = this;
var parser = socket.parser;
var req = socket._httpMessage;
debug('HTTP SOCKET ERROR: ' + err.message + '\n' + err.stack);

if (req) {
req.emit('error', err);
// For Safety. Some additional errors might fire later on
// and we need to make sure we don't double-fire the error event.
req._hadError = true;
}

if (parser) {
parser.finish();
freeParser(parser, req);
}
socket.destroy();
}

function socketOnEnd() {
var socket = this;
var req = this._httpMessage;
var parser = this.parser;

if (!req.res) {
// If we don't have a response then we know that the socket
// ended prematurely and we need to emit an error on the request.
req.emit('error', createHangUpError());
req._hadError = true;
}
if (parser) {
parser.finish();
freeParser(parser, req);
}
socket.destroy();
}

function socketOnData(d, start, end) {


var socket = this;
var req = this._httpMessage;
var parser = this.parser;

var ret = parser.execute(d, start, end - start);


if (ret instanceof Error) {
debug('parse error');
freeParser(parser, req);
socket.destroy();
req.emit('error', ret);
req._hadError = true;
} else if (parser.incoming && parser.incoming.upgrade) {
// Upgrade or CONNECT
var bytesParsed = ret;
var res = parser.incoming;
req.res = res;

socket.ondata = null;
socket.onend = null;
parser.finish();

// This is start + byteParsed


var bodyHead = d.slice(start + bytesParsed, end);

var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';


if (req.listeners(eventName).length) {
req.upgradeOrConnect = true;

// detach the socket


socket.emit('agentRemove');
socket.removeListener('close', socketCloseListener);
socket.removeListener('error', socketErrorListener);

req.emit(eventName, res, socket, bodyHead);


req.emit('close');
} else {
// Got Upgrade header or CONNECT method, but have no handler.
socket.destroy();
}
freeParser(parser, req);
} else if (parser.incoming && parser.incoming.complete &&
// When the status code is 100 (Continue), the server will
// send a final response after this client sends a request
// body. So, we must not free the parser.
parser.incoming.statusCode !== 100) {
freeParser(parser, req);
}
}

function parserOnIncomingClient(res, shouldKeepAlive) {


var parser = this;
var socket = this.socket;
var req = socket._httpMessage;

// propogate "domain" setting...


if (req.domain && !res.domain) {
debug('setting "res.domain"');
res.domain = req.domain;
}

debug('AGENT incoming response!');

if (req.res) {
// We already have a response object, this means the server
// sent a double response.
socket.destroy();
return;
}
req.res = res;

// Responses to CONNECT request is handled as Upgrade.


if (req.method === 'CONNECT') {
res.upgrade = true;
return true; // skip body
}

// Responses to HEAD requests are crazy.


// HEAD responses aren't allowed to have an entity-body
// but *can* have a content-length which actually corresponds
// to the content-length of the entity-body had the request
// been a GET.
var isHeadResponse = req.method == 'HEAD';
debug('AGENT isHeadResponse ' + isHeadResponse);

if (res.statusCode == 100) {
// restart the parser, as this is a continue message.
delete req.res; // Clear res so that we don't hit double-responses.
req.emit('continue');
return true;
}

if (req.shouldKeepAlive && !shouldKeepAlive && !req.upgradeOrConnect) {


// Server MUST respond with Connection:keep-alive for us to enable it.
// If we've been upgraded (via WebSockets) we also shouldn't try to
// keep the connection open.
req.shouldKeepAlive = false;
}

;
req.emit('response', res);
req.res = res;
res.req = req;

res.on('end', responseOnEnd);

return isHeadResponse;
}

function responseOnEnd() {
var res = this;
var req = res.req;
var socket = req.socket;

if (!req.shouldKeepAlive) {
if (socket.writable) {
debug('AGENT socket.destroySoon()');
socket.destroySoon();
}
assert(!socket.writable);
} else {
debug('AGENT socket keep-alive');
if (req.timeoutCb) {
socket.setTimeout(0, req.timeoutCb);
req.timeoutCb = null;
}
socket.removeListener('close', socketCloseListener);
socket.removeListener('error', socketErrorListener);
socket.emit('free');
}
}

ClientRequest.prototype.onSocket = function(socket) {
var req = this;

process.nextTick(function() {
var parser = parsers.alloc();
req.socket = socket;
req.connection = socket;
parser.reinitialize(HTTPParser.RESPONSE);
parser.socket = socket;
parser.incoming = null;
req.parser = parser;

socket.parser = parser;
socket._httpMessage = req;

// Setup "drain" propogation.


httpSocketSetup(socket);

// Propagate headers limit from request object to parser


if (typeof req.maxHeadersCount === 'number') {
parser.maxHeaderPairs = req.maxHeadersCount << 1;
} else {
// Set default value because parser may be reused from FreeList
parser.maxHeaderPairs = 2000;
}

socket.on('error', socketErrorListener);
socket.ondata = socketOnData;
socket.onend = socketOnEnd;
socket.on('close', socketCloseListener);
parser.onIncoming = parserOnIncomingClient;
req.emit('socket', socket);
});

};

ClientRequest.prototype._deferToConnect = function(method, arguments_, cb) {


// This function is for calls that need to happen once the socket is
// connected and writable. It's an important promisy thing for all the socket
// calls that happen either now (when a socket is assigned) or
// in the future (when a socket gets assigned out of the pool and is
// eventually writable).
var self = this;
var onSocket = function() {
if (self.socket.writable) {
if (method) {
self.socket[method].apply(self.socket, arguments_);
}
if (cb) { cb(); }
} else {
self.socket.once('connect', function() {
if (method) {
self.socket[method].apply(self.socket, arguments_);
}
if (cb) { cb(); }
});
}
}
if (!self.socket) {
self.once('socket', onSocket);
} else {
onSocket();
}
};

ClientRequest.prototype.setTimeout = function(msecs, callback) {


if (callback) this.once('timeout', callback);

var self = this;


function emitTimeout() {
self.emit('timeout');
}

if (this.socket && this.socket.writable) {


if (this.timeoutCb)
this.socket.setTimeout(0, this.timeoutCb);
this.timeoutCb = emitTimeout;
this.socket.setTimeout(msecs, emitTimeout);
return;
}

if (this.socket) {
this.socket.once('connect', function() {
this.setTimeout(msecs, emitTimeout);
});
return;
}

this.once('socket', function(sock) {
this.setTimeout(msecs, emitTimeout);
});
};

ClientRequest.prototype.setNoDelay = function() {
this._deferToConnect('setNoDelay', arguments);
};
ClientRequest.prototype.setSocketKeepAlive = function() {
this._deferToConnect('setKeepAlive', arguments);
};

ClientRequest.prototype.clearTimeout = function(cb) {
this.setTimeout(0, cb);
};

exports.request = function(options, cb) {


if (typeof options === 'string') {
options = url.parse(options);
}

if (options.protocol && options.protocol !== 'http:') {


throw new Error('Protocol:' + options.protocol + ' not supported.');
}

return new ClientRequest(options, cb);


};

exports.get = function(options, cb) {


var req = exports.request(options, cb);
req.end();
return req;
};

function ondrain() {
if (this._httpMessage) this._httpMessage.emit('drain');
}

function httpSocketSetup(socket) {
socket.removeListener('drain', ondrain);
socket.on('drain', ondrain);
}

function Server(requestListener) {
if (!(this instanceof Server)) return new Server(requestListener);
net.Server.call(this, { allowHalfOpen: true });

if (requestListener) {
this.addListener('request', requestListener);
}

// Similar option to this. Too lazy to write my own docs.


// http://www.squid-cache.org/Doc/config/half_closed_clients/
// http://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-
closed_filedescriptor.3F
this.httpAllowHalfOpen = false;

this.addListener('connection', connectionListener);
}
util.inherits(Server, net.Server);

exports.Server = Server;
exports.createServer = function(requestListener) {
return new Server(requestListener);
};

function connectionListener(socket) {
var self = this;
var outgoing = [];
var incoming = [];

function abortIncoming() {
while (incoming.length) {
var req = incoming.shift();
req.emit('aborted');
req.emit('close');
}
// abort socket._httpMessage ?
}

function serverSocketCloseListener() {
debug('server socket close');
// mark this parser as reusable
if (this.parser)
freeParser(this.parser);

abortIncoming();
}

debug('SERVER new http connection');

httpSocketSetup(socket);

socket.setTimeout(2 * 60 * 1000); // 2 minute timeout


socket.once('timeout', function() {
socket.destroy();
});

var parser = parsers.alloc();


parser.reinitialize(HTTPParser.REQUEST);
parser.socket = socket;
socket.parser = parser;
parser.incoming = null;

// Propagate headers limit from server instance to parser


if (typeof this.maxHeadersCount === 'number') {
parser.maxHeaderPairs = this.maxHeadersCount << 1;
} else {
// Set default value because parser may be reused from FreeList
parser.maxHeaderPairs = 2000;
}

socket.addListener('error', function(e) {
self.emit('clientError', e);
});

socket.ondata = function(d, start, end) {


var ret = parser.execute(d, start, end - start);
if (ret instanceof Error) {
debug('parse error');
socket.destroy(ret);
} else if (parser.incoming && parser.incoming.upgrade) {
// Upgrade or CONNECT
var bytesParsed = ret;
var req = parser.incoming;

socket.ondata = null;
socket.onend = null;
socket.removeListener('close', serverSocketCloseListener);
parser.finish();
freeParser(parser, req);

// This is start + byteParsed


var bodyHead = d.slice(start + bytesParsed, end);

var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';


if (self.listeners(eventName).length) {
self.emit(eventName, req, req.socket, bodyHead);
} else {
// Got upgrade header or CONNECT method, but have no handler.
socket.destroy();
}
}
};

socket.onend = function() {
var ret = parser.finish();

if (ret instanceof Error) {


debug('parse error');
socket.destroy(ret);
return;
}

if (!self.httpAllowHalfOpen) {
abortIncoming();
if (socket.writable) socket.end();
} else if (outgoing.length) {
outgoing[outgoing.length - 1]._last = true;
} else if (socket._httpMessage) {
socket._httpMessage._last = true;
} else {
if (socket.writable) socket.end();
}
};

socket.addListener('close', serverSocketCloseListener);

// The following callback is issued after the headers have been read on a
// new message. In this callback we setup the response object and pass it
// to the user.
parser.onIncoming = function(req, shouldKeepAlive) {
incoming.push(req);

var res = new ServerResponse(req);


debug('server response shouldKeepAlive: ' + shouldKeepAlive);
res.shouldKeepAlive = shouldKeepAlive;
;
if (socket._httpMessage) {
// There are already pending outgoing res, append.
outgoing.push(res);
} else {
res.assignSocket(socket);
}

// When we're finished writing the response, check if this is the last
// respose, if so destroy the socket.
res.on('finish', function() {
// Usually the first incoming element should be our request. it may
// be that in the case abortIncoming() was called that the incoming
// array will be empty.
assert(incoming.length == 0 || incoming[0] === req);

incoming.shift();

res.detachSocket(socket);

if (res._last) {
socket.destroySoon();
} else {
// start sending the next message
var m = outgoing.shift();
if (m) {
m.assignSocket(socket);
}
}
});

if ('expect' in req.headers &&


(req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
continueExpression.test(req.headers['expect'])) {
res._expect_continue = true;
if (self.listeners('checkContinue').length) {
self.emit('checkContinue', req, res);
} else {
res.writeContinue();
self.emit('request', req, res);
}
} else {
self.emit('request', req, res);
}
return false; // Not a HEAD response. (Not even a response!)
};
}
exports._connectionListener = connectionListener;

// Legacy Interface

function Client(port, host) {


if (!(this instanceof Client)) return new Client(port, host);
EventEmitter.call(this);

host = host || 'localhost';


port = port || 80;
this.host = host;
this.port = port;
this.agent = new Agent({ host: host, port: port, maxSockets: 1 });
}
util.inherits(Client, EventEmitter);
Client.prototype.request = function(method, path, headers) {
var self = this;
var options = {};
options.host = self.host;
options.port = self.port;
if (method[0] === '/') {
headers = path;
path = method;
method = 'GET';
}
options.method = method;
options.path = path;
options.headers = headers;
options.agent = self.agent;
var c = new ClientRequest(options);
c.on('error', function(e) {
self.emit('error', e);
});
// The old Client interface emitted 'end' on socket end.
// This doesn't map to how we want things to operate in the future
// but it will get removed when we remove this legacy interface.
c.on('socket', function(s) {
s.on('end', function() {
self.emit('end');
});
});
return c;
};

exports.Client = util.deprecate(Client,
'http.Client will be removed soon. Do not use it.');

exports.createClient = util.deprecate(function(port, host) {


return new Client(port, host);
}, 'http.createClient is deprecated. Use `http.request` instead.');
#####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var tls = require('tls');
var http = require('http');
var url = require('url');
var inherits = require('util').inherits;

function Server(opts, requestListener) {


if (!(this instanceof Server)) return new Server(opts, requestListener);

if (process.features.tls_npn && !opts.NPNProtocols) {


opts.NPNProtocols = ['http/1.1', 'http/1.0'];
}

tls.Server.call(this, opts, http._connectionListener);

this.httpAllowHalfOpen = false;

if (requestListener) {
this.addListener('request', requestListener);
}
}
inherits(Server, tls.Server);

exports.Server = Server;

exports.createServer = function(opts, requestListener) {


return new Server(opts, requestListener);
};

// HTTPS agents.

function createConnection(/* [port, host, options] */) {


var options = {};

if (typeof arguments[0] === 'object') {


options = arguments[0];
} else if (typeof arguments[1] === 'object') {
options = arguments[1];
options.port = arguments[0];
} else if (typeof arguments[2] === 'object') {
options = arguments[2];
options.port = arguments[0];
options.host = arguments[1];
} else {
if (typeof arguments[0] === 'number') {
options.port = arguments[0];
}
if (typeof arguments[1] === 'string') {
options.host = arguments[1];
}
}
return tls.connect(options);
}

function Agent(options) {
http.Agent.call(this, options);
this.createConnection = createConnection;
}
inherits(Agent, http.Agent);
Agent.prototype.defaultPort = 443;

var globalAgent = new Agent();

exports.globalAgent = globalAgent;
exports.Agent = Agent;

exports.request = function(options, cb) {


if (typeof options === 'string') {
options = url.parse(options);
}

if (options.protocol && options.protocol !== 'https:') {


throw new Error('Protocol:' + options.protocol + ' not supported.');
}

if (options.agent === undefined) {


options.agent = globalAgent;
}
options.createConnection = createConnection;
options.defaultPort = options.defaultPort || 443;
return new http.ClientRequest(options, cb);
};

exports.get = function(options, cb) {


var req = exports.request(options, cb);
req.end();
return req;
};
########// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var NativeModule = require('native_module');


var Script = process.binding('evals').NodeScript;
var runInThisContext = Script.runInThisContext;
var runInNewContext = Script.runInNewContext;
var assert = require('assert').ok;
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}

function Module(id, parent) {


this.id = id;
this.exports = {};
this.parent = parent;
if (parent && parent.children) {
parent.children.push(this);
}

this.filename = null;
this.loaded = false;
this.children = [];
}
module.exports = Module;

// Set the environ variable NODE_MODULE_CONTEXTS=1 to make node load all


// modules in thier own context.
Module._contextLoad = (+process.env['NODE_MODULE_CONTEXTS'] > 0);
Module._cache = {};
Module._pathCache = {};
Module._extensions = {};
var modulePaths = [];
Module.globalPaths = [];

Module.wrapper = NativeModule.wrapper;
Module.wrap = NativeModule.wrap;

var path = NativeModule.require('path');

Module._debug = function() {};


if (process.env.NODE_DEBUG && /module/.test(process.env.NODE_DEBUG)) {
Module._debug = function(x) {
console.error(x);
};
}

// We use this alias for the preprocessor that filters it out


var debug = Module._debug;

// given a module name, and a list of paths to test, returns the first
// matching file in the following precedence.
//
// require("a.<ext>")
// -> a.<ext>
//
// require("a")
// -> a
// -> a.<ext>
// -> a/index.<ext>
function statPath(path) {
var fs = NativeModule.require('fs');
var result = fs.statSyncNoException(path);
return result === false ? false : result;
}

// check if the directory is a package.json dir


var packageCache = {};

function readPackage(requestPath) {
if (hasOwnProperty(packageCache, requestPath)) {
return packageCache[requestPath];
}

var fs = NativeModule.require('fs');
var jsonPath = path.resolve(requestPath, 'package.json');
if (fs.statSyncNoException(jsonPath) === false) // check existence.
return false;
try {
var json = fs.readFileSync(jsonPath, 'utf8');
} catch (e) {
return false;
}

try {
var pkg = packageCache[requestPath] = JSON.parse(json);
} catch (e) {
e.path = jsonPath;
e.message = 'Error parsing ' + jsonPath + ': ' + e.message;
throw e;
}
return pkg;
}

function tryPackage(requestPath, exts) {


var pkg = readPackage(requestPath);

if (!pkg || !pkg.main) return false;

var filename = path.resolve(requestPath, pkg.main);


return tryFile(filename) || tryExtensions(filename, exts) ||
tryExtensions(path.resolve(filename, 'index'), exts);
}

// In order to minimize unnecessary lstat() calls,


// this cache is a list of known-real paths.
// Set to an empty object to reset.
Module._realpathCache = {};

// check if the file exists and is not a directory


function tryFile(requestPath) {
var fs = NativeModule.require('fs');
var stats = statPath(requestPath);
if (stats && !stats.isDirectory()) {
return fs.realpathSync(requestPath, Module._realpathCache);
}
return false;
}
// given a path check a the file exists with any of the set extensions
function tryExtensions(p, exts) {
for (var i = 0, EL = exts.length; i < EL; i++) {
var filename = tryFile(p + exts[i]);

if (filename) {
return filename;
}
}
return false;
}

Module._findPath = function(request, paths) {


var exts = Object.keys(Module._extensions);

if (request.charAt(0) === '/') {


paths = [''];
}

var trailingSlash = (request.slice(-1) === '/');

var cacheKey = JSON.stringify({request: request, paths: paths});


if (Module._pathCache[cacheKey]) {
return Module._pathCache[cacheKey];
}

// For each path


for (var i = 0, PL = paths.length; i < PL; i++) {
// Modified by CEP to fix the issue where a module fails to load
// when its path contains spaces.
var p = unescape(paths[i]);
var basePath = path.resolve(p, request);
var filename;

if (!trailingSlash) {
// try to join the request to the path
filename = tryFile(basePath);

if (!filename && !trailingSlash) {


// try it with each of the extensions
filename = tryExtensions(basePath, exts);
}
}

if (!filename) {
filename = tryPackage(basePath, exts);
}

if (!filename) {
// try it with each of the extensions at "index"
filename = tryExtensions(path.resolve(basePath, 'index'), exts);
}

if (filename) {
Module._pathCache[cacheKey] = filename;
return filename;
}
}
return false;
};

// 'from' is the __dirname of the module.


Module._nodeModulePaths = function(from) {
// guarantee that 'from' is absolute.
from = path.resolve(from);

// note: this approach *only* works when the path is guaranteed


// to be absolute. Doing a fully-edge-case-correct path.split
// that works on both Windows and Posix is non-trivial.
var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\//;
// yes, '/' works on both, but let's be a little canonical.
var joiner = process.platform === 'win32' ? '\\' : '/';
var paths = [];
var parts = from.split(splitRe);

for (var tip = parts.length - 1; tip >= 0; tip--) {


// don't search in .../node_modules/node_modules
if (parts[tip] === 'node_modules') continue;
var dir = parts.slice(0, tip + 1).concat('node_modules').join(joiner);
paths.push(dir);
}

return paths;
};

Module._resolveLookupPaths = function(request, parent) {


if (NativeModule.exists(request)) {
return [request, []];
}

var start = request.substring(0, 2);


if (start !== './' && start !== '..') {
var paths = modulePaths;
if (parent) {
if (!parent.paths) parent.paths = [];
paths = parent.paths.concat(paths);
}
return [request, paths];
}

// with --eval, parent.id is not set and parent.filename is null


if (!parent || !parent.id || !parent.filename) {
// make require('./path/to/foo') work - normally the path is taken
// from realpath(__filename) but with eval there is no filename
var mainPaths = ['.'].concat(modulePaths);
mainPaths = Module._nodeModulePaths('.').concat(mainPaths);
return [request, mainPaths];
}

// Is the parent an index module?


// We can assume the parent has a valid extension,
// as it already has been accepted as a module.
var isIndex = /^index\.\w+?$/.test(path.basename(parent.filename));
var parentIdPath = isIndex ? parent.id : path.dirname(parent.id);
var id = path.resolve(parentIdPath, request);
// make sure require('./path') and require('path') get distinct ids, even
// when called from the toplevel js file
if (parentIdPath === '.' && id.indexOf('/') === -1) {
id = './' + id;
}

debug('RELATIVE: requested:' + request +


' set ID to: ' + id + ' from ' + parent.id);

return [id, [path.dirname(parent.filename)]];


};

Module._load = function(request, parent, isMain) {


if (parent) {
debug('Module._load REQUEST ' + (request) + ' parent: ' + parent.id);
}

var filename = Module._resolveFilename(request, parent);

var cachedModule = Module._cache[filename];


if (cachedModule) {
return cachedModule.exports;
}

if (NativeModule.exists(filename)) {
// REPL is a special case, because it needs the real require.
if (filename == 'repl') {
var replModule = new Module('repl');
replModule._compile(NativeModule.getSource('repl'), 'repl.js');
NativeModule._cache.repl = replModule;
return replModule.exports;
}

debug('load native module ' + request);


return NativeModule.require(filename);
}

var module = new Module(filename, parent);

if (isMain) {
process.mainModule = module;
module.id = '.';
}

Module._cache[filename] = module;

var hadException = true;

try {
module.load(filename);
hadException = false;
} finally {
if (hadException) {
delete Module._cache[filename];
}
}
return module.exports;
};

Module._resolveFilename = function(request, parent) {


if (NativeModule.exists(request)) {
return request;
}

var resolvedModule = Module._resolveLookupPaths(request, parent);


var id = resolvedModule[0];
var paths = resolvedModule[1];

// look up the filename first, since that's the cache key.


debug('looking for ' + JSON.stringify(id) +
' in ' + JSON.stringify(paths));

var filename = Module._findPath(request, paths);


if (!filename) {
var err = new Error("Cannot find module '" + request + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
}
return filename;
};

Module.prototype.load = function(filename) {
debug('load ' + JSON.stringify(filename) +
' for module ' + JSON.stringify(this.id));

assert(!this.loaded);
this.filename = filename;
this.paths = Module._nodeModulePaths(path.dirname(filename));

var extension = path.extname(filename) || '.js';


if (!Module._extensions[extension]) extension = '.js';
Module._extensions[extension](this, filename);
this.loaded = true;
};

Module.prototype.require = function(path) {
return Module._load(path, this);
};

// Resolved path to process.argv[1] will be lazily placed here


// (needed for setting breakpoint when called with --debug-brk)
var resolvedArgv;

// Returns exception if any


Module.prototype._compile = function(content, filename) {
var self = this;
// remove shebang
content = content.replace(/^\#\!.*/, '');

var direwolf_bindings_cache;
function require(path) {
if (typeof __direwolf == 'object' &&
(path == 'direwolf' || path == 'nw.gui')) {
if (typeof direwolf_bindings_cache == 'object')
return direwolf_bindings_cache;

return direwolf_bindings_cache = __direwolf.direwolfBindings();


}

return self.require(path);
}

require.resolve = function(request) {
return Module._resolveFilename(request, self);
};

Object.defineProperty(require, 'paths', { get: function() {


throw new Error('require.paths is removed. Use ' +
'node_modules folders, or the NODE_PATH ' +
'environment variable instead.');
}});

require.main = process.mainModule;

// Enable support to add extra extension types


require.extensions = Module._extensions;
require.registerExtension = function() {
throw new Error('require.registerExtension() removed. Use ' +
'require.extensions instead.');
};

require.cache = Module._cache;

var dirname = path.dirname(filename);

if (Module._contextLoad) {
if (self.id !== '.') {
debug('load submodule');
// not root module
var sandbox = {};
for (var k in global) {
sandbox[k] = global[k];
}
sandbox.require = require;
sandbox.exports = self.exports;
sandbox.__filename = filename;
sandbox.__dirname = dirname;
sandbox.module = self;
sandbox.global = sandbox;
sandbox.root = root;

return runInNewContext(content, sandbox, filename, true);


}

debug('load root module');


// root module
global.require = require;
global.exports = self.exports;
global.__filename = filename;
global.__dirname = dirname;
global.module = self;

return runInThisContext(content, filename, true);


}

// create wrapper function


var wrapper = Module.wrap(content);

var compiledWrapper = runInThisContext(wrapper, filename, true);


if (global.v8debug) {
if (!resolvedArgv) {
resolvedArgv = Module._resolveFilename(process.argv[1], null);
}

// Set breakpoint on module start


if (filename === resolvedArgv) {
global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0);
}
}
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);
};

function stripBOM(content) {
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
// because the buffer-to-string conversion in `fs.readFileSync()`
// translates it to FEFF, the UTF-16 BOM.
if (content.charCodeAt(0) === 0xFEFF) {
content = content.slice(1);
}
return content;
}

// Native extension for .js


Module._extensions['.js'] = function(module, filename) {
var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
module._compile(stripBOM(content), filename);
};

// Native extension for .json


Module._extensions['.json'] = function(module, filename) {
var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
try {
module.exports = JSON.parse(stripBOM(content));
} catch (err) {
err.message = filename + ': ' + err.message;
throw err;
}
};

//Native extension for .node


Module._extensions['.node'] = function(module, filename) {
process.dlopen(filename, module.exports);
};
// bootstrap main module.
Module.runMain = function() {
// Load the main module--the command line argument.
Module._load(process.argv[1], null, true);
};

Module._initPaths = function() {
var paths = [];
if (process.platform != 'darwin')
paths = [path.resolve(process.execPath, '..', '..', 'lib', 'node')];

if (process.env['HOME']) {
paths.unshift(path.resolve(process.env['HOME'], '.node_libraries'));
paths.unshift(path.resolve(process.env['HOME'], '.node_modules'));
}

if (process.env['NODE_PATH']) {
var splitter = process.platform === 'win32' ? ';' : ':';
paths = process.env['NODE_PATH'].split(splitter).concat(paths);
}

modulePaths = paths;

// clone as a read-only copy, for introspection.


Module.globalPaths = modulePaths.slice(0);
};

// bootstrap repl
Module.requireRepl = function() {
return Module._load('repl', '.');
};

Module._initPaths();

// backwards compatibility
Module.Module = Module;
###// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var events = require('events');


var Stream = require('stream');
var timers = require('timers');
var util = require('util');
var assert = require('assert');
var cares = process.binding('cares_wrap');
var cluster;

function noop() {}

// constructor for lazy loading


function createPipe() {
var Pipe = process.binding('pipe_wrap').Pipe;
return new Pipe();
}

// constructor for lazy loading


function createTCP() {
var TCP = process.binding('tcp_wrap').TCP;
return new TCP();
}

/* Bit flags for socket._flags */


var FLAG_GOT_EOF = 1 << 0;
var FLAG_SHUTDOWN = 1 << 1;
var FLAG_DESTROY_SOON = 1 << 2;
var FLAG_SHUTDOWN_QUEUED = 1 << 3;

var debug;
if (process.env.NODE_DEBUG && /net/.test(process.env.NODE_DEBUG)) {
debug = function(x) { console.error('NET:', x); };
} else {
debug = function() { };
}

function isPipeName(s) {
return typeof s === 'string' && toNumber(s) === false;
}

exports.createServer = function() {
return new Server(arguments[0], arguments[1]);
};

// Target API:
//
// var s = net.connect({port: 80, host: 'google.com'}, function() {
// ...
// });
//
// There are various forms:
//
// connect(options, [cb])
// connect(port, [host], [cb])
// connect(path, [cb]);
//
exports.connect = exports.createConnection = function() {
var args = normalizeConnectArgs(arguments);
var s = new Socket(args[0]);
return Socket.prototype.connect.apply(s, args);
};

// Returns an array [options] or [options, cb]


// It is the same as the argument of Socket.prototype.connect().
function normalizeConnectArgs(args) {
var options = {};

if (typeof args[0] === 'object') {


// connect(options, [cb])
options = args[0];
} else if (isPipeName(args[0])) {
// connect(path, [cb]);
options.path = args[0];
} else {
// connect(port, [host], [cb])
options.port = args[0];
if (typeof args[1] === 'string') {
options.host = args[1];
}
}

var cb = args[args.length - 1];


return (typeof cb === 'function') ? [options, cb] : [options];
}
exports._normalizeConnectArgs = normalizeConnectArgs;

/* called when creating new Socket, or when re-using a closed Socket */


function initSocketHandle(self) {
self._pendingWriteReqs = 0;

self._flags = 0;
self._connectQueueSize = 0;
self.destroyed = false;
self.errorEmitted = false;
self.bytesRead = 0;
self._bytesDispatched = 0;

// Handle creation may be deferred to bind() or connect() time.


if (self._handle) {
self._handle.owner = self;
self._handle.onread = onread;
}
}

function Socket(options) {
if (!(this instanceof Socket)) return new Socket(options);

Stream.call(this);

switch (typeof options) {


case 'number':
options = { fd: options }; // Legacy interface.
break;
case 'undefined':
options = {};
break;
}

if (typeof options.fd === 'undefined') {


this._handle = options && options.handle; // private
} else {
this._handle = createPipe();
this._handle.open(options.fd);
this.readable = this.writable = true;
}

initSocketHandle(this);
this.allowHalfOpen = options && options.allowHalfOpen;
}
util.inherits(Socket, Stream);

exports.Socket = Socket;
exports.Stream = Socket; // Legacy naming.

Socket.prototype.listen = function() {
var self = this;
self.on('connection', arguments[0]);
listen(self, null, null, null);
};

Socket.prototype.setTimeout = function(msecs, callback) {


if (msecs > 0 && !isNaN(msecs) && isFinite(msecs)) {
timers.enroll(this, msecs);
timers.active(this);
if (callback) {
this.once('timeout', callback);
}
} else if (msecs === 0) {
timers.unenroll(this);
if (callback) {
this.removeListener('timeout', callback);
}
}
};

Socket.prototype._onTimeout = function() {
debug('_onTimeout');
this.emit('timeout');
};

Socket.prototype.setNoDelay = function(enable) {
// backwards compatibility: assume true when `enable` is omitted
if (this._handle && this._handle.setNoDelay)
this._handle.setNoDelay(typeof enable === 'undefined' ? true : !!enable);
};

Socket.prototype.setKeepAlive = function(setting, msecs) {


if (this._handle && this._handle.setKeepAlive)
this._handle.setKeepAlive(setting, ~~(msecs / 1000));
};

Socket.prototype.address = function() {
if (this._handle && this._handle.getsockname) {
return this._handle.getsockname();
}
return null;
};

Object.defineProperty(Socket.prototype, 'readyState', {
get: function() {
if (this._connecting) {
return 'opening';
} else if (this.readable && this.writable) {
return 'open';
} else if (this.readable && !this.writable) {
return 'readOnly';
} else if (!this.readable && this.writable) {
return 'writeOnly';
} else {
return 'closed';
}
}
});

Object.defineProperty(Socket.prototype, 'bufferSize', {
get: function() {
if (this._handle) {
return this._handle.writeQueueSize + this._connectQueueSize;
}
}
});

Socket.prototype.pause = function() {
this._paused = true;
if (this._handle && !this._connecting) {
this._handle.readStop();
}
};

Socket.prototype.resume = function() {
this._paused = false;
if (this._handle && !this._connecting) {
this._handle.readStart();
}
};

Socket.prototype.end = function(data, encoding) {


if (this._connecting && ((this._flags & FLAG_SHUTDOWN_QUEUED) == 0)) {
// still connecting, add data to buffer
if (data) this.write(data, encoding);
this.writable = false;
this._flags |= FLAG_SHUTDOWN_QUEUED;
}

if (!this.writable) return;
this.writable = false;

if (data) this.write(data, encoding);


;

if (!this.readable) {
this.destroySoon();
} else {
this._flags |= FLAG_SHUTDOWN;
var shutdownReq = this._handle.shutdown();

if (!shutdownReq) {
this._destroy(errnoException(errno, 'shutdown'));
return false;
}

shutdownReq.oncomplete = afterShutdown;
}

return true;
};

function afterShutdown(status, handle, req) {


var self = handle.owner;

assert.ok(self._flags & FLAG_SHUTDOWN);


assert.ok(!self.writable);

// callback may come after call to destroy.


if (self.destroyed) {
return;
}

if (self._flags & FLAG_GOT_EOF || !self.readable) {


self._destroy();
} else {
}
}

Socket.prototype.destroySoon = function() {
this.writable = false;
this._flags |= FLAG_DESTROY_SOON;

if (this._pendingWriteReqs == 0) {
this._destroy();
}
};

Socket.prototype._connectQueueCleanUp = function(exception) {
this._connecting = false;
this._connectQueueSize = 0;
this._connectQueue = null;
};

Socket.prototype._destroy = function(exception, cb) {


var self = this;

function fireErrorCallbacks() {
if (cb) cb(exception);
if (exception && !self.errorEmitted) {
process.nextTick(function() {
self.emit('error', exception);
});
self.errorEmitted = true;
}
};

if (this.destroyed) {
fireErrorCallbacks();
return;
}

self._connectQueueCleanUp();

debug('destroy');

this.readable = this.writable = false;

timers.unenroll(this);

debug('close');
if (this._handle) {
this._handle.close();
this._handle.onread = noop;
this._handle = null;
}

fireErrorCallbacks();

process.nextTick(function() {
self.emit('close', exception ? true : false);
});

this.destroyed = true;

if (this.server) {
this.server._connections--;
if (this.server._emitCloseIfDrained) {
this.server._emitCloseIfDrained();
}
}
};

Socket.prototype.destroy = function(exception) {
this._destroy(exception);
};
function onread(buffer, offset, length) {
var handle = this;
var self = handle.owner;
assert(handle === self._handle, 'handle != self._handle');

timers.active(self);

var end = offset + length;

if (buffer) {
// Emit 'data' event.

if (self._decoder) {
// Emit a string.
var string = self._decoder.write(buffer.slice(offset, end));
if (string.length) self.emit('data', string);
} else {
// Emit a slice. Attempt to avoid slicing the buffer if no one is
// listening for 'data'.
if (self._events && self._events['data']) {
self.emit('data', buffer.slice(offset, end));
}
}

self.bytesRead += length;

// Optimization: emit the original buffer with end points


if (self.ondata) self.ondata(buffer, offset, end);

} else if (errno == 'EOF') {


// EOF
self.readable = false;

assert.ok(!(self._flags & FLAG_GOT_EOF));


self._flags |= FLAG_GOT_EOF;

// We call destroy() before end(). 'close' not emitted until nextTick so


// the 'end' event will come first as required.
if (!self.writable) self._destroy();

if (!self.allowHalfOpen) self.end();
if (self._events && self._events['end']) self.emit('end');
if (self.onend) self.onend();
} else {
// Error
if (errno == 'ECONNRESET') {
self._destroy();
} else {
self._destroy(errnoException(errno, 'read'));
}
}
}

Socket.prototype.setEncoding = function(encoding) {
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder(encoding);
};
Socket.prototype._getpeername = function() {
if (!this._handle || !this._handle.getpeername) {
return {};
}
if (!this._peername) {
this._peername = this._handle.getpeername();
// getpeername() returns null on error
if (this._peername === null) {
return {};
}
}
return this._peername;
};

Socket.prototype.__defineGetter__('remoteAddress', function() {
return this._getpeername().address;
});

Socket.prototype.__defineGetter__('remotePort', function() {
return this._getpeername().port;
});

/*
* Arguments data, [encoding], [cb]
*/
Socket.prototype.write = function(data, arg1, arg2) {
var encoding, cb;

// parse arguments
if (arg1) {
if (typeof arg1 === 'string') {
encoding = arg1;
cb = arg2;
} else if (typeof arg1 === 'function') {
cb = arg1;
} else {
throw new Error('bad arg');
}
}

if (typeof data === 'string') {


encoding = (encoding || 'utf8').toLowerCase();
switch (encoding) {
case 'utf8':
case 'utf-8':
case 'ascii':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
// This encoding can be handled in the binding layer.
break;

default:
data = new Buffer(data, encoding);
}
} else if (!Buffer.isBuffer(data)) {
throw new TypeError('First argument must be a buffer or a string.');
}

// If we are still connecting, then buffer this for later.


if (this._connecting) {
this._connectQueueSize += data.length;
if (this._connectQueue) {
this._connectQueue.push([data, encoding, cb]);
} else {
this._connectQueue = [[data, encoding, cb]];
}
return false;
}

return this._write(data, encoding, cb);


};

Socket.prototype._write = function(data, encoding, cb) {


timers.active(this);

if (!this._handle) {
this._destroy(new Error('This socket is closed.'), cb);
return false;
}

var writeReq;

if (Buffer.isBuffer(data)) {
writeReq = this._handle.writeBuffer(data);

} else {
switch (encoding) {
case 'utf8':
case 'utf-8':
writeReq = this._handle.writeUtf8String(data);
break;

case 'ascii':
writeReq = this._handle.writeAsciiString(data);
break;

case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
writeReq = this._handle.writeUcs2String(data);
break;

default:
assert(0);
}
}

if (!writeReq || typeof writeReq !== 'object') {


this._destroy(errnoException(errno, 'write'), cb);
return false;
}

writeReq.oncomplete = afterWrite;
writeReq.cb = cb;

this._pendingWriteReqs++;
this._bytesDispatched += writeReq.bytes;

return this._handle.writeQueueSize == 0;
};

Socket.prototype.__defineGetter__('bytesWritten', function() {
var bytes = this._bytesDispatched,
connectQueue = this._connectQueue;

if (connectQueue) {
connectQueue.forEach(function(el) {
var data = el[0];
if (Buffer.isBuffer(data)) {
bytes += data.length;
} else {
bytes += Buffer.byteLength(data, el[1]);
}
}, this);
}

return bytes;
});

function afterWrite(status, handle, req) {


var self = handle.owner;

// callback may come after call to destroy.


if (self.destroyed) {
return;
}

if (status) {
self._destroy(errnoException(errno, 'write'), req.cb);
return;
}

timers.active(self);

self._pendingWriteReqs--;

if (self._pendingWriteReqs == 0) {
self.emit('drain');
}

if (req.cb) req.cb();

if (self._pendingWriteReqs == 0 && self._flags & FLAG_DESTROY_SOON) {


self._destroy();
}
}
function connect(self, address, port, addressType, localAddress) {
// TODO return promise from Socket.prototype.connect which
// wraps _connectReq.

assert.ok(self._connecting);

if (localAddress) {
var r;
if (addressType == 6) {
r = self._handle.bind6(localAddress);
} else {
r = self._handle.bind(localAddress);
}

if (r) {
self._destroy(errnoException(errno, 'bind'));
return;
}
}

var connectReq;
if (addressType == 6) {
connectReq = self._handle.connect6(address, port);
} else if (addressType == 4) {
connectReq = self._handle.connect(address, port);
} else {
connectReq = self._handle.connect(address, afterConnect);
}

if (connectReq !== null) {


connectReq.oncomplete = afterConnect;
} else {
self._destroy(errnoException(errno, 'connect'));
}
}

Socket.prototype.connect = function(options, cb) {


if (typeof options !== 'object') {
// Old API:
// connect(port, [host], [cb])
// connect(path, [cb]);
var args = normalizeConnectArgs(arguments);
return Socket.prototype.connect.apply(this, args);
}

var self = this;


var pipe = !!options.path;

if (this.destroyed || !this._handle) {
this._handle = pipe ? createPipe() : createTCP();
initSocketHandle(this);
}

if (typeof cb === 'function') {


self.once('connect', cb);
}
timers.active(this);

self._connecting = true;
self.writable = true;

if (pipe) {
connect(self, options.path);

} else if (!options.host) {
debug('connect: missing host');
connect(self, '127.0.0.1', options.port, 4);

} else {
var host = options.host;
debug('connect: find host ' + host);
require('dns').lookup(host, function(err, ip, addressType) {
// It's possible we were destroyed while looking this up.
// XXX it would be great if we could cancel the promise returned by
// the look up.
if (!self._connecting) return;

if (err) {
// net.createConnection() creates a net.Socket object and
// immediately calls net.Socket.connect() on it (that's us).
// There are no event listeners registered yet so defer the
// error event to the next tick.
process.nextTick(function() {
self.emit('error', err);
self._destroy();
});
} else {
timers.active(self);

addressType = addressType || 4;

// node_net.cc handles null host names graciously but user land


// expects remoteAddress to have a meaningful value
ip = ip || (addressType === 4 ? '127.0.0.1' : '0:0:0:0:0:0:0:1');

connect(self, ip, options.port, addressType, options.localAddress);


}
});
}
return self;
};

function afterConnect(status, handle, req, readable, writable) {


var self = handle.owner;

// callback may come after call to destroy


if (self.destroyed) {
return;
}

assert(handle === self._handle, 'handle != self._handle');

debug('afterConnect');
assert.ok(self._connecting);
self._connecting = false;

if (status == 0) {
self.readable = readable;
self.writable = writable;
timers.active(self);

if (self.readable && !self._paused) {


handle.readStart();
}

if (self._connectQueue) {
debug('Drain the connect queue');
var connectQueue = self._connectQueue;
for (var i = 0; i < connectQueue.length; i++) {
self._write.apply(self, connectQueue[i]);
}
self._connectQueueCleanUp();
}

self.emit('connect');

if (self._flags & FLAG_SHUTDOWN_QUEUED) {


// end called before connected - call end now with no data
self._flags &= ~FLAG_SHUTDOWN_QUEUED;
self.end();
}
} else {
self._connectQueueCleanUp();
self._destroy(errnoException(errno, 'connect'));
}
}

function errnoException(errorno, syscall) {


// TODO make this more compatible with ErrnoException from src/node.cc
// Once all of Node is using this function the ErrnoException from
// src/node.cc should be removed.
var e = new Error(syscall + ' ' + errorno);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}

function Server(/* [ options, ] listener */) {


if (!(this instanceof Server)) return new Server(arguments[0], arguments[1]);
events.EventEmitter.call(this);

var self = this;

var options;

if (typeof arguments[0] == 'function') {


options = {};
self.on('connection', arguments[0]);
} else {
options = arguments[0] || {};

if (typeof arguments[1] == 'function') {


self.on('connection', arguments[1]);
}
}

this._connections = 0;

// when server is using slaves .connections is not reliable


// so null will be return if thats the case
Object.defineProperty(this, 'connections', {
get: function() {
if (self._usingSlaves) {
return null;
}
return self._connections;
},
set: function(val) {
return (self._connections = val);
},
configurable: true, enumerable: true
});

this.allowHalfOpen = options.allowHalfOpen || false;

this._handle = null;
}
util.inherits(Server, events.EventEmitter);
exports.Server = Server;

function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }

var createServerHandle = exports._createServerHandle =


function(address, port, addressType, fd) {
var r = 0;
// assign handle in listen, and clean up if bind or listen fails
var handle;

if (typeof fd === 'number' && fd >= 0) {


var tty_wrap = process.binding('tty_wrap');
var type = tty_wrap.guessHandleType(fd);
switch (type) {
case 'PIPE':
debug('listen pipe fd=' + fd);
// create a PipeWrap
handle = createPipe();
handle.open(fd);
handle.readable = true;
handle.writable = true;
break;

default:
// Not a fd we can listen on. This will trigger an error.
debug('listen invalid fd=' + fd + ' type=' + type);
global.errno = 'EINVAL'; // hack, callers expect that errno is set
handle = null;
break;
}
return handle;

} else if (port == -1 && addressType == -1) {


handle = createPipe();
if (process.platform === 'win32') {
var instances = parseInt(process.env.NODE_PENDING_PIPE_INSTANCES);
if (!isNaN(instances)) {
handle.setPendingInstances(instances);
}
}
} else {
handle = createTCP();
}

if (address || port) {
debug('bind to ' + address);
if (addressType == 6) {
r = handle.bind6(address, port);
} else {
r = handle.bind(address, port);
}
}

if (r) {
handle.close();
handle = null;
}

return handle;
};

Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {


var self = this;
var r = 0;

// If there is not yet a handle, we need to create one and bind.


// In the case of a server sent via IPC, we don't need to do this.
if (!self._handle) {
self._handle = createServerHandle(address, port, addressType, fd);
if (!self._handle) {
var error = errnoException(errno, 'listen');
process.nextTick(function() {
self.emit('error', error);
});
return;
}
}

self._handle.onconnection = onconnection;
self._handle.owner = self;

// Use a backlog of 512 entries. We pass 511 to the listen() call because
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
// which will thus give us a backlog of 512 entries.
r = self._handle.listen(backlog || 511);
if (r) {
var ex = errnoException(errno, 'listen');
self._handle.close();
self._handle = null;
process.nextTick(function() {
self.emit('error', ex);
});
return;
}

// generate connection key, this should be unique to the connection


this._connectionKey = addressType + ':' + address + ':' + port;

process.nextTick(function() {
self.emit('listening');
});
};

function listen(self, address, port, addressType, backlog, fd) {


if (!cluster) cluster = require('cluster');

if (cluster.isMaster) {
self._listen2(address, port, addressType, backlog, fd);
return;
}

cluster._getServer(self, address, port, addressType, fd, function(handle) {


// Some operating systems (notably OS X and Solaris) don't report EADDRINUSE
// errors right away. libuv mimics that behavior for the sake of platform
// consistency but that means we have have a socket on our hands that is
// not actually bound. That's why we check if the actual port matches what
// we requested and if not, raise an error. The exception is when port == 0
// because that means "any random port".
if (port && handle.getsockname && port != handle.getsockname().port) {
self.emit('error', errnoException('EADDRINUSE', 'bind'));
return;
}

self._handle = handle;
self._listen2(address, port, addressType, backlog, fd);
});
}

Server.prototype.listen = function() {
var self = this;

var lastArg = arguments[arguments.length - 1];


if (typeof lastArg == 'function') {
self.once('listening', lastArg);
}

var port = toNumber(arguments[0]);

// The third optional argument is the backlog size.


// When the ip is omitted it can be the second argument.
var backlog = toNumber(arguments[1]) || toNumber(arguments[2]);
var TCP = process.binding('tcp_wrap').TCP;

if (arguments.length == 0 || typeof arguments[0] == 'function') {


// Bind to a random port.
listen(self, '0.0.0.0', 0, null, backlog);

} else if (arguments[0] && typeof arguments[0] === 'object') {


var h = arguments[0];
if (h._handle) {
h = h._handle;
} else if (h.handle) {
h = h.handle;
}
if (h instanceof TCP) {
self._handle = h;
listen(self, null, -1, -1, backlog);
} else if (typeof h.fd === 'number' && h.fd >= 0) {
listen(self, null, null, null, backlog, h.fd);
} else {
throw new Error('Invalid listen argument: ' + h);
}
} else if (isPipeName(arguments[0])) {
// UNIX socket or Windows pipe.
var pipeName = self._pipeName = arguments[0];
listen(self, pipeName, -1, -1, backlog);

} else if (typeof arguments[1] == 'undefined' ||


typeof arguments[1] == 'function' ||
typeof arguments[1] == 'number') {
// The first argument is the port, no IP given.
listen(self, '0.0.0.0', port, 4, backlog);

} else {
// The first argument is the port, the second an IP.
require('dns').lookup(arguments[1], function(err, ip, addressType) {
if (err) {
self.emit('error', err);
} else {
listen(self, ip || '0.0.0.0', port, ip ? addressType : 4, backlog);
}
});
}
return self;
};

Server.prototype.address = function() {
if (this._handle && this._handle.getsockname) {
return this._handle.getsockname();
} else if (this._pipeName) {
return this._pipeName;
} else {
return null;
}
};

function onconnection(clientHandle) {
var handle = this;
var self = handle.owner;
debug('onconnection');

if (!clientHandle) {
self.emit('error', errnoException(errno, 'accept'));
return;
}

if (self.maxConnections && self._connections >= self.maxConnections) {


clientHandle.close();
return;
}

var socket = new Socket({


handle: clientHandle,
allowHalfOpen: self.allowHalfOpen
});
socket.readable = socket.writable = true;

clientHandle.readStart();

self._connections++;
socket.server = self;

;
self.emit('connection', socket);
socket.emit('connect');
}

Server.prototype.close = function(cb) {
if (!this._handle) {
// Throw error. Follows net_legacy behaviour.
throw new Error('Not running');
}

if (cb) {
this.once('close', cb);
}
this._handle.close();
this._handle = null;
this._emitCloseIfDrained();

// fetch new socket lists


if (this._usingSlaves) {
this._slaves.forEach(function(socketList) {
if (socketList.list.length === 0) return;
socketList.update();
});
}

return this;
};

Server.prototype._emitCloseIfDrained = function() {
var self = this;

if (self._handle || self._connections) return;


process.nextTick(function() {
self.emit('close');
});
};

Server.prototype.listenFD = util.deprecate(function(fd, type) {


return this.listen({ fd: fd });
}, 'listenFD is deprecated. Use listen({fd: <number>}).');

// when sending a socket using fork IPC this function is executed


Server.prototype._setupSlave = function(socketList) {
if (!this._usingSlaves) {
this._usingSlaves = true;
this._slaves = [];
}
this._slaves.push(socketList);
};

// TODO: isIP should be moved to the DNS code. Putting it here now because
// this is what the legacy system did.
exports.isIP = cares.isIP;

exports.isIPv4 = function(input) {
return exports.isIP(input) === 4;
};

exports.isIPv6 = function(input) {
return exports.isIP(input) === 6;
};

if (process.platform === 'win32') {


var simultaneousAccepts;

exports._setSimultaneousAccepts = function(handle) {
if (typeof handle === 'undefined') {
return;
}

if (typeof simultaneousAccepts === 'undefined') {


simultaneousAccepts = (process.env.NODE_MANY_ACCEPTS &&
process.env.NODE_MANY_ACCEPTS !== '0');
}

if (handle._simultaneousAccepts !== simultaneousAccepts) {


handle.setSimultaneousAccepts(simultaneousAccepts);
handle._simultaneousAccepts = simultaneousAccepts;
}
};
} else {
exports._setSimultaneousAccepts = function(handle) {};
}
########// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var binding = process.binding('os');


var util = require('util');

exports.hostname = binding.getHostname;
exports.loadavg = binding.getLoadAvg;
exports.uptime = binding.getUptime;
exports.freemem = binding.getFreeMem;
exports.totalmem = binding.getTotalMem;
exports.cpus = binding.getCPUs;
exports.type = binding.getOSType;
exports.release = binding.getOSRelease;
exports.networkInterfaces = binding.getInterfaceAddresses;

exports.arch = function() {
return process.arch;
};

exports.platform = function() {
return process.platform;
};

exports.tmpDir = function() {
return process.env.TMPDIR ||
process.env.TMP ||
process.env.TEMP ||
(process.platform === 'win32' ? 'c:\\windows\\temp' : '/tmp');
};

exports.getNetworkInterfaces = util.deprecate(function() {
return exports.networkInterfaces();
}, 'getNetworkInterfaces is now called `os.networkInterfaces`.');

exports.EOL = process.platform === 'win32' ? '\r\n' : '\n';


##// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var isWindows = process.platform === 'win32';


var util = require('util');

// resolves . and .. elements in a path array with directory names there


// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}

// if the path is allowed to go above the root, restore leading ..s


if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}

return parts;
}

if (isWindows) {
// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;

// Regex to split the tail part of the above into [*, dir, basename, ext]
var splitTailRe =
/^([\s\S]+[\\\/](?!$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
// Function to split a filename into [root, dir, basename, ext]
// windows version
var splitPath = function(filename) {
// Separate device+slash from tail
var result = splitDeviceRe.exec(filename),
device = (result[1] || '') + (result[2] || ''),
tail = result[3] || '';
// Split the tail into dir, basename and extension
var result2 = splitTailRe.exec(tail),
dir = result2[1] || '',
basename = result2[2] || '',
ext = result2[3] || '';
return [device, dir, basename, ext];
};

// path.resolve([from ...], to)


// windows version
exports.resolve = function() {
var resolvedDevice = '',
resolvedTail = '',
resolvedAbsolute = false;

for (var i = arguments.length - 1; i >= -1; i--) {


var path;
if (i >= 0) {
path = arguments[i];
} else if (!resolvedDevice) {
path = process.cwd();
} else {
// Windows has the concept of drive-specific current working
// directories. If we've resolved a drive letter but not yet an
// absolute path, get cwd for that drive. We're sure the device is not
// an unc path at this points, because unc paths are always absolute.
path = process.env['=' + resolvedDevice];
// Verify that a drive-local cwd was found and that it actually points
// to our drive. If not, default to the drive's root.
if (!path || path.slice(0, 3).toLowerCase() !==
resolvedDevice.toLowerCase() + '\\') {
path = resolvedDevice + '\\';
}
}

// Skip empty and invalid entries


if (typeof path !== 'string' || !path) {
continue;
}

var result = splitDeviceRe.exec(path),


device = result[1] || '',
isUnc = device && device.charAt(1) !== ':',
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
tail = result[3];

if (device &&
resolvedDevice &&
device.toLowerCase() !== resolvedDevice.toLowerCase()) {
// This path points to another device so it is not applicable
continue;
}
if (!resolvedDevice) {
resolvedDevice = device;
}
if (!resolvedAbsolute) {
resolvedTail = tail + '\\' + resolvedTail;
resolvedAbsolute = isAbsolute;
}

if (resolvedDevice && resolvedAbsolute) {


break;
}
}

// Replace slashes (in UNC share name) by backslashes


resolvedDevice = resolvedDevice.replace(/\//g, '\\');

// At this point the path should be resolved to a full absolute path,


// but handle relative paths to be safe (might happen when process.cwd()
// fails)

// Normalize the tail path

function f(p) {
return !!p;
}

resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
!resolvedAbsolute).join('\\');

return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||


'.';
};

// windows version
exports.normalize = function(path) {
var result = splitDeviceRe.exec(path),
device = result[1] || '',
isUnc = device && device.charAt(1) !== ':',
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
tail = result[3],
trailingSlash = /[\\\/]$/.test(tail);

// Normalize the tail path


tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
return !!p;
}), !isAbsolute).join('\\');

if (!tail && !isAbsolute) {


tail = '.';
}
if (tail && trailingSlash) {
tail += '\\';
}

// Convert slashes to backslashes when `device` points to an UNC root.


device = device.replace(/\//g, '\\');

return device + (isAbsolute ? '\\' : '') + tail;


};

// windows version
exports.join = function() {
function f(p) {
return p && typeof p === 'string';
}

var paths = Array.prototype.slice.call(arguments, 0).filter(f);


var joined = paths.join('\\');

// Make sure that the joined path doesn't start with two slashes
// - it will be mistaken for an unc path by normalize() -
// unless the paths[0] also starts with two slashes
if (/^[\\\/]{2}/.test(joined) && !/^[\\\/]{2}/.test(paths[0])) {
joined = joined.slice(1);
}

return exports.normalize(joined);
};

// path.relative(from, to)
// it will solve the relative path from 'from' to 'to', for instance:
// from = 'C:\\orandea\\test\\aaa'
// to = 'C:\\orandea\\impl\\bbb'
// The output of the function should be: '..\\..\\impl\\bbb'
// windows version
exports.relative = function(from, to) {
from = exports.resolve(from);
to = exports.resolve(to);

// windows is not case sensitive


var lowerFrom = from.toLowerCase();
var lowerTo = to.toLowerCase();

function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}

var end = arr.length - 1;


for (; end >= 0; end--) {
if (arr[end] !== '') break;
}

if (start > end) return [];


return arr.slice(start, end - start + 1);
}

var toParts = trim(to.split('\\'));

var lowerFromParts = trim(lowerFrom.split('\\'));


var lowerToParts = trim(lowerTo.split('\\'));

var length = Math.min(lowerFromParts.length, lowerToParts.length);


var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (lowerFromParts[i] !== lowerToParts[i]) {
samePartsLength = i;
break;
}
}

if (samePartsLength == 0) {
return to;
}

var outputParts = [];


for (var i = samePartsLength; i < lowerFromParts.length; i++) {
outputParts.push('..');
}

outputParts = outputParts.concat(toParts.slice(samePartsLength));

return outputParts.join('\\');
};

exports.sep = '\\';

} else /* posix */ {

// Split a filename into [root, dir, basename, ext], unix version


// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?)([\s\S]+\/(?!$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
var splitPath = function(filename) {
var result = splitPathRe.exec(filename);
return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
};

// path.resolve([from ...], to)


// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;

for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {


var path = (i >= 0) ? arguments[i] : process.cwd();

// Skip empty and invalid entries


if (typeof path !== 'string' || !path) {
continue;
}

resolvedPath = path + '/' + resolvedPath;


resolvedAbsolute = path.charAt(0) === '/';
}

// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)

// Normalize the path


resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
return !!p;
}), !resolvedAbsolute).join('/');

return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';


};

// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';

// Normalize the path


path = normalizeArray(path.split('/').filter(function(p) {
return !!p;
}), !isAbsolute).join('/');

if (!path && !isAbsolute) {


path = '.';
}
if (path && trailingSlash) {
path += '/';
}

return (isAbsolute ? '/' : '') + path;


};

// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(paths.filter(function(p, index) {
return p && typeof p === 'string';
}).join('/'));
};

// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);

function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}

var end = arr.length - 1;


for (; end >= 0; end--) {
if (arr[end] !== '') break;
}

if (start > end) return [];


return arr.slice(start, end - start + 1);
}

var fromParts = trim(from.split('/'));


var toParts = trim(to.split('/'));

var length = Math.min(fromParts.length, toParts.length);


var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}

var outputParts = [];


for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}

outputParts = outputParts.concat(toParts.slice(samePartsLength));

return outputParts.join('/');
};

exports.sep = '/';
}

exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];

if (!root && !dir) {


// No dirname whatsoever
return '.';
}

if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substring(0, dir.length - 1);
}

return root + dir;


};

exports.basename = function(path, ext) {


var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};

exports.extname = function(path) {
return splitPath(path)[3];
};

exports.exists = util.deprecate(function(path, callback) {


require('fs').exists(path, callback);
}, 'path.exists is now called `fs.exists`.');
exports.existsSync = util.deprecate(function(path) {
return require('fs').existsSync(path);
}, 'path.existsSync is now called `fs.existsSync`.');

if (isWindows) {
exports._makeLong = function(path) {
path = '' + path;
if (!path) {
return '';
}

var resolvedPath = exports.resolve(path);

if (resolvedPath.match(/^[a-zA-Z]\:\\/)) {
// path is local filesystem path, which needs to be converted
// to long UNC path.
return '\\\\?\\' + resolvedPath;
} else if (resolvedPath.match(/^\\\\[^?.]/)) {
// path is network UNC path, which needs to be converted
// to long UNC path.
return '\\\\?\\UNC\\' + resolvedPath.substring(2);
}

return path;
};
} else {
exports._makeLong = function(path) {
return path;
};
}
#####/*! http://mths.be/punycode by @mathias */
;(function(root) {

/**
* The `punycode` object.
* @name punycode
* @type Object
*/
var punycode,

/** Detect free variables `define`, `exports`, `module` and `require` */


freeDefine = typeof define == 'function' && typeof define.amd == 'object' &&
define.amd && define,
freeExports = typeof exports == 'object' && exports,
freeModule = typeof module == 'object' && module,
freeRequire = typeof require == 'function' && require,

/** Highest positive signed 32-bit float value */


maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1

/** Bootstring parameters */


base = 36,
tMin = 1,
tMax = 26,
skew = 38,
damp = 700,
initialBias = 72,
initialN = 128, // 0x80
delimiter = '-', // '\x2D'

/** Regular expressions */


regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
regexPunycode = /^xn--/,

/** Error messages */


errors = {
'overflow': 'Overflow: input needs wider integers to process.',
'ucs2decode': 'UCS-2(decode): illegal sequence',
'ucs2encode': 'UCS-2(encode): illegal value',
'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
'invalid-input': 'Invalid input'
},

/** Convenience shortcuts */


baseMinusTMin = base - tMin,
floor = Math.floor,
stringFromCharCode = String.fromCharCode,

/** Temporary variable */


key;

/*--------------------------------------------------------------------------
*/

/**
* A generic error utility function.
* @private
* @param {String} type The error type.
* @returns {Error} Throws a `RangeError` with the applicable error message.
*/
function error(type) {
throw RangeError(errors[type]);
}

/**
* A generic `Array#map` utility function.
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function that gets called for every array
* item.
* @returns {Array} A new array of values returned by the callback function.
*/
function map(array, fn) {
var length = array.length;
while (length--) {
array[length] = fn(array[length]);
}
return array;
}

/**
* A simple `Array#map`-like wrapper to work with domain name strings.
* @private
* @param {String} domain The domain name.
* @param {Function} callback The function that gets called for every
* character.
* @returns {Array} A new string of characters returned by the callback
* function.
*/
function mapDomain(string, fn) {
var glue = '.';
return map(string.split(glue), fn).join(glue);
}

/**
* Creates an array containing the decimal code points of each Unicode
* character in the string. While JavaScript uses UCS-2 internally,
* this function will convert a pair of surrogate halves (each of which
* UCS-2 exposes as separate characters) into a single code point,
* matching UTF-16.
* @see `punycode.ucs2.encode`
* @see <http://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode.ucs2
* @name decode
* @param {String} string The Unicode input string (UCS-2).
* @returns {Array} The new array of code points.
*/
function ucs2decode(string) {
var output = [],
counter = 0,
length = string.length,
value,
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if ((value & 0xF800) == 0xD800) {
extra = string.charCodeAt(counter++);
if ((value & 0xFC00) != 0xD800 || (extra & 0xFC00) !=
0xDC00) {
error('ucs2decode');
}
value = ((value & 0x3FF) << 10) + (extra & 0x3FF) +
0x10000;
}
output.push(value);
}
return output;
}

/**
* Creates a string based on an array of decimal code points.
* @see `punycode.ucs2.decode`
* @memberOf punycode.ucs2
* @name encode
* @param {Array} codePoints The array of decimal code points.
* @returns {String} The new Unicode string (UCS-2).
*/
function ucs2encode(array) {
return map(array, function(value) {
var output = '';
if ((value & 0xF800) == 0xD800) {
error('ucs2encode');
}
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF |
0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
return output;
}).join('');
}

/**
* Converts a basic code point into a digit/integer.
* @see `digitToBasic()`
* @private
* @param {Number} codePoint The basic (decimal) code point.
* @returns {Number} The numeric value of a basic code point (for use in
* representing integers) in the range `0` to `base - 1`, or `base` if
* the code point does not represent a value.
*/
function basicToDigit(codePoint) {
return codePoint - 48 < 10
? codePoint - 22
: codePoint - 65 < 26
? codePoint - 65
: codePoint - 97 < 26
? codePoint - 97
: base;
}

/**
* Converts a digit/integer into a basic code point.
* @see `basicToDigit()`
* @private
* @param {Number} digit The numeric value of a basic code point.
* @returns {Number} The basic code point whose value (when used for
* representing integers) is `digit`, which needs to be in the range
* `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
* used; else, the lowercase form is used. The behavior is undefined
* if flag is non-zero and `digit` has no uppercase form.
*/
function digitToBasic(digit, flag) {
// 0..25 map to ASCII a..z or A..Z
// 26..35 map to ASCII 0..9
return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
}

/**
* Bias adaptation function as per section 3.4 of RFC 3492.
* http://tools.ietf.org/html/rfc3492#section-3.4
* @private
*/
function adapt(delta, numPoints, firstTime) {
var k = 0;
delta = firstTime ? floor(delta / damp) : delta >> 1;
delta += floor(delta / numPoints);
for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k +=
base) {
delta = floor(delta / baseMinusTMin);
}
return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
}

/**
* Converts a basic code point to lowercase is `flag` is falsy, or to
* uppercase if `flag` is truthy. The code point is unchanged if it's
* caseless. The behavior is undefined if `codePoint` is not a basic code
* point.
* @private
* @param {Number} codePoint The numeric value of a basic code point.
* @returns {Number} The resulting basic code point.
*/
function encodeBasic(codePoint, flag) {
codePoint -= (codePoint - 97 < 26) << 5;
return codePoint + (!flag && codePoint - 65 < 26) << 5;
}

/**
* Converts a Punycode string of ASCII code points to a string of Unicode
* code points.
* @memberOf punycode
* @param {String} input The Punycode string of ASCII code points.
* @returns {String} The resulting string of Unicode code points.
*/
function decode(input) {
// Don't use UCS-2
var output = [],
inputLength = input.length,
out,
i = 0,
n = initialN,
bias = initialBias,
basic,
j,
index,
oldi,
w,
k,
digit,
t,
length,
/** Cached calculation results */
baseMinusT;

// Handle the basic code points: let `basic` be the number of input
code
// points before the last delimiter, or `0` if there is none, then copy
// the first basic code points to the output.

basic = input.lastIndexOf(delimiter);
if (basic < 0) {
basic = 0;
}

for (j = 0; j < basic; ++j) {


// if it's not a basic code point
if (input.charCodeAt(j) >= 0x80) {
error('not-basic');
}
output.push(input.charCodeAt(j));
}

// Main decoding loop: start just after the last delimiter if any basic
code
// points were copied; start at the beginning otherwise.

for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no


final expression */) {

// `index` is the index of the next character to be consumed.


// Decode a generalized variable-length integer into `delta`,
// which gets added to `i`. The overflow checking is easier
// if we increase `i` as we go, then subtract off its starting
// value at the end to obtain `delta`.
for (oldi = i, w = 1, k = base; /* no condition */; k += base) {

if (index >= inputLength) {


error('invalid-input');
}

digit = basicToDigit(input.charCodeAt(index++));

if (digit >= base || digit > floor((maxInt - i) / w)) {


error('overflow');
}

i += digit * w;
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k -
bias);

if (digit < t) {
break;
}

baseMinusT = base - t;
if (w > floor(maxInt / baseMinusT)) {
error('overflow');
}

w *= baseMinusT;

out = output.length + 1;
bias = adapt(i - oldi, out, oldi == 0);

// `i` was supposed to wrap around from `out` to `0`,


// incrementing `n` each time, so we'll fix that now:
if (floor(i / out) > maxInt - n) {
error('overflow');
}

n += floor(i / out);
i %= out;

// Insert `n` at position `i` of the output


output.splice(i++, 0, n);

}
return ucs2encode(output);
}

/**
* Converts a string of Unicode code points to a Punycode string of ASCII
* code points.
* @memberOf punycode
* @param {String} input The string of Unicode code points.
* @returns {String} The resulting Punycode string of ASCII code points.
*/
function encode(input) {
var n,
delta,
handledCPCount,
basicLength,
bias,
j,
m,
q,
k,
t,
currentValue,
output = [],
/** `inputLength` will hold the number of code points in `input`.
*/
inputLength,
/** Cached calculation results */
handledCPCountPlusOne,
baseMinusT,
qMinusT;

// Convert the input in UCS-2 to Unicode


input = ucs2decode(input);

// Cache the length


inputLength = input.length;

// Initialize the state


n = initialN;
delta = 0;
bias = initialBias;

// Handle the basic code points


for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < 0x80) {
output.push(stringFromCharCode(currentValue));
}
}

handledCPCount = basicLength = output.length;

// `handledCPCount` is the number of code points that have been


handled;
// `basicLength` is the number of basic code points.

// Finish the basic string - if it is not empty - with a delimiter


if (basicLength) {
output.push(delimiter);
}

// Main encoding loop:


while (handledCPCount < inputLength) {

// All non-basic code points < n have been handled already. Find
the next
// larger one:
for (m = maxInt, j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue >= n && currentValue < m) {
m = currentValue;
}
}

// Increase `delta` enough to advance the decoder's <n,i> state


to <m,0>,
// but guard against overflow
handledCPCountPlusOne = handledCPCount + 1;
if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
error('overflow');
}

delta += (m - n) * handledCPCountPlusOne;
n = m;

for (j = 0; j < inputLength; ++j) {


currentValue = input[j];

if (currentValue < n && ++delta > maxInt) {


error('overflow');
}

if (currentValue == n) {
// Represent delta as a generalized variable-length
integer
for (q = delta, k = base; /* no condition */; k +=
base) {
t = k <= bias ? tMin : (k >= bias + tMax ? tMax
: k - bias);
if (q < t) {
break;
}
qMinusT = q - t;
baseMinusT = base - t;
output.push(
stringFromCharCode(digitToBasic(t +
qMinusT % baseMinusT, 0))
);
q = floor(qMinusT / baseMinusT);
}

output.push(stringFromCharCode(digitToBasic(q, 0)));
bias = adapt(delta, handledCPCountPlusOne,
handledCPCount == basicLength);
delta = 0;
++handledCPCount;
}
}

++delta;
++n;

}
return output.join('');
}

/**
* Converts a Punycode string representing a domain name to Unicode. Only the
* Punycoded parts of the domain name will be converted, i.e. it doesn't
* matter if you call it on a string that has already been converted to
* Unicode.
* @memberOf punycode
* @param {String} domain The Punycode domain name to convert to Unicode.
* @returns {String} The Unicode representation of the given Punycode
* string.
*/
function toUnicode(domain) {
return mapDomain(domain, function(string) {
return regexPunycode.test(string)
? decode(string.slice(4).toLowerCase())
: string;
});
}

/**
* Converts a Unicode string representing a domain name to Punycode. Only the
* non-ASCII parts of the domain name will be converted, i.e. it doesn't
* matter if you call it with a domain that's already in ASCII.
* @memberOf punycode
* @param {String} domain The domain name to convert, as a Unicode string.
* @returns {String} The Punycode representation of the given domain name.
*/
function toASCII(domain) {
return mapDomain(domain, function(string) {
return regexNonASCII.test(string)
? 'xn--' + encode(string)
: string;
});
}

/*--------------------------------------------------------------------------
*/

/** Define the public API */


punycode = {
/**
* A string representing the current Punycode.js version number.
* @memberOf punycode
* @type String
*/
'version': '1.0.0',
/**
* An object of methods to convert from JavaScript's internal character
* representation (UCS-2) to decimal Unicode code points, and back.
* @see <http://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode
* @type Object
*/
'ucs2': {
'decode': ucs2decode,
'encode': ucs2encode
},
'decode': decode,
'encode': encode,
'toASCII': toASCII,
'toUnicode': toUnicode
};

/** Expose `punycode` */


if (freeExports) {
if (freeModule && freeModule.exports == freeExports) {
// in Node.js or Ringo 0.8+
freeModule.exports = punycode;
} else {
// in Narwhal or Ringo 0.7-
for (key in punycode) {
punycode.hasOwnProperty(key) && (freeExports[key] =
punycode[key]);
}
}
} else if (freeDefine) {
// via curl.js or RequireJS
define('punycode', punycode);
} else {
// in a browser or Rhino
root.punycode = punycode;
}

}(this));
########// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// Query String Utilities

var QueryString = exports;


var urlDecode = process.binding('http_parser').urlDecode;
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}

function charCode(c) {
return c.charCodeAt(0);
}

// a safe fast alternative to decodeURIComponent


QueryString.unescapeBuffer = function(s, decodeSpaces) {
var out = new Buffer(s.length);
var state = 'CHAR'; // states: CHAR, HEX0, HEX1
var n, m, hexchar;

for (var inIndex = 0, outIndex = 0; inIndex <= s.length; inIndex++) {


var c = s.charCodeAt(inIndex);
switch (state) {
case 'CHAR':
switch (c) {
case charCode('%'):
n = 0;
m = 0;
state = 'HEX0';
break;
case charCode('+'):
if (decodeSpaces) c = charCode(' ');
// pass thru
default:
out[outIndex++] = c;
break;
}
break;

case 'HEX0':
state = 'HEX1';
hexchar = c;
if (charCode('0') <= c && c <= charCode('9')) {
n = c - charCode('0');
} else if (charCode('a') <= c && c <= charCode('f')) {
n = c - charCode('a') + 10;
} else if (charCode('A') <= c && c <= charCode('F')) {
n = c - charCode('A') + 10;
} else {
out[outIndex++] = charCode('%');
out[outIndex++] = c;
state = 'CHAR';
break;
}
break;

case 'HEX1':
state = 'CHAR';
if (charCode('0') <= c && c <= charCode('9')) {
m = c - charCode('0');
} else if (charCode('a') <= c && c <= charCode('f')) {
m = c - charCode('a') + 10;
} else if (charCode('A') <= c && c <= charCode('F')) {
m = c - charCode('A') + 10;
} else {
out[outIndex++] = charCode('%');
out[outIndex++] = hexchar;
out[outIndex++] = c;
break;
}
out[outIndex++] = 16 * n + m;
break;
}
}

// TODO support returning arbitrary buffers.

return out.slice(0, outIndex - 1);


};

QueryString.unescape = function(s, decodeSpaces) {


return QueryString.unescapeBuffer(s, decodeSpaces).toString();
};

QueryString.escape = function(str) {
return encodeURIComponent(str);
};

var stringifyPrimitive = function(v) {


switch (typeof v) {
case 'string':
return v;

case 'boolean':
return v ? 'true' : 'false';

case 'number':
return isFinite(v) ? v : '';

default:
return '';
}
};

QueryString.stringify = QueryString.encode = function(obj, sep, eq, name) {


sep = sep || '&';
eq = eq || '=';
if (obj === null) {
obj = undefined;
}

if (typeof obj === 'object') {


return Object.keys(obj).map(function(k) {
var ks = QueryString.escape(stringifyPrimitive(k)) + eq;
if (Array.isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + QueryString.escape(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + QueryString.escape(stringifyPrimitive(obj[k]));
}
}).join(sep);

if (!name) return '';


return QueryString.escape(stringifyPrimitive(name)) + eq +
QueryString.escape(stringifyPrimitive(obj));
};

// Parse a key=val string.


QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {
sep = sep || '&';
eq = eq || '=';
var obj = {};

if (typeof qs !== 'string' || qs.length === 0) {


return obj;
}

var regexp = /\+/g;


qs = qs.split(sep);

var maxKeys = 1000;


if (options && typeof options.maxKeys === 'number') {
maxKeys = options.maxKeys;
}

var len = qs.length;


// maxKeys <= 0 means that we should not limit keys count
if (maxKeys > 0 && len > maxKeys) {
len = maxKeys;
}

for (var i = 0; i < len; ++i) {


var x = qs[i].replace(regexp, '%20'),
idx = x.indexOf(eq),
kstr, vstr, k, v;

if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}

try {
k = decodeURIComponent(kstr);
v = decodeURIComponent(vstr);
} catch (e) {
k = QueryString.unescape(kstr, true);
v = QueryString.unescape(vstr, true);
}
if (!hasOwnProperty(obj, k)) {
obj[k] = v;
} else if (Array.isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}

return obj;
};
##// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// Inspiration for this code comes from Salvatore Sanfilippo's linenoise.


// https://github.com/antirez/linenoise
// Reference:
// * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
// * http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html

var kHistorySize = 30;


var kBufSize = 10 * 1024;

var util = require('util');


var inherits = require('util').inherits;
var EventEmitter = require('events').EventEmitter;

exports.createInterface = function(input, output, completer, terminal) {


var rl;
if (arguments.length === 1) {
rl = new Interface(input);
} else {
rl = new Interface(input, output, completer, terminal);
}
return rl;
};

function Interface(input, output, completer, terminal) {


if (!(this instanceof Interface)) {
return new Interface(input, output, completer, terminal);
}

EventEmitter.call(this);

if (arguments.length === 1) {
// an options object was given
output = input.output;
completer = input.completer;
terminal = input.terminal;
input = input.input;
}

completer = completer || function() { return []; };

if (typeof completer !== 'function') {


throw new TypeError('Argument \'completer\' must be a function');
}

// backwards compat; check the isTTY prop of the output stream


// when `terminal` was not specified
if (typeof terminal == 'undefined') {
terminal = !!output.isTTY;
}

var self = this;

this.output = output;
this.input = input;

// Check arity, 2 - for async, 1 for sync


this.completer = completer.length === 2 ? completer : function(v, callback) {
callback(null, completer(v));
};

this.setPrompt('> ');

this.terminal = !!terminal;

function ondata(data) {
self._normalWrite(data);
}

function onend() {
self.close();
}

function onkeypress(s, key) {


self._ttyWrite(s, key);
}

function onresize() {
self._refreshLine();
}

if (!this.terminal) {
input.on('data', ondata);
input.on('end', onend);
self.once('close', function() {
input.removeListener('data', ondata);
input.removeListener('end', onend);
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');

} else {

exports.emitKeypressEvents(input);

// input usually refers to stdin


input.on('keypress', onkeypress);

// Current line
this.line = '';

this._setRawMode(true);
this.terminal = true;

// Cursor position on the line.


this.cursor = 0;

this.history = [];
this.historyIndex = -1;

output.on('resize', onresize);
self.once('close', function() {
input.removeListener('keypress', onkeypress);
output.removeListener('resize', onresize);
});
}

input.resume();
}

inherits(Interface, EventEmitter);

Interface.prototype.__defineGetter__('columns', function() {
return this.output.columns || Infinity;
});

Interface.prototype.setPrompt = function(prompt, length) {


this._prompt = prompt;
if (length) {
this._promptLength = length;
} else {
var lines = prompt.split(/[\r\n]/);
var lastLine = lines[lines.length - 1];
this._promptLength = lastLine.length;
}
};

Interface.prototype._setRawMode = function(mode) {
if (typeof this.input.setRawMode === 'function') {
return this.input.setRawMode(mode);
}
};
Interface.prototype.prompt = function(preserveCursor) {
if (this.paused) this.resume();
if (this.terminal) {
if (!preserveCursor) this.cursor = 0;
this._refreshLine();
} else {
this.output.write(this._prompt);
}
};

Interface.prototype.question = function(query, cb) {


if (typeof cb === 'function') {
if (this._questionCallback) {
this.prompt();
} else {
this._oldPrompt = this._prompt;
this.setPrompt(query);
this._questionCallback = cb;
this.prompt();
}
}
};

Interface.prototype._onLine = function(line) {
if (this._questionCallback) {
var cb = this._questionCallback;
this._questionCallback = null;
this.setPrompt(this._oldPrompt);
cb(line);
} else {
this.emit('line', line);
}
};

Interface.prototype._addHistory = function() {
if (this.line.length === 0) return '';

this.history.unshift(this.line);
this.historyIndex = -1;

// Only store so many


if (this.history.length > kHistorySize) this.history.pop();

return this.history[0];
};

Interface.prototype._refreshLine = function() {
var columns = this.columns;

// line length
var line = this._prompt + this.line;
var lineLength = line.length;
var lineCols = lineLength % columns;
var lineRows = (lineLength - lineCols) / columns;

// cursor position
var cursorPos = this._getCursorPos();

// first move to the bottom of the current line, based on cursor pos
var prevRows = this.prevRows || 0;
if (prevRows > 0) {
exports.moveCursor(this.output, 0, -prevRows);
}

// Cursor to left edge.


exports.cursorTo(this.output, 0);
// erase data
exports.clearScreenDown(this.output);

// Write the prompt and the current buffer content.


this.output.write(line);

// Force terminal to allocate a new line


if (lineCols === 0) {
this.output.write(' ');
}

// Move cursor to original position.


exports.cursorTo(this.output, cursorPos.cols);

var diff = lineRows - cursorPos.rows;


if (diff > 0) {
exports.moveCursor(this.output, 0, -diff);
}

this.prevRows = cursorPos.rows;
};

Interface.prototype.close = function() {
if (this.closed) return;
if (this.terminal) {
this._setRawMode(false);
}
this.pause();
this.closed = true;
this.emit('close');
};

Interface.prototype.pause = function() {
if (this.paused) return;
this.input.pause();
this.paused = true;
this.emit('pause');
};

Interface.prototype.resume = function() {
if (!this.paused) return;
this.input.resume();
this.paused = false;
this.emit('resume');
};

Interface.prototype.write = function(d, key) {


if (this.paused) this.resume();
this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d);
};

Interface.prototype._normalWrite = function(b) {
if (b === undefined) {
return;
}
var string = this._decoder.write(b);
if (this._line_buffer) {
string = this._line_buffer + string;
this._line_buffer = null;
}
if (string.indexOf('\n') !== -1) {
// got one or more newlines; process into "line" events
var lines = string.split('\n');
// either '' or (concievably) the unfinished portion of the next line
string = lines.pop();
this._line_buffer = string;
lines.forEach(function(line) {
this._onLine(line + '\n');
}, this);
} else if (string) {
// no newlines this time, save what we have for next time
this._line_buffer = string;
}
};

Interface.prototype._insertString = function(c) {
//BUG: Problem when adding tabs with following content.
// Perhaps the bug is in _refreshLine(). Not sure.
// A hack would be to insert spaces instead of literal '\t'.
if (this.cursor < this.line.length) {
var beg = this.line.slice(0, this.cursor);
var end = this.line.slice(this.cursor, this.line.length);
this.line = beg + c + end;
this.cursor += c.length;
this._refreshLine();
} else {
this.line += c;
this.cursor += c.length;

if (this._getCursorPos().cols === 0) {
this._refreshLine();
} else {
this.output.write(c);
}

// a hack to get the line refreshed if it's needed


this._moveCursor(0);
}
};

Interface.prototype._tabComplete = function() {
var self = this;

self.pause();
self.completer(self.line.slice(0, self.cursor), function(err, rv) {
self.resume();

if (err) {
// XXX Log it somewhere?
return;
}

var completions = rv[0],


completeOn = rv[1]; // the text that was completed
if (completions && completions.length) {
// Apply/show completions.
if (completions.length === 1) {
self._insertString(completions[0].slice(completeOn.length));
} else {
self.output.write('\r\n');
var width = completions.reduce(function(a, b) {
return a.length > b.length ? a : b;
}).length + 2; // 2 space padding
var maxColumns = Math.floor(self.columns / width) || 1;
var group = [], c;
for (var i = 0, compLen = completions.length; i < compLen; i++) {
c = completions[i];
if (c === '') {
handleGroup(self, group, width, maxColumns);
group = [];
} else {
group.push(c);
}
}
handleGroup(self, group, width, maxColumns);

// If there is a common prefix to all matches, then apply that


// portion.
var f = completions.filter(function(e) { if (e) return e; });
var prefix = commonPrefix(f);
if (prefix.length > completeOn.length) {
self._insertString(prefix.slice(completeOn.length));
}

}
self._refreshLine();
}
});
};

// this = Interface instance


function handleGroup(self, group, width, maxColumns) {
if (group.length == 0) {
return;
}
var minRows = Math.ceil(group.length / maxColumns);
for (var row = 0; row < minRows; row++) {
for (var col = 0; col < maxColumns; col++) {
var idx = row * maxColumns + col;
if (idx >= group.length) {
break;
}
var item = group[idx];
self.output.write(item);
if (col < maxColumns - 1) {
for (var s = 0, itemLen = item.length; s < width - itemLen;
s++) {
self.output.write(' ');
}
}
}
self.output.write('\r\n');
}
self.output.write('\r\n');
}

function commonPrefix(strings) {
if (!strings || strings.length == 0) {
return '';
}
var sorted = strings.slice().sort();
var min = sorted[0];
var max = sorted[sorted.length - 1];
for (var i = 0, len = min.length; i < len; i++) {
if (min[i] != max[i]) {
return min.slice(0, i);
}
}
return min;
}

Interface.prototype._wordLeft = function() {
if (this.cursor > 0) {
var leading = this.line.slice(0, this.cursor);
var match = leading.match(/([^\w\s]+|\w+|)\s*$/);
this._moveCursor(-match[0].length);
}
};

Interface.prototype._wordRight = function() {
if (this.cursor < this.line.length) {
var trailing = this.line.slice(this.cursor);
var match = trailing.match(/^(\s+|\W+|\w+)\s*/);
this._moveCursor(match[0].length);
}
};

Interface.prototype._deleteLeft = function() {
if (this.cursor > 0 && this.line.length > 0) {
this.line = this.line.slice(0, this.cursor - 1) +
this.line.slice(this.cursor, this.line.length);

this.cursor--;
this._refreshLine();
}
};
Interface.prototype._deleteRight = function() {
this.line = this.line.slice(0, this.cursor) +
this.line.slice(this.cursor + 1, this.line.length);
this._refreshLine();
};

Interface.prototype._deleteWordLeft = function() {
if (this.cursor > 0) {
var leading = this.line.slice(0, this.cursor);
var match = leading.match(/([^\w\s]+|\w+|)\s*$/);
leading = leading.slice(0, leading.length - match[0].length);
this.line = leading + this.line.slice(this.cursor, this.line.length);
this.cursor = leading.length;
this._refreshLine();
}
};

Interface.prototype._deleteWordRight = function() {
if (this.cursor < this.line.length) {
var trailing = this.line.slice(this.cursor);
var match = trailing.match(/^(\s+|\W+|\w+)\s*/);
this.line = this.line.slice(0, this.cursor) +
trailing.slice(match[0].length);
this._refreshLine();
}
};

Interface.prototype._deleteLineLeft = function() {
this.line = this.line.slice(this.cursor);
this.cursor = 0;
this._refreshLine();
};

Interface.prototype._deleteLineRight = function() {
this.line = this.line.slice(0, this.cursor);
this._refreshLine();
};

Interface.prototype.clearLine = function() {
this._moveCursor(+Infinity);
this.output.write('\r\n');
this.line = '';
this.cursor = 0;
this.prevRows = 0;
};

Interface.prototype._line = function() {
var line = this._addHistory();
this.clearLine();
this._onLine(line);
};
Interface.prototype._historyNext = function() {
if (this.historyIndex > 0) {
this.historyIndex--;
this.line = this.history[this.historyIndex];
this.cursor = this.line.length; // set cursor to end of line.
this._refreshLine();

} else if (this.historyIndex === 0) {


this.historyIndex = -1;
this.cursor = 0;
this.line = '';
this._refreshLine();
}
};

Interface.prototype._historyPrev = function() {
if (this.historyIndex + 1 < this.history.length) {
this.historyIndex++;
this.line = this.history[this.historyIndex];
this.cursor = this.line.length; // set cursor to end of line.

this._refreshLine();
}
};

// Returns current cursor's position and line


Interface.prototype._getCursorPos = function() {
var columns = this.columns;
var cursorPos = this.cursor + this._promptLength;
var cols = cursorPos % columns;
var rows = (cursorPos - cols) / columns;
return {cols: cols, rows: rows};
};

// This function moves cursor dx places to the right


// (-dx for left) and refreshes the line if it is needed
Interface.prototype._moveCursor = function(dx) {
var oldcursor = this.cursor;
var oldPos = this._getCursorPos();
this.cursor += dx;

// bounds check
if (this.cursor < 0) this.cursor = 0;
if (this.cursor > this.line.length) this.cursor = this.line.length;

var newPos = this._getCursorPos();

// check if cursors are in the same line


if (oldPos.rows === newPos.rows) {
exports.moveCursor(this.output, this.cursor - oldcursor, 0);
this.prevRows = newPos.rows;
} else {
this._refreshLine();
}
};

// handle a write from the tty


Interface.prototype._ttyWrite = function(s, key) {
key = key || {};

// Ignore escape key - Fixes #2876


if (key.name == 'escape') return;

if (key.ctrl && key.shift) {


/* Control and shift pressed */
switch (key.name) {
case 'backspace':
this._deleteLineLeft();
break;

case 'delete':
this._deleteLineRight();
break;
}

} else if (key.ctrl) {
/* Control key pressed */

switch (key.name) {
case 'c':
if (this.listeners('SIGINT').length) {
this.emit('SIGINT');
} else {
// This readline instance is finished
this.close();
}
break;

case 'h': // delete left


this._deleteLeft();
break;

case 'd': // delete right or EOF


if (this.cursor === 0 && this.line.length === 0) {
// This readline instance is finished
this.close();
} else if (this.cursor < this.line.length) {
this._deleteRight();
}
break;

case 'u': // delete the whole line


this.cursor = 0;
this.line = '';
this._refreshLine();
break;

case 'k': // delete from current to end of line


this._deleteLineRight();
break;

case 'a': // go to the start of the line


this._moveCursor(-Infinity);
break;

case 'e': // go to the end of the line


this._moveCursor(+Infinity);
break;

case 'b': // back one character


this._moveCursor(-1);
break;

case 'f': // forward one character


this._moveCursor(+1);
break;

case 'n': // next history item


this._historyNext();
break;

case 'p': // previous history item


this._historyPrev();
break;

case 'z':
if (process.platform == 'win32') break;
if (this.listeners('SIGTSTP').length) {
this.emit('SIGTSTP');
} else {
process.once('SIGCONT', (function(self) {
return function() {
// Don't raise events if stream has already been abandoned.
if (!self.paused) {
// Stream must be paused and resumed after SIGCONT to catch
// SIGINT, SIGTSTP, and EOF.
self.pause();
self.emit('SIGCONT');
}
// explictly re-enable "raw mode" and move the cursor to
// the correct position.
// See https://github.com/joyent/node/issues/3295.
self._setRawMode(true);
self._refreshLine();
};
})(this));
this._setRawMode(false);
process.kill(process.pid, 'SIGTSTP');
}
break;

case 'w': // delete backwards to a word boundary


case 'backspace':
this._deleteWordLeft();
break;

case 'delete': // delete forward to a word boundary


this._deleteWordRight();
break;

case 'backspace':
this._deleteWordLeft();
break;

case 'left':
this._wordLeft();
break;

case 'right':
this._wordRight();
break;
}

} else if (key.meta) {
/* Meta key pressed */

switch (key.name) {
case 'b': // backward word
this._wordLeft();
break;

case 'f': // forward word


this._wordRight();
break;

case 'd': // delete forward word


case 'delete':
this._deleteWordRight();
break;

case 'backspace': // delete backwards to a word boundary


this._deleteWordLeft();
break;
}

} else {
/* No modifier keys used */

switch (key.name) {
case 'enter':
this._line();
break;

case 'backspace':
this._deleteLeft();
break;

case 'delete':
this._deleteRight();
break;

case 'tab': // tab completion


this._tabComplete();
break;

case 'left':
this._moveCursor(-1);
break;

case 'right':
this._moveCursor(+1);
break;

case 'home':
this._moveCursor(-Infinity);
break;

case 'end':
this._moveCursor(+Infinity);
break;

case 'up':
this._historyPrev();
break;

case 'down':
this._historyNext();
break;

default:
if (Buffer.isBuffer(s))
s = s.toString('utf-8');

if (s) {
var lines = s.split(/\r\n|\n|\r/);
for (var i = 0, len = lines.length; i < len; i++) {
if (i > 0) {
this._line();
}
this._insertString(lines[i]);
}
}
}
}
};

exports.Interface = Interface;

/**
* accepts a readable Stream instance and makes it emit "keypress" events
*/

function emitKeypressEvents(stream) {
if (stream._emitKeypress) return;
stream._emitKeypress = true;

function onData(b) {
if (stream.listeners('keypress').length > 0) {
emitKey(stream, b);
} else {
// Nobody's watching anyway
stream.removeListener('data', onData);
stream.on('newListener', onNewListener);
}
}
function onNewListener(event) {
if (event == 'keypress') {
stream.on('data', onData);
stream.removeListener('newListener', onNewListener);
}
}

if (stream.listeners('keypress').length > 0) {
stream.on('data', onData);
} else {
stream.on('newListener', onNewListener);
}
}
exports.emitKeypressEvents = emitKeypressEvents;

/*
Some patterns seen in terminal key escape codes, derived from combos seen
at http://www.midnight-commander.org/browser/lib/tty/key.c

ESC letter
ESC [ letter
ESC [ modifier letter
ESC [ 1 ; modifier letter
ESC [ num char
ESC [ num ; modifier char
ESC O letter
ESC O modifier letter
ESC O 1 ; modifier letter
ESC N letter
ESC [ [ num ; modifier char
ESC [ [ 1 ; modifier letter
ESC ESC [ num char
ESC ESC O letter

- char is usually ~ but $ and ^ also happen with rxvt


- modifier is 1 +
(shift * 1) +
(left_alt * 2) +
(ctrl * 4) +
(right_alt * 8)
- two leading ESCs apparently mean the same as one leading ESC
*/

// Regexes used for ansi escape code splitting


var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
var functionKeyCodeRe =
/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;

function emitKey(stream, s) {
var ch,
key = {
name: undefined,
ctrl: false,
meta: false,
shift: false
},
parts;

if (Buffer.isBuffer(s)) {
if (s[0] > 127 && s[1] === undefined) {
s[0] -= 128;
s = '\x1b' + s.toString(stream.encoding || 'utf-8');
} else {
s = s.toString(stream.encoding || 'utf-8');
}
}

key.sequence = s;

if (s === '\r' || s === '\n') {


// enter
key.name = 'enter';

} else if (s === '\t') {


// tab
key.name = 'tab';

} else if (s === '\b' || s === '\x7f' ||


s === '\x1b\x7f' || s === '\x1b\b') {
// backspace or ctrl+h
key.name = 'backspace';
key.meta = (s.charAt(0) === '\x1b');

} else if (s === '\x1b' || s === '\x1b\x1b') {


// escape key
key.name = 'escape';
key.meta = (s.length === 2);

} else if (s === ' ' || s === '\x1b ') {


key.name = 'space';
key.meta = (s.length === 2);

} else if (s <= '\x1a') {


// ctrl+letter
key.name = String.fromCharCode(s.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
key.ctrl = true;

} else if (s.length === 1 && s >= 'a' && s <= 'z') {


// lowercase letter
key.name = s;

} else if (s.length === 1 && s >= 'A' && s <= 'Z') {


// shift+letter
key.name = s.toLowerCase();
key.shift = true;

} else if (parts = metaKeyCodeRe.exec(s)) {


// meta+character key
key.name = parts[1].toLowerCase();
key.meta = true;
key.shift = /^[A-Z]$/.test(parts[1]);

} else if (parts = functionKeyCodeRe.exec(s)) {


// ansi escape sequence

// reassemble the key code leaving out leading \x1b's,


// the modifier key bitflag and any meaningless "1;" sequence
var code = (parts[1] || '') + (parts[2] || '') +
(parts[4] || '') + (parts[6] || ''),
modifier = (parts[3] || parts[5] || 1) - 1;

// Parse the key modifier


key.ctrl = !!(modifier & 4);
key.meta = !!(modifier & 10);
key.shift = !!(modifier & 1);
key.code = code;

// Parse the key itself


switch (code) {
/* xterm/gnome ESC O letter */
case 'OP': key.name = 'f1'; break;
case 'OQ': key.name = 'f2'; break;
case 'OR': key.name = 'f3'; break;
case 'OS': key.name = 'f4'; break;

/* xterm/rxvt ESC [ number ~ */


case '[11~': key.name = 'f1'; break;
case '[12~': key.name = 'f2'; break;
case '[13~': key.name = 'f3'; break;
case '[14~': key.name = 'f4'; break;

/* from Cygwin and used in libuv */


case '[[A': key.name = 'f1'; break;
case '[[B': key.name = 'f2'; break;
case '[[C': key.name = 'f3'; break;
case '[[D': key.name = 'f4'; break;
case '[[E': key.name = 'f5'; break;

/* common */
case '[15~': key.name = 'f5'; break;
case '[17~': key.name = 'f6'; break;
case '[18~': key.name = 'f7'; break;
case '[19~': key.name = 'f8'; break;
case '[20~': key.name = 'f9'; break;
case '[21~': key.name = 'f10'; break;
case '[23~': key.name = 'f11'; break;
case '[24~': key.name = 'f12'; break;

/* xterm ESC [ letter */


case '[A': key.name = 'up'; break;
case '[B': key.name = 'down'; break;
case '[C': key.name = 'right'; break;
case '[D': key.name = 'left'; break;
case '[E': key.name = 'clear'; break;
case '[F': key.name = 'end'; break;
case '[H': key.name = 'home'; break;

/* xterm/gnome ESC O letter */


case 'OA': key.name = 'up'; break;
case 'OB': key.name = 'down'; break;
case 'OC': key.name = 'right'; break;
case 'OD': key.name = 'left'; break;
case 'OE': key.name = 'clear'; break;
case 'OF': key.name = 'end'; break;
case 'OH': key.name = 'home'; break;

/* xterm/rxvt ESC [ number ~ */


case '[1~': key.name = 'home'; break;
case '[2~': key.name = 'insert'; break;
case '[3~': key.name = 'delete'; break;
case '[4~': key.name = 'end'; break;
case '[5~': key.name = 'pageup'; break;
case '[6~': key.name = 'pagedown'; break;

/* putty */
case '[[5~': key.name = 'pageup'; break;
case '[[6~': key.name = 'pagedown'; break;

/* rxvt */
case '[7~': key.name = 'home'; break;
case '[8~': key.name = 'end'; break;

/* rxvt keys with modifiers */


case '[a': key.name = 'up'; key.shift = true; break;
case '[b': key.name = 'down'; key.shift = true; break;
case '[c': key.name = 'right'; key.shift = true; break;
case '[d': key.name = 'left'; key.shift = true; break;
case '[e': key.name = 'clear'; key.shift = true; break;

case '[2$': key.name = 'insert'; key.shift = true; break;


case '[3$': key.name = 'delete'; key.shift = true; break;
case '[5$': key.name = 'pageup'; key.shift = true; break;
case '[6$': key.name = 'pagedown'; key.shift = true; break;
case '[7$': key.name = 'home'; key.shift = true; break;
case '[8$': key.name = 'end'; key.shift = true; break;

case 'Oa': key.name = 'up'; key.ctrl = true; break;


case 'Ob': key.name = 'down'; key.ctrl = true; break;
case 'Oc': key.name = 'right'; key.ctrl = true; break;
case 'Od': key.name = 'left'; key.ctrl = true; break;
case 'Oe': key.name = 'clear'; key.ctrl = true; break;

case '[2^': key.name = 'insert'; key.ctrl = true; break;


case '[3^': key.name = 'delete'; key.ctrl = true; break;
case '[5^': key.name = 'pageup'; key.ctrl = true; break;
case '[6^': key.name = 'pagedown'; key.ctrl = true; break;
case '[7^': key.name = 'home'; key.ctrl = true; break;
case '[8^': key.name = 'end'; key.ctrl = true; break;

/* misc. */
case '[Z': key.name = 'tab'; key.shift = true; break;
default: key.name = 'undefined'; break;

}
} else if (s.length > 1 && s[0] !== '\x1b') {
// Got a longer-than-one string of characters.
// Probably a paste, since it wasn't a control sequence.
Array.prototype.forEach.call(s, function(c) {
emitKey(stream, c);
});
return;
}

// Don't emit a key if no name was found


if (key.name === undefined) {
key = undefined;
}

if (s.length === 1) {
ch = s;
}

if (key || ch) {
stream.emit('keypress', ch, key);
}
}

/**
* moves the cursor to the x and y coordinate on the given stream
*/

function cursorTo(stream, x, y) {
if (typeof x !== 'number' && typeof y !== 'number')
return;

if (typeof x !== 'number')


throw new Error("Can't set cursor row without also setting it's column");

if (typeof y !== 'number') {


stream.write('\x1b[' + (x + 1) + 'G');
} else {
stream.write('\x1b[' + (y + 1) + ';' + (x + 1) + 'H');
}
}
exports.cursorTo = cursorTo;

/**
* moves the cursor relative to its current location
*/

function moveCursor(stream, dx, dy) {


if (dx < 0) {
stream.write('\x1b[' + (-dx) + 'D');
} else if (dx > 0) {
stream.write('\x1b[' + dx + 'C');
}

if (dy < 0) {
stream.write('\x1b[' + (-dy) + 'A');
} else if (dy > 0) {
stream.write('\x1b[' + dy + 'B');
}
}
exports.moveCursor = moveCursor;

/**
* clears the current line the cursor is on:
* -1 for left of the cursor
* +1 for right of the cursor
* 0 for the entire line
*/
function clearLine(stream, dir) {
if (dir < 0) {
// to the beginning
stream.write('\x1b[1K');
} else if (dir > 0) {
// to the end
stream.write('\x1b[0K');
} else {
// entire line
stream.write('\x1b[2K');
}
}
exports.clearLine = clearLine;

/**
* clears the screen from the current position of the cursor down
*/

function clearScreenDown(stream) {
stream.write('\x1b[0J');
}
exports.clearScreenDown = clearScreenDown;
####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

/* A repl library that you can include in your own code to get a runtime
* interface to your program.
*
* var repl = require("/repl.js");
* // start repl on stdin
* repl.start("prompt> ");
*
* // listen for unix socket connections and start repl on them
* net.createServer(function(socket) {
* repl.start("node via Unix socket> ", socket);
* }).listen("/tmp/node-repl-sock");
*
* // listen for TCP socket connections and start repl on them
* net.createServer(function(socket) {
* repl.start("node via TCP socket> ", socket);
* }).listen(5001);
*
* // expose foo to repl context
* repl.start("node > ").context.foo = "stdin is fun";
*/

var util = require('util');


var inherits = require('util').inherits;
var Stream = require('stream');
var vm = require('vm');
var path = require('path');
var fs = require('fs');
var rl = require('readline');
var EventEmitter = require('events').EventEmitter;

// If obj.hasOwnProperty has been overridden, then calling


// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}

// hack for require.resolve("./relative") to work properly.


module.filename = path.resolve('repl');

// hack for repl require to work properly with node_modules folders


module.paths = require('module')._nodeModulePaths(module.filename);

// Can overridden with custom print functions, such as `probe` or `eyes.js`.


// This is the default "writer" value if none is passed in the REPL options.
exports.writer = util.inspect;

exports._builtinLibs = ['assert', 'buffer', 'child_process', 'cluster',


'crypto', 'dgram', 'dns', 'events', 'fs', 'http', 'https', 'net',
'os', 'path', 'punycode', 'querystring', 'readline', 'repl',
'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib'];

function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {


if (!(this instanceof REPLServer)) {
return new REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined);
}

EventEmitter.call(this);

var options, input, output;


if (typeof prompt == 'object') {
// an options object was given
options = prompt;
stream = options.stream || options.socket;
input = options.input;
output = options.output;
eval_ = options.eval;
useGlobal = options.useGlobal;
ignoreUndefined = options.ignoreUndefined;
prompt = options.prompt;
} else if (typeof prompt != 'string') {
throw new Error('An options Object, or a prompt String are required');
} else {
options = {};
}

var self = this;

self.useGlobal = !!useGlobal;
self.ignoreUndefined = !!ignoreUndefined;

self.eval = eval_ || function(code, context, file, cb) {


var err, result;
try {
if (self.useGlobal) {
result = vm.runInThisContext(code, file);
} else {
result = vm.runInContext(code, context, file);
}
} catch (e) {
err = e;
}
cb(err, result);
};

self.resetContext();
self.bufferedCommand = '';

if (!input && !output) {


// legacy API, passing a 'stream'/'socket' option
if (!stream) {
// use stdin and stdout as the default streams if none were given
stream = process;
}
if (stream.stdin && stream.stdout) {
// We're given custom object with 2 streams, or the `process` object
input = stream.stdin;
output = stream.stdout;
} else {
// We're given a duplex readable/writable Stream, like a `net.Socket`
input = stream;
output = stream;
}
}

self.inputStream = input;
self.outputStream = output;

self.prompt = (prompt != undefined ? prompt : '> ');

function complete(text, callback) {


self.complete(text, callback);
}

var rli = rl.createInterface({


input: self.inputStream,
output: self.outputStream,
completer: complete,
terminal: options.terminal
});
self.rli = rli;

this.commands = {};
defineDefaultCommands(this);

// figure out which "writer" function to use


self.writer = options.writer || exports.writer;

if (typeof options.useColors === 'undefined') {


options.useColors = rli.terminal;
}
self.useColors = !!options.useColors;

if (self.useColors && self.writer === util.inspect) {


// Turn on ANSI coloring.
self.writer = function(obj, showHidden, depth) {
return util.inspect(obj, showHidden, depth, true);
};
}

rli.setPrompt(self.prompt);

rli.on('close', function() {
self.emit('exit');
});

var sawSIGINT = false;


rli.on('SIGINT', function() {
var empty = rli.line.length === 0;
rli.clearLine();

if (!(self.bufferedCommand && self.bufferedCommand.length > 0) && empty) {


if (sawSIGINT) {
rli.close();
sawSIGINT = false;
return;
}
rli.output.write('(^C again to quit)\n');
sawSIGINT = true;
} else {
sawSIGINT = false;
}

self.bufferedCommand = '';
self.displayPrompt();
});

rli.on('line', function(cmd) {
sawSIGINT = false;
var skipCatchall = false;
cmd = trimWhitespace(cmd);

// Check to see if a REPL keyword was used. If it returns true,


// display next prompt and return.
if (cmd && cmd.charAt(0) === '.') {
var matches = cmd.match(/^(\.[^\s]+)\s*(.*)$/);
var keyword = matches && matches[1];
var rest = matches && matches[2];
if (self.parseREPLKeyword(keyword, rest) === true) {
return;
} else {
self.outputStream.write('Invalid REPL keyword\n');
skipCatchall = true;
}
}

// Check if a builtin module name was used and then include it


// if there's no conflict.
if (exports._builtinLibs.indexOf(cmd) !== -1) {
var lib = require(cmd);
if (cmd in self.context && lib !== self.context[cmd]) {
self.outputStream.write('A different "' + cmd +
'" already exists globally\n');
} else {
self.context._ = self.context[cmd] = lib;
self.outputStream.write(self.writer(lib) + '\n');
}
self.displayPrompt();
return;
}

if (!skipCatchall) {
var evalCmd = self.bufferedCommand + cmd + '\n';

// This try is for determining if the command is complete, or should


// continue onto the next line.
// We try to evaluate both expressions e.g.
// '{ a : 1 }'
// and statements e.g.
// 'for (var i = 0; i < 10; i++) console.log(i);'

// First we attempt to eval as expression with parens.


// This catches '{a : 1}' properly.
self.eval('(' + evalCmd + ')',
self.context,
'repl',
function(e, ret) {
if (e && !isSyntaxError(e)) return finish(e);

if (typeof ret === 'function' &&


/^[\r\n\s]*function/.test(evalCmd) ||
e) {
// Now as statement without parens.
self.eval(evalCmd, self.context, 'repl', finish);
} else {
finish(null, ret);
}
});

} else {
finish(null);
}

function finish(e, ret) {

self.memory(cmd);

// If error was SyntaxError and not JSON.parse error


if (isSyntaxError(e)) {
if (!self.bufferedCommand && cmd.trim().match(/^npm /)) {
self.outputStream.write('npm should be run outside of the ' +
'node repl, in your normal shell.\n' +
'(Press Control-D to exit.)\n');
self.bufferedCmd = '';
self.displayPrompt();
return;
}

// Start buffering data like that:


// {
// ... x: 1
// ... }
self.bufferedCommand += cmd + '\n';
self.displayPrompt();
return;
} else if (e) {
self.outputStream.write((e.stack || e) + '\n');
}

// Clear buffer if no SyntaxErrors


self.bufferedCommand = '';

// If we got any output - print it (if no error)


if (!e && (!self.ignoreUndefined || ret !== undefined)) {
self.context._ = ret;
self.outputStream.write(self.writer(ret) + '\n');
}

// Display prompt again


self.displayPrompt();
};
});

rli.on('SIGCONT', function() {
self.displayPrompt(true);
});

self.displayPrompt();
}
inherits(REPLServer, EventEmitter);
exports.REPLServer = REPLServer;

// prompt is a string to print on each line for the prompt,


// source is a stream to use for I/O, defaulting to stdin/stdout.
exports.start = function(prompt, source, eval_, useGlobal, ignoreUndefined) {
var repl = new REPLServer(prompt, source, eval_, useGlobal, ignoreUndefined);
if (!exports.repl) exports.repl = repl;
return repl;
};

REPLServer.prototype.createContext = function() {
var context;
if (this.useGlobal) {
context = global;
} else {
context = vm.createContext();
for (var i in global) context[i] = global[i];
}

context.module = module;
context.require = require;
context.global = context;
context.global.global = context;

this.lines = [];
this.lines.level = [];

return context;
};

REPLServer.prototype.resetContext = function() {
for (var i in require.cache) delete require.cache[i];
this.context = this.createContext();
};

REPLServer.prototype.displayPrompt = function(preserveCursor) {
var prompt = this.prompt;
if (this.bufferedCommand.length) {
prompt = '...';
var levelInd = new Array(this.lines.level.length).join('..');
prompt += levelInd + ' ';
}
this.rli.setPrompt(prompt);
this.rli.prompt(preserveCursor);
};

// A stream to push an array into a REPL


// used in REPLServer.complete
function ArrayStream() {
Stream.call(this);

this.run = function(data) {
var self = this;
data.forEach(function(line) {
self.emit('data', line + '\n');
});
}
}
util.inherits(ArrayStream, Stream);
ArrayStream.prototype.readable = true;
ArrayStream.prototype.writable = true;
ArrayStream.prototype.resume = function() {};
ArrayStream.prototype.write = function() {};

var requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/;


var simpleExpressionRE =
/(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/;

// Provide a list of completions for the given leading text. This is


// given to the readline interface for handling tab completion.
//
// Example:
// complete('var foo = util.')
// -> [['util.print', 'util.debug', 'util.log', 'util.inspect', 'util.pump'],
// 'util.' ]
//
// Warning: This eval's code like "foo.bar.baz", so it will run property
// getter code.
REPLServer.prototype.complete = function(line, callback) {
// There may be local variables to evaluate, try a nested REPL
if (this.bufferedCommand != undefined && this.bufferedCommand.length) {
// Get a new array of inputed lines
var tmp = this.lines.slice();
// Kill off all function declarations to push all local variables into
// global scope
this.lines.level.forEach(function(kill) {
if (kill.isFunction) {
tmp[kill.line] = '';
}
});
var flat = new ArrayStream(); // make a new "input" stream
var magic = new REPLServer('', flat); // make a nested REPL
magic.context = magic.createContext();
flat.run(tmp); // eval the flattened code
// all this is only profitable if the nested REPL
// does not have a bufferedCommand
if (!magic.bufferedCommand) {
return magic.complete(line, callback);
}
}

var completions;

// list of completion lists, one for each inheritance "level"


var completionGroups = [];

var completeOn, match, filter, i, j, group, c;

// REPL commands (e.g. ".break").


var match = null;
match = line.match(/^\s*(\.\w*)$/);
if (match) {
completionGroups.push(Object.keys(this.commands));
completeOn = match[1];
if (match[1].length > 1) {
filter = match[1];
}

completionGroupsLoaded();
} else if (match = line.match(requireRE)) {
// require('...<Tab>')
//TODO: suggest require.exts be exposed to be introspec registered
//extensions?
//TODO: suggest include the '.' in exts in internal repr: parity with
//`path.extname`.
var exts = ['.js', '.node'];
var indexRe = new RegExp('^index(' + exts.map(regexpEscape).join('|') +
')$');

completeOn = match[1];
var subdir = match[2] || '';
var filter = match[1];
var dir, files, f, name, base, ext, abs, subfiles, s;
group = [];
var paths = module.paths.concat(require('module').globalPaths);
for (i = 0; i < paths.length; i++) {
dir = path.resolve(paths[i], subdir);
try {
files = fs.readdirSync(dir);
} catch (e) {
continue;
}
for (f = 0; f < files.length; f++) {
name = files[f];
ext = path.extname(name);
base = name.slice(0, -ext.length);
if (base.match(/-\d+\.\d+(\.\d+)?/) || name === '.npm') {
// Exclude versioned names that 'npm' installs.
continue;
}
if (exts.indexOf(ext) !== -1) {
if (!subdir || base !== 'index') {
group.push(subdir + base);
}
} else {
abs = path.resolve(dir, name);
try {
if (fs.statSync(abs).isDirectory()) {
group.push(subdir + name + '/');
subfiles = fs.readdirSync(abs);
for (s = 0; s < subfiles.length; s++) {
if (indexRe.test(subfiles[s])) {
group.push(subdir + name);
}
}
}
} catch (e) {}
}
}
}
if (group.length) {
completionGroups.push(group);
}

if (!subdir) {
completionGroups.push(exports._builtinLibs);
}

completionGroupsLoaded();

// Handle variable member lookup.


// We support simple chained expressions like the following (no function
// calls, etc.). That is for simplicity and also because we *eval* that
// leading expression so for safety (see WARNING above) don't want to
// eval function calls.
//
// foo.bar<|> # completions for 'foo' with filter 'bar'
// spam.eggs.<|> # completions for 'spam.eggs' with filter ''
// foo<|> # all scope vars with filter 'foo'
// foo.<|> # completions for 'foo' with filter ''
} else if (line.length === 0 || line[line.length - 1].match(/\w|\.|\$/)) {
match = simpleExpressionRE.exec(line);
if (line.length === 0 || match) {
var expr;
completeOn = (match ? match[0] : '');
if (line.length === 0) {
filter = '';
expr = '';
} else if (line[line.length - 1] === '.') {
filter = '';
expr = match[0].slice(0, match[0].length - 1);
} else {
var bits = match[0].split('.');
filter = bits.pop();
expr = bits.join('.');
}

// Resolve expr and get its completions.


var obj, memberGroups = [];
if (!expr) {
// If context is instance of vm.ScriptContext
// Get global vars synchronously
if (this.useGlobal ||
this.context.constructor &&
this.context.constructor.name === 'Context') {
var contextProto = this.context;
while (contextProto = Object.getPrototypeOf(contextProto)) {
completionGroups.push(Object.getOwnPropertyNames(contextProto));
}
completionGroups.push(Object.getOwnPropertyNames(this.context));
addStandardGlobals(completionGroups, filter);
completionGroupsLoaded();
} else {
this.eval('.scope', this.context, 'repl', function(err, globals) {
if (err || !globals) {
addStandardGlobals(completionGroups, filter);
} else if (Array.isArray(globals[0])) {
// Add grouped globals
globals.forEach(function(group) {
completionGroups.push(group);
});
} else {
completionGroups.push(globals);
addStandardGlobals(completionGroups, filter);
}
completionGroupsLoaded();
});
}
} else {
this.eval(expr, this.context, 'repl', function(e, obj) {
// if (e) console.log(e);

if (obj != null) {
if (typeof obj === 'object' || typeof obj === 'function') {
memberGroups.push(Object.getOwnPropertyNames(obj));
}
// works for non-objects
try {
var sentinel = 5;
var p;
if (typeof obj === 'object' || typeof obj === 'function') {
p = Object.getPrototypeOf(obj);
} else {
p = obj.constructor ? obj.constructor.prototype : null;
}
while (p !== null) {
memberGroups.push(Object.getOwnPropertyNames(p));
p = Object.getPrototypeOf(p);
// Circular refs possible? Let's guard against that.
sentinel--;
if (sentinel <= 0) {
break;
}
}
} catch (e) {
//console.log("completion error walking prototype chain:" + e);
}
}

if (memberGroups.length) {
for (i = 0; i < memberGroups.length; i++) {
completionGroups.push(memberGroups[i].map(function(member) {
return expr + '.' + member;
}));
}
if (filter) {
filter = expr + '.' + filter;
}
}

completionGroupsLoaded();
});
}
} else {
completionGroupsLoaded();
}
} else {
completionGroupsLoaded();
}

// Will be called when all completionGroups are in place


// Useful for async autocompletion
function completionGroupsLoaded(err) {
if (err) throw err;

// Filter, sort (within each group), uniq and merge the completion groups.
if (completionGroups.length && filter) {
var newCompletionGroups = [];
for (i = 0; i < completionGroups.length; i++) {
group = completionGroups[i].filter(function(elem) {
return elem.indexOf(filter) == 0;
});
if (group.length) {
newCompletionGroups.push(group);
}
}
completionGroups = newCompletionGroups;
}
if (completionGroups.length) {
var uniq = {}; // unique completions across all groups
completions = [];
// Completion group 0 is the "closest"
// (least far up the inheritance chain)
// so we put its completions last: to be closest in the REPL.
for (i = completionGroups.length - 1; i >= 0; i--) {
group = completionGroups[i];
group.sort();
for (var j = 0; j < group.length; j++) {
c = group[j];
if (!hasOwnProperty(c)) {
completions.push(c);
uniq[c] = true;
}
}
completions.push(''); // separator btwn groups
}
while (completions.length && completions[completions.length - 1] === '') {
completions.pop();
}
}

callback(null, [completions || [], completeOn]);


}
};

/**
* Used to parse and execute the Node REPL commands.
*
* @param {keyword} keyword The command entered to check.
* @return {Boolean} If true it means don't continue parsing the command.
*/
REPLServer.prototype.parseREPLKeyword = function(keyword, rest) {
var cmd = this.commands[keyword];
if (cmd) {
cmd.action.call(this, rest);
return true;
}
return false;
};

REPLServer.prototype.defineCommand = function(keyword, cmd) {


if (typeof cmd === 'function') {
cmd = {action: cmd};
} else if (typeof cmd.action !== 'function') {
throw new Error('bad argument, action must be a function');
}
this.commands['.' + keyword] = cmd;
};

REPLServer.prototype.memory = function memory(cmd) {


var self = this;

self.lines = self.lines || [];


self.lines.level = self.lines.level || [];
// save the line so I can do magic later
if (cmd) {
// TODO should I tab the level?
self.lines.push(new Array(self.lines.level.length).join(' ') + cmd);
} else {
// I don't want to not change the format too much...
self.lines.push('');
}

// I need to know "depth."


// Because I can not tell the difference between a } that
// closes an object literal and a } that closes a function
if (cmd) {
// going down is { and ( e.g. function() {
// going up is } and )
var dw = cmd.match(/{|\(/g);
var up = cmd.match(/}|\)/g);
up = up ? up.length : 0;
dw = dw ? dw.length : 0;
var depth = dw - up;

if (depth) {
(function workIt() {
if (depth > 0) {
// going... down.
// push the line#, depth count, and if the line is a function.
// Since JS only has functional scope I only need to remove
// "function() {" lines, clearly this will not work for
// "function()
// {" but nothing should break, only tab completion for local
// scope will not work for this function.
self.lines.level.push({
line: self.lines.length - 1,
depth: depth,
isFunction: /\s*function\s*/.test(cmd)
});
} else if (depth < 0) {
// going... up.
var curr = self.lines.level.pop();
if (curr) {
var tmp = curr.depth + depth;
if (tmp < 0) {
//more to go, recurse
depth += curr.depth;
workIt();
} else if (tmp > 0) {
//remove and push back
curr.depth += depth;
self.lines.level.push(curr);
}
}
}
}());
}

// it is possible to determine a syntax error at this point.


// if the REPL still has a bufferedCommand and
// self.lines.level.length === 0
// TODO? keep a log of level so that any syntax breaking lines can
// be cleared on .break and in the case of a syntax error?
// TODO? if a log was kept, then I could clear the bufferedComand and
// eval these lines and throw the syntax error
} else {
self.lines.level = [];
}
};

function addStandardGlobals(completionGroups, filter) {


// Global object properties
// (http://www.ecma-international.org/publications/standards/Ecma-262.htm)
completionGroups.push(['NaN', 'Infinity', 'undefined',
'eval', 'parseInt', 'parseFloat', 'isNaN', 'isFinite', 'decodeURI',
'decodeURIComponent', 'encodeURI', 'encodeURIComponent',
'Object', 'Function', 'Array', 'String', 'Boolean', 'Number',
'Date', 'RegExp', 'Error', 'EvalError', 'RangeError',
'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
'Math', 'JSON']);
// Common keywords. Exclude for completion on the empty string, b/c
// they just get in the way.
if (filter) {
completionGroups.push(['break', 'case', 'catch', 'const',
'continue', 'debugger', 'default', 'delete', 'do', 'else',
'export', 'false', 'finally', 'for', 'function', 'if',
'import', 'in', 'instanceof', 'let', 'new', 'null', 'return',
'switch', 'this', 'throw', 'true', 'try', 'typeof', 'undefined',
'var', 'void', 'while', 'with', 'yield']);
}
}

function defineDefaultCommands(repl) {
// TODO remove me after 0.3.x
repl.defineCommand('break', {
help: 'Sometimes you get stuck, this gets you out',
action: function() {
this.bufferedCommand = '';
this.displayPrompt();
}
});

var clearMessage;
if (repl.useGlobal) {
clearMessage = 'Alias for .break';
} else {
clearMessage = 'Break, and also clear the local context';
}
repl.defineCommand('clear', {
help: clearMessage,
action: function() {
this.bufferedCommand = '';
if (!this.useGlobal) {
this.outputStream.write('Clearing context...\n');
this.resetContext();
}
this.displayPrompt();
}
});
repl.defineCommand('exit', {
help: 'Exit the repl',
action: function() {
this.rli.close();
}
});

repl.defineCommand('help', {
help: 'Show repl options',
action: function() {
var self = this;
Object.keys(this.commands).sort().forEach(function(name) {
var cmd = self.commands[name];
self.outputStream.write(name + '\t' + (cmd.help || '') + '\n');
});
this.displayPrompt();
}
});

repl.defineCommand('save', {
help: 'Save all evaluated commands in this REPL session to a file',
action: function(file) {
try {
fs.writeFileSync(file, this.lines.join('\n') + '\n');
this.outputStream.write('Session saved to:' + file + '\n');
} catch (e) {
this.outputStream.write('Failed to save:' + file + '\n');
}
this.displayPrompt();
}
});

repl.defineCommand('load', {
help: 'Load JS from a file into the REPL session',
action: function(file) {
try {
var stats = fs.statSync(file);
if (stats && stats.isFile()) {
var self = this;
var data = fs.readFileSync(file, 'utf8');
var lines = data.split('\n');
this.displayPrompt();
lines.forEach(function(line) {
if (line) {
self.rli.write(line + '\n');
}
});
}
} catch (e) {
this.outputStream.write('Failed to load:' + file + '\n');
}
this.displayPrompt();
}
});
}

function trimWhitespace(cmd) {
var trimmer = /^\s*(.+)\s*$/m,
matches = trimmer.exec(cmd);

if (matches && matches.length === 2) {


return matches[1];
}
return '';
}

function regexpEscape(s) {
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

/**
* Converts commands that use var and function <name>() to use the
* local exports.context when evaled. This provides a local context
* on the REPL.
*
* @param {String} cmd The cmd to convert.
* @return {String} The converted command.
*/
REPLServer.prototype.convertToContext = function(cmd) {
var self = this, matches,
scopeVar = /^\s*var\s*([_\w\$]+)(.*)$/m,
scopeFunc = /^\s*function\s*([_\w\$]+)/;

// Replaces: var foo = "bar"; with: self.context.foo = bar;


matches = scopeVar.exec(cmd);
if (matches && matches.length === 3) {
return 'self.context.' + matches[1] + matches[2];
}

// Replaces: function foo() {}; with: foo = function foo() {};


matches = scopeFunc.exec(self.bufferedCommand);
if (matches && matches.length === 2) {
return matches[1] + ' = ' + self.bufferedCommand;
}

return cmd;
};

/**
* Returns `true` if "e" is a SyntaxError, `false` otherwise.
* This function filters out false positives likes JSON.parse() errors and
* RegExp syntax errors.
*/
function isSyntaxError(e) {
// Convert error to string
e = e && (e.stack || e.toString());
return e && e.match(/^SyntaxError/) &&
// RegExp syntax error
!e.match(/^SyntaxError: Invalid regular expression/) &&
!e.match(/^SyntaxError: Invalid flags supplied to RegExp constructor/) &&
// JSON.parse() error
!(e.match(/^SyntaxError: Unexpected (token .*|end of input)/) &&
e.match(/\n at Object.parse \(native\)\n/));
}
######// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var events = require('events');


var util = require('util');

function Stream() {
events.EventEmitter.call(this);
}
util.inherits(Stream, events.EventEmitter);
module.exports = Stream;
// Backwards-compat with node 0.4.x
Stream.Stream = Stream;

Stream.prototype.pipe = function(dest, options) {


var source = this;

function ondata(chunk) {
if (dest.writable) {
if (false === dest.write(chunk) && source.pause) {
source.pause();
}
}
}

source.on('data', ondata);

function ondrain() {
if (source.readable && source.resume) {
source.resume();
}
}

dest.on('drain', ondrain);

// If the 'end' option is not supplied, dest.end() will be called when


// source gets the 'end' or 'close' events. Only dest.end() once.
if (!dest._isStdio && (!options || options.end !== false)) {
source.on('end', onend);
source.on('close', onclose);
}
var didOnEnd = false;
function onend() {
if (didOnEnd) return;
didOnEnd = true;

dest.end();
}

function onclose() {
if (didOnEnd) return;
didOnEnd = true;

if (typeof dest.destroy === 'function') dest.destroy();


}

// don't leave dangling pipes when there are errors.


function onerror(er) {
cleanup();
if (this.listeners('error').length === 0) {
throw er; // Unhandled stream error in pipe.
}
}

source.on('error', onerror);
dest.on('error', onerror);

// remove all the event listeners that were added.


function cleanup() {
source.removeListener('data', ondata);
dest.removeListener('drain', ondrain);

source.removeListener('end', onend);
source.removeListener('close', onclose);

source.removeListener('error', onerror);
dest.removeListener('error', onerror);

source.removeListener('end', cleanup);
source.removeListener('close', cleanup);

dest.removeListener('end', cleanup);
dest.removeListener('close', cleanup);
}

source.on('end', cleanup);
source.on('close', cleanup);

dest.on('end', cleanup);
dest.on('close', cleanup);

dest.emit('pipe', source);

// Allow for unix-like usage: A.pipe(B).pipe(C)


return dest;
};
########// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var StringDecoder = exports.StringDecoder = function(encoding) {


this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
switch (this.encoding) {
case 'utf8':
// CESU-8 represents each of Surrogate Pair by 3-bytes
this.surrogateSize = 3;
break;
case 'ucs2':
case 'utf16le':
// UTF-16 represents each of Surrogate Pair by 2-bytes
this.surrogateSize = 2;
this.detectIncompleteChar = utf16DetectIncompleteChar;
break;
default:
this.write = passThroughWrite;
return;
}

this.charBuffer = new Buffer(6);


this.charReceived = 0;
this.charLength = 0;
};

StringDecoder.prototype.write = function(buffer) {
var charStr = '';
var offset = 0;

// if our last write ended with an incomplete multibyte character


while (this.charLength) {
// determine how many remaining bytes this buffer has to offer for this char
var i = (buffer.length >= this.charLength - this.charReceived) ?
this.charLength - this.charReceived :
buffer.length;

// add the new bytes to the char buffer


buffer.copy(this.charBuffer, this.charReceived, offset, i);
this.charReceived += (i - offset);
offset = i;
if (this.charReceived < this.charLength) {
// still not enough chars in this buffer? wait for more ...
return '';
}

// get the character that was split


charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);

// lead surrogate (D800-DBFF) is also the incomplete character


var charCode = charStr.charCodeAt(charStr.length - 1);
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
this.charLength += this.surrogateSize;
charStr = '';
continue;
}
this.charReceived = this.charLength = 0;

// if there are no more bytes in this buffer, just emit our char
if (i == buffer.length) return charStr;

// otherwise cut off the characters end from the beginning of this buffer
buffer = buffer.slice(i, buffer.length);
break;
}

var lenIncomplete = this.detectIncompleteChar(buffer);

var end = buffer.length;


if (this.charLength) {
// buffer the incomplete character bytes we got
buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end);
this.charReceived = lenIncomplete;
end -= lenIncomplete;
}

charStr += buffer.toString(this.encoding, 0, end);

var end = charStr.length - 1;


var charCode = charStr.charCodeAt(end);
// lead surrogate (D800-DBFF) is also the incomplete character
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
var size = this.surrogateSize;
this.charLength += size;
this.charReceived += size;
this.charBuffer.copy(this.charBuffer, size, 0, size);
this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding);
return charStr.substring(0, end);
}

// or just emit the charStr


return charStr;
};

StringDecoder.prototype.detectIncompleteChar = function(buffer) {
// determine how many bytes we have to check at the end of this buffer
var i = (buffer.length >= 3) ? 3 : buffer.length;

// Figure out if one of the last i bytes of our buffer announces an


// incomplete char.
for (; i > 0; i--) {
var c = buffer[buffer.length - i];

// See http://en.wikipedia.org/wiki/UTF-8#Description

// 110XXXXX
if (i == 1 && c >> 5 == 0x06) {
this.charLength = 2;
break;
}

// 1110XXXX
if (i <= 2 && c >> 4 == 0x0E) {
this.charLength = 3;
break;
}

// 11110XXX
if (i <= 3 && c >> 3 == 0x1E) {
this.charLength = 4;
break;
}
}

return i;
};

function passThroughWrite(buffer) {
return buffer.toString(this.encoding);
}

function utf16DetectIncompleteChar(buffer) {
var incomplete = this.charReceived = buffer.length % 2;
this.charLength = incomplete ? 2 : 0;
return incomplete;
}
########// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// the sys module was renamed to 'util'.


// this shim remains to keep old programs working.
module.exports = require('util');
####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var Timer = process.binding('timer_wrap').Timer;


var L = require('_linklist');
var assert = require('assert').ok;

// Timeout values > TIMEOUT_MAX are set to 1.


var TIMEOUT_MAX = 2147483647; // 2^31-1

var debug;
if (process.env.NODE_DEBUG && /timer/.test(process.env.NODE_DEBUG)) {
debug = function() { require('util').error.apply(this, arguments); };
} else {
debug = function() { };
}

// IDLE TIMEOUTS
//
// Because often many sockets will have the same idle timeout we will not
// use one timeout watcher per item. It is too much overhead. Instead
// we'll use a single watcher for all sockets with the same timeout value
// and a linked list. This technique is described in the libev manual:
// http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Be_smart_about_timeouts

// Object containing all lists, timers


// key = time in milliseconds
// value = list
var lists = {};

// the main function - creates lists on demand and the watchers associated
// with them.
function insert(item, msecs) {
item._idleStart = new Date();
item._idleTimeout = msecs;

if (msecs < 0) return;


var list;

if (lists[msecs]) {
list = lists[msecs];
} else {
list = new Timer();
list.start(msecs, 0);

L.init(list);

lists[msecs] = list;

list.ontimeout = function() {
debug('timeout callback ' + msecs);

var now = new Date();


debug('now: ' + now);

var first;
while (first = L.peek(list)) {
var diff = now - first._idleStart;
if (diff + 1 < msecs) {
list.start(msecs - diff, 0);
debug(msecs + ' list wait because diff is ' + diff);
return;
} else {
L.remove(first);
assert(first !== L.peek(list));

if (!first._onTimeout) continue;

// v0.4 compatibility: if the timer callback throws and the user's


// uncaughtException handler ignores the exception, other timers that
// expire on this tick should still run. If #2582 goes through, this
// hack should be removed.
//
// https://github.com/joyent/node/issues/2631
if (first.domain) {
if (first.domain._disposed) continue;
first.domain.enter();
}
try {
first._onTimeout();
} catch (e) {
if (!process.listeners('uncaughtException').length) throw e;
process.emit('uncaughtException', e);
}
if (first.domain) first.domain.exit();
}
}

debug(msecs + ' list empty');


assert(L.isEmpty(list));
list.close();
delete lists[msecs];
};
}

L.append(list, item);
assert(!L.isEmpty(list)); // list is not empty
}

var unenroll = exports.unenroll = function(item) {


L.remove(item);

var list = lists[item._idleTimeout];


// if empty then stop the watcher
debug('unenroll');
if (list && L.isEmpty(list)) {
debug('unenroll: list empty');
list.close();
delete lists[item._idleTimeout];
}
// if active is called later, then we want to make sure not to insert again
item._idleTimeout = -1;
};

// Does not start the time, just sets up the members needed.
exports.enroll = function(item, msecs) {
// if this item was already in a list somewhere
// then we should unenroll it from that
if (item._idleNext) unenroll(item);

item._idleTimeout = msecs;
L.init(item);
};

// call this whenever the item is active (not idle)


// it will reset its timeout.
exports.active = function(item) {
var msecs = item._idleTimeout;
if (msecs >= 0) {
var list = lists[msecs];
if (!list || L.isEmpty(list)) {
insert(item, msecs);
} else {
item._idleStart = new Date();
L.append(list, item);
}
}
};

/*
* DOM-style timers
*/

exports.setTimeout = function(callback, after) {


var timer;

after *= 1; // coalesce to number or NaN

if (!(after >= 1 && after <= TIMEOUT_MAX)) {


after = 1; // schedule on next tick, follows browser behaviour
}

timer = { _idleTimeout: after };


timer._idlePrev = timer;
timer._idleNext = timer;

if (arguments.length <= 2) {
timer._onTimeout = callback;
} else {
/*
* Sometimes setTimeout is called with arguments, EG
*
* setTimeout(callback, 2000, "hello", "world")
*
* If that's the case we need to call the callback with
* those args. The overhead of an extra closure is not
* desired in the normal case.
*/
var args = Array.prototype.slice.call(arguments, 2);
timer._onTimeout = function() {
callback.apply(timer, args);
}
}

if (process.domain) timer.domain = process.domain;

exports.active(timer);

return timer;
};

exports.clearTimeout = function(timer) {
if (timer && (timer.ontimeout || timer._onTimeout)) {
timer.ontimeout = timer._onTimeout = null;
if (timer instanceof Timer) {
timer.close(); // for after === 0
} else {
exports.unenroll(timer);
}
}
};

exports.setInterval = function(callback, repeat) {


var timer = new Timer();

if (process.domain) timer.domain = process.domain;

repeat *= 1; // coalesce to number or NaN

if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) {


repeat = 1; // schedule on next tick, follows browser behaviour
}

var args = Array.prototype.slice.call(arguments, 2);


timer.ontimeout = function() {
callback.apply(timer, args);
}
timer.start(repeat, repeat);
return timer;
};

exports.clearInterval = function(timer) {
if (timer instanceof Timer) {
timer.ontimeout = null;
timer.close();
}
};
####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var crypto = require('crypto');


var util = require('util');
var net = require('net');
var url = require('url');
var events = require('events');
var Stream = require('stream');
var END_OF_FILE = 42;
var assert = require('assert').ok;
var constants = require('constants');

var DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2


'RC4:HIGH:!MD5:!aNULL:!EDH'; // TLS 1.0

// Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations


// every {CLIENT_RENEG_WINDOW} seconds. An error event is emitted if more
// renegotations are seen. The settings are applied to all remote client
// connections.
exports.CLIENT_RENEG_LIMIT = 3;
exports.CLIENT_RENEG_WINDOW = 600;

var debug;
if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) {
debug = function(a) { console.error('TLS:', a); };
} else {
debug = function() { };
}

var Connection = null;


try {
Connection = process.binding('crypto').Connection;
} catch (e) {
throw new Error('node.js not compiled with openssl crypto support.');
}

// Convert protocols array into valid OpenSSL protocols list


// ("\x06spdy/2\x08http/1.1\x08http/1.0")
function convertNPNProtocols(NPNProtocols, out) {
// If NPNProtocols is Array - translate it into buffer
if (Array.isArray(NPNProtocols)) {
var buff = new Buffer(NPNProtocols.reduce(function(p, c) {
return p + 1 + Buffer.byteLength(c);
}, 0));

NPNProtocols.reduce(function(offset, c) {
var clen = Buffer.byteLength(c);
buff[offset] = clen;
buff.write(c, offset + 1);

return offset + 1 + clen;


}, 0);

NPNProtocols = buff;
}

// If it's already a Buffer - store it


if (Buffer.isBuffer(NPNProtocols)) {
out.NPNProtocols = NPNProtocols;
}
}

function checkServerIdentity(host, cert) {


// Create regexp to much hostnames
function regexpify(host, wildcards) {
// Add trailing dot (make hostnames uniform)
if (!/\.$/.test(host)) host += '.';

// The same applies to hostname with more than one wildcard,


// if hostname has wildcard when wildcards are not allowed,
// or if there are less than two dots after wildcard (i.e. *.com or *d.com)
//
// also
//
// "The client SHOULD NOT attempt to match a presented identifier in
// which the wildcard character comprises a label other than the
// left-most label (e.g., do not match bar.*.example.net)."
// RFC6125
if (!wildcards && /\*/.test(host) || /[\.\*].*\*/.test(host) ||
/\*/.test(host) && !/\*.*\..+\..+/.test(host)) {
return /$./;
}

// Replace wildcard chars with regexp's wildcard and


// escape all characters that have special meaning in regexps
// (i.e. '.', '[', '{', '*', and others)
var re = host.replace(
/\*([a-z0-9\\-_\.])|[\.,\-\\\^\$+?*\[\]\(\):!\|{}]/g,
function(all, sub) {
if (sub) return '[a-z0-9\\-_]*' + (sub === '-' ? '\\-' : sub);
return '\\' + all;
});

return new RegExp('^' + re + '$', 'i');


}

var dnsNames = [],


uriNames = [],
ips = [],
matchCN = true,
valid = false;

// There're several names to perform check against:


// CN and altnames in certificate extension
// (DNS names, IP addresses, and URIs)
//
// Walk through altnames and generate lists of those names
if (cert.subjectaltname) {
matchCN = false;
cert.subjectaltname.split(/, /g).forEach(function(altname) {
if (/^DNS:/.test(altname)) {
dnsNames.push(altname.slice(4));
} else if (/^IP Address:/.test(altname)) {
ips.push(altname.slice(11));
} else if (/^URI:/.test(altname)) {
var uri = url.parse(altname.slice(4));
if (uri) uriNames.push(uri.hostname);
}
});
}

// If hostname is an IP address, it should be present in the list of IP


// addresses.
if (net.isIP(host)) {
valid = ips.some(function(ip) {
return ip === host;
});
} else {
// Transform hostname to canonical form
if (!/\.$/.test(host)) host += '.';

// Otherwise check all DNS/URI records from certificate


// (with allowed wildcards)
dnsNames = dnsNames.map(function(name) {
return regexpify(name, true);
});

// Wildcards ain't allowed in URI names


uriNames = uriNames.map(function(name) {
return regexpify(name, false);
});

dnsNames = dnsNames.concat(uriNames);
if (dnsNames.length > 0) matchCN = false;

// Match against Common Name (CN) only if altnames are not present.
//
// "As noted, a client MUST NOT seek a match for a reference identifier
// of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
// URI-ID, or any application-specific identifier types supported by the
// client."
// RFC6125
if (matchCN) {
var commonNames = cert.subject.CN;
if (Array.isArray(commonNames)) {
for (var i = 0, k = commonNames.length; i < k; ++i) {
dnsNames.push(regexpify(commonNames[i], true));
}
} else {
dnsNames.push(regexpify(commonNames, true));
}
}

valid = dnsNames.some(function(re) {
return re.test(host);
});
}

return valid;
}
exports.checkServerIdentity = checkServerIdentity;

function SlabBuffer() {
this.create();
}

SlabBuffer.prototype.create = function create() {


this.isFull = false;
this.pool = new Buffer(10 * 1024 * 1024);
this.offset = 0;
this.remaining = this.pool.length;
};

SlabBuffer.prototype.use = function use(context, fn) {


if (this.remaining === 0) {
this.isFull = true;
return 0;
}

var bytes = fn.call(context, this.pool, this.offset, this.remaining);

if (bytes > 0) {
this.offset += bytes;
this.remaining -= bytes;
}

assert(this.remaining >= 0);


return bytes;
};

var slabBuffer = new SlabBuffer();

// Base class of both CleartextStream and EncryptedStream


function CryptoStream(pair) {
Stream.call(this);

this.pair = pair;

this.readable = this.writable = true;

this._paused = false;
this._needDrain = false;
this._pending = [];
this._pendingCallbacks = [];
this._pendingBytes = 0;
this._buffer = slabBuffer;
}
util.inherits(CryptoStream, Stream);

CryptoStream.prototype.write = function(data /* , encoding, cb */) {


if (this == this.pair.cleartext) {
debug('cleartext.write called with ' + data.length + ' bytes');
} else {
debug('encrypted.write called with ' + data.length + ' bytes');
}

if (!this.writable) {
throw new Error('CryptoStream is not writable');
}

var encoding, cb;

// parse arguments
if (typeof arguments[1] == 'string') {
encoding = arguments[1];
cb = arguments[2];
} else {
cb = arguments[1];
}

// Transform strings into buffers.


if (typeof data == 'string') {
data = new Buffer(data, encoding);
}

debug((this === this.pair.cleartext ? 'clear' : 'encrypted') + 'In data');

this._pending.push(data);
this._pendingCallbacks.push(cb);
this._pendingBytes += data.length;
this.pair._writeCalled = true;
this.pair.cycle();

// In the following cases, write() should return a false,


// then this stream should eventually emit 'drain' event.
//
// 1. There are pending data more than 128k bytes.
// 2. A forward stream shown below is paused.
// A) EncryptedStream for CleartextStream.write().
// B) CleartextStream for EncryptedStream.write().
//
if (!this._needDrain) {
if (this._pendingBytes >= 128 * 1024) {
this._needDrain = true;
} else {
if (this === this.pair.cleartext) {
this._needDrain = this.pair.encrypted._paused;
} else {
this._needDrain = this.pair.cleartext._paused;
}
}
}
return !this._needDrain;
};

CryptoStream.prototype.pause = function() {
debug('paused ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted'));
this._paused = true;
};

CryptoStream.prototype.resume = function() {
debug('resume ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted'));
this._paused = false;
this.pair.cycle();
};

CryptoStream.prototype.setTimeout = function(timeout, callback) {


if (this.socket) this.socket.setTimeout(timeout, callback);
};

CryptoStream.prototype.setNoDelay = function(noDelay) {
if (this.socket) this.socket.setNoDelay(noDelay);
};

CryptoStream.prototype.setKeepAlive = function(enable, initialDelay) {


if (this.socket) this.socket.setKeepAlive(enable, initialDelay);
};

CryptoStream.prototype.setEncoding = function(encoding) {
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder(encoding);
};
// Example:
// C=US\nST=CA\nL=SF\nO=Joyent\nOU=Node.js\nCN=ca1\nemailAddress=ry@clouds.org
function parseCertString(s) {
var out = {};
var parts = s.split('\n');
for (var i = 0, len = parts.length; i < len; i++) {
var sepIndex = parts[i].indexOf('=');
if (sepIndex > 0) {
var key = parts[i].slice(0, sepIndex);
var value = parts[i].slice(sepIndex + 1);
if (key in out) {
if (!Array.isArray(out[key])) {
out[key] = [out[key]];
}
out[key].push(value);
} else {
out[key] = value;
}
}
}
return out;
}

CryptoStream.prototype.getPeerCertificate = function() {
if (this.pair.ssl) {
var c = this.pair.ssl.getPeerCertificate();

if (c) {
if (c.issuer) c.issuer = parseCertString(c.issuer);
if (c.subject) c.subject = parseCertString(c.subject);
return c;
}
}

return null;
};

CryptoStream.prototype.getSession = function() {
if (this.pair.ssl) {
return this.pair.ssl.getSession();
}

return null;
};

CryptoStream.prototype.isSessionReused = function() {
if (this.pair.ssl) {
return this.pair.ssl.isSessionReused();
}

return null;
};

CryptoStream.prototype.getCipher = function(err) {
if (this.pair.ssl) {
return this.pair.ssl.getCurrentCipher();
} else {
return null;
}
};

CryptoStream.prototype.end = function(d) {
if (this.pair._doneFlag) return;
if (!this.writable) return;

if (d) {
this.write(d);
}

this._pending.push(END_OF_FILE);
this._pendingCallbacks.push(null);

// If this is an encrypted stream then we need to disable further 'data'


// events.

this.writable = false;

this.pair.cycle();
};

CryptoStream.prototype.destroySoon = function(err) {
if (this.writable) {
this.end();
} else {
this.destroy();
}
};

CryptoStream.prototype.destroy = function(err) {
if (this.pair._doneFlag) return;
this.pair.destroy();
};

CryptoStream.prototype._done = function() {
this._doneFlag = true;

if (this.pair.cleartext._doneFlag &&
this.pair.encrypted._doneFlag &&
!this.pair._doneFlag) {
// If both streams are done:
if (!this.pair._secureEstablished) {
this.pair.error();
} else {
this.pair.destroy();
}
}
};

// readyState is deprecated. Don't use it.


Object.defineProperty(CryptoStream.prototype, 'readyState', {
get: function() {
if (this._connecting) {
return 'opening';
} else if (this.readable && this.writable) {
return 'open';
} else if (this.readable && !this.writable) {
return 'readOnly';
} else if (!this.readable && this.writable) {
return 'writeOnly';
} else {
return 'closed';
}
}
});

// Move decrypted, clear data out into the application.


// From the user's perspective this occurs as a 'data' event
// on the pair.cleartext.
// also
// Move encrypted data to the stream. From the user's perspective this
// occurs as a 'data' event on the pair.encrypted. Usually the application
// will have some code which pipes the stream to a socket:
//
// pair.encrypted.on('data', function (d) {
// socket.write(d);
// });
//
CryptoStream.prototype._push = function() {
if (this == this.pair.encrypted && !this.writable) {
// If the encrypted side got EOF, we do not attempt
// to write out data anymore.
return;
}

while (!this._paused) {
var chunkBytes = 0,
bytesRead = 0,
start = this._buffer.offset;

do {
chunkBytes = this._buffer.use(this, this._pusher);
if (chunkBytes > 0) bytesRead += chunkBytes;

if (this.pair.ssl && this.pair.ssl.error) {


this.pair.error();
return;
}

this.pair.maybeInitFinished();

} while (chunkBytes > 0 && !this._buffer.isFull);

var pool = this._buffer.pool;

// Create new buffer if previous was filled up


if (this._buffer.isFull) this._buffer.create();

assert(bytesRead >= 0);


// Bail out if we didn't read any data.
if (bytesRead == 0) {
if (this._internallyPendingBytes() == 0 && this._destroyAfterPush) {
this._done();
}
return;
}

var chunk = pool.slice(start, start + bytesRead);

if (this === this.pair.cleartext) {


debug('cleartext emit "data" with ' + bytesRead + ' bytes');
} else {
debug('encrypted emit "data" with ' + bytesRead + ' bytes');
}

if (this._decoder) {
var string = this._decoder.write(chunk);
if (string.length) this.emit('data', string);
} else {
this.emit('data', chunk);
}

// Optimization: emit the original buffer with end points


if (this.ondata) this.ondata(pool, start, start + bytesRead);
}
};

// Push in any clear data coming from the application.


// This arrives via some code like this:
//
// pair.cleartext.write("hello world");
//
// also
//
// Push in incoming encrypted data from the socket.
// This arrives via some code like this:
//
// socket.on('data', function (d) {
// pair.encrypted.write(d)
// });
//
CryptoStream.prototype._pull = function() {
var havePending = this._pending.length > 0;

assert(havePending || this._pendingBytes == 0);

while (this._pending.length > 0) {


if (!this.pair.ssl) break;

var tmp = this._pending.shift();


var cb = this._pendingCallbacks.shift();

assert(this._pending.length === this._pendingCallbacks.length);

if (tmp === END_OF_FILE) {


// Sending EOF
if (this === this.pair.encrypted) {
debug('end encrypted ' + this.pair.fd);
this.pair.cleartext._destroyAfterPush = true;
} else {
// CleartextStream
assert(this === this.pair.cleartext);
debug('end cleartext');

this.pair.ssl.shutdown();

// TODO check if we get EAGAIN From shutdown, would have to do it


// again. should unshift END_OF_FILE back onto pending and wait for
// next cycle.

this.pair.encrypted._destroyAfterPush = true;
}
this.pair.cycle();
this._done();
return;
}

if (tmp.length == 0) continue;

var rv = this._puller(tmp);

if (this.pair.ssl && this.pair.ssl.error) {


this.pair.error();
return;
}

this.pair.maybeInitFinished();

if (rv === 0 || rv < 0) {


this._pending.unshift(tmp);
this._pendingCallbacks.unshift(cb);
break;
}

this._pendingBytes -= tmp.length;
assert(this._pendingBytes >= 0);

if (cb) cb();

assert(rv === tmp.length);


}

// If pending data has cleared, 'drain' event should be emitted


// after write() returns a false.
// Except when a forward stream shown below is paused.
// A) EncryptedStream for CleartextStream._pull().
// B) CleartextStream for EncryptedStream._pull().
//
if (this._needDrain && this._pending.length === 0) {
var paused;
if (this === this.pair.cleartext) {
paused = this.pair.encrypted._paused;
} else {
paused = this.pair.cleartext._paused;
}
if (!paused) {
debug('drain ' + (this === this.pair.cleartext ? 'clear' : 'encrypted'));
var self = this;
process.nextTick(function() {
self.emit('drain');
});
this._needDrain = false;
if (this.__destroyOnDrain) this.end();
}
}
};

function CleartextStream(pair) {
CryptoStream.call(this, pair);
}
util.inherits(CleartextStream, CryptoStream);

CleartextStream.prototype._internallyPendingBytes = function() {
if (this.pair.ssl) {
return this.pair.ssl.clearPending();
} else {
return 0;
}
};

CleartextStream.prototype._puller = function(b) {
debug('clearIn ' + b.length + ' bytes');
return this.pair.ssl.clearIn(b, 0, b.length);
};

CleartextStream.prototype._pusher = function(pool, offset, length) {


debug('reading from clearOut');
if (!this.pair.ssl) return -1;
return this.pair.ssl.clearOut(pool, offset, length);
};

CleartextStream.prototype.address = function() {
return this.socket && this.socket.address();
};

CleartextStream.prototype.__defineGetter__('remoteAddress', function() {
return this.socket && this.socket.remoteAddress;
});

CleartextStream.prototype.__defineGetter__('remotePort', function() {
return this.socket && this.socket.remotePort;
});

function EncryptedStream(pair) {
CryptoStream.call(this, pair);
}
util.inherits(EncryptedStream, CryptoStream);
EncryptedStream.prototype._internallyPendingBytes = function() {
if (this.pair.ssl) {
return this.pair.ssl.encPending();
} else {
return 0;
}
};

EncryptedStream.prototype._puller = function(b) {
debug('writing from encIn');
return this.pair.ssl.encIn(b, 0, b.length);
};

EncryptedStream.prototype._pusher = function(pool, offset, length) {


debug('reading from encOut');
if (!this.pair.ssl) return -1;
return this.pair.ssl.encOut(pool, offset, length);
};

function onhandshakestart() {
debug('onhandshakestart');

var self = this, ssl = this.ssl;

if (ssl.timer === null) {


ssl.timer = setTimeout(function timeout() {
ssl.handshakes = 0;
ssl.timer = null;
}, exports.CLIENT_RENEG_WINDOW * 1000);
}
else if (++ssl.handshakes > exports.CLIENT_RENEG_LIMIT) {
// Defer the error event to the next tick. We're being called from OpenSSL's
// state machine and OpenSSL is not re-entrant. We cannot allow the user's
// callback to destroy the connection right now, it would crash and burn.
process.nextTick(function() {
var err = new Error('TLS session renegotiation attack detected.');
if (self.cleartext) self.cleartext.emit('error', err);
});
}
}

function onhandshakedone() {
// for future use
debug('onhandshakedone');
}

/**
* Provides a pair of streams to do encrypted communication.
*/

function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,


options) {
if (!(this instanceof SecurePair)) {
return new SecurePair(credentials,
isServer,
requestCert,
rejectUnauthorized,
options);
}

var self = this;

options || (options = {});

events.EventEmitter.call(this);

this._secureEstablished = false;
this._isServer = isServer ? true : false;
this._encWriteState = true;
this._clearWriteState = true;
this._doneFlag = false;

if (!credentials) {
this.credentials = crypto.createCredentials();
} else {
this.credentials = credentials;
}

if (!this._isServer) {
// For clients, we will always have either a given ca list or be using
// default one
requestCert = true;
}

this._rejectUnauthorized = rejectUnauthorized ? true : false;


this._requestCert = requestCert ? true : false;

this.ssl = new Connection(this.credentials.context,


this._isServer ? true : false,
this._isServer ? this._requestCert : options.servername,
this._rejectUnauthorized);

if (this._isServer) {
this.ssl.onhandshakestart = onhandshakestart.bind(this);
this.ssl.onhandshakedone = onhandshakedone.bind(this);
this.ssl.handshakes = 0;
this.ssl.timer = null;
}

if (process.features.tls_sni) {
if (this._isServer && options.SNICallback) {
this.ssl.setSNICallback(options.SNICallback);
}
this.servername = null;
}

if (process.features.tls_npn && options.NPNProtocols) {


this.ssl.setNPNProtocols(options.NPNProtocols);
this.npnProtocol = null;
}

/* Acts as a r/w stream to the cleartext side of the stream. */


this.cleartext = new CleartextStream(this);
/* Acts as a r/w stream to the encrypted side of the stream. */
this.encrypted = new EncryptedStream(this);

process.nextTick(function() {
/* The Connection may be destroyed by an abort call */
if (self.ssl) {
self.ssl.start();
}
self.cycle();
});
}

util.inherits(SecurePair, events.EventEmitter);

exports.createSecurePair = function(credentials,
isServer,
requestCert,
rejectUnauthorized) {
var pair = new SecurePair(credentials,
isServer,
requestCert,
rejectUnauthorized);
return pair;
};

/* Attempt to cycle OpenSSLs buffers in various directions.


*
* An SSL Connection can be viewed as four separate piplines,
* interacting with one has no connection to the behavoir of
* any of the other 3 -- This might not sound reasonable,
* but consider things like mid-stream renegotiation of
* the ciphers.
*
* The four pipelines, using terminology of the client (server is just
* reversed):
* (1) Encrypted Output stream (Writing encrypted data to peer)
* (2) Encrypted Input stream (Reading encrypted data from peer)
* (3) Cleartext Output stream (Decrypted content from the peer)
* (4) Cleartext Input stream (Cleartext content to send to the peer)
*
* This function attempts to pull any available data out of the Cleartext
* input stream (4), and the Encrypted input stream (2). Then it pushes any
* data available from the cleartext output stream (3), and finally from the
* Encrypted output stream (1)
*
* It is called whenever we do something with OpenSSL -- post reciving
* content, trying to flush, trying to change ciphers, or shutting down the
* connection.
*
* Because it is also called everywhere, we also check if the connection has
* completed negotiation and emit 'secure' from here if it has.
*/
SecurePair.prototype.cycle = function(depth) {
if (this._doneFlag) return;
depth = depth ? depth : 0;

if (depth == 0) this._writeCalled = false;

var established = this._secureEstablished;

if (!this.cycleEncryptedPullLock) {
this.cycleEncryptedPullLock = true;
debug('encrypted._pull');
this.encrypted._pull();
this.cycleEncryptedPullLock = false;
}

if (!this.cycleCleartextPullLock) {
this.cycleCleartextPullLock = true;
debug('cleartext._pull');
this.cleartext._pull();
this.cycleCleartextPullLock = false;
}

if (!this.cycleCleartextPushLock) {
this.cycleCleartextPushLock = true;
debug('cleartext._push');
this.cleartext._push();
this.cycleCleartextPushLock = false;
}

if (!this.cycleEncryptedPushLock) {
this.cycleEncryptedPushLock = true;
debug('encrypted._push');
this.encrypted._push();
this.cycleEncryptedPushLock = false;
}

if ((!established && this._secureEstablished) ||


(depth == 0 && this._writeCalled)) {
// If we were not established but now we are, let's cycle again.
// Or if there is some data to write...
this.cycle(depth + 1);
}
};

SecurePair.prototype.maybeInitFinished = function() {
if (this.ssl && !this._secureEstablished && this.ssl.isInitFinished()) {
if (process.features.tls_npn) {
this.npnProtocol = this.ssl.getNegotiatedProtocol();
}

if (process.features.tls_sni) {
this.servername = this.ssl.getServername();
}

this._secureEstablished = true;
debug('secure established');
this.emit('secure');
}
};
SecurePair.prototype.destroy = function() {
var self = this;

if (!this._doneFlag) {
this._doneFlag = true;

if (this.ssl.timer) {
clearTimeout(this.ssl.timer);
this.ssl.timer = null;
}

this.ssl.error = null;
this.ssl.close();
this.ssl = null;

self.encrypted.writable = self.encrypted.readable = false;


self.cleartext.writable = self.cleartext.readable = false;

process.nextTick(function() {
self.cleartext.emit('end');
self.encrypted.emit('close');
self.cleartext.emit('close');
});
}
};

SecurePair.prototype.error = function() {
if (!this._secureEstablished) {
var error = this.ssl.error;
if (!error) {
error = new Error('socket hang up');
error.code = 'ECONNRESET';
}
this.destroy();
this.emit('error', error);
} else {
var err = this.ssl.error;
this.ssl.error = null;

if (this._isServer &&
this._rejectUnauthorized &&
/peer did not return a certificate/.test(err.message)) {
// Not really an error.
this.destroy();
} else {
this.cleartext.emit('error', err);
}
}
};

// TODO: support anonymous (nocert) and PSK

// AUTHENTICATION MODES
//
// There are several levels of authentication that TLS/SSL supports.
// Read more about this in "man SSL_set_verify".
//
// 1. The server sends a certificate to the client but does not request a
// cert from the client. This is common for most HTTPS servers. The browser
// can verify the identity of the server, but the server does not know who
// the client is. Authenticating the client is usually done over HTTP using
// login boxes and cookies and stuff.
//
// 2. The server sends a cert to the client and requests that the client
// also send it a cert. The client knows who the server is and the server is
// requesting the client also identify themselves. There are several
// outcomes:
//
// A) verifyError returns null meaning the client's certificate is signed
// by one of the server's CAs. The server know's the client idenity now
// and the client is authorized.
//
// B) For some reason the client's certificate is not acceptable -
// verifyError returns a string indicating the problem. The server can
// either (i) reject the client or (ii) allow the client to connect as an
// unauthorized connection.
//
// The mode is controlled by two boolean variables.
//
// requestCert
// If true the server requests a certificate from client connections. For
// the common HTTPS case, users will want this to be false, which is what
// it defaults to.
//
// rejectUnauthorized
// If true clients whose certificates are invalid for any reason will not
// be allowed to make connections. If false, they will simply be marked as
// unauthorized but secure communication will continue. By default this is
// false.
//
//
//
// Options:
// - requestCert. Send verify request. Default to false.
// - rejectUnauthorized. Boolean, default to false.
// - key. string.
// - cert: string.
// - ca: string or array of strings.
//
// emit 'secureConnection'
// function (cleartextStream, encryptedStream) { }
//
// 'cleartextStream' has the boolean property 'authorized' to determine if
// it was verified by the CA. If 'authorized' is false, a property
// 'authorizationError' is set on cleartextStream and has the possible
// values:
//
// "UNABLE_TO_GET_ISSUER_CERT", "UNABLE_TO_GET_CRL",
// "UNABLE_TO_DECRYPT_CERT_SIGNATURE", "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
// "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY", "CERT_SIGNATURE_FAILURE",
// "CRL_SIGNATURE_FAILURE", "CERT_NOT_YET_VALID" "CERT_HAS_EXPIRED",
// "CRL_NOT_YET_VALID", "CRL_HAS_EXPIRED" "ERROR_IN_CERT_NOT_BEFORE_FIELD",
// "ERROR_IN_CERT_NOT_AFTER_FIELD", "ERROR_IN_CRL_LAST_UPDATE_FIELD",
// "ERROR_IN_CRL_NEXT_UPDATE_FIELD", "OUT_OF_MEM",
// "DEPTH_ZERO_SELF_SIGNED_CERT", "SELF_SIGNED_CERT_IN_CHAIN",
// "UNABLE_TO_GET_ISSUER_CERT_LOCALLY", "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
// "CERT_CHAIN_TOO_LONG", "CERT_REVOKED" "INVALID_CA",
// "PATH_LENGTH_EXCEEDED", "INVALID_PURPOSE" "CERT_UNTRUSTED",
// "CERT_REJECTED"
//
//
// TODO:
// cleartext.credentials (by mirroring from pair object)
// cleartext.getCertificate() (by mirroring from pair.credentials.context)
function Server(/* [options], listener */) {
var options, listener;
if (typeof arguments[0] == 'object') {
options = arguments[0];
listener = arguments[1];
} else if (typeof arguments[0] == 'function') {
options = {};
listener = arguments[0];
}

if (!(this instanceof Server)) return new Server(options, listener);

this._contexts = [];

var self = this;

// Handle option defaults:


this.setOptions(options);

var sharedCreds = crypto.createCredentials({


pfx: self.pfx,
key: self.key,
passphrase: self.passphrase,
cert: self.cert,
ca: self.ca,
ciphers: self.ciphers || DEFAULT_CIPHERS,
secureProtocol: self.secureProtocol,
secureOptions: self.secureOptions,
crl: self.crl,
sessionIdContext: self.sessionIdContext
});

// constructor call
net.Server.call(this, function(socket) {
var creds = crypto.createCredentials(null, sharedCreds.context);

var pair = new SecurePair(creds,


true,
self.requestCert,
self.rejectUnauthorized,
{
NPNProtocols: self.NPNProtocols,
SNICallback: self.SNICallback
});

var cleartext = pipe(pair, socket);


cleartext._controlReleased = false;

pair.on('secure', function() {
pair.cleartext.authorized = false;
pair.cleartext.npnProtocol = pair.npnProtocol;
pair.cleartext.servername = pair.servername;

if (!self.requestCert) {
cleartext._controlReleased = true;
self.emit('secureConnection', pair.cleartext, pair.encrypted);
} else {
var verifyError = pair.ssl.verifyError();
if (verifyError) {
pair.cleartext.authorizationError = verifyError.message;

if (self.rejectUnauthorized) {
socket.destroy();
pair.destroy();
} else {
cleartext._controlReleased = true;
self.emit('secureConnection', pair.cleartext, pair.encrypted);
}
} else {
pair.cleartext.authorized = true;
cleartext._controlReleased = true;
self.emit('secureConnection', pair.cleartext, pair.encrypted);
}
}
});
pair.on('error', function(err) {
self.emit('clientError', err);
});
});

if (listener) {
this.on('secureConnection', listener);
}
}

util.inherits(Server, net.Server);
exports.Server = Server;
exports.createServer = function(options, listener) {
return new Server(options, listener);
};

Server.prototype.setOptions = function(options) {
if (typeof options.requestCert == 'boolean') {
this.requestCert = options.requestCert;
} else {
this.requestCert = false;
}

if (typeof options.rejectUnauthorized == 'boolean') {


this.rejectUnauthorized = options.rejectUnauthorized;
} else {
this.rejectUnauthorized = false;
}

if (options.pfx) this.pfx = options.pfx;


if (options.key) this.key = options.key;
if (options.passphrase) this.passphrase = options.passphrase;
if (options.cert) this.cert = options.cert;
if (options.ca) this.ca = options.ca;
if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
if (options.crl) this.crl = options.crl;
if (options.ciphers) this.ciphers = options.ciphers;
var secureOptions = options.secureOptions || 0;
if (options.honorCipherOrder) {
secureOptions |= constants.SSL_OP_CIPHER_SERVER_PREFERENCE;
}
if (secureOptions) this.secureOptions = secureOptions;
if (options.NPNProtocols) convertNPNProtocols(options.NPNProtocols, this);
if (options.SNICallback) {
this.SNICallback = options.SNICallback;
} else {
this.SNICallback = this.SNICallback.bind(this);
}
if (options.sessionIdContext) {
this.sessionIdContext = options.sessionIdContext;
} else if (this.requestCert) {
this.sessionIdContext = crypto.createHash('md5')
.update(process.argv.join(' '))
.digest('hex');
}
};

// SNI Contexts High-Level API


Server.prototype.addContext = function(servername, credentials) {
if (!servername) {
throw 'Servername is required parameter for Server.addContext';
}

var re = new RegExp('^' +


servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
.replace(/\*/g, '.*') +
'$');
this._contexts.push([re, crypto.createCredentials(credentials).context]);
};

Server.prototype.SNICallback = function(servername) {
var ctx;

this._contexts.some(function(elem) {
if (servername.match(elem[0]) !== null) {
ctx = elem[1];
return true;
}
});

return ctx;
};

// Target API:
//
// var s = tls.connect({port: 8000, host: "google.com"}, function() {
// if (!s.authorized) {
// s.destroy();
// return;
// }
//
// // s.socket;
//
// s.end("hello world\n");
// });
//
//
function normalizeConnectArgs(listArgs) {
var args = net._normalizeConnectArgs(listArgs);
var options = args[0];
var cb = args[1];

if (typeof listArgs[1] === 'object') {


options = util._extend(options, listArgs[1]);
} else if (typeof listArgs[2] === 'object') {
options = util._extend(options, listArgs[2]);
}

return (cb) ? [options, cb] : [options];


}

exports.connect = function(/* [port, host], options, cb */) {


var args = normalizeConnectArgs(arguments);
var options = args[0];
var cb = args[1];

var socket = options.socket ? options.socket : new net.Stream();

var sslcontext = crypto.createCredentials(options);

convertNPNProtocols(options.NPNProtocols, this);
var hostname = options.servername || options.host || 'localhost',
pair = new SecurePair(sslcontext, false, true,
options.rejectUnauthorized === true ? true : false,
{
NPNProtocols: this.NPNProtocols,
servername: hostname
});

if (options.session) {
pair.ssl.setSession(options.session);
}

var cleartext = pipe(pair, socket);


if (cb) {
cleartext.once('secureConnect', cb);
}

if (!options.socket) {
var connect_opt = (options.path && !options.port) ? {path: options.path} : {
port: options.port,
host: options.host,
localAddress: options.localAddress
};
socket.connect(connect_opt);
}

pair.on('secure', function() {
var verifyError = pair.ssl.verifyError();
cleartext.npnProtocol = pair.npnProtocol;

// Verify that server's identity matches it's certificate's names


if (!verifyError) {
var validCert = checkServerIdentity(hostname,
pair.cleartext.getPeerCertificate());
if (!validCert) {
verifyError = new Error('Hostname/IP doesn\'t match certificate\'s ' +
'altnames');
}
}

if (verifyError) {
cleartext.authorized = false;
cleartext.authorizationError = verifyError.message;

if (pair._rejectUnauthorized) {
cleartext.emit('error', verifyError);
pair.destroy();
} else {
cleartext.emit('secureConnect');
}
} else {
cleartext.authorized = true;
cleartext.emit('secureConnect');
}
});
pair.on('error', function(err) {
cleartext.emit('error', err);
});

cleartext._controlReleased = true;
return cleartext;
};

function pipe(pair, socket) {


pair.encrypted.pipe(socket);
socket.pipe(pair.encrypted);

pair.fd = socket.fd;
var cleartext = pair.cleartext;
cleartext.socket = socket;
cleartext.encrypted = pair.encrypted;
cleartext.authorized = false;

function onerror(e) {
if (cleartext._controlReleased) {
cleartext.emit('error', e);
}
}

function onclose() {
socket.removeListener('error', onerror);
socket.removeListener('end', onclose);
socket.removeListener('timeout', ontimeout);
}
function ontimeout() {
cleartext.emit('timeout');
}

socket.on('error', onerror);
socket.on('close', onclose);
socket.on('timeout', ontimeout);

return cleartext;
}
####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var assert = require('assert');


var inherits = require('util').inherits;
var net = require('net');
var TTY = process.binding('tty_wrap').TTY;
var isTTY = process.binding('tty_wrap').isTTY;
var util = require('util');

exports.isatty = function(fd) {
return isTTY(fd);
};

// backwards-compat
exports.setRawMode = util.deprecate(function(flag) {
if (!process.stdin.isTTY) {
throw new Error('can\'t set raw mode on non-tty');
}
process.stdin.setRawMode(flag);
}, 'tty.setRawMode: Use `process.stdin.setRawMode()` instead.');

function ReadStream(fd) {
if (!(this instanceof ReadStream)) return new ReadStream(fd);
net.Socket.call(this, {
handle: new TTY(fd, true)
});

this.readable = true;
this.writable = false;
this.isRaw = false;
}
inherits(ReadStream, net.Socket);

exports.ReadStream = ReadStream;

ReadStream.prototype.pause = function() {
return net.Socket.prototype.pause.call(this);
};

ReadStream.prototype.resume = function() {
return net.Socket.prototype.resume.call(this);
};

ReadStream.prototype.setRawMode = function(flag) {
flag = !!flag;
this._handle.setRawMode(flag);
this.isRaw = flag;
};

ReadStream.prototype.isTTY = true;

function WriteStream(fd) {
if (!(this instanceof WriteStream)) return new WriteStream(fd);
net.Socket.call(this, {
handle: new TTY(fd, false)
});

this.readable = false;
this.writable = true;

var winSize = this._handle.getWindowSize();


if (winSize) {
this.columns = winSize[0];
this.rows = winSize[1];
}
}
inherits(WriteStream, net.Socket);
exports.WriteStream = WriteStream;

WriteStream.prototype.isTTY = true;

WriteStream.prototype._refreshSize = function() {
var oldCols = this.columns;
var oldRows = this.rows;
var winSize = this._handle.getWindowSize();
if (!winSize) {
this.emit('error', errnoException(errno, 'getWindowSize'));
return;
}
var newCols = winSize[0];
var newRows = winSize[1];
if (oldCols !== newCols || oldRows !== newRows) {
this.columns = newCols;
this.rows = newRows;
this.emit('resize');
}
};

// backwards-compat
WriteStream.prototype.cursorTo = function(x, y) {
require('readline').cursorTo(this, x, y);
};
WriteStream.prototype.moveCursor = function(dx, dy) {
require('readline').moveCursor(this, dx, dy);
};
WriteStream.prototype.clearLine = function(dir) {
require('readline').clearLine(this, dir);
};
WriteStream.prototype.clearScreenDown = function() {
require('readline').clearScreenDown(this);
};
WriteStream.prototype.getWindowSize = function() {
return [this.columns, this.rows];
};

// TODO share with net_uv and others


function errnoException(errorno, syscall) {
var e = new Error(syscall + ' ' + errorno);
e.errno = e.code = errorno;
e.syscall = syscall;
return e;
}
##// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var punycode = require('punycode');

exports.parse = urlParse;
exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;
// Reference: RFC 3986, RFC 1808, RFC 2396

// define these here so at least they only have to be


// compiled once on the first module load.
var protocolPattern = /^([a-z0-9.+-]+:)/i,
portPattern = /:[0-9]*$/,

// RFC 2396: characters reserved for delimiting URLs.


// We actually just auto-escape these.
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],

// RFC 2396: characters not allowed for various reasons.


unwise = ['{', '}', '|', '\\', '^', '~', '`'].concat(delims),

// Allowed by RFCs, but cause of XSS attacks. Always escape these.


autoEscape = ['\''].concat(delims),
// Characters that are never ever allowed in a hostname.
// Note that any invalid chars are also handled, but these
// are the ones that are *expected* to be seen, so we fast-path
// them.
nonHostChars = ['%', '/', '?', ';', '#']
.concat(unwise).concat(autoEscape),
nonAuthChars = ['/', '@', '?', '#'].concat(delims),
hostnameMaxLen = 255,
hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
// protocols that can allow "unsafe" and "unwise" chars.
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that never have a hostname.
hostlessProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that always have a path component.
pathedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'ftp:': true,
'gopher:': true,
'file:': true
},
// protocols that always contain a // bit.
slashedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'https:': true,
'ftp:': true,
'gopher:': true,
'file:': true
},
querystring = require('querystring');

function urlParse(url, parseQueryString, slashesDenoteHost) {


if (url && typeof(url) === 'object' && url.href) return url;

if (typeof url !== 'string') {


throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}

var out = {},


rest = url;

// trim before proceeding.


// This is to support parse stuff like " http://foo.com \n"
rest = rest.trim();

var proto = protocolPattern.exec(rest);


if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
out.protocol = lowerProto;
rest = rest.substr(proto.length);
}

// figure out if it's got a host


// user@server is *always* interpreted as a hostname, and url
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
out.slashes = true;
}
}

if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
// don't enforce full RFC correctness, just be unstupid about it.

// If there is an @ in the hostname, then non-host chars *are* allowed


// to the left of the first @ sign, unless some non-auth character
// comes *before* the @-sign.
// URLs are obnoxious.
var atSign = rest.indexOf('@');
if (atSign !== -1) {
var auth = rest.slice(0, atSign);

// there *may be* an auth


var hasAuth = true;
for (var i = 0, l = nonAuthChars.length; i < l; i++) {
if (auth.indexOf(nonAuthChars[i]) !== -1) {
// not a valid auth. Something like http://foo.com/bar@baz/
hasAuth = false;
break;
}
}

if (hasAuth) {
// pluck off the auth portion.
out.auth = decodeURIComponent(auth);
rest = rest.substr(atSign + 1);
}
}

var firstNonHost = -1;


for (var i = 0, l = nonHostChars.length; i < l; i++) {
var index = rest.indexOf(nonHostChars[i]);
if (index !== -1 &&
(firstNonHost < 0 || index < firstNonHost)) firstNonHost = index;
}

if (firstNonHost !== -1) {


out.host = rest.substr(0, firstNonHost);
rest = rest.substr(firstNonHost);
} else {
out.host = rest;
rest = '';
}

// pull out port.


var p = parseHost(out.host);
var keys = Object.keys(p);
for (var i = 0, l = keys.length; i < l; i++) {
var key = keys[i];
out[key] = p[key];
}

// we've indicated that there is a hostname,


// so even if it's empty, it has to be present.
out.hostname = out.hostname || '';

// if hostname begins with [ and ends with ]


// assume that it's an IPv6 address.
var ipv6Hostname = out.hostname[0] === '[' &&
out.hostname[out.hostname.length - 1] === ']';

// validate a little.
if (out.hostname.length > hostnameMaxLen) {
out.hostname = '';
} else if (!ipv6Hostname) {
var hostparts = out.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
var newpart = '';
for (var j = 0, k = part.length; j < k; j++) {
if (part.charCodeAt(j) > 127) {
// we replace non-ASCII char with a temporary placeholder
// we need this to make sure size of hostname is not
// broken by replacing non-ASCII by nothing
newpart += 'x';
} else {
newpart += part[j];
}
}
// we test again with ASCII char only
if (!newpart.match(hostnamePartPattern)) {
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
out.hostname = validParts.join('.');
break;
}
}
}
}

// hostnames are always lower case.


out.hostname = out.hostname.toLowerCase();

if (!ipv6Hostname) {
// IDNA Support: Returns a puny coded representation of "domain".
// It only converts the part of the domain name that
// has non ASCII characters. I.e. it dosent matter if
// you call it with a domain that already is in ASCII.
var domainArray = out.hostname.split('.');
var newOut = [];
for (var i = 0; i < domainArray.length; ++i) {
var s = domainArray[i];
newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
'xn--' + punycode.encode(s) : s);
}
out.hostname = newOut.join('.');
}

out.host = (out.hostname || '') +


((out.port) ? ':' + out.port : '');
out.href += out.host;

// strip [ and ] from the hostname


if (ipv6Hostname) {
out.hostname = out.hostname.substr(1, out.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
}
}

// now rest is set to the post-host stuff.


// chop off any delim chars.
if (!unsafeProtocol[lowerProto]) {

// First, make 100% sure that any "autoEscape" chars get


// escaped, even if encodeURIComponent doesn't think they
// need to be.
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
}

// chop off from the tail first.


var hash = rest.indexOf('#');
if (hash !== -1) {
// got a fragment string.
out.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
out.search = rest.substr(qm);
out.query = rest.substr(qm + 1);
if (parseQueryString) {
out.query = querystring.parse(out.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
// no query string, but parseQueryString still requested
out.search = '';
out.query = {};
}
if (rest) out.pathname = rest;
if (slashedProtocol[proto] &&
out.hostname && !out.pathname) {
out.pathname = '/';
}

//to support http.request


if (out.pathname || out.search) {
out.path = (out.pathname ? out.pathname : '') +
(out.search ? out.search : '');
}

// finally, reconstruct the href based on what has been validated.


out.href = urlFormat(out);
return out;
}

// format a parsed object into a url string


function urlFormat(obj) {
// ensure it's an object, and not a string url.
// If it's an obj, this is a no-op.
// this way, you can call url_format() on strings
// to clean up potentially wonky urls.
if (typeof(obj) === 'string') obj = urlParse(obj);

var auth = obj.auth || '';


if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}

var protocol = obj.protocol || '',


pathname = obj.pathname || '',
hash = obj.hash || '',
host = false,
query = '';

if (obj.host !== undefined) {


host = auth + obj.host;
} else if (obj.hostname !== undefined) {
host = auth + (obj.hostname.indexOf(':') === -1 ?
obj.hostname :
'[' + obj.hostname + ']');
if (obj.port) {
host += ':' + obj.port;
}
}

if (obj.query && typeof obj.query === 'object' &&


Object.keys(obj.query).length) {
query = querystring.stringify(obj.query);
}

var search = obj.search || (query && ('?' + query)) || '';

if (protocol && protocol.substr(-1) !== ':') protocol += ':';

// only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
// unless they had them to begin with.
if (obj.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}

if (hash && hash.charAt(0) !== '#') hash = '#' + hash;


if (search && search.charAt(0) !== '?') search = '?' + search;

return protocol + host + pathname + search + hash;


}

function urlResolve(source, relative) {


return urlFormat(urlResolveObject(source, relative));
}

function urlResolveObject(source, relative) {


if (!source) return relative;

source = urlParse(urlFormat(source), false, true);


relative = urlParse(urlFormat(relative), false, true);

// hash is always overridden, no matter what.


source.hash = relative.hash;
if (relative.href === '') {
source.href = urlFormat(source);
return source;
}

// hrefs like //foo/bar always cut to the protocol.


if (relative.slashes && !relative.protocol) {
relative.protocol = source.protocol;
//urlParse appends trailing / to urls like http://www.example.com
if (slashedProtocol[relative.protocol] &&
relative.hostname && !relative.pathname) {
relative.path = relative.pathname = '/';
}
relative.href = urlFormat(relative);
return relative;
}

if (relative.protocol && relative.protocol !== source.protocol) {


// if it's a known url protocol, then changing
// the protocol does weird things
// first, if it's not file:, then we MUST have a host,
// and if there was a path
// to begin with, then we MUST have a path.
// if it is file:, then the host is dropped,
// because that's known to be hostless.
// anything else is assumed to be absolute.
if (!slashedProtocol[relative.protocol]) {
relative.href = urlFormat(relative);
return relative;
}
source.protocol = relative.protocol;
if (!relative.host && !hostlessProtocol[relative.protocol]) {
var relPath = (relative.pathname || '').split('/');
while (relPath.length && !(relative.host = relPath.shift()));
if (!relative.host) relative.host = '';
if (!relative.hostname) relative.hostname = '';
if (relPath[0] !== '') relPath.unshift('');
if (relPath.length < 2) relPath.unshift('');
relative.pathname = relPath.join('/');
}
source.pathname = relative.pathname;
source.search = relative.search;
source.query = relative.query;
source.host = relative.host || '';
source.auth = relative.auth;
source.hostname = relative.hostname || relative.host;
source.port = relative.port;
//to support http.request
if (source.pathname !== undefined || source.search !== undefined) {
source.path = (source.pathname ? source.pathname : '') +
(source.search ? source.search : '');
}
source.slashes = source.slashes || relative.slashes;
source.href = urlFormat(source);
return source;
}

var isSourceAbs = (source.pathname && source.pathname.charAt(0) === '/'),


isRelAbs = (
relative.host !== undefined ||
relative.pathname && relative.pathname.charAt(0) === '/'
),
mustEndAbs = (isRelAbs || isSourceAbs ||
(source.host && relative.pathname)),
removeAllDots = mustEndAbs,
srcPath = source.pathname && source.pathname.split('/') || [],
relPath = relative.pathname && relative.pathname.split('/') || [],
psychotic = source.protocol &&
!slashedProtocol[source.protocol];

// if the url is a non-slashed url, then relative


// links like ../.. should be able
// to crawl up to the hostname, as well. This is strange.
// source.protocol has already been set by now.
// Later on, put the first path part into the host field.
if (psychotic) {

delete source.hostname;
delete source.port;
if (source.host) {
if (srcPath[0] === '') srcPath[0] = source.host;
else srcPath.unshift(source.host);
}
delete source.host;
if (relative.protocol) {
delete relative.hostname;
delete relative.port;
if (relative.host) {
if (relPath[0] === '') relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
delete relative.host;
}
mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
}

if (isRelAbs) {
// it's absolute.
source.host = (relative.host || relative.host === '') ?
relative.host : source.host;
source.hostname = (relative.hostname || relative.hostname === '') ?
relative.hostname : source.hostname;
source.search = relative.search;
source.query = relative.query;
srcPath = relPath;
// fall through to the dot-handling below.
} else if (relPath.length) {
// it's relative
// throw away the existing file, and take the new path instead.
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
source.search = relative.search;
source.query = relative.query;
} else if ('search' in relative) {
// just pull out the search.
// like href='?foo'.
// Put this after the other two cases because it simplifies the booleans
if (psychotic) {
source.hostname = source.host = srcPath.shift();
//occationaly the auth can get stuck only in host
//this especialy happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = source.host && source.host.indexOf('@') > 0 ?
source.host.split('@') : false;
if (authInHost) {
source.auth = authInHost.shift();
source.host = source.hostname = authInHost.shift();
}
}
source.search = relative.search;
source.query = relative.query;
//to support http.request
if (source.pathname !== undefined || source.search !== undefined) {
source.path = (source.pathname ? source.pathname : '') +
(source.search ? source.search : '');
}
source.href = urlFormat(source);
return source;
}
if (!srcPath.length) {
// no path at all. easy.
// we've already handled the other stuff above.
delete source.pathname;
//to support http.request
if (!source.search) {
source.path = '/' + source.search;
} else {
delete source.path;
}
source.href = urlFormat(source);
return source;
}
// if a url ENDs in . or .., then it must get a trailing slash.
// however, if it ends in anything else non-slashy,
// then it must NOT get a trailing slash.
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
(source.host || relative.host) && (last === '.' || last === '..') ||
last === '');

// strip single dots, resolve double dots to parent dir


// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = srcPath.length; i >= 0; i--) {
last = srcPath[i];
if (last == '.') {
srcPath.splice(i, 1);
} else if (last === '..') {
srcPath.splice(i, 1);
up++;
} else if (up) {
srcPath.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (!mustEndAbs && !removeAllDots) {
for (; up--; up) {
srcPath.unshift('..');
}
}

if (mustEndAbs && srcPath[0] !== '' &&


(!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
srcPath.unshift('');
}

if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {


srcPath.push('');
}

var isAbsolute = srcPath[0] === '' ||


(srcPath[0] && srcPath[0].charAt(0) === '/');

// put the host back


if (psychotic) {
source.hostname = source.host = isAbsolute ? '' :
srcPath.length ? srcPath.shift() : '';
//occationaly the auth can get stuck only in host
//this especialy happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = source.host && source.host.indexOf('@') > 0 ?
source.host.split('@') : false;
if (authInHost) {
source.auth = authInHost.shift();
source.host = source.hostname = authInHost.shift();
}
}

mustEndAbs = mustEndAbs || (source.host && srcPath.length);

if (mustEndAbs && !isAbsolute) {


srcPath.unshift('');
}

source.pathname = srcPath.join('/');
//to support request.http
if (source.pathname !== undefined || source.search !== undefined) {
source.path = (source.pathname ? source.pathname : '') +
(source.search ? source.search : '');
}
source.auth = relative.auth || source.auth;
source.slashes = source.slashes || relative.slashes;
source.href = urlFormat(source);
return source;
}

function parseHost(host) {
var out = {};
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
out.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
if (host) out.hostname = host;
return out;
}
##// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var formatRegExp = /%[sdj%]/g;


exports.format = function(f) {
if (typeof f !== 'string') {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(inspect(arguments[i]));
}
return objects.join(' ');
}

var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j': return JSON.stringify(args[i++]);
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (x === null || typeof x !== 'object') {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};

// Mark that a method should not be used.


// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
if (process.noDeprecation === true) {
return fn;
}

var warned = false;


function deprecated() {
if (!warned) {
if (process.traceDeprecation) {
console.trace(msg);
} else {
console.error(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}

return deprecated;
};

exports.print = function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
process.stdout.write(String(arguments[i]));
}
};

exports.puts = function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
process.stdout.write(arguments[i] + '\n');
}
};

exports.debug = function(x) {
process.stderr.write('DEBUG: ' + x + '\n');
};

var error = exports.error = function(x) {


for (var i = 0, len = arguments.length; i < len; ++i) {
process.stderr.write(arguments[i] + '\n');
}
};

/**
* Echos the value of a value. Trys to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
* @param {Boolean} showHidden Flag that shows hidden (not enumerable)
* properties of objects.
* @param {Number} depth Depth in which to descend in object. Default is 2.
* @param {Boolean} colors Flag to turn on ANSI escape codes to color the
* output. Default is false (no coloring).
*/
function inspect(obj, showHidden, depth, colors) {
var ctx = {
showHidden: showHidden,
seen: [],
stylize: colors ? stylizeWithColor : stylizeNoColor
};
return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
}
exports.inspect = inspect;

// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
var colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39]
};

// Don't use 'blue' not visible on cmd.exe


var styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};

function stylizeWithColor(str, styleType) {


var style = styles[styleType];

if (style) {
return '\u001b[' + colors[style][0] + 'm' + str +
'\u001b[' + colors[style][1] + 'm';
} else {
return str;
}
}
function stylizeNoColor(str, styleType) {
return str;
}

function arrayToHash(array) {
var hash = {};

array.forEach(function(val, idx) {
hash[val] = true;
});

return hash;
}

function formatValue(ctx, value, recurseTimes) {


// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (value && typeof value.inspect === 'function' &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
return String(value.inspect(recurseTimes));
}

// Primitive types cannot have properties


var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}

// Look up the keys of the object.


var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);

if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}

// Some type of object without properties can be shortcutted.


if (keys.length === 0) {
if (typeof value === 'function') {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
}
var base = '', array = false, braces = ['{', '}'];

// Make Array say that they are Array


if (isArray(value)) {
array = true;
braces = ['[', ']'];
}

// Make functions say that they are functions


if (typeof value === 'function') {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}

// Make RegExps say that they are RegExps


if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}

// Make dates with properties first say the date


if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}

// Make error with message first say the error


if (isError(value)) {
base = ' ' + formatError(value);
}

if (keys.length === 0 && (!array || value.length == 0)) {


return braces[0] + base + braces[1];
}

if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}

ctx.seen.push(value);

var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}

ctx.seen.pop();

return reduceToSingleString(output, base, braces);


}
function formatPrimitive(ctx, value) {
switch (typeof value) {
case 'undefined':
return ctx.stylize('undefined', 'undefined');

case 'string':
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');

case 'number':
return ctx.stylize('' + value, 'number');

case 'boolean':
return ctx.stylize('' + value, 'boolean');
}
// For some reason typeof null is "object", so special case here.
if (value === null) {
return ctx.stylize('null', 'null');
}
}

function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}

function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {


var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function(key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}

function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {


var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (recurseTimes === null) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (typeof name === 'undefined') {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}

return name + ': ' + str;


}

function reduceToSingleString(output, base, braces) {


var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.length + 1;
}, 0);

if (length > 60) {


return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}

return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}

// NOTE: These type checking functions intentionally don't use `instanceof`


// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar) ||
(typeof ar === 'object' && objectToString(ar) === '[object Array]');
}
exports.isArray = isArray;

function isRegExp(re) {
return typeof re === 'object' && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;

function isDate(d) {
return typeof d === 'object' && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;

function isError(e) {
return typeof e === 'object' && objectToString(e) === '[object Error]';
}
exports.isError = isError;

function objectToString(o) {
return Object.prototype.toString.call(o);
}

exports.p = exports.deprecate(function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
error(exports.inspect(arguments[i]));
}
}, 'util.p: Use console.error() instead.');

function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}

var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];

// 26 Feb 16:19:34
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}

exports.log = function(msg) {
exports.puts(timestamp() + ' - ' + msg.toString());
};

exports.exec = exports.deprecate(function() {
return require('child_process').exec.apply(this, arguments);
}, 'util.exec is now called `child_process.exec`.');

exports.pump = function(readStream, writeStream, callback) {


var callbackCalled = false;

function call(a, b, c) {
if (callback && !callbackCalled) {
callback(a, b, c);
callbackCalled = true;
}
}

readStream.addListener('data', function(chunk) {
if (writeStream.write(chunk) === false) readStream.pause();
});

writeStream.addListener('drain', function() {
readStream.resume();
});

readStream.addListener('end', function() {
writeStream.end();
});

readStream.addListener('close', function() {
call();
});

readStream.addListener('error', function(err) {
writeStream.end();
call(err);
});

writeStream.addListener('error', function(err) {
readStream.destroy();
call(err);
});
};

/**
* Inherit the prototype methods from one constructor into another.
*
* The Function.prototype.inherits from lang.js rewritten as a standalone
* function (not on Function.prototype). NOTE: If this file is to be loaded
* during bootstrapping this function needs to be rewritten using some native
* functions as prototype setup using normal JavaScript does not work as
* expected during bootstrapping (see mirror.js in r114903).
*
* @param {function} ctor Constructor function which needs to inherit the
* prototype.
* @param {function} superCtor Constructor function to inherit prototype from.
*/
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};

exports._extend = function(origin, add) {


// Don't do anything if add isn't an object
if (!add || typeof add !== 'object') return origin;

var keys = Object.keys(add);


var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};

function hasOwnProperty(obj, prop) {


return Object.prototype.hasOwnProperty.call(obj, prop);
}
########// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var binding = process.binding('evals');

module.exports = Script;
Script.Script = Script;

function Script(code, ctx, filename) {


if (!(this instanceof Script)) {
return new Script(code, ctx, filename);
}

var ns = new binding.NodeScript(code, ctx, filename);

// bind all methods to this Script object


Object.keys(binding.NodeScript.prototype).forEach(function(f) {
if (typeof binding.NodeScript.prototype[f] === 'function') {
this[f] = function() {
if (!(this instanceof Script)) {
throw new TypeError('invalid call to ' + f);
}
return ns[f].apply(ns, arguments);
};
}
}, this);
}

Script.createScript = function(code, ctx, name) {


return new Script(code, ctx, name);
};

Script.createContext = binding.NodeScript.createContext;
Script.runInContext = binding.NodeScript.runInContext;
Script.runInThisContext = binding.NodeScript.runInThisContext;
Script.runInNewContext = binding.NodeScript.runInNewContext;
####// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var binding = process.binding('zlib');


var util = require('util');
var Stream = require('stream');
var assert = require('assert').ok;
// zlib doesn't provide these, so kludge them in following the same
// const naming scheme zlib uses.
binding.Z_MIN_WINDOWBITS = 8;
binding.Z_MAX_WINDOWBITS = 15;
binding.Z_DEFAULT_WINDOWBITS = 15;

// fewer than 64 bytes per chunk is stupid.


// technically it could work with as few as 8, but even 64 bytes
// is absurdly low. Usually a MB or more is best.
binding.Z_MIN_CHUNK = 64;
binding.Z_MAX_CHUNK = Infinity;
binding.Z_DEFAULT_CHUNK = (16 * 1024);

binding.Z_MIN_MEMLEVEL = 1;
binding.Z_MAX_MEMLEVEL = 9;
binding.Z_DEFAULT_MEMLEVEL = 8;

binding.Z_MIN_LEVEL = -1;
binding.Z_MAX_LEVEL = 9;
binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION;

// expose all the zlib constants


Object.keys(binding).forEach(function(k) {
if (k.match(/^Z/)) exports[k] = binding[k];
});

// translation table for return codes.


exports.codes = {
Z_OK: binding.Z_OK,
Z_STREAM_END: binding.Z_STREAM_END,
Z_NEED_DICT: binding.Z_NEED_DICT,
Z_ERRNO: binding.Z_ERRNO,
Z_STREAM_ERROR: binding.Z_STREAM_ERROR,
Z_DATA_ERROR: binding.Z_DATA_ERROR,
Z_MEM_ERROR: binding.Z_MEM_ERROR,
Z_BUF_ERROR: binding.Z_BUF_ERROR,
Z_VERSION_ERROR: binding.Z_VERSION_ERROR
};

Object.keys(exports.codes).forEach(function(k) {
exports.codes[exports.codes[k]] = k;
});

exports.Deflate = Deflate;
exports.Inflate = Inflate;
exports.Gzip = Gzip;
exports.Gunzip = Gunzip;
exports.DeflateRaw = DeflateRaw;
exports.InflateRaw = InflateRaw;
exports.Unzip = Unzip;

exports.createDeflate = function(o) {
return new Deflate(o);
};

exports.createInflate = function(o) {
return new Inflate(o);
};
exports.createDeflateRaw = function(o) {
return new DeflateRaw(o);
};

exports.createInflateRaw = function(o) {
return new InflateRaw(o);
};

exports.createGzip = function(o) {
return new Gzip(o);
};

exports.createGunzip = function(o) {
return new Gunzip(o);
};

exports.createUnzip = function(o) {
return new Unzip(o);
};

// Convenience methods.
// compress/decompress a string or buffer in one step.
exports.deflate = function(buffer, callback) {
zlibBuffer(new Deflate(), buffer, callback);
};

exports.gzip = function(buffer, callback) {


zlibBuffer(new Gzip(), buffer, callback);
};

exports.deflateRaw = function(buffer, callback) {


zlibBuffer(new DeflateRaw(), buffer, callback);
};

exports.unzip = function(buffer, callback) {


zlibBuffer(new Unzip(), buffer, callback);
};

exports.inflate = function(buffer, callback) {


zlibBuffer(new Inflate(), buffer, callback);
};

exports.gunzip = function(buffer, callback) {


zlibBuffer(new Gunzip(), buffer, callback);
};

exports.inflateRaw = function(buffer, callback) {


zlibBuffer(new InflateRaw(), buffer, callback);
};

function zlibBuffer(engine, buffer, callback) {


var buffers = [];
var nread = 0;

function onError(err) {
engine.removeListener('end', onEnd);
engine.removeListener('error', onError);
callback(err);
}

function onData(chunk) {
buffers.push(chunk);
nread += chunk.length;
}

function onEnd() {
var buf = Buffer.concat(buffers, nread);
buffers = [];
callback(null, buf);
engine._clear();
}

engine.on('error', onError);
engine.on('data', onData);
engine.on('end', onEnd);

engine.write(buffer);
engine.end();
}

// generic zlib
// minimal 2-byte header
function Deflate(opts) {
if (!(this instanceof Deflate)) return new Deflate(opts);
Zlib.call(this, opts, binding.DEFLATE);
}

function Inflate(opts) {
if (!(this instanceof Inflate)) return new Inflate(opts);
Zlib.call(this, opts, binding.INFLATE);
}

// gzip - bigger header, same deflate compression


function Gzip(opts) {
if (!(this instanceof Gzip)) return new Gzip(opts);
Zlib.call(this, opts, binding.GZIP);
}

function Gunzip(opts) {
if (!(this instanceof Gunzip)) return new Gunzip(opts);
Zlib.call(this, opts, binding.GUNZIP);
}

// raw - no header
function DeflateRaw(opts) {
if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts);
Zlib.call(this, opts, binding.DEFLATERAW);
}

function InflateRaw(opts) {
if (!(this instanceof InflateRaw)) return new InflateRaw(opts);
Zlib.call(this, opts, binding.INFLATERAW);
}

// auto-detect header.
function Unzip(opts) {
if (!(this instanceof Unzip)) return new Unzip(opts);
Zlib.call(this, opts, binding.UNZIP);
}

// the Zlib class they all inherit from


// This thing manages the queue of requests, and returns
// true or false if there is anything in the queue when
// you call the .write() method.

function Zlib(opts, mode) {


Stream.call(this);

this._opts = opts = opts || {};


this._queue = [];
this._processing = false;
this._ended = false;
this.readable = true;
this.writable = true;
this._flush = binding.Z_NO_FLUSH;

if (opts.chunkSize) {
if (opts.chunkSize < exports.Z_MIN_CHUNK ||
opts.chunkSize > exports.Z_MAX_CHUNK) {
throw new Error('Invalid chunk size: ' + opts.chunkSize);
}
}

if (opts.windowBits) {
if (opts.windowBits < exports.Z_MIN_WINDOWBITS ||
opts.windowBits > exports.Z_MAX_WINDOWBITS) {
throw new Error('Invalid windowBits: ' + opts.windowBits);
}
}

if (opts.level) {
if (opts.level < exports.Z_MIN_LEVEL ||
opts.level > exports.Z_MAX_LEVEL) {
throw new Error('Invalid compression level: ' + opts.level);
}
}

if (opts.memLevel) {
if (opts.memLevel < exports.Z_MIN_MEMLEVEL ||
opts.memLevel > exports.Z_MAX_MEMLEVEL) {
throw new Error('Invalid memLevel: ' + opts.memLevel);
}
}

if (opts.strategy) {
if (opts.strategy != exports.Z_FILTERED &&
opts.strategy != exports.Z_HUFFMAN_ONLY &&
opts.strategy != exports.Z_RLE &&
opts.strategy != exports.Z_FIXED &&
opts.strategy != exports.Z_DEFAULT_STRATEGY) {
throw new Error('Invalid strategy: ' + opts.strategy);
}
}

if (opts.dictionary) {
if (!Buffer.isBuffer(opts.dictionary)) {
throw new Error('Invalid dictionary: it should be a Buffer instance');
}
}

this._binding = new binding.Zlib(mode);

var self = this;


this._binding.onerror = function(message, errno) {
// there is no way to cleanly recover.
// continuing only obscures problems.
self._binding = null;
self._hadError = true;
self._queue.length = 0;
self._processing = false;

var error = new Error(message);


error.errno = errno;
error.code = exports.codes[errno];
self.emit('error', error);
};

this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS,
opts.level || exports.Z_DEFAULT_COMPRESSION,
opts.memLevel || exports.Z_DEFAULT_MEMLEVEL,
opts.strategy || exports.Z_DEFAULT_STRATEGY,
opts.dictionary);

this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK;


this._buffer = new Buffer(this._chunkSize);
this._offset = 0;
var self = this;
}

util.inherits(Zlib, Stream);

Zlib.prototype.write = function write(chunk, cb) {


if (this._hadError) return true;

if (this._ended) {
return this.emit('error', new Error('Cannot write after end'));
}

if (arguments.length === 1 && typeof chunk === 'function') {


cb = chunk;
chunk = null;
}

if (!chunk) {
chunk = null;
} else if (typeof chunk === 'string') {
chunk = new Buffer(chunk);
} else if (!Buffer.isBuffer(chunk)) {
return this.emit('error', new Error('Invalid argument'));
}

var empty = this._queue.length === 0;

this._queue.push([chunk, cb]);
this._process();
if (!empty) {
this._needDrain = true;
}
return empty;
};

Zlib.prototype.reset = function reset() {


return this._binding.reset();
};

Zlib.prototype.flush = function flush(cb) {


this._flush = binding.Z_SYNC_FLUSH;
return this.write(cb);
};

Zlib.prototype.end = function end(chunk, cb) {


if (this._hadError) return true;

var self = this;


this._ending = true;
var ret = this.write(chunk, function() {
self.emit('end');
if (cb) cb();
});
this._ended = true;
return ret;
};

Zlib.prototype._clear = function() {
return this._binding.clear();
};

Zlib.prototype._process = function() {
if (this._hadError) return;

if (this._processing || this._paused) return;

if (this._queue.length === 0) {
if (this._needDrain) {
this._needDrain = false;
this.emit('drain');
}
// nothing to do, waiting for more data at this point.
return;
}

var req = this._queue.shift();


var cb = req.pop();
var chunk = req.pop();
if (this._ending && this._queue.length === 0) {
this._flush = binding.Z_FINISH;
}

var self = this;


var availInBefore = chunk && chunk.length;
var availOutBefore = this._chunkSize - this._offset;

var inOff = 0;
var req = this._binding.write(this._flush,
chunk, // in
inOff, // in_off
availInBefore, // in_len
this._buffer, // out
this._offset, //out_off
availOutBefore); // out_len

req.buffer = chunk;
req.callback = callback;
this._processing = req;

function callback(availInAfter, availOutAfter, buffer) {


if (self._hadError) return;

var have = availOutBefore - availOutAfter;

assert(have >= 0, 'have should not go down');

if (have > 0) {
var out = self._buffer.slice(self._offset, self._offset + have);
self._offset += have;
self.emit('data', out);
}

// XXX Maybe have a 'min buffer' size so we don't dip into the
// thread pool with only 1 byte available or something?
if (availOutAfter === 0 || self._offset >= self._chunkSize) {
availOutBefore = self._chunkSize;
self._offset = 0;
self._buffer = new Buffer(self._chunkSize);
}

if (availOutAfter === 0) {
// Not actually done. Need to reprocess.
// Also, update the availInBefore to the availInAfter value,
// so that if we have to hit it a third (fourth, etc.) time,
// it'll have the correct byte counts.
inOff += (availInBefore - availInAfter);
availInBefore = availInAfter;

var newReq = self._binding.write(self._flush,


chunk,
inOff,
availInBefore,
self._buffer,
self._offset,
self._chunkSize);
newReq.callback = callback; // this same function
newReq.buffer = chunk;
self._processing = newReq;
return;
}

// finished with the chunk.


self._processing = false;
if (cb) cb();
self._process();
}
};

Zlib.prototype.pause = function() {
this._paused = true;
this.emit('pause');
};

Zlib.prototype.resume = function() {
this._paused = false;
this._process();
};

Zlib.prototype.destroy = function() {
this.readable = false;
this.writable = false;
this._ended = true;
this.emit('close');
};

util.inherits(Deflate, Zlib);
util.inherits(Inflate, Zlib);
util.inherits(Gzip, Zlib);
util.inherits(Gunzip, Zlib);
util.inherits(DeflateRaw, Zlib);
util.inherits(InflateRaw, Zlib);
util.inherits(Unzip, Zlib);
######var sqlite3 = module.exports = exports = process.binding('sqlite3');
var path = require('path');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

function errorCallback(args) {
if (typeof args[args.length - 1] === 'function') {
var callback = args[args.length - 1];
return function(err) { if (err) callback(err); };
}
}

function inherits(target, source) {


for (var k in source.prototype)
target.prototype[k] = source.prototype[k];
}

sqlite3.cached = {
Database: function(file, a, b) {
if (file === '' || file === ':memory:') {
// Don't cache special databases.
return new Database(file, a, b);
}
if (file[0] !== '/') {
file = path.join(process.cwd(), file);
}

if (!sqlite3.cached.objects[file]) {
var db =sqlite3.cached.objects[file] = new Database(file, a, b);
}
else {
// Make sure the callback is called.
var db = sqlite3.cached.objects[file];
var callback = (typeof a === 'number') ? b : a;
if (typeof callback === 'function') {
function cb() { callback.call(db, null); }
if (db.open) process.nextTick(cb);
else db.once('open', cb);
}
}

return db;
},
objects: {}
};

var Database = sqlite3.Database;


var Statement = sqlite3.Statement;

inherits(Database, EventEmitter);
inherits(Statement, EventEmitter);

// Database#prepare(sql, [bind1, bind2, ...], [callback])


Database.prototype.prepare = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);

if (!params.length || (params.length === 1 && typeof params[0] === 'function'))


{
return new Statement(this, sql, params[0]);
}
else {
var statement = new Statement(this, sql, errorCallback(params));
return statement.bind.apply(statement, params);
}
};

// Database#run(sql, [bind1, bind2, ...], [callback])


Database.prototype.run = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);
var statement = new Statement(this, sql, errorCallback(params));
statement.run.apply(statement, params).finalize();
return this;
};

// Database#get(sql, [bind1, bind2, ...], [callback])


Database.prototype.get = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);
var statement = new Statement(this, sql, errorCallback(params));
statement.get.apply(statement, params).finalize();
return this;
};
// Database#all(sql, [bind1, bind2, ...], [callback])
Database.prototype.all = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);
var statement = new Statement(this, sql, errorCallback(params));
statement.all.apply(statement, params).finalize();
return this;
};

// Database#each(sql, [bind1, bind2, ...], [callback], [complete])


Database.prototype.each = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);
var statement = new Statement(this, sql, errorCallback(params));
statement.each.apply(statement, params).finalize();
return this;
};

Database.prototype.map = function(sql) {
var params = Array.prototype.slice.call(arguments, 1);
var statement = new Statement(this, sql, errorCallback(params));
statement.map.apply(statement, params).finalize();
return this;
};

Statement.prototype.map = function() {
var params = Array.prototype.slice.call(arguments);
var callback = params.pop();
params.push(function(err, rows) {
if (err) return callback(err);
var result = {};
if (rows.length) {
var keys = Object.keys(rows[0]), key = keys[0];
if (keys.length > 2) {
// Value is an object
for (var i = 0; i < rows.length; i++) {
result[rows[i][key]] = rows[i];
}
} else {
var value = keys[1];
// Value is a plain value
for (var i = 0; i < rows.length; i++) {
result[rows[i][key]] = rows[i][value];
}
}
}
callback(err, result);
});
return this.all.apply(this, params);
};

var isVerbose = false;

var supportedEvents = [ 'trace', 'profile', 'insert', 'update', 'delete' ];

Database.prototype.addListener = Database.prototype.on = function(type) {


var val = EventEmitter.prototype.addListener.apply(this, arguments);
if (supportedEvents.indexOf(type) >= 0) {
this.configure(type, true);
}
return val;
};

Database.prototype.removeListener = function(type) {
var val = EventEmitter.prototype.removeListener.apply(this, arguments);
if (supportedEvents.indexOf(type) >= 0 && !this._events[type]) {
this.configure(type, false);
}
return val;
};

Database.prototype.removeAllListeners = function(type) {
var val = EventEmitter.prototype.removeAllListeners.apply(this, arguments);
if (supportedEvents.indexOf(type) >= 0) {
this.configure(type, false);
}
return val;
};

// Save the stack trace over EIO callbacks.


sqlite3.verbose = function() {
return this;
};
#### Do not edit. Generated by the configure script.
{ 'target_defaults': { 'cflags': [],
'default_configuration': 'Release',
'defines': [],
'include_dirs': [],
'libraries': []},
'variables': { 'node_install_npm': 'true',
'node_install_waf': 'true',
'node_prefix': '',
'node_shared_openssl': 'false',
'node_shared_v8': 'false',
'node_shared_zlib': 'false',
'node_use_dtrace': 'false',
'node_use_etw': 'false',
'node_use_openssl': 'true',
'node_tag': '',
'v8_no_strict_aliasing': 1,
'v8_use_snapshot': 'true'}}
####|��#���#�?##���#(��#?###x��#h��#�###l��###�#9�##`��#X��#g###X��#��#�*##
��#h��#�x##H��#P\�#�###8��##k�#�Y##�L�#���#�###���#���#�###|
��#h��#�###0��##��#�;##(��#�!�#3###$��##E�#�####��##^�#�####��##z�#G####��#H��#�###
��#(��#��##t)�#�B�#��##l)�#�#�#�
##T}�#�%�#�:## ��#P`�#�k##��#(��#.####��#X��#�2###��#
#�#H7##��#p>�#v###��#�T�#4r##��# ��#�o###��#�6�#�
##Я�#�C�#�###̯�#XW�#�###į�#H\�#L###���#�v�#��##��#X

�#N###�V�#�#�#�O##���#hh�#P9##���#��#D###d��##��#*1##���#8��#}###���#���###########
######cefode.js###node_buffer#src\node_buffer.cc######ABCDEFGHIJKLMNOPQRSTUVWXYZabc
defghijklmnopqrstuvwxyz0123456789+/########����������������������������������������
�����������������������������������������������������������������������������������
�������������������������������������������������>###����>###����?
###4###5###6###7###8###9###:###;###<###=###����������������������������############
######################## ###
#######
######################################################����������������?
###����######################## ###!###"#######$###
%###&###'###(###)###*###+###,###-
###.###/###0###1###2###3###��������������������������������������������������������
�����������������������������������������������������������������������������������
�����������������������������������������������������������������������������������
�����������������������������������������������������������������������������������
�����������������������������������������������������������������������������������
�����������������������������������������������������������������������������������
�������������������������������������������������������������Buffer##end cannot be
longer than parent.length#Must have start <= end##value is not a number###offset or
length out of range###length out of range#First argument must be a
Buffer#Buffer##sourceEnd out of bounds#sourceStart out of bounds###targetStart out
of bounds###sourceEnd < sourceStart#First arg should be a Buffer####Offset is out
of bounds#Argument must be a string###length > kMaxLength#Bad
argument####makeFastBuffer##byteLength##fill####ucs2Write###base64Write#binaryWrite
#asciiWrite##utf8Write###utf8Slice###ucs2Slice###base64Slice#asciiSlice##binarySlic
e#SlowBuffer##_charsWritten###NPN_ENABLED#SSL_OP_TLS_ROLLBACK_BUG#SSL_OP_TLS_D5_BUG
###SSL_OP_TLS_BLOCK_PADDING_BUG####SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG##SSL_OP_SSLEA
Y_080_CLIENT_DH_BUG#SSL_OP_SINGLE_ECDH_USE##SSL_OP_SINGLE_DH_USE####SSL_OP_PKCS1_CH
ECK_2####SSL_OP_PKCS1_CHECK_1####SSL_OP_NO_TLSv1#SSL_OP_NO_TICKET####SSL_OP_NO_SSLv
3#SSL_OP_NO_SSLv2#SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION###SSL_OP_NO_QUERY_M
TU#SSL_OP_NO_COMPRESSION###SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG#SSL_OP_NETSCAPE_
DEMO_CIPHER_CHANGE_BUG##SSL_OP_NETSCAPE_CHALLENGE_BUG###SSL_OP_NETSCAPE_CA_DN_BUG##
#SSL_OP_MSIE_SSLV2_RSA_PADDING###SSL_OP_MICROSOFT_SESS_ID_BUG####SSL_OP_MICROSOFT_B
IG_SSLV3_BUFFER###SSL_OP_LEGACY_SERVER_CONNECT####SSL_OP_EPHEMERAL_RSA####SSL_OP_DO
NT_INSERT_EMPTY_FRAGMENTS##SSL_OP_CRYPTOPRO_TLSEXT_BUG#SSL_OP_COOKIE_EXCHANGE##SSL_
OP_CISCO_ANYCONNECT#SSL_OP_CIPHER_SERVER_PREFERENCE#SSL_OP_ALLOW_UNSAFE_LEGACY_RENE
GOTIATION####SSL_OP_ALL##WSAEREFUSED#WSA_E_CANCELLED#WSA_E_NO_MORE###WSATYPE_NOT_FO
UND###WSASERVICE_NOT_FOUND####WSASYSCALLFAILURE###WSAEPROVIDERFAILEDINIT##WSAEINVAL
IDPROVIDER#WSAEINVALIDPROCTABLE####WSAECANCELLED###WSAENOMORE##WSAEDISCON##WSANOTIN
ITIALISED###WSAVERNOTSUPPORTED##WSASYSNOTREADY##WSAEREMOTE##WSAESTALE###WSAEDQUOT##
#WSAEUSERS###WSAEPROCLIM#WSAENOTEMPTY####WSAEHOSTUNREACH#WSAEHOSTDOWN####WSAENAMETO
OLONG#WSAELOOP####WSAECONNREFUSED#WSAETIMEDOUT####WSAETOOMANYREFS#WSAESHUTDOWN####W
SAENOTCONN#WSAEISCONN##WSAENOBUFS##WSAECONNRESET###WSAECONNABORTED#WSAENETRESET####
WSAENETUNREACH##WSAENETDOWN#WSAEADDRNOTAVAIL####WSAEADDRINUSE###WSAEAFNOSUPPORT#WSA
EPFNOSUPPORT#WSAEOPNOTSUPP###WSAESOCKTNOSUPPORT##WSAEPROTONOSUPPORT##WSAENOPROTOOPT
##WSAEPROTOTYPE###WSAEMSGSIZE#WSAEDESTADDRREQ#WSAENOTSOCK#WSAEALREADY#WSAEINPROGRES
S##WSAEWOULDBLOCK##WSAEMFILE###WSAEINVAL###WSAEFAULT###WSAEACCES###WSAEBADF####WSAE
INTR####EOPNOTSUPP##E2BIG###O_APPEND####O_TRUNC#O_EXCL##O_CREAT#S_IFLNK#S_IFCHR#S_I
FDIR#S_IFREG#S_IFMT##O_RDWR##O_WRONLY####O_RDONLY####node_
%s#`�###�=#�z##�###node_typed_array####src\v8_typed_array.cc###Int8Array###Uint8Arr
ay##Uint8ClampedArray###Int16Array##Uint16Array#Int32Array##Uint32Array#Float32Arra
y####Float64Array####byteOffset out of range.####byteOffset##byteOffset/byteLength
out of range.#byteLength out of range.####Object must be an ArrayBuffer.##Wrong
number of arguments.##Constructor cannot be called as a function.#Offset/length out
of range.#Offset out of range.####Offset may not be negative.#Index out of
range.#Unable to allocate ArrayBuffer.#ArrayBufferView size is not a small enough
positive
integer.####ArrayBuffer#DataView####getUint8####getInt8#getUint16###getInt16####get
Uint32###getInt32####getFloat32##getFloat64##setUint8####setInt8#setUint16###setInt
16####setUint32###setInt32####setFloat32##setFloat64##Byte offset / length is not
aligned.####Length is out of range.#Length out of range.####Byte offset out of
range.###Byte offset is not
aligned.#BYTES_PER_ELEMENT###subarray####node_sqlite3####src\nw\sqlite3\node_sqlite
3.cc##SQLITE_DONE#SQLITE_ROW##SQLITE_NOTADB###SQLITE_RANGE####SQLITE_FORMAT###SQLIT
E_AUTH#SQLITE_NOLFS####SQLITE_MISUSE###SQLITE_MISMATCH#SQLITE_CONSTRAINT###SQLITE_T
OOBIG###SQLITE_SCHEMA###SQLITE_EMPTY####SQLITE_PROTOCOL#SQLITE_CANTOPEN#SQLITE_FULL
#SQLITE_NOTFOUND#SQLITE_CORRUPT##SQLITE_IOERR####SQLITE_INTERRUPT####SQLITE_READONL
Y#SQLITE_NOMEM####SQLITE_LOCKED###SQLITE_BUSY#SQLITE_ABORT####SQLITE_PERM#SQLITE_IN
TERNAL#SQLITE_ERROR####SQLITE_OK###insert##update##NOTADB##RANGE###FORMAT##AUTH####
NOLFS###MISUSE##MISMATCH####CONSTRAINT##TOOBIG##SCHEMA##EMPTY###PROTOCOL####CANTOPE
N####FULL####NOTFOUND####CORRUPT#IOERR###INTERRUPT###READONLY####NOMEM###LOCKED##BU
SY####ABORT###PERM####VERSION_NUMBER##SOURCE_ID###2011-05-19 13:26:54
ed1da510a239ea767a01dc332b667119fa3c908e####VERSION#3.7.6.3#OPEN_CREATE#OPEN_READWR
ITE##OPEN_READONLY###node_v8_util####src\nw\node_v8_util.cc##getObjectHash###getCre
ationContext##setDestructor###getConstructorName##setHiddenValue##getHiddenValue##n
ode_id_weak_map####src\nw\node_id_weak_map.cc##�####D�# D�#Invalid
arguments###IDWeakMapKey####Element already
exists##allocateId##IDWeakMap###node_fs_event_wrap##src\fs_event_wrap.cc####change#
#rename##Bad arguments###FSEventWrap: Aborting due to unwrap failure at %s:%d
###FSEvent#node_process_wrap###src\process_wrap.cc#onexit##ProcessWrap: Aborting
due to unwrap failure at %s:%d
###fd##wrapType####pipe####stdio###detached####windowsVerbatimArguments####envPairs
####options.gid should be a number##options.uid should be a number##options.gid is
out of range#gid#options.uid is out of
range#unref###kill####spawn###Process#node_tty_wrap###src\tty_wrap.cc#�4##��##FILE#
###PIPE####TTY#TTYWrap: Aborting due to unwrap failure at %s:%d
###guessHandleType#isTTY###setRawMode##getWindowSize###writeUcs2String#writeUtf8Str
ing#writeAsciiString####writeBuffer#readStop####readStart###node_cares_wrap#src\car
es_wrap.cc###(UNKNOWN)###ECANCELLED##EADDRGETNETWORKPARAMS###ELOADIPHLPAPI###ENOTIN
ITIALIZED#EBADHINTS###ENONAME#EBADFLAGS###EBADSTR#EDESTRUCTION####EFILE###ETIMEOUT#
###EBADRESP####EBADFAMILY##EBADNAME####EBADQUERY###EREFUSED####ENOTIMP#ENOTFOUND###
ESERVFAIL###EFORMERR####SUCCESS#0E##�#�#��3#0p�#�
!#0E##�#�#�G##0p�# H##0E##�#�##I##0p�#@I##0E##�#�#0J##0p�#`?
##0E##�#�#`J##0p�#`@##exchange####0E##�#�#�J##0p�#�J##0E##�#�#�K##0p�##B##0E##�#�#�
K##0p�##C##0E##�#�##L##�L##�
!#0E## M##��3#PM##�
!
#oncomplete##AF_UNSPEC###AF_INET6####AF_INET#isIP####getHostByName###getHostByAddr#
##querySrv####queryTxt####queryNs#queryMx#queryCname##queryAaaa###queryA##node_pipe
_wrap##src\pipe_wrap.cc####PipeWrap: Aborting due to unwrap failure at %s:%d
##onconnection####setPendingInstances#listen##shutdown####Pipe####node_udp_wrap###s
rc\udp_wrap.cc#UDPWrap: Aborting due to unwrap failure at %s:%d
###setTTL##setBroadcast####setMulticastLoopback####setMulticastTTL#dropMembership##
addMembership###getsockname#recvStop####recvStart###send6###bind6###UDP#onmessage##
#node_tcp_wrap###src\tcp_wrap.cc#0�##��##TCPWrap: Aborting due to unwrap failure at
%s:%d
###IPv6####IPv4####setSimultaneousAccepts##setKeepAlive####setNoDelay##getpeername#
connect6####node_timer_wrap#src\timer_wrap.cc### �##К##TimerWrap: Aborting due to
unwrap failure at %s:%d
#ontimeout###again###getRepeat###setRepeat###node_zlib###src\node_zlib.cc####��###D
�# D�#Init error##Failed to set dictionary####Failed to reset stream##Zlib
error##Bad dictionary##Missing
dictionary##ZLIB_VERSION####UNZIP###INFLATERAW##DEFLATERAW##GUNZIP##GZIP####INFLATE
#DEFLATE#ZLIB_VERNUM#Z_DEFAULT_STRATEGY##Z_FIXED#Z_RLE###Z_HUFFMAN_ONLY##Z_FILTERED
##Z_DEFAULT_COMPRESSION###Z_BEST_COMPRESSION##Z_BEST_SPEED####Z_NO_COMPRESSION####Z
_VERSION_ERROR#Z_BUF_ERROR#Z_MEM_ERROR#Z_DATA_ERROR####Z_STREAM_ERROR##Z_ERRNO#Z_NE
ED_DICT#Z_STREAM_END####Z_OK####Z_BLOCK#Z_FINISH####Z_FULL_FLUSH####Z_SYNC_FLUSH###
#Z_PARTIAL_FLUSH#Z_NO_FLUSH##callback####Zlib####node_os#src\node_os.cc##gethostnam
e#Windows_NT##speed###model###irq#idle####nice####user####<unknown sa
family>#getInterfaceAddresses###getOSRelease####getOSType###getCPUs#getFreeMem##get
TotalMem#getUptime###getLoadAvg##getHostname#node_http_parser####src\node_http_pars
er.cc# �###D�# D�#Argument must be HTTPParser.REQUEST or
HTTPParser.RESPONSE##bytesParsed#Parse Error#off + len > buffer.length###Argument
should be a buffer#Already parsing a
buffer####shouldKeepAlive#versionMinor####versionMajor####httpVersion#UNKNOWN_METHO
D##PURGE###UNSUBSCRIBE#SUBSCRIBE###NOTIFY##M-
SEARCH####MERGE###CHECKOUT####MKACTIVITY##REPORT##SEARCH##onMessageComplete###onBod
y##onHeadersComplete###onHeaders###reinitialize####finish##execute#RESPONSE####REQU
EST#HTTPParser##node_fs#src\node_file.cc####ctime###mtime###atime###blocks##blksize
#rdev####nlink###ino#dev#stat####path must be a string###path
required###lstat###fstat###symlink#Unknown symlink type####junction####src path
must be a string###dest path must be a string##src path required###dest path
required##readlink####new path must be a string###old path must be a string###new
path required###old path required###ftruncate###Not an
integer##fdatasync###fsync###unlink##rmdir###mkdir###sendfile####readdir#mode must
be an int#flags must be an int####mode required###flags required##Second argument
needs to be a buffer####read####Length extends beyond
buffer####chmod###fchmod##chown###gid must be an int##uid must be an int##gid
required####uid required####fchown##fd must be an int###fd required#utime###mtime
must be a number##atime must be a number##mtime required##atime
required##futime##__buf###node:encoding###futimes#utimes##statNoException#Stats###n
ode_evals##src\node_script.cc##�?###D�# D�#####(function(source, target) {
Object.getOwnPropertyNames(source).forEach(function(key) {
try {
var desc = Object.getOwnPropertyDescriptor(source, key);
if (desc.value === source) desc.value = target;
Object.defineProperty(target, key, desc);
} catch (e) {
// Catch sealed properties errors
}
});
})####binding:script##createContext() accept only object as first
argument.###Must be called as a method of Script.###evalmachine.<anonymous>#needs
at least 'code' argument.#'this' must be a result of previous new Script(code)
call.##needs a 'context'
argument.#runInNewContext#runInThisContext####runInContext####createContext###NodeS
cript##node_crypto#src\node_crypto.cc######-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD
T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4
MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG
A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk
WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD
YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew
MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb
m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk
HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT
xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2
3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9
2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq
TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz
4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU
9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg
aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP
eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk
zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1
ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI
KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq
nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE
I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp
MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o
tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA
c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw
DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG
SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy
aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf
TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC
+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw
UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa
Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF
MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD
HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh
AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA
cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr
AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw
cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G
A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo
ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL
abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678
IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh
Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2
yyqcjg==
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK
QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw
MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz
bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm
GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD
Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo
hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt
ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w
gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P
AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz
aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff
ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa
BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t
WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3
mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K
ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA
4Z7CRneC9VkGjCFMhwnN5ag=
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC
TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ
5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn
vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj
CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil
e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR
OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI
CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65
48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi
trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737
qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB
AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC
ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA
A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz
+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj
f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk
CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF
URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb
CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h
oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV
IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
66+KAQ==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
mJO37M2CYfE45k+XmCpajQ==
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
npaqBA+K
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT
SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw
MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl
cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4
fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN
wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE
jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu
nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU
WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV
BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD
vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs
o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g
/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD
io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW
dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
rosot4LKGAfmt1t06SAZf7IbiVQ=
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE
ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw
OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD
o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz
VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT
VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or
czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK
y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC
wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S
lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5
Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM
O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8
BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2
G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m
mxE=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF
bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg
QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe
Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p
ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt
IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by
X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b
gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr
eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ
TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy
Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn
uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI
qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm
ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0
Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW
Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t
FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm
zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k
XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT
bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU
RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK
1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt
2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ
Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9
AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1
MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx
ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0
n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia
AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c
1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC
MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P
AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7
pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA
EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5
htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj
el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2
MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M
cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83
0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4
0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R
uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC
MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P
AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV
1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt
7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2
fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w
wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH
DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q
aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry
b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV
BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg
S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4
MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl
IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF
n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl
IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft
dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl
cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO
Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1
xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR
6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd
BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4
N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT
y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh
LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M
dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
WL1WMRJOEcgh4LMRkWXbtKaIOM5V
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE
AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w
NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD
QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs
49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH
7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB
kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1
9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw
AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t
U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA
j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC
AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a
BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp
FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP
51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD
EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy
MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp
Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q
ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy
P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN
GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk
YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM
rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy
oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P
AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+
VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2
QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI
mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb
/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG
zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U
AGegcQCCSA==
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
Cm26OWMohpLzGITY+9HPBVZkVw==
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN
MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg
VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw
JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC
qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv
xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw
ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O
gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j
BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG
1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy
vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3
ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a
7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw
MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE
AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W
yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo
6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ
uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk
2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB
7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE
O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8
yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9
IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal
092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc
5A==
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw
MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE
AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw
IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2
xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ
Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u
SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB
7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G
dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ
KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj
TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP
JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
vQ==
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT
AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg
LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w
HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+
U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh
IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN
yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU
2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3
4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP
2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm
8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf
HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa
Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK
5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b
czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g
ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF
BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug
cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf
AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX
EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v
/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3
MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4
3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk
eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f
/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h
RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU
Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ==
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE
BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL
EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0
MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz
dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT
GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG
d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N
oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc
QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ
PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb
MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG
IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD
VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3
LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A
dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA
4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg
AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA
egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6
Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO
PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv
c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h
cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw
IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT
WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV
MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER
MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp
Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal
HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT
nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE
aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK
yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB
S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh
cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT
LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w
NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk
ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj
aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp
b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob
4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL
g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf
eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3
KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB
/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv
bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU
D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD
pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08
P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA
nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit
F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b
Hz2eBIPdltkdOpQ=
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh
dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE
BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl
Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO
/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX
WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z
ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4
bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK
9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm
iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG
Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW
mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW
T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD
VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE
Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy
MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI
EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT
STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2
TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW
So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy
HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd
frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ
tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB
egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC
iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK
q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q
MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI
lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF
0mBWWg==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIEMjCCA5ugAwIBAgIBQjANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
bmVzcyBDQS0xMB4XDTA0MDczMTAwMDAwMVoXDTA0MDkwMjAwMDAwMVowPDE6MDgGA1UEAxMxTUQ1
IENvbGxpc2lvbnMgSW5jLiAoaHR0cDovL3d3dy5waHJlZWRvbS5vcmcvbWQ1KTCBnzANBgkqhkiG
9w0BAQEFAAOBjQAwgYkCgYEAuqZZySwo1iqw+O2fRqSkN+4OGWhZ0bMDmVHWFppeN2sV4A5L9YRk
+KPbQW811ZsVH9vEOFJwgZdej6C193458DKsHq1E0rP6SMPOkZvs9Jx84Vr1yDdrmoPe58oglzFC
cxWRaPSIr/koKMXpD3OwF0sTTJl10ETmfghsGvJPG0ECAwEAAaOCAiQwggIgMAsGA1UdDwQEAwIB
xjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSnBGAfq3JDCMV/CJBVVhzWzuY46zAfBgNVHSME
GDAWgBS+qKB0clBrRLfJI9j7qP+zV2tobDCCAb4GCWCGSAGG+EIBDQSCAa8WggGrMwAAACdeOeCJ
YQ9Oo8VFCza7AdFTqsMIj2/4Tz6Hh0QR3GDg35JV+bhzG1STxZ/QRsRgtjVizbmvHKhpGslbPJY3
wO1n77v+wIucUC8pvYMino4I+qwTcKJYf2JiihH3ifbftmdZcxb7YxaKtJE4zi71tr5MpJRJ5GUR
CkIVycEw4mnVRX2lJru5YexiZPA54ee8aNhQUZ4dYNPRo6cK+AMgoXABF5E2TwJwMYaD3fcP2Acd
EbMTBKXc8K5QsSgOY2kqDIJvj0cz32yiBpLxT0W+2TA2oyuM1neuNWN/Tkyak0g22Z8CAwEAAaOB
vTCBujAOBgNVHQ8BAf8EBAMCBPAwHQYDVR0OBBYEFM2mg/qlYDf3ljcXKd5BePGHiVXnMDsGA1Ud
HwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmwuZ2VvdHJ1c3QuY29tL2NybHMvZ2xvYmFsY2ExLmNybDAf
BgNVHSMEGDAWgBS+qKB0clBrRLfJI9j7qP+zV2tobDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
BQUHAwIwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQQFAAOBgQCnIQKN0Q6igHcl/UNgFY/s75BH
1IRCFSYRHM3CPBApqbbfq1d1kdrlK7OQRRwwY1Y/itlQ+u1YbMBlrGZX3hzGdjv1AA6ORc5/TJDs
K8bNs7SPYtD+t8UmckTt9phbrsvRlfXaCL5oRrF1yOwdjx56lPGqU3iiRa5U6tGedMh2Zw==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM
F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw
NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl
bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD
VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1
iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13
i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8
bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB
K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB
AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu
cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm
lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB
i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww
GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI
K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0
bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj
qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es
E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ
tylv2G0xffX8oRAHh84vWdw+WNs=
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCQ0gxFTAT
BgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIw
HhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAwWjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMM
U3dpc3NTaWduIEFHMSMwIQYDVQQDExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu
669yIIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2HtnIuJpX+UF
eNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+6ixuEFGSzH7VozPY1kne
WCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5objM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIo
j5+saCB9bzuohTEJfwvH6GXp43gOCWcwizSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/6
8++QHkwFix7qepF6w9fl+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34T
aNhxKFrYzt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaPpZjy
domyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtFKwH3HBqi7Ri6Cr2D
+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuWae5ogObnmLo2t/5u7Su9IPhlGdpV
CX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMBAAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCv
zAeHFUdvOMW0ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW
IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUAA4ICAQAIhab1
Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0uMoI3LQwnkAHFmtllXcBrqS3
NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4
U99REJNi54Av4tHgvI42Rncz7Lj7jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8
KV2LwUvJ4ooTHbG/u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl
9x8DYSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1puEa+S1B
aYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXaicYwu+uPyyIIoK6q8QNs
OktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbGDI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSY
Mdp08YSTcU1f+2BY0fvEwW2JorsgH51xkcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAci
IfNAChs0B0QTwoRqjt8ZWr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g==
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF
bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN
MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr
dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G
A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe
LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI
x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g
QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr
5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB
AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt
Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+
hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P
9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5
UrbnBEI=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP
MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0
acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx
MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg
U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB
TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC
aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX
yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i
Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ
8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4
W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME
BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46
sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE
q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY
nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG
EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT
MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha
MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE
CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI
DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa
pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow
GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy
MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu
Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy
dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU
CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2
5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t
Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs
vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
oKfN5XozNmr6mis=
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
l7+ijrRU
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG
EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4
MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC
IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM
MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF
NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe
AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC
b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn
7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN
cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp
WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5
haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY
MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9
MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn
jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ
MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H
VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl
vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl
OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3
1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq
nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy
x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW
NY6E0F/6MBr1mmz0DlP5OlvRHA==
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV
BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl
bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv
MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX
x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3
E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5
OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j
sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj
YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF
BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD
ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv
m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R
OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023
tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT
GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp
Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA
ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL
MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT
OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2
ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V
j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH
lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf
3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8
NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww
KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG
AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud
DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD
ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf
wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm
7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG
VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG
EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv
dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN
w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5
BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O
1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO
htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov
J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB
O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV
HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2
09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj
Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2
Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU
D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz
DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk
Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk
7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ
CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0
Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj
YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH
AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw
Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg
U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5
LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh
cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT
dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC
AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh
3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm
vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk
fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3
fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ
EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl
1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/
lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro
g14=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
vZ8=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT
CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD
KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ
BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j
ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB
jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z
W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63
euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw
DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN
RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn
YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB
IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i
aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0
ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo
dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y
emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k
IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ
UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg
YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2
xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW
gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A==
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg
VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD
VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv
bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg
VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S
o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr
1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ
RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh
dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0
ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv
c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg
YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz
Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA
bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl
IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2
YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj
cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM
43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR
stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI
EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j
ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX
DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH
EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD
VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz
cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM
D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ
z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC
/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7
tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6
4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG
A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC
Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv
bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn
LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0
ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz
IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh
IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu
b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh
bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg
Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp
bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5
ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP
ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB
CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr
KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
8CgHrTwXZoi1/baI
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT
CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV
BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn
eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0
bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER
MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0
LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0
dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP
aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV
CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e
8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb
m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ
0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM
0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV
HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2
YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh
biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p
a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz
YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg
YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg
ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov
L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr
Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0
aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg
YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0
IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3
DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN
wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg
W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc
R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR
5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx
NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt
YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg
MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw
ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J
1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O
by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl
6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c
8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/
BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j
aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B
Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj
aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y
ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA
PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y
gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ
PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4
IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx
NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp
cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn
MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC
AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU
xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH
NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW
DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV
d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud
EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v
cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P
AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh
bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD
VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi
fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD
L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN
UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n
ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1
erfutGWaIZDgqtCYvDi1czyL+Nw=
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb
BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz
NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx
HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy
dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR
loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ
w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu
lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7
RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL
BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8
ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly
c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw
DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw
NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO
PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE
qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG
hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd
BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx
OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0
eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz
ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI
wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd
tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8
i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf
Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw
gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF
lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF
UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW
XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2
lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn
iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67
nfhmqA==
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0
BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05
OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx
FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx
ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz
dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx
B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8
om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG
TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl
yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE
AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV
HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll
bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH
AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne
xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+
5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV
NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ
w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ=
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ
BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa
MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w
HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy
dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys
raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo
wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA
9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv
33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud
DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9
BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD
LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0
I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx
EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP
DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE
ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5
MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH
nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0
zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV
iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde
dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO
3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB
5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k
ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm
cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp
Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x
LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM
MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm
aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy
MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647
+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6
NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4
A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc
A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9
AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1
AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE
ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx
NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu
ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j
xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL
znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc
5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6
otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI
AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM
VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM
MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC
AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe
UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G
CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m
gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb
O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU
Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE
ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g
Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w
HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh
bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt
vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P
jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca
C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth
vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6
22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV
HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v
dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN
BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR
EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw
MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
llpwrN9M
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw
NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88
7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9
EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl
0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645
2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa
HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT
iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9
28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV
yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR
vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P
qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z
IRlXvVWa
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
FL39vmwLAw==
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
5nrQNiOKSnQ2+Q==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYTAkVTMRIwEAYDVQQI
EwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1
Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAg
Qi02MDkyOTQ1MjE0MDIGA1UECxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTE0MDIGA1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMTAxOFoXDTI1
MTIyNzAxMTAxOFowggEeMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQH
EwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMu
bC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxNDAyBgNVBAsT
K0lQUyBDQSBUaW1lc3RhbXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQ
UyBDQSBUaW1lc3RhbXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEW
D2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLjuVqWajOY2ycJi
oGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4Efdo/BdApWgnMjvEp+ZCccWZ73b/
K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6KaFYq6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0Gm
qaMCAwEAAaOCBIAwggR8MB0GA1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSC
AUcwggFDgBSL0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkGA1UEBhMCRVMxEjAQ
BgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJu
ZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5J
LkYuICBCLTYwOTI5NDUyMTQwMgYDVQQLEytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRp
b24gQXV0aG9yaXR5MTQwMgYDVQQDEytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB
/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMG
CCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYK
KwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVz
MBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5n
IENBIENlcnRpZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC
BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFodHRwOi8vd3d3
Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMEUGCWCGSAGG+EIBAwQ4FjZo
dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25UaW1lc3RhbXBpbmcuaHRtbD8wQgYJ
YIZIAYb4QgEHBDUWM2h0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGlu
Zy5odG1sPzBABglghkgBhvhCAQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lU
aW1lc3RhbXBpbmcuaHRtbDB/BgNVHR8EeDB2MDegNaAzhjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMy
MDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFjay5pcHMuZXMv
aXBzMjAwMi9pcHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUH
MAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAZbrBzAAalZHK6Ww6vzoe
FAh8+4Pua2JR0zORtWB5fgTYXXk36MNbsMRnLWhasl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWT
s/zif/WN87GphV+I3pGW7hdbrqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU=
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQI
EwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1
Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAg
Qi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJ
KoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNzUwWhcNMjUxMjI3MDEwNzUw
WjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9u
YTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENM
QVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwgZ8w
DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO6AAPYaZC6tasiDsYun7o/ZttvNG7uGBiJ2MwwSbUhW
YdLcgiViL5/SaTBlA0IjWLxH3GvWdV0XPOH/8lhneaDBgbHUVqLyjRGZ/fZ98cfEXgIqmuJKtROK
AP2Md4bm15T1IHUuDky/dMQ/gT6DtKM4Ninn6Cr1jIhBqoCm42zvAgMBAAGjggRTMIIETzAdBgNV
HQ4EFgQUHp9XUEe2YZM50yz82l09BXW3mQIwggFGBgNVHSMEggE9MIIBOYAUHp9XUEe2YZM50yz8
2l09BXW3mQKhggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ
BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2Vydmlj
ZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0G
A1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQ
UyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNA
bWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsG
AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB
FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcw
GgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBC
BglghkgBhvhCAQ0ENRYzQ0xBU0VBMyBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3
dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7Bglg
hkgBhvhCAQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMy5jcmww
QAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2b2NhdGlvbkNMQVNF
QTMuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdh
bENMQVNFQTMuaHRtbD8wOwYJYIZIAYb4QgEIBC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIv
cG9saWN5Q0xBU0VBMy5odG1sMHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lw
czIwMDIvaXBzMjAwMkNMQVNFQTMuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz
MjAwMi9pcHMyMDAyQ0xBU0VBMy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUFBzABhhNodHRw
Oi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAEo9IEca2on0eisxeewBwMwB9dbB/MjD
81ACUZBYKp/nNQlbMAqBACVHr9QPDp5gJqiVp4MI3y2s6Q73nMify5NF8bpqxmdRSmlPa/59Cy9S
KcJQrSRE7SOzSMtEQMEDlQwKeAYSAfWRMS1Jjbs/RU4s4OjNtckUFQzjB4ObJnXv
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQI
EwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1
Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAg
Qi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJ
KoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNTMyWhcNMjUxMjI3MDEwNTMy
WjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9u
YTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE
ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENM
QVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwgZ8w
DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsw19zQVL01Tp/FTILq0VA8R5j8m2mdd81u4D/u6zJf
X5/S0HnllXNEITLgCtud186Nq1KLK3jgm1t99P1tCeWu4WwdByOgF9H5fahGRpEiqLJpxq339fWU
oTCUvQDMRH/uxJ7JweaPCjbB/SQ9AaD1e+J8eGZDi09Z8pvZ+kmzAgMBAAGjggRTMIIETzAdBgNV
HQ4EFgQUZyaW56G/2LUDnf473P7yiuYV3TAwggFGBgNVHSMEggE9MIIBOYAUZyaW56G/2LUDnf47
3P7yiuYV3TChggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ
BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2Vydmlj
ZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0G
A1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQ
UyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNA
bWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsG
AQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB
FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcw
GgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBC
BglghkgBhvhCAQ0ENRYzQ0xBU0VBMSBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3
dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7Bglg
hkgBhvhCAQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMS5jcmww
QAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2b2NhdGlvbkNMQVNF
QTEuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdh
bENMQVNFQTEuaHRtbD8wOwYJYIZIAYb4QgEIBC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIv
cG9saWN5Q0xBU0VBMS5odG1sMHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lw
czIwMDIvaXBzMjAwMkNMQVNFQTEuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz
MjAwMi9pcHMyMDAyQ0xBU0VBMS5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUFBzABhhNodHRw
Oi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAH66iqyAAIQVCtWYUQxkxZwCWINmyq0e
B81+atqAB98DNEock8RLWCA1NnHtogo1EqWmZaeFaQoO42Hu6r4okzPV7Oi+xNtff6j5YzHIa5bi
KcJboOeXNp13XjFr/tOn2yrb25aLH2betgPAK7N41lUH5Y85UN4HI3LmvSAUS7SG
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVTMRIwEAYDVQQI
EwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1
Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAg
Qi02MDkyOTQ1MjEuMCwGA1UECxMlSVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTEuMCwGA1UEAxMlSVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqG
SIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMDE0NFoXDTI1MTIyNzAxMDE0NFow
ggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmEx
LjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoU
Imlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFT
RTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTMgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAqxf+DrDGaBtT8FK+n/ra+osTBLsBjzLZH49NzjaY2uQARIwo
2BNEKqRrThckQpzTiKRBgtYj+4vJhuW5qYIF3PHeH+AMmVWY8jjsbJ0gA8DvqqPGZARRLXgNo9Ko
OtYkTOmWehisEyMiG3zoMRGzXwmqMHBxRiVrSXGAK5UBsh8CAwEAAaOCBEowggRGMB0GA1UdDgQW
BBS4k/8uy9wsjqLnev42USGjmFsMNDCCAUQGA1UdIwSCATswggE3gBS4k/8uy9wsjqLnev42USGj
mFsMNKGCARqkggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE
BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBz
LmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS4wLAYDVQQL
EyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0Eg
Q0xBU0UzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5p
cHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMB
BggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYB
BAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0R
BBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBBBglghkgB
hvhCAQ0ENBYyQ0xBU0UzIENBIENlcnRpZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5l
cy8wKQYJYIZIAYb4QgECBBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIB
BAQtFitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMuY3JsMD8GCWCGSAGG
+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25DTEFTRTMuaHRtbD8w
PAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFMy5o
dG1sPzA6BglghkgBhvhCAQgELRYraHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFT
RTMuaHRtbDBzBgNVHR8EbDBqMDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIw
MDJDTEFTRTMuY3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy
Q0xBU0UzLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5l
cy8wDQYJKoZIhvcNAQEFBQADgYEAF2VcmZVDAyevJuXr0LMXI/dDqsfwfewPxqmurpYPdikc4gYt
fibFPPqhwYHOU7BC0ZdXGhd+pFFhxu7pXu8Fuuu9D6eSb9ijBmgpjnn1/7/5p6/ksc7C0YBCJwUE
NPjDfxZ4IwwHJPJGR607VNCv1TGyr33I6unUVtkOE7LFRVA=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVTMRIwEAYDVQQI
EwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1
Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAg
Qi02MDkyOTQ1MjEuMCwGA1UECxMlSVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTEuMCwGA1UEAxMlSVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqG
SIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAwNTkzOFoXDTI1MTIyNzAwNTkzOFow
ggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmEx
LjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoU
Imlwc0BtYWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFT
RTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTEgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEA4FEnpwvdr9G5Q1uCN0VWcu+atsIS7ywSzHb5BlmvXSHU0lq4
oNTzav3KaY1mSPd05u42veiWkXWmcSjK5yISMmmwPh5r9FBSYmL9Yzt9fuzuOOpi9GyocY3h6YvJ
P8a1zZRCb92CRTzo3wno7wpVqVZHYUxJZHMQKD/Kvwn/xi8CAwEAAaOCBEowggRGMB0GA1UdDgQW
BBTrsxl588GlHKzcuh9morKbadB4CDCCAUQGA1UdIwSCATswggE3gBTrsxl588GlHKzcuh9morKb
adB4CKGCARqkggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE
BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBz
LmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMS4wLAYDVQQL
EyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0Eg
Q0xBU0UxIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5p
cHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMB
BggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYB
BAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0R
BBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBBBglghkgB
hvhCAQ0ENBYyQ0xBU0UxIENBIENlcnRpZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5l
cy8wKQYJYIZIAYb4QgECBBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIB
BAQtFitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEuY3JsMD8GCWCGSAGG
+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25DTEFTRTEuaHRtbD8w
PAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFMS5o
dG1sPzA6BglghkgBhvhCAQgELRYraHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFT
RTEuaHRtbDBzBgNVHR8EbDBqMDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIw
MDJDTEFTRTEuY3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy
Q0xBU0UxLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5l
cy8wDQYJKoZIhvcNAQEFBQADgYEAK9Dr/drIyllq2tPMMi7JVBuKYn4VLenZMdMu9Ccj/1urxUq2
ckCuU3T0vAW0xtnIyXf7t/k0f3gA+Nak5FI/LEpjV4F1Wo7ojPsCwJTGKbqz3Bzosq/SLmJbGqmO
DszFV0VRFOlOHIilkfSj945RyKm+hjM+5i9Ibq9UkE6tsSU=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARwxCzAJBgNVBAYTAkVTMRIwEAYDVQQI
EwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1
Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAg
Qi02MDkyOTQ1MjEzMDEGA1UECxMqSVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MTMwMQYDVQQDEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczAeFw0wMTEyMjkwMDUzNThaFw0yNTEy
MjcwMDUzNThaMIIBHDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJ
QmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwu
MSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTMwMQYDVQQLEypJ
UFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBD
QSBDaGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPaXBz
QG1haWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcVpJJspQgvJhPUOtopKdJ
C7/SMejHT8KGC/po/UNaivNgkjWZOLtNA1IhW/A3mTXhQSCBhYEFcYGdtJUZqV92NC5jNzVXjrQf
Qj8VXOF6wV8TGDIxya2+o8eDZh65nAQTy2nBBt4wBrszo7Uf8I9vzv+W6FS+ZoCua9tBhDaiPQID
AQABo4IEQzCCBD8wHQYDVR0OBBYEFKGtMbH5PuEXpsirNPxShwkeYlJBMIIBTgYDVR0jBIIBRTCC
AUGAFKGtMbH5PuEXpsirNPxShwkeYlJBoYIBJKSCASAwggEcMQswCQYDVQQGEwJFUzESMBAGA1UE
CBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBw
dWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g
IEItNjA5Mjk0NTIxMzAxBgNVBAsTKklQUyBDQSBDaGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTEzMDEGA1UEAxMqSVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9y
aXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNV
HQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUF
BwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGC
NwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud
EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ2hhaW5lZCBDQSBDZXJ0aWZp
Y2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8v
d3d3Lmlwcy5lcy9pcHMyMDAyLzA3BglghkgBhvhCAQQEKhYoaHR0cDovL3d3dy5pcHMuZXMvaXBz
MjAwMi9pcHMyMDAyQ0FDLmNybDA8BglghkgBhvhCAQMELxYtaHR0cDovL3d3dy5pcHMuZXMvaXBz
MjAwMi9yZXZvY2F0aW9uQ0FDLmh0bWw/MDkGCWCGSAGG+EIBBwQsFipodHRwOi8vd3d3Lmlwcy5l
cy9pcHMyMDAyL3JlbmV3YWxDQUMuaHRtbD8wNwYJYIZIAYb4QgEIBCoWKGh0dHA6Ly93d3cuaXBz
LmVzL2lwczIwMDIvcG9saWN5Q0FDLmh0bWwwbQYDVR0fBGYwZDAuoCygKoYoaHR0cDovL3d3dy5p
cHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0FDLmNybDAyoDCgLoYsaHR0cDovL3d3d2JhY2suaXBzLmVz
L2lwczIwMDIvaXBzMjAwMkNBQy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUFBzABhhNodHRw
Oi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAERyMJ1WWKJBGyi3leGmGpVfp3hAK+/b
lkr8THFj2XOVvQLiogbHvpcqk4A0hgP63Ng9HgfNHnNDJGD1HWHc3JagvPsd4+cSACczAsDAK1M9
2GsDgaPb1pOVIO/Tln4mkImcJpvNb2ar7QMiRDjMWb2f2/YHogF/JsRj9SVCXmK9
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw
MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h
bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw
IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7
3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y
/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6
juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS
ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud
DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp
ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl
cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA
BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l
R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O
9y5Xt5hwXsjEeLBi
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw
MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi
BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP
9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc
rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC
oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V
p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E
FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj
YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm
aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL
DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw
pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H
RR3B7Hzs/Sk=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK
ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla
Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u
by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x
wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL
kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ
89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K
Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P
NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+
GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg
GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/
0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS
qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRFMRAwDgYDVQQI
EwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFUQyBUcnVzdENlbnRlciBmb3Ig
U2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJIMSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBD
bGFzcyAzIENBMSkwJwYJKoZIhvcNAQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05
ODAzMDkxMTU5NTlaFw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFt
YnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3Vy
aXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3Mg
MyBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVAdHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZI
hvcNAQEBBQADgY0AMIGJAoGBALa0wTUFLg2N7KBAahwOJ6ZQkmtQGwfeLud2zODa/ISoXoxjaitN
2U4CdhHBC/KNecoAtvGwDtf7pBc9r6tpepYnv68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+7
7uMMfTDWw1Krj10nnGvAo+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3LnRydXN0Y2VudGVy
LmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0GCSqGSIb3DQEBBAUAA4GBABY9xs3B
u4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4iJIETb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm
5gZOngylerpuw3yCGdHHsbHD2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQS
CdS7kjXvD9s0
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRFMRAwDgYDVQQI
EwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFUQyBUcnVzdENlbnRlciBmb3Ig
U2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJIMSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBD
bGFzcyAyIENBMSkwJwYJKoZIhvcNAQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05
ODAzMDkxMTU5NTlaFw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFt
YnVyZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9yIFNlY3Vy
aXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3Mg
MiBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVAdHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZI
hvcNAQEBBQADgY0AMIGJAoGBANo46O0yAClxgwENv4wB3NrGrTmkqYov1YtcaF9QxmL1Zr3KkSLs
qh1R1z2zUbKDTl3LSbDwTFXlay3HhQswHJJOgtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5N
u6hLVxa8/vhYnvgpjbB7zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3LnRydXN0Y2VudGVy
LmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0GCSqGSIb3DQEBBAUAA4GBAIRS+yjf
/x91AbwBvgRWl2p0QiQxg/lGsQaKic+WLDO/jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ2
9ELw+HkuCkhcq8xRT3h2oNmsGb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/Ac
ASZ4smZHcFFk
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
398znM/jra6O1I7mT1GvFpLgXPYHDw==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG
A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en
fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8
f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO
qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN
RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0
gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn
6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid
FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6
Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj
B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op
aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY
T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p
+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg
JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy
zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO
ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh
1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf
GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff
Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP
cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk=
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG
A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg
T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG
v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z
DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh
sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP
8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z
o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf
GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF
VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft
3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g
Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp
BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5
WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T
YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB
cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug
mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj
DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu
Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi
P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE
j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w
HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j
cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G
CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y
IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK
RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp
xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq
DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
P/rmMuGNG2+k5o7Y+SlIis5z/iw=
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw
MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/
NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k
LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA
Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b
HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH
K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7
srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh
ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL
OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC
x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF
H4z1Ir+rzoPz4iIprn2DQKi6bA==
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
Mw==
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK
ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy
MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb
BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7
Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb
WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH
KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP
+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/
MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E
FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY
v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj
0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj
VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395
nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA
pKnXwiJPZ9d37CAFYd4=
-----END CERTIFICATE-----
##-----BEGIN CERTIFICATE-----
MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUFADBiMRIwEAYDVQQK
EwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEvMC0GA1UEAxMmYmVUUlVT
VGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRpb24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEy
MTEwNzI1WjBiMRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENB
czEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRpb24wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQwCY5X0LkGLG9uJIAiv11DpvpPrILnHGhwhRuj
brWqeNluB0s/6d/16uhUoWGKDi9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I1DpAa5LxmZZk3tv/ePTu
lh1HiXzUvrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPktPDgaTuID0GQ+NRxQyTBjyZLO1bp/4xs
N+lFrYWMU8NghpBKlsmzVLC7F/AcRdnUGxlkVgoZ98zh/4avflherHqQH8koOUV7orbHnB/ahdQh
hlkwk75TMzf270HPM8ercmsl9fNTGwxMLvF1S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMB
AAGjggIYMIICFDAMBgNVHRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+AAAD
CSiDkTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVjdHNf
c2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIBOhqCATZSZWxpYW5jZSBvbiBvciB1
c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBjcmVhdGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2Nl
cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlv
bnMgb2YgdXNlLCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQgYW5kIHRoZSBS
ZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IHRoZSBiZVRSVVNU
ZWQgd2ViIHNpdGUsIGh0dHA6Ly93d3cuYmV0cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9p
bmRleC5odG1sMAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBSp7BR++dlDzFMrFK3P9/BZiUHNGTAd
BgNVHQ4EFgQUqewUfvnZQ8xTKxStz/fwWYlBzRkwDQYJKoZIhvcNAQEFBQADggEBANuXsHXqDMTB
mMpWBcCorSZIry0g6IHHtt9DwSwddUvUQo3neqh03GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05
pmuKmET7m9cqg5c0Lcd9NUwtNLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbdLrML3kqN
Wz2rDcI1UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28BbJ1zTcwfBwvNMm2+fG8oe
qqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3SK41ty8ymmFei74pnykkiFY5LKjSq5YD
WtRIn7lAhAuYaPsBQ9Yb4gmxlxw=
-----END CERTIFICATE-----
#####-----BEGIN CERTIFICATE-----
MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwliZVRSVVNUZWQx
GzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMqYmVUUlVTVGVkIFJvb3QgQ0Eg
LSBFbnRydXN0IEltcGxlbWVudGF0aW9uMB4XDTAyMDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1ow
ZjESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNV
BAMTKmJlVFJVU1RlZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1Q+xVkrYwfTVXDNvzDSduTPdQqJtOK2/b9a0c
S12zqcH+e0TrW6MFDR/FNCswACnxeECypP869AGIF37m1CbTukzqMvtDd5eHI8XbQ6P1KqNRXuE7
0mVpflUVm3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdjDheT389Lrm5zdeDzqrmkwAkbhepxKYhB
MvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCeyv78IZTuEyhL11xeDGbu6bsPwTSxfwh28z0mcMmLJR1i
JAzqHHVOwBLkuhMdMCktVjMFu5dZfsZJT4nXLySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOC
AwUwggMBMIIBtwYDVR0gBIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYIKwYB
BQUHAgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNyZWF0
ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9u
IFByYWN0aWNlIFN0YXRlbWVudCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGlj
aCBjYW4gYmUgZm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0cHM6Ly93d3cuYmV0
cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMEIGCCsGAQUFBwIBFjZodHRw
czovL3d3dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwEQYJYIZI
AYb4QgEBBAQDAgAHMIGJBgNVHR8EgYEwfzB9oHugeaR3MHUxEjAQBgNVBAoTCWJlVFJVU1RlZDEb
MBkGA1UECxMSYmVUUlVTVGVkIFJvb3QgQ0FzMTMwMQYDVQQDEypiZVRSVVNUZWQgUm9vdCBDQSAt
IEVudHJ1c3QgSW1wbGVtZW50YXRpb24xDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0
MTEwODI0MjdagQ8yMDIyMDQxMTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFH1w5a44
iwY/qhwaj/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQwqoSEFjAMBgNVHRMEBTAD
AQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEAKrgX
zh8QlOu4mre5X+za95IkrNySO8cgjfKZ5V04ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevd
kObRVlTa4y0MnxEylCIBevZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/
T220Y/ozADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2KjiS2d2kXgCl
zMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFiaDrmLzfzgYYhxKlkqu9FNtEaZnz4
6TfW1mG+oq1I59/mdP7TbX3SJdysYlep9w==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwliZVRSVVNUZWQx
GzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMqYmVUUlVTVGVkIFJvb3QgQ0Et
QmFsdGltb3JlIEltcGxlbWVudGF0aW9uMB4XDTAyMDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVow
ZjESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNV
BAMTKmJlVFJVU1RlZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBALx+xDmcjOPWHIb/ymKt4H8wRXqOGrO4x/nRNv8i805qX4QQ
+2aBw5R5MdKR4XeOGCrDFN5R9U+jK7wYFuK13XneIviCfsuBH/0nLI/6l2Qijvj/YaOcGx6Sj8Co
Cd8JEey3fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92BFODEPM2dMPgwqZfT7syj0B9fHBOB1Bir
lNFjw55/NZKeX0Tq7PQiXLfoPX2k+YmpkbIq2eszh+6l/ePazIjmiSZuxyuC0F6dWdsU7JGDBcNe
DsYq0ATdcT0gTlgn/FP7eHgZFLL8kFKJOGJgB7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOC
Ah4wggIaMA8GA1UdEwEB/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4AAAEJ
KIORMTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3IgdXNlIG9mIHRoaXMg
Q2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVudCBhbmQgYWNjZXB0YW5jZSBvZiB0
aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwg
dGhlIENlcnRpZmljYXRpb24gUHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0
eSBBZ3JlZW1lbnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVTVGVkIHdlYiBzaXRl
LCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDBB
BggrBgEFBQcCARY1aHR0cDovL3d3dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2VzL2lu
ZGV4Lmh0bWwwHQYDVR0OBBYEFEU9w6nR3D8kVpgccxiIav+DR+22MB8GA1UdIwQYMBaAFEU9w6nR
3D8kVpgccxiIav+DR+22MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEASZK8o+6s
vfoNyYt5hhwjdrCAWXf82n+0S9/DZEtqTg6t8n1ZdwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyX
EHu67RMdmgduyzFiEuhjA6p9beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AYgkHNZTfq
jjJ+vWuZXTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb4cV97yHgjQ5dUX2xZ/2j
vTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9CReJf8Py05yc493EG931t3GzUwWJBtDL
SoDByFOQtTwxiBdQn8nEDovYqAJjDQ==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMxHTAbBgNVBAoT
FEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNhIE9ubGluZSBJbmMuMTcwNQYD
VQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAy
MDUyOTA2MDAwMFoXDTM3MDkyODIzNDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wg
VGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMu
QU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZI
hvcNAQEBBQADggIPADCCAgoCggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ7ouZzU9AhqS2TcnZsdw8
TQ2FTBVsRotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilbm2BPJoPRYxJWSXakFsKlnUWsi4SVqBax
7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOYxFSMFkpBd4aVdQxHAWZg/BXxD+r1FHjHDtdugRxev17n
OirYlxcwfACtCJ0zr7iZYYCLqJV+FNwSbKTQ2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2w
TPDaRrbqJS5Gr42whTg0ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fxI2rS
AG2X+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETzkxmlJ85per5n0/xQ
pCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFhEVsVS6kkUfykXPcXnbDS+gfpj1bk
GoxoigTTfFrjnqKhynFbotSg5ymFXQNoKk/SBtc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuW
CpTehTacyH+BCQJJKg71ZDIMgtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1Ex
MVCgyhwn2RAurda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaAFE9pbQN+nZ8HGEO8txBO1b+pxCAoMA4G
A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAO/Ouyuguh4X7ZVnnrREUpVe8WJ8kEle7
+z802u6teio0cnAxa8cZmIDJgt43d15Ui47y6mdPyXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRFASbI
5Rq8NEQh3q0l/HYWdyGQgJhXnU7q7C+qPBR7V8F+GBRn7iTGvboVsNIYvbdVgaxTwOjdaRITQrcC
tQVBynlQboIOcXKTRuidDV29rs4prWPVVRaAMCf/drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ
68W/ClTluUI8JPu3B5wwn3la5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyBM5kYJRF3
p+v9WAksmWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQmy8YJPamTQr5O8t1wswv
ziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xOAU++CrYD062KRffaJ00psUjf5BHklka9
bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT9Y41xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4o
GKQWDzH9OmwjkyB24f0HhdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2
uBOLZ8/5fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMxHTAbBgNVBAoT
FEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNhIE9ubGluZSBJbmMuMTcwNQYD
VQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAy
MDUyOTA2MDAwMFoXDTM3MTEyMDE1MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wg
VGltZSBXYXJuZXIgSW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMu
QU9MIFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U0pPlLYnKhHw/EEMbjIt8
hFj4JHxIzyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItITuLCxFlpMGK2MKKMCxGZYTVtfu/FsRkG
IBKOQuHfD5YQUqjPnF+VFNivO3ULMSAfRC+iYkGzuxgh28pxPIzstrkNn+9R7017EvILDOGsQI93
f7DKeHEMXRZxcKLXwjqFzQ6axOAAsNUl6twr5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQI
fHNlIAqhBC4aMqiaILGcLCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEAAaNj
MGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jYPXy+XxIwHwYDVR0j
BBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUA
A4IBAQCKIBilvrMvtKaEAEAwKfq0FHNMeUWn9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u
0FIy2VkyvNp5ctZ7CegCgTXTCt8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77Bf
WgDrvq2g+EQFZ7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oTLW4jYYehY0KswsuX
n2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCzvhGbRWeDhhmH05i9CBoWH1iCC+GWaQVL
juyDUTEH1dSf/1l7qG6Fz9NLqUmwX7A5KGgOc90lmt4S
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NBX0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxp
bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
BAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDcx
NjE2NDBaFw0yMDAyMDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
d3d3LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
MCMGA1UECxMcKGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
ZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQCTdLS25MVL1qFof2LV7PdRV7NySpj10InJrWPNTTVRaoTUrcloeW+46xHbh65cJFET8VQl
hK8pK5/jgOLZy93GRUk0iJBeAZfv6lOm3fzB3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKkl
Wb1m9fkn5JVn1j+SgF7yNH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHdBgNV
HR8EgdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUAwPgYDVQQLFDd3
d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUw
IwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5l
dCBDbGllbnQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
IoAPMjAwMDAyMDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQDAgEGMB8GA1UdIwQY
MBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQWBBSEi3T9xY3A/ydtIDdFfP4tzrrTfTAM
BgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQF
AAOBgQBObzWAO9GK9Q6nIMstZVXQkvTnhLUGJoMShAusO7JE7r3PQNsgDrpuFOow4DtifH+La3xK
p9U1PL6oXOpLu5OOgGarDyn9TS2/GpsKkMWr2tGzhtQvJFJcem3G8v7lTRowjJDyutdKPkN+1MhQ
Gof4T4HHdguEOnKdzmVml64mXg==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UEChMLRW50cnVzdC5u
ZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xfQ1BTIGluY29ycC4gYnkgcmVmLiAobGlt
aXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UE
AxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0w
MDAyMDQxNzIwMDBaFw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDE/MD0G
A1UECxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlh
Yi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRy
dXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3
DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO8GCGD9JYf9Mzly0XonUwtZZkJi9ow0SrqHXmAGc0V55l
xyKbc+bT3QgON1WqJUaBbL3+qPZ1V1eMkGxKwz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439P
mrkDQYC2dWcTC5/oVzbIXQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4QgEB
BAQDAgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoTC0VudHJ1c3QubmV0
MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0
cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAwIEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMT
MUVudHJ1c3QubmV0IFNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNV
BAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIwNDE3NTAwMFowCwYD
VR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc/vuLkpyw8m4iMB0GA1UdDgQWBBTLbMBr
47s+y/winP77i5KcsPJuIjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4w
AwIEkDANBgkqhkiG9w0BAQQFAAOBgQBi24GRzsiad0Iv7L0no1MPUBvqTpLwqa+poLpIYcvvyQbv
H9X07t9WLebKahlzqlO+krNQAraFJnJj2HVQYnUUt7NQGj/KEQALhUVpbbalrlHhStyCP2yMNLJ3
a9kC9n8O6mUE8c1UyrrJzOCE98g+EZfTYAkYvAX/bIkz8OwVDw==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgT
DFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG
A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg
Q0EwHhcNOTcwMTAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNV
BAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEd
MBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBp
bmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT6jR7UZztsOYuGA7+4F+o
J9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQaWt9MevPZQx08EHp5JduQ/vBR5zDWQQD9
nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzAR
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCo
uqoEiYbC9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQpgCe
d/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZCayJSdM=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU
cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx
CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx
64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3
KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o
L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR
wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU
MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE
BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y
azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD
ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze
RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB
iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU
cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ
BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l
dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu
nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i
d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG
Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw
HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G
A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G
A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4
JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9
Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H
EufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU
cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw
CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO
ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6
54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr
oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1
Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui
GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w
HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD
AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT
RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw
HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt
ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr
mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj
ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJXVzESMBAGA1UE
ChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQgUm9vdCBDQXMxGjAYBgNVBAMTEWJlVFJV
U1RlZCBSb290IENBMB4XDTAwMDYyMDE0MjEwNFoXDTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMC
V1cxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRowGAYD
VQQDExFiZVRSVVNUZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANS0
c3oTCjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4SP+00PpeQY1hRIfo7clY+vyTmt9P6j41ffgz
eubx181vSUs9Ty1uDoM6GHh3o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwMjmVZxXH/YgmPqsWPzGCg
c0rXOD8Vcr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX2P8ZDoMbjNx4RWc0PfSvHI3kbWvtILNn
mrRhyxdviTX/507AMhLn7uzf/5cwdO2NR47rtMNE5qdMf1ZD6Li8tr76g5fmu/vEtpO+GRg+jIG5
c4gW9JZDnGdzF5DYCW5jrEq2I8QBoa2k5MUCAwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8w
ggFZBgNVHSAEggFQMIIBTDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQagfFS
ZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFu
Y2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBv
ZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJl
IGZvdW5kIGF0IGJlVFJVU1RlZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29t
L3ZhdWx0L3Rlcm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0
L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYDVQQKEwliZVRSVVNUZWQxCzAJBgNVBAYT
AldXMB0GA1UdDgQWBBQquZtpLjub2M3eKjEENGvKBxirZzAfBgNVHSMEGDAWgBQquZtpLjub2M3e
KjEENGvKBxirZzAOBgNVHQ8BAf8EBAMCAf4wDQYJKoZIhvcNAQEFBQADggEBAHlh26Nebhax6nZR
+csVm8tpvuaBa58oH2U+3RGFktToQb9+M70j5/Egv6S0phkBxoyNNXxlpE8JpNbYIxUFE6dDea/b
ow6be3ga8wSGWsb2jCBHOElQBp1yZzrwmAOtlmdE/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ
1gMe1lMBzW1MaFVA4e5rxyoAAEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5mlWXKWWu
GVUlBXJH0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYctmBjRYoQtLpGEK5BV2Vs
PyMQPyEQWbfkQN0mDCP2qq4=
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE
ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y
MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT
DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn
2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5
BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG
A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx
JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG
A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e
uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB
Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1
jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia
78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm
V+GRMOrN
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB
LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE
ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz
IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ
1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a
IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk
MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW
Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF
AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5
lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+
KpYrtWKmpj29f5JZzVoqgrI3eQ==
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT
RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp
bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx
HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds
b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV
PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN
qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn
hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs
MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN
I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY
NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC
AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER
gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B
AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS
o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z
2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX
OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ==
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UEBhMCVVMxFDASBgNV
BAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50cnVzdC5uZXQvQ2xpZW50X0NBX0luZm8v
Q1BTIGluY29ycC4gYnkgcmVmLiBsaW1pdHMgbGlhYi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1
c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9u
IEF1dGhvcml0eTAeFw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBaMIHJMQswCQYDVQQGEwJV
UzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRf
Q0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMpIDE5
OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDIOpleMRffrCdv
kHvkGf9FozTC28GoT/Bo6oT9n3V5z8GKUZSvx1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGp
OZ5V+Pux5zDeg7K6PvHViTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zmAqTm
T173iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSCARkwggEVMIHkoIHh
oIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3
dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBs
aWFiLjElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50
cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCyg
KqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9DbGllbnQxLmNybDArBgNVHRAEJDAigA8x
OTk5MTAxMjE5MjQzMFqBDzIwMTkxMDEyMTkyNDMwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU
xPucKXuXzUyW/O5bs8qZdIuV6kwwHQYDVR0OBBYEFMT7nCl7l81MlvzuW7PKmXSLlepMMAwGA1Ud
EwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEEBQADgYEAP66K
8ddmAwWePvrqHEa7pFuPeJoSSJn59DXeDDYHAmsQOokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6h
URzzwy5E97BnRqqS5TvaHBkUODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/aEkP/TOYG
JqibGapEPHayXOw=
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV
BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg
cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl
ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG
A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi
eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p
dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ
aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5
gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw
ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw
CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l
dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw
NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow
HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA
BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN
Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9
n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y
azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug
b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0
aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ
BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6
tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7
C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS
0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs
Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0
JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf
0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx
JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j
GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E
bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ
rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+
Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB
FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N
y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h
a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc
D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg
UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td
3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H
BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs
3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF
V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r
on+jjBXu
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
W9ViH0Pd
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
Orf1LXLI
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
#-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----
######-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4
xBewRNzjMHPVKmIquNDMHO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDH
qGKB3FtKqsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwIDAQAB
MA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwjcSGIL4LcY/oCRaxF
WdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0ycyfYaT5DdPauxYma51N86Xv2S/PB
ZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRPT8qAkbYp
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h
cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp
Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1
c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx
nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC
wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA
ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK
1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk
LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg==
-----END CERTIFICATE-----
########-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd
k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq
WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM
XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC
lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
Tqj/ZA1k
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAy
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyhYGt+eSz6
Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7FYCTXOvnzAhsPz6zSvz/
S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBAIobK/o5wXTX
XtgZZKJYSi034DNHD6zt96rbHuSLBlxgJ8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUY
YAS/QoD90KioHgE796Ncr6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2
lw0Xd8rY
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTla
MF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3Mg
MSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0NH8xlbgyw
0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR4k5FVmkfeAKA2txHkSm7
NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATANBgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf
7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZoEWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnx
giJduLHdgSOjeyUVRjB5FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0A
NACY89FxlA==
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy
MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA
A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD
VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS
xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY
MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM
BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi
up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1
mPnHfxsb1gYgAlihw6ID
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE
ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy
MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs
IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA
A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE
NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i
o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo
BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0
dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw
IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY
MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM
BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB
ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq
kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4
RbyhkwS7hp86W0N6w4pl
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
70+sB3c4
-----END CERTIFICATE-----
###-----BEGIN CERTIFICATE-----
MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE
AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl
ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT
AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU
VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ
cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2
aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh
Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/
qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm
SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf
8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t
UCemDaYj+bvLpgcUQg==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs
dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE
AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j
b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV
BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u
c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG
A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0
ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl
/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7
1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J
GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ
GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc=
-----END CERTIFICATE-----
####-----BEGIN CERTIFICATE-----
MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkExFTATBgNVBAgT
DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYDVQQKExFUaGF3dGUgQ29uc3Vs
dGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMb
VGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVl
bWFpbEB0aGF3dGUuY29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNV
BAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE
ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2
aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJ
ARYccGVyc29uYWwtZnJlZW1haWxAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA1GnX1LCUZFtx6UfYDFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6W
ZBrCFG5ErHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVquzgk
CGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF
AAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjPMPuoSpaKH2JCI4wXD/S6ZJwXrEcp
352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK
/qarigd1iwzdUYRr5PjRzneigQ==
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG
A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz
MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL
Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0
IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u
sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql
HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID
AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW
M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF
NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
-----END CERTIFICATE-----
#######-----BEGIN CERTIFICATE-----
MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg
Q29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJvb3QwHhcNOTYwMjIzMjMwMTAw
WhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9u
MRwwGgYDVQQDExNHVEUgQ3liZXJUcnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC45k+625h8cXyvRLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH
6X4MypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/51KiOQswk
wB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKzdcZfHeFhVYAA1IFLezEP
I2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWlIjeaY8JIILTbcuPI9tl8vrGvU9oUtCG4
1tWW4/5ODFlitppK+ULdjG+BqXH/9ApybW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
-----END CERTIFICATE-----
#modp18##modp17##modp16##modp15##modp14##modp5###modp2###modp1###-----BEGIN PUBLIC
KEY-----##-----BEGIN RSA PUBLIC KEY-----##node-crypto : Invalid key length %d
####node-crypto : Unknown cipher %s
####node-crypto : Invalid IV length %d
#node-crypto : Unknown message digest %s
####Unknown message digest %s
######node-crypto : Diffie-Hellman parameter encoding can be binary, hex or base64
####g###D�# D�#�i###D�# D�#`j###D�# D�##k###D�# D�#pl###D�# D�#�m###D�# D�#Unknown
method##TLSv1_client_method#TLSv1_server_method#TLSv1_method####SSLv23_client_metho
d####SSLv23_server_method####SSLv23_method###SSLv3_client_method#SSLv3_server_metho
d#SSLv3_method####SSLv2_client_method#SSLv2_server_method#SSLv2_method####PEM_read_
bio_PrivateKey#Bad
parameter###SSL_CTX_use_certificate_chain###SSL_CTX_set_session_id_context
error####Bad password####Not a string or buffer##Unable to load
BIO##receivedShutdown####sentShutdown####SSL_set_session
error###CERT_REJECTED###CERT_UNTRUSTED##INVALID_PURPOSE#PATH_LENGTH_EXCEEDED####INV
ALID_CA##CERT_REVOKED####CERT_CHAIN_TOO_LONG#UNABLE_TO_VERIFY_LEAF_SIGNATURE#UNABLE
_TO_GET_ISSUER_CERT_LOCALLY###SELF_SIGNED_CERT_IN_CHAIN###DEPTH_ZERO_SELF_SIGNED_CE
RT#OUT_OF_MEM##ERROR_IN_CRL_NEXT_UPDATE_FIELD##ERROR_IN_CRL_LAST_UPDATE_FIELD##ERRO
R_IN_CERT_NOT_AFTER_FIELD###ERROR_IN_CERT_NOT_BEFORE_FIELD##CRL_HAS_EXPIRED#CRL_NOT
_YET_VALID###CERT_HAS_EXPIRED####CERT_NOT_YET_VALID##CRL_SIGNATURE_FAILURE###CERT_S
IGNATURE_FAILURE##UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY##UNABLE_TO_DECRYPT_CRL_SIGNATU
RE#UNABLE_TO_DECRYPT_CERT_SIGNATURE####UNABLE_TO_GET_CRL###UNABLE_TO_GET_ISSUER_CER
T###Must give a Buffer as first argument####Must give a Function as first
argument##Must give cipher-type, key##CipherInit error####Must give cipher-type,
key, and iv as argument##CipherInitIv error##node-crypto : Cipher .update encoding
can be binary, hex or base64
#DecipherUpdate fail#CipherFinal fail########node-crypto : Cipher .final encoding
can be binary, hex or base64
##Must give cipher-type, key as argument##DecipherInit error##DecipherInitIv
error####node-crypto : Decipher .update encoding can be binary, hex or base64
###node`DecodeBytes() failed###Must give hashtype string as argument###hmac
error##HmacUpdate fail#node-crypto : Hmac .digest encoding can be binary, hex or
base64
###Digest method not supported#HashUpdate fail#node-crypto : Hash .digest encoding
can be binary, hex or base64
###Not initialized#Must give signtype string as argument###SignInit
error##SignUpdate fail#####node-crypto : Sign .sign encoding can be binary, hex or
base64
#Must give verifytype string as argument#VerifyInit error####VerifyUpdate
fail###node-crypto : Verify .verify encoding can be binary, hex or base64
#No group name given#Unknown group###Initialization failed###First argument must be
public key###First argument must be private key##DecipherFinal
fail##loadPKCS12##setSessionIdContext#setOptions##setCiphers##addRootCerts####addCR
L##addCACert###setCert#setKey##SecureContext###onhandshakedone#onhandshakestart####
BIO_write###Second argument should be a buffer##Takes 3
parameters##SSL_read:ClearOut###SSL_connect:ClearOut####SSL_accept:ClearOut#BIO_rea
d:EncOut#SSL_write:ClearIn###SSL_connect:ClearIn#SSL_accept:ClearIn##SSL_connect:St
art###SSL_accept:Start####SSL_shutdown####Cipher##setAutoPadding##initiv##Decipher#
###finaltol####Hmac####Hash####Sign####sign####Verify##verify##Key generation
failed###No public key - did you forget to generate one?#No private key - did you
forget to generate one?####Supplied key is too large###Supplied key is too
small###Invalid key#First argument must be other party's public key#ondone##PBKDF2
error####Callback not a function#Bad key length##Key length not a number#Bad
iterations##Iterations not a number#Bad salt####Operation not supported#Argument #1
must be number > 0##First argument must be a crypto module
Credentials##DiffieHellmanGroup##DiffieHellman###setPrivateKey###setPublicKey####ge
tPrivateKey###getPublicKey####getGenerator####getPrime####computeSecret###generateK
eys####setSNICallback##getServername###setNPNProtocols#getNegotiatedProtocol###getC
urrentCipher####verifyError#isInitFinished##isSessionReused#setSession##getSession#
#getPeerCertificate##encPending##clearPending####encOut##clearIn#clearOut####encIn#
##ext_key_usage###exponent####modulus#subjectaltname##valid_to####valid_from##issue
r##subject#pseudoRandomBytes###randomBytes#PBKDF2##0 ##�;##�1##�1##Statement is
already finalized##�;###D�# D�#lastID##Argument 0 must be a function###Database
object expected####SQL query expected##sql#Callback expected###Use the new operator
to create new Statement objects####Data type is not
supported##finalize####each####Statement###Database handle is closed###Database is
closed##�###D�# D�#Ѓ##Argument 0 must be a string#Use the new operator to create
new Database objects# is not a valid configuration option####Value must be an
integer####busyTimeout#Expected 2arguments#Argument 1 must be a
function###configure###parallelize#serialize###loadExtension###`�##destructor###�##
К##HandleWrap: Aborting due to unwrap failure at %s:%d
####src\handle_wrap.cc##onread##writeQueueSize##StreamWrap: Aborting due to unwrap
failure at %s:%d
####src\stream_wrap.cc##slab_%p#�###D�# D�#onstop##StatWatcher#an unknown error
occurred###HPE_UNKNOWN#parser is paused####HPE_PAUSED##strict mode assertion
failed####HPE_STRICT##encountered unexpected internal
state###HPE_INVALID_INTERNAL_STATE##invalid constant
string#HPE_INVALID_CONSTANT####invalid character in chunk size
header##HPE_INVALID_CHUNK_SIZE##invalid character in content-length
header##HPE_INVALID_CONTENT_LENGTH##invalid character in
header#HPE_INVALID_HEADER_TOKEN####LF character expected###HPE_LF_EXPECTED#invalid
fragment####HPE_INVALID_FRAGMENT####invalid query
string####HPE_INVALID_QUERY_STRING####invalid path####HPE_INVALID_PATH####invalid
port####HPE_INVALID_PORT####invalid host####HPE_INVALID_HOST####invalid
URL#HPE_INVALID_URL#invalid HTTP method#HPE_INVALID_METHOD##invalid HTTP status
code####HPE_INVALID_STATUS##invalid HTTP version####HPE_INVALID_VERSION#data
received after completed connection: close message#HPE_CLOSED_CONNECTION###too many
header bytes seen; overflow detected###HPE_HEADER_OVERFLOW#stream ended at an
unexpected time##HPE_INVALID_EOF_STATE###the on_message_complete callback
failed#HPE_CB_message_complete#the on_body callback failed#HPE_CB_body#the
on_headers_complete callback failed#HPE_CB_headers_complete#the on_header_value
callback failed#HPE_CB_header_value#the on_header_field callback
failed#HPE_CB_header_field#the on_url callback failed##HPE_CB_url##the
on_message_begin callback
failed####HPE_CB_message_begin####HPE_OK###################################!##$
%&'##*+#-.#0123456789#######abcdefghijklmnopqrstuvwxyz###^_`abcdefghijklmnopqrstuvw
xyz#|
#~#################################################################################
################################################�����������������������������������
�������������######### �������
#
##��������������������������
#
##�������������������������########################################################
###################################################################################
###################################################################################
###################################################################################
###############################################################################open
ssl\ssl\ssl_lib.c###ALL:!aNULL:!eNULL:!SSLv2####SSLv2###SSLv3###TLSv1###s-
>sid_ctx_length <= sizeof s->sid_ctx##ssl3-sha1###ssl3-md5####ssl2-
md5####fips2###fips####comp####ec_pre_comp#ecdh####ecdsa###ui##engine##dynlock#dso#
debug_malloc2###RSA_blinding####getservbyname###gethostbyname###BIO#debug_malloc###
#rand2###rand####ssl_method##ssl#ssl_sess_cert###ssl_session#ssl_cert####ssl_ctx#x5
09_store##evp_pkey####rsa#dsa#x509_req####x509_crl####x509_pkey###x509_info###x509#
###ex_data#err#<<ERROR>>###d��#`��#X��#P��#D��#8��#,��# ��##��##��#
��##��#���#���#���#���#���#���#���#���#���#���#���#|
��###�#l��#�=�#\��#X��#P��#H��#D��#<��#X��#4��#�#�#(��#
#�# ��##��##��########openssl\crypto\cryptlib.c###S#e#r#v#i#c#e#-
#0#x#####_OPENSSL_isservice##O#p#e#n#S#S#L#:# #F#A#T#A#L#####O#P#E#N#S#S#L###n#o#
#s#t#a#c#k#?###%s(%d): OpenSSL internal error, assertion failed: %s
###pointer != NULL#called a function that was disabled at compile-time#passed a
null parameter#called a function you should not call###malloc
failure##fatal###missing asn1 eos####asn1 length mismatch####expecting an asn1
sequence##bad get asn1 object call####bad asn1 object header##nested asn1
error###TS lib##OCSP lib####ENGINE lib##DSO lib#RAND lib####PKCS12 lib##X509V3
lib##PKCS7 lib###BIO lib#SSL lib#EC lib##CRYPTO lib##CONF lib####ASN1 lib####X509
lib####DSA lib#PEM lib#OBJ lib#BUF lib#EVP lib#DH lib##RSA lib#BN lib##system
lib##fread###opendir#WSAstartup##ioctlsocket#fopen###HMAC routines###CMS
routines####FIPS routines###OCSP routines###engine routines#time stamp routines#DSO
support routines####random number generator#PKCS12 routines#X509 V3
routines####PKCS7 routines##BIO routines####SSL routines####elliptic curve
routines#common libcrypto routines###configuration file routines#asn1 encoding
routines##x509 certificate routines###dsa routines####PEM routines####object
identifier routines##memory buffer routines##digital envelope routines###Diffie-
Hellman routines#rsa routines####bignum routines#system library##unknown
library#�###`###�###P###�###�###@###�###@###�#######openssl\crypto\err\err.c####int
_err_get (err.c)#int_thread_get (err.c)##error:%08lX:%s:%s:
%s####reason(%lu)#func(%lu)###lib(%lu)####CERTIFICATE#Stack part of OpenSSL 1.0.0f
4 Jan
2012#openssl\crypto\stack\stack.c####X509####sig_alg#cert_info###X509_CINF###extens
ions##subjectUID##issuerUID###validity####signature###serialNumber#################
###########(###�###########d��#�\##############���#�\##############���#�b##########
###T��#�###############���#�b##############\��#�###############���#�`##�###########
���#�]##�####### ###���#�]##�#######$###���#�5##########���#
###���#4###|
��#################p###################p��#`###############h��#�b##############���#
�]##########���#####���#h###`��#openssl\ssl\ssl_rsa.c###TRUSTED
CERTIFICATE#openssl\crypto\bio\bio_lib.c####memory
buffer###openssl\crypto\bio\bss_mem.c####base64
encoding#openssl\crypto\evp\bio_b64.c####ctx->buf_off+i < (int)sizeof(ctx-
>buf)##ctx->buf_len >= ctx->buf_off####ctx->tmp_len <= 3###ctx->buf_off <=
(int)sizeof(ctx->buf)###i <= n##ctx->buf_len <= (int)sizeof(ctx->buf)###ctx-
>buf_off < (int)sizeof(ctx->buf)####EVP part of OpenSSL 1.0.0f 4 Jan
2012###openssl\crypto\evp\evp_enc.c####bl <= (int)sizeof(ctx->buf)#b <= sizeof ctx-
>buf####b <= sizeof ctx->final##EVP_CIPHER_CTX_iv_length(ctx) <= (int)sizeof(ctx-
>iv)###ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || ctx->cipher-
>block_size == 16###niv <=
EVP_MAX_IV_LENGTH####openssl\crypto\evp\evp_key.c####nkey <=
EVP_MAX_KEY_LENGTH##################�G##�G###H##########@�##
�######################@###`#######openssl\crypto\evp\evp_lib.c####l <= sizeof(c-
>iv)##j <= sizeof(c->iv)##len>=0 && len<=(int)sizeof(ctx-
>key)####openssl\crypto\hmac\hmac.c##j <= (int)sizeof(ctx-
>key)##openssl\crypto\evp\digest.c#ctx->digest->md_size <=
EVP_MAX_MD_SIZE#openssl\crypto\evp\p_lib.c##openssl\crypto\evp\p_sign.c#openssl\cry
pto\pem\pem_pkey.c###ENCRYPTED PRIVATE KEY###PRIVATE KEY#ANY PRIVATE
KEY#PARAMETERS##openssl\crypto\x509\x509_cmp.c##openssl\crypto\evp\p_verify.c###RSA
part of OpenSSL 1.0.0f 4 Jan 2012###openssl\crypto\rsa\rsa_lib.c####CERTIFICATE
REQUEST#NEW CERTIFICATE REQUEST#X509 CRL####PKCS7###RSA PRIVATE KEY#RSA PUBLIC
KEY##PUBLIC KEY##DSA PRIVATE KEY#EC PRIVATE KEY##%lu:%s:%s:%d:%s
####Big Number part of OpenSSL 1.0.0f 4 Jan
2012########x��####################################################################
###################################################################################
###################################################################################
#######################################openssl\crypto\bn\bn_lib.c##Diffie-Hellman
part of OpenSSL 1.0.0f 4 Jan 2012####openssl\crypto\dh\dh_lib.c##keylen <= sizeof
key####openssl\crypto\evp\p5_crpt2.c###openssl\crypto\dh\dh_gen.c#######�##p�##@�##
#�###�##��##Т## �##�##p�##��##0�##p�##��##0�##��##`�##
�##`�##p�##`#4#P�##�###�##Т## �##p�##@�###########�##p�##@�##�
###�##��##Т## �##�##p�##��##0�##p�##��##0�##��##`�## �##`�##p�##`#4#P�## �###�##Т##
�##p�##@�###########�##p�##@�##�
###�##��##Т## �##�##p�##��##0�##p�##��##0�##��##`�## �##`�##p�##`#4#P�##P�###�##Т##
�##p�##@�###########�##p�##@�###�##@�##��##0�##��###�###�##��'#0�##p�##��##0�##��##
`�##P�##p�##@�###�## �##��##��##D�##
�##p�##@�##openssl\ssl\s23_clnt.c###########�##p�##@�##�###�##��##0�##��###�###�##�
�'#0�##p�##��##0�##��##`�##P�##p�##@�###�## �##��##��##D�## �##p�##@�##PUT ####HEAD
###POST ###openssl\ssl\s23_srvr.c##########��###�###�###�###�##��##Т##
�##�##p�##��##0�##p�##��##0�##��##`�## �##`�##p�##`#4#P�##��###�##��##
�##p�##@�##openssl\ssl\s3_clnt.c###########��###�###�##�
###�##��##Т## �##�##p�##��##0�##p�##��##0�##��##`�##
�##`�##p�##`#4#P�###�###�##��## �##p�##@�##openssl\ssl\s3_srvr.c###GOST signature
length is %d#####��###�###�##�
###�##��##Т## �##�##p�##��##0�##p�##��##0�##��##`�## �##`�##p�##`#4#P�##
####�##��##
�##p�##@�##########��##��##@�###�##�)##�###�###�###��##��'#��'#################��##
К@##�##P�###�##�###��##P###��##D�##
�##К@#К@#openssl\ssl\s2_clnt.c###########��##��##@�##`@###�##�###�###�###��##��'#��
'#################��##К@##�##P�###�##�###��###.##��##D�##
�##К@#К@#openssl\ssl\s2_srvr.c###########��##��##@�##`@##�)##�###�###�###��##��'#��
'#################��##К@##�##P�###�##�###��##�D##��##D�##
�##К@#К@##########�##p�##@�##�##@�##��##0�##��###�###�##��'#0�##p�##��##0�##��##`�#
#P�##p�##@�###�## �###E##��##D�## �##p�##@�##SSL for verify
callback#openssl\ssl\ssl_cert.c##ssl_server##ssl_client##%s/%s###openssl\crypto\x50
9\x509_lu.c###X509_CRL####crl#X509_CRL_INFO###revoked#nextUpdate##lastUpdate##X509_
REVOKED####revocationDate##################���#�\##############l��#@.##############
���#�5##########���#############\��#################�^##################d��#�\#####
#########h��#�b##############T��#�###########
###P��#@.##############D��#@.##############<��##Z##�###########���#�5##########���#
####���#(###,��#########
#######�^##################(��##Z##############h��#�b##############���#�]##########
���#####���#L####��#openssl\crypto\asn1\x_crl.c#PKCS12_AUTHSAFES####PKCS12_SAFEBAGS
#attrib##PKCS12_SAFEBAG##value.bag###value.safes#value.shkeybag##value.keybag####PK
CS12_BAGS#value.sdsicert##value.x509crl###value.x509cert##value.other#PKCS12_MAC_DA
TA#iter####salt####dinfo###PKCS12##mac#authsafes###############d��#�\##############
#��# K###############��#�`########## ��#########
####��##############��#�
##############���#�]##############���#�\##########x��#########
###���#�###########���##_###############��#####���#####�###�###########���#�]##�###
�###########���#�]##�###�###########���#�^##############���#�^######����####���#�`#
#########H��#############���#�###########���##_##�###�###########���#`###�###�#####
######x��#�
##�###�###########l��##a##�###�###########`��#�`##�###�###########`��#�`##�###�####
#######`��#�`##############���#####���#################���#�^######����####P��#�`##
############H��#p###########L��#########
###P��#############8��##a######�������#############8��#############$��#
K######�������#############$��#openssl\crypto\pkcs12\p12_kiss.c####openssl\crypto\p
kcs12\p12_utl.c#openssl\crypto\asn1\a_object.c##<INVALID>###dmdName#deltaRevocation
List#supportedAlgorithms#houseIdentifier#uniqueMember####distinguishedName###protoc
olInformation#enhancedSearchGuide#crossCertificatePair####certificateRevocationList
###authorityRevocationList#cACertificate###userCertificate#userPassword####seeAlso#
roleOccupant####owner###member##supportedApplicationContext#presentationAddress#pre
ferredDeliveryMethod#destinationIndicator####registeredAddress###internationaliSDNN
umber#x121Address#facsimileTelephoneNumber####teletexTerminalIdentifier###telexNumb
er#telephoneNumber#physicalDeliveryOfficeName##postOfficeBox###postalAddress###busi
nessCategory####searchGuide#Permanent Identifier####id-on-
permanentIdentifier###X509v3 Freshest CRL#freshestCRL#Microsoft Local Key
set#LocalKeySet#hmac####HMAC####GOST R 3410-2001 Parameter Set Cryptocom####id-
GostR3410-2001-ParamSet-cc###GOST R 34.11-94 with GOST R 34.10-2001
Cryptocom####id-GostR3411-94-with-GostR3410-2001-cc##GOST R 34.11-94 with GOST R
34.10-94 Cryptocom##id-GostR3411-94-with-GostR3410-94-cc####GOST 34.10-2001
Cryptocom###gost2001cc##GOST 34.10-94 Cryptocom#gost94cc####GOST 28147-89 Cryptocom
ParamSet####id-Gost28147-89-cc##id-GostR3410-94-bBis####id-GostR3410-94-b###id-
GostR3410-94-aBis####id-GostR3410-94-a###id-GostR3410-2001-CryptoPro-XchB-
ParamSet###id-GostR3410-2001-CryptoPro-XchA-ParamSet###id-GostR3410-2001-CryptoPro-
C-ParamSet##id-GostR3410-2001-CryptoPro-B-ParamSet##id-GostR3410-2001-CryptoPro-A-
ParamSet##id-GostR3410-2001-TestParamSet##id-GostR3410-94-CryptoPro-XchC-
ParamSet#id-GostR3410-94-CryptoPro-XchB-ParamSet#id-GostR3410-94-CryptoPro-XchA-
ParamSet#id-GostR3410-94-CryptoPro-D-ParamSet####id-GostR3410-94-CryptoPro-C-
ParamSet####id-GostR3410-94-CryptoPro-B-ParamSet####id-GostR3410-94-CryptoPro-A-
ParamSet####id-GostR3410-94-TestParamSet####id-Gost28147-89-CryptoPro-RIC-1-
ParamSet####id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet####id-Gost28147-89-
CryptoPro-Oscar-1-1-ParamSet####id-Gost28147-89-CryptoPro-D-ParamSet####id-
Gost28147-89-CryptoPro-C-ParamSet####id-Gost28147-89-CryptoPro-B-ParamSet####id-
Gost28147-89-CryptoPro-A-ParamSet####id-Gost28147-89-TestParamSet####id-GostR3411-
94-CryptoProParamSet###id-GostR3411-94-TestParamSet####id-Gost28147-89-None-
KeyMeshing#id-Gost28147-89-CryptoPro-KeyMeshing####GOST R 34.10-94 DH##id-
GostR3410-94DH###GOST R 34.10-2001 DH####id-GostR3410-2001DH#GOST R 34.11-94
PRF#prf-gostr3411-94####GOST 28147-89 MAC###gost-mac####gost89-cnt##GOST 28147-
89###gost89##GOST R 34.10-94#gost94##GOST R 34.10-2001###gost2001####HMAC GOST
34.11-94##id-HMACGostR3411-94#GOST R 34.11-94#md_gost94###GOST R 34.11-94 with GOST
R 34.10-94####id-GostR3411-94-with-GostR3410-94###GOST R 34.11-94 with GOST R
34.10-2001##id-GostR3411-94-with-GostR3410-
2001#cryptocom###cryptopro###whirlpool###dsa_with_SHA256#dsa_with_SHA224#hmacWithSH
A512##hmacWithSHA384##hmacWithSHA256##hmacWithSHA224##hmacWithMD5#ecdsa-with-
SHA512###ecdsa-with-SHA384###ecdsa-with-SHA256###ecdsa-with-SHA224###ecdsa-with-
Specified####ecdsa-with-Recommended##id-aes256-wrap##id-aes192-wrap##id-aes128-
wrap##id-ct-asciiTextWithCRLF#id-smime-ct-compressedData##CA
Repository###caRepository####id-it-suppLangTags##Diffie-Hellman based MAC####id-
DHBasedMac###password based MAC##id-PasswordBasedMAC#hmac-sha1###HMAC-SHA1###hmac-
md5####HMAC-MD5####seed-cfb####SEED-CFB####seed-ofb####SEED-OFB####seed-
cbc####seed-ecb####SEED-ECB####kisa####KISA####X509v3 Certificate
Issuer###certificateIssuer###X509v3 Issuing Distrubution
Point###issuingDistributionPoint####X509v3 Subject Directory
Attributes#subjectDirectoryAttributes##camellia-256-ofb####CAMELLIA-256-
OFB####camellia-192-ofb####CAMELLIA-192-OFB####camellia-128-ofb####CAMELLIA-128-
OFB####camellia-256-cfb8###CAMELLIA-256-CFB8###camellia-192-cfb8###CAMELLIA-192-
CFB8###camellia-128-cfb8###CAMELLIA-128-CFB8###camellia-256-cfb1###CAMELLIA-256-
CFB1###camellia-192-cfb1###CAMELLIA-192-CFB1###camellia-128-cfb1###CAMELLIA-128-
CFB1###camellia-256-cfb####CAMELLIA-256-CFB####camellia-192-cfb####CAMELLIA-192-
CFB####camellia-128-cfb####CAMELLIA-128-CFB####camellia-256-ecb####CAMELLIA-256-
ECB####camellia-192-ecb####CAMELLIA-192-ECB####camellia-128-ecb####CAMELLIA-128-
ECB####camellia-256-cbc####CAMELLIA-256-CBC####camellia-192-cbc####CAMELLIA-192-
CBC####camellia-128-cbc####CAMELLIA-128-CBC####ipsec4##Oakley-EC2N-
4###ipsec3##Oakley-EC2N-3###X509v3 Inhibit Any Policy###inhibitAnyPolicy####X509v3
Policy Mappings##policyMappings##X509v3 Any Policy###anyPolicy###wap-wsg-idm-ecid-
wtls12#wap-wsg-idm-ecid-wtls11#wap-wsg-idm-ecid-wtls10#wap-wsg-idm-ecid-wtls9##wap-
wsg-idm-ecid-wtls8##wap-wsg-idm-ecid-wtls7##wap-wsg-idm-ecid-wtls6##wap-wsg-idm-
ecid-wtls5##wap-wsg-idm-ecid-wtls4##wap-wsg-idm-ecid-wtls3##wap-wsg-idm-ecid-
wtls1##sect571r1###sect571k1###sect409r1###sect409k1###sect283r1###sect283k1###sect
239k1###sect233r1###sect233k1###sect193r2###sect193r1###sect163r2###sect163r1###sec
t163k1###sect131r2###sect131r1###sect113r2###sect113r1###secp521r1###secp384r1###se
cp256k1###secp224r1###secp224k1###secp192k1###secp160r2###secp160r1###secp160k1###s
ecp128r2###secp128r1###secp112r2###secp112r1###c2tnb431r1##c2pnb368w1##c2tnb359v1##
c2pnb304w1##c2pnb272w1##c2onb239v5##c2onb239v4##c2tnb239v3##c2tnb239v2##c2tnb239v1#
#c2pnb208w1##c2onb191v5##c2onb191v4##c2tnb191v3##c2tnb191v2##c2tnb191v1##c2pnb176v1
##c2pnb163v3##c2pnb163v2##c2pnb163v1##ppBasis#tpBasis#onBasis#id-characteristic-
two-basis#wap-wsg#wap#certicom-arc####identified-
organization#sha224##SHA224##sha512##SHA512##sha384##SHA384##sha256##SHA256##sha224
WithRSAEncryption#RSA-SHA224##sha512WithRSAEncryption#RSA-
SHA512##sha384WithRSAEncryption#RSA-SHA384##sha256WithRSAEncryption#RSA-
SHA256##Independent#id-ppl-independent##X509v3 Name
Constraints#nameConstraints#Inherit all#id-ppl-inheritAll###Any language####id-ppl-
anyLanguage##Proxy Certificate Information###proxyCertInfo###id-
ppl##postalCode##streetAddress###street##des-ede3-cfb8###DES-EDE3-CFB8###des-ede3-
cfb1###DES-EDE3-CFB1###des-cfb8####DES-CFB8####des-cfb1####DES-CFB1####aes-256-
cfb8####AES-256-CFB8####aes-192-cfb8####AES-192-CFB8####aes-128-cfb8####AES-128-
CFB8####aes-256-cfb1####AES-256-CFB1####aes-192-cfb1####AES-192-CFB1####aes-128-
cfb1####AES-128-CFB1####Microsoft Universal Principal Name##msUPN###Microsoft
Smartcardlogin####msSmartcardLogin####International Organizations#international-
organizations#joint-iso-itu-t#JOINT-ISO-ITU-T#itu-t###ITU-
T###rsaOAEPEncryptionSET####des-cdmf####DES-CDMF####set-brand-Novus#set-brand-
MasterCard####set-brand-Visa##set-brand-JCB###set-brand-AmericanExpress###set-
brand-Diners####set-brand-IATA-ATA##secure device signature#setAttr-SecDevSig###ICC
or token signature##setAttr-TokICCsig###cleartext track 2###setAttr-
T2cleartxt##encrypted track 2###setAttr-T2Enc###generate cryptogram#setAttr-
GenCryptgrm#setAttr-IssCap-Sig##setAttr-IssCap-T2###setAttr-IssCap-CVM##setAttr-
Token-B0Prime###setAttr-Token-EMV###set-addPolicy###set-rootKeyThumb####issuer
capabilities#setAttr-IssCap##setAttr-TokenType###payment gateway
capabilities####setAttr-PGWYcap#setAttr-Cert####setCext-
IssuerCapabilities##setCext-TokenType###setCext-Track2Data##setCext-
TokenIdentifier#setCext-PGWYcapabilities####setCext-setQualf####setCext-
setExt##setCext-tunneling###setCext-cCertRequired###setCext-merchData###setCext-
certType####setCext-hashedRoot##set-policy-root#additional verification#setext-
cv###setext-track2###setext-pinAny###setext-pinSecure####merchant initiated
auth#setext-miAuth###generic cryptogram##setext-genCrypt#setct-
BCIDistributionTBS####setct-CRLNotificationResTBS#setct-
CRLNotificationTBS####setct-CertResTBE####setct-CertReqTBEX###setct-
CertReqTBE####setct-RegFormReqTBE#setct-BatchAdminResTBE##setct-
BatchAdminReqTBE##setct-CredRevResTBE#setct-CredRevReqTBEX####setct-
CredRevReqTBE#setct-CredResTBE####setct-CredReqTBEX###setct-CredReqTBE####setct-
CapRevResTBE##setct-CapRevReqTBEX#setct-CapRevReqTBE##setct-CapResTBE#setct-
CapReqTBEX####setct-CapReqTBE#setct-AuthRevResTBEB####setct-AuthRevResTBE#setct-
AuthRevReqTBE#setct-AcqCardCodeMsgTBE#setct-CapTokenTBEX##setct-
CapTokenTBE###setct-AuthTokenTBE##setct-AuthResTBEX###setct-AuthResTBE####setct-
AuthReqTBE####setct-PIUnsignedTBE#setct-PIDualSignedTBE###setct-ErrorTBS##setct-
CertInqReqTBS#setct-CertResData###setct-CertReqTBS####setct-CertReqData###setct-
RegFormResTBS#setct-MeAqCInitResTBS###setct-CardCInitResTBS###setct-
BatchAdminResData#setct-BatchAdminReqData#setct-PCertResTBS###setct-
PCertReqData##setct-CredRevResData####setct-CredRevReqTBSX####setct-
CredRevReqTBS#setct-CredResData###setct-CredReqTBSX###setct-CredReqTBS####setct-
CapRevResData#setct-CapRevReqTBSX#setct-CapRevReqTBS##setct-CapResData####setct-
CapReqTBSX####setct-CapReqTBS#setct-AuthRevResTBS#setct-AuthRevResData####setct-
AuthRevReqTBS#setct-AcqCardCodeMsg####setct-CapTokenTBS###setct-
CapTokenData##setct-AuthTokenTBS##setct-AuthResTBSX###setct-AuthResTBS####setct-
AuthReqTBS####setct-PResData##setct-PI-TBS####setct-PInitResData##setct-
CapTokenSeq###setct-AuthRevResBaggage#setct-AuthRevReqBaggage#setct-
AuthResBaggage####setct-HODInput##setct-PIDataUnsigned####setct-PIData####setct-
PI####setct-OIData####setct-PANOnly###setct-PANToken##setct-PANData###set-
brand###certificate extensions##set-certExt#set-policy##set-attr####message
extensions##set-msgExt##content types###set-ctype###Secure Electronic
Transactions##id-set##pseudonym###generationQualifier#id-hex-multipart-
message####id-hex-partial-message##mime-mhs-bodies#mime-mhs-headings###MIME
MHS####mime-
mhs####x500UniqueIdentifier####documentPublisher###dITRedirect#personalSignature###
subtreeMaximumQuality###subtreeMinimumQuality###singleLevelQuality##dSAQuality##bui
ldingName####mailPreferenceOption####janetMailbox####organizationalStatus####friend
lyCountryName#pagerTelephoneNumber####mobileTelephoneNumber###personalTitle###
homePostalAddress###associatedName##associatedDomain####cNAMERecord#sOARecord###nSR
ecord####mXRecord####pilotAttributeType27####aRecord#lastModifiedBy##lastModifiedTi
me####otherMailbox####secretary###homeTelephoneNumber#documentLocation####documentA
uthor##documentVersion#documentTitle###documentIdentifier##manager#userClass###phot
o###roomNumber##favouriteDrink##rfc822Mailbox###mail####textEncodedORAddress####use
rId##UID#qualityLabelledData#pilotDSA####pilotOrganization###simpleSecurityObject##
##friendlyCountry#domainRelatedObject#dNSDomain###rFC822localPart#documentSeries##r
oom####account#pilotPerson#pilotObject#caseIgnoreIA5StringSyntax###iA5StringSyntax#
pilotGroups#pilotObjectClass####pilotAttributeSyntax####pilotAttributeType##pilot##
#ucl#pss#Hold Instruction Reject#holdInstructionReject###Hold Instruction Call
Issuer####holdInstructionCallIssuer###Hold Instruction
None###holdInstructionNone#Hold Instruction Code###holdInstructionCode#aes-256-
cfb#AES-256-CFB#aes-256-ofb#AES-256-OFB#aes-256-cbc#AES-256-CBC#aes-256-ecb#AES-
256-ECB#aes-192-cfb#AES-192-CFB#aes-192-ofb#AES-192-OFB#aes-192-cbc#AES-192-
CBC#aes-192-ecb#AES-192-ECB#aes-128-cfb#AES-128-CFB#aes-128-ofb#AES-128-OFB#aes-
128-cbc#AES-128-CBC#aes-128-ecb#AES-128-ECB#Microsoft CSP Name##CSPName#ecdsa-with-
SHA1#prime256v1##prime239v3##prime239v2##prime239v1##prime192v3##prime192v2##prime1
92v1##id-ecPublicKey##characteristic-two-field####prime-field#ANSI X9.62##ansi-X9-
62##X509v3 No Revocation Available##noRevAvail##X509v3 AC
Targeting#targetInformation###X509v3 Policy Constraints###policyConstraints###id-
aca-encAttrs#Subject Information Access##subjectInfoAccess###ac-
proxying#md4WithRSAEncryption####RSA-MD4#clearance###Selected Attribute
Types####selected-attribute-
types####Domain##domainComponent#DC##dcObject####dcobject####Enterprises#enterprise
s#Mail####SNMPv2##snmpv2##Security####security####Private#private#Experimental####e
xperimental####Management##mgmt####iana####dod#DOD#ORG#directory services -
algorithms#X500algorithms##rsaSignature####Trust Root##trustRoot###Extended OCSP
Status####extendedStatus##OCSP Service Locator####serviceLocator##OCSP Archive
Cutoff#archiveCutoff###OCSP No Check###noCheck#Acceptable OCSP
Responses###acceptableResponses#OCSP CRL ID#CrlID###OCSP Nonce##Nonce###Basic OCSP
Response#basicOCSPResponse###ad dvcs#AD_DVCS#AD Time
Stamping####ad_timestamping#id-cct-PKIResponse##id-cct-PKIData##id-cct-crs##id-qcs-
pkixQCSyntax-v1##id-aca-role#id-aca-group####id-aca-chargingIdentity#id-aca-
accessIdentity###id-aca-authenticationInfo###id-pda-countryOfResidence###id-pda-
countryOfCitizenship#id-pda-gender###id-pda-placeOfBirth#id-pda-dateOfBirth##id-on-
personalData##id-cmc-confirmCertAcceptance####id-cmc-popLinkWitness###id-cmc-
popLinkRandom####id-cmc-queryPending#id-cmc-responseInfo#id-cmc-regInfo##id-cmc-
revokeRequest####id-cmc-getCRL###id-cmc-getCert##id-cmc-lraPOPWitness####id-cmc-
decryptedPOP#id-cmc-encryptedPOP#id-cmc-addExtensions####id-cmc-
recipientNonce###id-cmc-senderNonce##id-cmc-transactionId####id-cmc-
dataReturn###id-cmc-identityProof####id-cmc-identification###id-cmc-
statusInfo###id-alg-dh-pop###id-alg-dh-sig-hmac-sha1#id-alg-noSignature##id-alg-
des40####id-regInfo-certReq##id-regInfo-utf8Pairs####id-regCtrl-
protocolEncrKey##id-regCtrl-oldCertID####id-regCtrl-pkiArchiveOptions####id-
regCtrl-pkiPublicationInfo###id-regCtrl-authenticator####id-regCtrl-regToken#id-
regInfo##id-regCtrl##id-it-origPKIMessage####id-it-confirmWaitTime###id-it-
implicitConfirm###id-it-revPassphrase#id-it-keyPairParamRep###id-it-
keyPairParamReq###id-it-subscriptionResponse##id-it-subscriptionRequest###id-it-
unsupportedOIDs###id-it-currentCRL####id-it-caKeyUpdateInfo###id-it-
preferredSymmAlg##id-it-encKeyPairTypes###id-it-signKeyPairTypes##id-it-
caProtEncCert#dvcs####DVCS####IPSec User##ipsecUser###IPSec
Tunnel####ipsecTunnel#IPSec End System####ipsecEndSystem##textNotice##sbgp-
routerIdentifier###sbgp-autonomousSysNum###sbgp-ipAddrBlock####aaControls##ac-
targeting####ac-auditEntity##qcStatements####Biometric Info##biometricInfo###id-
mod-cmp2000##id-mod-dvcs#id-mod-ocsp#id-mod-timestamp-protocol###id-mod-attribute-
cert###id-mod-qualified-cert-93####id-mod-qualified-cert-88####id-mod-cmp##id-mod-
kea-profile-93###id-mod-kea-profile-88###id-mod-cmc##id-mod-crmf#id-pkix1-implicit-
93####id-pkix1-explicit-93####id-pkix1-implicit-88####id-pkix1-explicit-88####id-
cct##id-qcs##id-aca##id-pda##id-on###id-cmc##id-alg##id-pkip#id-it###id-qt###id-
pkix-mod#md4#MD4#id-smime-cti-ets-proofOfCreation####id-smime-cti-ets-
proofOfApproval####id-smime-cti-ets-proofOfSender##id-smime-cti-ets-
proofOfDelivery####id-smime-cti-ets-proofOfReceipt#id-smime-cti-ets-
proofOfOrigin##id-smime-spq-ets-sqt-unotice####id-smime-spq-ets-sqt-uri####id-
smime-cd-ldap####id-smime-alg-CMSRC2wrap#id-smime-alg-CMS3DESwrap####id-smime-alg-
ESDH###id-smime-alg-RC2wrap####id-smime-alg-3DESwrap###id-smime-alg-
ESDHwithRC2####id-smime-alg-ESDHwith3DES###id-smime-aa-dvcs-dvc####id-smime-aa-
signatureType###id-smime-aa-ets-archiveTimeStamp####id-smime-aa-ets-
certCRLTimestamp####id-smime-aa-ets-escTimeStamp####id-smime-aa-ets-
revocationValues####id-smime-aa-ets-certValues##id-smime-aa-ets-RevocationRefs##id-
smime-aa-ets-CertificateRefs#id-smime-aa-ets-contentTimestamp####id-smime-aa-ets-
otherSigCert####id-smime-aa-ets-signerAttr##id-smime-aa-ets-signerLocation##id-
smime-aa-ets-commitmentType##id-smime-aa-ets-sigPolicyId#id-smime-aa-
timeStampToken##id-smime-aa-smimeEncryptCerts###id-smime-aa-signingCertificate##id-
smime-aa-encrypKeyPref###id-smime-aa-contentReference####id-smime-aa-
equivalentLabels####id-smime-aa-macValue####id-smime-aa-contentIdentifier###id-
smime-aa-encapContentType####id-smime-aa-msgSigDigest####id-smime-aa-
contentHint#id-smime-aa-mlExpandHistory#id-smime-aa-securityLabel###id-smime-aa-
receiptRequest##id-smime-ct-DVCSResponseData####id-smime-ct-DVCSRequestData#id-
smime-ct-contentInfo#id-smime-ct-TDTInfo#id-smime-ct-TSTInfo#id-smime-ct-
publishCert#id-smime-ct-authData####id-smime-ct-receipt#id-smime-mod-ets-
eSigPolicy-97##id-smime-mod-ets-eSigPolicy-88##id-smime-mod-ets-eSignature-97##id-
smime-mod-ets-eSignature-88##id-smime-mod-msg-v3#id-smime-mod-oid####id-smime-mod-
ess####id-smime-mod-cms####id-smime-cti####id-smime-spq####id-smime-cd#id-smime-
alg####id-smime-aa#id-smime-ct#id-smime-
mod####S/MIME##SMIME###pkcs5###pkcs1###X9.57 CM ?##X9cm####X9.57###X9-57###ISO US
Member Body##ISO-US##ISO Member Body#member-body#iso#ISO#OCSP
Signing####OCSPSigning#CA Issuers##caIssuers###OCSP####Authority Information
Access####authorityInfoAccess#id-ad###id-pe###dnQualifier#Extension
Request###extReq##Microsoft Extension Request#msExtReq####pbeWithSHA1AndDES-
CBC###PBE-SHA1-DES####pbeWithMD5AndRC2-CBC####PBE-MD5-RC2-64##pbeWithMD2AndRC2-
CBC####PBE-MD2-RC2-64##S/MIME Capabilities#SMIME-CAPS##rc2-64-cbc##RC2-64-
CBC##Policy Qualifier User Notice####id-qt-unotice###Policy Qualifier CPS####id-qt-
cps###hmacWithSHA1####PBMAC1##PBES2###x509Crl#sdsiCertificate#x509Certificate#local
KeyID##friendlyName####safeContentsBag#secretBag###crlBag##certBag#pkcs8ShroudedKey
Bag#keyBag##pbeWithSHA1And40BitRC2-CBC##PBE-SHA1-RC2-40#pbeWithSHA1And128BitRC2-
CBC#PBE-SHA1-RC2-128####pbeWithSHA1And2-KeyTripleDES-CBC####PBE-SHA1-
2DES###pbeWithSHA1And3-KeyTripleDES-CBC####PBE-SHA1-
3DES###pbeWithSHA1And40BitRC4##PBE-SHA1-RC4-40#pbeWithSHA1And128BitRC4#PBE-SHA1-
RC4-128####Strong Extranet ID##SXNetID#Invalidity Date#invalidityDate##X509v3 CRL
Reason Code##CRLReason###X509v3 Delta CRL Indicator##deltaCRL####Netscape Server
Gated Crypto####nsSGC###Microsoft Encrypted File System#msEFS###Microsoft Server
Gated Crypto###msSGC###Microsoft Trust List Signing####msCTLSign###Microsoft
Commercial Code Signing###msCodeCom###Microsoft Individual Code
Signing###msCodeInd###Time Stamping###timeStamping####E-mail
Protection###emailProtection#Code Signing####codeSigning#TLS Web Client
Authentication###clientAuth##TLS Web Server Authentication###serverAuth##id-
kp###PKIX####X509v3 Extended Key Usage###extendedKeyUsage####zlib
compression####ZLIB####run length compression##RLE#rc5-ofb#RC5-OFB#rc5-cfb#RC5-
CFB#rc5-ecb#RC5-ECB#rc5-cbc#RC5-CBC#ripemd160WithRSA####RSA-
RIPEMD160###ripemd160###RIPEMD160###dsaEncryption###sha1WithRSA#RSA-SHA1-2##md5-
sha1####MD5-SHA1####dsaWithSHA1#DSA-SHA1####pbeWithMD5AndCast5CBC###cast5-
ofb###CAST5-OFB###cast5-cfb###CAST5-CFB###cast5-ecb###CAST5-ECB###cast5-
cbc###CAST5-CBC###md5WithRSA##RSA-NP-MD5##X509v3 CRL Distribution
Points##crlDistributionPoints###initials####surname#givenName###rc2-40-cbc##RC2-40-
CBC##rc4-40##mdc2WithRSA#RSA-MDC2####mdc2####MDC2####bf-ofb##BF-OFB##bf-cfb##BF-
CFB##bf-ecb##BF-ECB##bf-cbc##BF-CBC##X509v3 Authority Key
Identifier#authorityKeyIdentifier##X509v3 Certificate
Policies#certificatePolicies#X509v3 CRL Number###crlNumber###X509v3 Basic
Constraints####basicConstraints####X509v3 Issuer Alternative
Name##issuerAltName###X509v3 Subject Alternative Name#subjectAltName##X509v3
Private Key Usage Period#privateKeyUsagePeriod###X509v3 Key
Usage####keyUsage####X509v3 Subject Key Identifier###subjectKeyIdentifier####id-
ce###desx-cbc####DESX-CBC####Netscape Certificate
Sequence###nsCertSequence##Netscape Comment####nsComment###Netscape SSL Server
Name####nsSslServerName#Netscape CA Policy Url##nsCaPolicyUrl###Netscape Renewal
Url####nsRenewalUrl####Netscape CA Revocation Url##nsCaRevocationUrl###Netscape
Revocation Url#nsRevocationUrl#Netscape Base Url###nsBaseUrl###Netscape Cert
Type##nsCertType##dsaWithSHA1-old#DSA-SHA1-old####pbeWithSHA1AndRC2-CBC###PBE-SHA1-
RC2-64#dsaEncryption-old###DSA-old#dsaWithSHA##DSA-SHA#sha1WithRSAEncryption###RSA-
SHA1####sha1####des-ede3-ofb####DES-EDE3-OFB####des-ede-ofb#DES-EDE-OFB#des-ede3-
cfb####DES-EDE3-CFB####des-ede-cfb#DES-EDE-CFB#Netscape Data
Type##nsDataType##Netscape Certificate Extension##nsCertExt###Netscape
Communications
Corp.###extendedCertificateAttributes###unstructuredAddress#challengePassword###cou
ntersignature####signingTime#messageDigest###contentType#unstructure
dName####emailAddress####pkcs9###idea-ofb####IDEA-OFB####des-ofb#DES-OFB#des-ede3-
cbc####des-ede-cbc#DES-EDE-CBC#shaWithRSAEncryption####RSA-SHA#sha#SHA#rc2-ofb#RC2-
OFB#rc2-cfb#RC2-CFB#rc2-ecb#RC2-ECB#rc2-cbc#idea-ecb####IDEA-ECB####idea-
cfb####IDEA-CFB####idea-cbc####des-ede3####DES-EDE3####des-ede#DES-EDE#des-cbc#des-
cfb#DES-CFB#des-ecb#DES-ECB#dhKeyAgreement##pkcs3###pkcs7-encryptedData#pkcs7-
digestData####pkcs7-signedAndEnvelopedData####pkcs7-envelopedData#pkcs7-
signedData####pkcs7-
data##pkcs7###organizationalUnitName##OU##organizationName####stateOrProvinceName#l
ocalityName####countryName#commonName##directory services
(X.500)##X500####pbeWithMD5AndDES-CBC####PBE-MD5-DES#pbeWithMD2AndDES-CBC####PBE-
MD2-DES#md5WithRSAEncryption####RSA-MD5#md2WithRSAEncryption####RSA-
MD2#rsaEncryption###rc4#md2#MD2#RSA Data Security, Inc. PKCS####pkcs####RSA Data
Security, Inc.#rsadsi##UNDEF####*�H��*�H��#*�H��##*�H��##*�H��##*�H��###*�H��
###*�H��###*�H��###*�H��###UU#U##U##U##U##U#
U##U###*�H��##*�H��###*�H��###*�H��###*�H��###*�H��###*�H��###*�H��##*�H��
###+####+### +####+####+####�<####*�H��##+####+####*�H��##+####*�H��# *�H��#
#*�H��# #*�H��# #*�H��# #*�H��# #*�H��# #*�H��# #*�H��
# #*�H��# `�H#��B`�H#��B#`�H#��B#+####*�H��###+###+###
*�H��###*�H��##
+####`�H#��B##`�H#��B##`�H#��B##`�H#��B##`�H#��B##`�H#��B##`�H#��B#
`�H#��B#`�H#��B##U#U##U##U##U##U##U##U##U#
U##+####�U##U##eU##dU#*U##U#+U##+####U##U#
U#*�H��}#B
*�H��}#B
*�H�8##+####*�H�8##+$###+$####*�H��##)##�##*�H��# ###U#%
+#####+######+#######+#######+#######+#######+#######+####�7###+####�7###+####�7
##+####�7
##+####�7
##`�H#��B##U##U##U##+e###*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��#
##*�H��# #*�H��# #*�H��# ##*�H��# ##*�H��# ##*�H��##*�H��###*�H��
##+#######+#######*�H��# #*�H��###*�H��###*�H��##
+####�7###*�H��# #U#)U#.+######+#####0+#######+#####0#+#####0#+######
(**�H*�H�8*�H�8#*�H��##*�H��##*�H��# #*�H��# ##*�H��# ##*�H��#
##*�H��# ##*�H��# ##*�H��# ##*�H��# ##*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ## *�H��#
##
*�H��# ###*�H��# ##
*�H��# ##*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��# ###*�H��#
###*�H��# ###*�H��# ###*�H��
##+######+######+######+######+######+######+######+##### +#####
+######+#####
+#######+#######+#######+#######+#######+#######+#######+#######+######
+######
+#######+######
+######
+#######+#######+#######+#######+#######+#######+#######+#######+#######+#######+##
#### +#######+#######+#######+#######+######
+#######+#######+#######+#######+#######+#######+#######+#######+######
+######
+#######+######
+######
+#######+#######+#######+#######+########+########+########+########+########+#####
###+########+########+#######+#######+#######+#######+#######+#######+#######+#####
##+#######+#######+#######+#######+###### +######
+#######+#######+#######+#######+#######+#######+#######+#######+#######+#######+##
#####+##### #+##### #+##### #+##### #+##### #+#####
#+#####
#+#####
#+#####
#+#####
#+#######+#####
#+#####
#+#####
#+#####0#+#####0#+#####0##+#####0##+#####0##+#####0##+#####0##+#####0##+#####0##+##
###0##+#####0# +#####0#
+#####0##+###+####U#++#+##+###+###+###+###+###+###+###+####+####�:�X �&���,d##
�&���,d##U##U##7*�H��###+######
+#######+#####
#U#HU#$U#7U#8#*�H�=*�H�=##*�H�=##*�H�=##*�H�=###*�H�=###*�H�=###*�H�=###*�H�=###*�H
�=###*�H�=###*�H�=##+####�7##`�H#e####`�H#e####`�H#e####`�H#e####`�H#e####`�H#e####
`�H#e####`�H#e####`�H#e###)`�H#e###*`�H#e###+`�H#e###,U##*�H�8##*�H�8##*�H�8##
�& �&���, �&���,d �&���,d# �&���,d# �&���,d# �&���,d
�&���,d## �&���,d## �&���,d## �&���,d## �&���,d## �&���,d##
�&���,d## �&���,d# �&���,d## �&���,d## �&���,d## �&���,d##
�&���,d## �&���,d## �&���,d## �&���,d## �&���,d## �&���,d##
�&���,d## �&���,d## �&���,d## �&���,d## �&���,d## �&���,d##
�&���,d# �&���,d#
�&���,d## �&���,d#
�&���,d# �&���,d## �&���,d## �&���,d## �&���,d## �&���,d##
�&���,d## �&���,d## �&���,d## �&���,d## �&���,d## �&���,d##
�&���,d## �&���,d## �&���,d#% �&���,d#& �&���,d#' �&���,d#(
�&���,d#) �&���,d#* �&���,d#+ �&���,d#- �&���,d#. �&���,d#/
�&���,d#0 �&���,d#1 �&���,d#2 �&���,d#3 �&���,d#4 �&���,d#5
�&���,d#6 �&���,d#7 �&���,d#8U#-
+####+#####+#####+######+######U#,U#Ag*g*#g*#g*#g*#g*#g*#g*##g*##g*##g*##g*##g*##g*
##g*##g*##g*# g*#
g*##g*#
g*#g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*# g*#!
g*#"g*##g*#$g*#%g*#&g*#'g*#(g*#)g*#*g*#+g*#,g*#-
g*#.g*#/g*#0g*#1g*#2g*#3g*#4g*#5g*#6g*#7g*#8g*#9g*#:g*#;g*#<g*#=g*#>g*#?
g*#@g*#Ag*#Bg*#Cg*#Dg*#Eg*#Fg*#Gg*#Hg*#Ig*#Jg*#Kg*#Lg*#Mg*#Ng*#Og*#Pg*#Qg*#Rg*##g*#
#g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*##g*# g*#
g*##g*##g*##g*##g*##g*###g*###g*###g*###g*###g*###g*###g*####g*####g*####g*####g*##
##g*##g*##g*#"g*##g*##g*##g*#�{*�H��#
*�H��####Pg+####�7###+####�7###U#
U##+######+#######+#######+#######U##+#######*�H��###*�H��##
*�H��##*�H��###`�H#e####`�H#e####`�H#e####`�H#e####+
+�#g+g+#*�H�=###*�H�=####*�H�=####*�H�=####*�H�=###*�H�=###*�H�=###*�H�=###*�H�=###
*�H�=###*�H�=###*�H�=###*�H�=## *�H�=##
*�H�=###*�H�=##
*�H�=##
*�H�=###*�H�=###*�H�=###*�H�=###*�H�=###*�H�=###*�H�=###+�###+�###+�###+�###+�##
+�###+�###+�###+�## +�##!+�##
+�##"+�###+�###+�###+�###+�###+�###+�###+�###+�###+�###+�###+�###+�###+�###+�###+�#
#$+�##%+�##&+�##'g+###g+###g+###g+###g+###g+###g+###g+## g+##
g+###g+##
U# #U#!U#6*�#��K=####*�#��K=####*�#��K=#####�1### ##�1### ##�1###
)#�1### ##�1### ##�1### ,#�1### ##�1### ##�1### +U#
U##U##*�#��D*�#��D##*�#��D##*�#��D##*�#��D##+#######+#######*�H��}#B
*�H��}#B#+#######+#####0#*�H��# ## *�H��#
###`�H#e####`�H#e####`�H#e###-
*�H�=##*�H�=##*�H�=###*�H�=###*�H�=###*�H�=###*�H��##*�H��##*�H��# *�H��#
*�H��##`�H#e####`�H#e####(�###7*�###*�## *�####*�####*�### *�###
*�####*�####*�####*�####*�####*�###b*�###c*�#####*�#####*�#####*�#####*�#####*�####
#*�#####*�#####*�#####*�#####*�#####*�#####*�### #*�### #*�### #*�### #*�###
#*�###!#*�###!#*�###!
#*�#####*�#####*�#####*�#####*�###$#*�###$#*�#####*�#####*�#####*�#####*�##
###*�## ###*�## ###*�## ###*�## ###*�## ###+####�7##U#.
+#######U##U##U##U##U##U##U##U##U##U##U##U##U##U##U##U##U##U# U#!U#"U##U#$U#
%U#&U#'U#(U#/U#0U#1U#2U#3U#4U#5U#6#04�#���#########84�#####(4�##4�#########94�#####
#4�#�3�#########?
4�#####�3�#�3�#########F4�#####h��#@��#########N4�#####(d�#�3�#########V4�#####�3�#
�3�##### ###^4�#####�3�#�3�##### ###g4�#####�3�#�3�##### ###p4�#####�3�#h3�#
### ###y4�#####\3�#D3�#
### ###�4�#####<3�# 3�#########�4�#####`��#`��#
#######�4�#####
7�##3�#
#######�4�#####�#�##3�#########�4�#####(��#�2�#########�4�#####d��#�2�#########�4�#
####�#�2�#########�4�#####�2�#�2�#########�4�#####pe�##��#########�4�#####�2�#�2�##
#######�4�#####�2�#�2�##### ###�4�#####�2�#�2�##### ###�4�#####x2�#x2�#####
###�4�#####X2�#X2�##### ###�4�#####D2�#D2�##### ###�4�#####02�#02�#####
###�4�#####(2�#(2�#########�4�######2�##2�#####

###�4�######2�##2�#########�4�######2�#�1�#########�4�#####�r�#�1�#########�4�#####
�1�#�1�# ########5�#####�1�#�1�#!
###############�r�#�1�#"########5�#####�1�#�1�#################�1�#�1�#$###########
####�r�#�1�#%########5�#####|
1�#t1�#&###############l1�#d1�#'###############\1�#T1�#(###############P1�#L1�#)###
#####5�#####D1�#,1�#*########5�##### 1�##1�#+###############�|
�##1�#,#######$5�#####�0�#�0�#-
#######,5�#####�0�#�0�#.###############�0�#�0�#/#######15�#####�0�#�0�#0###
###95�#####�0�#�0�#1### ###B5�#####�0�#�0�#2### ###K5�#####�0�#�0�#3###
###T5�#####�0�#�0�#4### ###]5�#####t0�#t0�#5### ###f5�#####`0�#`0�#6###
###o5�#####L0�#L0�#7### ###x5�#####,0�#,0�#8### ###�5�#####X��#
0�#9#######�5�######0�#�/�#:#######�5�#####�/�#�/�#;#######�5�#####�/�#�/�#<#######
########�/�#�/�#=###############|/�#p/�#>###############`/�#P/�#?
###############Xe�#H/�#@#######�5�#####</�#$/�#A###
###�5�######/�##/�#B#######�5�######/�#�.�#C#######�5�#####�.�#�.�#D###
###�5�#####���#���#E### ###�5�#####�.�#�.�#F#######�5�#####�.�#�.�#G###
###�5�#####�.�#l.�#H### ###�5�#####\.�#D.�#I### ###�5�#####0.�##.�#J###
###�5�######.�#�-�#K### ###�5�#####�-�#�-�#L### ###�5�#####�-�#�-�#M###
####6�#####�-�#x-�#N### ####6�#####h-�#H-�#O### ####6�#####<-�#0-
�#P###############(-�#(-�#Q#######!6�######-
�#�,�#R########6�#####�,�#�,�#S#######&6�#####�,�#�,�#T#######)6�#####�,�#h,�#U####
###,6�#####X,�#8,�#V#######/6�#####$,�##,�#W#######26�#####�+�#�+�#X#######56�#####
�+�#�+�#Y#######86�#####�+�#�+�#Z#######;6�#####x+�#p+�#[###

###>6�#####h+�#`+�#\###############X+�#P+�#]###############H+�#@+�#^###############
8+�#0+�#_#######G6�#####$
+�##+�#`#######K6�#####�r�##+�#a################+�#�*�#b###############,��#�*�#c###
####O6�#####p��#�*�#d#######R6�#####�*�#�*�#e#######U6�############################
#�*�#�*�#g#######X6�#####�*�#�*�#h#######[6�#####���#���#i#######`6�#####�7�#�7�#j#
######c6�#####�T�#�T�#k#######f6�#####|*�#p*�#l###

###i6�#####d*�#X*�#m###############L*�#@*�#n###############4*�#(*�#o###############
#*�##*�#p###

###r6�######*�#�)�#q#######{6�#####�)�#�)�#r###############�)�#�)�#s#######�6�#####
,e�#�)�#t#######�6�#####�)�#�)�#u#######�6�#############################�)�#|)�#w##
#####�6�#####t)�#l)�#x#######�6�#####d)�#\)�#y###############T)�#L)�#z#############
##D)�#<)�#{###############8)�# )�#|
#######�6�######)�##)�#}#######�6�#####�(�#�(�#~#######�6�#####�(�#�(�########�6�#
####�(�#�(�#�#######�6�#####�(�#�(�#�#######�6�#####�(�#l(�#�#######�6�#####`(�#P(�
#�#######�6�#####@(�#,(�#�#######�6�######(�#
(�#�#######�6�######(�#�'�#�###
###�6�#####�'�#�'�#�###
###�6�#####�'�#�'�#�###
###�6�#####x'�#X'�#�###
####7�#####P'�#0'�#�###
####7�#####('�##'�#�### ####7�#####�&�#�&�#�#######
%7�#####�&�#�&�#�#######(7�#####�&�#�&�#�#######+7�#####�&�#�&�#�#######.7�#####l&�
#T&�#�###
###37�#####D&�#,&�#�###
###=7�######&�#�%�#�###
###G7�#####�%�#�%�#�###
###Q7�#####�%�#�%�#�###
###[7�#####�%�#h%�#�###
###e7�#####`%�#`%�#�#######o7�#####L%�#L%�#�#######z7�#####D%�#D
%�#�#######�7�#####<%�#<%�#�#######�7�#####0%�#0%�#�#######�7�##### %�#
%�#�#######�7�######%�##%�#�### ###�7�######%�##%�#�### ###�7�#####�$�#�$�#�###
###�7�#####�$�#�$�#�###
###�7�#####�$�#�$�#�###
###�7�#####�$�#�$�#�### ###�7�#####�$�#�$�#�###

###�7�#####�$�#�$�#�#######�7�#####�$�#�$�#�#######�7�#####�$�#h$�#�########8�#####
\$�#P$�#�###############D$�#0$�#�### ####8�##### $�##$�#�###
####8�#####�#�#�#�#�### ####8�#####�#�#�#�#�### ###&8�#####�#�#�#�#�###
###/8�#####�#�#t#�#�###

###98�#####Ѐ�#Ѐ�#�#######B8�#####h#�#h#�#�#######E8�#####`#�#`#�#�#######H8�#####X#
�#X#�#�#######O8�#####D#�#$#�#�#######V8�#######�###�#�#######^8�#######�###�#�####
###f8�#####�"�#�"�#�#######n8�#####�"�#�"�#�#######v8�#####�"�#�"�#�#######w8�#####
�"�#�"�#�#######x8�#####�"�#�"�#�#######{8�#####�"�#�"�#�#######�8�#####|"�#|"�#�##
#####�8�#####t"�#t"�#�#######�8�#####l"�#d"�#�### ###�8�#####T"�#T"�#�###
###�8�#####H"�#H"�#�###
###�8�#####<"�#<"�#�###
###�8�#####,"�#,"�#�###
###�8�##### "�# "�#�###
###�8�######"�##"�#�###
###�8�######"�##"�#�###
###�8�#####�!�#�!�#�#######�8�#####�!�#�!�#�#######�8�#####�!�#�!
�#�#######�8�#####�!�#�!�#�########9�#####�!�#�!�#�########9�#####p!�#p!
�#�########9�#####P!�#P!�#�#######'9�#####0!�#0!�#�#######29�######!�##!
�#�#######=9�######!�##!�#�#######H9�#####� �#� �#�#######S9�#####� �#�
�#�#######^9�#####� �#� �#�#######i9�#####� �#� �#�#######t9�#####� �#�
�#�#######9�#####p �#p �#�#######�9�#####T �#T �#�#######�9�#####8 �#8
�#�#######�9�###### �## �#�#######�9�###### �##
�#�#######�9�#####�#�#�#�#�#######�9�#####�#�#�#�#�#######�9�#####�#�#�#�#�#######�
9�#####�#�#�#�#�#######�9�#####p#�#p#�#�#######�9�#####P#�#P#�#�#######�9�#####4#�#
4#�#�########:�#######�###�#�########:�#####�#�#�#�#�########:�#####�#�#�#�#�######
#$:�#####�#�#�#�#�#######/:�#####�#�#�#�#�#######::�#####|#�#|
#�#�#######E:�#####`#�#`#�#�#######P:�#####@#�#@#�#�#######[:�#######�###�#�#######
f:�#####�#�#�#�#�#######q:�#####�#�#�#�#�#######|:�#####�#�#�#�#�#######�:�#####�#�
#�#�#�#######�:�#####|#�#|
#�#�#######�:�#####X#�#X#�#�#######�:�#####4#�#4#�#�#######�:�#######�###�#�#######
�:�#######�###�#�#######�:�#####�#�#�#�#�#######�:�#####�#�#�#�#�#######�:�#####�#�
#�#�#�#######�:�#####�#�#�#�#�#######�:�#####�#�#�#�#�########;�#####h#�#h#�#�#####
###;�#####P#�#P#�#�########;�#####<#�#<#�#�#######!;�##### #�#
#�#�#######,;�#######�###�#�#######7;�#####�#�#�#�#�#######B;�#####�#�#�#�#�#######
M;�#####�#�#�#�#�#######X;�#####|#�#|
#�#�#######c;�#####X#�#X#�#�#######n;�#####4#�#4#�#########y;�#####0#�#,#�#########
�;�##### #�#
#�#########�;�#######�###�#########�;�#######�###�#########�;�#######�###�#########
�;�#######�###�#########�;�#####�#�#�#�#########�;�#####�#�#�#�#########�;�#####�#�
#�#�# #######�;�#####�#�#�#�#
#######�;�#####�#�#�#�#########�;�#####�#�#�#�#
#######�;�#####�#�#�#�#
#######�;�#####�#�#�#�#########�;�#####�#�#�#�#########�;�#####p#�#p#�#########�;�#
####d#�#d#�#########�;�#####X#�#X#�##########<�#####@#�#@#�#########
<�#####(#�#(#�##########<�#######�###�##########<�#######�###�#########!
<�#####�#�#�#�#########)<�#####�#�#�#�#########1<�#####�#�#�#�#########9<�#####�#�#
�#�#########A<�#####�#�#�#�#########I<�#####�#�#�#�#########Q<�#####x#�#h#�########
#Y<�#####X#�#X#�#########a<�#####H#�#H#�#########i<�#####8#�#8#�#
#######q<�#####,#�#,#�#!
#######y<�#######�###�#"#######�<�#######�###�#########�<�#####�#�#�#�#$#######�<�#
####�#�#�#�#
%#######�<�#####�#�#�#�#&#######�<�#####�#�#�#�#'#######�<�#####�#�#�#�#(#######�<�
#####|
#�#t#�#)#######�<�#####`#�#`#�#*#######�<�#####H#�#H#�#+#######�<�#####0#�#0#�#,###
####�<�#######�###�#-
#######�<�#######�###�#.#######�<�#####�#�#�#�#/#######�<�#####�#�#�#�#0#######�<�#
####�#�#�#�#1#######�<�#####�#�#�#�#2########=�#####�#�#�#�#3#######
=�#####l#�#l#�#4########=�#####X#�#X#�#5########=�#####@#�#@#�#6#######!
=�#####(#�#(#�#7#######)=�#######�###�#8#######1=�#######�###�#9#######9=�#####�#�#
�#�#:#######A=�#####�#�#�#�#;### ###I=�#####�#�#�#�#<### ###R=�#####�#�#�#�#=###
###[=�#####�#�#�#�#>### ###d=�#####p#�#p#�#?### ###m=�#####T#�#T#�#@###
###v=�#####<#�#<#�#A### ### =�#####(#�#(#�#B###

###�=�#######�###�#C#######�=�#######�###�#D#######�=�#####�#�#�#�#E#######�=�#####
�#�#�#�#F#######�=�#####�#�#�#�#G#######�=�#####�#�#�#�#H#######�=�#####�#�#�#�#I##
#####�=�#####�#�#�#�#J#######�=�#####l#�#l#�#K#######�=�#####X#�#X#�#L#######�=�###
##@#�#@#�#M#######�=�#####(#�#(#�#N#######�=�#######�###�#O#######�=�#######�###�#P
#######�=�#####�#�#�#�#Q########>�#####�#�#�#�#R#######
>�#####�#�#�#�#S########>�#####�#�#�#�#T########>�#####�#�#�#�#U#######!
>�#####�#�#�#�#V#######)>�#####x#�#x#�#W#######1>�#####`#�#`#�#X#######9>�#####H#�#
H#�#Y#######A>�#####(#�#(#�#Z#######I>�#######�###�#[#######Q>�#######�###�#\######
#Y>�#####�#�#�#�#]#######a>�#############################�#�#�#�#_#######i>�#####�#
�#�#�#`#######q>�#####�#�#�#�#a#######y>�#####�#�#�#�#b#######�>�#####p#�#p#�#c####
###�>�#####X#�#X#�#d#######�>�#####H#�#H#�#e#######�>�#####<#�#<#�#f#######�>�#####
$#�#$#�#g#######�>�#######�###�#h#######�>�#######�###�#i#######�>�#####�#�#�#�#j##
#####�>�#####�#�#�#�#k#######�>�#####�#�#�#�#l#######�>�#####�#�#�#�#m###
###�>�#####�#�#�#�#n### ###�>�#####|#�#p#�#o### ###�>�#####\#�#@#�#p###
###�>�#####8#�#(#�#q### ###�>�#######�###�#r### ####?�#####�#�#�#�#s### ####?
�#####�#�#�#�#t### ####?�#####tH�#tH�#u### ###!?�######��##��#v### ###*?
�#####�#�#�#�#w### ###3?�#####D��#D��#x#######<?�#####�#�#�#�#y#######@?
�#####|#�#\#�#z#######E?�#####X#�# U�#{#######G?�#####T#�#P#�#|#######H?
�#####�0�#H#�#}#######J?�#####��#�D�#~#######M?�#####@#�#4#�########Q?
�#####$#�###�#�#######U?�#####
#�###�#�#######Y?�#####�#�#�#�#�#######]?�#####�#�#�#�#�#######a?
�#####�#�#�#�#�#######e?�#####�#�#�#�#�#######i?�#####�#�#�#�#�### ###n?
�#####�#�#�#�#�###
###w?�######��#�#�#�###
###�?�#####P��#P��#�#######�?�#####l#�#P#�#�#######�?�#####D#�#D#�#�#######�?
�#####<#�#$#�#�### ###�?�#######�###�#�#######�?�#######�#�#�#�#######�?
�#####�#�#�#�#�#######�?�###### �## �#�#######�?�#####�#�#�#�#�#######�?
�#####�#�#�#�#�#######�?�#####t#�#T#�#�#######�?�#####P��#P��#�#######�?
�#####H#�#<#�#�#######�?�#####0#�#0#�#�#######�?�#######�###�#�#######�?
�#######�###�#�#######�?�#####�#�#�#�#�#######�?�#####�#�#�#�#�#######�?
�#####�#�#�#�#�#######�?�#####�#�#�#�#�#######�?�#####�#�#�#�#�#######�?
�#####�#�#�#�#�########@�#####�#�#�#�#�########@�#####�#�#�#�#�########@�#####�#�#�
#�#�### ####@�#####x#�#l#�#�### ####@�#####`#�#T#�#�### ###,@�#####H#�#<#�#�###
###5@�#####0#�#$#�#�### ###>@�#######�#
#�#�### ###G@�#######�#��#�### ###P@�#####��#��#�### ###Y@�#####��#��#�###
###b@�#####��#��#�### ###k@�#####��#��#�### ###t@�#####��#|�#�###
###}@�#####p�#d�#�### ###�@�#####P�#8�#�#######�@�#####$�#
�#�#######�@�#####�
�#�
�#�#######�@�#####�
�#�
�#�#######�@�#####P)�#P)�#�#######�@�#####�
�#�
�#�#######�@�#####�
�#�
�#�#######�@�#####�
�#�
�#�#######�@�#####|
�#|
�#�### ###�@�#####d
�#d
�#�### ###�@�#####P
�#P
�#�### ###�@�#####D
�#D
�#�### ###�@�#####4
�#4
�#�###
###�@�######
�##
�#�###
###�@�#####
�#
�#�###
###�@�######
�##
�#�###
###�@�#####�#�#�#�#�###
####A�#####���#���#�###
####A�#####�#�#�#�#�###
####A�#####�#�#�#�#�###
###$A�#####�#�#�#�#�###
###.A�#####�#�#�#�#�###
###8A�#####�#�#�#�#�###
###BA�#####�#�#�#�#�###
###LA�#####�#�#�#�#�###
###VA�#####t#�#t#�#�###
###`A�#####h#�#h#�#�###
###jA�#####T#�#T#�#�###
###tA�#####P#�#H#�#�###
###~A�#####0#�#0#�#�###
###�A�#####(#�###�#�###
###�A�#####���#���#�###
###�A�#######�###�#�###
###�A�#####�
�#�
�#�###
###�A�#####�
�#�
�#�###
###�A�#####�
�#�
�#�###
###�A�#####���#���#�###
###�A�#####�
�#�
�#�###
###�A�#####�
�#�
�#�###
###�A�#####�
�#�
�#�###
###�A�#####�
�#�
�#�###
###�A�#####�
�#�
�#�###
####B�#####�
�#�
�#�###
###
B�#####t
�#t
�#�###
####B�#####h
�#h
�#�###
####B�#####X
�#X
�#�###
###(B�#####D
�#D
�#�###
###2B�#####4
�#4
�#�###
###<B�#####,
�#,
�#�###
###FB�######
�##
�#�###
###PB�######
�##
�#�###
###ZB�#####� �#� �#�###
###dB�#####� �#� �#�###
###nB�#####� �#� �#�###
###xB�#####� �#� �#�###
###�B�#####� �#� �#�###
###�B�#####� �#� �#�###
###�B�#####� �#� �#�###
###�B�#####� �#� �#�###
###�B�#####l �#l �#�###
###�B�#####X �#X �#�###
###�B�#####@ �#@ �#�###
###�B�#####0 �#0 �#�###
###�B�###### �## �#�###
###�B�###### �## �#�###
###�B�#####�#�#�#�#�###
###�B�#####�#�#�#�#�###
###�B�#####�#�#�#�#�###
####C�#####�#�#�#�#�###
####C�#####�#�#�#�#�###
####C�#####�#�#�#�#�###
###"C�#####���#���#�###
###,C�#####�#�#�#�#�###
###6C�#####l#�#l#�#�#######@C�#####`#�#T#�#�#######CC�#####@#�#@#�#�#######HC�#####
0#�#0#�#�#######NC�#######�###�#�#######TC�#####�#�#�#�#�#######[C�#####�#�#�#�#�##
#####bC�#####�#�#�#�#�#######eC�#############################�#�#�#�#########hC�###
##�#�#�#�#########jC�#####�#�#x#�#########mC�#####l#�#l#�#########pC�#####`#�#`#�##
#######sC�#####T#�#<#�#########vC�#####0#�#0#�#########yC�##### #�# #�#########|
C�#######�###�#########�C�#######�###�# #######�C�#####�#�#�#�#
#######�C�#####�#�#�#�#########�C�#####�#�#�#�#
#######�C�#####�#�#�#�#
#######�C�#####�#�#�#�#########�C�#####�#�#�#�#########�C�#####|#�#|
#�#########�C�#####d#�#d#�#########�C�#####P#�#P#�#########�C�#####<#�#<#�#########
�C�#####,#�#,#�#########�C�#######�###�#########�C�#######�###�#########�C�#####�#�
#�#�#########�C�#####�#�#�#�#########�C�#####�#�#�#�#########�C�#####�#�#�#�#######
##�C�#####�#�#�#�#########�C�#####�#�#�#�#########�C�#####x#�#x#�#########�C�#####`
#�#`#�#########�C�#####L#�#L#�#########�C�#####<#�#<#�# #######�C�#####(#�#(#�#!
#######�C�#######�###�#"#######�C�#######�###�#########�C�#####�#�#�#�#$#######�C�#
####�#�#�#�#
%#######�C�#####�#�#�#�#&#######�C�#####�#�#�#�#'#######�C�#####�#�#�#�#(########D�
#####�#�#�#�#)########D�#####p#�#p#�#*########D�#####X#�#X#�#+#######
D�#####D#�#D#�#,########D�#####0#�#0#�#-
########D�#######�###�#.########D�#######�###�#/########D�#####�#�#�#�#0#######
D�#####�#�#�#�#1#######$D�#####�#�#�#�#2#######(D�#####�#�#�#�#3#######,D�#####�#�#
�#�#4#######0D�#####�#�#�#�#5#######4D�#####l#�#l#�#6#######8D�#####\#�#\#�#7######
#<D�#####D#�#D#�#8#######@D�#####0#�#0#�#9#######DD�#######�###�#:#######HD�#######
�###�#;#######LD�#####�#�#�#�#<#######PD�#####�#�#�#�#=#######TD�#####�#�#�#�#>####
###XD�#####�#�#�#�#?
#######\D�#####�#�#�#�#@#######`D�#####�#�#�#�#A#######dD�#####x#�#x#�#B#######hD�#
####`#�#`#�#C#######lD�#####P#�#P#�#D#######pD�#####<#�#<#�#E#######tD�#####,#�#,#�
#F#######xD�#######�###�#G#######|
D�#######�###�#H#######�D�#####�#�#�#�#I#######�D�#####�#�#�#�#J#######�D�#####�#�#
�#�#K#######�D�#####�#�#�#�#L#######�D�#####�#�#�#�#M#######�D�#####�#�#�#�#N######
#�D�#####t#�#t#�#O#######�D�#####\#�#\#�#P#######�D�#####D#�#D#�#Q#######�D�#####0#
�#0#�#R#######�D�#######�###�#S#######�D�#######�###�#T#######�D�#####�#�#�#�#U####
###�D�#####�#�#�#�#V#######�D�#####�#�#�#�#W#######�D�#####�#�#�#�#X#######�D�#####
�#�#|
#�#Y#######�D�#####l#�#T#�#Z#######�D�#####@#�#@#�#[#######�D�#####0#�#0#�#\#######
�D�##### #�#
#�#]#######�D�#######�#��#^#######�D�#####��#��#_#######�D�#####��#��#`#######�D�##
###��#��#a#######�D�#####���#���#b#######�D�#####���#���#c#######�D�#####���#���#d#
######�D�#####t��#t��#e#######�D�#####`��#`��#f#######�D�#####D��#D��#g#######�D�##
###,��#,��#h########E�######��##��#i########E�######��##��#j########E�#####��#��#k#
######
E�#####��#��#l########E�#####��#���#m########E�#####���#���#n########E�#####���#p��
#o########E�#####\��#\��#p####### E�#####L��#L��#q#######
%E�#####8��#8��#r#######*E�##### ��# ��#s#######/E�#####
��#
��#t#######4E�#####���#���#u#######9E�#####���#���#v#######>E�#####���#���#w#######
CE�#####���#���#x#######IE�#####���#p��#y#######OE�#####\��#D��#z#######UE�#####0��
##��#{#######[E�######��##��#|
#######aE�#####���#���#}#######eE�#####���#���#~#######iE�#####���#���########mE�#
####���#���#�#######qE�#####���#���#�#######uE�#####���#���#�#######yE�#####���#t��
#�#######~E�#####\��#\��#�###

###�E�#####T��#L��#�#######�E�#####<��#,��#�#######�E�######��#���#�#######�E�#####
���#���#�###
###�E�#####���#���#�###
###�E�#####���#x��#�###############h��#X��#�###############H��#8��#�###############
(��##��#�################��#���#�###############���#���#�###############���#���#�##
#############���#���#�###############���#���#�###############x��#h��#�#############
##`��#P��#�#######�E�#####D��#D��#�#######�E�#####<��#<��#�#######�E�#####,��#
��#�#######�E�#####���#���#�#######�E�#####���#���#�#######�E�#####���#���#�#######
�E�#####���#���#�#######�E�#####t��#\��#�### ###�E�#####P��#8��#�###
###�E�#####,��##��#�### ###�E�######��#���#�### ###�E�#####���#���#�###
###�E�#####���#���#�### ####F�#####���#���#�### ###
F�#####���#���#�###

####F�#####���#���#�########F�#####���#���#�########F�#####���#���#�#######"F�#####
|��#|��#�#######$F�#####`��#`��#�#######'F�#####X��#X��#�###
###/F�#####P��#P��#�### ###8F�#####H��#H��#�###

###AF�#####<��#<��#�#######JF�#####0��#0��#�#######RF�#####$��#$��#�#######ZF�#####
#��##��#�#######bF�#####
��#
��#�#######jF�######��##��#�#######rF�#####���#���#�#######zF�#####���#���#�#######
�F�#####���#���#�#######�F�#####���#���#�#######�F�#####���#���#�#######�F�#####���
#���#�#######�F�#####���#���#�#######�F�#####���#���#�#######�F�#####���#���#�#####
##�F�#####���#���#�#######�F�#####|��#|
��#�#######�F�#####p��#p��#�#######�F�#####d��#d��#�#######�F�#####X��#X��#�#######
�F�#####L��#L��#�#######�F�#####@��#@��#�#######�F�#####4��#4��#�#######�F�#####(��
#(��#�#######�F�######��##��#�#######�F�######��##��#�########G�######��##��#�#####
###G�#####���#���#�#######
G�#####���#���#�########G�#####���#���#�########G�#####���#���#�########G�#####���#
���#�#######!
G�#####���#���#�#######&G�#####���#���#�#######+G�#####���#���#�#######0G�#####���#
���#�#######5G�#####���#���#�#######:G�#####���#���#�#######?
G�#####t��#t��#�#######DG�#####h��#h��#�#######IG�#####\��#\��#�#######NG�#####P��#
P��#�#######SG�#####D��#D��#�#######XG�#####8��#8��#�#######]G�#####,��#,��#�######
#bG�##### ��#
��#�#######gG�######��##��#�#######lG�######��##��#�#######qG�#####���#���#�#######
vG�#####���#���#�#######{G�#####���#���#�#######�G�#####���#���#�#######�G�#####���
#���#�#######�G�#####���#���#�#######�G�#####���#���#�#######�G�#####l��#l��#�#####
##�G�#####T��#T��#�#######�G�#####<��#<��#�#######�G�#####$��#$��#�#######�G�#####
��#
��#�#######�G�#####���#���#�#######�G�#####���#���#�#######�G�#####���#���#�#######
�G�#####���#���#�#######�G�#####���#d��#�#######�G�#####T��#L��#�###############<��
#4��#�############### ��#
��#�#######�G�#####���#���#�#######�G�#####���#���#�#######�G�#####���#���#�#######
�G�#####���#l��#�#######�G�#####X��#D��#�#######�G�#####0��##��#�#######�G�######��
#���#�########H�#####���#���#�########H�#####���#���#�###############���#|
��#�###############h��#T��#�###############@��#,��#�################��##��#�#######
########���#���#�###############���#���#�########H�#####���#���#�########H�#####x��
#d��#########'H�#####H��#$��#########/H�######��#���#########2H�#####���#���#######
##5H�#############################���#���#########8H�##############################
#######################���#���#########>H�#####pr�#���# #######FH�#####t��#h��#
#######NH�#####\��#P��#########VH�#####D��#8��#
#######^H�#####,��# ��########fH�#####
��#���##### ###nH�#####���#���#####
###wH�#####���#���#########�H�#####���#���#########�H�#####|��#|
��#########�H�#####d��#d��#########�H�#####T��#T��##### ###�H�#####D��#D��#####
###�H�#####4��#4��#####

###�H�######��##��#########�H�######��##��#########�H�#####���#���#########�H�#####
���#���#########�H�#####���#���#########�H�#####���#���#########�H�#####���#���####
#####�H�#####���#���#########�H�#####���#���#########�H�#####x��#x��#
########I�#####h��#h��#!########I�#####X��#X��#"### ####I�#####H��#H��##### ###
I�#####<��#<��#$#######)I�#####0��#0��#
%#######/I�#####$��#$��#&#######4I�######��#���#'#######9I�#####���#���#(#######?
I�#####���#p��#)#######EI�#####\��#H��#*#######KI�#####<��#(��#+#######QI�#####
��##��#,#######WI�######��#���#-
#######]I�#####���#���#.###############���#���#/#######cI�#####���#���#0#######iI�#
####���#x��#1#######oI�#####d��#P��#2#######uI�#####(��#(��#3#######{I�######��##��
#4#######�I�#####���#���#5#######�I�#####���#���#6#######�I�#####���#���#7#######�I
�#####|��#|
��#8#######�I�#####T��#T��#9#######�I�#####,��#,��#:#######�I�######��##��#;#######
�I�#####���#���#<#######�I�#####���#���#=#######�I�#####x��#x��#>#######�I�#####X��
#X��#?
#######�I�#####0��#0��#@#######�I�######��##��#A#######�I�#####���#���#B#######�I�#
####���#���#C#######�I�#####���#���#D#######�I�#####h��#h��#E#######�I�#####@��#@��
#F########J�##### ��#
��#G########J�#####���#���#H########J�#####���#���#I########J�#####���#���#J#######
#J�#####|��#|
��#K########J�#####P��#P��#L#######*J�#####<��#<��#M#######1J�#####$��#$��#N#######
8J�######��##��#O#######?
J�#####���#���#P#######FJ�#####���#���#Q#######MJ�#####���#���#R#######UJ�#####���#
t��#S#######]J�#####L��##��#T#######eJ�#####���#���#U#######mJ�#####���#t��#V######
#uJ�#####l��#d��#W###############X��#@��#X### ###}J�#####4��#
��#Y#######�J�######��#���#Z#######�J�#####���#���#[#######�J�#####���#���#\#######
�J�#####���#���#]#######�J�#####���#���#^#######�J�#####���#���#_#######�J�#####���
#���#`#######�J�#####t��#t��#a#######�J�#####X��#X��#b#######�J�#####<��#<��#c#####
##�J�#####0��#0��#d#######�J�######��##��#e#######�J�######��##��#f#######�J�#####�
��#���#g#######�J�#####���#���#h#######�J�#####���#���#i#######�J�#####���#���#j###
####�J�#####���#���#k#######�J�#####���#���#l#######�J�#####���#���#m#######�J�####
#|��#|
��#n#######�J�#####l��#l��#o#######�J�#####\��#\��#p#######�J�#####L��#L��#q#######
�J�#####4��#4��#r#######�J�######��##��#s#######�J�######��##��#t#######�J�#####���
#���#u#######�J�#####���#���#v#######�J�#####���#���#w#######�J�#####���#���#x#####
##�J�#####���#���#y#######�J�#####���#���#z#######�J�#####|��#|
��#{#######�J�#####t��#t��#|
#######�J�#####l###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###�###[###]###\###^#######�###�###�###�###�###�###�###�###�###�###�###�###�###�##
#�###�###�#######l###n###m###o######�###�###o###�#######�#######�###�#######
###+###<###>###!###,###=###�###�###?###-###P###|###t###B###q###F###C###)###c###W###
###
###}###"#######$###.###�###�###�###�###########X###############r###_###�###�###�###
9###n#######�###�###{#######�###�### ###�###
###�###�###�###�###�###�###D###�###�###�###E###�######b###�###
%###'###&###(#######a###x###z###y###{###u###|
###########�#######`###h###w###*###A###s###�###�###�###�### ###########
###)###@###�###�###�###�###�###�###d#######�###�###########z###
###�###�###}###�###!#######�###
###p###�###k###x###�###�###r###�###�###�###�###Z###r###W###m#######�###\###�###�###
�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###q###�###�##
#####�###�###�#######Y###s###6###�###�###�###�###2###5###�###g###X###t###&###
%###�###�###�###�###�###�###{###k###g#######~###w###|
###�###�###�###�###�###�###�###�###�###�###�###"###########�#######################
0###�###u###�###�###�###8###~###t###c###�###Y###�###�###�###�###/###+###S###-
###.###,###R#######�########### ###!
###�###�###�###�###�###�###�###y###�#######8###9###:###;###3###=###<###>###4###7###
Q###H###I###J###K###L###V###G###1###@###A###B###C###D###E###F###?
###M###N###O###P###2###6###5###'###U###(###T###*#######
###c###b###d###�###e###f###�###################C###F###E###D###
###i###j###h###Q###�#######N###Z###J###P###O###S###R###H###I###Q###X###Y###W###M###
U###V###T###L###G###K#######�###�###�#######.###*###7###/###,###6###4###3###8###-
###5###+###1###2#######0###�#######################################################
Z###[### ###`###a###\###_###]###�###########
###############�###�###�###�#######g#######�###�###9###<###?
###>###=###@###;###:###B###A#######�###�###�###�###�###�###�###�###�###�###�###�###
�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�##
#�###�###�###�###�###�###�###�###�###�###�###�###�#######�###�###�###�###�#######�#
##�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###e###�###e
###�###&###'###(###V#######�###�###S###�###�###�###�###�###�###�###)###k###�###3###
###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###q###�###H###L###J##
#:###O###G###N###;###K###I###�###M###�###�###�###l###�###v###p###�###�###�###_###�#
##�###�###�###�###�###�###�###�###�#######�#######�###############################�
###/###�###�###^###]###�###�###h###i###0###�###�###�###�###�###�###�###�###�###T###
v###�###�###�#######�###�###f###�###m###�###�#######�###y#######�###�#######"###$##
#�###[###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�#
##�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###n###�###i###�###s###q
###########~###}###|
######�###�###�###################_###p###l###w###o###t###v###u###m###{###x###y###
z###s###r###n###k###g###h###j###i###c###a###`###b###e###f###d#######@###:##########
#;###<###############A###############B###C#######=#######X###.###P###/###Q###W###V#
##D###E### ###!###"###F###G###H#######$###%###I###########>###?
#######0###6###3###S###T###4###5###U###J###K###&###'###(###L###M###N###)###*###+###
O###7#######1###
####### #######,###-###########
###
###8###9###########R###2###^###Y###Z###\###[###]###4###�###�###�###�###U#######�###
R###�###�###z###j###�###`###b###a###�###
%###�###j###�###w###�###x###7###1###p###�###o###u###�###�###�###�###�###�###�###�##
#�###�###�###�###�###$###d###�###�###�###k###�###p###�###�###m#######�#######�#####
##~###�###�###�###�###t###�###-
###Q###/###S###R###+###1###,###2###)###0###'###U###(###T###V###*###�###�###�###�###
z###&###'###(###�###�###�###�###�###�###�###�######�###�###�###�###�###X###�###�##
#�###�###�###�###H###L###J###G###:###O###N###9###;###K###I###M###�###�###r###o###q#
##n###s###�###�###E###�######Z###�###�###�###�###########�###�###�#######�###�###�
###�###�###�###�###w###
###�###�###Z###W###g###X###�#######Y###�###~###Y###�###V#######S###�###�###�###�###
T###U#######R###�###�###�###!#######�###
###�###l###^###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###x###�###�###�###r###[###]###\###^###�###\###�###�###�###�###�###�###�###�###�##
#�###�###�###�###�###�###�###�###�###�###�###q###�###�###�###�###�###�###�###�###�#
##�###�###�###�###�###�###�###�###�#######�###l###n###m###o###�###�#######s###6###�
###�###y##########2###5#######�###t###&###
%###�###�###�###�###�###{#######�#######�###�####### ###+###<###>###!
###,###=###�###�###?###-###k###g###P###########z###w###|
###�###�###�###�###�###�###�###�###�###|
###�###�###t###C###B###q###F###"#######)#######�#######################0###x###u###
8###c###�###�###�###�###w###�###Y###c###.###W###
##########�########### ###!
###�###�###�###y###�###}###8###9###:###;###3###=###<###>###4###7###H###I###J###K###
L###G###@###A###B###C###D###E###F###?###M###N###O###P###6###5###
###c###b###d###�###e###f###�###################C###F###E###D###
###i###j###h###Q###�#######N###Z###J###P###O###S###R###H###I###Q###X###Y###W###M###
U###V###T###L###G###K#######�###�###�#######.###*###7###/###,###6###4###3###8###-
###5###+###1###2#######0###�#######################################################
[### ###`###a###\###_###]###�##########################�#######g#######9###<###?
###>###=###@###;###:###B###A###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�##
#�###�###�###�###�###�###�###�###�###�###�###�#######�###�###�###�###�#######�###�#
##�###�###�###�###�###�###�###�###�###�###�###�###�###�###"#######$###.###�###�###e
###e###�###�###�###o###�###�###�###�#######�###�###�#######�###�###�###############
�#######r###h#######_###`###k###Z#######3###�###�###�###�###�###�###{#######�######
#�###l###�#######v###m### ###�###p###
###�###�###�###�###�###�###�###�###D###�###�###�###_###�###�###�###�###�###�###�###
�###�###�###�#######�###############################�###/###^###]###�###�###h###i##
#�###�###�###�###�###�###�###�###v###�###�#######�###�###b###�###
%###'###&###(#######a###x###z###y###{###f###�###u###w###�###m###�###�###########�##
#y###|
###�###�#######"###$###�###[###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###{##
#n### ###########
###i###q###########~###}###|
######�###�###�#######_###p###l###t###v###u###s###r###n###k###g###h###j###i###c###
a###`###b###e###f###d#######@###:###########;###<###############A###############B##
#C#######=#######X###.###P###/###Q###W###V###D###E### ###!
###"###F###G###H#######$###%###I###########>###?
#######0###6###3###S###T###4###5###U###J###K###&###'###(###L###M###N###)###*###+###
O###7#######1###
####### #######,###-###########
###
###8###9###########R###2###\###[###]###)###@###s###A###�###�###�###�###�###�###�###
�###*###4###�###�#######�###�###�###z###j###d###`###b###a###�###
%###j###�###�#######x###7###1###p###�###�###o###u###�###�###�###�###�###�###�###�##
#�###�###�###�###�###$###d###�###�###�###}#######�###�###�###�###�###�###{###�###�#
######�###|###
###z###Q#######�###�###�###}###�###�###
###d###i###############�###########j###k###[###\###]###�###^###_###`###a###b###c###
d###e###f###g###h###i###j###k###l###m###n###o###p###q###r###s###t###�###c###e###�##
#�###�###u###v###w###x###y###z###{###|
###�###�#######R###S###T###U###V###W###X###�###�###�###�###########�###g###Y###�###
Z###�###~###Y###�###�###�###########################�###~######�###�###�###�###�##
#x###�#######`###_###�########### ###
#######
############################################################################## ###!
###"#######$###%###&###'###(###)###*###+###,###-
###.###/###0###1###2###3###4###5###6###7###8###9###:###;###<###=###>###?
###@###A###B###C###D###E###F###G###H###I###J###K###L###M###N###O###P###Q###R###S###
T###U###V###W###X###Y###Z###[###\###]###^###l###m###n###o###_###`###a###b###c###d##
#e###f###g###h###i###j###k###|###�###�###}###~######
%###&###�###�###�###�###h###########-#######y###C###B###*###
###)###@###F###s###u###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###p###q###r###s##
#t###u###v###�###�###�###�###�###�###�###�###�###�###�###�###$###|
#######'###(###)###*###+###,###-
###/###0###1###2#######�######�###�###w###w###x###y###z###{###�###4###3###M###N###
O###P###5###6###7###8###9###:###;###<###=###>###?
###@###A###B###C###D###E###F###G###H###I###J###K###L#######�###�###�###t###q###�###
�###�###�###############�#######�####################### ###
#######
###�###�###�###�###9###�###�###�###�###�###�###�#######�###�####### #######
###T###U###R###S###Q###V###�#######�#######/###################�########### ###!###
%#######,###x###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�##
#�###�###�###�###�###�###�###�###�###�###�###�###################
###############################################################�###############
###!###"#######$###�###�###�###�###�###
%###�###�###�###�###&###'###(###�###�###)###*###+###,###-
###.###/###0###1###2###3###4###5###6###7###8#######9###:###C###D###E###F###G###H###
I###J###K###L###M###N###O###P###Q###R###S###T###U###V###W###X###Y###Z###[###Z###\##
#]###_###`###a###b###c###d###e###f###�###g###h###i###j###�###�###�###�###�###k###l#
######
###
###:###;###�###�###�###�###l###p###################�#######A###�###�###�###�###�###
#### ###
###�###�###�###D###E###�###�###########################0###1###2###3###4###5###6###
7###8###�###�###�###�###�###�###�###�###�###X###�###[###;###<###=###>###?
###@###A###B###m###n###o###p###q###r###s###t###u###v###w###�###�###�###�#######�###
�###�###�#######�###�###�###�#######�###�###�###�###"#######G###H###I###J###K###L##
#M###N###O###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�#
##�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�
###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�##
#�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�#
##�###�###�###�###�###�###########�###�###�###�###�###�###�###�###�###�###�###�###�
###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###�###
�###�###�###}###�###�###�###�###�###�###�###�#######�###�###�###�###�###�###"###ope
nssl\crypto\objects\obj_dat.c####.%lu########@###A#######
###�z##��##�z##########@�## �######################@###d###########�###�#######
####{##@{##`{##########@�## �######################@###t###########�###�### ###
### {##@{##`{##########@�## �######################@###t###########�###�###0###
###�{##�{###|##########@�## �######################�###�###########�###�###@###
###�{##�{###|##########@�## �######################�###�#######
%02X####openssl\crypto\asn1\t_x509.c####%02x%s##Bad time value##%s %2d %02d:%02d:
%02d%.*s %d%s## GMT####%s %2d %02d:%02d:%02d %d%s##%02x%c##
(Negative)#0123456789ABCDEF####openssl\crypto\bn\bn_print.c####%09u####<EMPTY>
####%*s#%*s<Not Supported>##%*s<Parse Error>####%*s%s###critical####%*s%s:
#####################################x##(####################### #

#################################################################0123456789ABCDEF##
##������������#������##�###�#�#�##\%02X###\U%04lX#\W
%08lX#openssl\crypto\asn1\a_strex.c###openssl\ssl\ssl_asn1.c##os.length <=
(int)sizeof(ret->session_id)###openssl\ssl\ssl_sess.c##error number %ld####CRL path
validation error###unsupported or invalid name syntax##unsupported or invalid name
constraint syntax###unsupported name constraint type####name constraints minimum
and maximum not supported##excluded subtree violation##permitted subtree
violation#RFC 3779 resource not subset of parent's resources##Unsupported extension
feature###Different CRL scope#no explicit policy##invalid or inconsistent
certificate policy extension####invalid or inconsistent certificate
extension###unhandled critical CRL extension####key usage does not include digital
signature####key usage does not include CRL signing##unhandled critical
extension####unable to get CRL issuer certificate####key usage does not include
certificate signing##authority and issuer serial number mismatch#authority and
subject key identifier mismatch###subject issuer mismatch#application verification
failure####certificate rejected####certificate not trusted#unsupported certificate
purpose#####proxy certificates not allowed, please set the appropriate flag#proxy
path length constraint exceeded###path length constraint exceeded#invalid non-CA
certificate (has CA markings)####invalid CA certificate##certificate
revoked#certificate chain too long##unable to verify the first certificate##unable
to get local issuer certificate##self signed certificate in certificate
chain####self signed certificate#format error in CRL's nextUpdate field##format
error in CRL's lastUpdate field##format error in certificate's notAfter
field####format error in certificate's notBefore field###CRL has
expired#certificate has expired#CRL is not yet valid####certificate is not yet
valid####CRL signature failure###certificate signature failure###unable to decode
issuer public key##unable to decrypt CRL's signature###unable to decrypt
certificate's signature###unable to get certificate CRL###unable to get issuer
certificate####ok##%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s
###FIPS####HIGH####MEDIUM##LOW#EXPORT56####EXPORT40####EXP#GOST89MAC###GOST94##CAME
LLIA256#CAMELLIA128#AES256##AES128##eNULL###IDEA####PSK#AECDH###ADH#KRB5####EECDH##
#EDH#aGOST###aGOST01#aGOST94#aPSK####aECDSA##aECDH###aDH#aNULL###aKRB5###DSS#aDSS##
##aRSA####kGOST###kPSK####kEECDH##kECDH###kECDHe##kECDHr##kKRB5###DH##kEDH####kDH#k
DHd####kDHr####kRSA####COMPLEMENTOFDEFAULT#COMPLEMENTOFALL#####LH�#############���#
###########################���#############
###############################���#####�#######���############################���##
###########################################���#####################################
########���#############################################���########################
#####################���#############################################���###########
##################################���#############################################|
��#####
#######################################t��#####@###################################
####l��#####`#######################################d��#####�######################
#################<a�#####�#######################################\��###############
##############################T��#############################################L��##
###########################################D��#####################################
########@��#############################################8��#########
###################################0��#############################################
,��#############################################$��################################
##############��#########@###################################Da�#########@#########
###########################��#########�###################################
��##############################################��#################################
############���#############################################���#########���########
########################���#####�###���################################P��#########
#### ###############################���#########
###################################pe�#############################################
���#############################################���#####�##########################
#############���#########�###################################�b�###################
###########################c�#############################################(d�######
#######################################�a�#########################################
####���#############################################�c�############################
#################���#############
###############################���#############@###############################���#
############�################################e�#############�######################
#########���#############################################���#######################
######################`e�#############################################h��##########
###################################Xe�#############################################
P1�#############################################���################################
#############���#############################################���###################
##########################���#############################################���######
#######################################���#########################################
####�%�#############################################|
��#############################################p��#################################
############l��#########################
###################d��#########################@###################\��#############
############�###################T��#############���########################ssl_mac_
secret_size[SSL_MD_GOST94_IDX] >= 0#ssl_mac_secret_size[SSL_MD_SHA1_IDX] >=
0###openssl\ssl\ssl_ciph.c##ssl_mac_secret_size[SSL_MD_MD5_IDX] >=
0####STRENGTH####TLSv1/SSLv3#(NONE)##OpenSSL DH
Method###openssl\crypto\dh\dh_key.c##rmd160##ripemd##dss1####DSS1####lhash part of
OpenSSL 1.0.0f 4 Jan
2012#openssl\crypto\lhash\lhash.c####smime_sign##�$�#############################d#
######�2�#############################����####���#############################����#
###���#############################����####���#############################����####
openssl\crypto\x509\x509_vpm.c##openssl\ssl\s3_pkt.c####mac_size >= 0###SSL alert
number
###openssl\crypto\engine\eng_init.c####X509_NAME###X509_NAME_INTERNAL##X509_NAME_EN
TRIES###RDNS####X509_NAME_ENTRY#############肹#�^###############+�#�_##########\��#
############L��#############D��#`#######�������#############0��##############��#�##
#####�������##############��#####p ###
##########�###�####################��######��#openssl\crypto\asn1\x_name.c####opens
sl\crypto\ex_data.c################################*###)#######A###@#######B###)###
t###F###@###C###`###_#######h###########q###@###t###s###@#######w###u#######�######
#####�###@###�###�###�#######�###�#######�###�#######�###�###############�#########
##�#######�###�#######�###�#######�###�#######�###�###"###�###t#######�###t###'###)
###+###(###)###,###T###)###R###U###)###S#######D��#P��#x��#���#���#���#���#���#���#
���#���##��#���#���#���##��#���#h��#
��#t��#,��#���#8��#���#\��#���#���#���#���#timestampsign###Time Stamp
signing##ocsphelper##OCSP helper#Any Purpose#crlsign#CRL
signing#smimeencrypt####S/MIME encryption###smimesign###S/MIME
signing##nssslserver#Netscape SSL server#sslserver###SSL server##sslclient###SSL
client##G###S###U###W###Y###~###�###�###�###�###�###openssl\crypto\x509v3\v3_purp.c
#openssl\crypto\comp\comp_lib.c##openssl\crypto\bio\bf_buff.c####openssl\crypto\buf
fer\buffer.c##OCSP_SERVICELOC#locator#OCSP_CRLID##crlTime#crlNum##crlUrl##OCSP_BASI
CRESP##tbsResponseData#OCSP_RESPDATA###responseExtensions##responses###producedAt##
responderId#OCSP_SINGLERESP#singleExtensions####thisUpdate##certStatus##certId##OCS
P_CERTSTATUS#value.unknown###value.revoked###value.good##OCSP_REVOKEDINFO####revoca
tionReason####revocationTime##OCSP_RESPID#value.byKey#value.byName####OCSP_RESPONSE
###responseBytes###responseStatus##OCSP_RESPBYTES##responseType####OCSP_REQUEST####
optionalSignature###tbsRequest##OCSP_REQINFO####requestExtensions###requestList#req
uestorName###OCSP_ONEREQ#singleRequestExtensions#reqCert#OCSP_CERTID#issuerKeyHash#
##issuerNameHash##hashAlgorithm###OCSP_SIGNATURE##certs###signatureAlgorithm#######
###########���#�b##############���#�]##�###########���#`###########���#########
###���#############���#�b##############p��#�]##############`��#�]##########
###���#�\###########��#############T��#############L��#�4##�###########4��#�5######
####���#############(��#�###########d��#�\##�############��##�##############
��#�4##�#######
###���#�5##########���#############���#############���#�4##�###########���#�4######
####4��#############���#############���#�^##############
#�#�]##########x��#############���#############���#@]##�###########x��#�4##########
���#############h��#�###########X��#�###�###########L��#�]###########��############
#@��#############0��#�^##�############��#@]##########D��##############��#�#########
##���#p^##�###########���#p5##�###########���#p^##########���#############���######
#######���#�4##############���#�5##############���#�^##�#######
###D��#�^##�###########���#�5##########���#############���#�###########d��#�\######
########|��##5##############p��#�^##########
###d��#�5##�###########P��#�5##########`��#############@��#############0��#�5######
########���#�b##############���#�]##�#######
###���#`###########���#############
��#�############��#�^##�############��#�\##�############��#�^##########L��#########
###���#############T��#�###############���#`�##########���#############���#X509_EXT
ENSIONS#Extension###X509_EXTENSION##############肹
#�^##############P��#�_###############+�#�]###########��#########
####��#############���#�5######����l��#############���#openssl\crypto\mem_dbg.c####
openssl\crypto\bio\b_print.c####<NULL>##doapr()#openssl\crypto\pem\pem_oth.c####PEM
part of OpenSSL 1.0.0f 4 Jan
2012###0123456789ABCDEF####openssl\crypto\pem\pem_lib.c####phrase is too short,
needs to be at least %d chars
#Enter PEM pass phrase:##ENCRYPTED###DEK-Info: ##-----END ###-----
##-----BEGIN #PKCS #7 SIGNED DATA#X509 CERTIFICATE####Proc-Type: #Expecting:
#ASN1_SET_ANY####ASN1_SEQUENCE_ANY###ASN1_OCTET_STRING_NDEF##ASN1_FBOOLEAN###ASN1_T
BOOLEAN###ASN1_BOOLEAN####DIRECTORYSTRING#DISPLAYTEXT#ASN1_PRINTABLE##ASN1_SEQUENCE
###ASN1_ANY####ASN1_BMPSTRING##ASN1_UNIVERSALSTRING####ASN1_VISIBLESTRING##ASN1_GEN
ERALIZEDTIME####ASN1_UTCTIME####ASN1_GENERALSTRING##ASN1_IA5STRING##ASN1_T61STRING#
#ASN1_PRINTABLESTRING####ASN1_UTF8STRING#ASN1_OBJECT#ASN1_NULL###ASN1_OCTET_STRING#
##ASN1_BIT_STRING#ASN1_ENUMERATED#ASN1_INTEGER############################���#####
###################���#########################���#########################���#####
####################���#########################���#####
###################���#########################t��#########################d��#####
####################T��#########################@��#########################0��####
######################��##########################��#########################���###
######################���#####���################���#########################���###
###=##################���#####P(##################���######)##################���##
###################�������#########################t��#########################d��#
########################L��#############8��##_######�������#############8��########
#####(��##_######�������#############(��#X509_PUBKEY#public_key##algor#############
######``##################,��#�b############## ��#�]##########L��#####4��#
####��#openssl\crypto\asn1\x_pubkey.c##X509_VAL####notAfter####notBefore###########
####���#@.##############���#@.##########���#############���#X509_ALGORS#algorithms#
#X509_ALGOR##############D��#�^##############L˼##_##########<��#############0��####
#########$��#�b######�������##############��#######################################
########### ###########################################@###�##
###@###�###################openssl\crypto\asn1\tasn_dec.c##Type=###Field=##,
Type=#openssl\crypto\asn1\tasn_enc.c##openssl\crypto\asn1\tasn_new.c##NAME_CONSTRAI
NTS####excludedSubtrees####permittedSubtrees###GENERAL_SUBTREE#maximum#minimum#�###
#####�##############################0�##�######################���##�##�###########
���#�\##�###########���#�\##########<��#########
###���#�###########���#�##�###########���#�##########���#############���#openssl\cr
ypto\x509v3\v3_ncons.c####excluded####permitted###IP Address:<invalid>####%X##%d.
%d.%d.%d/%d.%d.%d.
%d#IP:#Excluded####Permitted###GENERAL_NAMES###GeneralNames####GENERAL_NAME####d.re
gisteredID##d.iPAddress#d.uniformResourceIdentifier#d.ediPartyName##d.directoryName
#d.x400Address###d.dNSName###d.rfc822Name####d.otherName#EDIPARTYNAME####partyName#
##nameAssigner####OTHERNAME###type_id#################\��#�^##�############+�##_###
#######h��#############P��#�###########@��#�_##�###########4��#�_##########���#####
########$��#�############��#К##�############��#�^##�###########���#�^##�###########
���##_##�###########���#�###�###########���#�##�###########���#�^##�###########���#
�]##�###########���#�^##########���#

###########���#############t��##�######������#############d��#openssl\crypto\x509v3
\pcy_cache.c###ISSUING_DIST_POINT##onlyattr####indirectCRL#onlysomereasons#onlyCA##
onlyuser####CRL_DIST_POINTS#CRLDistributionPoints###DIST_POINT##CRLissuer###reasons
#distpoint###DIST_POINT_NAME#name.relativename###name.fullname###AACompromise####AA
Compromise###privilegeWithdrawn##Privilege Withdrawn#certificateHold#Certificate
Hold####cessationOfOperation####Cessation Of
Operation##superseded##Superseded##affiliationChanged##Affiliation
Changed#CACompromise####CA Compromise###keyCompromise###Key
Compromise##unused##Unused##g#######P�###############################�##��#########
#Y#######P�###############################�##��################�###�#####�#�#�#�###
##�#�#�#�#####�#�#�#�#####�#�#�#�#####p#�#X#�#####D#�#4#�##### #�#
#�#####��#��#����########################Т######�###########��##�##�###########��#`
#############�#######�#
###���#�###########���##�##�###########���#�]##�###########���##�##########\#�#####
########���#############t��#
�######�����#�#############d��###########�##############��#�###########���##�##�###
########X��#�_##�###########P��#�_##�#######
###@��#�]##�###########4��#�_##�###########(��#�_##########��######################
########��##��##########openssl\crypto\x509v3\v3_crld.c#%*s%s:
%*s##%*sRelative Name:
%*s###%*sFull Name:
##%*s<EMPTY>
#%*sOnly Attribute Certificates
#Only Some Reasons###%*sIndirect CRL
####%*sOnly CA Certificates
####%*sOnly User Certificates
##%*sCRL Issuer:
#Reasons#relativename####fullname####section:####,name:##,value:#onlyAA##AUTHORITY_
KEYID#serial##keyid###�#############�#�]##�###########T��##�##�###########�#�#�\###
#########�#########
###�#�#X509_CERT_PAIR##reverse#X509_CERT_AUX###alias###reject##trust###############
�#�#�^##�###########�#�#�^##############�#�#�^##########
#####�#�]##�###########���#�b##########�#�#############x#�#�############.�#`###�###
########p#�#`###########
#�#############`#�#0123456789ABCDEF####openssl\crypto\x509\x509_obj.c##NO
X509_NAME####openssl\crypto\asn1\a_dup.c#openssl\ssl\s3_both.c###i <=
EVP_MAX_MD_SIZE####FILE
pointer####openssl\crypto\bio\bss_file.c###fopen('#','#r+##a+##openssl\crypto\asn1\
d2i_pr.c####iqmp####dmq1####dmp1####################��##################d��#
###############p
�#�###############��#�###############t��#�###############(=�#�###########
###,��#�###########$###h#�#�###########(###`#�#�###########,###X#�#�###########�#�#
###p#�#X###pe�#################��##################p
�#�###############��#�###########p#�#####X#�#X###pe�#####ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/########�������������������������������������
���>��?456789:;<=���#���#########
#
############������###### !"#$%&'()*+,-./0123�����openssl\crypto\evp\encode.c#ctx-
>length <= (int)sizeof(ctx->enc_data)###n < (int)sizeof(ctx-
>enc_data)##openssl\crypto\engine\tb_cipher.c###openssl\crypto\ui\ui_lib.c##You
must type in ### characters#openssl\crypto\rsa\rsa_sign.c###signature has problems,
re-make with post SSLeay045
####MD5 part of OpenSSL 1.0.0f 4 Jan
2012###openssl\crypto\objects\o_names.c############ ###########p#######
###########p#######D###�###@###p#######�#######@###�!######�###a###@###�!
######�###,###@###�!######�###+###@###�!######�###%###@###�!######�###b###@###�!
######�###��������#�######�###�#######p#######�###�#######p#######�#######@###p####
###�###����@###############����################�����###############�����###########
###�����###########!
###�����###########*###����)#######openssl\crypto\evp\evp_pbe.c####TYPE=###openssl\
crypto\asn1\evp_asn1.c##openssl\crypto\evp\pmeth_lib.c##openssl\crypto\engine\tb_di
gest.c###DSA part of OpenSSL 1.0.0f 4 Jan
2012###openssl\crypto\dsa\dsa_lib.c####openssl\crypto\ec\ec_key.c##X509_ATTRIBUTE##
value.single####value.set###############��##_##############��##_##########�
�#########
###p�#############肹#�^##################`###########��#########
###p
�#openssl\crypto\evp\pmeth_fn.c###X509_SIG################,��#�b##############���#�
]##########P#�#############D#�#PKCS8_PRIV_KEY_INFO#pkey####pkeyalg#################
0###################d��#�\##############�#�#�b##########
###�#�##_##�###########��#p###########�#�#####�#�#####�#�#openssl\crypto\evp\evp_pk
ey.c###ASN.1 part of OpenSSL 1.0.0f 4 Jan
2012#openssl\crypto\asn1\asn1_lib.c##address=#### offset=####Eric Young's PKCS#1
RSA#openssl\crypto\rsa\rsa_eay.c########openssl\crypto\bn\bn_blind.c####openssl\cry
pto\bn\bn_ctx.c##openssl\crypto\bn\bn_gcd.c##openssl\crypto\bn\bn_add.c##X509_REQ##
##req_info####X509_REQ_INFO###pubkey######################PJ##############
###d��#�\##############\��#�###############�#�#�`##�###########��#p###########�#�##
###�#�#####�#�#########
###########################x#�#�J##############h��#�b##############���#�]##########
<#�#####$#�#####l#�#PKCS7_ATTR_VERIFY###PKCS7_ATTR_SIGN#PKCS7_ATTRIBUTES####PKCS7_D
IGEST####PKCS7_ENCRYPT###PKCS7_SIGN_ENVELOPE#PKCS7_ENC_CONTENT###content_type####PK
CS7_RECIP_INFO####enc_key#key_enc_algor###PKCS7_ENVELOPE##enc_data####recipientinfo
###PKCS7_ISSUER_AND_SERIAL#PKCS7_SIGNER_INFO###unauth_attr#enc_digest##digest_enc_a
lg##auth_attr###digest_alg##issuer_and_serial###PKCS7_SIGNED####signer_info#cert###
#md_algs#d.encrypted#d.digest####d.signed_and_enveloped##d.enveloped#d.sign##d.data
##d.other#####�###########t#�##_##############�#�#####�#�#########�###########l#�#�
_######�###########d#�#PK######�###########X#�#�K######�###########@#�##L######�###
########4#�#0L######�###########(#�#
L##################�J##################���#�^######����####���#�J##########X#�#####
@#�#####���#########�#�#############�#�#############d��#�\##############
#�#�b##############8-�# K##�#############�#`###�#######
###(��##\##############
#�#�K##################`K##################d��#�\##############�#�#�K##############
�#�#�b##�#######
###�#�#p###############�#�#�b##############�#�#�]##�###########�#�#p###########H#�#
####0#�# ###�#�#############T��#�###############�#�#�\##########�#�#############|
#�#############d��#�\##############l#�#�K##############`#�##L##########4#�#########
###P#�#################�K##############�#�#####�#�#####$#�#############d��#�\######
########�#�#�K##############@#�#�b##########
###8#�#�]################�#�^##############D��#�b##�###########`#�#�_############�#
##############�#############d��#�\##############l#�#�K##############
#�#�b##############`#�##L##�#############�#`###�#######
###(��##\##############
#�#�K##########h#�#############�#�#############d��#�\##############`#�##L##########
##�#############�#�#########p#�#############�#�#############d��#�\##############H}�
#�b##############8-�# K##########
###���#�]##############�#�#p#######�����#�#############�#�#
###########�#�#p#######�����#�#############�#�#NETSCAPE_CERT_SEQUENCE##############
####PL##################���#�^##�###########���#`###########P#�#####8#�#####
#�#priv_key####pub_key#DSA_SIG#################�L##################��#�###########
####$8�#�###########�#�#####�#�#####�#�#################PM##############@#�#####
#�#D###,e�#############d��# ###########
###(=�#�###############,��#�###############D#�#�###############�#�#�###############
�#�#�###################PM##############
###(=�#�###############,��#�###############D#�#�###########�#�#####�#�#D###,e�#####
########�#�#�###########
###(=�#�###############,��#�###############D#�#�###########(#�#########D###,e�#####
############PM##################�#�#�###################
N##########�#�#####�#�#D###,e�#openssl\crypto\dsa\dsa_asn1.c###EC_PRIVATEKEY###publ
icKey###privateKey##ECPKPARAMETERS##value.implicitlyCA##value.parameters####value.n
amed_curve###ECPARAMETERS####cofactor####curve###fieldID#X9_62_CURVE#seed####X9_62_
FIELDID###fieldType###p.char_two##p.prime#X9_62_CHARACTERISTIC_TWO####p.ppBasis###p
.tpBasis###p.onBasis###p.other#X9_62_PENTANOMIAL###k3##k2##k1##################X#�#
###############T#�# ###############P#�# ###########`#�#########
###<#�#############4#�##_##############�#�#####�#�#####�###############(#�#p^##�###
##############�#�\##�#################�#�O##############d-�#
###############���#�^######����####�#�#�O##########0#�#########
###�#�#############4#�##_##�###############�#�#�\##�###############�#�#�O##########
####�#�#####�#�#################�#�#�^######����####�#�#�O##########�#�############
#�#�#############T8�#�]##############���#�]##############�#�#�]##########,#�#######
##
###�#�#########�#�#############�#�#############d��#
###############�#�#�O##############�#�#�O##########
###���#�]###############��#�\##############�#�#�\##############p#�#�^##############
\#�##P##############H#�#p^########### �#############8#�#############d��#
###############,#�#�]##�###########
r�##P##�#######
### #�#�]##########p
�###############�#openssl\crypto\ec\ec_asn1.c#################pi##################(
=�#�###########
###D#�#�###############$��#0############!�#####� �#L###���###################
###########
%#)#+#/#5#;#=#C#G#I#O#S#Y#a#e#g#k#m#q##�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�
#�##############
%#3#7#9#=#K#Q#[#]#a#g#o#u#{##�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#
#######-
#3#9#;#A#K#Q#W#Y#_#e#i#k#w#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#########)#+#5#7#
;#=#G#U#Y#[#_#m#q#s#w#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�### #######%#'#-#?
#C#E#I#O#U#]#c#i##�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�###
###########'#)#/#Q#W#]#e#w#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�###
#########+#/#=#A#G#I#M#S#U#[#e#y##�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#
#####'#7#E#K#O#Q#U#W#a#m#s#y#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#######!
###'#)#3#?#A#Q#S#Y#]#_#i#q#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�## # # #
% + / 5 C I M O U Y _ k q
w � � � � � � � � � � � �
� � � #
#
!
1
9
=
I
W
a
c
g
o
u
{




















##########)#-#?#G#Q#W#]#e#o#{#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�##
#
#
%
/
1
A
[
_
a
m
s
w
















#####!+-=?OUiy�������������������� #####!
#'#/#5#;#K#W#Y#]#k#q#u#}#�#�#�#�#�#�#�#�#�#�#�#�#�#�########
%#)#1#C#G#M#O#S#Y#[#g#k##�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#######!#%#+#9#=#?
#Q#i#s#y#{#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#######'#-
#9#E#G#Y#_#c#i#o#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#
#######)#+#1#7#A#G#S#_#q#s#y#}#�#�#�#�#�#�#�#�#�#�#�#�######'#-
#7#C#E#I#O#W#]#g#i#m#{#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�###!
#/#3#;#E#M#Y#k#o#q#u#�#�#�#�#�#�#�#�#�#�#�###########
%#)#+#7#=#A#C#I#_#e#g#k#}##�#�#�#�#�#�#�#�#�#�#�#�### ###########
%#3#9#=#E#O#U#i#m#o#u#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#

#####'#3#A#]#c#w#{#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#######5#7#;#C#I#M#U#g#q#w#}##�#
�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#####1#3#E#I#Q#[#y#�#�#�#�#�#�#�#�#�#�#�#�#�#�####
#####!###-#/#5#?#M#Q#i#k#{#}#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�#####
%#/#1#7#;#A#G#O#U#Y#e#k#s##�#�#�#�#�#�#�#�#�#�#�# #####'#+#-
#3#=#E#K#O#U#s#�#�#�#�#�#�#�#�#�#�#�#�# ###!###5#9#?
#A#K#S#]#c#i#q#u#{#}#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�###########
%#+#/#=#I#M#O#m#q#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�###
#####9#I#K#Q#g#u#{#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�## # # ' ) - 3 G M Q _ c e i w } �
� � � � � � � � � � � � !#!5!A!I!O!Y![!_!s!}!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!�!#"
"#"#"!"%"+"1"9"K"O"c"g"s"u""�"�"�"�"�"�"�"�"�"�"�"�"�"##
###'#)#/#3#5#E#Q#S#Y#c#k#�#�#�#�#�#�#�#�#�#�#�#�#�#�#�##$#$#$#$)
$=$A$C$M$_$g$k$y$}$$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$�$#%#%#%#%'%1%=%C%K%O%s%�%�%�%�
%�%�%�%�%�%�%�%�%�%�%�%#&#&#&#&'&)&5&;&?
&K&S&Y&e&i&o&{&�&�&�&�&�&�&�&�&�&�&�&�&�&�&#'#'5'7'M'S'U'_'k'm's'w''�'�'�'�'�'�'�'
�'�'�'�'�'#(#((#(#(#(!(1(=(?(I(Q([(]
(a(g(u(�(�(�(�(�(�(�(�(�(�(�(�(#)#)#)!)#)?)G)])e)i)o)u)�)�)�)�)�)�)�)�)�)�)�)�)�)�)
�)#*#*#*%*/*O*U*_*e*k*m*s*�*�*�*�*�*�*�*�*�*�*�*�*�*�*#+'+1+3+=+?+K+O+U+i+m+o+
{+�+�+�+�+�+�+�+�+�+�+�+�+�+ ,#,#,#,/,5,9,A,W,Y,i,w,�,�,�,�,�,�,�,�,�,�,�,�,�,�,�,
#-#-#-;-C-I-M-a-e-q-�-�-�-�-�-�-�-�-�-�-#.#.#..#.#.%.-.3.7.9.?.W.[.o.y.
.�.�.�.�.�.�.�.�.�.�.�.�.�.�.#/ /#/#/'/)/A/E/K/M/Q/W/o/u/}/�/�/�/�/�/�/�/�/�/�/
�/�/�/�/#00#0)070;0U0Y0[0g0q0y0}0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0�0#1 1#1!1'1-
191C1E1K1]1a1g1m1s11�1�1�1�1�1�1�1�1�1�1�1�1

2#2#2#2)252Y2]2c2k2o2u2w2{2�2�2�2�2�2�2�2�2�2�2�2�2�2�2�2#3%3+3/353A3G3[3_3g3k3s3y3
3�3�3�3�3�3�3�3�3�3�3�3#4#4#4#4#474E4U4W4c4i4m4�4�4�4�4�4�4�4�4�4�4�4�4�4 5#5#5-
535;5A5Q5e5o5q5w5{5}5�5�5�5�5�5�5�5�5�5�5�5�5�5�5#6#6#6#6165676;6M6O6S6Y6a6k6m6�6�6
�6�6�6�6�6�6�6�6�6#7#7#7#7?7E7I7O7]7a7u77�7�7�7�7�7�7�7�7�7�7#8#8!
83858A8G8K8S8W8_8e8o8q8}8�8�8�8�8�8�8�8�8�8�8�8�8�8#9#9#9%9)9/9=9A9M9[9k9y9}9�9�9�9
�9�9�9�9�9�9�9�9�9�9�9�9�9�9#:#:#:#:':+:1:K:Q:
[:c:g:m:y:�:�:�:�:�:�:�:�:�:�:�:#;#;#;!;#;-;9;E;S;Y;_;q;
{;�;�;�;�;�;�;�;�;�;�;�;�;�;�;�;�;�;#<
<#<#<#<)<5<C<O<S<[<e<k<q<�<�<�<�<�<�<�<�<�<�<�<�<#==#=#=#=!=-=3=7=?
=C=o=s=u=y={=�=�=�=�=�=�=�=�=�=�=�=�=#>
>#>#>#>#>)>/>3>A>W>c>e>w>�>�>�>�>�>�>�>�>�>�>�>�>�>�>�>#??7?;?=?A?Y?_?e?g?
y?}?�?�?�?�?�?�?�?�?�?�?�?#@!@%@+@1@?@C@E@]@a@g@m@�@�@�@�@�@�@�@�@�@�@�@�@
A#A#A#A!A3A5A;A?
AYAeAkAwA{A�A�A�A�A�A�A�A�A�A�A#B#B#B#B#B)B/BCBSBUB[BaBsB}B�B�B�B�B�B�B�B�B�B�B�B�B
�B#C#C#C%C'C3C7C9COCWCiC�C�C�C�C�C�C�C�C�C�C�C�C�C�C�C�C D#D#D#D)D;D?
DEDKDQDSDYDeDoD�D�D�D�D�D�D�D�D�D�D�D�D�D#E#E#E+E1EAEIESEUEaEwE}EE�E�E�E�E�E�EPBKD
F2PARAM#prf#keylength###PBE2PARAM###keyfunc#############�1�#�b##############p��#�b#
#########�1�#############�1�##########2�#############p1�#############���##_########
######���#�\##############�1�#�\##########
###|1�#�b##openssl\crypto\asn1\a_int.c#RAND part of OpenSSL 1.0.0f 4 Jan
2012##openssl\crypto\rand\md_rand.c#######You need to read the OpenSSL FAQ,
http://www.openssl.org/support/faq.html###....................########SRVR####CLNT#
###AECDH-AES256-SHA####AECDH-AES128-SHA####AECDH-DES-CBC3-SHA##AECDH-RC4-
SHA###AECDH-NULL-SHA##ECDHE-RSA-AES256-SHA####ECDHE-RSA-AES128-SHA####ECDHE-RSA-
DES-CBC3-SHA##ECDHE-RSA-RC4-SHA###ECDHE-RSA-NULL-SHA##ECDH-RSA-AES256-SHA#ECDH-RSA-
AES128-SHA#ECDH-RSA-DES-CBC3-SHA###ECDH-RSA-RC4-SHA####ECDH-RSA-NULL-SHA###ECDHE-
ECDSA-AES256-SHA##ECDHE-ECDSA-AES128-SHA##ECDHE-ECDSA-DES-CBC3-SHA####ECDHE-ECDSA-
RC4-SHA#ECDHE-ECDSA-NULL-SHA####ECDH-ECDSA-AES256-SHA###ECDH-ECDSA-AES128-
SHA###ECDH-ECDSA-DES-CBC3-SHA#ECDH-ECDSA-RC4-SHA##ECDH-ECDSA-NULL-SHA#PSK-AES256-
CBC-SHA##PSK-AES128-CBC-SHA##PSK-3DES-EDE-CBC-SHA####PSK-RC4-SHA#GOST2001-NULL-
GOST94####GOST94-NULL-GOST94##GOST2001-GOST89-GOST89##GOST94-GOST89-GOST89####ADH-
AES256-SHA##DHE-RSA-AES256-SHA##DHE-DSS-AES256-SHA##DH-RSA-AES256-SHA###DH-DSS-
AES256-SHA###AES256-SHA##ADH-AES128-SHA##DHE-RSA-AES128-SHA##DHE-DSS-AES128-
SHA##DH-RSA-AES128-SHA###DH-DSS-AES128-SHA###AES128-SHA##ADH-DES-CBC3-SHA####ADH-
DES-CBC-SHA#EXP-ADH-DES-CBC-SHA#ADH-RC4-MD5#EXP-ADH-RC4-MD5#EDH-RSA-DES-CBC3-
SHA####EDH-RSA-DES-CBC-SHA#EXP-EDH-RSA-DES-CBC-SHA#EDH-DSS-DES-CBC3-SHA####EDH-DSS-
DES-CBC-SHA#EXP-EDH-DSS-DES-CBC-SHA#DH-RSA-DES-CBC3-SHA#DH-RSA-DES-CBC-SHA##EXP-DH-
RSA-DES-CBC-SHA##DH-DSS-DES-CBC3-SHA#DH-DSS-DES-CBC-SHA##EXP-DH-DSS-DES-CBC-
SHA##DES-CBC3-SHA####DES-CBC-SHA#EXP-DES-CBC-SHA#EXP-RC2-CBC-MD5#RC4-SHA#RC4-
MD5#EXP-RC4-MD5#NULL-SHA####NULL-MD5####SSLv3 part of OpenSSL 1.0.0f 4 Jan
2012#openssl\ssl\s3_lib.c####TLSv1 part of OpenSSL 1.0.0f 4 Jan
2012#openssl\ssl\t1_lib.c####openssl\ssl\s23_lib.c###CCC#openssl\ssl\s3_enc.c####DE
S-CBC3-MD5####DES-CBC-MD5#RC2-CBC-MD5#####SSLv2 part of OpenSSL 1.0.0f 4 Jan
2012#####l8�#�#######################A#######�###�#######t8�#�#####################
##
#######(###�#######h9�#�#######################A#######�###�#######T8�#�###########
############
#######(###�#######\9�#@#######################!
#######8###8#######L9�#�#######################�#######�###�###openssl\ssl\s2_lib.c
####s->session->master_key_length >= 0 && s->session->master_key_length <
(int)sizeof(s->session->master_key)###error >= 0 && error <=
(int)sizeof(buf)#####�###�###########�z##��##�z##########@�###�##�#################
##@###d###########t###q###########�z##��##�z##########��##��##t###B###q###F#######@
###d#######EC part of OpenSSL 1.0.0f 4 Jan 2012####openssl\crypto\ec\ec_lib.c##
IPSec/IKE/Oakley curve #4 over a 185 bit binary field.
Not suitable for ECDSA.
Questionable extension field!########
IPSec/IKE/Oakley curve #3 over a 155 bit binary field.
Not suitable for ECDSA.
Questionable extension field!####WTLS curvs over a 224 bit prime field###WTLS
curve over a 160 bit prime field###WTLS curve over a 112 bit prime field###WTLS
curve over a 113 bit binary field##X9.62 curve over a 431 bit binary field#X9.62
curve over a 368 bit binary field#X9.62 curve over a 359 bit binary field#X9.62
curve over a 304 bit binary field#X9.62 curve over a 272 bit binary field#X9.62
curve over a 239 bit binary field#X9.62 curve over a 208 bit binary field#X9.62
curve over a 191 bit binary field#X9.62 curve over a 176 bit binary field#X9.62
curve over a 163 bit binary field#NIST/SECG curve over a 571 bit binary
field#NIST/SECG curve over a 409 bit binary field#NIST/SECG curve over a 283 bit
binary field#SECG curve over a 239 bit binary field##NIST/SECG/WTLS curve over a
233 bit binary field####SECG curve over a 193 bit binary field##NIST/SECG curve
over a 163 bit binary field#SECG curve over a 163 bit binary field##NIST/SECG/WTLS
curve over a 163 bit binary field####SECG curve over a 131 bit binary
field##SECG/WTLS curve over a 131 bit binary field#SECG curve over a 113 bit binary
field##X9.62/SECG curve over a 256 bit prime field#X9.62 curve over a 239 bit prime
field##X9.62 curve over a 192 bit prime field##NIST/X9.62/SECG curve over a 192 bit
prime field####NIST/SECG curve over a 521 bit prime field##NIST/SECG curve over a
384 bit prime field##SECG curve over a 256 bit prime field###NIST/SECG curve over a
224 bit prime field##SECG curve over a 224 bit prime field###SECG curve over a 192
bit prime field###SECG/WTLS curve over a 160 bit prime field##SECG curve over a 160
bit prime field###SECG curve over a 128 bit prime field###SECG curve over a 112 bit
prime field###SECG/WTLS curve over a 112 bit prime
field######�###############0E�o�B/d�W�(Ӂ ��!
�������������������������������������������������d!##圀�#��r$0I�����F��#��#�0��|�
�C��#�
�####+����xc##�k$��s�w�#yH#���������������6#kɱ��(1####�###############�q4G�����E���
���j������������������############�����������������������������#

#���A2VPD��9#'‫׿غ‬C#U���#
�k��2#��J#��V�#"42��#\#!
�7c���#�L"���Cu�Z#GdDՁ��#~4��������������#���>#�)E\\*=####�#######0#######�5�j�#�z#
#�jgs��zͬ������������������������������������
s ########������������������������������
����������########����1/��>�䘎#k��-###�n��A####�P#�Z�V9��.ѝ*�����*慎�"��#7���#�
�tn#;b����Y�A�T*8U#�]�U)l:T^8rv
�6#�J�&,o]������)��#�(�#|��1#���
`��#~��zC#|��#_�������������������������cM��7-�X#
�H��z��#j��)s####�#######B#######�#)#�S��g#92����d�#������������������������������
�����������������������������������#�����������������������������������������������
������������������#Q�>�a�#�#��!���@��r[��#󸴉��� �V#9Q�~�{#R�;��#5s4,=߈��E#�kP?
##ƅ�#�##�͞>�f#��B�d�9#?�!
�(�`kM=��K^w��Y(�#�'����3H��jB��~~1��f##9)jx�;�#\�_�,}#٘�DIW�Dh#��#'>f,��r�^�&@�P�#
?�#a5<p��r�@���v��fP#���������������������������������Q����/�k�#H�
��;�ɸ��G��o�#�8d �###############1�.�#��
�##>�##��#ƶ�������������������������������������������������"�߹\k%�cd��
9:�#h�S��IxB��wi����r
ɉ �ioH#Jet�#i�zg+ �*#=��}�p��#������������_��$‫܀‬A�H��1####�####
###########�ihD5޳xĶ\�Y#*Wc#�.������������������������������������������������"#=�9Z
#ʧB=���G`��b%k�i#})w�#�Z#�x7#X��+�J�"�#�8�#"cs73KIܶjm���vH�C�������������zb�1�?
B��@�#####�###############�;�`�
��uy���`�2#}�����������������#####����������������������#####�����k#l;��A��T�#
u�q��/�}#7ya�”,
#�<‫�ܨ‬l�3�d+��#��XW=?'�;<���}����
]�n@T�S#�FT�h#�"k9��{#���������������^��]�q��R&���#�###############�###

S#�;���+�˚�#�����������������#####����������������������#####�����a�h2Wl���
��$�?�X�K�#�z�L��/,8� ‫'ه‬pQ �!�^�&)j<���WW���0�[#%���#�
m��#ٰ�2��U�n�`#}���������������##ϧ�YCw�#�8!�X c�###############}st#��4q�
�v���uӿ�������������������#####����������������������#####�����%W#�*0fT���#֧P�
%##Ԙ�#‫ٺ‬#�m>gh��#����#\�����HS��`��T��P_�Z##扏 9
#�#U+�"o;o��n����#��l���������������
�  �] �A�#|<C!FReQ� #######
#######ĝ6#��#�jfx�#�&���~�����################����������������################�����
�������Z�5‫ت‬:���Uv���e##��S��;�<>'�`Kk#���,BG���c�@�w#}�-�3��9E–‫ ؘ‬O�B�#����J|
#�#+�3Wk1^�˶@h7�Q����####�����������#������c
%Q####�################�##�MinghuaQu)#rx?��|*�b�^f�v�� ��|*�b�^f�v�� �e��#9#�‫މ‬#p+"
Hr9�Z^�kU��𘨜寇$�>##�u#�|*�b�^v(߬eaŖ################'W�#MinghuaQuS#�^#��|
*�b�^f�v�� �a'�L#�
��\#�,Q��]��t��L�� K�
�蒴�d�В�C��F�.7G��n�n�6�
�‫�ظ‬Y|�# �K�#################MinghuaQu
�:Ds�6y�������������������������������uy�#y�=�$�<,�^�##�R���-
(`|�,[��Z�9[��#�-����z�����####u�
#�8�#####�################MinghuaQu#��41��;�����������������##�ѳ���Y̛��� ^ ���
)# ,eX
� m

�]{j��^W)���2����@'��j�M:�q#��_�KD?
�#$r##
������� �#### �################�������������������s###########################
################;L8,�z���#�v06���M~�#���51���k ‚�S#3��<O�###########��#߫��#��##�###
#############S��,#֖�v�V##S;��3E#�������������������
�# ������������������
 �## �� T�z�e�
��ԭ�e�E#J��h��s(Fdi�hË�#��##�(U1h�}Y��###Q7z��2###########���'���u"W######�########
#######������#�' �֖�v�V##Q#�������������������s#�������������������p#��4��Y 닫
W'I#fMZ�#��#Rܰ4):#~#O�#0�#�1D�m#�����1��q��,���?.###########5#熨
#�k######�###############�����������������������7##################################
##############�O�#�W�&�}#���4#�ѱ��l}�//m�V(��Ac�#��4@����^/�������������&��##iFjt��
################���������������������������m#######################################
####################�E[3M��0�(�i�g��pu�#~e#���\#~#����
 4B����� #���Y��K�Uma�########
#######����a���qv���##�#######
#######�������������������������������/############################################
####################y�f~�ܻ��U�b�·###���-
�(�Y�[#�#�H:�w&��e]���###��#�H��T#�GЏ�#Ը��������������������H�;��^��6AA�###########
#####��������������################################################################
####��U#�7�######�################������������������###############################
################################################################�Ɋ���WJ�3##�######
#########����������������############�����������������������������#

#���A2VPD��9#'‫׿غ‬C#U���#
�k��2#��J#��V�#"42��#\#!
�7c���#�L"���Cu�Z#GdDՁ��#~4��������������#���>#�)E\\*=�################�#�#֖�v�V##V�
���I�################0�%
���d��X
�#����&#D#����##�sao5�##�5b�##�(0'yX��1^�#�########���9�o##�################��#v#`�
���֖�v�V##]################h�#��~Z���U�#���){Կ6�Y#O#�zj{&�^�/͸#G�#���N�gL#敺�######
####x�$���##�###############MinghuaQu�[ӭ��!�:��#################�# �kV!DA���
%p�##�V#�Kc���)#x��A#���#3ߘ�#�##Cc��#�n~��##s�#K#N��P#########1#�:�d�M######�#####
##########�[ӭ��֖�v�V##Z!�:��#################娉#���A_#�#es�#�&jF�VW�sL�#�!
�#V����P1�e-
#�#�f�#H�m�y@�6m�&]��$##########iT�3#���######�###################################�
###########################################�#�S{�#��#‫�ד‬Nm^\���#�##�]8�X2#.�#6�8�‫ڣ‬
�#############���
���##�###################################�#��,��O�T��(���F�x*�##a-�ܴ
��k�)ʑ�:�X��#i����C�w�Vg�Vxzxv�T#C^�B‫��ﯲ‬Q����

��#�#����������H���œ�#'�##�###################################�####################
##
`##��S�#��#Q/xtJ2#�#��b���~��#hԙF7�4>6#�#�lq� O���E�#\
ys$�###########��w�
#�#L3##�################?
��MinghuaQuwű��0#######################�###���z��Qi�q�{@�� �ȩ#�{##��I��è����z#[�|
����1G�##�_#�Jt�l�o��aybSr����#%��7#���:#���
��
#j��###############��Jw�D:̒
# I######
� ################
� �֖�v�V##Q7ȡo��"###############

#########�##c�ZQ7��>��g###�>�i�w#p�#ɻ��'��L7~*��j[#���#C#�#‫}ٶ‬#.#g�#�#~��#�Q5
�a~�#Δ3V#�#�)�����#��'"L��l#############Z�V##T#����######�#########################
#################################################################################r2
��:~s#�)�/�#�c�#�k�
L�n�a&#�S}��#��#UZg�'�͛��
V ��
#V ��# ##############
� [
� # n #
� �� s ��
� �� #### ###############t
� ՟
�kA=#�K4K
��#�P�#############################################################fd~�l3,�
#�X!;3; ��B��#_}���#���ˬ�#�!
9�u_�e�9#�6���sq�U�##j#�##5#x�(���#��g��6qo~#�#R################�t�/�i"##&#��‫ח‬#####
##########�#########@##############################################################
#################)�������s ���'���&�L��{*eU#05�v1##�.T��###0��5#��u�1*]ƷeS��
##############Zy��|
��###�#�x�####�#######$##########################################�#################
#########################################################!?x�D�?
#;�b��S�&_#�Vz#�i#�¬$XI(6#��8##�1���]#�Bo�~E��#F��Yb6N4#aw�"Y#������������������.�u
w&]���
 E####<a�#######$#######w�sp�#ն*mն-
��#���###################################�#####################################{h
ȸYm����#�0?ʗ�vE0����HZ�&>1;y��#�9%��‫�ݐ‬O�p���.�%�U~������;͆�S#ghT $##� # Qo
���Բ � #5#

‫�ݰ‬gy�#��E��#�#������������������9�`�#[#*|#######�#####‫ﭳ‬
4################################################�#################################
##################################################################################`
�_e�I�:��#q�!#� ��#�L'�ϸ��|��`#����b�".��U@��#7F#�i##|
NB��#��#)�4`x/���'�2Qe��#��_lB��R#���zXc�H��(k#�������������������������_����
@#�U}^����[K\���#_ϗ#######4#######@���W�֟y!= LK�MBb!
##########################################�########################################
#######################!�����\K�u;{Gk�B.���gGa�֬'ȩ���r�/l�zU�OP�1{#T_#]H`Ј‫ݳ‬Ik
`dub`D#�J�w#M�#�[4�#�
%Z��#�QV#��`yNT�y��#a�ϫk��+���$�#jv6�ŧ�#�#X�OT�Џ8QO#�KO@�##6��d�#s�################
############�֦#�3#�_�|
<�#/��d�7٢#s####�#######H##########################################################
####################
%##################################################################################
###############################################################n��Y�?��#�1�#?䬜��##
��`$�H#�#�Cp����#�G�0M�ΰ��Ѻ9IGv�G#Mʈ��R��#�r#I‫܀‬O�7OJ��;ʕ1MՌ�0zT��#�#m�,�Iy�D��O���
�r�ܶ ��#{��#2#0�Y#��#�L#>�ǣ######################################P��c 䳑�
‫ۑ‬A8�0�K��98#�޴\�w�c|
##�#######H#######*�X�:#3�Hk#a##�:################################################
##########################
%#########################################################################�#~"!
��)q#���/\j��ˌ���k��J�#�������Y3+�gV�n)J�#Zx�#�R#M�9��
��)Urz####4�V)l#��<�u
��ҕ_�
��#��{*���9P��ғ��#�[g�#��`#�#�9J����P�'��v���-##{�sB�c�m���=i‫׌‬l'�#���#��S9!覄
B>C���Wb���F#���S#/#��#��Qn#�<#H'�#��[#������������������������������������a�#�U�s#
#�#h#�#�‫�ݜ‬##�=Qt�n���/�NG####�###############���#v#`����֖�v�V##T##################
####%F�CR4�"�x�u�2Ȕ5�RB#�Q}#�$<�8�K ��Mo���#�i��F#=y2��=t�#3��#�#�#!#Yf��#?
���XH��ʟ###########�#Ȃ#�M���######�###############S�L#D֖�v�V##X
���#######################��wı#�‫�ف‬#�##|Q#�r#g��8�NH�@t3��O#�#8� #$&nN�#m
�M�Ć#&qۛl�#�hM�f���
%�8�###��џ�#�����������M�##۷�#�######�###############P���\�MinghuaQu�j6��#########
#############�&�=>%�V�#i�TG�*�V�##�##���8�o#�[H��HT%+#��{|WM#�ϊ"�RGu�5�#�޽Y
#^#�H�?�q��=�#�#����������#�###
��# ######�###########n�##########################���)�#\@}�9�Ж{�pK���##]�G
�d#3�‫����(�ގ‬
��#�#†g��#���`�)��JW�#o�S�-��ֺ�#}a�6��+�jV,####�Ss���#W��+
#�#�&�######�###############N#�T'D֖�v�V##U/'����#######################(fS{ggRcjh�eT
�&@'kd��Rbg.E�W##xog�##����Tb��
���6���2#���7�6�#‫��ײ‬J�
v[�43��^3)2�#�E�$#�#�#�@############�#�Ðgȓ���####�################q�/�$֖�v�V##X���\#
�#######################@#(wMwwǷfm#f�C q'O��#�## #�(��#�$��#+|�ї#�b�j#8
���#(�Z��j���(x�����##CC�bm#���#`�!:>#�z�C}f�
###########PP���e($�k�s####�###############�SQ-
Ƅ֖�v�V##Pg�xm#�#######################l##GV
 q�#�&τy� Y�c��#2�?#�7]L�O�CD�‫އ‬F�#�#P
�""#V�#w�~w�w�����
�n8�&�TZ9#a�W]�Y�6nj�L�|�#{#�#UUUUUUUUUUUa
##h#��(�>�####�###########H�#######################################################
##�a��Zb�!.#`4�+�D9��*?�c��#�����ߕY��z��xUN'��#ѥz##U�##玚 Ê#_�
‫ذ‬#�����#a}�####��\�#�{l!�.�-^Ո��q~!/�######�###############�K�MinghuaQu�q�
��]�#############################2##W#|T1#:F�#�gV�CB>�'�ux#Wx�vy##����#��9/0�2|
��#�"��#W�p��.|
���[pn����V�k~|�#�R�#a��Pw�?���k&��i��tN��qd�ǩac#
###############MB��I*I����f�G�###############*��/֖ߤ�v�V##]&g''}�###################
##########B0#wW�g��#�V�tc%�S#�#f&dy�VT�_P7�eA���͂��J/ .?

�wR��Er/#�ͷK(��N�#i��G��4�vҹ#���1�p�
L�#Vg3LE��;���^,q��bV}TS��n"~�3#UUUUUUUUUUUUUU<o(�%�1���#F$R-�###########
###�#oMinghuaQu�#��w�
A�###############################�tfjgvmfv�x�v�i�#ff�fm�f�j�j�#w��jCQ���Q#~Շ�#��A��
A#�#@p���M(�N��<�S#��#�}B�F�9�#�N��.Z#�n^##�#M�\#�Y�V#�87�#�#y�a
ߐ>�#L��############�######################################����;_�J
I# ��
�������������̬
���N�"#�(q-B�u+,@ M�͵�� #qg��+���|���4�*�Up#��:o�#?��̄��
@ #a#
� , ��
�� # #l
� �
�b-w#���#�#�#�q‫ݍ‬##�iW#�#�k��.aB��A�0�^��ʰ^##]‫ޝ‬#####��#T��H��n1�r�###�E�{��#{�#b�!
######�#######'###.�##########################################�i1I�#�Q��� �7~_�-
#Q#D##t�(�x6Z#���#�ۗ�U�
��C�#y��‫ڦ‬x�#�yN��qf��@9`#U�s@�##{#�^���j�#_<,��z>����\�&��(ZdOt
&##៾�n�qQ~�@#P(��##2�Rz�Aj#^�&#T��#��;####�VW*���##�VW*���##-\��#?
��a�h�#DC########�#######-###L###+5I �$֖�v�V##X[�3-
ƀ############################################VggjeK uO5n� #�FV|
FgUV�V�F#�g�#��VV�T�#�fV�W$r��#|I6?#���#]R��}#]��E�]9�4V&#��t+c)�#�##�<
%��#wg�����y��8A6j#.#:���$#ߜk�‫��ޘ‬#�z"9���S��)TpH##���y#�#�9H�O�{�N�#e�xh�W�-
�#0Z@q#�#�(k�#򆼡�(k�#򆼡�(k��k��V�,
��O�q�t�u�;######�#######/###p�######################################
###########���% R#����"�#%ny��U���[�Gx�v�/
�Q��*#�j�#�##�2
�E,v
X��0��#�<4E87�N�
�I#��#-��d�D��G�#j##��uS�����Uz�#��� ‚VFųJ9L���k"���'�!o#��#j_#{>��ܺb�
‫ز‬#�RW��s�,Y#�b:E�8C���|хZ‫ڨ‬#*#P�#�######�Q-��r��I‫�]ي‬ǰS.�Q�#��#;z�y���

�@��1���[�g######�#######6###`'##�#################################################
#####�~���##L�#lj]��9[#lĭ,�*
����� ��#Еlo��aTh�#M�͏‫��ٴ‬#}
# �#CY��#T��L 놂 7���
‫*ژ‬g�Z��bmNP��s##z�b8#��#�&###�]<g���a�� &"��p#��#GXqN����X�!����e6#l)���G���
� �#�o�_��Ut]<E#0,�F
‫���ٷ‬#kY#>�j�˰�L/�z}ᨛb]jY�7`##@4#@4#@4#@4#@4#@4#@4#@4#@4##�#�#�p;^ƍ5���
##�I�J�####�#############################################################fyy�#�����
px###�KJ���c##x\��##��������m�s######�###########################@#################
############################3�###################{###################�#�����������
Lj#І��l�##############################
#######################################################�###########################
#####################�������������|D۟$
��^�###XM�#�C�#�###�M�#�C�#�###HN�#xC�#�###�N�#xC�#�###XO�#PC�#�###�O�#PC�#�###�P�#
$C�#�###8Q�#�B�#�###�Q�#�B�#�###�D�#�B�#�###�R�#�B�#�###�E�#TB�#�###�F�#(B�#�###�C�
#�A�#�###xH�#�A�#�###0I�#�A�#�###�I�#�A�#�###�J�#�A�#�###�K�#�A�#�###pL�#xA�#�###
U�#PA�#�###�U�#PA�#�###
V�#$A�#�###�V�#�@�#�###@W�#�@�#�###�W�#�@�#�###`X�#t@�#�###�X�#L@�#�###�Y�#L@�#�###
pZ�##@�#�###8[�##@�#�####\�#�?�#�###�\�#�?�#�###�]�#�?�#�###�^�#�?�#�####`�#�?
�#�###ha�#l?�#�###(c�#l?�#�####e�#D?�#�###�e�#D?�#�###Pf�#D?�#�###�f�##?
�#�###�g�#�>�#�###Ph�#�>�#�####i�#�>�#�###�i�#�>�#�###xj�#�>�#�###Pk�#�>�#�###(l�#�
>�#�####m�#|>�#�###�m�#T>�#�###�n�#,>�#�###
p�##>�#�###Pq�#�=�#�###�r�#�=�#�###@W�#�@�#�### U�#PA�#�####e�#D?
�#�###XM�#�C�#�###�P�#$C�#�###hS�#�=�#�###�S�#d=�#�###pZ�##@�#�###8[�##@�#�###hT�#<
=�#�####s�#�<�#�###�s�#P<�#openssl\crypto\ec\ec_curve.c####openssl\crypto\engine\en
g_pkey.c####�###################�##@�######�####K##�J##########�###################
�###�######�####K##�J##########�###################�##��######�####K##�J##########�
###################�##p�######�####K##�J##########�###################�##@�######�#
###K##�J##########�###################�###�######�####K##�J##########�#############
######�##��######�####K##�J##########�###################�##p�######�####K##�J#####
#####�####### ###########�##@�######�####K##�J##########�#######
###########�###�######�####K##�J##########�#######
###########�##��######�####K##�J##########�#######
###########�##p�######�####K##�J##########�###################�##��######�####K##�J
##########�###################�##��######�####K##�J##########�#######
###########�##��######�####K##�J##########�###################�##`�######�####K##�J
##########�###################�##`�######�####K##�J##########�#######
###########�##`�######�####K##�J##########openssl\crypto\evp\e_aes.c##openssl\ssl\s
2_pkt.c####mac_size <= MAX_MAC_SIZE####c->iv_len <= (int)sizeof(s->session-
>key_arg)###s->s2->key_material_length <= sizeof s->s2-
>key_material####openssl\ssl\s2_enc.c####X.509 part of OpenSSL 1.0.0f 4 Jan
2012#openssl\crypto\x509\x509_vfy.c##OPENSSL_ALLOW_PROXY_CERTS###ASN1_TIME########�
##################�|
�#openssl\crypto\asn1\a_time.c####openssl\crypto\asn1\a_enum.c####openssl\crypto\as
n1\a_verify.c##openssl\crypto\pkcs12\p12_add.c#openssl\crypto\pkcs12\p12_mutl.c####
openssl\crypto\asn1\a_d2i_fp.c##openssl\crypto\asn1\asn_pack.c##openssl\crypto\obje
cts\obj_lib.c####NETSCAPE_SPKI###sig_algor###spkac###NETSCAPE_SPKAC##challenge#####
##########�#�#�`##############�}�#�^##########�}�#############�}�#############�}�#
?##############�}�#�b##############���#�]##########<~�#########
###�}�#SHA1 part of OpenSSL 1.0.0f 4 Jan 2012######SHA-256 part of OpenSSL 1.0.0f 4
Jan 2012#######�/�B�D7q����۵�[�V9�#�Y��?��^#���#�#[�#��1$�}
Ut]�r��‫ܛ‬#�‫ހ‬t���i��G��Ɲ�#̡
$o,�-��tJ‫�ܩ�\ڈ‬vRQ>�m�1��'#��Y��#��G���Qc�#g))#�
�'8!#.�m,M#8STs
e�
jv.��,r��迢 Kf#�p�K£Ql�#��$#�օ5#�p�j##�##l7#LwH'���4�
#9J��NOʜ[�o.htoc�x#xȄ##nj����lP����xq�SHA-512 part of OpenSSL 1.0.0f 4 Jan
2012#######"�(‫ט‬/�B�e�#�D7q/;M�����8�۵��‫�ۉ‬H�[�V9#�#��#�Y�O#���?�#�m��^#�B##���#
‫ؾ‬opE#[�#���N��1$���}
Uo�{�t]�r��#;��‫ܛ‬#�%�#5‫&�ހ‬i�t���J��i���%O8�G��Ռ�Ɲ�#e��w̡
$u#+Yo,�-��n��tJ��A�‫�\�ܩ‬S#�‫�ڈ‬v��f�RQ>�#2�-m�1�?!��'#��#��Y��=�#��%�
�G���o�#�Qc�#pn#
g))#�/�F�
�'&�&\8!#.�*�Z�m,M߳��#8S�c��Ts
e��w<�
jv��G.�;5�#�,r�d#�L�迢#0B�Kf#�����p�K�0�T#�Ql�#R��#��#�eU$#��*
qW�5#�ѻ2p�j#��Ҹ#�#S�AQ#l7#���LwH'�H�ᵼ�4cZ�ų
#9ˊA�J��Ns�cwOʜ[�����o.h��]t`/#Coc�xr��#xȄ�9d###nj(#c#���齂�
�lP�#yƲ��+Sr��xqƜa&��>'�#��!Ǹ��#����}��x�n�O}�o#r�g�#���Ȣ�}c
��#�?##G##5#q#�}##�w�(�$�@{��2���#
��<L#��g#C�B>˾��L*~e�)Y���:�o�_#XGJ�#Dl%s%04x - <SPACES/NULS>
# #%04x - #BMPSTRING###<ASN1
29>###UNIVERSALSTRING#GENERALSTRING###VISIBLESTRING###GRAPHICSTRING###GENERALIZEDTI
ME#UTCTIME#IA5STRING###VIDEOTEXSTRING##T61STRING###PRINTABLESTRING#NUMERICSTRING###
SET#<ASN1 15>###<ASN1 14>###<ASN1 13>###UTF8STRING##<ASN1
11>###ENUMERATED##REAL####OBJECT DESCRIPTOR###OCTET STRING####BIT
STRING##INTEGER#BOOLEAN#EOC#####%-
18s####��##��##��#��#��#P��#XS�#Ѓ�#�и#ȃ�#���#���#���#���#���#���#PH�#|
��#l��#\��#P��#@��#4��#,��##��#
��#��#��#‫�܂‬#Ђ�#Ă�#<ASN1 %d>###appl [ %d ]#cont [ %d ]#priv [ %d ] ####prim: ##cons:
##length is greater than %ld
#Error in encoding
##BAD ENUMERATED##BAD INTEGER#[HEX DUMP]:#Bad boolean
####:BAD OBJECT#d=%-2d hl=%ld l=inf ###d=%-2d hl=%ld l=%4ld ###
%5ld:###0123456789ABCDEF####openssl\crypto\x509v3\v3_utl.c##FALSE###TRUE####openssl
\crypto\x509\x509name.c##'()+,-./:=?#maxsize=####minsize=####
%ld#openssl\crypto\asn1\a_mbstr.c###(undef)#####################��'#��#############
#############openssl\crypto\bn\bn_rand.c#openssl\crypto\bn\bn_mont.c#openssl\crypto
\bn\bn_exp.c##unknown control command#result too small####result too large####no
result buffer####index too small#index too large#common ok and cancel
characters#UI_set_result###UI_new_method###UI_get0_result##UI_dup_verify_string####
UI_dup_input_string#UI_dup_input_boolean####UI_dup_info_string##UI_dup_error_string
#UI_ctrl#GENERAL_ALLOCATE_STRING#GENERAL_ALLOCATE_PROMPT#GENERAL_ALLOCATE_BOOLEAN##
##unsupported requestorname type##unknown nid#unknown message digest##status too
old##status not yet valid####status expired##signer certificate not
found####signature failure###server write error##server response parse error#server
response error###server read error###root ca not trusted#response contains no
revocation data####request not signed##private key does not match certificate##no
revoked time#no response data####no public key###no content##no certificates in
chain####not basic response##nextupdate before thisupdate####missing ocspsigning
usage###error parsing url###error in thisupdate field###error in nextupdate
field###digest err##certificate verify error####bad
data####REQUEST_VERIFY##PARSE_HTTP_LINE1####OCSP_sendreq_nbio###OCSP_sendreq_bio###
#OCSP_response_get1_basic####OCSP_request_verify#OCSP_request_sign###OCSP_parse_url
##OCSP_MATCH_ISSUERID#OCSP_check_validity#OCSP_CHECK_ISSUER###OCSP_CHECK_IDS##OCSP_
CHECK_DELEGATED####OCSP_cert_id_new####OCSP_basic_verify###OCSP_basic_sign#OCSP_bas
ic_add1_status##D2I_OCSP_NONCE##ASN1_STRING_encode##version
incompatibility#unimplemented public key method#unimplemented
digest####unimplemented cipher####rsa not implemented#provide parameters##no unload
function##no such engine##no reference####no load function####no index####no
control function#not loaded##not initialised#invalid string##invalid init
value##invalid cmd number##invalid cmd name####internal list error#init failed#'id'
or 'name' missing##could not obtain hardware handle####finish failed###failed
loading public key###failed loading private key##engine section error####engine is
not in the list###engine configuration error##engines section error###dso not
found###DSO failure#dsa not implemented#dh not implemented##ctrl command not
implemented####conflicting engine id###command takes no input##command takes
input#cmd not executable##argument is not a number####already
loaded##LOG_MESSAGE#INT_ENGINE_MODULE_INIT##INT_ENGINE_CONFIGURE####INT_CTRL_HELPER
#ENGINE_up_ref###ENGINE_UNLOCKED_FINISH##ENGINE_UNLOAD_KEY###ENGINE_TABLE_REGISTER#
##ENGINE_set_name#ENGINE_set_id###ENGINE_SET_DEFAULT_TYPE#ENGINE_set_default_string
###ENGINE_remove###ENGINE_new##ENGINE_load_ssl_client_cert#ENGINE_load_public_key##
ENGINE_load_private_key#ENGINE_LIST_REMOVE##ENGINE_LIST_ADD#ENGINE_init#ENGINE_get_
prev#ENGINE_get_pkey_meth####ENGINE_get_pkey_asn1_meth###ENGINE_get_next#ENGINE_get
_digest###ENGINE_GET_DEFAULT_TYPE#ENGINE_get_cipher###ENGINE_FREE_UTIL####ENGINE_fi
nish###ENGINE_ctrl_cmd_string##ENGINE_ctrl_cmd#ENGINE_ctrl#ENGINE_cmd_is_executable
####ENGINE_by_id####ENGINE_add##DYNAMIC_SET_DATA_CTX####DYNAMIC_LOAD####DYNAMIC_GET
_DATA_CTX####DYNAMIC_CTRL####wrong content type##unsupported version#unsupported md
algorithm####unacceptable policy#ts datasign#tst info setup error####tsa
untrusted###tsa name mismatch###token present###token not present###time syscall
error##there must be one signer####response setup error####policy mismatch#pkcs7 to
ts tst info failed#pkcs7 add signed attr error#pkcs7 add signature error###no time
stamp token#nonce not returned##nonce mismatch##message imprint mismatch####invalid
signer certificate purpose##invalid null pointer####ess signing certificate
error###ess add signing cert error##detached content####d2i ts resp int
failed##could not set time##could not set engine####bad type####bad pkcs7
type##TS_VERIFY_CTX_new###TS_VERIFY_CERT##TS_VERIFY###TS_TST_INFO_set_tsa#TS_TST_IN
FO_set_time####TS_TST_INFO_set_serial##TS_TST_INFO_set_policy_id###TS_TST_INFO_set_
nonce###TS_TST_INFO_set_msg_imprint#TS_TST_INFO_set_accuracy####TS_RESP_verify_toke
n####TS_RESP_verify_signature####TS_RESP_SIGN####TS_RESP_set_tst_info####TS_RESP_se
t_status_info#TS_RESP_SET_GENTIME_WITH_PRECISION##TS_RESP_GET_POLICY##TS_RESP_CTX_s
et_status_info#TS_RESP_CTX_set_signer_cert#TS_RESP_CTX_set_def_policy##TS_RESP_CTX_
set_certs###TS_RESP_CTX_set_accuracy####TS_RESP_CTX_new#TS_RESP_CTX_add_policy##TS_
RESP_CTX_add_md##TS_RESP_CTX_add_failure_info####TS_RESP_CREATE_TST_INFO#TS_RESP_cr
eate_response#TS_REQ_set_policy_id####TS_REQ_set_nonce####TS_REQ_set_msg_imprint##T
S_MSG_IMPRINT_set_algo#TS_GET_STATUS_TEXT##TS_CONF_set_default_engine##TS_COMPUTE_I
MPRINT##TS_CHECK_STATUS_INFO####TS_CHECK_SIGNING_CERTS##TS_CHECK_POLICY#TS_CHECK_NO
NCES#TS_CHECK_IMPRINTS###TS_ACCURACY_set_seconds#TS_ACCURACY_set_millis##TS_ACCURAC
Y_set_micros##PKCS7_to_TS_TST_INFO####INT_TS_RESP_VERIFY_TOKEN####ESS_SIGNING_CERT_
NEW_INIT###ESS_CERT_ID_NEW_INIT####ESS_ADD_SIGNING_CERT####DEF_TIME_CB#DEF_SERIAL_C
B###d2i_TS_RESP#functionality not supported#could not unload the shared
library#could not bind to the requested symbol name#the meth_data stack is
corrupt##set filename failed#a null shared library handle was used###no file
specification###no filename#name translation failed#could not load the shared
library###incorrect file syntax###cleanup method function failed##filename too
big####failure#empty file structure####dso already loaded##control command
failed##WIN32_UNLOAD####WIN32_SPLITTER##WIN32_PATHBYADDR####WIN32_NAME_CONVERTER###
#WIN32_MERGER####WIN32_LOAD##WIN32_JOINER####WIN32_GLOBALLOOKUP_FUNC#WIN32_GLOBALLO
OKUP##WIN32_BIND_VAR##WIN32_BIND_FUNC#VMS_UNLOAD##VMS_MERGER##VMS_LOAD####VMS_BIND_
SYM####PATHBYADDR##GLOBAL_LOOKUP_FUNC##DSO_up_ref##DSO_set_name_converter##DSO_set_
filename####DSO_pathbyaddr##DSO_new_method##DSO_merge###DSO_load####DSO_global_look
up###DSO_get_loaded_filename#DSO_get_filename####DSO_free####DSO_ctrl####DSO_conver
t_filename####DSO_bind_var####DSO_bind_func###DL_UNLOAD###DL_NAME_CONVERTER###DL_ME
RGER###DL_LOAD#DL_BIND_VAR#DL_BIND_FUNC####DLFCN_UNLOAD####DLFCN_NAME_CONVERTER####
DLFCN_MERGER####DLFCN_LOAD##DLFCN_BIND_VAR##DLFCN_BIND_FUNC#BEOS_UNLOAD#BEOS_NAME_C
ONVERTER#BEOS_LOAD###BEOS_BIND_VAR###BEOS_BIND_FUNC##PRNG not
seeded#SSLEAY_RAND_BYTES###RAND_get_rand_method####unsupported pkcs12 mode#unknown
digest algorithm####pkcs12 pbe crypt error##pkcs12 cipherfinal error####pkcs12
algor cipherinit error###parse error#mac verify failure##mac verify error####mac
string set error####mac setup error#mac generation error####mac absent##key gen
error###iv gen error####invalid null pkcs12 pointer#invalid null argument###error
setting encrypted data type###encrypt error###encode error####decode
error####content type not data###cant pack
structure#PKCS8_encrypt###PKCS8_add_keyusage##PKCS12_verify_mac###PKCS12_unpack_p7d
ata####PKCS12_unpack_authsafes#PKCS12_set_mac##PKCS12_setup_mac####PKCS12_PBE_keyiv
gen#PKCS12_pbe_crypt####PKCS12_parse####PKCS12_pack_p7encdata###PKCS12_pack_p7data#
#PKCS12_newpass##PKCS12_MAKE_SHKEYBAG####PKCS12_MAKE_KEYBAG##PKCS12_key_gen_uni##PK
CS12_key_gen_asc##PKCS12_item_pack_safebag####PKCS12_item_i2d_encrypt#PKCS12_item_d
ecrypt_d2i#PKCS12_init#PKCS12_gen_mac##PKCS12_create###PKCS12_add_localkeyid###PKCS
12_add_friendlyname_uni#PKCS12_add_friendlyname_asc#PKCS12_ADD_FRIENDLYNAME#PARSE_B
AGS##PARSE_BAG###user too long###unsupported type####unsupported option##unknown
option##unknown extension name##unknown extension###unknown bit string
argument#unable to get issuer keyid##unable to get issuer details####section not
found###policy when proxy language requires no policy###policy syntax not currently
supported###policy path length already defined##policy path length##policy language
already defined#othername error#operation not defined###odd number of digits####no
subject details##no proxy cert policy language defined###no policy identifier####no
issuer details###no issuer certificate###no config database##need organization and
numbers###missing value###issuer decode error#invalid syntax##invalid
section#invalid safi####invalid purpose#invalid proxy policy setting####invalid
policy identifier###invalid option##invalid object identifier###invalid
numbers#invalid number##invalid null value##invalid null name###invalid
name####invalid ipaddress###invalid inheritance#invalid extension string####invalid
boolean string##invalid asrange#invalid asnumber####invalid multiple
rdns###incorrect policy syntax tag#illegal hex digit###illegal empty
extension#extension value error###extension setting not supported#extension not
found#extension name error####extension exists####expected a section name#error in
extension##error creating extension####error converting zone###duplicate zone
id###distpoint already set###dirname error###bn to asn1 integer error####bn dec2bn
error#bad object##bad ip
address##X509_PURPOSE_set####X509_PURPOSE_add####X509V3_parse_list###X509V3_get_val
ue_bool###X509V3_get_string###X509V3_get_section##X509V3_EXT_nconf####X509V3_EXT_i2
d##X509V3_EXT_conf#X509V3_EXT_add_alias####X509V3_EXT_add##X509V3_add_value####X509
V3_add1_i2d#V3_GENERIC_EXTENSION####V3_ADDR_VALIDATE_PATH_INTERNAL##V2I_SUBJECT_ALT
#V2I_POLICY_MAPPINGS#V2I_POLICY_CONSTRAINTS##V2I_NAME_CONSTRAINTS####V2I_ISSUER_ALT
##V2I_IPADDRBLOCKS####V2I_IDP#v2i_GENERAL_NAME_ex#v2i_GENERAL_NAMES###V2I_EXTENDED_
KEY_USAGE##V2I_CRLD####V2I_BASIC_CONSTRAINTS###V2I_AUTHORITY_KEYID#V2I_AUTHORITY_IN
FO_ACCESS###v2i_ASN1_BIT_STRING#V2I_ASIDENTIFIERS###SXNET_get_id_ulong##SXNET_get_i
d_asc####SXNET_add_id_ulong##SXNET_add_id_INTEGER####SXNET_add_id_asc####string_to_
hex###SET_DIST_POINT_NAME#S2I_SKEY_ID#S2I_ASN1_SKEY_ID####s2i_ASN1_OC
TET_STRING###s2i_ASN1_INTEGER####S2I_ASN1_IA5STRING##R2I_PCI#R2I_CERTPOL#PROCESS_PC
I_VALUE###POLICY_SECTION##NREF_NOS####NOTICE_SECTION##I2V_AUTHORITY_INFO_ACCESS###i
2s_ASN1_INTEGER####I2S_ASN1_IA5STRING##i2s_ASN1_ENUMERATED#hex_to_string###GNAMES_F
ROM_SECTNAME####DO_I2V_NAME_CONSTRAINTS#DO_EXT_NCONF####DO_EXT_I2D##DO_EXT_CONF#DO_
DIRNAME##COPY_ISSUER#COPY_EMAIL##ASIDENTIFIERCHOICE_IS_CANONICAL#ASIDENTIFIERCHOICE
_CANONIZE#A2I_GENERAL_NAME####wrong pkcs7 type####unsupported content
type####unsupported cipher type#unknown operation###unknown digest type#unable to
find message digest###unable to find mem bio##unable to find certificate##smime
text error####sig invalid mime type###signing not supported for this key
type#signing ctrl failure####pkcs7 sig parse error###pkcs7 parse error###pkcs7
datasign##pkcs7 datafinal error###pkcs7 datafinal#pkcs7 add signer error##operation
not supported on this type####no sig content type#no signers##no signatures on
data###no recipient matches key####no recipient matches certificate####no multipart
boundary###no multipart body failure###no matching digest type found###no default
digest###no content type#missing ceripend info###mime sig parse error####mime parse
error####mime no content type####invalid mime type###error setting cipher####error
adding recipient##encryption not supported for this key type##encryption ctrl
failure#digest failure##decrypt error###decrypted key is wrong length###ctrl
error##content and data present####cipher not initialized##cipher has no object
identifier#SMIME_text##SMIME_read_PKCS7####PKCS7_verify####PKCS7_simple_smimecap###
PKCS7_sign_add_signer###PKCS7_SIGNER_INFO_sign##PKCS7_SIGNER_INFO_set###PKCS7_signa
tureVerify###PKCS7_sign##PKCS7_set_type##PKCS7_set_digest####PKCS7_set_content###PK
CS7_set_cipher####PKCS7_RECIP_INFO_set####PKCS7_get0_signers##PKCS7_FIND_DIGEST###P
KCS7_final#PKCS7_encrypt###PKCS7_ENCODE_RINFO##PKCS7_DECRYPT_RINFO#PKCS7_decrypt###
PKCS7_dataVerify####PKCS7_DATASIGN##PKCS7_dataInit##PKCS7_dataFinal#PKCS7_dataDecod
e####PKCS7_ctrl##PKCS7_COPY_EXISTING_DIGEST##PKCS7_BIO_ADD_DIGEST####PKCS7_add_sign
er####PKCS7_add_signature#PKCS7_add_recipient_info####PKCS7_add_crl###PKCS7_add_cer
tificate###PKCS7_add_attrib_smimecap###PKCS7_add0_attrib_signing_time##i2d_PKCS7_bi
o_stream####DO_PKCS7_SIGNED_ATTRIB##B64_WRITE_PKCS7#B64_READ_PKCS7##write to read
only BIO##unsupported method##unable to listen socket#unable to create
socket#unable to bind socket###tag mismatch####null parameter##no such file####no
port specified###no port defined#no hostname specified###no accept port
specified####nbio connect error##keepalive###in use##invalid ip
address##gethostbyname addr is not af inet###error setting nbio on accept
socket#error setting nbio on accepted socket###error setting nbio##EOF on memory
BIO###connect error###bad hostname lookup#bad fopen mode##accept
error####WSASTARTUP##SSL_new#MEM_WRITE###MEM_READ####LINEBUFFER_CTRL#FILE_READ###FI
LE_CTRL###CONN_STATE##CONN_CTRL###BUFFER_CTRL#BIO_sock_init###BIO_read####BIO_puts#
###BIO_nwrite0#BIO_nwrite##BIO_nread0##BIO_nread###BIO_new_mem_buf#BIO_new_file####
BIO_new#BIO_MAKE_PAIR###BIO_get_port####BIO_get_host_ip#BIO_get_accept_socket###BIO
_gets####BIO_gethostbyname###BIO_ctrl####BIO_callback_ctrl###BIO_BER_GET_HEADER##BI
O_accept##ACPT_STATE##point arithmetic failure####no private value####KDF
failed##ECDH_DATA_new_method####ECDH_compute_key####signature malloc failed#random
number generation failed#need new setup values###missing parameters##err ec
lib##data too large for key size#bad
signature###ECDSA_sign_setup####ECDSA_do_verify#ECDSA_do_sign###ECDSA_DATA_NEW_METH
OD###wrong order#unsupported field###unknown order###unknown group###undefined
order#undefined generator#slot full###point is not on curve###point at
infinity###pkparameters2group failure##passed null parameter###no parameters
set###no field mod####not initialized#not implemented#not a supported NIST
prime##not a NIST prime####missing private key#keys not set####invalid trinomial
basis#invalid private key#invalid pentanomial basis###invalid group order#invalid
form####invalid field###invalid encoding####invalid digest type#invalid
curve###invalid compression bit#invalid compressed point####incompatible
objects####i2d ecpkparameters failure##group2pkparameters failure##field too
large#ec group new by name failure####discriminant is zero####d2i ecpkparameters
failure##buffer too small####asn1 unknown field##asn1
error##PKEY_EC_SIGN####PKEY_EC_PARAMGEN####PKEY_EC_KEYGEN##PKEY_EC_DERIVE##PKEY_EC_
CTRL_STR####PKEY_EC_CTRL####OLD_EC_PRIV_DECODE##o2i_ECPublicKey#i2o_ECPublicKey#i2d
_ECPrivateKey####i2d_ECPKParameters##i2d_ECParameters####ec_wNAF_precompute_mult#ec
_wNAF_mul#EC_PRE_COMP_NEW#EC_PRE_COMP_DUP#EC_POINT_set_to_infinity####EC_POINT_set_
Jprojective_coordinates_GFp####EC_POINT_set_compressed_coordinates_GFp#EC_POINT_set
_compressed_coordinates_GF2m####EC_POINT_set_affine_coordinates_GFp#EC_POINT_set_af
fine_coordinates_GF2m####EC_POINT_point2oct##EC_POINT_oct2point##EC_POINT_new####EC
_POINT_mul####EC_POINT_make_affine####EC_POINT_is_on_curve####EC_POINT_is_at_infini
ty#EC_POINT_invert#EC_POINT_get_Jprojective_coordinates_GFp####EC_POINT_get_affine_
coordinates_GFp#EC_POINT_get_affine_coordinates_GF2m####EC_POINT_dbl####EC_POINT_co
py###EC_POINT_cmp####EC_POINT_add####EC_POINTs_make_affine###EC_KEY_print_fp#EC_KEY
_print####EC_KEY_new##EC_KEY_generate_key#EC_KEY_copy#EC_KEY_check_key####EC_GROUP_
set_generator##EC_GROUP_SET_EXTRA_DATA#EC_GROUP_set_curve_GFp##EC_GROUP_set_curve_G
F2m#EC_GROUP_precompute_mult####EC_GROUP_NEW_FROM_DATA##EC_GROUP_new_by_curve_name#
#EC_GROUP_new####EC_GROUP_get_trinomial_basis####EC_GROUP_get_pentanomial_basis##EC
_GROUP_get_order##EC_GROUP_get_degree#EC_GROUP_get_curve_GFp##EC_GROUP_get_curve_GF
2m#EC_GROUP_get_cofactor###EC_GROUP_get0_generator#EC_GROUP_copy###EC_GROUP_check_d
iscriminant#EC_GROUP_check##EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP####ec_GFp_
simple_set_compressed_coordinates####EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP
##ec_GFp_simple_point_set_affine_coordinates##EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDI
NATES_GFP##ec_GFp_simple_point_get_affine_coordinates##ec_GFp_simple_points_make_af
fine####ec_GFp_simple_point2oct#ec_GFp_simple_oct2point#ec_GFp_simple_make_affine##
#EC_GFP_SIMPLE_GROUP_SET_GENERATOR###EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP###ec_GFp_sim
ple_group_set_curve###ec_GFp_simple_group_check_discriminant##ec_GFp_nist_group_set
_curve#ec_GFp_nist_field_sqr###ec_GFp_nist_field_mul###EC_GFP_MONT_GROUP_SET_CURVE_
GFP#ec_GFp_mont_group_set_curve#ec_GFp_mont_field_sqr###ec_GFp_mont_field_set_to_on
e####ec_GFp_mont_field_mul###ec_GFp_mont_field_encode####ec_GFp_mont_field_decode##
##ec_GF2m_simple_set_compressed_coordinates###ec_GF2m_simple_point_set_affine_coord
inates#ec_GF2m_simple_point_get_affine_coordinates#ec_GF2m_simple_point2oct####ec_G
F2m_simple_oct2point####ec_GF2m_simple_group_set_curve##ec_GF2m_simple_group_check_
discriminant#EC_GF2M_MONTGOMERY_POINT_MULTIPLY###EC_EX_DATA_set_data#EC_ASN1_PKPARA
METERS2GROUP##EC_ASN1_PARAMETERS2GROUP####EC_ASN1_GROUP2PKPARAMETERS##EC_ASN1_GROUP
2PARAMETERS####EC_ASN1_GROUP2FIELDID###EC_ASN1_GROUP2CURVE#ECP_NIST_MOD_521####ECP_
NIST_MOD_256####ECP_NIST_MOD_224####ECP_NIST_MOD_192####ECPKParameters_print_fp#ECP
KParameters_print####ECParameters_print_fp###ECParameters_print##ECKEY_TYPE2PARAM##
##ECKEY_PUB_ENCODE####ECKEY_PUB_DECODE####ECKEY_PRIV_ENCODE###ECKEY_PRIV_DECODE###E
CKEY_PARAM_DECODE##ECKEY_PARAM2TYPE####DO_EC_KEY_PRINT#d2i_ECPrivateKey####d2i_ECPK
Parameters##d2i_ECParameters####COMPUTE_WNAF####zlib not supported##zlib inflate
error##zlib deflate
error##BIO_ZLIB_WRITE##BIO_ZLIB_READ###BIO_ZLIB_NEW####BIO_ZLIB_FLUSH##no dynlock
create
callback##INT_NEW_EX_DATA#INT_FREE_EX_DATA####INT_DUP_EX_DATA#DEF_GET_CLASS###DEF_A
DD_INDEX###CRYPTO_set_ex_data##CRYPTO_get_new_lockid###CRYPTO_get_new_dynlockid####
CRYPTO_get_ex_new_index#variable has no value###unknown module name#unable to
create new section####no value####no section##no conf or environment variable#no
conf#no close brace##module initialization error#missing init function###missing
finish function#missing equal sign##missing close square bracket####list cannot be
null#error loading
dso###STR_COPY####NCONF_new###NCONF_load_fp###NCONF_load_bio##NCONF_load##NCONF_get
_string####NCONF_get_section###NCONF_get_number_e##NCONF_get_number####NCONF_dump_f
p###NCONF_dump_bio##MODULE_RUN##MODULE_LOAD_DSO#MODULE_INIT#DEF_LOAD_BIO####DEF_LOA
D####CONF_parse_list#CONF_modules_load###CONF_load_fp####CONF_load_bio###CONF_load#
##CONF_dump_fp####wrong type##wrong tag###wrong public key type###unsupported
public key type#unsupported encryption algorithm####unsupported cipher##unsupported
any defined by type#unkown format###unknown tag#unknown signature algorithm#unknown
public key type#unknown object type#unknown message digest algorithm####unknown
format##universalstring is wrong length#unexpected eoc##unable to decode rsa
private key####unable to decode rsa key####type not constructed####too long####time
not ascii format###the asn1 object identifier is not known for this md#tag value
too high##string too short####streaming not supported#short line##sequence or set
needs config####sequence not constructed####sequence length mismatch####second
number too large#private key header missing##odd number of chars#object not ascii
format#null is wrong length####no matching choice type#not enough data#not ascii
format####non hex characters##nested asn1 string##mstring wrong tag###mstring not
universal###missing second number###missing eoc#list error##length error####iv too
large####invalid utf8string##invalid universalstring length##invalid time
format#invalid separator###invalid object encoding#invalid modifier####invalid
digit###invalid bmpstring length####integer too large for long##integer not ascii
format####illegal time value##illegal tagged any##illegal
options on item template####illegal optional any####illegal object##illegal null
value##illegal null####illegal nested tagging##illegal integer#illegal implicit
tag####illegal hex#illegal format##illegal characters##illegal boolean#illegal
bitstring format####header too long#first num too large#field missing###explicit
tag not constructed####explicit length mismatch####expecting a time####expecting a
boolean#expecting an object#expecting an integer####error setting cipher
params#error parsing set element###error loading section###error getting
time##digest and key type not supported###depth exceeded##decoding error##data is
wrong###boolean is wrong length#bn lib##bmpstring is wrong length###bad tag#bad
password read###bad object header###bad class###aux error###asn1 sig parse
error####asn1 parse error####adding
object###X509_PKEY_new###X509_NEW####X509_NAME_EX_NEW####X509_NAME_EX_D2I####X509_N
AME_ENCODE####X509_INFO_new###X509_CRL_add0_revoked###X509_CINF_NEW###SMIME_read_AS
N1#PKCS5_pbe_set0_algor####PKCS5_pbe_set###PKCS5_pbe2_set_iv###PARSE_TAGGING###OID_
MODULE_INIT#LONG_C2I####i2d_RSA_PUBKEY##i2d_RSA_NET#i2d_PublicKey###i2d_PrivateKey#
#i2d_EC_PUBKEY###i2d_DSA_PUBKEY##I2D_ASN1_TIME###i2d_ASN1_SET####i2d_ASN1_bio_strea
m#d2i_X509_PKEY###D2I_X509_CINF###D2I_X509####D2I_RSA_NET_2###d2i_RSA_NET#d2i_Publi
cKey###d2i_PrivateKey##D2I_NETSCAPE_RSA_2##d2i_Netscape_RSA####d2i_AutoPrivateKey##
D2I_ASN1_UTCTIME####d2i_ASN1_UINTEGER###d2i_ASN1_type_bytes#d2i_ASN1_SET####d2i_ASN
1_OBJECT#D2I_ASN1_INTEGER####D2I_ASN1_HEADER#D2I_ASN1_GENERALIZEDTIME####d2i_ASN1_b
ytes##d2i_ASN1_BOOLEAN####D2I_ASN1_BIT_STRING#COLLECT_DATA####c2i_ASN1_OBJECT#c2i_A
SN1_INTEGER####c2i_ASN1_BIT_STRING#BN_to_ASN1_INTEGER##BN_to_ASN1_ENUMERATED###BITS
TR_CB###BIO_new_NDEF####B64_WRITE_ASN1##B64_READ_ASN1###ASN1_verify#ASN1_UTCTIME_se
t####ASN1_UTCTIME_adj####ASN1_unpack_string##ASN1_TYPE_get_octetstring###ASN1_TYPE_
get_int_octetstring###ASN1_TIME_set###ASN1_TIME_adj###ASN1_TEMPLATE_NOEXP_D2I#ASN1_
TEMPLATE_NEW###ASN1_TEMPLATE_EX_D2I####ASN1_STRING_type_new####ASN1_STRING_TABLE_ad
d###ASN1_STRING_set#ASN1_STR2TYPE###ASN1_sign###ASN1_seq_unpack#ASN1_seq_pack###ASN
1_PKCS5_PBE_SET##ASN1_PCTX_new###ASN1_pack_string####ASN1_OUTPUT_DATA####ASN1_OBJEC
T_new#ASN1_mbstring_ncopy#ASN1_item_verify####ASN1_item_unpack####ASN1_item_sign##A
SN1_item_pack##ASN1_item_i2d_fp####ASN1_item_i2d_bio###ASN1_ITEM_EX_D2I####ASN1_ITE
M_EX_COMBINE_NEW####ASN1_item_dup###ASN1_item_d2i_fp####ASN1_INTEGER_to_BN##ASN1_IN
TEGER_set####ASN1_i2d_fp#ASN1_i2d_bio####ASN1_HEADER_NEW#ASN1_get_object#ASN1_gener
ate_v3####ASN1_GENERALIZEDTIME_set####ASN1_GENERALIZEDTIME_adj####ASN1_FIND_END###A
SN1_EX_C2I#ASN1_ENUMERATED_to_BN###ASN1_ENUMERATED_set#ASN1_dup####ASN1_DO_ADB#ASN1
_digest#ASN1_D2I_READ_BIO###ASN1_d2i_fp#ASN1_D2I_EX_PRIMITIVE###ASN1_COLLECT####ASN
1_COLLATE_PRIMITIVE##ASN1_CHECK_TLEN#ASN1_CB#ASN1_BIT_STRING_set_bit#APPEND_EXP##a2
i_ASN1_STRING#a2i_ASN1_INTEGER####a2i_ASN1_ENUMERATED#a2d_ASN1_OBJECT#wrong lookup
type###unsupported algorithm###unknown trust id####unknown purpose id##unknown key
type####unable to get certs public key##unable to find parameters in chain##should
retry####public key encode error#public key decode error#no cert set for us to
verify####method not supported####loading defaults####loading cert dir####key
values mismatch#key type mismatch###invalid trust###invalid field name##invalid
directory###err asn1 lib####cert already in hash table##cant check dh key###base64
decode error#bad x509
filetype###X509_verify_cert####X509_TRUST_set##X509_TRUST_add##X509_to_X509_REQ####
X509_STORE_CTX_purpose_inherit##X509_STORE_CTX_new##X509_STORE_CTX_init#X509_STORE_
CTX_get1_issuer##X509_STORE_add_crl##X509_STORE_add_cert#X509_REQ_to_X509####X509_R
EQ_print_fp###X509_REQ_print_ex###X509_REQ_check_private_key##X509_PUBKEY_set#X509_
PUBKEY_get#X509_print_ex_fp####X509_NAME_print#X509_NAME_oneline###X509_NAME_ENTRY_
set_object##X509_NAME_ENTRY_create_by_txt###X509_NAME_ENTRY_create_by_NID###X509_NA
ME_add_entry#X509_load_crl_file##X509_load_cert_file#X509_load_cert_crl_file#X509_g
et_pubkey_parameters##X509_EXTENSION_create_by_OBJ####X509_EXTENSION_create_by_NID#
###X509_CRL_print_fp###X509_check_private_key##X509_ATTRIBUTE_set1_data####X509_ATT
RIBUTE_get0_data####X509_ATTRIBUTE_create_by_txt####X509_ATTRIBUTE_create_by_OBJ###
#X509_ATTRIBUTE_create_by_NID####X509v3_add_ext##X509at_add1_attr####NETSCAPE_SPKI_
b64_encode####NETSCAPE_SPKI_b64_decode####GET_CERT_BY_SUBJECT#DIR_CTRL####CHECK_POL
ICY####BY_FILE_CTRL####ADD_CERT_DIR####parameter encoding error####modulus too
large###bn error####bn decode error#bad q
value#SIG_CB##PKEY_DSA_KEYGEN#PKEY_DSA_CTRL###OLD_DSA_PRIV_DECODE#i2d_DSA_SIG#DSA_v
erify##DSA_SIG_new#DSA_sign_setup##DSA_sign####DSA_PUB_ENCODE##DSA_PUB_DECODE##DSA_
PRIV_ENCODE#DSA_PRIV_DECODE#DSA_print_fp####DSA_PARAM_DECODE####DSA_new_method##DSA
_do_verify###DSA_do_sign#DSAparams_print_fp##DSAparams_print#DO_DSA_PRINT####d2i_DS
A_SIG#unsupported key components##unsupported encryption##short header####read
key####pvk too short###pvk data too short##public key no rsa###problems getting
password###no start line###not proc type###not encrypted###not dek info####keyblob
too short###keyblob header parse error##inconsistent header#expecting public key
blob###expecting private key blob##error converting private key####cipher is
null##bio write failure###bad version number##bad magic number####bad iv
chars####bad end line####bad decrypt#bad base64
decode###PEM_X509_INFO_write_bio#PEM_X509_INFO_read_bio##PEM_X509_INFO_read##PEM_WR
ITE_PRIVATEKEY####PEM_write_bio###PEM_write###PEM_SignFinal###PEM_SealInit####PEM_S
ealFinal###PEM_READ_PRIVATEKEY#PEM_READ_BIO_PRIVATEKEY#PEM_read_bio_Parameters#PEM_
read_bio####PEM_read####PEM_PK8PKEY#PEM_get_EVP_CIPHER_INFO#PEM_F_PEM_WRITE_PKCS8PR
IVATEKEY#PEM_do_header###PEM_def_callback####PEM_ASN1_write_bio##PEM_ASN1_write##PE
M_ASN1_read_bio###PEM_ASN1_read###LOAD_IV#i2b_PVK_bio#I2B_PVK#DO_PVK_HEADER###DO_PV
K_BODY#DO_PK8PKEY_FP###DO_PK8PKEY##DO_BLOB_HEADER##DO_B2I_BIO##DO_B2I##d2i_PKCS8Pri
vateKey_fp##d2i_PKCS8PrivateKey_bio#CHECK_BITLEN_RSA####CHECK_BITLEN_DSA####B2I_RSA
#b2i_PVK_bio#B2I_DSS#OBJ_nid2sn##OBJ_nid2obj#OBJ_nid2ln##OBJ_NAME_new_index##OBJ_du
p#OBJ_create##OBJ_add_object##BUF_strndup#BUF_strdup##BUF_MEM_new#BUF_MEM_grow_clea
n##BUF_MEM_grow####BUF_memdup##wrong final block length####unsupported salt
type###unsupported private key algorithm###unsupported prf#unsupported key
size####unsupported key derivation function#unsupported keylength###unsuported
number of rounds#unknown pbe algorithm###unknown digest##unknown cipher##public key
not rsa##private key encode error####private key decode error####pkcs8 unknown
broken type###operaton not initialized####operation not supported for this
keytype####no verify function configured###no sign function configured#no operation
set####no key set##no dsa parameters###no digest set###no cipher set###message
digest is null##keygen failure##invalid operation###invalid key length##invalid
digest##input not initialized###initialization error####expecting a ec
key##expecting a ecdsa key###expecting a dsa key#expecting a dh key##expecting an
rsa key####evp pbe cipherinit error####different parameters####different key
types#data not multiple of block length###ctrl operation not implemented##ctrl not
implemented####command not supported###cipher parameter error##camellia key setup
failed###bn pubkey error#bad key length##bad block length####asn1 lib####aes key
setup
failed####RC5_CTRL####RC2_MAGIC_TO_METH###PKEY_SET_TYPE###PKCS8_set_broken####PKCS5
_v2_PBE_keyivgen###PKCS5_PBE_keyivgen##INT_CTX_NEW#EVP_VerifyFinal#EVP_SignFinal###
EVP_RIJNDAEL####EVP_PKEY_verify_recover_init####EVP_PKEY_verify_recover#EVP_PKEY_ve
rify_init####EVP_PKEY_verify#EVP_PKEY_sign_init##EVP_PKEY_sign###EVP_PKEY_paramgen_
init##EVP_PKEY_paramgen###EVP_PKEY_new####EVP_PKEY_keygen_init####EVP_PKEY_keygen#E
VP_PKEY_get1_RSA###EVP_PKEY_get1_EC_KEY####EVP_PKEY_GET1_ECDSA#EVP_PKEY_get1_DSA###
EVP_PKEY_get1_DH####EVP_PKEY_encrypt_old####EVP_PKEY_encrypt_init###EVP_PKEY_encryp
t####EVP_PKEY_derive_set_peer####EVP_PKEY_derive_init####EVP_PKEY_derive#EVP_PKEY_d
ecrypt_old####EVP_PKEY_decrypt_init###EVP_PKEY_decrypt####EVP_PKEY_CTX_dup####EVP_P
KEY_CTX_ctrl_str###EVP_PKEY_CTX_ctrl###EVP_PKEY_copy_parameters####EVP_PKEY2PKCS8_b
roken###EVP_PKCS82PKEY_BROKEN###EVP_PKCS82PKEY##EVP_PBE_CipherInit##EVP_PBE_alg_add
_type####EVP_PBE_alg_add#EVP_OpenInit####EVP_MD_SIZE#EVP_MD_CTX_copy_ex##EVP_Encryp
tFinal_ex#EVP_DigestInit_ex###EVP_DecryptFinal_ex#EVP_CIPHER_CTX_set_key_length###E
VP_CIPHER_CTX_ctrl#EVP_CIPHER_CTX_copy#EVP_CipherInit_ex###ECKEY_PKEY2PKCS8####ECDS
A_PKEY2PKCS8####DSA_PKEY2PKCS8##DSAPKEY2PKCS8###DO_SIGVER_INIT##D2I_PKEY####CAMELLI
A_INIT_KEY###AES_INIT_KEY####invalid public key##bad
generator###PKEY_DH_KEYGEN##PKEY_DH_DERIVE##GENERATE_PARAMETERS#GENERATE_KEY####DO_
DH_PRINT#DH_PUB_ENCODE###DH_PUB_DECODE###DH_PRIV_ENCODE##DH_PRIV_DECODE##DH_PARAM_D
ECODE#DH_new_method###DH_BUILTIN_GENPARAMS####DHparams_print_fp###COMPUTE_KEY#wrong
signature length##value missing###unknown padding type####unknown algorithm
type##sslv3 rollback attack###salt length recovery failed#salt length check
failed####rsa operations not supported####q not prime#p not prime#padding check
failed####oaep decoding error#n does not equal p q####null before block
missing###no public exponent##last octet invalid##key size too small##iqmp not
inverse of q###invalid x931 digest#invalid trailer#invalid pss saltlen#invalid
padding mode####invalid padding#invalid message length##invalid keybits#invalid
header##invalid digest length###illegal or unsupported padding mode#first octet
invalid#d e not congruent to 1##dmq1 not congruent to d#dmp1 not congruent to
d#digest too big for rsa key##data too small for key size#data too small##data too
large for modulus##data too large##data greater than mod len###block type is not
02####block
type is not 01####bad pad byte count##bad fixed header decrypt####bad e
value#algorithm
mismatch##RSA_verify_PKCS1_PSS####RSA_verify_ASN1_OCTET_STRING####RSA_verify##RSA_s
ign_ASN1_OCTET_STRING##RSA_sign####RSA_setup_blinding##RSA_PUB_DECODE##RSA_PRIV_ENC
ODE#RSA_PRIV_DECODE#RSA_print_fp####RSA_print###RSA_padding_check_X931##RSA_padding
_check_SSLv23####RSA_padding_check_PKCS1_type_2##RSA_padding_check_PKCS1_type_1##RS
A_padding_check_PKCS1_OAEP####RSA_padding_check_none##RSA_padding_add_X931####RSA_p
adding_add_SSLv23##RSA_padding_add_PKCS1_type_2####RSA_padding_add_PKCS1_type_1####
RSA_padding_add_PKCS1_PSS###RSA_padding_add_PKCS1_OAEP##RSA_padding_add_none####RSA
_NULL_PUBLIC_ENCRYPT#RSA_NULL_PUBLIC_DECRYPT#RSA_NULL_PRIVATE_ENCRYPT####RSA_NULL_P
RIVATE_DECRYPT####RSA_NULL_MOD_EXP####RSA_NULL####RSA_new_method##RSA_memory_lock#R
SA_generate_key####RSA_EAY_PUBLIC_ENCRYPT##RSA_EAY_PUBLIC_DECRYPT##RSA_EAY_PRIVATE_
ENCRYPT#RSA_EAY_PRIVATE_DECRYPT#RSA_check_key###RSA_BUILTIN_KEYGEN##PKEY_RSA_VERIFY
RECOVER##PKEY_RSA_SIGN###PKEY_RSA_CTRL_STR###PKEY_RSA_CTRL###OLD_RSA_PRIV_DECODE#ME
MORY_LOCK#INT_RSA_VERIFY##DO_RSA_PRINT####CHECK_PADDING_MD####too many temporary
variables####too many iterations#p is not prime##no solution#no inverse##not a
square####invalid range###invalid length##input not reduced###expand on static
bignum data####encoding error##div by zero#called with even modulus####bignum too
long#bad reciprocal##arg2 lt
arg3####BN_usub#BN_rand_range###BN_rand#BN_new##BN_mpi2bn###BN_mod_sqrt#BN_mod_mul_
reciprocal###BN_mod_lshift_quick#BN_mod_inverse_no_branch####BN_mod_inverse##BN_mod
_exp_simple###BN_mod_exp_recp#BN_mod_exp_mont_word####BN_mod_exp_mont_consttime###B
N_mod_exp_mont#BN_mod_exp2_mont####BN_GF2m_mod_sqrt####BN_GF2m_mod_sqr#BN_GF2m_mod_
solve_quad_arr##BN_GF2m_mod_solve_quad##BN_GF2m_mod_mul#BN_GF2m_mod_exp#BN_GF2m_mod
#BN_EXPAND_INTERNAL##bn_expand2##BN_exp##BN_div_recp#BN_div_no_branch####BN_div##BN
_CTX_start####BN_CTX_new##BN_CTX_get##BN_bn2hex###BN_bn2dec###BN_BLINDING_update##B
N_BLINDING_new#BN_BLINDING_invert_ex###BN_BLINDING_create_param####BN_BLINDING_conv
ert_ex##BNRAND##x509 verification setup problems####x509 lib####wrong version
number####wrong ssl version###wrong signature size####wrong number of key
bits####wrong message type##wrong cipher returned###write bio not set###unsupported
status type#unsupported ssl version#unsupported protocol####unsupported elliptic
curve##unsupported digest type#unsupported compression algorithm###unsafe legacy
renegotiation disabled####unknown state###unknown ssl version#unknown remote error
type###unknown protocol####unknown pkey type###unknown key exchange type###unknown
cipher type#unknown cipher returned#unknown certificate type####unknown alert
type##unexpected record###unexpected message##unable to load ssl3 sha1
routines###unable to load ssl3 md5 routines####unable to load ssl2 md5
routines####unable to find ssl method###unable to find public key
parameters####unable to find ecdh parameters##unable to find dh
parameters####unable to extract public key####unable to decode ecdh certs#unable to
decode dh certs###tried to use unsupported cipher#tls rsa encrypted value length is
wrong#tls peer did not respond with certificate list##tls invalid ecpointformat
list##tls client cert req with anon cipher####tlsv1 unsupported extension#tlsv1
unrecognized name#tlsv1 certificate unobtainable##tlsv1 bad certificate status
response###tlsv1 bad certificate hash value####tlsv1 alert user cancelled##tlsv1
alert unknown ca##tlsv1 alert record overflow#tlsv1 alert protocol version####tlsv1
alert no renegotiation####tlsv1 alert internal error##tlsv1 alert insufficient
security###tlsv1 alert export restriction##tlsv1 alert decrypt error###tlsv1 alert
decryption failed###tlsv1 alert decode error####tlsv1 alert access denied###ssl
session id is different#ssl session id has bad length###ssl session id context too
long#ssl session id conflict#ssl session id callback failed##ssl library has no
ciphers##ssl handshake failure###ssl ctx has no default ssl version##sslv3 alert
unsupported certificate#sslv3 alert unexpected message##sslv3 alert no
certificate##sslv3 alert illegal parameter###sslv3 alert handshake failure###sslv3
alert decompression failure###sslv3 alert certificate unknown#sslv3 alert
certificate revoked#sslv3 alert certificate expired#sslv3 alert bad record
mac##sslv3 alert bad certificate#ssl3 session id too short###ssl3 session id too
long####ssl3 ext invalid servername type####ssl3 ext invalid servername#ssl3 ext
invalid ecpointformat##ssl2 connection id too long#ssl23 doing session id
reuse####signature for non signing certificate###short read##session may not be
created##session id context uninitialized####serverhello tlsext##scsv received when
renegotiating####reuse cipher list not zero##reuse cert type not zero####reuse cert
length not zero##required compresssion algorithm missing#required cipher
missing#renegotiation mismatch##renegotiation encoding err##renegotiate ext too
long####record too small####record too large####record length mismatch##read wrong
packet type##read timeout expired####read bio not set####public key is not
rsa###public key encrypt error####psk no server cb####psk no client cb####psk
identity not found##protocol is shutdown####problems mapping cipher functions###pre
mac length too long#peer error unsupported certificate type#peer error no
cipher####peer error no certificate###peer error certificate##peer error##peer did
not return a certificate###path too long###parse tlsext####packet length too
long##opaque PRF input too long###only tls allowed in fips mode###old session
compression algorithm not returned##old session cipher not returned#null ssl method
passed##null ssl ctx####no verify callback##no shared cipher####digest requred for
handshake isn't computed#no renegotiation####no publickey####no protocols
available##no private key assigned#no privatekey###no method specified#####Peer
haven't sent GOST certificate, required for selected ciphersuite###no compression
specified####no client cert received#no client cert method###no cipher match#no
cipher list##no ciphers specified####no ciphers passed###no ciphers available####no
certificate specified####no certificate set##no certificate returned#no certificate
assigned#no certificates returned####non sslv2 initial packet####multiple sgc
restarts###missing verify message##missing tmp rsa pkey####missing tmp rsa
key#missing tmp ecdh key####missing tmp dh key##missing rsa signing cert####missing
rsa encrypting cert#missing rsa certificate#missing export tmp rsa key##missing
export tmp dh key###missing dsa signing cert####missing dh rsa cert#missing dh
key##missing dh dsa cert#library has no ciphers##library bug#length too
short####length mismatch#krb5 server tkt skew####krb5 server tkt not yet
valid###krb5 server tkt expired#krb5 server rd_req (keytab perms?)##krb5 server
init####krb5 server bad ticket##krb5 client mk_req (expired tkt?)###krb5 client
init####krb5 client get cred####krb5 client cc principal (no tkt?)##krb5####key arg
too long####invalid ticket keys length##invalid status response#invalid compression
algorithm###invalid command#invalid challenge length####inconsistent
compression####illegal padding#http request####https proxy request#got next proto
without seeing extension#got next proto before a ccs#got a fin before a ccs##extra
data in message###excessive message size##error in received cipher list###error
generating tmp rsa key####encrypted length too long###ecgroup too large for
cipher####ecc cert should have sha1 signature#ecc cert should have rsa
signature##ecc cert not for signing####ecc cert not for key agreement##duplicate
compression id####dtls message too big####digest check failed#dh public value
length is wrong#decryption failed or bad record mac#decryption failed###data length
too long####data between ccs and finished###cookie mismatch#connection type not
set#connection id is different##compression library error###compression id not
within private range#compression failure#compression disabled####compressed length
too long##clienthello tlsext##cipher table src error##cipher or hash
unavailable##cipher code wrong length####challenge is different##cert length
mismatch####certificate verify failed###ccs received early##ca dn too long##ca dn
length mismatch###block cipher pad is wrong###bio not set#bad write retry#bad ssl
session id length###bad ssl filetype####bad rsa signature###bad rsa modulus
length##bad rsa e length####bad rsa encrypt#bad rsa decrypt#bad response
argument###bad psk identity hint length####bad protocol version number#bad packet
length###bad message type####bad mac length##bad mac decode##bad length##bad hello
request###bad handshake length####bad ecpoint#bad ecdsa signature#bad ecc
cert####bad dsa signature###bad digest length###bad dh p length#bad dh pub key
length###bad dh g length#bad decompression###bad data returned by callback###bad
checksum####bad change cipher spec##bad authentication type#bad alert
record####attempt to reuse session in different context###app data in
handshake###WRITE_PENDING###TLS1_SETUP_KEY_BLOCK####tls1_prf####TLS1_PREPARE_SERVER
HELLO_TLSEXT#TLS1_PREPARE_CLIENTHELLO_TLSEXT#TLS1_ENC####TLS1_CHECK_SERVERHELLO_TLS
EXT###TLS1_CHANGE_CIPHER_STATE####tls1_cert_verify_mac####SSL_write###SSL_VERIFY_CE
RT_CHAIN###SSL_use_RSAPrivateKey_file##SSL_use_RSAPrivateKey_ASN1##SSL_use_RSAPriva
teKey###SSL_use_psk_identity_hint###SSL_use_PrivateKey_file#SSL_use_PrivateKey_ASN1
#SSL_use_PrivateKey##SSL_use_certificate_file####SSL_use_certificate_ASN1####SSL_us
e_certificate#SSL_UNDEFINED_VOID_FUNCTION#SSL_UNDEFINED_FUNCTION##SSL_UNDEFINED_CON
ST_FUNCTION####SSL_set_wfd#SSL_set_trust###SSL_set_session_ticket_ext##SSL_set_sess
ion_id_context##SSL_set_session#SSL_set_rfd#SSL_set_purpose#SSL_SET_PKEY####SSL_set
_fd##SSL_set_cipher_list#SSL_SET_CERT####SSL_SESS_CERT_NEW###SSL_SESSION_print_fp##
##SSL_SESSION_new#SSL_RSA_PUBLIC_ENCRYPT##SSL_RSA_PRIVATE_DECR
YPT#SSL_read####SSL_PREPARE_SERVERHELLO_TLSEXT##SSL_PREPARE_CLIENTHELLO_TLSEXT##SSL
_peek####SSL_PARSE_SERVERHELLO_TLSEXT####SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT###SS
L_PARSE_CLIENTHELLO_TLSEXT####SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT###SSL_load_clie
nt_CA_file#SSL_INIT_WBIO_BUFFER####SSL_GET_SIGN_PKEY###SSL_GET_SERVER_SEND_CERT####
SSL_GET_PREV_SESSION####SSL_GET_NEW_SESSION#SSL_do_handshake####SSL_CTX_use_RSAPriv
ateKey_file##SSL_CTX_use_RSAPrivateKey_ASN1##SSL_CTX_use_RSAPrivateKey###SSL_CTX_us
e_psk_identity_hint###SSL_CTX_use_PrivateKey_file#SSL_CTX_use_PrivateKey_ASN1#SSL_C
TX_use_PrivateKey##SSL_CTX_use_certificate_file####SSL_CTX_use_certificate_chain_fi
le##SSL_CTX_use_certificate_ASN1####SSL_CTX_use_certificate#SSL_CTX_set_trust###SSL
_CTX_set_ssl_version#SSL_CTX_set_session_id_context##SSL_CTX_set_purpose#SSL_CTX_se
t_client_cert_engine##SSL_CTX_set_cipher_list#SSL_CTX_new#SSL_CTX_check_private_key
###SSL_ctrl####SSL_CREATE_CIPHER_LIST##SSL_COMP_add_compression_method#SSL_clear###
SSL_CIPHER_STRENGTH_SORT####SSL_CIPHER_PROCESS_RULESTR##SSL_CHECK_SRVR_ECC_CERT_AND
_ALG#SSL_CHECK_SERVERHELLO_TLSEXT####SSL_check_private_key###SSL_CERT_NEW####SSL_CE
RT_INSTANTIATE####SSL_CERT_INST###SSL_CERT_DUP####SSL_BYTES_TO_CIPHER_LIST####SSL_B
AD_METHOD##SSL_ADD_SERVERHELLO_TLSEXT##SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT#SSL_add_
file_cert_subjects_to_stack#SSL_add_dir_cert_subjects_to_stack##SSL_ADD_CLIENTHELLO
_TLSEXT##SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT#SSL3_WRITE_PENDING##SSL3_WRITE_BYTES##
##SSL3_SETUP_WRITE_BUFFER#SSL3_SETUP_READ_BUFFER##SSL3_SETUP_KEY_BLOCK####SSL3_SEND
_SERVER_KEY_EXCHANGE###SSL3_SEND_SERVER_HELLO##SSL3_SEND_SERVER_CERTIFICATE####SSL3
_SEND_CLIENT_VERIFY#SSL3_SEND_CLIENT_KEY_EXCHANGE###SSL3_SEND_CLIENT_CERTIFICATE###
#SSL3_SEND_CERTIFICATE_REQUEST###SSL3_READ_N#SSL3_READ_BYTES#SSL3_PEEK###SSL3_OUTPU
T_CERT_CHAIN##SSL3_NEW_SESSION_TICKET#ssl3_handshake_mac##SSL3_GET_SERVER_HELLO###S
SL3_GET_SERVER_DONE####SSL3_GET_SERVER_CERTIFICATE#SSL3_GET_RECORD#SSL3_GET_NEXT_PR
OTO#SSL3_GET_NEW_SESSION_TICKET#SSL3_GET_MESSAGE####SSL3_GET_KEY_EXCHANGE###SSL3_GE
T_FINISHED###SSL3_GET_CLIENT_KEY_EXCHANGE####SSL3_GET_CLIENT_HELLO###SSL3_GET_CLIEN
T_CERTIFICATE#SSL3_GET_CERT_VERIFY####SSL3_GET_CERT_STATUS####SSL3_GET_CERTIFICATE_
REQUEST####SSL3_GENERATE_KEY_BLOCK#SSL3_ENC####SSL3_DO_CHANGE_CIPHER_SPEC##SSL3_DIG
EST_CACHED_RECORDS##SSL3_CTX_CTRL###SSL3_CTRL###SSL3_CONNECT####SSL3_CLIENT_HELLO##
#SSL3_CHECK_CLIENT_HELLO#SSL3_CHECK_CERT_AND_ALGORITHM###SSL3_CHANGE_CIPHER_STATE##
##SSL3_CALLBACK_CTRL##SSL3_ADD_CERT_TO_BUF####SSL3_ACCEPT#SSL2_WRITE##SSL2_SET_CERT
IFICATE####SSL2_READ_INTERNAL##SSL2_READ###SSL2_PEEK###SSL2_GENERATE_KEY_MATERIAL##
SSL2_ENC_INIT###SSL2_CONNECT####SSL2_ACCEPT#SSL23_WRITE#SSL23_READ##SSL23_PEEK##SSL
23_GET_SERVER_HELLO##SSL23_GET_CLIENT_HELLO##SSL23_CONNECT###SSL23_CLIENT_HELLO##SS
L23_ACCEPT####SERVER_VERIFY###SERVER_HELLO####SERVER_FINISH###REQUEST_CERTIFICATE#R
EAD_N##i2d_SSL_SESSION#GET_SERVER_VERIFY###GET_SERVER_HELLO####GET_SERVER_FINISHED#
GET_CLIENT_MASTER_KEY###GET_CLIENT_HELLO####GET_CLIENT_FINISHED#DTLS1_WRITE_APP_DAT
A_BYTES##DTLS1_SEND_SERVER_KEY_EXCHANGE##DTLS1_SEND_SERVER_HELLO#DTLS1_SEND_SERVER_
CERTIFICATE###DTLS1_SEND_HELLO_VERIFY_REQUEST#DTLS1_SEND_CLIENT_VERIFY####DTLS1_SEN
D_CLIENT_KEY_EXCHANGE##DTLS1_SEND_CLIENT_CERTIFICATE###DTLS1_SEND_CERTIFICATE_REQUE
ST##DTLS1_READ_FAILED###DTLS1_READ_BYTES####DTLS1_PROCESS_RECORD####DTLS1_PROCESS_O
UT_OF_SEQ_MESSAGE####DTLS1_PREPROCESS_FRAGMENT###DTLS1_OUTPUT_CERT_CHAIN#DTLS1_HAND
LE_TIMEOUT####DTLS1_GET_RECORD####DTLS1_GET_MESSAGE_FRAGMENT##DTLS1_GET_MESSAGE###D
TLS1_GET_HELLO_VERIFY##DTLS1_ENC###DTLS1_CONNECT###DTLS1_CLIENT_HELLO##DTLS1_BUFFER
_RECORD#DTLS1_ADD_CERT_TO_BUF###DTLS1_ACCEPT####DO_SSL3_WRITE###DO_DTLS1_WRITE##d2i
_SSL_SESSION#CLIENT_MASTER_KEY###CLIENT_HELLO####CLIENT_FINISHED#CLIENT_CERTIFICATE
######$#######@########�##0�##P�######################################@###�########
###u###w###########�z##��##��##########@�##
�######################@###d###########B###B###########�z##��##�z##########��##��##
t###B###q###F#######@###d###########)###*###########�z##��###�##########@�##
�######################@###d###############�###########�G##0�##P�##########@�##
�######################@###`#######aes256##aes192##AES192##aes128##cast-
cbc####CAST-
cbc####cast####CAST####blowfish####rc2#des3####DES3####des#desx####DESX####
%###############J###��##p�##########
�##@�##��######'###############K###��###�##########
�##@�##��######(###############L###��##��##########
�##@�##��######&###############I###��##p�##########
�##@�##��######�###############J###��##p�##########
�##@�##��######b###############J###��##p�##########
�##@�##��######openssl\crypto\evp\e_rc2.c##l <= sizeof(iv)#####################
�##P�##########################a###################
�##P�##########################+###################��##��######�####K##�J##
�######<###################��###�######�####K##�J##
�######>###################��##��######�####K##�J## �######
###################��##��######�####K##�J##
�######,###################��##��######�####K##�J##
�######=###################��###�######�####K##�J## �######?
###################��##��######�####K##�J## �######!
###################��##��######�####K##�J##
�######�###################��##��######�####K##�J##
�######�###################��##`�######�####K##�J##
�##########################��##��######�####K##�J##��##########################��##
#�######�####K##�J##��######-
###################��###�######�####K##�J##��##########################��##��######
�####K##�J##��######�###################��##��######�####K##�J##��######�##########
#########��##��######�####K##�J##��######TSA server##OCSP request####OCSP
responder##Object Signer###S/MIME email####SSL Server##SSL
Client##compatible##openssl\crypto\engine\eng_lib.c#PROXY_CERT_INFO_EXTENSION###pro
xyPolicy#pcPathLengthConstraint##PROXY_POLICY####policy##policyLanguage############
##�7�#�^##############�7�#�]##########�7�#############�7�#############�7�#�\#######
#######x7�#
�###########8�#############\7�#BASIC_CONSTRAINTS###pathlen#W#######p�##############
############��##��##########################T#�#�_##############`8�#�\##########�8�
#############L8�#openssl\crypto\x509v3\v3_bcons.c####Load certs from files in a
directory####openssl\crypto\x509\by_dir.c####%s%c%08lx.%s%d##Load file into
cache####openssl\crypto\x509\by_file.c###AUTHORITY_INFO_ACCESS###ACCESS_DESCRIPTION
##�#######��##########################��###�##############�#######��###############
###########��###�##########################T��#�^###############��##�##########4:�#
############�9�#############t��#`�######����x:�#############�9�#openssl\crypto\x509
v3\v3_info.c#value=##openssl\crypto\asn1\a_bitstr.c##openssl\crypto\asn1\tasn_utl.c
##U#######@�##########################��##
###############V#######@�##########################��##########################@�##
########################��##################Registered ID###IP
Address##DirName#URI#DNS#EdiPartyName####X400Name####othername###<unsupported>###:
%X#IP Address:%d.%d.%d.%d##DirName: ###URI:%s##DNS:%s##email:
%s####EdiPartyName:<unsupported>##X400Name:<unsupported>##othername:<unsupported>#o
penssl\crypto\x509v3\v3_alt.c##section=####otherName###dirName#IP##RID#openssl\cryp
to\x509v3\pcy_data.c####NOTICEREF###noticenos###organization####USERNOTICE##exptext
#noticeref###POLICYQUALINFO##pqualid#d.usernotice####d.cpsuri####POLICYINFO##qualif
iers##policyid####CERTIFICATEPOLICIES#Y#######@###################################�
###0###################�=�#P#######����#>�#############�=�#############�=�#�^######
########�=�#�###########4>�#############�=�#############t#�##_##�###############�=�
#�^##�###############x=�#�###############�>�#####x>�#################p=�#�^######��
��####`=�#�###########�>�#############`=�#############T=�#�###############L=�#�_###
########?�#############@=�#############0=�#�_##############$=�#�\##########`?
�##############=�#openssl\crypto\x509v3\v3_cpols.c####%*sExplicit Text: %s
###%*sNumber%s: ###%*sOrganization: %s
####noticeNumbers###explicitText####%*sCPS: %s
#%*sUser Notice:
####%*sUnknown Qualifier: ##%*sPolicy:
#userNotice##CPS#policyIdentifier####ia5org##POLICY_CONSTRAINTS##inhibitPolicyMappi
ng####requireExplicitPolicy###�#######�###########################�###
###############�###########�@�#�\##�###########�@�#�\###########A�#############�@�#
Inhibit Policy Mapping##Require Explicit
Policy#openssl\crypto\x509v3\v3_pcons.c####openssl\crypto\x509v3\v3_conf.c#BIGNUM##
################��######�A�#################��######�A�#ZLONG###LONG###############
#####��##���#B�#################��######
B�#openssl\crypto\asn1\x_long.c####%ld
####openssl\crypto\engine\eng_table.c###LOAD####OpenSSL default user
interface##con#openssl\crypto\ui\ui_openssl.c##Verify failure
#Verifying - %s##openssl\crypto\pkcs12\p12_crpt.c####EVP_CIPHER_iv_length(cipher)
<= 16##EVP_CIPHER_key_length(cipher) <=
(int)sizeof(md_tmp)####openssl\crypto\evp\p5_crpt.c########W#######�&##
'##�'###############(##########################�(##�(##############################
#### )
##�)##openssl\crypto\hmac\hm_pmeth.c##hexkey######�#######�*##�*##P+######�.######P
/######�+###### ,##############################################p,###-
##0.##openssl\crypto\ec\ec_pmeth.c####ec_paramgen_curve###t#######�/###0##�0######�
3######p4######�0#######1##################################################P1##�2##
openssl\crypto\dsa\dsa_pmeth.c##dsa_paramgen_md#dsa_paramgen_q_bits#dsa_paramgen_bi
ts###############�4##05##�0######�6######
7##############################################################�7##�5##�5##openssl\
crypto\dh\dh_pmeth.c####dh_paramgen_generator###dh_paramgen_prime_len##############
#�7##P8##09##############�C######p9######@<######�:######################�=#######>
##########�>##p@##openssl\crypto\rsa\rsa_pmeth.c##rsa_keygen_pubexp###rsa_keygen_bi
ts#rsa_pss_saltlen#x931####oeap####sslv23##rsa_padding_mode####openssl\crypto\engin
e\tb_pkmeth.c###OpenSSL DSA method##openssl\crypto\dsa\dsa_ossl.c#######OpenSSL
HMAC
method#####W###W#######l��#�G�#############################��)#####################
########�L##�L##�L##0M##openssl\crypto\hmac\hm_ameth.c##OpenSSL EC
algorithm####�###�#######|��#PH�#0P##`N## Q##�X##pQ##0S##�X##�T##�T##
X##�X##�T###U##`U##�X##�U##�d###Y##`Y##openssl\crypto\ec\ec_ameth.c####pub:
###priv:###%s: (%d bit)
###ECDSA-Parameters####Public-Key##Private-
Key#####B###t######################################################################
#####################C###t#########################################################
##################################F###t############################################
###############################################q###t###############################
############################################################t###t#######,e�#�G�#�Y#
#�Z##�`##�c##�[## ^##�c##0_##P_##0c##�c##p_##�_##P`##�c##�`##�d##
d##pd##openssl\crypto\dsa\dsa_ameth.c##G: ###Q: ###P: ###DSA-
Parameters##OpenSSL PKCS#3 DH method####################���#`K�#`e##�f##�m##
n##�g##�h##@n##`l##�l##�i###j##pm##�l##�l###n##@e##############openssl\crypto\dh\dh
_ameth.c####recommended-private-length: %d bits
####generator:##prime:##public-key:#private-key:####PKCS#3 DH Parameters####PKCS#3
DH Public-Key####PKCS#3 DH Private-Key###OpenSSL RSA
method##################pe�#�L�#�n##`n##@o##Pt##�p###p##pt##�p###q#################
#########0q##�t##�o##�o############################################################
######################################openssl\crypto\rsa\rsa_ameth.c##coefficient:#
###exponent2:##exponent1:##prime2:#prime1:#privateExponent:####Exponent:###Modulus:
####Public-Key: (%d bit)
###publicExponent:#modulus:####Private-Key: (%d bit)
##openssl\crypto\engine\tb_asnmth.c###openssl\crypto\pkcs12\p12_decr.c####openssl\c
rypto\rsa\rsa_none.c###openssl\crypto\rsa\rsa_ssl.c####openssl\crypto\rsa\rsa_oaep.
c###openssl\crypto\rsa\rsa_pk1.c####openssl\crypto\rsa\rsa_x931.c###openssl\crypto\
bn\bn_div.c##openssl\crypto\bn\bn_mod.c##openssl\crypto\pkcs7\pk7_doit.c#openssl\cr
ypto\pkcs7\pk7_lib.c##�###��##к###�##P�##p�##��###�##0�##�###�## �
#P�
#��
#########@�##�##��##��##��##p�###�## �##@�
#��##��##p�##p�##�3
#�5
#�5
#��##��###�##############openssl\crypto\ec\ec2_smpl.c####Module32Next####Module32Fi
rst###Thread32Next####Thread32First###Process32Next###Process32First##Heap32ListNex
t##Heap32ListFirst#Heap32Next##Heap32First#CloseToolhelp32Snapshot#GetQueueStatus##
GetCursorInfo###GetForegroundWindow#####I#n#t#e#l# #H#a#r#d#w#a#r#e#
#C#r#y#p#t#o#g#r#a#p#h#i#c# #S#e#r#v#i#c#e#
#P#r#o#v#i#d#e#r###CryptReleaseContext#CryptGenRandom##CryptAcquireContextW####L#a#
n#m#a#n#S#e#r#v#e#r##############�F@L#a#n#m#a#n#W#o#r#k#s#t#a#t#i#o#n###NetApiBuffe
rFree####NetStatisticsGet####N#E#T#A#P#I#3#2#.#D#L#L#####openssl\ssl\t1_enc.c####ch
unk >= 0##key expansion###IV block####client write key####server write
key################n >= 0##t > 0###t >= 0##master
secret###openssl\ssl\t1_reneg.c##!expected_len || s->s3-
>previous_server_finished_len####!expected_len || s->s3-
>previous_client_finished_len####openssl\crypto\ec\ec_mult.c#ECDH part of OpenSSL
1.0.0f 4 Jan 2012##openssl\crypto\ecdh\ech_lib.c###ECDSA part of OpenSSL 1.0.0f 4
Jan
2012#openssl\crypto\ecdsa\ecs_lib.c##ECDSA_SIG###############���
 #�###############$8
�#�###########LT�#############@T�#�ccƄ||�ww�{{����kkֱoo�T�őP00`####�gg�}++V#���b�‫׵‬櫫
M�vv�E�ʏ���#@�ɉ�}}�#����YY��GG�#���쭭 Ag�Գ�_꯯E���#�S�rr�[��·�u#��ᮓ�=j&&LZ66lA??
~#���O�̃
\44h Q4
� ��� # ���
qq s ‫ث‬S11b?##*
� �
###R�Ǖe##F^�Ý(##0���7###
���/ ###6##$���#=���&���i''NͲ�� �uu�#
 #���#t,,X.##4-
##6�nn��ZZ��[�RR�M;;va�ַγ�}{))R>���q//^���#�SS�h�ѹ####,���` @#���ȱ�y�[[��jj�F�ˍ
‫�پ‬gK99r�JJ��LL��XX�J�υk�л*���媪 O#����CC��MM�U33f���#�EE�#���####����
 PP �D<<x�� %㨨
K�QQ����]�@@����#���?���!H88p#���߼�c��wu�‫گ‬c!!B0## #���#���m�ҿL�́
#
�‫ܣ‬f""D~**T���;���
#5##&/����__����5�DD�9##.W�ē�U�~~�G==z�dd��]]�+##2�ss�``���#�OO��
#�FF�)���Ӹ�k<##(y�ާ�^^�####v�ۭ;���V22dN::t#

#�II�
##
l$$H�\\�]�Ÿn�ӽ‫שּׁ‬C�bbĨ��9���17��Ӌyy�2���C�ȋY77n�mm‫��ڌ‬#d�ձ�NN�੩ I�ll��VV�#���
%��ϯeeʎzz�鮮 G####պ�o�xx�o%%Jr..\$##8�WǴ�sQ�Ɨ#���|�‫�ݡ‬tt�!##>�KK�ܽ��a���
���#�pp�B>>|ĵ�q�ff��HH�#####���####�aa�_55j�WW�й�i���#X��'##:���'8���#��볘
�+3##"�ii�p�٩���#���3���-"##<���# ���I�·�UU�x((Pz�ߥ���#�Y��� ##
‫�ڿ‬e1����BB��hh��AA����)w--Z####˰�{�TT�ֻ�m:##,ccƥ||�ww�{{���kkֽoo‫�ޱ‬őT00`P####ggΩ+
+V}���#�‫׵‬b��M�vv��ʏE��#��ɉ@}}����#YY��GG�����#��A��Գg��_�Eꜜ#���S�rr���[��u����#��=�
&&Lj66lZ??~A���#�̃
O44h\ ��
Q ����4 ��� ‫ث‬s11bS##*?###
#qq ��
�ǕR##Fe�Ý^##0(��7�##
#��/�### ##$6��#����=���&''Ni����
 uu� ##��#�,,Xt##4.##6-
nnܲZZ�[�RR��;;vM�ַa��}�))R{���>//^q��#�SS���ѹh####���,
@`���#��y�[[��jjԾ�ˍF��g�99rKJJ��LL��XX���υJ�лk���*��O����#CC��MM��33fU��#�EE�����##
###��PP��<<xD��%���K�QQ��]�@@���#���?���!�88pH���#��c߶�w��‫گ‬u!!Bc##
0���#���#�ҿm�́
L
####&5���/__�ᗗ5�DD��##.9�ēW��U�~~�==zGddȬ]]��##2+ss�``���#�OO���‫""ܣ‬Df**T~��;���#�
FF�����)��k�##(<�ާy^^��####�ۭv���;22dV::tN

##II��##
$$Hl\\���Ÿ]�ӽn��C�bbĦ��9���1����7yy����2�ȋC77nYmm‫��ڷ‬#��ձdNN�ҩ�I�ll‫ش‬VV�����#���
%eeʯzz􎮮G�####��o�xx�%%Jo..\r##8$��W�s��ƗQ���#�‫|ݡ‬tt�##>!KK�‫�ݽ‬a‫����܋‬#�pp�>>|
B��q�ff̪
HH ��
#### ���#####aa£55j_WW ��
iІ # X##:' ��
� ��� ' ����
8 ���
# ��
+ ##"3ii
� ٩p��#���3���-
һ�
�##<"��#���� �·IUU��((Px�ߥz��#���Y� �##��e����1BB��hhиAA�Ù�)�--
Zw####��{�TT��m�##,:cƥc|�|w�w{�{��kֽko‫ޱ‬oőT�0`P0####gΩg+V}+��#�‫׵‬b
‫׫‬M�v�vʏEʂ#��ɉ@�}�}��#�Y��YG��G��#�A�ԳgԢ_�E ꯜ#���S�r�r�[�u·��#�=��&Lj&6lZ6?~A?
��#�̃
O �
4h\4 �
Q ���4 ���
# �
q �‫ث‬s
q �1bS1#*?###
#ǕR�#Fe#Ý^�#0(#�7��#
##�/��## ##$6#�#����=���&�'Ni'�Ͳu�u ## �#��,Xt,#4.##6-
#nܲnZ��Z�[�R��R;vM;ַaֳ}γ)R{)��>�/^q/�#��S��Sѹh�####��,� @` ��#�yȱ[��[jԾjˍF˾g ‫پ‬
9rK9J��JL��LX��XυJ�лk���*�O���#�C��CM��M3fU3�#��E��E��#�####��P��P<xD<�
%���K�Q��Q�]��@��@�#���?���!��8pH8��#�c߼�w�‫گ‬u�!Bc!# 0#��#���#�ҿm�́ L �
##
#&5#��/�_��_�5��D��D#.9#ēWħU�~�~=zG=dȬd]��]#2+#s�s`�`�#��O��O‫"�ܣ‬Df"*T~*�;���#��F�
�F��)�kӸ#(<#ާy�^��^####ۭv���;�2dV2:tN:
##
I��I#
#$Hl$\��\Ÿ]�ӽnӬC�bĦb�9���1����7�y�y��2�ȋC�7nY7m‫ڷ‬m�#��ձd�N��N�I�l‫ش‬lV��V��#���
%�eʯez�z�G�####�oպx�x%Jo%.\r.#8$#�W�sǴƗQ���#�‫�|ݡ‬t�t#>!#K��K�aܽ����#��p�p>|
B>�qĵf̪
fH ��
H#### ��# ####a£a5j_5W
� W iй
�� � # X #:'#
� ��� � ' 8 ���
� ���� # + #"3#i i
� �� һ٩pَ#���3���-
��#<"#�#���� �·I�U��U(Px(ߥzߌ#���Y� ��##�e1��‫�ڿ‬B��BhиhA��A�)��-Zw-
####�{˰T��T�mֻ#,:#ƥcc�||�ww�{{���ֽkk‫ޱ‬oo�T��`P00####ΩggV}++�#���b��M 櫫
�vv�E��#����@���}}�#���YY��GG�#��A 쭭�g��_�E꯯#���S��rr�[��u·��#��=���Lj&&lZ66~A??
�#��O��h\44Q��4���#���qq�s��bS11*?###
##�R��Fe##�^��0(##7���
###/���# ##$6###����=���&��Ni''Ͳ��uu## #���Xt,,4.##6-
##ܲnn��ZZ[��RRvM;;�a��}γ�R{))�>��^q//#�����SS�h��####�,��@` �#��yȱ���[[Ծjj�F��g
‫�پ‬rK99��JJ��LL��XX�J�ϻk���*��O 媪�#���CC��MMfU33#�����EE�#��####�����
 PPxD<<% �� K 㨨
��QQ]�����@@#���?���!���pH88�#��c߼�w���u��Bc!! 0##�#���#��m�ҁL��##
&5##�/���__5�����DD.9##�W��U��~~zG==Ȭdd��]]2+##�ss�``#�����OO���Df""T~**;���#����
�FF�)��kӸ�(<##�y�޼�^^####�v���;��dV22tN::##

��II
##Hl$$��\\�]�½n��C‫שּׁ‬Ħbb9���1����7���yy�2��C��nY77‫ڷ‬mm#����d�՜�NNI ੩‫ش‬ll��VV�#���
%��ʯee�zzG 鮮####oպ��xxJo%%\r..8$##W�sǴ��Q���#��|���tt>!##��KKaܽ����#����pp|
B>>qĵ�̪
ff ��
HH#### # ####£aaj_55 ��
� �� WWiй # X ��
� ���� :'##' ����
8 ���
# ��
+ ���
"3## ii
һ p # ���
� �� 3 �
��-���<"###���� ��I�Ϊ�UUPx((�z��#���Y� ���##e1��‫���ڿ‬BBиhh��AA)���Zw--
####{˰���TTmֻ�,:##P��QSeA~ä##�^':�k�;�E�#�X�#�KU�0 �mv��v̈
%L#����O��*ŀD5&��b�IZ��g#�
%�#�E��]#u/�#�L���F����k�_�#���#�zm��YR�-����!tX)i�ID�Ɏj��uxy��k>X��q�'�O�#���f�
ɴ:�}#J�c�1#�`3Q�ESb �wd���k�#����+#�XhHp#�E��l ‫{��ޔ‬R#�s��#KrW�#�*�Uf#(�#µ/�{ņ�#7��
(0���#�j##\�#�+#ϊ��y���#��iN���eվ###b4ъ��ĝS.4�U�2�#u��9�#��`@#�q^Q#n��!>=#
‫�ݖ‬#>�F��M��T�#]�qo�##�#P`$�#����C@�w��g�B 谈��#8[#����yG
|��#B|�#��####��� H�+2�p##NrZl�#�V8�##ծ='9-6d�#
!�\h�T[�:.6$�g
#�W�Җ��#O��� �aiKwZ####
����*��C�"<##### #�Nj򹨶-ȩ##�#�WL#u��
‫&��`��ݙ‬#��r\�;fD4~�[v)C���#�h��c����1�#�cB@"�# #Ƅ}$J��=��#2�m�)�K/�#�0���R�
���wl#�+��p��H�#"d�GČ�#?��,}V�3"�NI���8��ʌ6#Ԙρ�(�z�&��‫�?��ڤ‬:,
�xP��_jbF~T�#���ؐ^�9.�Â��]�|��i�-�o�#%�;��ȧ}##nc��{�;� x&��#Yn#��쨚 O�en��~��#ϼ!
��#�ٛ��6oJ� ���|�)���11#?*0����f�57�Nt�ʂ�А�#3‫ا‬J�#����A#P�
/�#��MvM��CTM���#���ў#�jL�#,�QeF#�^�]5�#st��.A#�Z#g�R�3‫ے‬V#�#G�m�a‫ך‬z
�7�#�Y�<#��'��5�a���#�<�GzY�Ҝ?s�Uy�##�7�s���S[��_#o=߆�Dx���>�h�,4$8_@��r�##
%⼋I<(A��q#�9޳
#��ؐ�Vda��{p�2�t\lHBW�Ч�QPeA~S�##�^':�k�;�E�#�X�#�K��0 Umv��v̈
�L#�
%��O��*��D5&��b��Z��I#�%g#�E��]�u/�#�L�#�F����k�_�#眒#�zm��YR�‫��ڃ‬-!
tX�i�I)�ɎD��ujy��x>X�kq�'�Oᾶ���#� �f:�}�J�c#1#�3Q�`SbEwd��k�����#+#�hHpX�E�#l
‫{��ޔ‬R��s�##Kr�#�W�Uf*(�#µ/#{ņ�#7ӥ�(0�#�j##��#�\#ϊ+�y���#���iN���e;##�b4�#��ĊS.4�U�
�#2��u�#9�`@��q^##n�Q�!>�#‫>ݮ‬#=‫��ݖ‬MF�T��]�q#�##o#P`��#$�֗C@�̞�gwB 谽��#�[#�8��y�
|�G#B|�#���####�� ��+2Hp##�rZlN�#��8�#Vծ=#9-6'�#
d�\h!T[��.6$:g
��W�#��ґ�#���O �a�KwZi####���
*����"<C#### ##Nj򭨶-��##�#�W�#u�L
‫&��`�ݙ‬#��r\�;fD�~�[4)C�v�#����h��c�1�ʅcB#"�#@#Ƅ $J�}=���2�#�)�m/�#K0���R�
���w�#�+l�p��H�#�d�G"���?�#,}Vؐ3"�NI���8��ʌ�#Ԙ6����z�(���&��?��:,�xP
�_j�F~Tb#��¸ؐ��9.^�Â�]����i|-�o�#%ϳ���;}##�c��n�;�{x&� #Yn��#�O��n��e��~ϼ!
#�#����6oJ� ���|�)ֲ�1�#?*1���0f�5�Nt7ʂ�А�3‫ا‬#�#�J��A�P�#�#/�Mv���CMM��T#��
ߵў�jL##,�QeF�^�#5�#]t��sA#�.#g�Z�‫ے‬RV#�3G�m#a‫�ך‬
�7z#�Y�<#�'����a�5�#��Gz<�ҜYs�U?�##y7�s���S��_[o=�#�Dx��ʁ�h�>4$8,@��_�##r%�
I<(���A#�9q�
�Vd���{a�2�p\lHtW��B�QP�A~Se##ä':�^�;�k�#�E�X�K�#0 U�v��m̈
#��‫؜‬ �v#�
%L�O��*���5&�Db�����IZ�%g#�E�#�]��/�#uL�#�F����k��#�_�#��m��zR��Y��-�tX�!
�I)iɎD��uj���xyX�k>�'�qᾶO��#� �f��}�:�c#J#�1Q�`3SbEd��wk�����#�#�+HpXhE�#�
‫�ޔ‬l{R��s�#�Kr�##�W�Uf*��#(�/#�ņ�{7ӥ#(0�#��##�j#�\�ϊ+#y���#���iN���e��##վ4�#b�Ċ�.4�
S�U�#2��u�#9�`@��q^#�n�Q#!>�‫>ݮ‬#=‫ݖ‬#�MF�T����q#]##o�P`�#�#$�֗�@��C�gw�谽
B�#��#�8[�y��|�G
B|�#���#####� ��+2H�##�pZlNr#���#V8�=#�-6'9#
d�\h!�[��T6$:.
�gW�#��Җ�#���O��a� wZiK####��
����*"<C�#### ##��Ƕ-
��##ȩ�W�#u�L#�����
�`# �&r\�fD �;�[4~C�v)#����h��c�1���cB#��#@"Ƅ #J�}
$���=�#2)�m��#K/���0��R�w��+l#p����#�H�G"d�Č�#?}V�,3"�I��N8���ʌ��Ԙ6#�ρz�(޷�&��?
��:,�xP�_j��~TbF���#ؐ�9.^�Â�]����i|��o�-%ϳ#��;�##�}��nc;�{�&�
xYn�#��#�O�����en��~�!#�#����ٛoJ�6��� �)�|�1��?
*1#��0��5�fNt7���ʐ�Ч3#�#�J��A���#P�#/�Mv���CM���TM���#ў�jL#�,�#eFQ^�#�#]5��st#�.A
g�Z#‫ے‬R�#�3V�m#G‫�ך‬a�7z
�Y�##�<���'a�5�#���Gz<�ҜY��U?s##y��s�7�S���_[�=�#oDx�‫ۯ‬ʁ�h�>�$8,4��_@##r��
%<(�I�A��9q#
#�
‫�޳ ؜‬Vd���{a�2�p�lHt\��BWQP��~SeA#ä#:�^';�k�#�E���X�K�#� U�0��mv��v��
%L#O������*&�D5���b�IZ�%g#�E�#�]���#u/�#�L���Fk���#�_�#�����zm��YR�-��X�!
tI)i�D��uj���xy��k>X'�q���O��#���f� }
�:�c#J��1#�`3QbES��wd���k�#���+#pXhH�#�E��l�R��{�#�sr�#K�W�#f*�U�#(�/#µ��{�ӥ#70�(#
���#�j#�\�#�+#ϧ��y���#N��ie���#վ#�#b4Ċ��4�S.��U�#2 ኤ u��#9�@��`^#�q�Q#n>�!�=#�‫ݮ‬#>MF�
摵�Tq#]�#o�#`�#P#$�֗齉�C@gw�ٰ�B�#����8[#y��ȡG
||�#B��#�#### ���2H�+#�p#lNrZ��##V8�=#ծ6'9-
d�#h!�\��T[$:.6
�g
�#�W�Җ�#����O��a� �ZiKw####�
����*�<C�"###### �Nj-���#ȩ#W�#�L#u�
‫&�`��ݙ‬#\��rD�;f[4~�v)C���#�h��c�����1B#�c#@"�� #ƅ}$J��=��#2��m�)#K/���0�
�R�w���+l#����p#�H�G"d�Č�#?�V�,}"�3��NI���8���ʘ6#Ԧρ�(�z�&��?���,�:P
�xj��_TbF~��#����.^�9��ß��]i|��o�-�ϳ#%�;��#�}#�nc��{�;� x&n�#Y�#�����O�en��~�!
#ϼ���#�ٛ�J�6o�� �)�|�1���*1#?�0��5�f�t7�N�ʂ�А3#
‫�ا‬J�#A���#P�#/�v��MCM���TM���#����L#�j�#,FQe�#�^#]5��st��.A#�Z#g�R���3V#m#G֚�a�7z
�Y�#��<#��'��5�a���#z<�G�Y��U?s�#y�#s�7�S���_[���#o=x��Dʁ�>�h8,4$�_@�#r�#�
%�(�I<�A�9q#�#޳

‫ ؜‬d��V{a���p�2Ht\l�BW�R j�06�8�@������|
�9��/��4�CD����T{�2��#=�L�#B��N#.�f(�$�v[�Im��%r��d�h�#Ԥ\�]e��lpHP���^#FW�����
‫ث‬#���
��X#��E#�,#��?##��###�k:�#AOg�������s��t"�5���7�#u�nG�#q#)ʼno�b#�#�#�V>K��y ���x�Z�#
1�#�3‫�ݨ‬##Y'��_`Q�#�J-�z��ɜ��;M�*���<�S�a#+#~�w�&�i#cU!
}#######################
###@###�#######6openssl\crypto\x509v3\pcy_tree.c###################################
#####c###c###
###########;###;###
###;###%04d%02d%02d%02d%02d
%02dZ###openssl\crypto\asn1\a_gentm.c###################################c###
###########;###;###
###;###%02d%02d%02d%02d%02d
%02dZ###openssl\crypto\asn1\a_utctm.c###PBEPARAM################���#�]#############
#���#�\##########�v�#############�v�#openssl\crypto\pkcs12\p12_key.c#X#######�\####
##############��##########################�#######�\##################��###########
###############�#######�\##################��##�:

#####################POLICY_MAPPINGS#POLICY_MAPPING##subjectDomainPolicy#issuerDoma
inPolicy##�#######�: ######################### ; #�;

#########################(x�#�^###############x�#�^##########tx�##############x�###
##########�w�#�:

#####�����x�#############�w�#openssl\crypto\x509v3\v3_pmaps.c####�#######0�########
##########################P= #�C #####%*sPolicy Text: %s
#%*sPolicy Language: ####infinite####%*sPath Length Constraint:
#text:###hex:####openssl\crypto\x509v3\v3_pci.c##o#######�5########################
########## F #########r#######�^################################## G
#########�#######�^################################## G
#########�#######�^##################################`G
#########n###########�G #pH #�G #�G #################�H
#########q#######p^######################�H
#########��'#########s#######�5##################################�H
#########%*scrlTime: ####%*scrlNum: #%*scrlUrl:
#openssl\crypto\x509v3\v3_ocsp.c#
%*s####%*sIssuer: #EXTENDED_KEY_USAGE##~#######�I #########################�I
#`J #############p#######�I #########################�I #`J
#########################�{�#�^######����0|
�#############�{�#openssl\crypto\x509v3\v3_extku.c####SXNET###ids#SXNETID#zone####�
#######PK ##############################N #`K #####################�|
�#�\##############�#�#�]##########�|�#############�|
�#############d��#�\##############�|�#@K ##########}�#############�|�#
%*sZone: %s, User: ####%*sVersion: %ld (0x
%lX)#openssl\crypto\x509v3\v3_sxnet.c####removeFromCRL###Remove From
CRL#unspecified#Unspecified#�#######@]##################�N
#####################p�##Z########�##########################�N #pO
#############openssl\crypto\x509v3\v3_akey.c#PKEY_USAGE_PERIOD###T#######pR
#################################�R
#########�###########���#�^##�###########���#�^##########�~�#############|
~�#Not After: #Not Before: ####decipherOnly####Decipher
Only###encipherOnly####Encipher Only###cRLSign#CRL Sign####keyCertSign#Certificate
Sign####keyAgreement####Key Agreement###dataEncipherment####Data
Encipherment###keyEncipherment#Key Encipherment####nonRepudiation##Non
Repudiation#digitalSignature####Digital Signature###objCA###Object Signing
CA###emailCA#S/MIME CA###sslCA###SSL CA##reserved####objsign#Object
Signing##G#######�]###########################S #PS
#########��##S#######�]###########################S #PS

#########h�##openssl\crypto\x509v3\v3_bitst.c####R#######�]##################�T
#�U

#####################openssl\crypto\x509v3\v3_skey.c#hash####H#######�^############
######�V #PW #####################I#######�^##################�V #PW
#####################J#######�^##################�V #PW
#####################K#######�^##################�V #PW
#####################L#######�^##################�V #PW
#####################M#######�^##################�V #PW
#####################N#######�^##################�V #PW

#####################����####################################################openss
l\crypto\x509v3\v3_ia5.c##openssl\crypto\asn1\a_bool.c####openssl\crypto\conf\conf_
mod.c##
#######@####(##################################�####(##############�####(##########
####@####(##############@####(######0#######�###########1#######����#(######6######
#����#(######7#######����#(######c########�###(######d########�###(######e########�
###(######i#######@###########�###��������########�########�###(######�###��������#
#######�#######����########�###��������########openssl\crypto\bn\bn_recp.c#RIPE-
MD160 part of OpenSSL 1.0.0f 4 Jan 2012####SHA part of OpenSSL 1.0.0f 4 Jan
2012###MD4 part of OpenSSL 1.0.0f 4 Jan 2012###l###############
###�� #�� #####�####K##�J##########n###################�� # �
#####�####K##�J##########o###############
###�� #� #####�####K##�J##########m############### ###�� #��
#####�####K##�J##########[###############
###� #� #####H####K##�J##########]###################� #`�
#####H####K##�J##########^###############
###� #0� #####H####K##�J##########\############### ###� #С
#####H####K##�J##########P###################0� #��
#####�####K##�J##########RC2 part of OpenSSL 1.0.0f 4 Jan 2012#######�x��#
‫��(�ݵ‬yJ�7~�‫�؝‬+vS�bLd�D��#�Y�O#aEm� �}2��@놷
{#�!"\kN�T�e��`�#sV�#����#u�#;���B=�0�<�&o�#�Fi#W'�#���C#�#���>�#��/�f#�#��‫ހ‬R��r�5M
j*�#�qZ#ItK��^##����An#Q��$��P��p9�|:�#��z�#6[%U�1-]�㊒�#�)#gl���#��ឨ,c##?X≩
84#�3���H
_���.���G 奜 w
� h��
�RC4 part of OpenSSL 1.0.0f 4 Jan
2012###############################################################################
###################################################################################
###################################################################################
###############�#@#####�#####@###@#�###�#@#�###�#####@#####�#@#####�#@###@#########
�#@###@#�###�#####@#########�#@#�###�#@###@###@#####�###�#@#####�#@#�#@#�###�#@####
###@#######@#�#########@#�#####@#�###�#@#�#@#�#########@#####�#@#�#####@###@#####�#
##�#@#�#@#######@#�################################################################
###################################################################################
###################################################################################
##############################@###########@#######@#######@###@###################@
###@#######@###@###########@#######@###############@###@#######@###@###@###@#######
@#######@###########@###############@#######@###@###########@###@###@###@##########
#@###@###@###@###################@############# ### ####### ########### ### #######
### ################### ### ####### ####### ### ### ### ### ########### ###########
### ########### ### ############### ####### ########### ### ########### ### #######
########### ####### ### ### ####### ###@##�@# ###### �@# ## ##@ #�## #@ ##@ �#
####�# #�@##�## �@ ### #@ #�@# �##### ##@#### �@# �@ �## �###�@ ##@#### #@ ##
#�@ #####�# #�@ ## �@# ###### #�###�# ##@# �## #@# #@ �# #@###@ �# ### #@
#�@##�## �@ ###### ##@##�@ #�# �## �@ ##@###@#
�#@###############B###@###B###################@#######B###@###########@###@###B####
###########B###@###B###B#######B###@###########B###@###@#######@###########@#######
B###B###################################B#######@###B#######B#######@###B#######B##
#@###@##�#� ##� �########## �#�###� �#� �###### ##�#�###�#�#�## �## ##�
####�#�#�#�#### �#� �## ######�#### ##�#�## �#� ##�#######� �#####�#####�## �#�
�###### ######�#�#� �## ### �#�###� �###�#�#### �#� ##�###� �## ##�#�###�## ##�
�#####� �#�######## �#� ####�#�############################### ##%
%&&))**,,//1122447788;;==>>@@CCEEFFIIJJLLOOQQRRTTWWXX[[]]^^aabbddgghhkkmmnnppssuuvv
yyzz||
�����������������������������������������������������������������������������������
��������������������������������������������########��������########��������#�#�#�#
��#�#�#�##�#�#�#��#�#�#�##�#�#�#��#�#�#�##�#�#�#��#�#�#�#################���������#
########## ### ########### ### ########### ### ########### ### ###0### ## 0##
###0### ## 0## ###0### ## 0## ###0### ## 0## ########### ### ## ### ###
## ########### ### ## ### ### ## ###0### ## 0## # #0# # #
0# ###0### ## 0## # #0# # # 0# ######### ### #### ### ## ##
########## ### #### ### ## ## ##########$###$#### ### ##$ ##$ ##########$###$####
### ##$ ##$ ########## ### #### ### ## ## ########## ### #### ### ## ##
##########$###$#### ### ##$ ##$ ##########$###$#### ### ##$ ##$
###################################################################################
################################################################# ### ###
### ################### ### ### ### ################### ###
### ### ################### ### ### ###

###################################################################################
###################################################################################
###################################################################################
########################################## ###0### ###0### ###0###
###0################################### ###0### ###0### ###0###
###0################################### ###0### ###0### ###0###
###0################################### ###0### ###0### ###0###
###0######################################################################## ###
########### ### ########### ### ########### ### ##########
#######
#######
#######
#######
#######
#######
#######
#######
### ##
#######
### ##
#######
### ##
#######
### ##
################################################################## ### ###(###(###
### ###(###(### ### ###(###(### ###
###(###(################################################################### ###
###(###(### ### ###(###(### ### ###(###(### ###
###(###(################################## ### ### ### ### ### ### ### ## ### ###
### ###"###"###"###"### ## ## ## ##" ##" ##" ##"
###################################(###(###(###(###(###(###(###(## ### ### ###
###"###"###"###"### (## (## (##
(##"(##"(##"(##"(##################################################################
libdes part of OpenSSL 1.0.0f 4 Jan 2012####DES part of OpenSSL 1.0.0f 4 Jan
2012###idx#ssl/certs###ssl/cert.pem####SSL_CERT_DIR####SSL_CERT_FILE###openssl\cryp
to\asn1\x_info.c####openssl\crypto\pem\pem_info.c###FORM####BITWRAP#SETWRAP#SEQWRAP
#OCTWRAP#IMPLICIT####IMP#EXPLICIT####SEQ#NUMERIC#GENSTR##GeneralString###TELETEXSTR
ING###T61#PRINTABLE###VISIBLE#UTF8String##IA5#UNIV####BITSTRING###BITSTR##OCTETSTRI
NG#OCT#GENTIME#OID#ENUM####INT#BOOL####���##########��#########P��#########|
��##########��#########t��#####
###���#
###
###p��#########XS�#########,��#########8��##########��#########h��#########d��#####
####X��#########P��#########D��# ################��8#########��<#########�‫܂‬
4��# #######�#�#####
###,��#
###
###T9�#########�# #######��########$��#########\��##########��#
########��#########P��# ########��########��#
#######��#########��#########l��########PH�#########��#########|
��#########���#########ԛ�#########Л�#########ě�#########���#########���#########���
#########���#########���##########

�#########Char=###openssl\crypto\asn1\asn1_gen.c##BITLIST#HEX#tag=####string=#CONF
part of OpenSSL 1.0.0f 4 Jan 2012##openssl\crypto\conf\conf_lib.c##group=##
name=##openssl\crypto\evp\pmeth_gn.c###########openssl\crypto\rsa\rsa_pss.c####open
ssl\crypto\rsa\rsa_gen.c####openssl\crypto\bn\bn_exp2.c#Generator
(hybrid):#Generator (uncompressed):###Generator
(compressed):#openssl\crypto\ec\eck_prn.c#Seed:###Cofactor: ##Order: #B: ###A:
###Prime:##Polynomial:#Basis Type: %s
#Field Type: %s
#ASN1 OID: %s####%s %s%lu (%s0x%lx)
#%s 0
###openssl\crypto\ec\ec_print.c####message
digest##cipher##openssl\crypto\evp\bio_enc.c####openssl\crypto\evp\m_sigver.c###ope
nssl\crypto\pkcs7\pk7_attr.c#openssl\crypto\ec\ec2_mult.c##########################
##############@###A###D###E###P###Q###T###U###openssl\crypto\bn\bn_gf2m.c#####�####
G
#0G
#�G
#�G
#�H
#��
#��
##�
#��
##�## �
#P�
#��
#��
#@�
#`�
#��
#P�
#��
#��
##�
##�
##�
#@�
#P�
#��
#0�
# �
#############�I
#@J
#####�J
#�J
#0K
#openssl\crypto\ec\ecp_mont.c####�###��
#к##��
#�K
#�K
#��
#��
##�
#��
##�## �
#P�
#��
#��
#@�
#`�
#��
#P�
#��
#��
##�
##�
##�
#@�
#P�
#��
#0�
# �
##############M
#�M
#################openssl\crypto\ec\ecp_nist.c####OpenSSL ECDH
method#openssl\crypto\ecdh\ech_ossl.c######OpenSSL ECDSA
method####openssl\crypto\ecdsa\ecs_ossl.c#####openssl\crypto\x509v3\pcy_node.c####\
########`#�x0�##`#�x0�##�##�F&##�##�F&��?�~���?�~����#o�����#o��&�L�#ˇ�&�L�#˸�
‫�ڸ‬bm#��‫�ڸ‬bm######## ####### OO!OBn�OO!OBn�
66�6��l�66�6��l�����Y#Q�����Y#Q���o�޽�
��o�޽�
�����#�#�����#�#yy�y��yy�y��oo�o_��0oo�o_��0��~���?m��~���?
mRRUR�#��RRUR�#��``�`'��G``�`'��G��ʼ�ve5��ʼ�ve5��V���+7��V���+7��#�#�#���#�#�#�����
q#[ң���q#[�
0
`<#l
0
`<#l{{�{���{{�{���55�5��j�55�5��j�##t#�i:�##t#�i:����SG‫���ݳ‬SG‫��!��{��!��{��ݳ‬/�^활�
�/�^활..�.m�\C..�.m�\CKK1Kbz�)KK1Kbz�)����!�]����!
�]WWAW�#��WWAW�#��##T#�A*�##T#�A*�ww�w����ww�w����77�7��n�77�7��n����{V‫{���מ‬V‫��מ‬
F���##��F���##�����#�#�����#�#JJ5Jj� JJ5Jj� ��O‫��ڞ‬D��O‫��ڞ‬DXX}X�%��XX}X�
%����#�#ʏ���#�#ʏ�))�)U�R|))�)U�R|

(
P"#Z

(
P"#Z�����OP�����OP����i#]ɠ���i#]�kk�k��#kk�k��#��.�\�#‫ٽ‬#�\�.�‫�م‬ν�sg<��ν�sg<]
]i]�4��]]i]�4��##@#�P �##@#�P ������#�#�����#�#��#�#����#�#��>>�>��|�>>�>��|�####(#
-####(#
-
gg�g#��xgg�g#��x���sS՗���sS՗''�'%�N#''�'%�N#AA#A2X�sAA#A2X�s��#�,�#���#�,�#�����Q#S
��Q#S�}}�}ϔ�}}�}ϔ�n���7I��n���7I��G؎��V��G؎��V����0�p����0�p���#q�����#q��||�|
Ǒ�||�|Ǒ�ff�f#��qff�f#��q��S‫��{��ݦ‬S‫{��ݦ‬##\#�K.�##\#�K.�GG#G#F�EGG#G#F�E��B���!
#��B���!#��#�#ʼn���#�#ʼn�--�-u�ZX--�-u�ZX��ƿ�yc.��ƿ�yc.####8##?####8##?
����##G�����##G�ZZuZ�/��ZZuZ�/����6�l�#6�l�#�33�3��f�33�3��f�cc�c?��\cc�c?��\#####
#######
##����98I�����98I�qq�q����qq�q������#�#ύ���#�#ύ�##d#�}2�##d#�}2�II9Irp�;II9Irp�;��C
‫��_��ن‬C1�#�����1�#�����_��‫���ن‬KHۨ���KHۨ[[q[�*��[[q[�*����#�4����#�4�
���R���)>��R���)>&&�&-�L#&&�&-
�L#22�2��d�22�2��d�����J}Y����J}Y���#j�����#j��##<#x3#w##<#x3#w��s�榷 3��s�榷
3��:�t�#�:�t�#�¾�|a'��¾�|a'��#�&�44�‫�&އ‬#���‫އ‬
4��h�44�4��h�HH=Hzu�2HH=Hzu�2����$�T����$�Tzz�z��zz�z�􍐐z���=d��z���=d__a_�>��__a_�>
�� � #�@= �
#�@=hh�hg��#hh�hg��###h#�r4�##h#�r4ʮ���#,A�����#,A�����^u}����^u}TTMT�#��TTMT�#�Γ�v
���;��v���;""�"�D/""�"
�D/dd�d#��cdd�d#��c�����#�*�����#�*ss�s����ss�s����##H#�Z$�##H#�Z$�@@#@:]�z@@#@:]�z
## #@(#H## #@(#H��+�V 蛕��+�V 蛕��
�3{�����3{����Kۖ��M��Kۖ��M����a#_����a#_��#�#�#���#�#�#�==�=��z�==�=��zȗ�f���3[��f�
ႂ 2�d�#悂
��3[################��#�6ԃ���#�6ԃ�++�+E�Vn++�+E�Vnvv�v����vv�v���
2�d�#������
�( �����(##l# �w6�##l#�w6õ�� [wt����[wt����#)C�����#)C�jj�jw��#jj�jw��#PP
]P���PP]P���EE E#L�WEE E#L�W�����#�8�����#�800�0��`�00�0��`����+t�����+t��??
�?��~�??�?
��~�UUIU�#��UUIU�#�Ǣ���y#Yۢ���y#Y����#e�����#e��ee�e#��jee�e#��j��Һ�hi#��Һ�hi#//�/
e�^J//�/e�^J��'�N 睎��'�N 睎��_޾_ � � `� �޾�
�`##p#�l8�##p#�l8�����.�F����.�FMM)MRd�#MM)MRd�#��r���9v��r���9vuu�u����uu�u����##
##0#
6####0#
6��#�$� ���#�$� �����@yK����@yK���cYх���cYх##8#p6#~##8#p6#~##|#�c>�##|
#�c>�bb�b7��Ubb�b7��U��w�:��w�:����)2M�����)2M���b���1R��b���1R����:�b����:�b��
3�f���3�f�%%�%5�J#%%�%5�J#YYyY� ��YYyY�
����*�T�#Є�*�T�#�rr�r����rr�r����99�9��r�99�9��r�LL-LZa�#LL-
LZa�#^^e^�;��^^e^�;��xx�x��xx�x��88�8��p�88�8��p 匌
�#�#���
�#�#���c�Ʋ�#��c�Ʋ�#����A#W 䥥��A#W����CM١���CM١aa�a/��Naa�a/��N����E{B����E{B!!�!
#�B4!!�!#�B4��J���%#��J���
%###x#�f<�##x#�f<�CC#C"R�aCC#C"R�a��;�v���;�v�����+�O����+�O#### ##$####
##$QQYQ�#��QQYQ�#�㙙^���/%��^���/%mm�mO��"mm�mO��"4h9#e4
h9#e����5�y����5�y��[߶��i��[߶��i~~�~‫�כ�~~�~כ‬$$�$=�H#$
$�$=�H#;;�;��v�;;�;��v�����1=K�����1=K���#�>с���#�>с�##D#�U"�##D#�U"���#�
�#���#�
�#�NN%NJk�#NN%NJk�#����Qsf����Qsf���#`�����#`��<<�<��x�<<�<��x��>�|�#�>�|
�#�j��5@��j��5@�����
�#�����
�#��޹�go#��޹�go###L#�_&�##L#�_&�,,�,}�XQ,,�,}�XQ��k�ָ�#��k�ָ�#���k\ӌ���k\ӌnn�nW��9
nn�nW��9��7�n���7�n�##
#######
#####VVEV�#��VVEV�#��DDD#I�^DDD#I�^�7!������ߞ���ߞ��ߞ 
O�����!
7O�**�*M�Tg**�*M�Tg��ֻ�mk
��ֻ�mk
��#�F⟇��#�F⟇SSQS�#��SSQS�#����W‫��ܮ‬r��W‫��ܮ‬r##,#X'#S##,#X'#S��N���'#��N���'#ll�lG�
�+ll�lG��+11�1��b�11�1��b�tt�t����tt�t�������� �#���� �#FF#F
C�LFF#F
C�L���� &E����� &E���#�<�#���#�<�#�##P#�D(�##P#�D(����[Bߺ���[B
ߺ##X#�N,�##X#�N,�::�:��t�::�:��t�ii�io��#ii�io��# $ H-#A $
H-#App�p����pp�p���‫���׶‬Tqo����Tqo��g�η�#��g�η�#���;~�����;~����#�.
‫ۅ‬.�#���‫�ۅ‬BB#B*W�hBB#B*W�h��Z���-,��Z���-,����I#U���I#U�((�(]�Pu((�(]�Pu\\m\�1��\\
m\�1������?�k����?�k��"�D�#†�"�D�#�##�臸#O6���yo�R`����
{5#���.K�W#w7��J�X�)
��k��]#��>#g�'A��}����|f�#G��-�#�Z�3CAST part of OpenSSL 1.0.0f 4 Jan
2012##�@�0#���/��kz�%?/?!
#�M#�@�#`Iɟ�'�Կ�����@#�u�И�cn�a�##f� Ž��"o;h(Y����y#
 �P_w �@�CV�/�#�|�-
�Ң��ɡ#Hl4�m�a/#T"�2�*k#T�:�V"�AӢ�@�f/9��/�M#�ҹ-�?����J�DvR�7��,�Y�Q����o#z
Z�h{�.��T�"5Y��/mK�d�P#If�-�徐"3��#;�#䎴]4�K@�E�?�1�.���e��U�ʱծ-��m�ԢP
���@"�8On
‫�׿‬r�[O/#LV#S��T�I��iF������X#�EŅc]�##ՊSW�#9j�7=��T*_}x:��vb��#j
Bz���)�##�^'r�g�P��#�8�#�ƌ�DŽ#Z�*'#J�k�Ѣ���*��V�`C��u\B&���Ʉq#-
�#l#��s<���y7bT��Ed��2?��#w�΢Y.#�#�x��P �?��_2#?8���ci�Z�v�t���
#�Ղ#8�\��##Ê#��5Б�G��#�A�Ab61��###;W��]�J�#�T<*2#��d���W�+7�uAӯPu2��#Z���Tk&##+��L�
�͜De����Ņ���U#$�Ԫ?�����-#M ��%�ȳU�ꘞ�ղ1#�l��*�)C�(E��i#q�#�Q��kx�#?
Q"��Q��D�*�AZ{��|�#�##���A�2ô�h"#�
`�m~8�l�k�x�pj��#�9���c#�d�6G�(�Z��G��#�u�#Q�5��Ojϋ��
#�J�ſ#�

W9�/D#?S��a.z9�y�'W�A 뜍֬#�|�*��u# ����e[��@��yw#���DGt2#���$‫ݽ‬T#~�D#�#$��u�U7���'|
�M_�Q�u�V�#���##X�,#��7##۪��J>�5��&5 M{��n0�f&��%�HV�V^��c�
ϲc|�E#p�P��r(����#�pH#��#��yM;-�A�B���
�G&L����jMG\^
|Y##јr#8����S���##/n��q�F�nEV�
9�q�� #�+�����#�A����|��i#CH�#y��}�B�#{BI��Z##�‫ݿ‬e�\�# #[�#�~��i�C?9z�a�z
��UQ#�ry 吝 5r#N�cZպ6#��0ę�#
_}��#��֡{/��#6�Y��#� ��#D�YD��̃�����
A �ѱ
* ;���{���B#[���A��
�‫ޘ‬N?�wi��y{��$[�#�#Ĭ%5P�_a��T1#bcKU!#h]Y�f�s�c=�4�·~��!
%#��#�#z�#��zӤ0X��
+g\�a##b�9�0#6;W��d/`��:�5F�#-#��
�#'�z��y�㠌�l��0�#^�7%�oo�#;��j� t�E�'���4:�NiO����M>�##�dY5�8E�fC�#�#r����3c
%�#�N����#�?��
(Υ��'R¦սT���U��dpf�M#�w#����&‫ۄ‬#g��C�!`X��0�Tr�o#S�#�UG�‫]ڿ‬b��#Vh�kʃ;�n-�#���Ӧ\=��
�w�L��3��{9�+�^#S#_ao�dC� x#^��c#�"�#��&g��I�{‫"ڷ‬%-U^7�rR#��yL�
�#��H[��#k����#�##0
�c�q��/޹���
S��##E!�5(T�<)c�)�A�|-#n�R#P�f#�#4�,�0P#�1##�`#��sY�&�D\d�w�R�3��A#+��‫|ٺ‬o#�!
#��PaH?�e�k«�dv&4�{^�%�����#�
����;M�#M��1�$#~�I�,�;j��x��`]�sV�z�\�/�1#�Co�0T����#�y��X�R�^�/�#�2�z�j0�>�#՚1�#�
B°��#I��
#0(‫������ڸ‬q�_��#�#`���ɣaM���/Ǚ.�"�pł�N�0##��#4‫ؼ‬y�;'���Ƹ�aiH�#?��;
(�#Z��C����/�#v��#��7�ӧܱ #��ß�n#�>Ƽ�B7Q#�(h��e#R�wj-K�'5#�#�.n\
����)�^�X#OX�{i�T̨g&H`# ��
K ��
`8 ���
# �
~8lI ��
`��#s5�GƱ��VL����>��##��8d��^�BF#�zk#
���O���d^AE�#�#\�;]>r��C|�m~#��#��ll9�`qp��s#v����#E@� ]�
%�=��#�#�`GK�6D�#���������P#��#�Q#�#�H#��<��#p��}##�}d#���^(O= ������&g�.yr��?
U+�H���Լ?^#��!�#[���U�@�W##�#N���F�R##W���s3�����N�ɷ#�dŸW1O g_?
����@�#��k���{C�=��K�۵��c���U#ȗ�n-#J(J��qo��#�C��C#l<� �_��#P�/~�
‫׿‬P##��Z��G�.#Q#>�p��#�X.0�_��|r#�#
��#��*,]I�鎸��P��'��W�#I�oy#�R��}��}Yr��@��#E�E#t]�#�>�#u�O�iV�A��#.�#��
'`��v#te�y���v�v�w#�����HN�ma�#���}/���
4����H����<0�(�O����wV‫ ܒ‬#M"��7���)}��V'�|��@�#��|�硴 f�^a�Ý
�<�є`A���#Fv\;��#�x��,WG���l�"����}#N#�C��#��##�~��#�8��<�����=�#�Q#8d�{�h�'# ‫ف‬#I#�
�]j�~�#�vh#����]��9K�9�#��;���#�Im�<#Eub'z�\����a�B#��#�Β�~#��B#r�r���p�#�}#ȡ[(O�b<
���51�#��)�B���Sj�O[�}#�###�#�#m#��(��#�Ki�\j#M��#Ō?,�-�ҖX���R��g[#��HJI
������\EkӉ7�`:��#�SRqDIK�
@�s�#g4|�~q#6U�O�/Т�`���#?�m�PьG#�#n#U?墼��#�#�38W�g} �=�#�3{�r3O
̫]ňv��#{##{��u#W��#B���dB�#c�+��ri#���/�n+�#_maz�g�����#����aq%���9�̸L!gу�b>ܷν#8\
�=D�#�mn`I:T`H�'W#��+8#��$�� #‫�ږ‬%�Eh�;��}E`P�/(b�4�
##٠�m+1#+d#Z0���R�X##����BA#\1��>2�6F��#�3�#S��75�
#����#�{����s��{OJW��dC#Q��##�z(~c�#�5_ ��yC�#�dc#d��J#$_#(͸�O@#C� "�
0#��O7���#-##{#$##M�gQ�#L��q�_#-_d##��#
�###!#####S��^>���#'�_��aB�#����%�r���#�q�#K�=;&o�#��~��~T�LmD���l߫I&�Ǡ��36�~?Pa
w��8�###Pr��#�.P��w��#�WFgO�#T3ɏ1 i��##�#�##5M�\=�fȦ��[]�o�
‫ڑ‬o��/"F�}F�9�m��O�C##��C�N!и� #
#�?#��#�X#(>nH&p�‫��׋‬wt|�#�%
-�#� y����#;#(8��i#�t#b#�߷@#!�#�{7##Ȋ###@# ��Y��V���v�O@��/��{U���#���
���M��V�i3�5�#�'#W#�ȯ����V#�ek#a#^u˅n#�#�wU2���?�-ɿ[%;�з#��$;m��c� �fÀ(8�#2�
�Tɪ�2�‫�ס‬##Zb##,�#gTzu��w�11�&��o�6F�#�Hj��yZ�V�Lj#�~CR�v�/���
��t��#��#��#��#,�t���*� M��|k .T�A#5����B=!&|#,#��a��Re�1��i##
%�#���##��##�&#!\1c�r
^��I�#y#����p#1
d�>�#>̶��Ո
î
�#0��rl���qn�#/���#���k�#�‫ء‬D�V#��È9#�/ű�1��#(x�⤣#2�}o�~�X#�#���$�#��Ū#��{##����s�#
�0a#!�-�!��#��)��۳��*��)e��\,�0��?�Б�\��,�ԩT�
��
�##_##�#w�:��^V�x�V�޾\�!��u�Q#ų�å�Ҷ��w�#�)E#���i/�z 毲�p�[���v���
F�98��#/��#gs#��D���)k)��/I��f�ing���ӛ/#~�#p%��Q^#�$S�l��j#�##>!
D��Yܷ#)eyC���y9�A��+�M�W����N
)�zkS�<� #�~U3����#r����Ņ?�~�
#
�~�tn,�f#�#y3��j��X�#D��D#1#���#�#��###�#�Zs�"�*ˁc8:$�z�i���
��#HIĀ���@#�8H��#�#��ުL#
H_��##�#�%���A��@N�$�#��#��A#
U#�e����Qr%#����#�
�����9�j�yMc���@��hV�
틕�#�Z��� �Vq�‫)�ק‬N-�fc#��##���q�w�*7#
�5�W#�a"ɠBր�#��[�t�!h��!��<�S������
 (�� =#�#\��8�#�N
�#$#�O/�vi�O#�ǐt�����U�¢��'-��cBj�##e�f �#�U��U#�)�s#�u��##��2h���#�UGR�<�#�D�
����6��&t:�+‫س‬#It�#~-�d‫��ڱ‬#I�#��h���&��B��¥#�7gc#��P�fG��6ʎ�#n#���7z�������}����c0
‫��މ‬A)�f�&#dV���T�X��#T�H˺�#U��I0#��е[Z.‫�ׇ‬nj��f:"��+��#�G>�h##l#
�#��i��wW����#���~@Pճ�M#�#�#‫�װ‬x�
�Q�V����$AV#ʔ�UW#n�ྵ ��a�$
X�K�'�aU{��#��#wh#�kld�M�D��f�d���~i�/�IO7�0j5�,s���@�I#��vM�;#�#B(#�HD�Lns#)
��_ɋ�}oaO#�#w.�+#�r���#‫�<ץ‬##}#����+F��Y�YE�E#��‫ه‬T��N���oHm#�#|
ǥ#c�s_D�V#�j�͈#�pr�ͳ��]ny`� ���E��`�#1©\1���BN"r#\#,#r���#N@
%�/�N2�g@�###x��\n�#‫�"܃‬u#kMxn��X�O D�#H?{���v��w�##�Vu�*�F_#( +��8=6#�
�J�R���ft#;�#Q#���Z#��#�y��l��u e���X��&h#J���#p����FS(l�\��v�0�k�)h7�#6�*��#g��$
k��%�ֿ#�h,DUu�#��e��#I��###4��0�#�"� W�Ib#uU~b‫�ڨ‬v^FES�#�Gm������l�,gH�L|
3��#‫�ە‬Ch#�\��SU2` ����
ߝW��c���#9�^�2��8���aI�3�7#���#�~^b��#�<�#N���ygC�H#�#��K�J##�f#��-‫�ۄ‬oH�
Ja����#)�Yf#c(��`
��<�x.2#��#�#��#��r ��~#A�#���k��Ӿt<�-7HDL@Ե��#�m�#9#����
���IS
gN#�=\A��djc#,��}��so�b�#�ۚ�5��L\�����S��f��#���#��L(#���S�4��!:;�KC##9�n����͐�m" ���
@� �~�#����^|[��#"/�i�T��ho)��:��SU6����%��b��."�Ho�%����e‫۽‬S��o�x�g�c5�#�+4��#��
t�I�}#ș�䍠##�uy���
 &Z�O�#�( ��3�4x�mE#_��%";��ɾV�-��bO�^�W�
"�n�ҕ[�N���$�]�B��'n{�‫ܨ‬#�Es/##�##5&��攰 33��~#�t+7�s%iH‫�ة‬##�#�b:8⇧v��SH6tc#�
�ivE#��P�*Y#5�6�n�L�Τ}�-#l��#�]�ū#��/�! ��߉x��_3O�D�#Fu��#+�չHA�#‫�ܛ‬
Ȇ��}s3��##ABQ# j���#�r#��v (��g2�u[[�#�S�X��
"#�#��##�r�#J<�f1�##��Ɉ��b`z��G�Rȶ��<vi�?R#�NM1�d�p8�YTf#�# �!
0Q�h[l��/�>�#0�qt�&���@3#�/C~A�^
l( ��ؒ��0�##�~����o�f˜��o��s�*�`�6���#�4‫�ژ‬K-��%#���#���=
%I�H��##6Jo��#�#8C@��Tz�WOp���A�:�Z„��T#U��|5Y�#��ŗ��Z����:�G:
%�#Sj~=eI�&T�w�Q[�#P�]��vl#DȨ##!�帊
�#�iX�`�[ŗ#���#Y�)��#�#���L;��]J5##�U���Lk���D�$5 鰽����b
‫ע‬T/�I1�8T�(q#)9H�#[���#�/�u�#@�g�+3��-
f�V��o�*#ɛ��#`�#�( �'##)dM#��#���P#˲,\�2��6K�#���_��A�
!P��N��h�����‫ذ‬y\C�##PIMAC�8#�<�?����f�#��Ͼ�##��#�`&�euz#$d��H�f��Æ`#(���#�#m5��w#�
鲳��###5�#*�k#��#�#iH�#uM�:{N#gC_7���I�fB3�A���T�Јl:�)(�G7�%G+�j�##�z�\
#�7Db��#��B�#�
n��g�t###�r�9ѱE7X�X�#�V�þ0�n�$#!
#)��E1^�#Ŏ��F�8#���JX�F�N��P�F_C)x;#$�#��#�mN,�d��#�JT��O�#팦
�xoɚ���#nn���<�#�����###V��U;6��]򡳅���<#�a3bt#(L#<t
m�lŪy���<#��QZ��&#)+���/8#��O
xW2�{��>��wn\�e��0Rԋ@�+�>�`x�#��T7�}�0�##��2�m�����-
���#�yy#S"�w�u����#Xȃ�oxk��#cZ��\�3#�]����#ù���zv�#��٣#B�y�q##j3ƚ`�#'�P�C�#�#��=�+
m�v��N%ύHf��6AN�(�
a�ϩI=߹��_�d������: #��}#+�p?#��##����#���P�O�+��Zbby#j�#�.��H#@�#�,Z#@"�ғ��-
�E�##�S4n)��o�lI�I�##����Br��~�##V>#�o�##lbfL�Tq*+#�9)���#���X�LV�Rf����#�.�S9v.i�#
#��##硦����>i�F�t�#+LVvuOx39]O#2�]#2=����#�&K/#��~~�<#�O^���?
#��v�f)o�#=�E#�4��ӷ�+��4##g�rN=��U#�"����
�g �`k8##=ü0} �8�##�QcÐӝX��yTGָ#�a��Yw�SW-
�X�V�cN�x#.F~�e#y���U5@�0�‫����ڑ‬#㶼 P�?!�@=����L�XI�6�Qpӱ����#�‫��ڍ‬y���#�Koq���K�
0#��‫��ݻ‬맕�d5��w##��##$#��,#�ϩ##/��
���tц�#�B*#��v:�-����7�‫�ޚ‬,�
)p#�@ ��#:$��7Ѵ�yN���#]�##h1HZ޻�B�f1���畏?##�r3�uQB#���}\cm��d!@�
�#����#�#WS��1z�3]#‫���ݨ‬Co#�F�q"�#8Ԛ�έiG�b�[�U��g��fN#�#�G[#o��L�Ď�nr�W�xzdD]���Ջ`##
l�_�9�##]�c�2֋~
�#pIPӻ#ߘ)*�
���m�S�~�H��##~�X.�t;��/R�#G��'~#[!����<8z�##vOB9`�5��#��5�'{�ɸ�6�g�
�#��{�#��#�##�pqT3^-ZI��#��d,����=4��pB#�w#bO&�Ҹ$���#d
%�FN���`�7>�͕
x # E _
� ���� � {
� �
�#۫�v##�"{.�1‫ן‬%$r���_����m�����
�L#��=mP��#�O%�#�os#�(Ĵ�yI�%�#�4��aĘnz��n�|l�6##AT�#�
޾'��VA�J����<��m#g��##��B��`��u{��##� ���$;g9�?��T0�q;��Bd2�̤
# #E#
� } ���
�� #J ����
p ��
B
�}�z[�W�Z?ՌM� (ԤΤ0�y��4���3S;�w���7x�#�泀��hN~��Ţ��|
 .�@{ 脠����X���[�#
�9�O*##��C#}�/�#6"��#�+��7��$�����#W�x4�oag���H�^�R��#A^e$�����
‫ݔ‬VH ۲��8##rW��#s#1d[O~���/<P�#odJ�#u��w�z��!![z����M:&)�
Q��|��c#�eY{�nr##�0@#wm�#a�
J#F#���[`d�힨��"���Π6 砹�dU 2�#7����#�-#WQ�+� �l#i���#�##E�z���#H�:Ov�L+#wV��g��
5#�8Y�9B#{�6= �#a>�J{�`�
��#,8I#�%v��##K$%#G�v
���X�Y #�f��
��0��#�Nn�dQ&�#�#���P#h�ꃢ�����Blowfish part of OpenSSL 1.0.0f 4 Jan 2012######�j?
$�#��.�##Dsp#"8 ��1�)��.#�lN��!(Ew#�8�fT�l
�4�)���P|ɵՄ?# G���#�#�y��#1Ѭ�ߘ�r�/��#��Ḗ~&jE�|��,�G��$�l����###��
iciNWq��X�~=��t�
͋�J#�#�T{�YZ�9�0�#`�*#����`(#yA��8 ۸��y�##:`�#�l>�#��w#�'K1��/�x`\`U�%U 攫
X��rXq
U�b�HW@#�cj9�U�#�*4\̴��
A# ��
T ���
r|## *
� oc]ũ+
� 1#t#>\
� # 3 \�$l�S2zw��(�H�;��Kk#�ē!
� ����֯
(f� �a��!�`�|H2��]]]��u��##&‫܈‬#e�>�#Ŭ���om#9B�D#.# ��J��i^�#�Bh�!�l��a�
g�ӫҠQjh/T�(�#��3Q�l#�n�;z#P�;��*�~#e�v#�9>Y�f�#C�#��oEå�}�^�;�uo�s
��D#@�j�Vb��N#w?6r�#=#�B$��7H#
���#ۛ��I�rS#{#���y�%����#P��;Ly���l��#�#�O���`�@ž\^c$j#�o�h�Sl>�9#o�R;#Q�m,�0�DE��
�^�#���J3�#(#f�K.#W���#t�E9_#���ӹ��yU
2`#�#��yr,@�%�g̣ 饎
# ��
�"2��#u<#ka��#P/�R#��=2`�#�H{1S��#>�W\���o�.V�#�i#��B��~(�2g�sUO��'[i�Xʻ]���#�=�#��
!�l��J[��-y�S�eE�I�Ґ��K����3~ˤA#�b������ �#Lw6��~д#�+M�
‫����ە‬q���Փk�ю��%ǯ/[<���u����d+#�#���#���^�O#Ïh���ѭ��#"//w##��-
u�##�#̠��
to ���
# ����
O ����
# ;
� |
�٨��f�_##w��#s̓w##!e ���w�BT��5��
��렉>{�#A�I~#�-#%#^�q �#h"��W�6d$#� �#�cU���Y�C�xSZ٢[} Ź�#v#&��ϕbh#�#AJsN�-
G�J�#{R#Q##)S�?W#��ƛ�v�`+#t 恵 o�##�#Wk��#�*!ec����.#4�dV��]-�S�����G�#j#�n�pzKD)��.
u�#&#İ�n�}ߧI�`�f��q���#�ilRdV ឱ¥#6#)L u@#Y�>:#䚘 T?e�B[��k�?�#�ҡ�0���8-M�]
%� �L&�p���c^�##?kh ��>##�<�pjk�5h��R#S��7#P�#�#>\����
 D}�� #W7�:�
P�###��###�
��t�<Xz�%�! ��#���/�|
sG2�#G�"���:���74v�ȧ��FaD�##�#>���A#u���8�/#�;���21�>#8�TN#�mO#Bo�#
�#�,y|�$r�yV����#w��##��#���.?��#r#U$qk.��#P�̈́�#GXz# �#t �����
}K �
: �
z ��
# ��
fC
c��d�G##�#�#27;C�#��$CM�#Q�e*##�P��:#���qUN1#�w���##_�V5#kǣ�;##<
�$Y������,���n<##pE ㆱ o��
^#��*>Z#�#w�#=N��e)##�։>�%�fRx�L.j�#��##�x��S<��-
#�N��=+#6#&9#`y�##�#R�##�n���f#��E���{��7�(��#��2åZl��!Xe#��h#���;�/ۭ}�*�/n[(�!
ު
#pa#)uG��##�a0��#��a�#�4#�c#��\s�9�pL#���#˼��� ,b`�\��n��#�d��#�i#�P�Ze2Zh@��*<��1�!
�##T���_�~��}=b��7�w-�_��#�#h#)�5#�#�ǡ�‫��ޖ‬Xx���Wcr"#�Ã��F�#�
��T0.S�Hُ(1�m���X��4a�(�s<|��#J]�d�#]#B�#> ���E ꫪ�#Ol��O��B�Bǵ�j�#;Oe#!
�A�y#��M��jGK�Pb�=�b�F&�[�������$#�t�i#��G���V#�[ �H#�t�b###�#*�BX��U
>�#ap?#��r3A~����_��;"lY7�|`t�˧�@n2w΄�#��P�#U���5��a��i��#
��#Z��#�.zD��4E�#g��ɞ##��s�͈
U#y �
_g@Cg �
e4 ���
8>q ��
(= �m ��
!
>#J=��+�����hZ=��@��#&L�4)i�� #A��#v.k�h#��q$#�j� 3�ԷC�a#P.�9#FE$�tO!
#@���#�M�������pE/�f� �����#�m�#��1�'�A9�U�G%‫ښ‬
ʫ%xP(�)#S‫چ‬,
�m��b#�h#iH‫�פ‬#h' ��?O����#����z|#Ϊ�_7ә�x�B*k@5��
���٫�9�N#;���#V#mK1f�&����t�n:2C[���Ah� x�N�
�‫ج‬V@E'�H�::SU��� ��k�K��мg�UX�#�c)��3��VJ*��%1?#~�^|1)�#���p/'#\#���,(#H#�"m��?#�H
‫܆‬#����####A�yG@#n�]�Q_2��Տ��d5#A4x{%`�*`����#lc#´##�2�#�Of�#����#k�>3b#$;"���#����
��
r�(�-Ex#��b#}d����o�IT�H}�'��#�>�AcG
t�.��no:7���`�#����L�#�kn�#U{�7,gm;�e'#����)�#̒
#9 #
� #i
� {f
� } #ϑ ��
� �� ^#
‫و‬/#�$�[Q�y�{��;v�.97yY#̗�
& -1.
� Bh;+j
� Lu## .x7B#j
�� � Q 满#Pc�K##k#���#‫ؽ‬%=����Y#BD�##
� ��
n�
�*��Ng�d_��‫ڈ‬鿾���dW��������{x`M`#`F��Ѱ#8�#�Ew��6�3kB�q�#�A��_^#<�W�w$�轙
BFUa.X���XN����8�t�½����fSt���U�u����Fa&�z��#�y#j��_��YnFpW�
�UՌL�#��#��#��Hb�#��tu�#� ‫�ܩ‬ -f3F2�##Z 茾� %��J#�n##=�#ߤ�##�i�h(�#�‫ڷ‬
9W���R�O#^#P�#�ĵ#�'��'��A�?w#L`õ#�a(z#����X`#b}�0‫�מ‬#c�8#���S4#��V�˻޶���}��v#Y�
�#o�#|K=
r9$|�|_r ㆹ�Mr�[�#��xUT��#�|
=��#�M^�P#��a��#��<#Ql���o�N�Vο*67���42��#�c���#g�#`@7�9:����7w«#-
�Z�g�\B7�O@'�Ӿ�����#�#s#�~#-�{�#�k#��E��!��n��n6j/�HWyn���v����Ie��#S} ‫ލ‬F#
s��M�L9‫)ۻ‬PF���&��#�^����Q-j��c"�‰��.
$C�##����a�Mj�P#��[d��&(�::����K�bU���/���R�io#?Y
�w#��#����� ���>;Z���4�‫�ٷ‬,Q�+#:�Ֆ}�}#�>��(-}|�%�#���r��ZL�Zq�)��#��G�������W;
()f��(.#y�#_xU`u�D#��^���m##�m�%a�#��d##��âW�<�#'�*#:��m?#�!
c#�f��#��&(�3u��U��4V#�<��#wQ(��
�gQ̫
_ ���
Q# �
M ��
08bX � z ��
7 �� � {> �
d � Ow~㶨 F=)�iS�H��#d##��$�m��-�if!#
!Q2 �
F����Ed��lX�� #��[@�X##�̻�k~j ��E Y:D

5>�ʹ����r��d�#f�Go<�c�Ҟ]/T#w®pcN�#tW#[�q#r�]}S�#�@@��NjF�4��##(#��#:�����#H�n΂;?o��
5K###�'r'�`#a�?��+y:��%E4�9��Ky�Q��2/ɺ#�~�#���Ǽ�##�Ǫ�I��#��O�����8�
�*�9#g6��|1�O+��Y��:��C�#��E�',"��*��#q�#%#��a���뜶�Yd��Ѩ�#^#�
j#�eP�#B�#�#n��;ۘ#���Ld�x22�#�4+��ߒ��#�q�At
#�4�K
q���2vÍ�5�./��Go#�#��#T�L���#�yb�o~>�f�####,��ҏ��"��W�#�#v2�15��#��Vb���uZ�6#n�s�
�b�

��I��#�PL#V�q����
#z2#��E�{���S��##�b�%��ҽ5#i#q"##�|�˶+�v��>#S��@#`��8�G%� 8�v�F�š�w``u N�˅‫؍‬芰
�z~��L\�H#���#�j�#����i�Ԑ��\�-% ?��#�2aN�[�w��
ߏW�r�:openssl\crypto\asn1\x_pkey.c####WIN32###OpenSSL default#CONF_def part of
OpenSSL 1.0.0f 4 Jan 2012##openssl\crypto\conf\conf_def.c##[[%s]]
#[%s] %s=%s
#line ###vv == NULL##openssl\crypto\conf\conf_api.c######�###��
#к##��
#��
#`�
#��
#��
##�
#��
##�## �
#P�
#��
#��
#@�
#`�
#��
#P�
#��
#��
##�
##�
##�
#@�
#P�
#��
#0�
# �
#############@�
#p�
#################openssl\crypto\ec\ecp_smpl.c####����������������������������������
�����������������������������������########################�����������������������#
###########����������������############����������������############������������####
############����������������������������################����������������###########
#####���������������################��������������################��������������###
#############���############����������������####����####����########����####�������
�########����������������������������������������########��������������������������
������������########�������������������������������������########������������������
�������������������########����������������������������������####����############��
��########################����########���������������������������������������������
�������������������������������������������������������###���######################
############################################################�����������������������
�����������������������������������������###��#################p��#################
P��#
###
###########���#################���#
###
###########8��##################��#################@��#################���#!###!
#######################����####����########openssl\crypto\bn\bn_sqrt.c#NULL shared
library
method##googEchoCancellation####googAutoGainControl#googAutoGainControl2####googNoi
seSuppression####googHighpassFilter## ##@##�###�U##P###��##��##0###��##�###�U##
###��##��##0### ��#�#`###p###0###
��#�#DtlsSrtpKeyAgreement####RtpDataChannels#WebRTC##true####false###Failed to
create channels.##Description contains invalid candidates.####Invalid session
description.####Offer and answer descriptions m-lines are not matching. Rejecting
answer.###Called with a SDP without crypto enabled.###Session error code##Failed to
update session state.#Session description must have SDES or DTLS-
SRTP.####source\talk\app\webrtc\webrtcsession.cc#Remote peer request ice
restart.####Trying to enable/disable an unexisting audio SSRC.##SetAudioPlayout: No
audio channel exists.###SetVideoPlayout: No video channel
exists.###CreateDataChannel: Data is not supported in this call.##Transport is not
in writable state.#ProcessNewLocalCandidate: content name # not
found##SetLocalDescription failed: ####SetRemoteDescription failed: ###Failed to
create data channel.##Failed to create video channel.#Failed to create voice
channel.#STATE_DEINIT####STATE_INPROGRESS####STATE_RECEIVEDTERMINATE#STATE_SENTTERM
INATE#STATE_SENTREDIRECT##STATE_RECEIVEDREJECT####STATE_SENTREJECT####STATE_RECEIVE
DMODIFY####STATE_SENTMODIFY####STATE_RECEIVEDACCEPT####STATE_RECEIVEDPRACCEPT##STAT
E_SENTACCEPT####STATE_SENTPRACCEPT##STATE_RECEIVEDINITIATE##STATE_SENTINITIATE##STA
TE_INIT##Session error code: ####Called with type in wrong state,
###UseRemoteCandidateInSession: Invalid candidate media index.#Audio not used in
this call#Video not used in this call#CreateOffer called with invalid media
streams.##CreateOffer called with invalid constraints.####CreateAnswer called with
invalid media streams.#Offer can't be NULL in CreateAnswer.####CreateAnswer called
with invalid constraints.###SetAudioSend: SSRC does not exist.##SetAudioSend: No
audio channel exists.##Failed to set capture device.###Trying to set camera device
on a unknown SSRC.#Video not used in this call.####SetVideoSend: SSRC does not
exist.##SetVideoSend: No video channel exists.##CanInsertDtmf: Track does not
exist: ###CanInsertDtmf: No audio channel exists.#Failed to insert DTMF to
channel.###InsertDtmf: Track does not exist: ##InsertDtmf: No audio channel
exists.####ProcessIceMessage: Remote description not set, #save the candidate for
later use.###ProcessIceMessage: Candidate cannot be used#ProcessIceMessage:
Candidate is NULL####ProcessIceMessage: ICE candidates can't be added ###without
any offer (local or remote) ####session description.####SSRC ### exists in both
local and remote descriptions###Finished generating identity####DTLS-SRTP enabled;
generating identity##�R##�S##�###�p###P##�!##PQ##�p##0"##pp##`
##�N##�p##0###�p##�p##���#���#�#�#p$�#`t## !�#Pu�##[�##�#`c�#�c�#P_�#�###
###0###0p�##)##�'�#��#�_�#�###�[�#�##P�#�p##`\##offer###pranswer####answer##d######
#VP8#####�#######�v###�#��###w## w## �##�z##�z##�}##
~##P~##@w##�t##�t###y##0�###SM#@�4#�
##�######P�##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��
##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##@�##��##��##��##��##�
�##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##А##@�##���#���#�
#�#p$�#0�## !�#`### �######@###0###�###�O##��##Ѕ## ###@###p%##�"##�###�;##
###p###�###�### ###�####!##�###`###�b�#Жj##ɪ#�S##�
%##`�###�##p�##��##��##�##��##@�##`�###�##
�##��##��###�##0�##��##`�##А######��##��##��###�##��##
�##�###�##��##��##�###�##0�##��##�##P�##0�##��##�##@�##��##�##��##
�##А##@�##А##p�##А##`�##А##��##А##0�##p�##��##��###�##��##��##p�###�##��##��##Ћ##0�
##Ц##0�##�K�#�xS#0#t#��##�##��##��##�###�##��##��##Ћ##0�##Ц##0�##�K�#�xS#0#t#`�###�
##��##��##��##��##��##@�##��##Р##P�##��##
�##@�##�##Ќ##А##`�###�###�##��##��##��##��##@�##`�###�##
�##��##�##��##А##0�##А##`�###�##0�##��##��###�##�##@�##@�##��##��###�##А##�##0�##��
##p�##�##p�##�##p�##`�###�##��##�##�##��##��##@�##��##Р##P�##��##
�##@�##�##`�###�## �##�##�##0�##��##@�##`�###�##
�##��##�##`�###�##`�##�##�##p�##��##@�##`�###�## �##��##��###�##0�##��######0##@
##��###�##��##
�##�###�##��##��##�###�##0�##��##�##P�##0�##��##�##@�##��##�##��##`�###�##
�##�##�##0�##�##@�##@�##��##��##@�##p�##�##��##��##��##��##��##��##��##��##��##��##
��##��##��##��##��##��## �##��###### �##P�##��##��##Ь##�###�##
�##0�##@�##P�##`�##p�##��##��##��##��##�##Э##�##�###�###�##
�##0�##@�##P�##`�##p�##��##��##Ю##��#`{##`W�#0�##�##
�##P�##@�##���#���#�#�#p$�#��## !�##�##��##@�##
�##0�##��##FakeWindow##FakeDesktop#@�##�:P#���#p�## �##@�##��###�##`�##��##
�##��###�##��##0�##`�##`�###�##��#�z##`W�#��##p�##UpdateAspectRatio ignored invalid
ratio: ###source\talk\media\base\videocapturer.cc#P�##��>#��>#@#�#@"�# Best ##
Interval ## No acceptable camera format found## Supported # distance ## Capture
Requested #Couldn't convert to I420! ## To #### x #EXTRACTOR-
dtls_srtp#p�##RTCP####RTP#��#��##��##��##��##��##��3#`�!#��#�r
#P�##��##��##��#�r
#`W�##�###�##��##�v
#####Trying to send insecure packet when crypto is required by policy#### RTCP
packet: size=#, type=#Failed to protect ## RTP packet: size=##, seqnum=###,
SSRC=#Dropping outgoing ## packet: wrong
size=####source\talk\session\media\channel.cc####Trying to receive insecure packet
when crypto is required by policy#Failed to unprotect ####Dropping incoming
##Failure in SetRemoteContent with action ###Failure in SetLocalContent with
action #Channel enabled#Channel disabled####Channel socket not writable
(###Ignoring SDES answer parameters because we are using DTLS-SRTP##Stopping
ringback tone##Playing ringback tone, loop=####No early media received before
timeout##Changing video state, recv=# send=##Failed to SetSend on video
channel##Failed to SetRender on video channel####View request for (##', '####) is
not in the local streams.##DataChannel: Setting max bandwidth to ##Changing data
state, recv=##Failed to SetSend on data channel###Failed to SetReceive on data
channel####@#
#Changing voice state, recv=#Failed to SetSend ## on voice channel###DTLS-SRTP key
installation failed###DTLS-SRTP key export failed#Installing keys from DTLS-SRTP on
##No DTLS-SRTP selected cipher####Cand[###Couldn't finish DTLS-SRTP on RTCP
channel###Couldn't finish DTLS-SRTP on RTP channel####Using ##Channel socket
writable (### for the first
time#rtp#rtcp####video_rtp###video_rtcp##data_rtp####data_rtcp###Created channel
for ####�#
#�#
#P�##�B
#�B
#���#���#�#�#p$�#�B
# !�#�
#�R
##H
#�#
###
#��##��##��##��##��##��##��##Destroyed channel###�#
#�#
#P�## H
#@H
#���#���#�#�#p$�#0H
# !�#�
#�a
##H
###
# $
#�#
#��##�a
# c
#��###�## #
#�#
#�#
#�#
#P�##�K
#�K
#���#���#�#�#p$�#�K
# !�#p%
#pe
##H
#�#
###
#�#
#��##�e
#�g
#��##@�####
# #
##�##@#
#Unable to delete screencast with ssrc ##�#
#�#
#P�##�O
#�O
#���#���#�#�#p$�#�O
# !�#�#
#pi
##H
#�#
###
#�#
#`�##�i
#�j
#P#
#@�## #
###
#Add send ssrc: #Failed to remove send stream with ssrc #Failed to add send stream
ssrc: ####Ignore unsupported stream update####Add send stream ssrc: ##Add remote
ssrc: ###Failed to remove remote stream with ssrc ###Failed to add remote stream
ssrc: ##Ignore unsupported stream update.### Stream exists? #### existing stream =
# new stream = ##Add remote stream ssrc: ####Failed to set local voice
description###Setting local voice description#Failed to set remote voice
description##Failed to set voice channel options#Can not set audio options from on
remote content.###Setting remote voice description####Failed to set local video
description###Failed to set video channel options#Setting local video
description#Failed to set remote video description##Setting remote video
description####Failed to set local data description####Setting local data
description##Failed to set remote data description###Setting remote data
description#�m�#��#`{##�#�#Pt
#�r
#source\talk\session\media\channelmanager.cc#Device manager can't find camera:
##Failed to init data channel.####Failed to GetAudioOutputDevice: ####Failed to
GetAudioInputDevice: #Device manager can't find default camera: ##�
#���#���#�#�#p$�#p�## !�#��##���#���#p�
#���#���#�#�#p$�#@�
# !�#@�##��##Ъ##0�##0�##��##@�
#���#���#�#�#p$�#P�
# !�#@�
#0�
#@�
#Failed to SetCaptureDevice with camera: ####Failed to SetOutputVolume to ###Failed
to SetAudioOptions with## microphone: ### speaker: ## options: ## delay: ####The
preferred camera '##The preferred speaker '#The preferred microphone '##' is
unavailable. Fall back to the default.#inline:#RTP/AVPF####RTP/SAVPF###��
##k##`�
#��
#��
# �
#0�
##�
#��
#��
#��
#P�
#��
#####X###Duplicate id found. Reassigning from
###source\talk\session\media\mediasession.cc###Failed to AddTransportAnswer,
content name=#Failed to AddTransportOffer, content name=##�|#��##��##��##�y
#��##��##Pz#��#��##��##Pz#Є#��##��##Pz#��#��#К@#Pz#��#��#��'#Pz#Є#�#0�#Pz
#CreateAnswer failed to UpdateCryptoParamsForBundle.#CreateAnswer failed to
UpdateTransportInfoForBundle.####Data is not available in the offer.#Data is not
supported in the answer.####Video is not available in the offer.####Video is not
supported in the answer.###Audio is not available in the offer.####Audio is not
supported in the answer.###CreateOffer failed to
UpdateCryptoParamsForBundle.##CreateOffer failed to
UpdateTransportInfoForBundle.#default#defaulta0###defaultv0###OfferToReceiveAudio#O
fferToReceiveVideo#IceRestart##googUseRtpMUX###Remote peer requested a DataChannel
but DataChannels ###are not
supported.##source\talk\app\webrtc\mediastreamsignaling.cc##��##�#@�##�#��# �##�#��
# ###�####�#`�##�# �#��#P###Remote track with id ### does not exists.### already
exists.####`####### �#��#P###DataChannel with label #reliable data channels are not
implemented##source\talk\app\webrtc\datachannel.cc###SendBuffer: Sending of binary
data is not implemented###The DataEngine does not
exist.##�###���#���#�#�#p$�#�### !
�#��##��##�###`###�###�###@�#�S##`1######P###�###���#���#�#�#p$�#�### !
�#p###�###�###`###�###�###@�#�S##`1######P###x-google-max-quantization###x-google-
min-bitrate####x-google-max-
bitrate####fir#ccm#nack####useinbandfec####stereo##sprop-
stereo####minptime####maxptime####ptime###opus####apt#rtx#�_##�_###x##��Y?ff&?
���=����x#######################<###
###############FEC#FID#ssrcs:
[#semantics:##sync_label:#cname:##display:####type:###ssrc_groups:####id:#groupid:#
###G729####G728####MPA#QCELP###L16#G722####PCMA####LPC#DVI4####G723####GSM#PCMU####
group###mid#rtcp-mux####ssrc####cname###extmap##msid-
semantic###WMS#msid####default#mslabel#label###ssrc-
group##crypto##candidate###typ#raddr###rport###username####password####generation##
fingerprint#fmtp####rtpmap##rtcp####ice-ufrag###ice-pwd#ice-lite####ice-
options#sendonly####recvonly####rtcp-fb#sendrecv####inactive####x-google-
flag###conference##x-google-buffer-latency#host####srflx###relay###
##v=0#-###0###0###IN##IP4#127.0.0.1###s=-#t=0
0###a=group:BUNDLE##IN##IP4#video###audio###application#0###0.0.0.0#1###AS######p#�
#@#######���#########���#########l#�#@#######d#�#@#######\#�#@#######\#�#�>######X#
�#@#######P#�#@#######H#�#@#######D#�#D�######D#�#D�######<#�#@#######
7�#@#######8#�#�_######0#�#@#######\#�##+######\#�#"V######(#�#@#######Failed to
parse: "##". Reason: #source\talk\app\webrtc\webrtcsdp.cc#Unable to parse fmtp
parameter. '=' missing.####Expects exactly #### fields.####Expects at least
###Failed to get the value of attribute: ##Expect line: ###Unsupported candidate
type.#Unsupported transport type.#<candidate-str>#Failed to create fingerprint from
the digest.###Expected format "msid:<identifier>[ <appdata>]".####Failed to get the
ssrc attribute value from ####. Expected format <attribute>:<value>.## 0##Can't
have multiple fingerprint attributes at the same level.#######Expected format
"<encoding name>/<clock rate>[/<encodingparameters>]".##Ignore rtpmap line that did
not appear in the ##<fmt> of the m-line: ###Failed to parse video codecs
correctly.#Failed to parse audio codecs correctly.#Invalid buffer latency.#Can't
find valid SDP line.##Ignored line: ##Failed to AddTransportInfo with content name:
######The a=extmap MUST be either all session level or all media
level.###Unsupported media type:
####turns###stuns###stun####��##��##p###��##��##��##��##��##��##��##��##0p�#0p�#��#
#���#�##А##��##��##p##p###�###`
##�
## ###@###p###�###P###А###
##��#####`W�#�## ###��##��##�
##p###�###�###P ## ###� ##�####
###�##А### ##А##0 ##А##@###А##0##@##�
##p###�###�###P ## ###� ##�####
##0##@##p##p###�###`
##�
## ###@###p###�#######�###0&##�###CreateDtmfSender failed on
DtmfSender::Create.##CreateDtmfSender is called with a non local audio
track.####CreateDtmfSender - track is
NULL.###source\talk\app\webrtc\peerconnection.cc####UpdateIce is not
implemented.###CreateOffer failed.#CreateOffer - observer is NULL.#CreateAnswer
failed.########CreateAnswer failed because remote_description is not an
offer.#CreateAnswer can't be called before SetRemoteDescription.###CreateAnswer -
observer is NULL.####SessionDescription is NULL.#SetLocalDescription - observer is
NULL.#SetRemoteDescription - observer is NULL.####AddStream - Currently only one
audio track is supported#per PeerConnection.#Configuration not supported:
###Invalid TURN configuration : ### can't proceed.#Invalid port: ##Failed to parse
port string: ###Invalid service type: ##Invalid uri: ###Empty uri.##�<##GetStats -
observer is NULL.####`>##���#���#�#�#p$�#P>## !�#`###@>##�###�###�#######��##��##�?
## ###@###p%##�"##�###�;## ###p###�###�### ###�####!##�###`###�b�#Жj##ɪ#�S##�
%######minAspectRatio##maxAspectRatio##maxWidth####minWidth####maxHeight###minHeigh
t###maxFrameRate####minFrameRate####googNoiseReduction##googLeakyBucket#####���Mb@?
�###�###U��#####����########�###U��#####����####�###�###U��#####����####�###h###U��
#####����####�###�###U��#####����####@###�###U��#####����####@###�###U��#####����##
##Option # has unexpected value
##source\talk\app\webrtc\localvideosource.cc##��##��##0###��##��##��##��##��##Found
unknown MediaStream constraint. Name:# Value:#0N##���#���#�#�#p$�# N## !
�#�###�U###N##��##��##�O###N##�b�#�?##�?##P��##P##���#���#�#�#p$�#�O## !
�#�###�U##�O##�O##��###P###N##�b�#�?##�?##P��#Failed to find a suitable video
format.#Could not satisfy mandatory
options.####��##��##0###��##��##��##��##��##��##��##��##��##�###�U##PX##��##��##0[#
#`X##�X##�X##PU##�U##�[##�[##p\##�[##�###�U##pY##0Y##@Y##�Y##`X##�X##�X##PU##�U##�[
##�[##p\##�[##video###��##��##0###��##��##��##��##��##��##��##��##��##��##�###�U##�
]##��##��##�^##��##`a##`�##Жj##_##�c##��##��##��##��##�###�U##@^##��##��##�^##P^##`
a##`�##Жj#0`##�c###]## ]
##���#0I�#�###�U##�_##�_##�_###`##P^##`a##`�##Жj#0`##�c###]## ]
##���#0I�#audio###��##��##0###��##��##��##��##��##��##��##��##��##�^##��##`a##`�##Ж
j##_##�c##��##�###�U##�a##��##��##�a###b##`a##`�##Жj##_##�c###ɪ#�###�U##�b##�b##�b#
#�b###b##`a##`�##Жj##_##�c###ɪ#####��##��##0d##�e##0##@
##0d##�e##IYUVI420YU16I422YU24I444YUYVYUY2yuvsYUY2HDYCUYVY2vuyUYVYBA81BGGRJPEGMJPGd
mb1MJPGRGB3raw BGR324BG####K~�?
�n##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��#
#��##��##��##@$##��##�%##�%##
&##�&##��######0r##�u##�w##�o###p##pp##pp###p###p##0p##0p##�o##�o##�o##�xS#0#t###�#
`o##po##�o##0I*#`s##@t##�p##@$##�v##�%##�%## &##�&##0v##@q##Pq##�q##RGB type not
supported: ####RGB buffer is not large
enough##source\talk\media\webrtc\webrtcvideoframe.cc####Error parsing format: ##
return code :
#AES_CM_128_HMAC_SHA1_80#AES_CM_128_HMAC_SHA1_32#(###########��#`{##P�###|
##p{##SRTP event: unknown ####SRTP event: reached hard packet limit (2^48
packets)####SRTP event: reached hard key usage limit####SRTP event: reached soft
key usage limit####SRTP event: SSRC
collision##source\talk\session\media\srtpfilter.cc#inline:#Failed to install SRTP
event handler, err=##Failed to init SRTP, err=###Invalid parameters in SRTP
answer###Failed to create SRTP session: unsupported## cipher_suite ##Failed to
create SRTP session: invalid key##Failed to create SRTP session, err=#Failed to
create SRTP session: #SRTP session already created####Failed to protect SRTP
packet, seqnum=##, err=##, last seqnum=##Failed to protect SRTP packet: The buffer
length ### is less than the needed ###Failed to protect SRTP packet: no SRTP
Session##Failed to protect SRTCP packet, err=####Failed to protect SRTCP packet:
The buffer length ##Failed to protect SRTCP packet: no SRTP Session#Failed to
unprotect SRTP packet, err=###Failed to unprotect SRTP packet: no SRTP
Session####Failed to unprotect SRTCP packet, err=##Failed to unprotect SRTCP
packet: no SRTP Session###Failed to ProtectRtp: SRTP not active###Failed to
ProtectRtcp: SRTP not active##Failed to UnprotectRtp: SRTP not active#Failed to
UnprotectRtcp: SRTP not active####Tried to set SRTCP Params when filter already
active####SRTCP activated with negotiated parameters:# send cipher_suite # recv
cipher_suite #Failed to apply negotiated SRTP parameters##SRTP activated with
negotiated parameters:##SRTP reset to init state####Tried to set SRTP Params when
filter already active#Invalid state for SRTP answer###Wrong state to update SRTP
offer####Invalid state for change of RTCP mux
offer##source\talk\session\media\rtcpmuxfilter.cc##Invalid parameters in RTCP mux
provisional answer###Invalid state for RTCP mux provisional answer###Invalid
parameters in RTCP mux answer###Invalid state for RTCP mux answer###SDES packet
received for demux.#source\talk\session\media\ssrcmuxfilter.cc##Stream already
added to filter##ms.#p�##��##########�###h###U��#####����####Unsupported format:#
width=#. Supported formats
are:####source\talk\media\base\capturemanager.cc####google-
data#####e###RtpDataMediaChannel::SetSendBandwidth to
###bps.####source\talk\media\base\rtpdataengine.cc#з##���#���#�#�#p$�#�## !�#�
%�#��##��##��##��##��##��##��##��##��##��##��##���#���#�#�#p$�#�## !�#�
%�#��##��##��##��##��##��##pt�#��##��##��##��##��##P�##��##��##��##Received packet
for unknown ssrc: ## because unknown payload id: ###Not receiving packet ### before
SetReceive(true) called.####Sending data packet of len=#Dropped data packet of
len=#; already sent #Not sending data because codec is unknown: #Not sending data
because ssrc is unknown: ##Not sending packet with ssrc=### len=### before
SetSend(true).##`�##��##�y�#��##���#���#####�#�#p$�#��## !�#�
%�#0�##0p�##�##��##P�##0�##pt�#P�##P�##@�###�###�##P�##`�##p�## �##Failed to
SetRecvCodecs because of unknown codec: ##Failed to SetSendCodecs because there is
no known codec.####Added data send stream '####Not adding data send stream '###'
with ssrc=#### because stream already exists.#Added data recv stream '####Not
adding data recv stream
'###DataCodec[##��##��##��##��##��##��##���#`�##��##��##���#��##��##��##���#��##��#
#��##���#0�##���#��##���##�##audioOutputLevel####audioInputLevel#bytesSent###packet
sSent#bytesReceived###packetsReceived#packetsLost#googFirsReceived####googFirsSent#
###googFrameHeightReceived#googFrameHeightSent#googFrameRateReceived###googFrameRat
eDecoded####googFrameRateOutput#googFrameRateInput##googFrameRateSent###googFrameWi
dthReceived##googFrameWidthSent##googJitterReceived##googNacksReceived###googNacksS
ent###googRtt#googAvailableSendBandwidth##googAvailableReceiveBandwidth###googTarge
tEncBitrate####googActualEncBitrate####googRetransmitBitrate###googTransmitBitrate#
googBucketDelay#VideoBwe####ssrc####bweforvideo#The SSRC ### is not associated with
a track#source\talk\app\webrtc\statscollector.cc####Failed to get voice channel
stats.##No StatsReport is available for ####BWEs count: ####Failed to get video
channel stats.##,0123456789*#ABCDabcd###,0123456789*#ABCD###��#�r
#�#�#p### ###The Dtmf provider is deleted. Clear the sending
queue.##source\talk\app\webrtc\dtmfsender.cc####InsertDtmf is called with invalid
duration or tones gap. ###The duration cannot be more than ###ms or less than
####ms. ####The gap between tones must be at least #InsertDtmf is called on
DtmfSender that can't send DTMF.####The DtmfProvider can no longer send DTMF.###The
DtmfProvider has been destroyed.####�###########���#���#�#�#p$�#�### !�#��##��##p
##########�###�###@�4#####@#�##�##�###�###�###���#���#�#�#p$�#�### !
�#P###`###�###########�###�###@�4#####@#�##�##�"##� ##0!##Invalid dimensions:
####Validate frame passed.##Duplicate value for all pixels.#Size field is too
large.#### bytes: ####Size field is invalid.##Size field is too small.####
sample[0..3]: #NULL sample pointer.#### format: ### bpp: ## size: # expected:
#source\talk\media\base\videoframe.cc####Captured frame size not supported by
renderer: #source\talk\media\base\capturerenderadapter.cc##p9##���#���#�#�#p$�#`:##
!�#srtp#### unknown event reported to handler
# packet index limit reached
#### key usage hard limit reached
## key usage soft limit reached
## SSRC collision
####srtp: in stream 0x%x: ##crypto kernel###(off)
##(on)
### %s ###failed with error code %d
##debug modules loaded:
##auth func: %s
## self-test: ### instance count: %d
###cipher: %s
#passed
#failed
#testing rand_source...##alloc###auth func###stat test#######�(\��#G@H�z#�G#@-
C#��6j?WARNING: no real random source present!
####hmac sha-1##aes cbc#aes icm#sha-
1###LIBYUV_DISABLE_ASM##LIBYUV_DISABLE_AVX2#LIBYUV_DISABLE_AVX##LIBYUV_DISABLE_MOVB
E####LIBYUV_DISABLE_SSE42####LIBYUV_DISABLE_SSE41####LIBYUV_DISABLE_SSSE3####LIBYUV
_DISABLE_SSE2#LIBYUV_DISABLE_X86######A!#A!#A!#A!#p��#p��#p��#p��#�p#�p#�p#�p##!A#!
A#!A#!A#‫ڶ‬p#‫ڶ‬p#‫ڶ‬p#‫ڶ‬p#p��#p��#p��#p��!A#!A#!A#!A#‫ڶ‬p#‫ڶ‬p#‫ڶ‬p#‫ڶ‬p#p��#p��#p��#p��##A!#A!#
A!#A!#p��#p��#p��#p��#�p#�p#�p#�p################����������������###
#######
#####
########
########
#����######
##
����####### ����
#######
����##
#########f#f#f#f#f#f#f#f����������������########f#f#f#f#f#f#f#f#���
�������������J#J#J#J#J#J#J#J#################�?�?�?�?�?�?�?�?�#3#3#3#3#3#3#3#�‫ـــــــ‬
3##
#
#########
###
##########�#�#�#�#�#�#�#�######��######��######��######��#L&##L&##L&##L&##D###D###D
###D###X-##X-##X-##X-##b2##b2##b2##b2######## ��������##### #
��������### #
#��������#############
#########

#
#####

#
#########################################################################����������
������######����####
����������������####
����q#q#�*q#q#�*#####�#�#�#�#�#�����#�#�#� �
�#�����#�#���

�������UUUU#�UUUU#�####LIBYUV_FILTER###########################IYUVI420YU16I422YU24
I444YUYVYUY2yuvsYUY2HDYCUYVY2vuyUYVYJPEGMJPGdmb1MJPGBA81BGGRRGB3raw
BGR324BG####VP8#red#ulpfec##urn:ietf:params:rtp-
hdrext:toffset##\C�#d#######`C�#t#######dC�#u###############
###U��#####����########�###U��#####����####�###X###U��#####����####�#######U��#####
����####�###�###U��#####����####�###h###U��#####����####�###�###U��#####����####�##
#,###U��#####����####�#######U��#####����####�###h###U��#####����####@###�###U��###
##����####@###�###U��#####����####@###�###U��#####����####�###�###U��#####����####�
###�###U��#####����####�###�###U��#####����####�###d###U��#####����####�###Z###U��#
####����####�###x###U��#####����####�###�###U��#####����####p�##�##`v##�x##`x##�x##
�x###}##�
!
#P}##@}##p�##P}##0kk#source\talk\media\webrtc\webrtcvideoengine.cc###WebRtcRenderAd
apter SetRenderer failed to SetSize to: ##WebRtcRenderAdapter the renderer has not
been set. #SetSize will be called later in SetRenderer.####WebRtcRenderAdapter
frame size changed to: #WebRtcRenderAdapter received a strange frame size:
#SetVoiceEngine##RegisterVideoRenderModule###NULL voice engine###WebRtc VideoEngine
Version:#GetVersion##() failed,
err=#WebRtcVideoEngine::InitVideoEngine##SetVoiceEngine can not be called after
Init#EnableTimedRender can not be called after Init##StopRender##StartRender#)
failed, err=##SendKeyFrame####NACK enabled for channel ###SetNACKStatus###Hybrid
NACK/FEC enabled for channel ####SetHybridNACKFECStatus##SetSendCodec####0x0
resolution selected. Captured frames will be dropped ###for ssrc: ##webrtc:
####Malformed webrtc log message: ##Failed to parse type from received RTCP
packet##Failed to parse SSRC from received RTCP packet##invalid codec type##
GetRenderer ### reuse default renderer ####higher##frames##VP8 options : ##picture
loss indication = ##, feedback mode = ##, complexity = #, resilience = #, denoising
= ##, error concealment = ##, automatic resize = ###, frame dropping = #, key frame
interval = #VP8 number of temporal layers: #Video max quantization: #### : selected
video codec ####fps#kbps#### (min=##kbps,### start=#kbps)###GetSendCodec####Capture
size changed####SetRenderer #### reuse default channel #####The specified ssrc # is
not in use.#SetSendBandwidth()##The send codec has not been set up yet##Conference
mode ignores
SetSendBandWidth####WebRtcVideoMediaChanne::SetSendBandwidth####MaybeResetVieSendCo
dec failed with
#SetReceiveCodec#StartReceive####RegisterExternalReceiveCodec####Failed to send
black frame.##�##���#���#####�#�#p$�#��## !�#�
%�#��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##��##
��##��##��##��##Failed to start the video capturer##SetSendStreamFormat()###The
send codec has not been set yet.####SetRembStatus###StartSend###StopSend####Media
Effects dropped a frame.##Camera failed to restart####Camera failed to
stop###DeleteChannel###Removing video stream ## with VideoEngine channel
##DeregisterDecoderObserver###DeRegisterSendTransport#RemoveRenderer##RegisterDecod
erObserver#SetReceiverBufferingMode####EnableColorEnhancement##SetLocalSSRC####GetL
ocalSSRC####SetReceiveTimestampOffsetStatus#AddRenderer#A/V not
synchronized####ConnectAudioChannel#DeRegisterVideoRenderModule#WebRtcVideoEngine::
Terminate####SetTraceFile####tracefile###��###�##`�##P�##���#���#�#�#p$�#@�## !�#
y##�##��##�"#######)##
�##0�###�##`�##�##�###�###�##��##0�##��###�##��##�2##p�##@�#p�##p�## �##`�## ###No
stream added#VideoEngine Init failed, releasing##VideoEngine Init
done###WebRtcVideoEngine::Init#buffered mode latency###conference mode#leaky
bucket####video temporal layer screencast#watermark###high bitrate####1 layer
screencast##camera list#3 layers####noise reduction#adapt view switch###cpu
adaption####encoder adaption####VideoOptions
{##SetSendTimestampOffsetStatus####SetSenderBufferingMode##SetTransmissionSmoothing
Status##SetOptions()####Not setting options - already sending | ####Unknown codec
##SetSendCodecs()#No matching codecs
available####ReleaseCaptureDevice####DisconnectCaptureDevice#DeregisterEncoderObser
ver###RegisterEncoderObserver#ConnectCaptureDevice####AllocateExternalCaptureDevice
###Unable to delete channel with ssrc key #Try to remove stream with ssrc # which
doesn't
exist.###SetKeyFrameRequestMethod####SetRTCPStatus###SetMTU##RegisterSendTransport#
##CreateChannel###CreateReceiveChannel####SetRTCPCName####AddSendStream: unable to
create channel#Trying to register duplicate ssrc: #AddSendStream: bad local stream
parameters##AddSendStream ##Stream already exists###New video stream ### registered
to VideoEngine channel ##### and connected to channel ##WebRtcVideoMediaChannel
supports one receiving SSRC per# stream#Recv stream
####WebRtcVideoEngine::~WebRtcVideoEngine###�###2###2##���#���#�#�#p$�#�2## !
�#GetEstimatedReceiveBandwidth####GetStats: sender information not
ready.#GetCodecTargetBitrate###GetEstimatedSendBandwidth###GetBandwidthUsage###GetR
TPStatistics####Failed to RebuildCodecList##Failed to initialize list of supported
codec types##SetTraceCallback####WebRtcVideoEngine::WebRtcVideoEngine####telephone-
event#ILBC####CELT####ISAC####OPUS####�V�#��######o#######�V�#�>######g#######�V�##
}######h#######�V�##}######m#######�V�##}######n#######H#�#�>######
#######�V�#@#######f#######p#�#@###############P#�#@###############
7�#��######k#######
7�##}######j#######
7�#�>######i#######
7�#@############## ��#@##############�V�#@#######~#######urn:ietf:params:rtp-
hdrext:ssrc-audio-level#ISAC##

You might also like