gulp build system

This commit is contained in:
Evert Prants 2016-12-15 23:30:55 +02:00
parent 4cdec52820
commit 0f37d2caf6
26 changed files with 1111 additions and 3042 deletions

View File

@ -6,7 +6,8 @@ This application requires [node.js](https://nodejs.org/) to be installed.
1. Install the dependencies `npm install` 1. Install the dependencies `npm install`
2. Copy the configuration `cp client.config.example.toml client.config.toml` 2. Copy the configuration `cp client.config.example.toml client.config.toml`
3. Run the server `./teemant.js` 3. Build the project using `gulp`
4. Run the server `./teemant.js`
The client will be accessible at http://localhost:8080/ The client will be accessible at http://localhost:8080/

279
gulpfile.js Normal file
View File

@ -0,0 +1,279 @@
'use strict';
const path = require('path');
const gulp = require('gulp');
const sourcemaps = require('gulp-sourcemaps');
const gutil = require('gulp-util');
const gdata = require('gulp-data');
const del = require('del');
const gulpif = require('gulp-if');
const plumber = require('gulp-plumber');
const mergeStream = require('merge-stream');
const lodash = require('lodash');
const Sequence = require('run-sequence');
const watch = require('gulp-watch');
const realFavicon = require('gulp-real-favicon');
const debug = require('gulp-debug');
const filter = require('gulp-filter');
const fs = require('fs');
const eslint = require('gulp-eslint');
const webpack = require('webpack');
const webpackConfig = require(path.join(__dirname, '/webpack.config'));
const stylus = require('gulp-stylus');
const nib = require('nib');
const csso = require('gulp-csso');
const htmlmin = require('gulp-htmlmin');
const sequence = Sequence.use(gulp);
let sources = {
// script: ['main.js', 'admin.coffee', 'popout.js', 'livestream.js'],
style: ['layout.styl', 'theme_default.styl', 'theme_night.styl'],
document: ['index.html']
};
let lintES = ['src/script/**/*.js', 'server/**/*.js', 'gulpfile.js', 'teemant.js', 'webpack.config.js'];
let inProduction = process.env.NODE_ENV === 'production' || process.argv.indexOf('-p') !== -1;
let eslintOpts = {
rules: {
quotes: [1, 'single'],
semi: [1, 'always']
},
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
ecmaFeatures: {
impliedStrict: true,
globalReturn: true
}
}
};
let stylusOpts = {
use: nib(),
compress: false
};
let cssoOpts = {
restructure: true
};
let htmlminOpts = {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true,
collapseBooleanAttributes: true,
removeRedundantAttributes: true,
removeEmptyAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
};
let watchOpts = {
readDelay: 500,
verbose: true
};
// File where the favicon markups are stored
let faviconDataFile = 'build/icons/favicon-data.json';
if (inProduction) {
webpackConfig.plugins.push(new webpack.optimize.DedupePlugin());
webpackConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin(false));
webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true
},
comments: false,
mangle: {
screw_ie8: true
},
screw_ie8: true,
sourceMap: false
}));
}
let wpCompiler = webpack(lodash.assign({}, webpackConfig, {
cache: {},
devtool: inProduction ? null : 'inline-source-map',
debug: !inProduction
}));
function webpackTask (callback) {
// run webpack
wpCompiler.run(function (err, stats) {
if (err) throw new gutil.PluginError('webpack', err);
gutil.log('[script]', stats.toString({
colors: true,
hash: false,
version: false,
chunks: false,
chunkModules: false
}));
if (typeof callback === 'function') callback();
});
}
function styleTask () {
return gulp.src(sources.style.map(function (f) { return 'src/style/' + f; }))
.pipe(plumber())
.pipe(gulpif(!inProduction, sourcemaps.init()))
.pipe(stylus(stylusOpts))
.pipe(gulpif(inProduction, csso(cssoOpts)))
.pipe(gulpif(!inProduction, sourcemaps.write()))
.pipe(debug({title: '[style]'}))
.pipe(gulp.dest('build/style/'));
}
function documentTask (p) {
let data = {
config: require('./server/config'),
env: process.env.NODE_ENV || 'development',
};
return p
.pipe(plumber())
.pipe(gdata(function () { return data; }))
.pipe(realFavicon.injectFaviconMarkups(JSON.parse(fs.readFileSync(faviconDataFile)).favicon.html_code))
.pipe(gulpif(inProduction, htmlmin(htmlminOpts)))
.pipe(gulp.dest('build/document/'))
.pipe(debug({title: '[document]'}));
}
// Cleanup tasks
gulp.task('clean', () => del('build'));
gulp.task('clean:quick', ['clean:script', 'clean:style'], (done) => {
done();
});
gulp.task('clean:script', () => {
return del('build/script');
});
gulp.task('clean:style', () => {
return del('build/style');
});
gulp.task('clean:icons', () => {
return del('build/icons');
});
gulp.task('clean:document', () => {
return del('build/document');
});
// Main tasks
gulp.task('script', ['clean:script'], webpackTask);
gulp.task('watch:script', () => {
return watch(['src/script/**/*.js'], watchOpts, webpackTask);
});
gulp.task('style', ['clean:style'], styleTask);
gulp.task('watch:style', () => {
return watch('src/style/**/*.styl', watchOpts, styleTask);
});
// Generate the icons. This task takes a few seconds to complete.
// You should run it at least once to create the icons. Then,
// you should run it whenever RealFaviconGenerator updates its
// package (see the update-favicon task below).
gulp.task('generate-favicon', ['clean:icons'], (done) => {
realFavicon.generateFavicon({
masterPicture: 'static/image/diamond.svg',
dest: 'build/icons/',
iconsPath: '/',
design: {
ios: {
masterPicture: 'static/image/diamond.svg',
pictureAspect: 'backgroundAndMargin',
backgroundColor: '#00c7e0',
margin: '0%',
appName: 'Teemant'
},
desktopBrowser: {},
windows: {
pictureAspect: 'noChange',
backgroundColor: '#00c7e0',
onConflict: 'override',
appName: 'Teemant'
},
androidChrome: {
masterPicture: 'static/image/diamond.svg',
pictureAspect: 'noChange',
themeColor: '#00c7e0',
manifest: {
name: 'Teemant',
display: 'standalone',
orientation: 'notSet',
onConflict: 'override',
declared: true
}
},
safariPinnedTab: {
pictureAspect: 'silhouette',
themeColor: '#00c7e0'
}
},
settings: {
scalingAlgorithm: 'Lanczos',
errorOnImageTooSmall: false
},
versioning: true,
markupFile: faviconDataFile
}, done);
});
gulp.task('update-favicon', (done) => {
let currentVersion;
try {
currentVersion = JSON.parse(fs.readFileSync(faviconDataFile)).version;
} catch (e) {}
if (currentVersion) {
realFavicon.checkForUpdates(currentVersion, function (err) {
if (err) {
throw err;
}
done();
});
} else {
sequence('generate-favicon', done);
}
});
gulp.task('document', ['clean:document', 'update-favicon'], () => {
return documentTask(gulp.src(sources.document.map(function (f) { return 'src/document/' + f; })));
});
gulp.task('watch:document', () => {
return documentTask(
watch(['src/document/**/*.html'], watchOpts)
.pipe(filter(sources.document.map(function (f) { return 'src/document/' + f; })))
);
});
gulp.task('lint', () => {
return mergeStream(
gulp.src(lintES).pipe(eslint(eslintOpts))
.pipe(eslint.format())
);
});
gulp.task('watch:lint', () => {
return mergeStream(
watch(lintES, watchOpts, function (file) {
gulp.src(file.path).pipe(eslint(eslintOpts))
.pipe(eslint.format());
})
);
});
// Default task
gulp.task('default', (done) => {
sequence('script', 'style', 'lint', 'document', done);
});
// Watch task
gulp.task('watch', (done) => {
sequence('default', ['watch:lint', 'watch:script', 'watch:style', 'watch:document'], done);
});

View File

