switch to using lws.. clean up
This commit is contained in:
@ -1,5 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-16 Lloyd Brookes <75pound@gmail.com>
|
||||
Copyright (c) 2013-17 Lloyd Brookes <75pound@gmail.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
|
||||
|
@ -102,4 +102,4 @@ $ npm install -g local-web-server
|
||||
```
|
||||
* * *
|
||||
|
||||
© 2013-16 Lloyd Brookes <75pound@gmail.com>. Documented by [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown).
|
||||
© 2013-17 Lloyd Brookes <75pound@gmail.com>. Documented by [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown).
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict'
|
||||
const LocalWebServer = require('../')
|
||||
new LocalWebServer()
|
||||
const localWebServer = new LocalWebServer()
|
||||
localWebServer.start()
|
||||
|
@ -1,87 +0,0 @@
|
||||
exports.optionDefinitions = [
|
||||
{
|
||||
name: 'port', alias: 'p', type: Number, defaultOption: true,
|
||||
description: 'Web server port.', group: 'server'
|
||||
},
|
||||
{
|
||||
name: 'stack', type: String, multiple: true,
|
||||
description: 'Feature stack.', group: 'server'
|
||||
},
|
||||
{
|
||||
name: 'key', type: String, typeLabel: '[underline]{file}', group: 'server',
|
||||
description: 'SSL key. Supply along with --cert to launch a https server.'
|
||||
},
|
||||
{
|
||||
name: 'cert', type: String, typeLabel: '[underline]{file}', group: 'server',
|
||||
description: 'SSL cert. Supply along with --key to launch a https server.'
|
||||
},
|
||||
{
|
||||
name: 'https', type: Boolean, group: 'server',
|
||||
description: 'Enable HTTPS using a built-in key and cert, registered to the domain 127.0.0.1.'
|
||||
},
|
||||
{
|
||||
name: 'help', alias: 'h', type: Boolean,
|
||||
description: 'Print these usage instructions.', group: 'misc'
|
||||
},
|
||||
{
|
||||
name: 'view', type: String,
|
||||
description: 'Custom view', group: 'misc'
|
||||
},
|
||||
{
|
||||
name: 'config', type: Boolean,
|
||||
description: 'Print the stored config.', group: 'misc'
|
||||
},
|
||||
{
|
||||
name: 'config-file', type: String,
|
||||
description: 'Config file to use', group: 'misc'
|
||||
},
|
||||
{
|
||||
name: 'verbose', type: Boolean, alias: 'v',
|
||||
description: 'Verbose output.', group: 'misc'
|
||||
},
|
||||
{
|
||||
name: 'debug', type: Boolean,
|
||||
description: 'Very verbose output, intended for debugging.', group: 'misc'
|
||||
},
|
||||
{
|
||||
name: 'version', type: Boolean,
|
||||
description: 'Print the version number.', group: 'misc'
|
||||
}
|
||||
]
|
||||
|
||||
function usage (middlewareDefinitions) {
|
||||
return [
|
||||
{
|
||||
header: 'local-web-server',
|
||||
content: 'A simple web-server for productive front-end development.'
|
||||
},
|
||||
{
|
||||
header: 'Synopsis',
|
||||
content: [
|
||||
'$ ws [--verbose] [<server options>] [<middleware options>]',
|
||||
'$ ws --config',
|
||||
'$ ws --help'
|
||||
]
|
||||
},
|
||||
{
|
||||
header: 'Server',
|
||||
optionList: exports.optionDefinitions,
|
||||
group: 'server'
|
||||
},
|
||||
{
|
||||
header: 'Middleware',
|
||||
optionList: middlewareDefinitions,
|
||||
group: 'middleware'
|
||||
},
|
||||
{
|
||||
header: 'Misc',
|
||||
optionList: exports.optionDefinitions,
|
||||
group: 'misc'
|
||||
},
|
||||
{
|
||||
content: 'Project home: [underline]{https://github.com/75lb/local-web-server}'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
exports.usage = usage
|
@ -1,47 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Feature interface.
|
||||
*/
|
||||
class Feature {
|
||||
/**
|
||||
* localWebServer instance passed to constructor in case feature needs access to http server instance.
|
||||
*/
|
||||
constructor (localWebServer) {}
|
||||
|
||||
/**
|
||||
* Return one or more options definitions to collect command-line input
|
||||
* @returns {OptionDefinition|OptionDefinition[]}
|
||||
*/
|
||||
optionDefinitions () {}
|
||||
|
||||
/**
|
||||
* Return one of more middleware functions with three args (req, res and next). Can be created by express, Koa or hand-rolled.
|
||||
*/
|
||||
middleware (options) {}
|
||||
|
||||
expandStack () {
|
||||
const flatten = require('reduce-flatten')
|
||||
|
||||
if (this.stack) {
|
||||
const featureStack = this.stack()
|
||||
.map(Feature => new Feature())
|
||||
|
||||
this.optionDefinitions = function () {
|
||||
return featureStack
|
||||
.map(feature => feature.optionDefinitions && feature.optionDefinitions())
|
||||
.filter(definitions => definitions)
|
||||
.reduce(flatten, [])
|
||||
}
|
||||
this.middleware = function (options, view) {
|
||||
return featureStack
|
||||
.map(feature => feature.middleware(options, view))
|
||||
.reduce(flatten, [])
|
||||
.filter(mw => mw)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Feature
|
@ -1,10 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const flatten = require('reduce-flatten')
|
||||
const arrayify = require('array-back')
|
||||
const ansi = require('ansi-escape-sequences')
|
||||
const Lws = require('lws')
|
||||
|
||||
/**
|
||||
* @module local-web-server
|
||||
@ -12,329 +7,12 @@ const ansi = require('ansi-escape-sequences')
|
||||
|
||||
/**
|
||||
* @alias module:local-web-server
|
||||
* @extends module:middleware-stack
|
||||
*/
|
||||
class LocalWebServer {
|
||||
|
||||
/**
|
||||
* @param [options] {object} - Server options
|
||||
* @param [options.port} {number} - Port
|
||||
* @param [options.stack} {string[]|Features[]} - Port
|
||||
*/
|
||||
constructor (initOptions) {
|
||||
initOptions = initOptions || {}
|
||||
const commandLineUsage = require('command-line-usage')
|
||||
const CliView = require('./cli-view')
|
||||
const cli = require('../lib/cli-data')
|
||||
|
||||
/* get stored config */
|
||||
const loadConfig = require('config-master')
|
||||
const stored = loadConfig('local-web-server')
|
||||
|
||||
/* read the config and command-line for feature paths */
|
||||
const featurePaths = parseFeaturePaths(initOptions.stack || stored.stack)
|
||||
|
||||
/**
|
||||
* Loaded feature modules
|
||||
* @type {Feature[]}
|
||||
*/
|
||||
this.features = this._buildFeatureStack(featurePaths)
|
||||
|
||||
/* gather feature optionDefinitions and parse the command line */
|
||||
const featureOptionDefinitions = gatherOptionDefinitions(this.features)
|
||||
const usage = commandLineUsage(cli.usage(featureOptionDefinitions))
|
||||
const allOptionDefinitions = cli.optionDefinitions.concat(featureOptionDefinitions)
|
||||
let options = initOptions.testMode ? {} : parseCommandLineOptions(allOptionDefinitions, this.view)
|
||||
|
||||
/* combine in stored config */
|
||||
options = Object.assign(
|
||||
{ port: 8000 },
|
||||
initOptions,
|
||||
stored,
|
||||
options.server,
|
||||
options.middleware,
|
||||
options.misc
|
||||
)
|
||||
|
||||
/**
|
||||
* Config
|
||||
* @type {object}
|
||||
*/
|
||||
this.options = options
|
||||
|
||||
/**
|
||||
* Current view.
|
||||
* @type {View}
|
||||
*/
|
||||
this.view = null
|
||||
|
||||
/* --config */
|
||||
if (options.config) {
|
||||
console.error(JSON.stringify(options, null, ' '))
|
||||
process.exit(0)
|
||||
|
||||
/* --version */
|
||||
} else if (options.version) {
|
||||
const pkg = require(path.resolve(__dirname, '..', 'package.json'))
|
||||
console.error(pkg.version)
|
||||
process.exit(0)
|
||||
|
||||
/* --help */
|
||||
} else if (options.help) {
|
||||
console.error(usage)
|
||||
process.exit(0)
|
||||
|
||||
} else {
|
||||
/**
|
||||
* Node.js server
|
||||
* @type {Server}
|
||||
*/
|
||||
this.server = this.getServer()
|
||||
|
||||
if (options.view) {
|
||||
const View = loadModule(options.view)
|
||||
this.view = new View(this)
|
||||
} else {
|
||||
this.view = new CliView(this)
|
||||
}
|
||||
|
||||
for (const feature of this.features) {
|
||||
if (feature.ready) {
|
||||
feature.ready(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a middleware application suitable for passing to `http.createServer`. The application is a function with three args (req, res and next) which can be created by express, Koa or hand-rolled.
|
||||
* @returns {function}
|
||||
*/
|
||||
getApplication () {
|
||||
const Koa = require('koa')
|
||||
const app = new Koa()
|
||||
const compose = require('koa-compose')
|
||||
const convert = require('koa-convert')
|
||||
|
||||
const middlewareStack = this.features
|
||||
.filter(mw => mw.middleware)
|
||||
.map(mw => mw.middleware(this.options, this))
|
||||
.reduce(flatten, [])
|
||||
.filter(mw => mw)
|
||||
.map(convert)
|
||||
|
||||
app.use(compose(middlewareStack))
|
||||
app.on('error', err => {
|
||||
console.error(ansi.format(err.stack, 'red'))
|
||||
class LocalWebServer extends Lws {
|
||||
constructor () {
|
||||
super({
|
||||
stack: [ 'log', 'static' ]
|
||||
})
|
||||
return app.callback()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a listening server which processes requests using the middleware supplied.
|
||||
* @returns {Server}
|
||||
*/
|
||||
getServer () {
|
||||
const app = this.getApplication()
|
||||
const options = this.options
|
||||
|
||||
let key = options.key
|
||||
let cert = options.cert
|
||||
|
||||
if (options.https && !(key && cert)) {
|
||||
key = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.key')
|
||||
cert = path.resolve(__dirname, '..', 'ssl', '127.0.0.1.crt')
|
||||
}
|
||||
|
||||
let server = null
|
||||
if (key && cert) {
|
||||
const fs = require('fs')
|
||||
const serverOptions = {
|
||||
key: fs.readFileSync(key),
|
||||
cert: fs.readFileSync(cert)
|
||||
}
|
||||
|
||||
const https = require('https')
|
||||
server = https.createServer(serverOptions, app)
|
||||
server.isHttps = true
|
||||
} else {
|
||||
const http = require('http')
|
||||
server = http.createServer(app)
|
||||
}
|
||||
|
||||
server.listen(options.port)
|
||||
// if (onListening) server.on('listening', onListening)
|
||||
|
||||
/* on server-up message */
|
||||
if (!options.testMode) {
|
||||
server.on('listening', () => {
|
||||
const ipList = getIPList()
|
||||
.map(iface => `[underline]{${server.isHttps ? 'https' : 'http'}://${iface.address}:${options.port}}`)
|
||||
.join(', ')
|
||||
console.error('Serving at', ansi.format(ipList))
|
||||
})
|
||||
}
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of Feature instances, given their module paths/names.
|
||||
* @return {feature[]}
|
||||
*/
|
||||
_buildFeatureStack (featurePaths) {
|
||||
const FeatureBase = require('./feature')
|
||||
return featurePaths
|
||||
.map(featurePath => loadFeature(featurePath))
|
||||
.map(Feature => new Feature(this))
|
||||
.map(feature => FeatureBase.prototype.expandStack.call(feature))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a module and verify it's of the correct type
|
||||
* @returns {Feature}
|
||||
*/
|
||||
function loadFeature (modulePath) {
|
||||
const isModule = module => module.prototype && (module.prototype.middleware || module.prototype.stack || module.prototype.ready)
|
||||
if (isModule(modulePath)) return modulePath
|
||||
const module = loadModule(modulePath)
|
||||
if (module) {
|
||||
if (!isModule(module)) {
|
||||
const insp = require('util').inspect(module, { depth: 3, colors: true })
|
||||
const msg = `Not valid Middleware at: ${insp}`
|
||||
console.error(msg)
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
const msg = `No module found for: ${modulePath}`
|
||||
console.error(msg)
|
||||
process.exit(1)
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a module, loaded by the first to succeed from
|
||||
* - direct path
|
||||
* - 'node_modules/local-web-server-' + path, from current folder upward
|
||||
* - 'node_modules/' + path, from current folder upward
|
||||
* - also search local-web-server project node_modules? (e.g. to search for a feature module without need installing it locally)
|
||||
* @returns {object}
|
||||
*/
|
||||
function loadModule (modulePath) {
|
||||
let module
|
||||
const tried = []
|
||||
if (modulePath) {
|
||||
try {
|
||||
tried.push(path.resolve(modulePath))
|
||||
module = require(path.resolve(modulePath))
|
||||
} catch (err) {
|
||||
if (!(err && err.code === 'MODULE_NOT_FOUND')) {
|
||||
throw err
|
||||
}
|
||||
const walkBack = require('walk-back')
|
||||
const foundPath = walkBack(process.cwd(), path.join('node_modules', 'local-web-server-' + modulePath))
|
||||
tried.push('local-web-server-' + modulePath)
|
||||
if (foundPath) {
|
||||
module = require(foundPath)
|
||||
} else {
|
||||
const foundPath2 = walkBack(process.cwd(), path.join('node_modules', modulePath))
|
||||
tried.push(modulePath)
|
||||
if (foundPath2) {
|
||||
module = require(foundPath2)
|
||||
} else {
|
||||
const foundPath3 = walkBack(path.resolve(__filename, '..'), path.join('node_modules', 'local-web-server-' + modulePath))
|
||||
if (foundPath3) {
|
||||
return require(foundPath3)
|
||||
} else {
|
||||
const foundPath4 = walkBack(path.resolve(__filename, '..'), path.join('node_modules', modulePath))
|
||||
if (foundPath4) {
|
||||
return require(foundPath4)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of available IPv4 network interfaces
|
||||
* @example
|
||||
* [ { address: 'mbp.local' },
|
||||
* { address: '127.0.0.1',
|
||||
* netmask: '255.0.0.0',
|
||||
* family: 'IPv4',
|
||||
* mac: '00:00:00:00:00:00',
|
||||
* internal: true },
|
||||
* { address: '192.168.1.86',
|
||||
* netmask: '255.255.255.0',
|
||||
* family: 'IPv4',
|
||||
* mac: 'd0:a6:37:e9:86:49',
|
||||
* internal: false } ]
|
||||
*/
|
||||
function getIPList () {
|
||||
const flatten = require('reduce-flatten')
|
||||
const os = require('os')
|
||||
|
||||
let ipList = Object.keys(os.networkInterfaces())
|
||||
.map(key => os.networkInterfaces()[key])
|
||||
.reduce(flatten, [])
|
||||
.filter(iface => iface.family === 'IPv4')
|
||||
ipList.unshift({ address: os.hostname() })
|
||||
return ipList
|
||||
}
|
||||
|
||||
/* manually scan for any --stack passed, as we may need to display stack options */
|
||||
function parseFeaturePaths (configStack) {
|
||||
const featurePaths = arrayify(configStack)
|
||||
const featureIndex = process.argv.indexOf('--stack')
|
||||
if (featureIndex > -1) {
|
||||
for (var i = featureIndex + 1; i < process.argv.length; i++) {
|
||||
const featurePath = process.argv[i]
|
||||
if (/^-/.test(featurePath)) {
|
||||
break
|
||||
} else {
|
||||
featurePaths.push(featurePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if the user did not supply a stack, use the default */
|
||||
if (!featurePaths.length) featurePaths.push(path.resolve(__dirname, '..', 'node_modules', 'local-web-server-default-stack'))
|
||||
return featurePaths
|
||||
}
|
||||
|
||||
function gatherOptionDefinitions (features) {
|
||||
return features
|
||||
.filter(mw => mw.optionDefinitions)
|
||||
.map(mw => mw.optionDefinitions())
|
||||
.reduce(flatten, [])
|
||||
.filter(def => def)
|
||||
.map(def => {
|
||||
def.group = 'middleware'
|
||||
return def
|
||||
})
|
||||
}
|
||||
|
||||
function parseCommandLineOptions (allOptionDefinitions) {
|
||||
const commandLineArgs = require('command-line-args')
|
||||
try {
|
||||
return commandLineArgs(allOptionDefinitions)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
|
||||
/* handle duplicate option names */
|
||||
if (err.name === 'DUPLICATE_NAME') {
|
||||
console.error('\nOption Definitions:')
|
||||
console.error(allOptionDefinitions.map(def => {
|
||||
return `name: ${def.name}${def.alias ? ', alias: ' + def.alias : ''}`
|
||||
}).join('\n'))
|
||||
}
|
||||
console.error(usage)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
26
package.json
26
package.json
@ -30,32 +30,16 @@
|
||||
"ssl"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "tape test/*.js",
|
||||
"test": "test-runner test/*.js",
|
||||
"docs": "jsdoc2md -t jsdoc2md/api.hbs -p list lib/*.js > doc/api.md; echo",
|
||||
"cover": "istanbul cover ./node_modules/.bin/tape test/*.js && cat coverage/lcov.info | coveralls && rm -rf coverage; echo"
|
||||
},
|
||||
"repository": "https://github.com/75lb/local-web-server",
|
||||
"author": "Lloyd Brookes <75pound@gmail.com>",
|
||||
"dependencies": {
|
||||
"ansi-escape-sequences": "^3.0.0",
|
||||
"array-back": "^1.0.4",
|
||||
"command-line-args": "^4.0.1",
|
||||
"command-line-usage": "^4.0.0",
|
||||
"config-master": "^3.0.0",
|
||||
"koa": "next",
|
||||
"koa-compose": "^3.1.0",
|
||||
"koa-convert": "^1.2.0",
|
||||
"local-web-server-default-stack": "github:local-web-server/default-stack",
|
||||
"reduce-flatten": "^1.0.1",
|
||||
"table-layout": "~0.4.0",
|
||||
"typical": "^2.6.0",
|
||||
"walk-back": "^2.0.1"
|
||||
"local-web-server-log": "file:///Users/lloydb/Documents/lws/log",
|
||||
"local-web-server-static": "file:///Users/lloydb/Documents/lws/static",
|
||||
"lws": "^0.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jsdoc-to-markdown": "^3.0.0",
|
||||
"koa-cache-control": "^1.0.0",
|
||||
"koa-livereload": "~0.2.0",
|
||||
"req-then": "~0.5.1",
|
||||
"tape": "^4.6.3"
|
||||
}
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDLjCCAhYCCQC3MW7xH6DDyTANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJH
|
||||
QjETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMRIwEAYDVQQDEwkxMjcuMC4wLjEwHhcNMTYwMzEwMTAzMTMwWhcN
|
||||
MTcwMzEwMTAzMTMwWjBZMQswCQYDVQQGEwJHQjETMBEGA1UECBMKU29tZS1TdGF0
|
||||
ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDEwkx
|
||||
MjcuMC4wLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIWz+H5P3P
|
||||
5/Uixviwbj88y112TBCCdhPizqVb8f7EgTgeIA0Jpqe2+RR9siawwUAX9nqRUB1g
|
||||
vgLZE4NZS+5ICN3JqkC4EysDS6VtIVf2OAuem3kdKaHSLl4JabsmBprgf2Dtze0i
|
||||
eX5+Pur5Pi2BEAYNCUKzC4OuVaP//3jNWD/Xp6eHBbC76L03EIGPxytYf5wkITbY
|
||||
wCjIVQw0Mq+WsV9eJRuLT4bnoeefCK+zPeTEQ6o+3SFkTkhqfsTF83sHvgcy1T4u
|
||||
7f+GZ9TYiaUi/1OVvfUg2FdGDAlKtVVH/t+pAg0M2hGr7vTClSVOg/qiY3ktEaYW
|
||||
FvcxJa65DyQNAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFwrxsqXwA6BTFTvRYi1
|
||||
s4tqos8loaZxE4eug96mL7qRvYzhDY+nDluiDEjMapACQOQaGIV+uMraOBk9yCUo
|
||||
BsYqLcBLUTKBZvIMEmYmlUKxZrtFLVo1y6p7CJM9luwUEpbPRivA/Vofk9zlq9B1
|
||||
AeVjDtqK/iZbO05qN18sgp7VPZZc4zRLOYUGfiUfX6r+dvDAPx/NBFM3vAEyYSur
|
||||
Jqa2CdsiUXo08CytgIaxGgF1DJxLqoA4SZagSUWWcuOlDzLSooNlcW/zfEfQfeMQ
|
||||
h7SbUtD4IJuKNd0BCeWMyVN7rM91zp9tf7713l+skbo5wIJAsNQAa2o8uRIXLjNX
|
||||
jy4=
|
||||
-----END CERTIFICATE-----
|
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAyFs/h+T9z+f1Isb4sG4/PMtddkwQgnYT4s6lW/H+xIE4HiAN
|
||||
CaantvkUfbImsMFAF/Z6kVAdYL4C2RODWUvuSAjdyapAuBMrA0ulbSFX9jgLnpt5
|
||||
HSmh0i5eCWm7Jgaa4H9g7c3tInl+fj7q+T4tgRAGDQlCswuDrlWj//94zVg/16en
|
||||
hwWwu+i9NxCBj8crWH+cJCE22MAoyFUMNDKvlrFfXiUbi0+G56Hnnwivsz3kxEOq
|
||||
Pt0hZE5Ian7ExfN7B74HMtU+Lu3/hmfU2ImlIv9Tlb31INhXRgwJSrVVR/7fqQIN
|
||||
DNoRq+70wpUlToP6omN5LRGmFhb3MSWuuQ8kDQIDAQABAoIBAQDFiBkBvQVzxegM
|
||||
ColDQN597K5PpDyesxV2BnBHTzXzvMZ8BPN1sWYm4jmOl2bH2y96sJo0y/y61Xrv
|
||||
U+qqzk61nHA1k/JMyTEeBaWqCzay3JywGe51jwcotmgl9aT6n4ZwkYUZz23dEFVi
|
||||
2FtHskKgvRCKJ7gn19FSvsJ68P/Dyl7H3/XGucj/7S+0JK3tb7BJ/ce68XABF99x
|
||||
hvvkaWtxv0WNX2LWDyLVwv3T5i+pq4sscd9dmxwwCb1N3Lm3SkAOqH7BINia/qud
|
||||
BLLJwHamzToWH7NTSWqrM4X9I7mI3zcMfOGeH9yZEFhB3cVu63V4yHfnGGqEiUOk
|
||||
21fA+iLBAoGBAPXwZskl+nM0Z7yadaOOCqjRMdvPIgHOvQvjKtQJ/E7I4sH3ZBfO
|
||||
4YPU0pErV4rbOyv6TZcUQwmcHmepK5wcHjj52+vgDQMr+K1wjRai8WdapKgXi39n
|
||||
5IgPD0y5Hgi7qUJI6w67ybkawgknL8hm6TwtxfbKtVoJ5BVgS1UmFMYRAoGBANCN
|
||||
e3X685aGqsyuCVU3bXnZVGyromiCDQge3NGuUFqaSCA0uK9/Q4HuStktH7LiRoZo
|
||||
UwBmdnF0Wa4hMcjBBONv1bc8S43CdoJC3LR6DdFL8j4YarUSXnTFRo+MnKIbNwQh
|
||||
378E1ws+dsOGrJ+IIqQJHfzsnG+vvb9PUleXgtI9AoGAFOBKKUri/oJ1R8oosDBv
|
||||
cTMIs2rarSKaY3bt/L+4PgvJS8OvKGI0PFeFZDM0pCHF3Q7LJUbgBeHNpujyPbcZ
|
||||
TabP5y7Gi/1gh4BlSYWdTjOghHAzNCZifLYii1WvWfhr/qdn5IFGN0MxM0uzP6SU
|
||||
qboM8sz0JedvB+17l4e6/bECgYBYI0MHJGyns/ghEngtRISG13tfhdXYVwYM5YYr
|
||||
M4EQGV3cBov610z/b2bAi9p2rjxh91sEs0jhP+vatHqmvjRDrnLiwp+npISTHpDJ
|
||||
0T9fsboJ1iXaqo2yyeC9MA7OT7QbkflOcEw1m0tz7MmtjkodiyDaUGD4rowBexNw
|
||||
oz6NfQKBgQCbhTO6MNmdeQrJn/ojR6HipypKqpVXqqqraAgU5BapaH0ZZwXkXDAM
|
||||
36ldQviX8UnPNFqHj7jzVSNyWsgmKHnXFmdTEBYTd+0b+WEyn9FR/8kBlxHFR7Nc
|
||||
AcAF7XF79pkJM31e6GCwFymYPbFJEL4TkWSOnPkypGY6IXHp57bKzA==
|
||||
-----END RSA PRIVATE KEY-----
|
Reference in New Issue
Block a user