@ -16,6 +16,32 @@
"socketio": "^1.0.0", "socketio": "^1.0.0",
"toml": "^2.3.0" "toml": "^2.3.0"
}, },
"devDependencies": {
"gulp": "^3.9.1",
"lodash": "^4.17.2",
"webpack": "^1.13.3",
"del": "^2.2.2",
"gulp-csso": "^2.0.0",
"gulp-data": "^1.2.1",
"gulp-debug": "^3.0.0",
"gulp-eslint": "^3.0.1",
"gulp-filter": "^4.0.0",
"gulp-htmlmin": "^3.0.0",
"gulp-if": "^2.0.2",
"gulp-plumber": "^1.1.0",
"gulp-pug": "^3.2.0",
"gulp-real-favicon": "^0.2.1",
"gulp-sourcemaps": "^1.9.1",
"gulp-standard": "^8.0.2",
"gulp-stylus": "^2.6.0",
"gulp-util": "^3.0.7",
"gulp-watch": "^4.3.11",
"gulp-watch-pug": "^1.0.0",
"lazypipe": "^1.0.1",
"merge-stream": "^1.0.1",
"nib": "^1.1.2",
"run-sequence": "^1.2.2"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/DiamondtechDev/TeemantIRC.git" "url": "git://github.com/DiamondtechDev/TeemantIRC.git"

View File

@ -1,345 +0,0 @@
body {
margin: 0;
padding: 0;
font-family: Open Sans, Everson Mono, Helvetica;
}
.grade1 {
margin-bottom: 0;
margin-top: 0;
display: block;
text-align: center;
}
.grade2 {
margin-bottom: 0;
margin-top: 20px;
display: block;
text-align: center;
}
.grade3 {
margin-bottom: 0;
margin-top: 20px;
display: block;
text-align: center;
}
.ircclient {
position: absolute;
width: 100%;
height: 100%;
}
.ircclient input[type=text],
.ircclient input[type=number],
.ircclient input[type=password] {
padding: 8px;
width: 300px;
border-radius: 5px;
}
.ircclient input[type="submit"] {
width: 318px;
padding: 12px;
margin-top: 20px;
display: block;
border-radius: 4px;
font-size: 120%;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
}
.ircclient .coverwindow {
position: absolute;
width: 100%;
height: 100%;
}
.ircclient .coverwindow#authdialog {
z-index: 100;
}
.ircclient .coverwindow .wrapper {
width: 320px;
margin: auto;
margin-top: 5%;
padding: 15px;
}
.ircclient .coverwindow .wrapper label {
display: block;
font-size: 80%;
margin-top: 5px;
}
.ircclient .coverwindow .wrapper label.autosize {
width: auto;
display: inline-block !important;
font-size: 90% !important;
margin-bottom: 10px;
}
.ircclient #chat {
overflow: hidden;
}
.ircclient #chat .ircwrapper {
position: absolute;
width: 100%;
height: 100%;
}
.ircclient #chat .ircwrapper .toolbar {
height: 56px;
position: relative;
z-index: 15;
}
.ircclient #chat .ircwrapper .toolbar .open_settings {
width: 36px;
height: 36px;
display: inline-block;
position: absolute;
right: 10px;
top: 10px;
cursor: pointer;
-webkit-transition: transform 0.2s linear;
-moz-transition: transform 0.2s linear;
-ms-transition: transform 0.2s linear;
-o-transition: transform 0.2s linear;
transition: transform 0.2s linear;
}
.ircclient #chat .ircwrapper .toolbar .open_settings:hover {
transform: rotateZ(-90deg);
}
.ircclient #chat .ircwrapper .toolbar .tabby {
display: inline-block;
height: 56px;
position: absolute;
right: 45px;
left: 0;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab {
display: inline-block;
min-width: 60px;
height: 25px;
margin: 5px;
margin-right: 0;
padding: 10px;
line-height: 25px;
-webkit-transition: background-color 0.2s linear;
-moz-transition: background-color 0.2s linear;
-ms-transition: background-color 0.2s linear;
-o-transition: background-color 0.2s linear;
transition: background-color 0.2s linear;
border-radius: 5px;
cursor: pointer;
font-weight: 600;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #unread {
display: inline-block;
min-width: 18px;
height: 18px;
text-align: center;
font-size: 12px;
margin: 0 5px;
line-height: 20px;
border-radius: 100%;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #unread.none {
display: none;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #close {
display: inline-block;
width: 12px;
text-align: center;
margin-left: 5px;
}
.ircclient #chat .ircwrapper .chatarea {
position: absolute;
top: 56px;
width: 100%;
bottom: 46px;
}
.ircclient #chat .ircwrapper .chatarea .smsc-nicklistbtn {
width: 46px;
height: 46px;
position: absolute;
top: 16px;
right: 16px;
border-radius: 100%;
display: none;
opacity: 0.5;
cursor: pointer;
}
.ircclient #chat .ircwrapper .chatarea .topicbar {
position: absolute;
top: 0;
height: 20px;
right: 0;
left: 0;
padding: 12px;
display: none;
overflow: hidden;
z-index: 10;
}
.ircclient #chat .ircwrapper .chatarea .topicbar:hover {
height: auto;
max-height: 100px;
overflow: auto;
word-wrap: break-word;
}
.ircclient #chat .ircwrapper .chatarea .letterbox {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-y: auto;
white-space: pre-wrap;
word-wrap: break-word;
padding: 5px;
}
.ircclient #chat .ircwrapper .chatarea .nicklist {
width: 280px;
position: absolute;
right: 0;
padding: 10px;
top: 0;
bottom: 0;
display: none;
z-index: 11;
overflow: auto;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick {
cursor: pointer;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .nickname {
font-size: 120%;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .prefix {
width: 16px;
height: 16px;
line-height: 16px;
padding: 2px;
display: inline-block;
border-radius: 4px;
text-align: center;
margin-right: 5px;
font-weight: bold;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .no-prefix {
width: 25px;
display: inline-block;
}
.ircclient #chat .ircwrapper .chatarea .applet_default {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 20px;
width: 60%;
min-width: 360px;
margin: auto;
overflow: auto;
}
.ircclient #chat .ircwrapper .chatarea .applet_default .grade1,
.ircclient #chat .ircwrapper .chatarea .applet_default .grade2,
.ircclient #chat .ircwrapper .chatarea .applet_default .grade3 {
text-align: left;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button {
width: 120px;
height: 140px;
border-radius: 5px;
display: inline-block;
margin: 5px;
cursor: pointer;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button .sampler {
width: 90%;
height: 75%;
margin: 5px;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button .sampler .s_toolbar {
width: 100%;
height: 40%;
display: block;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button .name {
width: 100%;
text-align: center;
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .nicklist {
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .letterbox {
right: 301px;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .topicbar {
right: 301px;
}
.ircclient #chat .ircwrapper .chatarea.vtopic .topicbar {
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vtopic .letterbox {
top: 45px;
}
.ircclient #chat .ircwrapper .input {
position: absolute;
bottom: 0;
height: 46px;
width: 100%;
}
.ircclient #chat .ircwrapper .input .my_nickname {
margin: 5px;
padding: 7px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding-right: 20px;
margin-right: 0;
width: 183px;
overflow: hidden;
}
.ircclient #chat .ircwrapper .input .inputwrapper {
display: inline-block;
position: absolute;
margin: 5px 0;
left: 210px;
right: 55px;
top: 0;
}
.ircclient #chat .ircwrapper .input .inputwrapper input {
width: 100%;
padding: 6px;
font-size: 120%;
border-left: 0;
}
.ircclient #chat .ircwrapper .input .sendbutton {
width: 32px;
position: absolute;
height: 32px;
float: right;
top: 5px;
right: 5px;
cursor: pointer;
}
@media all and (max-width: 600px) {
.vnicks .nicklist {
display: none !important;
}
.vnicks .letterbox {
right: 0 !important;
}
.vnicks .topicbar {
right: 0 !important;
}
.vnicks.vopentrig .nicklist {
display: block !important;
}
.vnicks.vopentrig .topicbar {
right: 45px;
}
.vnicks .smsc-nicklistbtn {
z-index: 12;
display: block !important;
}
.my_nickname {
display: none;
}
.inputwrapper {
left: 38px !important;
}
}

View File

@ -1,707 +0,0 @@
body {
margin: 0;
padding: 0;
font-family: Open Sans, Everson Mono, Helvetica;
}
.grade1 {
font-size: 200%;
margin-bottom: 0;
margin-top: 0;
display: block;
color: #00bcd4;
text-align: center;
}
.grade2 {
font-size: 150%;
margin-bottom: 0;
margin-top: 20px;
display: block;
color: #00bcd4;
text-align: center;
}
.grade3 {
font-size: 120%;
margin-bottom: 0;
margin-top: 20px;
display: block;
color: #00bcd4;
text-align: center;
}
.ircclient {
position: absolute;
width: 100%;
height: 100%;
background: #fff;
background: -moz-linear-gradient(top, #fff 0%, #e5e5e5 100%);
background: -webkit-linear-gradient(top, #fff 0%, #e5e5e5 100%);
background: linear-gradient(to bottom, #fff 0%, #e5e5e5 100%);
}
.ircclient .coverwindow {
position: absolute;
width: 100%;
height: 100%;
}
.ircclient .coverwindow#authdialog {
z-index: 100;
}
.ircclient .coverwindow .wrapper {
width: 320px;
margin: auto;
margin-top: 5%;
padding: 15px;
background-color: #f7f7f7;
border: 1px solid #dadada;
-webkit-box-shadow: 4px 4px 18px #d6d6d6;
-moz-box-shadow: 4px 4px 18px #d6d6d6;
box-shadow: 4px 4px 18px #d6d6d6;
}
.ircclient .coverwindow .wrapper .msg.error {
color: #f00;
}
.ircclient .coverwindow .wrapper label {
display: block;
font-size: 80%;
margin-top: 5px;
color: #2196f3;
}
.ircclient .coverwindow .wrapper label.autosize {
width: auto;
display: inline-block !important;
font-size: 90% !important;
margin-bottom: 10px;
}
.ircclient .coverwindow .wrapper input[type=text],
.ircclient .coverwindow .wrapper input[type=number],
.ircclient .coverwindow .wrapper input[type=password] {
padding: 8px;
width: 300px;
border-radius: 5px;
border: 1px solid #d2d2d2;
-webkit-box-shadow: inset 2px 2px 4px #dcdcdc;
-moz-box-shadow: inset 2px 2px 4px #dcdcdc;
box-shadow: inset 2px 2px 4px #dcdcdc;
}
.ircclient .coverwindow .wrapper input[type="submit"] {
width: 318px;
padding: 12px;
margin-top: 20px;
display: block;
background: #87e0fd;
background: -moz-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: -webkit-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: linear-gradient(to bottom, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
border: 1px solid #2196f3;
border-radius: 4px;
color: #fff;
font-size: 120%;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
}
.ircclient .coverwindow .wrapper input[type="submit"]:hover {
background: #c4effc;
background: -moz-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
background: -webkit-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
background: linear-gradient(to bottom, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
}
.ircclient #chat {
overflow: hidden;
}
.ircclient #chat .ircwrapper {
position: absolute;
width: 100%;
height: 100%;
}
.ircclient #chat .ircwrapper .toolbar {
height: 56px;
background-color: #00c7e0;
position: relative;
z-index: 15;
-webkit-box-shadow: 2px 2px 4px #cecece;
-moz-box-shadow: 2px 2px 4px #cecece;
box-shadow: 2px 2px 4px #cecece;
}
.ircclient #chat .ircwrapper .toolbar .open_settings {
width: 36px;
height: 36px;
display: inline-block;
position: absolute;
right: 10px;
top: 10px;
cursor: pointer;
background-image: url("../image/settings.svg");
background-repeat: no-repeat;
background-size: contain;
-webkit-transition: transform 0.2s linear;
-moz-transition: transform 0.2s linear;
-ms-transition: transform 0.2s linear;
-o-transition: transform 0.2s linear;
transition: transform 0.2s linear;
}
.ircclient #chat .ircwrapper .toolbar .open_settings:hover {
transform: rotateZ(-90deg);
}
.ircclient #chat .ircwrapper .toolbar .tabby {
display: inline-block;
height: 56px;
position: absolute;
right: 45px;
left: 0;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab {
display: inline-block;
min-width: 60px;
height: 25px;
margin: 5px;
margin-right: 0;
padding: 10px;
line-height: 25px;
background-color: #29e1ff;
-webkit-transition: background-color 0.2s linear;
-moz-transition: background-color 0.2s linear;
-ms-transition: background-color 0.2s linear;
-o-transition: background-color 0.2s linear;
transition: background-color 0.2s linear;
border-radius: 5px;
border: 1px solid #00d0ea;
-webkit-box-shadow: inset 4px 4px 8px #44ebff;
-moz-box-shadow: inset 4px 4px 8px #44ebff;
box-shadow: inset 4px 4px 8px #44ebff;
color: #fff;
cursor: pointer;
font-weight: 600;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #unread {
display: inline-block;
min-width: 18px;
height: 18px;
background-color: #bf0000;
border: 1px solid #b00;
-webkit-box-shadow: inset 2px 2px 3px #f00;
-moz-box-shadow: inset 2px 2px 3px #f00;
box-shadow: inset 2px 2px 3px #f00;
text-align: center;
font-size: 12px;
margin: 0 5px;
line-height: 20px;
border-radius: 100%;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #unread.none {
display: none;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #close {
display: inline-block;
width: 12px;
text-align: center;
color: #ff3d3d;
margin-left: 5px;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab:hover {
background-color: #63e9ff;
-webkit-box-shadow: inset 4px 4px 8px #86f2ff;
-moz-box-shadow: inset 4px 4px 8px #86f2ff;
box-shadow: inset 4px 4px 8px #86f2ff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active {
background-color: #00b9d8;
border: 1px solid #009aad;
-webkit-box-shadow: inset 4px 4px 8px #009caf;
-moz-box-shadow: inset 4px 4px 8px #009caf;
box-shadow: inset 4px 4px 8px #009caf;
color: #fff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active:hover {
background-color: #00c7e8;
}
.ircclient #chat .ircwrapper .chatarea {
position: absolute;
top: 56px;
width: 100%;
bottom: 46px;
}
.ircclient #chat .ircwrapper .chatarea .smsc-nicklistbtn {
background-image: url("../image/users.svg");
background-repeat: no-repeat;
background-size: contain;
width: 46px;
height: 46px;
position: absolute;
top: 16px;
right: 16px;
background-color: #00bcd4;
border-radius: 100%;
border: 5px solid #389dbb;
display: none;
opacity: 0.5;
cursor: pointer;
}
.ircclient #chat .ircwrapper .chatarea .topicbar {
position: absolute;
top: 0;
height: 20px;
right: 0;
left: 0;
background-color: #fff;
border-bottom: 1px solid #ddd;
padding: 12px;
display: none;
overflow: hidden;
z-index: 10;
}
.ircclient #chat .ircwrapper .chatarea .topicbar:hover {
height: auto;
max-height: 100px;
overflow: auto;
word-wrap: break-word;
}
.ircclient #chat .ircwrapper .chatarea .letterbox {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-y: auto;
white-space: pre-wrap;
word-wrap: break-word;
padding: 5px;
}
.ircclient #chat .ircwrapper .chatarea .nicklist {
width: 280px;
position: absolute;
right: 0;
border-left: 1px solid #ddd;
padding: 10px;
top: 0;
bottom: 0;
display: none;
z-index: 11;
background-color: #fff;
overflow: auto;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick {
cursor: pointer;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick:hover {
background-color: #aeebff;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .nickname {
font-size: 120%;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .prefix {
width: 16px;
height: 16px;
line-height: 16px;
padding: 2px;
display: inline-block;
background-color: #05abe0;
border-radius: 4px;
color: #fff;
text-align: center;
margin-right: 5px;
font-weight: bold;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .no-prefix {
width: 25px;
display: inline-block;
}
.ircclient #chat .ircwrapper .chatarea .settings {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 20px;
width: 60%;
min-width: 360px;
margin: auto;
overflow: auto;
}
.ircclient #chat .ircwrapper .chatarea .settings .grade1,
.ircclient #chat .ircwrapper .chatarea .settings .grade2,
.ircclient #chat .ircwrapper .chatarea .settings .grade3 {
text-align: left;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .nicklist {
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .letterbox {
right: 301px;
}
.ircclient #chat .ircwrapper .chatarea.vnicks .topicbar {
right: 301px;
}
.ircclient #chat .ircwrapper .chatarea.vtopic .topicbar {
display: block;
}
.ircclient #chat .ircwrapper .chatarea.vtopic .letterbox {
top: 45px;
}
.ircclient #chat .ircwrapper .input {
position: absolute;
bottom: 0;
height: 46px;
width: 100%;
background-color: #00c7e0;
}
.ircclient #chat .ircwrapper .input .my_nickname {
background-color: #00efef;
margin: 5px;
padding: 7px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding-right: 20px;
margin-right: 0;
width: 183px;
overflow: hidden;
}
.ircclient #chat .ircwrapper .input .inputwrapper {
display: inline-block;
position: absolute;
margin: 5px 0;
left: 210px;
right: 55px;
top: 0;
}
.ircclient #chat .ircwrapper .input .inputwrapper input {
width: 100%;
padding: 6px;
font-size: 120%;
border: 1px solid #929292;
border-left: 0;
-webkit-box-shadow: inset 4px 4px 8px #d8d8d8;
-moz-box-shadow: inset 4px 4px 8px #d8d8d8;
box-shadow: inset 4px 4px 8px #d8d8d8;
}
.ircclient #chat .ircwrapper .input .sendbutton {
background-image: url("../image/send.svg");
background-repeat: no-repeat;
background-size: contain;
width: 32px;
position: absolute;
height: 32px;
float: right;
top: 5px;
right: 5px;
cursor: pointer;
}
.message.type_simple.mentioned {
background-color: #aeebff;
}
.message.type_simple .timestamp {
color: #696969;
}
.message.type_simple .timestamp:before {
color: #607d8b;
content: "[";
}
.message.type_simple .timestamp:after {
color: #607d8b;
content: "]";
}
.message.type_simple .sender {
color: #3f51b5;
}
.message.type_simple .sender:before {
content: "<";
}
.message.type_simple .sender:after {
content: ">";
}
.message.type_simple .arrowin,
.message.type_simple .arrowout {
font-weight: bolder;
}
.message.type_simple .channel {
font-weight: bold;
color: #a0a0a0;
}
.message.type_simple .m_listentry .channel {
min-width: 120px;
display: inline-block;
}
.message.type_simple .m_listentry .usercount {
display: inline-block;
min-width: 45px;
text-align: center;
}
.message .reason:before,
.message .hostmask:before {
content: "(";
}
.message .reason:after,
.message .hostmask:after {
content: ")";
}
.message .reason:before,
.message .hostmask:before,
.message .reason:after,
.message .hostmask:after {
color: #009606;
font-weight: bold;
}
.message .reason {
color: #bf0000;
}
.message .hostmask {
color: #004c88;
}
.message .arrowin {
color: #00ab00;
}
.message .arrowout {
color: #dc0f00;
}
.message.m_quit,
.message.m_part,
.message.m_kick {
color: #f00;
}
.message.m_join {
color: #008000;
}
.message.m_topic .content,
.message.m_names .content {
color: #03a9f4;
font-weight: bold;
}
.message.m_motd .content {
font-family: monospace;
}
.message.m_nick .content,
.message.m_notice .content {
color: #ff9800;
font-weight: bold;
}
.message.m_action .actionee {
color: #3f51b5;
}
.message.m_action .asterisk {
color: #e4c000;
}
.message.m_mode .content {
font-style: italic;
}
.message.m_mode .mode {
color: #008000;
}
.message.m_mode .asterisk {
color: #05abe0;
}
.message.m_error .content {
color: #f00;
font-weight: bold;
}
.message.m_help .content {
color: #008000;
font-weight: bold;
}
.message .irc-bg00,
.topicbar .irc-bg00,
.message .irc-bg0,
.topicbar .irc-bg0 {
background-color: #fff;
}
.message .irc-bg01,
.topicbar .irc-bg01,
.message .irc-bg1,
.topicbar .irc-bg1 {
background-color: #000;
}
.message .irc-bg02,
.topicbar .irc-bg02,
.message .irc-bg2,
.topicbar .irc-bg2 {
background-color: #000080;
}
.message .irc-bg03,
.topicbar .irc-bg03,
.message .irc-bg3,
.topicbar .irc-bg3 {
background-color: #008000;
}
.message .irc-bg04,
.topicbar .irc-bg04,
.message .irc-bg4,
.topicbar .irc-bg4 {
background-color: #f00;
}
.message .irc-bg05,
.topicbar .irc-bg05,
.message .irc-bg5,
.topicbar .irc-bg5 {
background-color: #a52a2a;
}
.message .irc-bg06,
.topicbar .irc-bg06,
.message .irc-bg6,
.topicbar .irc-bg6 {
background-color: #800080;
}
.message .irc-bg07,
.topicbar .irc-bg07,
.message .irc-bg7,
.topicbar .irc-bg7 {
background-color: #ffa500;
}
.message .irc-bg08,
.topicbar .irc-bg08,
.message .irc-bg8,
.topicbar .irc-bg8 {
background-color: #ff0;
}
.message .irc-bg09,
.topicbar .irc-bg09,
.message .irc-bg9,
.topicbar .irc-bg9 {
background-color: #0f0;
}
.message .irc-bg10,
.topicbar .irc-bg10 {
background-color: #008080;
}
.message .irc-bg11,
.topicbar .irc-bg11 {
background-color: #0ff;
}
.message .irc-bg12,
.topicbar .irc-bg12 {
background-color: #00f;
}
.message .irc-bg13,
.topicbar .irc-bg13 {
background-color: #ffc0cb;
}
.message .irc-bg14,
.topicbar .irc-bg14 {
background-color: #808080;
}
.message .irc-bg15,
.topicbar .irc-bg15 {
background-color: #d3d3d3;
}
.message .irc-fg00,
.topicbar .irc-fg00,
.message .irc-fg0,
.topicbar .irc-fg0 {
color: #fff;
}
.message .irc-fg01,
.topicbar .irc-fg01,
.message .irc-fg1,
.topicbar .irc-fg1 {
color: #000;
}
.message .irc-fg02,
.topicbar .irc-fg02,
.message .irc-fg2,
.topicbar .irc-fg2 {
color: #000080;
}
.message .irc-fg03,
.topicbar .irc-fg03,
.message .irc-fg3,
.topicbar .irc-fg3 {
color: #008000;
}
.message .irc-fg04,
.topicbar .irc-fg04,
.message .irc-fg4,
.topicbar .irc-fg4 {
color: #f00;
}
.message .irc-fg05,
.topicbar .irc-fg05,
.message .irc-fg5,
.topicbar .irc-fg5 {
color: #a52a2a;
}
.message .irc-fg06,
.topicbar .irc-fg06,
.message .irc-fg6,
.topicbar .irc-fg6 {
color: #800080;
}
.message .irc-fg07,
.topicbar .irc-fg07,
.message .irc-fg7,
.topicbar .irc-fg7 {
color: #ffa500;
}
.message .irc-fg08,
.topicbar .irc-fg08,
.message .irc-fg8,
.topicbar .irc-fg8 {
color: #dcdc00;
}
.message .irc-fg09,
.topicbar .irc-fg09,
.message .irc-fg9,
.topicbar .irc-fg9 {
color: #00e600;
}
.message .irc-fg10,
.topicbar .irc-fg10 {
color: #008080;
}
.message .irc-fg11,
.topicbar .irc-fg11 {
color: #00d2d2;
}
.message .irc-fg12,
.topicbar .irc-fg12 {
color: #00f;
}
.message .irc-fg13,
.topicbar .irc-fg13 {
color: #ffc0cb;
}
.message .irc-fg14,
.topicbar .irc-fg14 {
color: #808080;
}
.message .irc-fg15,
.topicbar .irc-fg15 {
color: #d3d3d3;
}
.message .irc-bold,
.topicbar .irc-bold {
font-weight: bold;
}
.message .irc-italic,
.topicbar .irc-italic {
font-style: italic;
}
.message .irc-underline,
.topicbar .irc-underline {
text-decoration: underline;
}
@media all and (max-width: 600px) {
.vnicks .nicklist {
display: none !important;
}
.vnicks .letterbox {
right: 0 !important;
}
.vnicks .topicbar {
right: 0 !important;
}
.vnicks.vopentrig .nicklist {
display: block !important;
}
.vnicks.vopentrig .topicbar {
right: 45px;
}
.vnicks .smsc-nicklistbtn {
z-index: 12;
display: block !important;
}
.my_nickname {
display: none;
}
.inputwrapper {
left: 38px !important;
}
}

View File

@ -1,482 +0,0 @@
.grade1 {
font-size: 200%;
color: #00bcd4;
}
.grade2 {
font-size: 150%;
color: #00bcd4;
}
.grade3 {
font-size: 120%;
color: #00bcd4;
}
.ircclient {
background: #fff;
background: -moz-linear-gradient(top, #fff 0%, #e5e5e5 100%);
background: -webkit-linear-gradient(top, #fff 0%, #e5e5e5 100%);
background: linear-gradient(to bottom, #fff 0%, #e5e5e5 100%);
}
.ircclient input[type=text],
.ircclient input[type=number],
.ircclient input[type=password] {
padding: 8px;
width: 300px;
border-radius: 5px;
border: 1px solid #d2d2d2;
-webkit-box-shadow: inset 2px 2px 4px #dcdcdc;
-moz-box-shadow: inset 2px 2px 4px #dcdcdc;
box-shadow: inset 2px 2px 4px #dcdcdc;
}
.ircclient input[type="submit"] {
background: #87e0fd;
background: -moz-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: -webkit-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: linear-gradient(to bottom, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
border: 1px solid #2196f3;
color: #fff;
font-size: 120%;
}
.ircclient input[type="submit"]:hover {
background: #c4effc;
background: -moz-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
background: -webkit-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
background: linear-gradient(to bottom, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
}
.ircclient .coverwindow .wrapper {
background-color: #f7f7f7;
border: 1px solid #dadada;
-webkit-box-shadow: 4px 4px 18px #d6d6d6;
-moz-box-shadow: 4px 4px 18px #d6d6d6;
box-shadow: 4px 4px 18px #d6d6d6;
}
.ircclient .coverwindow .wrapper .msg.error {
color: #f00;
}
.ircclient .coverwindow .wrapper label {
font-size: 80%;
color: #2196f3;
}
.ircclient .coverwindow .wrapper label.autosize {
font-size: 90% !important;
}
.ircclient #chat .ircwrapper .toolbar {
background-color: #00c7e0;
-webkit-box-shadow: 2px 2px 4px #cecece;
-moz-box-shadow: 2px 2px 4px #cecece;
box-shadow: 2px 2px 4px #cecece;
}
.ircclient #chat .ircwrapper .toolbar .open_settings {
background-image: url("../image/settings.svg");
background-repeat: no-repeat;
background-size: contain;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab {
background-color: #29e1ff;
border: 1px solid #00d0ea;
-webkit-box-shadow: inset 4px 4px 8px #44ebff;
-moz-box-shadow: inset 4px 4px 8px #44ebff;
box-shadow: inset 4px 4px 8px #44ebff;
color: #fff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #unread {
background-color: #bf0000;
border: 1px solid #b00;
-webkit-box-shadow: inset 2px 2px 3px #f00;
-moz-box-shadow: inset 2px 2px 3px #f00;
box-shadow: inset 2px 2px 3px #f00;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #close {
color: #ff3d3d;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab:hover {
background-color: #63e9ff;
-webkit-box-shadow: inset 4px 4px 8px #86f2ff;
-moz-box-shadow: inset 4px 4px 8px #86f2ff;
box-shadow: inset 4px 4px 8px #86f2ff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active {
background-color: #00b9d8;
border: 1px solid #009aad;
-webkit-box-shadow: inset 4px 4px 8px #009caf;
-moz-box-shadow: inset 4px 4px 8px #009caf;
box-shadow: inset 4px 4px 8px #009caf;
color: #fff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active:hover {
background-color: #00c7e8;
}
.ircclient #chat .ircwrapper .chatarea .smsc-nicklistbtn {
background-image: url("../image/users.svg");
background-repeat: no-repeat;
background-size: contain;
background-color: #00bcd4;
border: 5px solid #389dbb;
}
.ircclient #chat .ircwrapper .chatarea .topicbar {
background-color: #fff;
border-bottom: 1px solid #ddd;
}
.ircclient #chat .ircwrapper .chatarea .topicbar:hover {
height: auto;
max-height: 100px;
overflow: auto;
word-wrap: break-word;
}
.ircclient #chat .ircwrapper .chatarea .nicklist {
border-left: 1px solid #ddd;
background-color: #fff;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick:hover {
background-color: #aeebff;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .prefix {
background-color: #05abe0;
color: #fff;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button {
background-color: #e0e0e0;
border: 1px solid #a7a7a7;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button:hover {
background-color: #efefef;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button.selected {
border: 2px solid #00a0b5 !important;
}
.ircclient #chat .ircwrapper .input {
background-color: #00c7e0;
}
.ircclient #chat .ircwrapper .input .my_nickname {
background-color: #00efef;
}
.ircclient #chat .ircwrapper .input .inputwrapper input {
border: 1px solid #929292;
-webkit-box-shadow: inset 4px 4px 8px #d8d8d8;
-moz-box-shadow: inset 4px 4px 8px #d8d8d8;
box-shadow: inset 4px 4px 8px #d8d8d8;
}
.ircclient #chat .ircwrapper .input .sendbutton {
background-image: url("../image/send.svg");
background-repeat: no-repeat;
background-size: contain;
}
.message.type_simple.mentioned {
background-color: #aeebff;
}
.message.type_simple .timestamp {
color: #696969;
}
.message.type_simple .timestamp:before {
color: #607d8b;
content: "[";
}
.message.type_simple .timestamp:after {
color: #607d8b;
content: "]";
}
.message.type_simple .sender {
color: #3f51b5;
}
.message.type_simple .sender:before {
content: "<";
}
.message.type_simple .sender:after {
content: ">";
}
.message.type_simple .arrowin,
.message.type_simple .arrowout {
font-weight: bolder;
}
.message.type_simple .channel {
font-weight: bold;
color: #a0a0a0;
}
.message.type_simple .m_listentry .channel {
min-width: 120px;
display: inline-block;
}
.message.type_simple .m_listentry .usercount {
display: inline-block;
min-width: 45px;
text-align: center;
}
.message .reason:before,
.message .hostmask:before {
content: "(";
}
.message .reason:after,
.message .hostmask:after {
content: ")";
}
.message .reason:before,
.message .hostmask:before,
.message .reason:after,
.message .hostmask:after {
color: #009606;
font-weight: bold;
}
.message .reason {
color: #bf0000;
}
.message .hostmask {
color: #004c88;
}
.message .arrowin {
color: #00ab00;
}
.message .arrowout {
color: #dc0f00;
}
.message.m_ctcp_response,
.message.m_ctcp_request {
color: #39b7dd;
font-weight: bold;
}
.message.m_ctcp_response .asterisk,
.message.m_ctcp_request .asterisk {
color: #05abe0;
}
.message.m_quit,
.message.m_part,
.message.m_kick {
color: #f00;
}
.message.m_join {
color: #008000;
}
.message.m_topic .content,
.message.m_names .content {
color: #03a9f4;
font-weight: bold;
}
.message.m_motd .content {
font-family: monospace;
}
.message.m_nick .content,
.message.m_notice .content {
color: #ff9800;
font-weight: bold;
}
.message.m_action .actionee {
color: #3f51b5;
}
.message.m_action .asterisk {
color: #e4c000;
}
.message.m_mode .content {
font-style: italic;
}
.message.m_mode .mode {
color: #008000;
}
.message.m_mode .asterisk {
color: #05abe0;
}
.message.m_error .content {
color: #f00;
font-weight: bold;
}
.message.m_help .content {
color: #008000;
font-weight: bold;
}
.message .irc-bg00,
.topicbar .irc-bg00,
.message .irc-bg0,
.topicbar .irc-bg0 {
background-color: #fff;
}
.message .irc-bg01,
.topicbar .irc-bg01,
.message .irc-bg1,
.topicbar .irc-bg1 {
background-color: #000;
}
.message .irc-bg02,
.topicbar .irc-bg02,
.message .irc-bg2,
.topicbar .irc-bg2 {
background-color: #000080;
}
.message .irc-bg03,
.topicbar .irc-bg03,
.message .irc-bg3,
.topicbar .irc-bg3 {
background-color: #008000;
}
.message .irc-bg04,
.topicbar .irc-bg04,
.message .irc-bg4,
.topicbar .irc-bg4 {
background-color: #f00;
}
.message .irc-bg05,
.topicbar .irc-bg05,
.message .irc-bg5,
.topicbar .irc-bg5 {
background-color: #a52a2a;
}
.message .irc-bg06,
.topicbar .irc-bg06,
.message .irc-bg6,
.topicbar .irc-bg6 {
background-color: #800080;
}
.message .irc-bg07,
.topicbar .irc-bg07,
.message .irc-bg7,
.topicbar .irc-bg7 {
background-color: #ffa500;
}
.message .irc-bg08,
.topicbar .irc-bg08,
.message .irc-bg8,
.topicbar .irc-bg8 {
background-color: #ff0;
}
.message .irc-bg09,
.topicbar .irc-bg09,
.message .irc-bg9,
.topicbar .irc-bg9 {
background-color: #0f0;
}
.message .irc-bg10,
.topicbar .irc-bg10 {
background-color: #008080;
}
.message .irc-bg11,
.topicbar .irc-bg11 {
background-color: #0ff;
}
.message .irc-bg12,
.topicbar .irc-bg12 {
background-color: #00f;
}
.message .irc-bg13,
.topicbar .irc-bg13 {
background-color: #ffc0cb;
}
.message .irc-bg14,
.topicbar .irc-bg14 {
background-color: #808080;
}
.message .irc-bg15,
.topicbar .irc-bg15 {
background-color: #d3d3d3;
}
.message .irc-fg00,
.topicbar .irc-fg00,
.message .irc-fg0,
.topicbar .irc-fg0 {
color: #fff;
}
.message .irc-fg01,
.topicbar .irc-fg01,
.message .irc-fg1,
.topicbar .irc-fg1 {
color: #000;
}
.message .irc-fg02,
.topicbar .irc-fg02,
.message .irc-fg2,
.topicbar .irc-fg2 {
color: #000080;
}
.message .irc-fg03,
.topicbar .irc-fg03,
.message .irc-fg3,
.topicbar .irc-fg3 {
color: #008000;
}
.message .irc-fg04,
.topicbar .irc-fg04,
.message .irc-fg4,
.topicbar .irc-fg4 {
color: #f00;
}
.message .irc-fg05,
.topicbar .irc-fg05,
.message .irc-fg5,
.topicbar .irc-fg5 {
color: #a52a2a;
}
.message .irc-fg06,
.topicbar .irc-fg06,
.message .irc-fg6,
.topicbar .irc-fg6 {
color: #800080;
}
.message .irc-fg07,
.topicbar .irc-fg07,
.message .irc-fg7,
.topicbar .irc-fg7 {
color: #ffa500;
}
.message .irc-fg08,
.topicbar .irc-fg08,
.message .irc-fg8,
.topicbar .irc-fg8 {
color: #dcdc00;
}
.message .irc-fg09,
.topicbar .irc-fg09,
.message .irc-fg9,
.topicbar .irc-fg9 {
color: #00e600;
}
.message .irc-fg10,
.topicbar .irc-fg10 {
color: #008080;
}
.message .irc-fg11,
.topicbar .irc-fg11 {
color: #00d2d2;
}
.message .irc-fg12,
.topicbar .irc-fg12 {
color: #00f;
}
.message .irc-fg13,
.topicbar .irc-fg13 {
color: #ffc0cb;
}
.message .irc-fg14,
.topicbar .irc-fg14 {
color: #808080;
}
.message .irc-fg15,
.topicbar .irc-fg15 {
color: #d3d3d3;
}
.message .irc-bold,
.topicbar .irc-bold {
font-weight: bold;
}
.message .irc-italic,
.topicbar .irc-italic {
font-style: italic;
}
.message .irc-underline,
.topicbar .irc-underline {
text-decoration: underline;
}
@-moz-keyframes hotTab {
50% {
background-color: #6eebff;
}
}
@-webkit-keyframes hotTab {
50% {
background-color: #6eebff;
}
}
@-o-keyframes hotTab {
50% {
background-color: #6eebff;
}
}
@keyframes hotTab {
50% {
background-color: #6eebff;
}
}

View File

@ -1,500 +0,0 @@
.grade1 {
font-size: 200%;
color: #00bcd4;
}
.grade2 {
font-size: 150%;
color: #00bcd4;
}
.grade3 {
font-size: 120%;
color: #00bcd4;
}
a {
color: #23e7ff;
}
a:hover {
color: #5dedff;
}
.ircclient {
background: #1d1d1d;
}
.ircclient input[type=text],
.ircclient input[type=number],
.ircclient input[type=password] {
padding: 8px;
width: 300px;
border-radius: 5px;
border: 1px solid #d2d2d2;
-webkit-box-shadow: inset 2px 2px 4px #dcdcdc;
-moz-box-shadow: inset 2px 2px 4px #dcdcdc;
box-shadow: inset 2px 2px 4px #dcdcdc;
}
.ircclient input[type="submit"] {
background: #87e0fd;
background: -moz-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: -webkit-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: linear-gradient(to bottom, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
border: 1px solid #2196f3;
color: #fff;
font-size: 120%;
}
.ircclient input[type="submit"]:hover {
background: #c4effc;
background: -moz-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
background: -webkit-linear-gradient(top, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
background: linear-gradient(to bottom, #c4effc 0%, #7fd5ef 40%, #39b7dd 100%);
}
.ircclient .coverwindow .wrapper {
background-color: #3e3e3e;
border: 1px solid #171717;
-webkit-box-shadow: 4px 4px 18px #383838;
-moz-box-shadow: 4px 4px 18px #383838;
box-shadow: 4px 4px 18px #383838;
color: #fff;
}
.ircclient .coverwindow .wrapper .msg.error {
color: #f00;
}
.ircclient .coverwindow .wrapper label {
font-size: 80%;
color: #67bcff;
}
.ircclient .coverwindow .wrapper label.autosize {
font-size: 90% !important;
}
.ircclient #chat .ircwrapper .toolbar {
background-color: #008e8e;
-webkit-box-shadow: 2px 2px 4px #585858;
-moz-box-shadow: 2px 2px 4px #585858;
box-shadow: 2px 2px 4px #585858;
}
.ircclient #chat .ircwrapper .toolbar .open_settings {
background-image: url("../image/settings.svg");
background-repeat: no-repeat;
background-size: contain;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab {
background-color: #00bfde;
border: 1px solid #0092a5;
-webkit-box-shadow: inset 4px 4px 8px #00d1ea;
-moz-box-shadow: inset 4px 4px 8px #00d1ea;
box-shadow: inset 4px 4px 8px #00d1ea;
color: #fff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.hot {
animation: hotTab 1s linear infinite;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #unread {
background-color: #bf0000;
border: 1px solid #b00;
-webkit-box-shadow: inset 2px 2px 3px #f00;
-moz-box-shadow: inset 2px 2px 3px #f00;
box-shadow: inset 2px 2px 3px #f00;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab #close {
color: #ff3d3d;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab:hover {
background-color: #00dbff;
-webkit-box-shadow: inset 4px 4px 8px #23e7ff;
-moz-box-shadow: inset 4px 4px 8px #23e7ff;
box-shadow: inset 4px 4px 8px #23e7ff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active {
background-color: #006a7b;
border: 1px solid #006a77;
-webkit-box-shadow: inset 4px 4px 8px #003940;
-moz-box-shadow: inset 4px 4px 8px #003940;
box-shadow: inset 4px 4px 8px #003940;
color: #fff;
}
.ircclient #chat .ircwrapper .toolbar .tabby .tab.active:hover {
background-color: #00859a;
}
.ircclient #chat .ircwrapper .chatarea .smsc-nicklistbtn {
background-image: url("../image/users.svg");
background-repeat: no-repeat;
background-size: contain;
background-color: #00bcd4;
border: 5px solid #389dbb;
}
.ircclient #chat .ircwrapper .chatarea .topicbar {
background-color: #2d2d2d;
border-bottom: 1px solid #000;
color: #fff;
}
.ircclient #chat .ircwrapper .chatarea .topicbar:hover {
height: auto;
max-height: 100px;
overflow: auto;
word-wrap: break-word;
}
.ircclient #chat .ircwrapper .chatarea .nicklist {
background-color: #2d2d2d;
border-left: 1px solid #000;
color: #fff;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick:hover {
background-color: #006282;
}
.ircclient #chat .ircwrapper .chatarea .nicklist .nick .prefix {
background-color: #05abe0;
color: #fff;
}
.ircclient #chat .ircwrapper .chatarea .settings {
color: #fff;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button {
background-color: #424242;
border: 1px solid #444;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button:hover {
background-color: #545454;
}
.ircclient #chat .ircwrapper .chatarea .settings .theme_button.selected {
border: 2px solid #00e2ff !important;
}
.ircclient #chat .ircwrapper .input {
background-color: #005a5a;
}
.ircclient #chat .ircwrapper .input .my_nickname {
background-color: #009494;
color: #fff;
}
.ircclient #chat .ircwrapper .input .inputwrapper input {
-webkit-box-shadow: inset 4px 4px 8px #001419;
-moz-box-shadow: inset 4px 4px 8px #001419;
box-shadow: inset 4px 4px 8px #001419;
background-color: #002b36;
border: 1px solid #008e8e;
color: #fff;
}
.ircclient #chat .ircwrapper .input .sendbutton {
background-image: url("../image/send.svg");
background-repeat: no-repeat;
background-size: contain;
}
.message {
color: #fff;
}
.message.type_simple.mentioned {
background-color: #006282;
}
.message.type_simple .timestamp {
color: #afafaf;
}
.message.type_simple .timestamp:before {
color: #607d8b;
content: "[";
}
.message.type_simple .timestamp:after {
color: #607d8b;
content: "]";
}
.message.type_simple .sender {
color: #3f51b5;
}
.message.type_simple .sender:before {
content: "<";
}
.message.type_simple .sender:after {
content: ">";
}
.message.type_simple .arrowin,
.message.type_simple .arrowout {
font-weight: bolder;
}
.message.type_simple .channel {
font-weight: bold;
color: #a0a0a0;
}
.message.type_simple .m_listentry .channel {
min-width: 120px;
display: inline-block;
}
.message.type_simple .m_listentry .usercount {
display: inline-block;
min-width: 45px;
text-align: center;
}
.message .reason:before,
.message .hostmask:before {
content: "(";
}
.message .reason:after,
.message .hostmask:after {
content: ")";
}
.message .reason:before,
.message .hostmask:before,
.message .reason:after,
.message .hostmask:after {
color: #009606;
font-weight: bold;
}
.message .reason {
color: #bf0000;
}
.message .hostmask {
color: #1999ff;
}
.message .arrowin {
color: #00ab00;
}
.message .arrowout {
color: #dc0f00;
}
.message.m_ctcp_response,
.message.m_ctcp_request {
color: #39b7dd;
font-weight: bold;
}
.message.m_ctcp_response .asterisk,
.message.m_ctcp_request .asterisk {
color: #05abe0;
}
.message.m_quit,
.message.m_part,
.message.m_kick {
color: #f00;
}
.message.m_join {
color: #008000;
}
.message.m_topic .content,
.message.m_names .content {
color: #03a9f4;
font-weight: bold;
}
.message.m_motd .content {
font-family: monospace;
}
.message.m_nick .content,
.message.m_notice .content {
color: #ff9800;
font-weight: bold;
}
.message.m_action .actionee {
color: #3f51b5;
}
.message.m_action .asterisk {
color: #e4c000;
}
.message.m_mode .content {
font-style: italic;
}
.message.m_mode .mode {
color: #0f0;
}
.message.m_mode .asterisk {
color: #05abe0;
}
.message.m_error .content {
color: #f00;
font-weight: bold;
}
.message.m_help .content {
color: #0f0;
font-weight: bold;
}
.message .irc-bg00,
.topicbar .irc-bg00,
.message .irc-bg0,
.topicbar .irc-bg0 {
background-color: #fff;
}
.message .irc-bg01,
.topicbar .irc-bg01,
.message .irc-bg1,
.topicbar .irc-bg1 {
background-color: #000;
}
.message .irc-bg02,
.topicbar .irc-bg02,
.message .irc-bg2,
.topicbar .irc-bg2 {
background-color: #000080;
}
.message .irc-bg03,
.topicbar .irc-bg03,
.message .irc-bg3,
.topicbar .irc-bg3 {
background-color: #008000;
}
.message .irc-bg04,
.topicbar .irc-bg04,
.message .irc-bg4,
.topicbar .irc-bg4 {
background-color: #f00;
}
.message .irc-bg05,
.topicbar .irc-bg05,
.message .irc-bg5,
.topicbar .irc-bg5 {
background-color: #a52a2a;
}
.message .irc-bg06,
.topicbar .irc-bg06,
.message .irc-bg6,
.topicbar .irc-bg6 {
background-color: #800080;
}
.message .irc-bg07,
.topicbar .irc-bg07,
.message .irc-bg7,
.topicbar .irc-bg7 {
background-color: #ffa500;
}
.message .irc-bg08,
.topicbar .irc-bg08,
.message .irc-bg8,
.topicbar .irc-bg8 {
background-color: #ff0;
}
.message .irc-bg09,
.topicbar .irc-bg09,
.message .irc-bg9,
.topicbar .irc-bg9 {
background-color: #0f0;
}
.message .irc-bg10,
.topicbar .irc-bg10 {
background-color: #008080;
}
.message .irc-bg11,
.topicbar .irc-bg11 {
background-color: #00d2d2;
}
.message .irc-bg12,
.topicbar .irc-bg12 {
background-color: #004aff;
}
.message .irc-bg13,
.topicbar .irc-bg13 {
background-color: #ffc0cb;
}
.message .irc-bg14,
.topicbar .irc-bg14 {
background-color: #808080;
}
.message .irc-bg15,
.topicbar .irc-bg15 {
background-color: #d3d3d3;
}
.message .irc-fg00,
.topicbar .irc-fg00,
.message .irc-fg0,
.topicbar .irc-fg0 {
color: #fff;
}
.message .irc-fg01,
.topicbar .irc-fg01,
.message .irc-fg1,
.topicbar .irc-fg1 {
color: #000;
}
.message .irc-fg02,
.topicbar .irc-fg02,
.message .irc-fg2,
.topicbar .irc-fg2 {
color: #000080;
}
.message .irc-fg03,
.topicbar .irc-fg03,
.message .irc-fg3,
.topicbar .irc-fg3 {
color: #008000;
}
.message .irc-fg04,
.topicbar .irc-fg04,
.message .irc-fg4,
.topicbar .irc-fg4 {
color: #f00;
}
.message .irc-fg05,
.topicbar .irc-fg05,
.message .irc-fg5,
.topicbar .irc-fg5 {
color: #a52a2a;
}
.message .irc-fg06,
.topicbar .irc-fg06,
.message .irc-fg6,
.topicbar .irc-fg6 {
color: #800080;
}
.message .irc-fg07,
.topicbar .irc-fg07,
.message .irc-fg7,
.topicbar .irc-fg7 {
color: #ffa500;
}
.message .irc-fg08,
.topicbar .irc-fg08,
.message .irc-fg8,
.topicbar .irc-fg8 {
color: #dcdc00;
}
.message .irc-fg09,
.topicbar .irc-fg09,
.message .irc-fg9,
.topicbar .irc-fg9 {
color: #00e600;
}
.message .irc-fg10,
.topicbar .irc-fg10 {
color: #008080;
}
.message .irc-fg11,
.topicbar .irc-fg11 {
color: #00d2d2;
}
.message .irc-fg12,
.topicbar .irc-fg12 {
color: #004aff;
}
.message .irc-fg13,
.topicbar .irc-fg13 {
color: #ffc0cb;
}
.message .irc-fg14,
.topicbar .irc-fg14 {
color: #808080;
}
.message .irc-fg15,
.topicbar .irc-fg15 {
color: #d3d3d3;
}
.message .irc-bold,
.topicbar .irc-bold {
font-weight: bold;
}
.message .irc-italic,
.topicbar .irc-italic {
font-style: italic;
}
.message .irc-underline,
.topicbar .irc-underline {
text-decoration: underline;
}
@-moz-keyframes hotTab {
50% {
background-color: #3ee4ff;
}
}
@-webkit-keyframes hotTab {
50% {
background-color: #3ee4ff;
}
}
@-o-keyframes hotTab {
50% {
background-color: #3ee4ff;
}
}
@keyframes hotTab {
50% {
background-color: #3ee4ff;
}
}

View File

@ -1,278 +0,0 @@
// Run `stylus -w styl -o css` to compile
props(prop, args)
-webkit-{prop} args
-moz-{prop} args
-ms-{prop} args
-o-{prop} args
{prop} args
transition()
props('transition', arguments)
body
margin: 0
padding: 0
font-family: Open Sans, Everson Mono, Helvetica
.grade1
margin-bottom: 0
margin-top: 0
display: block
text-align: center
.grade2
margin-bottom: 0
margin-top: 20px
display: block
text-align: center
.grade3
margin-bottom: 0
margin-top: 20px
display: block
text-align: center
.ircclient
position: absolute
width: 100%
height: 100%
.coverwindow
position: absolute
width: 100%
height: 100%
&#authdialog
z-index: 100
.wrapper
width: 320px
margin: auto
margin-top: 5%
padding: 15px
label
display: block
font-size: 80%
margin-top: 5px
&.autosize
width: auto
display: inline-block !important
font-size: 90% !important
margin-bottom: 10px
input[type=text], input[type=number], input[type=password]
padding: 8px;
width: 300px;
border-radius: 5px;
input[type="submit"]
width: 318px;
padding: 12px;
margin-top: 20px;
display: block;
border-radius: 4px;
font-size: 120%;
font-weight: bold;
text-transform: uppercase;
cursor: pointer
#chat
overflow: hidden;
.ircwrapper
position: absolute
width: 100%
height: 100%
.toolbar
height: 56px
position: relative
z-index: 15
.open_settings
width: 36px;
height: 36px;
display: inline-block;
position: absolute;
right: 10px;
top: 10px;
cursor: pointer;
transition transform 0.2s linear
&:hover
transform: rotateZ(-90deg);
.tabby
display: inline-block
height: 56px
position: absolute
right: 45px
left: 0
white-space: nowrap
overflow-x: auto
overflow-y: hidden
.tab
display: inline-block;
min-width: 60px;
height: 25px;
margin: 5px;
margin-right: 0;
padding: 10px;
line-height: 25px;
transition background-color 0.2s linear
border-radius: 5px;
cursor: pointer;
font-weight: 600;
#unread
display: inline-block;
min-width: 18px;
height: 18px;
text-align: center;
font-size: 12px;
margin: 0 5px;
line-height: 20px;
border-radius: 100%;
&.none
display: none;
#close
display: inline-block;
width: 12px;
text-align: center;
margin-left: 5px
.chatarea
position: absolute;
top: 56px;
width: 100%;
bottom: 46px;
.smsc-nicklistbtn
width: 46px;
height: 46px;
position: absolute;
top: 16px;
right: 16px;
border-radius: 100%;
display: none;
opacity: 0.5;
cursor: pointer;
.topicbar
position: absolute;
top: 0;
height: 20px;
right: 0;
left: 0;
padding: 12px;
display: none;
overflow: hidden;
z-index: 10
&:hover
height: auto
max-height: 100px
overflow: auto
word-wrap: break-word
.letterbox
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-y: auto;
white-space: pre-wrap;
word-wrap: break-word;
padding: 5px;
.nicklist
width: 280px;
position: absolute;
right: 0;
padding: 10px;
top: 0;
bottom: 0;
display: none;
z-index: 11;
overflow: auto;
.nick
cursor: pointer;
.nickname
font-size: 120%;
.prefix
width: 16px;
height: 16px;
line-height: 16px;
padding: 2px;
display: inline-block;
border-radius: 4px;
text-align: center;
margin-right: 5px;
font-weight: bold;
.no-prefix
width: 25px;
display: inline-block;
.settings
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 20px;
width: 60%;
min-width: 360px;
margin: auto;
overflow: auto;
.grade1, .grade2, .grade3
text-align: left;
&.vnicks
.nicklist
display: block;
.letterbox
right: 301px;
.topicbar
right: 301px;
&.vtopic
.topicbar
display: block;
.letterbox
top: 45px;
.input
position: absolute;
bottom: 0;
height: 46px;
width: 100%;
.my_nickname
margin: 5px;
padding: 7px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
padding-right: 20px;
margin-right: 0;
width: 183px;
overflow: hidden;
.inputwrapper
display: inline-block
position: absolute
margin: 5px 0
left: 210px
right: 55px
top: 0
input
width: 100%
padding: 6px
font-size: 120%
border-left: 0
.sendbutton
width: 32px;
position: absolute;
height: 32px;
float: right;
top: 5px;
right: 5px;
cursor: pointer;
@media all and (max-width: 600px)
.vnicks
.nicklist
display: none !important;
.letterbox
right: 0 !important;
.topicbar
right: 0 !important;
&.vopentrig
.nicklist
display: block !important;
.topicbar
right: 45px;
.smsc-nicklistbtn
z-index: 12;
display: block !important;
.my_nickname
display: none;
.inputwrapper
left: 38px !important;

View File

@ -1,15 +1,15 @@
const util = require("util"), const util = require('util');
config = require(__dirname+'/config'); const config = require(__dirname+'/config');
module.exports.log = function() { module.exports.log = function() {
console.log.apply(null, arguments); console.log.apply(null, arguments);
} };
module.exports.debugLog = function() { module.exports.debugLog = function() {
if(!config.server.debug) return; if(!config.server.debug) return;
console.log.apply(null, arguments); console.log.apply(null, arguments);
} };
module.exports.errorLog = function(errObj, specify) { module.exports.errorLog = function(errObj, specify) {
if(specify) if(specify)
@ -19,8 +19,7 @@ module.exports.errorLog = function(errObj, specify) {
if(errObj.stack) if(errObj.stack)
console.error(errObj.stack); console.error(errObj.stack);
} };
module.exports.printRuntimeStats = function(runtime_stats, connections) { module.exports.printRuntimeStats = function(runtime_stats, connections) {
if(!config.server.printStats) return; if(!config.server.printStats) return;
@ -35,7 +34,7 @@ module.exports.printRuntimeStats = function(runtime_stats, connections) {
users += 1; users += 1;
for(let snam in ca) { for(let snam in ca) {
if(!snam) continue; if(!snam) continue;
if(snam == "host") continue; if(snam == 'host') continue;
servers += 1; servers += 1;
} }
} }
@ -43,9 +42,9 @@ module.exports.printRuntimeStats = function(runtime_stats, connections) {
if(users != 0) // Don't divide by zero lmao if(users != 0) // Don't divide by zero lmao
serversPerUser = servers/users; serversPerUser = servers/users;
console.log(date+": Currently connected users: "+users+";", console.log(date+': Currently connected users: {0};' +
"IRC server connections: "+servers+";", 'IRC server connections: {1};' +
"Average servers per user: "+serversPerUser+";", 'Average servers per user: {2};' +
"Total connections made: "+runtime_stats.connectionsMade+";", 'Total connections made: {3};' +
"Uptime: "+process.uptime()+"s;"); 'Uptime: {4}s;'.format(users, servers, serversPerUser, runtime_stats.connectionsMade, process.uptime()));
} };

View File

@ -4,4 +4,4 @@ let parser = require(__dirname+'/parser.js');
module.exports = { module.exports = {
IRCConnection: connector, IRCConnection: connector,
Parser: parser Parser: parser
} };

View File

@ -1,16 +1,7 @@
const EventEmitter = require('events').EventEmitter, const EventEmitter = require('events').EventEmitter;
net = require('net'), const net = require('net');
tls = require('tls'), const tls = require('tls');
parse = require(__dirname+"/parser"); const parse = require(__dirname+'/parser');
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != undefined ? args[number] : match;
});
};
}
class IRCConnectionHandler { class IRCConnectionHandler {
constructor(connection) { constructor(connection) {
@ -19,40 +10,40 @@ class IRCConnectionHandler {
handleUserLine(data) { handleUserLine(data) {
switch(data.command) { switch(data.command) {
case "topic": case 'topic':
this.conn.write(('{0} {1}'+(data.message != '' ? ' :'+data.message : '')).format(data.command.toUpperCase(), data.arguments[0])); this.conn.write(('{0} {1}'+(data.message != '' ? ' :'+data.message : '')).format(data.command.toUpperCase(), data.arguments[0]));
break; break;
case "kick": case 'kick':
this.conn.write('{0} {1} :{2}'.format(data.command.toUpperCase(), data.arguments.join(' '), data.message)); this.conn.write('{0} {1} :{2}'.format(data.command.toUpperCase(), data.arguments.join(' '), data.message));
break; break;
case "part": case 'part':
this.conn.write('{0} {1} :{2}'.format(data.command.toUpperCase(), data.arguments[0], data.message)); this.conn.write('{0} {1} :{2}'.format(data.command.toUpperCase(), data.arguments[0], data.message));
break; break;
case "nick": case 'nick':
case "whois": case 'whois':
case "who": case 'who':
case "names": case 'names':
case "join": case 'join':
this.conn.write('{0} {1}'.format(data.command.toUpperCase(), data.arguments[0])); this.conn.write('{0} {1}'.format(data.command.toUpperCase(), data.arguments[0]));
break; break;
case "quit": case 'quit':
this.conn.write('{0} :{1}'.format(data.command.toUpperCase(), (data.message == '' ? this.conn.write('{0} :{1}'.format(data.command.toUpperCase(), (data.message == '' ?
this.conn.globalConfig.default_quit_msg : data.message))); this.conn.globalConfig.default_quit_msg : data.message)));
break; break;
case "privmsg": case 'privmsg':
this.conn.write('PRIVMSG {0} :{1}'.format(data.arguments[0], data.message)); this.conn.write('PRIVMSG {0} :{1}'.format(data.arguments[0], data.message));
this.conn.emit('pass_to_client', {type: "message", messageType: "privmsg", to: data.arguments[0], this.conn.emit('pass_to_client', {type: 'message', messageType: 'privmsg', to: data.arguments[0],
user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server}); user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server});
break; break;
case "notice": case 'notice':
this.conn.write('NOTICE {0} :{1}'.format(data.arguments[0], data.message)); this.conn.write('NOTICE {0} :{1}'.format(data.arguments[0], data.message));
this.conn.emit('pass_to_client', {type: "message", messageType: "notice", to: data.arguments[0], this.conn.emit('pass_to_client', {type: 'message', messageType: 'notice', to: data.arguments[0],
user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server}); user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server});
break; break;
case "list": case 'list':
this.conn.write(data.command.toUpperCase()); this.conn.write(data.command.toUpperCase());
break; break;
case "ctcp": case 'ctcp':
let ctcpmsg = ''; let ctcpmsg = '';
if(data.arguments[1].toLowerCase() == 'ping') if(data.arguments[1].toLowerCase() == 'ping')
@ -61,15 +52,15 @@ class IRCConnectionHandler {
ctcpmsg = data.message; ctcpmsg = data.message;
this.conn.write('PRIVMSG {0} :\x01{1}\x01'.format(data.arguments[0], ctcpmsg)); this.conn.write('PRIVMSG {0} :\x01{1}\x01'.format(data.arguments[0], ctcpmsg));
this.conn.emit('pass_to_client', {type: "message", messageType: "ctcp_request", to: this.conn.config.nickname, this.conn.emit('pass_to_client', {type: 'message', messageType: 'ctcp_request', to: this.conn.config.nickname,
user: {nickname: data.arguments[0]}, message: ctcpmsg, server: data.server}); user: {nickname: data.arguments[0]}, message: ctcpmsg, server: data.server});
break; break;
default: default:
this.conn.write(data.command.toUpperCase()+' '+data.message); this.conn.write(data.command.toUpperCase()+' '+data.message);
} }
if(data.targetType == "channel" || data.targetType == "message") { if(data.targetType == 'channel' || data.targetType == 'message') {
this.conn.write('PRIVMSG {0} :{1}'.format(data.target, data.message)); this.conn.write('PRIVMSG {0} :{1}'.format(data.target, data.message));
this.conn.emit('pass_to_client', {type: "message", messageType: "privmsg", to: data.target, this.conn.emit('pass_to_client', {type: 'message', messageType: 'privmsg', to: data.target,
user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server}); user: {nickname: this.conn.config.nickname}, message: data.message, server: data.server});
} }
} }
@ -91,12 +82,12 @@ class IRCConnectionHandler {
if(!line[0]) return; if(!line[0]) return;
line[0] = line[0].toUpperCase(); line[0] = line[0].toUpperCase();
let resp = "\x01"+line[0]+" {0}\x01"; let resp = '\x01'+line[0]+' {0}\x01';
if(line[0] == "PING" && line[1] != null && line[1] != '') { if(line[0] == 'PING' && line[1] != null && line[1] != '') {
resp = resp.format(line.slice(1).join(' ')); resp = resp.format(line.slice(1).join(' '));
} else if(line[0] == "CLIENTINFO") { } else if(line[0] == 'CLIENTINFO') {
resp = resp.format("CLIENTINFO PING "+Object.keys(this.conn.extras.ctcps).join(" ")); resp = resp.format('CLIENTINFO PING '+Object.keys(this.conn.extras.ctcps).join(' '));
} else if(this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) { } else if(this.conn.extras.ctcps && this.conn.extras.ctcps[line[0]] != null) {
resp = resp.format(this.conn.extras.ctcps[line[0]](data, this.conn)); resp = resp.format(this.conn.extras.ctcps[line[0]](data, this.conn));
} else { } else {
@ -104,15 +95,15 @@ class IRCConnectionHandler {
} }
if (resp != null) if (resp != null)
this.conn.write("NOTICE {0} :{1}".format(data.user.nickname, resp)); this.conn.write('NOTICE {0} :{1}'.format(data.user.nickname, resp));
return resp != null; return resp != null;
} }
handleServerLine(line) { handleServerLine(line) {
if(this.conn.queue["supportsmsg"] && line.command != "005") { if(this.conn.queue['supportsmsg'] && line.command != '005') {
delete this.conn.queue["supportsmsg"]; delete this.conn.queue['supportsmsg'];
if(this.conn.config.autojoin.length > 0) if(this.conn.config.autojoin.length > 0)
for(let t in this.conn.config.autojoin) for(let t in this.conn.config.autojoin)
@ -128,15 +119,15 @@ class IRCConnectionHandler {
let list = null; let list = null;
switch(line.command) { switch(line.command) {
case "error": case 'error':
this.conn.emit("connerror", {type: "irc_error", raw: line.raw}); this.conn.emit('connerror', {type: 'irc_error', raw: line.raw});
break; break;
case "001": case '001':
this.conn.data.actualServer = line.user.hostname; this.conn.data.actualServer = line.user.hostname;
break break;
case "005": case '005':
if(!this.conn.queue["supportsmsg"]) if(!this.conn.queue['supportsmsg'])
this.conn.queue["supportsmsg"] = true; this.conn.queue['supportsmsg'] = true;
this.conn.authenticated = true; this.conn.authenticated = true;
@ -163,129 +154,129 @@ class IRCConnectionHandler {
} }
} }
break; break;
case "JOIN": case 'JOIN':
if(line.trailing) { if(line.trailing) {
this.conn.emit('pass_to_client', {type: "event_join_channel", user: line.user, channel: line.trailing, server: serverName }); this.conn.emit('pass_to_client', {type: 'event_join_channel', user: line.user, channel: line.trailing, server: serverName });
} else { } else {
for(let i in line.arguments) { for(let i in line.arguments) {
this.conn.emit('pass_to_client', {type: "event_join_channel", user: line.user, channel: line.arguments[i], server: serverName }); this.conn.emit('pass_to_client', {type: 'event_join_channel', user: line.user, channel: line.arguments[i], server: serverName });
} }
} }
break; break;
case "PART": case 'PART':
this.conn.emit('pass_to_client', {type: "event_part_channel", user: line.user, channel: line.arguments[0], reason: line.trailing, server: serverName }); this.conn.emit('pass_to_client', {type: 'event_part_channel', user: line.user, channel: line.arguments[0], reason: line.trailing, server: serverName });
break; break;
case "QUIT": case 'QUIT':
this.conn.emit('pass_to_client', {type: "event_quit", user: line.user, reason: line.trailing, server: serverName }); this.conn.emit('pass_to_client', {type: 'event_quit', user: line.user, reason: line.trailing, server: serverName });
break; break;
case "353": case '353':
if(!this.conn.queue["names"]) if(!this.conn.queue['names'])
this.conn.queue['names'] = {}; this.conn.queue['names'] = {};
let splittrail = line.trailing.split(' '); let splittrail = line.trailing.split(' ');
for(let a in splittrail) { for(let a in splittrail) {
let nick = splittrail[a]; let nick = splittrail[a];
if(nick.trim() == "") continue; if(nick.trim() == '') continue;
if(this.conn.queue["names"][line.arguments[2]]) if(this.conn.queue['names'][line.arguments[2]])
this.conn.queue["names"][line.arguments[2]].push(nick); this.conn.queue['names'][line.arguments[2]].push(nick);
else else
this.conn.queue["names"][line.arguments[2]] = [nick]; this.conn.queue['names'][line.arguments[2]] = [nick];
} }
break; break;
case "366": case '366':
if(!this.conn.queue["names"]) break; if(!this.conn.queue['names']) break;
if(this.conn.queue["names"][line.arguments[1]]) { if(this.conn.queue['names'][line.arguments[1]]) {
this.conn.emit('pass_to_client', {type: "channel_nicks", channel: line.arguments[1], nicks: this.conn.queue["names"][line.arguments[1]], server: serverName}); this.conn.emit('pass_to_client', {type: 'channel_nicks', channel: line.arguments[1], nicks: this.conn.queue['names'][line.arguments[1]], server: serverName});
delete this.conn.queue["names"][line.arguments[1]]; delete this.conn.queue['names'][line.arguments[1]];
} }
if(Object.keys(this.conn.queue["names"]).length == 0) if(Object.keys(this.conn.queue['names']).length == 0)
delete this.conn.queue["names"]; delete this.conn.queue['names'];
break; break;
case "PRIVMSG": case 'PRIVMSG':
if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0) if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0)
return this.ctcpManage(line); return this.ctcpManage(line);
if(line.user.nickname != "") if(line.user.nickname != '')
this.conn.emit('pass_to_client', {type: "message", messageType: "privmsg", to: line.arguments[0], this.conn.emit('pass_to_client', {type: 'message', messageType: 'privmsg', to: line.arguments[0],
user: line.user, message: line.trailing, server: serverName}); user: line.user, message: line.trailing, server: serverName});
else else
this.conn.emit('pass_to_client', {type: "server_message", messageType: "privmsg", message: line.trailing, server: serverName, from: realServerName}); this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'privmsg', message: line.trailing, server: serverName, from: realServerName});
break; break;
case "NOTICE": case 'NOTICE':
if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0) { if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0) {
let composethis = line.trailing.replace(/\x01/g,'').trim().split(" "); let composethis = line.trailing.replace(/\x01/g,'').trim().split(' ');
composethis[0] = composethis[0].toUpperCase(); composethis[0] = composethis[0].toUpperCase();
let message = composethis.join(" "); let message = composethis.join(' ');
if(composethis[0] == 'PING') if(composethis[0] == 'PING')
message = Math.floor(Date.now()/1000) - composethis[1]+"s"; message = Math.floor(Date.now()/1000) - composethis[1]+'s';
this.conn.emit('pass_to_client', {type: "message", messageType: "ctcp_response", to: line.arguments[0], this.conn.emit('pass_to_client', {type: 'message', messageType: 'ctcp_response', to: line.arguments[0],
user: line.user, message: message, server: serverName}); user: line.user, message: message, server: serverName});
return; return;
} }
if(line.user.nickname != "") if(line.user.nickname != '')
this.conn.emit('pass_to_client', {type: "message", messageType: "notice", to: line.arguments[0], this.conn.emit('pass_to_client', {type: 'message', messageType: 'notice', to: line.arguments[0],
user: line.user, message: line.trailing, server: serverName}); user: line.user, message: line.trailing, server: serverName});
else else
this.conn.emit('pass_to_client', {type: "server_message", messageType: "notice", message: line.trailing, server: serverName, from: realServerName}); this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'notice', message: line.trailing, server: serverName, from: realServerName});
break; break;
case "NICK": case 'NICK':
if(line.user.nickname == this.conn.config.nickname) if(line.user.nickname == this.conn.config.nickname)
this.conn.config.nickname = line.arguments[0]; this.conn.config.nickname = line.arguments[0];
this.conn.emit('pass_to_client', {type: "nick_change", nick: line.user.nickname, newNick: line.arguments[0], server: serverName}); this.conn.emit('pass_to_client', {type: 'nick_change', nick: line.user.nickname, newNick: line.arguments[0], server: serverName});
break; break;
case "KICK": case 'KICK':
this.conn.emit('pass_to_client', {type: "event_kick_channel", user: line.user, channel: line.arguments[0], reason: line.trailing, kickee: line.arguments[1], server: serverName}); this.conn.emit('pass_to_client', {type: 'event_kick_channel', user: line.user, channel: line.arguments[0], reason: line.trailing, kickee: line.arguments[1], server: serverName});
break; break;
case "TOPIC": case 'TOPIC':
this.conn.emit('pass_to_client', {type: "channel_topic", channel: line.arguments[0], set_by: line.user.nickname, topic: line.trailing, server: serverName}); this.conn.emit('pass_to_client', {type: 'channel_topic', channel: line.arguments[0], set_by: line.user.nickname, topic: line.trailing, server: serverName});
break; break;
case "332": case '332':
this.conn.emit('pass_to_client', {type: "channel_topic", channel: line.arguments[1], topic: line.trailing, server: serverName}); this.conn.emit('pass_to_client', {type: 'channel_topic', channel: line.arguments[1], topic: line.trailing, server: serverName});
break; break;
case "333": case '333':
this.conn.emit('pass_to_client', {type: "channel_topic", channel: line.arguments[1], set_by: line.arguments[2], time: line.arguments[3], server: serverName}); this.conn.emit('pass_to_client', {type: 'channel_topic', channel: line.arguments[1], set_by: line.arguments[2], time: line.arguments[3], server: serverName});
break; break;
case "375": case '375':
case "372": case '372':
case "376": case '376':
this.conn.emit('pass_to_client', {type: "server_message", messageType: "motd", message: line.trailing, server: serverName, from: realServerName}); this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'motd', message: line.trailing, server: serverName, from: realServerName});
break; break;
case "006": case '006':
case "007": case '007':
case "251": case '251':
case "255": case '255':
case "270": case '270':
case "290": case '290':
case "292": case '292':
case "323": case '323':
case "351": case '351':
case "381": case '381':
this.conn.emit('pass_to_client', {type: "server_message", messageType: "regular", message: line.trailing, server: serverName, from: realServerName}); this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'regular', message: line.trailing, server: serverName, from: realServerName});
break; break;
case "252": case '252':
case "254": case '254':
case "396": case '396':
case "042": case '042':
this.conn.emit('pass_to_client', {type: "server_message", messageType: "regular", message: line.arguments[1] +" "+ line.trailing, server: serverName, from: realServerName}); this.conn.emit('pass_to_client', {type: 'server_message', messageType: 'regular', message: line.arguments[1] +' '+ line.trailing, server: serverName, from: realServerName});
break; break;
case "501": case '501':
case "401": case '401':
case "402": case '402':
case "421": case '421':
case "482": case '482':
case "331": case '331':
case "432": case '432':
this.conn.emit('pass_to_client', {type: "message", to: null, message: line.arguments[1]+': '+line.trailing, this.conn.emit('pass_to_client', {type: 'message', to: null, message: line.arguments[1]+': '+line.trailing,
server: serverName, user: {nickname: realServerName}, messageType: "error"}); server: serverName, user: {nickname: realServerName}, messageType: 'error'});
break; break;
case "MODE": case 'MODE':
let isChannelMode = false; let isChannelMode = false;
let method = '+'; let method = '+';
if(line.arguments[0].indexOf('#') != -1) if(line.arguments[0].indexOf('#') != -1)
@ -308,7 +299,7 @@ class IRCConnectionHandler {
for(let i in modes) { for(let i in modes) {
let mode = modes[i]; let mode = modes[i];
if(this.conn.data.supportedModes[mode]) if(this.conn.data.supportedModes[mode])
this.conn.emit('pass_to_client', {type: "mode_"+(method=='+'?'add':'del'), target: line.arguments[0], mode: mode, this.conn.emit('pass_to_client', {type: 'mode_'+(method=='+'?'add':'del'), target: line.arguments[0], mode: mode,
modeTarget: line.arguments[2+parseInt(i)], server: serverName, user: {nickname: sender}}); modeTarget: line.arguments[2+parseInt(i)], server: serverName, user: {nickname: sender}});
else else
pass.push(mode); pass.push(mode);
@ -318,106 +309,106 @@ class IRCConnectionHandler {
} }
if(pass.length > 0) if(pass.length > 0)
this.conn.emit('pass_to_client', {type: "mode", target: line.arguments[0], message: method+pass.join(''), this.conn.emit('pass_to_client', {type: 'mode', target: line.arguments[0], message: method+pass.join(''),
server: serverName, user: {nickname: sender}}); server: serverName, user: {nickname: sender}});
break; break;
case "433": case '433':
let newNick = this.conn.config.nickname + "_"; let newNick = this.conn.config.nickname + '_';
this.conn.write('NICK '+newNick); this.conn.write('NICK '+newNick);
this.conn.config.nickname = newNick; this.conn.config.nickname = newNick;
break; break;
case "311": case '311':
// start whois queue // start whois queue
list = { list = {
nickname: line.arguments[1], nickname: line.arguments[1],
hostmask: "{0}!{1}@{2}".format(line.arguments[1], line.arguments[2], line.arguments[3]), hostmask: '{0}!{1}@{2}'.format(line.arguments[1], line.arguments[2], line.arguments[3]),
realname: line.trailing || "" realname: line.trailing || ''
}; };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "319": case '319':
// whois: channels // whois: channels
list = { list = {
channels: line.trailing.split(" "), channels: line.trailing.split(' '),
}; };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "378": case '378':
list = { list = {
connectingFrom: line.trailing, connectingFrom: line.trailing,
}; };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "379": case '379':
list = { list = {
usingModes: line.trailing, usingModes: line.trailing,
}; };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "312": case '312':
list = { list = {
server: line.arguments[2], server: line.arguments[2],
server_name: line.trailing || "" server_name: line.trailing || ''
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "313": case '313':
list = { list = {
title: line.trailing title: line.trailing
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "330": case '330':
list = { list = {
loggedIn: line.trailing+' '+line.arguments[2] loggedIn: line.trailing+' '+line.arguments[2]
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "335": case '335':
list = { list = {
bot: true bot: true
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "307": case '307':
list = { list = {
registered: line.trailing registered: line.trailing
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "671": case '671':
list = { list = {
secure: true secure: true
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "317": case '317':
list = { list = {
signonTime: line.arguments[3], signonTime: line.arguments[3],
idleSeconds: line.arguments[2] idleSeconds: line.arguments[2]
} };
this.whoisManage(line.arguments[1], list); this.whoisManage(line.arguments[1], list);
break; break;
case "318": case '318':
if(!this.conn.queue.whois || !this.conn.queue.whois[line.arguments[1]]) if(!this.conn.queue.whois || !this.conn.queue.whois[line.arguments[1]])
return; return;
this.conn.emit('pass_to_client', {type: "whoisResponse", whois: this.conn.queue.whois[line.arguments[1]], this.conn.emit('pass_to_client', {type: 'whoisResponse', whois: this.conn.queue.whois[line.arguments[1]],
server: serverName, from: realServerName}); server: serverName, from: realServerName});
delete this.conn.queue.whois[line.arguments[1]]; delete this.conn.queue.whois[line.arguments[1]];
break; break;
case "321": case '321':
this.conn.emit('pass_to_client', {type: "listedchan", channel: "Channel", users: "Users", topic: "Topic", this.conn.emit('pass_to_client', {type: 'listedchan', channel: 'Channel', users: 'Users', topic: 'Topic',
server: serverName, from: realServerName}); server: serverName, from: realServerName});
break; break;
case "322": case '322':
this.conn.emit('pass_to_client', {type: "listedchan", channel: line.arguments[1], users: line.arguments[2], topic: line.trailing, this.conn.emit('pass_to_client', {type: 'listedchan', channel: line.arguments[1], users: line.arguments[2], topic: line.trailing,
server: serverName, from: realServerName}); server: serverName, from: realServerName});
break; break;
case "CAP": case 'CAP':
// might come in the future, who knows // might come in the future, who knows
this.conn.write("CAP END"); this.conn.write('CAP END');
break; break;
} }
} }
@ -430,15 +421,15 @@ class IRCConnection extends EventEmitter {
this.globalConfig = globalConfig; this.globalConfig = globalConfig;
this.extras = extras || { authenticationSteps: [], ctcps: {} }; this.extras = extras || { authenticationSteps: [], ctcps: {} };
this.config = { this.config = {
nickname: "teemant", nickname: 'teemant',
username: globalConfig.username, username: globalConfig.username,
realname: globalConfig.realname, realname: globalConfig.realname,
server: "localhost", server: 'localhost',
port: 6667, port: 6667,
autojoin: [], autojoin: [],
secure: globalConfig.secure_by_default, secure: globalConfig.secure_by_default,
password: "", password: '',
address: "0.0.0.0", address: '0.0.0.0',
rejectUnauthorized: globalConfig.rejectUnauthorizedCertificates rejectUnauthorized: globalConfig.rejectUnauthorizedCertificates
}; };
@ -464,7 +455,7 @@ class IRCConnection extends EventEmitter {
} }
on(...args) { on(...args) {
return super.on(...args) return super.on(...args);
} }
emit(...args) { emit(...args) {
@ -482,19 +473,19 @@ class IRCConnection extends EventEmitter {
this.socket.setTimeout(this.globalConfig.timeout); this.socket.setTimeout(this.globalConfig.timeout);
this.socket.on('error', (data) => { this.socket.on('error', (data) => {
this.emit('connerror', {type: "sock_error", message: "A socket error occured.", raw: data}); this.emit('connerror', {type: 'sock_error', message: 'A socket error occured.', raw: data});
}); });
this.socket.on('lookup', (err, address, family, host) => { this.socket.on('lookup', (err, address, family, host) => {
if(err) { if(err) {
this.emit('connerror', {type: "resolve_error", message: "Failed to resolve host."}); this.emit('connerror', {type: 'resolve_error', message: 'Failed to resolve host.'});
} else { } else {
this.emit('lookup', {address: address, family: address, host: host}); this.emit('lookup', {address: address, family: address, host: host});
this.config.address = address; this.config.address = address;
} }
}); });
let buffer = ""; let buffer = '';
this.socket.on('data', (chunk) => { this.socket.on('data', (chunk) => {
buffer += chunk; buffer += chunk;
let data = buffer.split('\r\n'); let data = buffer.split('\r\n');
@ -502,7 +493,7 @@ class IRCConnection extends EventEmitter {
data.forEach((line) => { data.forEach((line) => {
if(line.indexOf('PING') === 0) { if(line.indexOf('PING') === 0) {
this.socket.write('PONG'+line.substring(4)+'\r\n'); this.socket.write('PONG'+line.substring(4)+'\r\n');
return return;
} }
this.emit('raw', line); this.emit('raw', line);
let parsed = parse(line); let parsed = parse(line);
@ -513,11 +504,11 @@ class IRCConnection extends EventEmitter {
this.socket.on('close', (data) => { this.socket.on('close', (data) => {
if(!this.queue['close']) if(!this.queue['close'])
this.emit('closed', {type: "sock_closed", raw: data, message: "Connection closed."}); this.emit('closed', {type: 'sock_closed', raw: data, message: 'Connection closed.'});
this.connected = false; this.connected = false;
this.authenticated = false; this.authenticated = false;
}) });
} }
authenticate() { authenticate() {
@ -537,7 +528,7 @@ class IRCConnection extends EventEmitter {
disconnect(message) { disconnect(message) {
if(!this.connected) { if(!this.connected) {
this.emit('connerror', {type: "sock_closed", message: "Connection already closed."}); this.emit('connerror', {type: 'sock_closed', message: 'Connection already closed.'});
return; return;
} }
@ -547,7 +538,7 @@ class IRCConnection extends EventEmitter {
write(message) { write(message) {
if(!this.connected) { if(!this.connected) {
this.emit('connerror', {type: "sock_closed", message: "Connection is closed."}); this.emit('connerror', {type: 'sock_closed', message: 'Connection is closed.'});
return; return;
} }
this.socket.write(message+'\r\n'); this.socket.write(message+'\r\n');

View File

@ -5,14 +5,14 @@
function parseERROR(line) { function parseERROR(line) {
let final = { let final = {
user: { nickname: "", username: "", hostname: "" }, user: { nickname: '', username: '', hostname: '' },
command: "ERROR", command: 'ERROR',
message: "", message: '',
raw: line.join(" ") raw: line.join(' ')
} };
let pass1 = line.slice(1).join(" "); let pass1 = line.slice(1).join(' ');
if(pass1.indexOf(":") == 0) if(pass1.indexOf(':') == 0)
pass1 = pass1.substring(1); pass1 = pass1.substring(1);
final.message = pass1; final.message = pass1;
@ -23,21 +23,21 @@ function parseERROR(line) {
module.exports = function(rawline) { module.exports = function(rawline) {
let final = { let final = {
user: { user: {
nickname: "", nickname: '',
username: "", username: '',
hostname: "" hostname: ''
}, },
command: "", command: '',
arguments: [], arguments: [],
trailing: "", trailing: '',
raw: rawline raw: rawline
} };
let pass1 = (rawline.indexOf(':') == 0 ? rawline.substring(1).split(" ") : rawline.split(" ")); let pass1 = (rawline.indexOf(':') == 0 ? rawline.substring(1).split(' ') : rawline.split(' '));
if (pass1[0] === "ERROR") if (pass1[0] === 'ERROR')
return parseERROR(pass1); return parseERROR(pass1);
if(pass1[0].indexOf("!") != -1) { if(pass1[0].indexOf('!') != -1) {
let nickuser = pass1[0].split('!'); let nickuser = pass1[0].split('!');
final.user.nickname = nickuser[0]; final.user.nickname = nickuser[0];
let userhost = nickuser[1].split('@'); let userhost = nickuser[1].split('@');
@ -49,13 +49,13 @@ module.exports = function(rawline) {
final.command = pass1[1]; final.command = pass1[1];
let pass2 = pass1.slice(2).join(" "); let pass2 = pass1.slice(2).join(' ');
if(pass2.indexOf(":") != -1) { if(pass2.indexOf(':') != -1) {
final.arguments = pass2.substring(0, pass2.indexOf(' :')).split(" "); final.arguments = pass2.substring(0, pass2.indexOf(' :')).split(' ');
final.trailing = pass2.substring(pass2.indexOf(':')+1); final.trailing = pass2.substring(pass2.indexOf(':')+1);
} else { } else {
final.arguments = pass2.split(" "); final.arguments = pass2.split(' ');
} }
return final; return final;
} };

View File

@ -1,9 +1,9 @@
const dns = require("dns"), const dns = require('dns');
fs = require("fs"), const fs = require('fs');
path = require("path"), const path = require('path');
config = require(__dirname+'/config'), const config = require(__dirname+'/config');
logger = require(__dirname+'/logger'), const logger = require(__dirname+'/logger');
webirc_data_path = path.resolve(__dirname+'/../webirc.data.json'); const webirc_data_path = path.resolve(__dirname+'/../webirc.data.json');
let webirc_data = {}; let webirc_data = {};
let timeouts = {}; let timeouts = {};
@ -16,11 +16,11 @@ function timeoutRefresh(address, seconds) {
if(timeouts[address]) if(timeouts[address])
clearTimeout(timeouts[address]); clearTimeout(timeouts[address]);
timeouts[address] = setTimeout(()=>{resolveAddress(address)}, seconds*1000); timeouts[address] = setTimeout(()=>{resolveAddress(address);}, seconds*1000);
} }
function resolveAddress(address, force) { function resolveAddress(address, force) {
logger.debugLog("** WEBIRC ** Attempting to update IP for "+address); logger.debugLog('** WEBIRC ** Attempting to update IP for '+address);
let obj = webirc_data[address]; let obj = webirc_data[address];
if(!obj) return; if(!obj) return;
@ -28,7 +28,7 @@ function resolveAddress(address, force) {
if((Date.now() - obj.last_update)/1000 < config.webirc.resolveInterval && !force) { if((Date.now() - obj.last_update)/1000 < config.webirc.resolveInterval && !force) {
let nextTime = (config.webirc.resolveInterval - (Date.now() - obj.last_update)/1000); let nextTime = (config.webirc.resolveInterval - (Date.now() - obj.last_update)/1000);
logger.debugLog("** WEBIRC ** "+address+" IP is "+obj.cached_ip+", refresh in "+nextTime+" seconds"); logger.debugLog('** WEBIRC ** {0} IP is {1}, refresh in {2} seconds'.format(address, obj.cached_ip, Math.floor(nextTime)));
return timeoutRefresh(address, nextTime); return timeoutRefresh(address, nextTime);
} }
@ -40,11 +40,11 @@ function resolveAddress(address, force) {
if(ip) { if(ip) {
resolve(ip); resolve(ip);
} else { } else {
reject(new Error("no ips")); reject(new Error('no ips'));
} }
}); });
}).then((data) => { }).then((data) => {
logger.debugLog("** WEBIRC ** Updated DNS for "+address+"; IP is now "+data); logger.debugLog('** WEBIRC ** Updated DNS for {0}; IP is now {1}'.format(address, data));
webirc_data[address].last_update = Date.now(); webirc_data[address].last_update = Date.now();
webirc_data[address].cached_ip = data; webirc_data[address].cached_ip = data;
@ -52,7 +52,7 @@ function resolveAddress(address, force) {
writeToFile(); writeToFile();
timeoutRefresh(address, config.webirc.resolveInterval); timeoutRefresh(address, config.webirc.resolveInterval);
}, (err) => { }, (err) => {
logger.debugLog("** WEBIRC ** Failed to updated DNS for "+address+"; IP is still "+webirc_data[address].cached_ip); logger.debugLog('** WEBIRC ** Failed to updated DNS for {0}; IP is still {1}'.format(address, webirc_data[address].cached_ip));
timeoutRefresh(address, (config.webirc.resolveInterval+60)); timeoutRefresh(address, (config.webirc.resolveInterval+60));
}); });
@ -96,8 +96,8 @@ class WebIRCAuthenticator {
authenticate(connection) { authenticate(connection) {
let serverpass = get_password(connection.config.address); let serverpass = get_password(connection.config.address);
if(serverpass) if(serverpass)
connection.socket.write('WEBIRC '+serverpass.password+' '+connection.config.username+ connection.socket.write('WEBIRC {0} {1} {2} {3}\r\n'.format(serverpass.password, connection.config.username,
' '+this.userInfo.hostname+' '+this.userInfo.ipaddr+'\r\n'); this.userInfo.hostname, this.userInfo.ipaddr));
} }
} }
@ -109,7 +109,7 @@ module.exports = {
}; };
process.on('SIGUSR1', () => { process.on('SIGUSR1', () => {
logger.log("\n!!! Received SIGUSR1; Reloading webirc data.. !!!\n"); logger.log('\n!!! Received SIGUSR1; Reloading webirc data.. !!!\n');
reload(true); reload(true);
}); });

View File

@ -9,13 +9,11 @@
<script src=//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.3.10/seedrandom.min.js></script> <script src=//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.3.10/seedrandom.min.js></script>
<script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript" src="js/main.js"></script> <script type="text/javascript" src="script/main.js"></script>
<script type="text/javascript" src="js/colorparser.js"></script>
<script type="text/javascript" src="js/theme.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="css/layout.css"> <link rel="stylesheet" type="text/css" href="style/layout.css">
<link rel="stylesheet" type="text/css" href="css/theme_default.css" id="theme_stylesheet"> <link rel="stylesheet" type="text/css" href="style/theme_default.css" id="theme_stylesheet">
</head> </head>
<!-- Codepony Diamond --> <!-- Codepony Diamond -->
<body> <body>

View File

@ -2,33 +2,35 @@
// Lol, I just gave credit, didn't I.. // Lol, I just gave credit, didn't I..
// Dammit, well, there's that. // Dammit, well, there's that.
let styleCheck_Re = /[\x00-\x1F]/, back_re = /^(\d{1,2})(,(\d{1,2}))?/, const styleCheck_Re = /[\x00-\x1F]/;
colourKey = "\x03", colour_re = /\x03/g, const back_re = /^(\d{1,2})(,(\d{1,2}))?/;
styleBreak = "\x0F"; // breaks all open styles ^O (\x0F) const colourKey = '\x03';
const colour_re = /\x03/g;
const styleBreak = '\x0F'; // breaks all open styles ^O (\x0F)
let styles = [ let styles = [
["normal", "\x00", ""], ["underline", "\x1F"], ['normal', '\x00', ''], ['underline', '\x1F'],
["bold", "\x02"], ["italic", "\x1D"] ['bold', '\x02'], ['italic', '\x1D']
].map(function(style) { ].map(function(style) {
var escaped = encodeURI(style[1]).replace("%", "\\x"); var escaped = encodeURI(style[1]).replace('%', '\\x');
return { return {
name: style[0], name: style[0],
style: style[2] != null ? style[2] : "irc-" + style[0], style: style[2] != null ? style[2] : 'irc-' + style[0],
key: style[1], key: style[1],
keyregex: new RegExp(escaped + "(.*?)(" + escaped + "|$)") keyregex: new RegExp(escaped + '(.*?)(' + escaped + '|$)')
}; };
}); });
//http://www.mirc.com/colors.html //http://www.mirc.com/colors.html
let colors = [ let colors = [
"white", "black", "navy", "green", "red", "brown", 'white', 'black', 'navy', 'green', 'red', 'brown',
"purple", "olive", "yellow", "lightgreen", "teal", 'purple', 'olive', 'yellow', 'lightgreen', 'teal',
"cyan", "blue", "pink", "gray", "lightgrey" 'cyan', 'blue', 'pink', 'gray', 'lightgrey'
].reduce(function(memo, name, index) { ].reduce(function(memo, name, index) {
memo[index] = { memo[index] = {
name: name, name: name,
fore: "irc-fg" + index, fore: 'irc-fg' + index,
back: "irc-bg" + index, back: 'irc-bg' + index,
key: index key: index
}; };
return memo; return memo;
@ -40,29 +42,29 @@ function stylize(line) {
// split up by the irc style break character ^O // split up by the irc style break character ^O
if (line.indexOf(styleBreak) >= 0) { if (line.indexOf(styleBreak) >= 0) {
return line.split(styleBreak).map(stylize).join(""); return line.split(styleBreak).map(stylize).join('');
} }
var result = line; var result = line;
var parseArr = result.split(colourKey); var parseArr = result.split(colourKey);
var text, match, colour, background = ""; var text, match, colour, background = '';
for (var i = 0; i < parseArr.length; i++) { for (var i = 0; i < parseArr.length; i++) {
text = parseArr[i]; text = parseArr[i];
match = text.match(back_re); match = text.match(back_re);
colour = match && colors[+match[1]]; colour = match && colors[+match[1]];
if (!match || !colour) { if (!match || !colour) {
// ^C (no colour) ending. Escape current colour and carry on // ^C (no colour) ending. Escape current colour and carry on
background = ""; background = '';
continue; continue;
} }
// set the background colour // set the background colour
// we don't overide the background local var to support nesting // we don't overide the background local var to support nesting
if (colors[+match[3]]) { if (colors[+match[3]]) {
background = " " + colors[+match[3]].back; background = ' ' + colors[+match[3]].back;
} }
// update the parsed text result // update the parsed text result
result = result.replace(colourKey + text, result = result.replace(colourKey + text,
"<span class='{0}'>{1}</span>".format(colour.fore + background, text.slice(match[0].length))); '<span class="{0}">{1}</span>'.format(colour.fore + background, text.slice(match[0].length)));
} }
// Matching styles (italics/bold/underline) // Matching styles (italics/bold/underline)
@ -70,12 +72,12 @@ function stylize(line) {
styles.forEach(function(style) { styles.forEach(function(style) {
if (result.indexOf(style.key) < 0) return; if (result.indexOf(style.key) < 0) return;
result = result.replace(style.keyregex, function(match, text) { result = result.replace(style.keyregex, function(match, text) {
return "<span class='{0}'>{1}</span>".format(style.style, text) return '<span class="{0}">{1}</span>'.format(style.style, text);
}); });
}); });
//replace the reminent colour terminations and be done with it //replace the reminent colour terminations and be done with it
return result.replace(colour_re, ""); return result.replace(colour_re, '');
} }
window.colorizer.stylize = stylize; module.exports = stylize;

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,38 @@
function swapSheet(name) { function swapSheet(name) {
document.querySelector("#theme_stylesheet").setAttribute('href', "css/"+name+".css"); document.querySelector('#theme_stylesheet').setAttribute('href', 'style/'+name+'.css');
} }
window.themes = { const themes = module.exports = {
available: { available: {
default: { default: {
name: "Default", name: 'Default',
type: "bright", type: 'bright',
nick_pallete: { nick_pallete: {
H: [1, 360], H: [1, 360],
S: [30, 100], S: [30, 100],
L: [30, 70] L: [30, 70]
}, },
stylesheet: "theme_default", stylesheet: 'theme_default',
default: true, default: true,
colorSamples: { colorSamples: {
toolbar: "#00c7e0", toolbar: '#00c7e0',
background: "#f5f5f5" background: '#f5f5f5'
} }
}, },
night: { night: {
name: "Night", name: 'Night',
type: "dark", type: 'dark',
nick_pallete: { nick_pallete: {
H: [1, 360], H: [1, 360],
S: [30, 100], S: [30, 100],
L: [50, 100] L: [50, 100]
}, },
stylesheet: "theme_night", stylesheet: 'theme_night',
default: false, default: false,
colorSamples: { colorSamples: {
toolbar: "#008e8e", toolbar: '#008e8e',
background: "#1d1d1d" background: '#1d1d1d'
} }
} }
}, },
@ -43,4 +43,4 @@ window.themes = {
window.irc.config.theme = name; window.irc.config.theme = name;
} }
} }
} };

17
static/image/diamond.svg Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 496.158 496.158" style="enable-background:new 0 0 496.158 496.158;" xml:space="preserve">
<path style="fill:#00C7E0;" d="M0,248.085C0,111.063,111.069,0.003,248.075,0.003c137.013,0,248.083,111.061,248.083,248.082
c0,137.002-111.07,248.07-248.083,248.07C111.069,496.155,0,385.087,0,248.085z"/>
<polygon style="fill:#F5F5F5;" points="334.88,110.792 161.117,110.792 64.076,208.887 248.275,422.128 432.081,208.869 "/>
<polygon style="fill:#00C7E0;" points="414.206,208.715 248.265,401.245 81.956,208.715 166.944,125.077 329.06,125.077 "/>
<g>
<polygon style="fill:#FFFFFF;" points="241.488,403.619 165.995,206.35 165.92,205.541 159.862,125.868 174.025,124.286
180.007,203.148 255.04,398.87 "/>
<polygon style="fill:#FFFFFF;" points="254.386,403.619 240.834,398.869 315.833,203.314 321.848,124.284 336.012,125.87
329.842,206.517 329.613,207.291 "/>
<polygon style="fill:#FFFFFF;" points="316.289,213.305 242.36,122.491 253.801,113.278 327.728,204.091 "/>
<polygon style="fill:#FFFFFF;" points="179.872,213.305 168.431,204.091 242.36,113.278 253.801,122.491 "/>
<rect x="81.959" y="200.979" style="fill:#FFFFFF;" width="332.6" height="15.476"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,19 +1,28 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict'; 'use strict';
const express = require("express"), const express = require('express');
path = require("path"), const path = require('path');
sockio = require("socket.io"), const sockio = require('socket.io');
dns = require("dns"), const dns = require('dns');
app = express(), const app = express();
router = express.Router(), const router = express.Router();
pubdir = path.join(__dirname, "public"), const pubdir = path.join(__dirname, 'build');
pkg = require(__dirname+"/package.json"), const pkg = require(__dirname+'/package.json');
config = require(__dirname+'/server/config'), const config = require(__dirname+'/server/config');
logger = require(__dirname+'/server/logger'), const logger = require(__dirname+'/server/logger');
port = config.server.port || 8080; const port = config.server.port || 8080;
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != undefined ? args[number] : match;
});
};
}
let irclib = require(__dirname+'/server/teemant_irc'); let irclib = require(__dirname+'/server/teemant_irc');
let webirc = require(__dirname+'/server/webirc'); let webirc = require(__dirname+'/server/webirc');
@ -26,29 +35,36 @@ let connections = {};
let customCTCPs = { let customCTCPs = {
VERSION: function(data, connection) { VERSION: function(data, connection) {
return "TeemantIRC ver. "+pkg.version+" - "+pkg.description+" - https://teemant.icynet.ml/"; return 'TeemantIRC ver. {0} - {1} - https://teemant.icynet.ml/'.format(pkg.version, pkg.description);
}, },
SOURCE: function(data, connection) { SOURCE: function(data, connection) {
return "https://github.com/DiamondtechDev/TeemantIRC"; return 'https://github.com/DiamondtechDev/TeemantIRC';
} }
} };
process.stdin.resume(); process.stdin.resume();
router.get("/", function(req, res){ router.get('/', function(req, res){
res.sendFile(pubdir+"/index.html"); res.sendFile(pubdir+'/document/index.html');
}); });
router.get("/:server", function(req, res){ router.get('/:server', function(req, res){
res.sendFile(pubdir+"/index.html"); res.sendFile(pubdir+'/document/index.html');
}); });
app.use('/', express.static(pubdir, { maxAge: 365*24*60*60*1000 })); app.use('/', express.static(pubdir, { maxAge: 365*24*60*60*1000 }));
app.use('/:server', express.static(pubdir, { maxAge: 365*24*60*60*1000 })); app.use('/:server', express.static(pubdir, { maxAge: 365*24*60*60*1000 }));
app.use('/', express.static(pubdir+'/icons', { maxAge: 365*24*60*60*1000 }));
app.use('/:server', express.static(pubdir+'/icons', { maxAge: 365*24*60*60*1000 }));
app.use('/', express.static(__dirname+'/static', { maxAge: 365*24*60*60*1000 }));
app.use('/:server', express.static(pubdir+'/static', { maxAge: 365*24*60*60*1000 }));
app.use('/', router); app.use('/', router);
const io = sockio.listen(app.listen(port, function() { const io = sockio.listen(app.listen(port, function() {
logger.log("*** Listening on http://localhost:" + port + "/"); logger.log('*** Listening on http://localhost:{0}/'.format(port));
setInterval(() => { setInterval(() => {
logger.printRuntimeStats(runtime_stats, connections); logger.printRuntimeStats(runtime_stats, connections);
@ -67,12 +83,12 @@ function resolveHostname(ipaddr) {
io.sockets.on('connection', function (socket) { io.sockets.on('connection', function (socket) {
let userip = socket.handshake.headers['x-real-ip'] || socket.handshake.headers['x-forwarded-for'] || let userip = socket.handshake.headers['x-real-ip'] || socket.handshake.headers['x-forwarded-for'] ||
socket.request.connection._peername.address || "127.0.0.1"; socket.request.connection._peername.address || '127.0.0.1';
if(userip.indexOf('::ffff:') == 0) if(userip.indexOf('::ffff:') == 0)
userip = userip.substring(7); userip = userip.substring(7);
logger.debugLog('clientID: '+socket.id+' from: ', userip); logger.debugLog('clientID: {0} from: {1}'.format(socket.id, userip));
// New object for connections // New object for connections
connections[socket.id] = { connections[socket.id] = {
@ -80,7 +96,7 @@ io.sockets.on('connection', function (socket) {
ipaddr: userip, ipaddr: userip,
hostname: userip hostname: userip
} }
} };
// Get the hostname of the connecting user // Get the hostname of the connecting user
let hostQuery = resolveHostname(userip); let hostQuery = resolveHostname(userip);
@ -88,10 +104,10 @@ io.sockets.on('connection', function (socket) {
if(arr.length > 0) if(arr.length > 0)
connections[socket.id].host.hostname = arr[0]; connections[socket.id].host.hostname = arr[0];
}).catch((err) => { }).catch((err) => {
logger.debugLog("Host resolve for "+socket.id+" failed: ", err); logger.debugLog('Host resolve for {0} failed: {1}'.format(socket.id, err));
}); });
logger.debugLog("Hostname of "+socket.id+" was determined to be "+connections[socket.id].host.hostname); logger.debugLog('Hostname of {0} was determined to be {1}'.format(socket.id, connections[socket.id].host.hostname));
socket.on('disconnect', function() { socket.on('disconnect', function() {
for (let d in connections[socket.id]) { for (let d in connections[socket.id]) {
@ -102,11 +118,11 @@ io.sockets.on('connection', function (socket) {
delete connections[socket.id]; delete connections[socket.id];
logger.debugLog('clientID: '+socket.id+' disconnect'); logger.debugLog('clientID: {0} disconnect'.format(socket.id));
}); });
socket.on('error', (e) => { socket.on('error', (e) => {
logger.errorLog(e, "Socket error"); logger.errorLog(e, 'Socket error');
}); });
socket.on('userinput', (data) => { socket.on('userinput', (data) => {
@ -114,15 +130,15 @@ io.sockets.on('connection', function (socket) {
if(!serv) return; if(!serv) return;
if(serv.authenticated == false) return; if(serv.authenticated == false) return;
logger.debugLog("["+socket.id+"] ->", data); logger.debugLog('['+socket.id+'] ->', data);
serv.handler.handleUserLine(data); serv.handler.handleUserLine(data);
}) });
socket.on('irc_create', function(connectiondata) { socket.on('irc_create', function(connectiondata) {
logger.debugLog(socket.id+" created irc connection: ", connectiondata); logger.debugLog(socket.id+' created irc connection: ', connectiondata);
socket.emit('act_client', {type: 'connect_message', message: "Connecting to server..", error: false}); socket.emit('act_client', {type: 'connect_message', message: 'Connecting to server..', error: false});
let newConnection = new irclib.IRCConnection(connectiondata, config.client, let newConnection = new irclib.IRCConnection(connectiondata, config.client,
{ {
@ -137,7 +153,7 @@ io.sockets.on('connection', function (socket) {
connections[socket.id][connectiondata.server] = newConnection; connections[socket.id][connectiondata.server] = newConnection;
newConnection.on('authenticated', () => { newConnection.on('authenticated', () => {
socket.emit('act_client', {type: "event_connect", address: connectiondata.server, network: newConnection.data.network, socket.emit('act_client', {type: 'event_connect', address: connectiondata.server, network: newConnection.data.network,
supportedModes: newConnection.data.supportedModes, nickname: newConnection.config.nickname, supportedModes: newConnection.data.supportedModes, nickname: newConnection.config.nickname,
max_channel_length: newConnection.data.max_channel_length}); max_channel_length: newConnection.data.max_channel_length});
@ -146,11 +162,11 @@ io.sockets.on('connection', function (socket) {
if(config.server.debug) { if(config.server.debug) {
newConnection.on('line', function(line) { newConnection.on('line', function(line) {
logger.debugLog("["+socket.id+"] <-", line); logger.debugLog('['+socket.id+'] <-', line);
}); });
newConnection.on('debug_log', function(data) { newConnection.on('debug_log', function(data) {
logger.debugLog("["+socket.id+"] <-", data); logger.debugLog('['+socket.id+'] <-', data);
}); });
} }
@ -159,7 +175,7 @@ io.sockets.on('connection', function (socket) {
if(newConnection.authenticated == false) if(newConnection.authenticated == false)
socket.emit('act_client', {type: 'connect_message', server: connectiondata.server, socket.emit('act_client', {type: 'connect_message', server: connectiondata.server,
message: "Failed to connect to the server!", error: true}); message: 'Failed to connect to the server!', error: true});
}); });
newConnection.on('pass_to_client', (data) => { newConnection.on('pass_to_client', (data) => {
@ -171,7 +187,7 @@ io.sockets.on('connection', function (socket) {
if(newConnection.authenticated == false) if(newConnection.authenticated == false)
socket.emit('act_client', {type: 'connect_message', server: connectiondata.server, socket.emit('act_client', {type: 'connect_message', server: connectiondata.server,
message: "Failed to connect to the server!", error: true}); message: 'Failed to connect to the server!', error: true});
else else
socket.emit('act_client', {type: 'event_server_quit', server: connectiondata.server}); socket.emit('act_client', {type: 'event_server_quit', server: connectiondata.server});
}); });

49
webpack.config.js Normal file
View File

@ -0,0 +1,49 @@
'use strict';
const webpack = require('webpack');
const path = require('path');
let inProduction = process.env.NODE_ENV === 'production' || process.argv.indexOf('-p') !== -1;
module.exports = {
entry: {
main: ['./src/script/main']
},
output: {
path: __dirname,
filename: './build/script/[name].js',
chunkFilename: './build/script/[id].js'
},
module: {
preLoaders: [
// { test: /\.js$/, loader: 'eslint-loader', exclude: /node_modules/ },
// { test: /\.coffee$/, loader: 'coffeelint-loader', exclude: /node_modules/ },
],
loaders: [
// { test: /\.mustache$/, loader: 'mustache', exclude: /node_modules/ }
],
noParse: [
/node_modules/
]
},
resolve: {
extensions: ['', '.js', '.json'],
root: [path.join(__dirname, '/src/script')],
alias: {
'underscore': 'lodash'
}
},
plugins: [
new webpack.ProvidePlugin({
// Detect and inject
_: 'underscore',
})
],
devtool: 'inline-source-map',
debug: true
};