├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── dist └── logplease.min.js ├── es5 └── index.js ├── example ├── browser.html ├── bundle.js ├── example.js └── index.html ├── package-lock.json ├── package.json ├── screenshot.png ├── src └── index.js ├── test ├── logplease.test.js └── mocha.opts ├── webpack.config.js └── webpack.example.config.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # This configuration was automatically generated from a CircleCI 1.0 config. 2 | # It should include any build commands you had along with commands that CircleCI 3 | # inferred from your project structure. We strongly recommend you read all the 4 | # comments in this file to understand the structure of CircleCI 2.0, as the idiom 5 | # for configuration has changed substantially in 2.0 to allow arbitrary jobs rather 6 | # than the prescribed lifecycle of 1.0. In general, we recommend using this generated 7 | # configuration as a reference rather than using it in production, though in most 8 | # cases it should duplicate the execution of your original 1.0 config. 9 | version: 2 10 | jobs: 11 | build: 12 | working_directory: ~/haadcode/logplease 13 | parallelism: 1 14 | shell: /bin/bash --login 15 | # CircleCI 2.0 does not support environment variables that refer to each other the same way as 1.0 did. 16 | # If any of these refer to each other, rewrite them so that they don't or see https://circleci.com/docs/2.0/env-vars/#interpolating-environment-variables-to-set-other-environment-variables . 17 | environment: 18 | CIRCLE_ARTIFACTS: /tmp/circleci-artifacts 19 | CIRCLE_TEST_REPORTS: /tmp/circleci-test-results 20 | # In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages. 21 | # In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images. 22 | # The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job. 23 | # We have selected a pre-built image that mirrors the build environment we use on 24 | # the 1.0 platform, but we recommend you choose an image more tailored to the needs 25 | # of each job. For more information on choosing an image (or alternatively using a 26 | # VM instead of a container) see https://circleci.com/docs/2.0/executor-types/ 27 | # To see the list of pre-built images that CircleCI provides for most common languages see 28 | # https://circleci.com/docs/2.0/circleci-images/ 29 | docker: 30 | - image: circleci/build-image:ubuntu-14.04-XXL-upstart-1189-5614f37 31 | command: /sbin/init 32 | steps: 33 | # Machine Setup 34 | # If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each 35 | # The following `checkout` command checks out your code to your working directory. In 1.0 we did this implicitly. In 2.0 you can choose where in the course of a job your code should be checked out. 36 | - checkout 37 | # Prepare for artifact and test results collection equivalent to how it was done on 1.0. 38 | # In many cases you can simplify this from what is generated here. 39 | # 'See docs on artifact collection here https://circleci.com/docs/2.0/artifacts/' 40 | - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS 41 | # This is based on your 1.0 configuration file or project settings 42 | - run: 43 | working_directory: ~/haadcode/logplease 44 | command: nvm install 8.11.3 && nvm alias default 8.11.3 45 | # Dependencies 46 | # This would typically go in either a build or a build-and-test job when using workflows 47 | # Restore the dependency cache 48 | - restore_cache: 49 | keys: 50 | # This branch if available 51 | - v1-dep-{{ .Branch }}- 52 | # Default branch if not 53 | - v1-dep-master- 54 | # Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly 55 | - v1-dep- 56 | # The following line was run implicitly in your 1.0 builds based on what CircleCI inferred about the structure of your project. In 2.0 you need to be explicit about which commands should be run. In some cases you can discard inferred commands if they are not relevant to your project. 57 | - run: if [ -z "${NODE_ENV:-}" ]; then export NODE_ENV=test; fi 58 | - run: export PATH="~/haadcode/logplease/node_modules/.bin:$PATH" 59 | - run: npm install 60 | # Save dependency cache 61 | - save_cache: 62 | key: v1-dep-{{ .Branch }}-{{ epoch }} 63 | paths: 64 | # This is a broad list of cache paths to include many possible development environments 65 | # You can probably delete some of these entries 66 | - ./node_modules 67 | # Test 68 | # This would typically be a build job when using workflows, possibly combined with build 69 | # The following line was run implicitly in your 1.0 builds based on what CircleCI inferred about the structure of your project. In 2.0 you need to be explicit about which commands should be run. In some cases you can discard inferred commands if they are not relevant to your project. 70 | - run: npm test 71 | # Teardown 72 | # If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each 73 | # Save test results 74 | - store_test_results: 75 | path: /tmp/circleci-test-results 76 | # Save artifacts 77 | - store_artifacts: 78 | path: /tmp/circleci-artifacts 79 | - store_artifacts: 80 | path: /tmp/circleci-test-results 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *sublime* 3 | node_modules/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Haad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | deps: 4 | npm install 5 | 6 | test: deps 7 | npm run test 8 | 9 | build: test 10 | npm run build 11 | @echo "Build success!" 12 | @echo "Output: 'dist/', 'es5/', 'examples/browser/'" 13 | 14 | clean: 15 | rm -rf node_modules/ 16 | 17 | .PHONY: test build 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # logplease 2 | Simple Javascript logger for Node.js and Browsers 3 | 4 | **[DEMO](https://ipfs.io/ipfs/QmRrBe2sp9ha2xypRoz5UDXqBJUB83NcecQU3QpqBJ5hkq)** 5 | *Open the dev tools to see the log output* 6 | 7 | ![Screenshot](https://raw.githubusercontent.com/haadcode/logplease/master/screenshot.png) 8 | 9 | *logplease* does two simple things: output log messages to the console and/or to a file (Node.js only) and display the log messages with nice colors. Inspired by [log4js](https://github.com/stritti/log4js) and [debug](https://github.com/visionmedia/debug). 10 | 11 | ## Features 12 | - Log messages to stdout or a file 13 | - Customize the log messages 14 | - Log levels 15 | - Colors! 16 | - Work in Node.js and Browsers 17 | 18 | ## Install 19 | ``` 20 | npm install logplease 21 | ``` 22 | 23 | ### Examples 24 | #### Node.js 25 | ``` 26 | npm run example 27 | ``` 28 | 29 | #### Browser 30 | Open `example/index.html` in your browser. 31 | 32 | ## Usage 33 | 34 | ### Node.js / Webpack 35 | See [example/example.js](https://github.com/haadcode/logplease/blob/master/example/example.js) for details. 36 | 37 | ```javascript 38 | const Logger = require('logplease'); 39 | const logger = Logger.create('utils'); 40 | logger.debug(`This is a debug message`); 41 | logger.log(`This is a log message`); // alias for debug() 42 | logger.info(`This is a info message`); 43 | logger.warn(`This is a warning`); 44 | logger.error(`This is an error`); 45 | ``` 46 | 47 | Default log level is `DEBUG`. You can set the log level with `LOG` environment variable, eg. `LOG=debug node example/example.js`. See [Log levels](#log-levels) for available options. 48 | 49 | There's an ES5 build in `es5/` which you can include if you need ES5 compatibility, eg. with Webpack. 50 | 51 | ### Browser 52 | Copy `dist/logplease.min.js` to your javascripts directory and include it in your html. See [example/index.html](https://github.com/haadcode/logplease/blob/master/example/index.html) for details. 53 | 54 | ```html 55 | 56 | 57 | 65 | 66 | ``` 67 | 68 | ### Options 69 | You can customize your logger to not show the timestamp or the log level, disable colors or specify, if using a log file, to overwrite the log file at start instead of appending to it. 70 | 71 | ```javascript 72 | const Logger = require('logplease'); 73 | const logger = Logger.create("logger name", options); 74 | ``` 75 | 76 | Available options and defaults: 77 | ```javascript 78 | const options = { 79 | useColors: true, // Enable colors 80 | color: Colors.White, // Set the color of the logger 81 | showTimestamp: true, // Display timestamp in the log message 82 | useLocalTime: false, // Display timestamp in local timezone 83 | showLevel: true, // Display log level in the log message 84 | filename: null, // Set file path to log to a file 85 | appendFile: true, // Append logfile instead of overwriting 86 | }; 87 | ``` 88 | 89 | ### Log levels 90 | ``` 91 | DEBUG 92 | INFO 93 | WARN 94 | ERROR 95 | NONE 96 | ``` 97 | 98 | Default log level is `DEBUG`. To display errors only, use `ERROR`. To turn off all logging, use `NONE`. 99 | 100 | ### Global log level 101 | You can set a global log level to display only the wanted log messages. 102 | 103 | ```javascript 104 | const Logger = require('logplease'); 105 | Logger.setLogLevel(Logger.LogLevels.ERROR) // Show only ERROR messages 106 | // or 107 | Logger.setLogLevel('ERROR') 108 | ``` 109 | 110 | You can mute all loggers with log level *NONE*: 111 | ```javascript 112 | Logger.setLogLevel(Logger.LogLevels.NONE) // output nothing 113 | ``` 114 | 115 | ### Global log file 116 | You can set a global log file to which all loggers write to. 117 | 118 | ```javascript 119 | const Logger = require('logplease'); 120 | const logger1 = Logger.create("logger1"); 121 | const logger2 = Logger.create("logger2"); 122 | Logger.setLogfile('debug.log'); 123 | logger1.debug('hello world 1'); 124 | logger2.debug('hello world 2'); 125 | // ==> 'debug.log' contains both log messages 126 | ``` 127 | 128 | ### Log file 129 | You can set a log file per logger. 130 | 131 | ```javascript 132 | const Logger = require('logplease'); 133 | const logger1 = Logger.create("logger1", { filename: 'debug.log' }); 134 | const logger2 = Logger.create("logger2"); 135 | logger1.debug('hello world 1'); // writes to 'debug.log' 136 | logger2.debug('hello world 2'); // doesn't write to 'debug.log' 137 | ``` 138 | 139 | ### Colors 140 | You can set a color per logger. Default color in Node.js is *White* and in the browser *Black*. 141 | 142 | ```javascript 143 | const Logger = require('logplease'); 144 | const logger = Logger.create("logger name", { color: Logger.Colors.Yellow }); 145 | ``` 146 | 147 | Colors: 148 | ``` 149 | Black, Red, Green, Yellow, Blue, Magenta, Cyan, Grey, White 150 | ``` 151 | 152 | ### Tests 153 | Run tests with: 154 | ``` 155 | npm test 156 | ``` 157 | 158 | ### Build 159 | Install build dependencies: 160 | ``` 161 | npm install 162 | ``` 163 | 164 | Build the browser distributable and examples: 165 | ``` 166 | npm run build 167 | ``` 168 | 169 | Build the browser distributable only: 170 | ``` 171 | npm run build:dist 172 | ``` 173 | 174 | The distributable file will be located in [dist/logplease.min.js](https://github.com/haadcode/logplease/tree/master/dist) 175 | 176 | Build the browser example: 177 | ``` 178 | npm run build:examples 179 | ``` 180 | -------------------------------------------------------------------------------- /dist/logplease.min.js: -------------------------------------------------------------------------------- 1 | var Logger=function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=15)}([function(t,e){var n=t.exports={version:"2.5.7"};"number"==typeof __e&&(__e=n)},function(t,e,n){t.exports=!n(2)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){e.nextTick=function(t){setTimeout(t,0)},e.platform=e.arch=e.execPath=e.title="browser",e.pid=1,e.browser=!0,e.env={},e.argv=[],e.binding=function(t){throw new Error("No such module. (Possibly not yet loaded)")},function(){var t,r="/";e.cwd=function(){return r},e.chdir=function(e){t||(t=n(16)),r=t.resolve(e,r)}}(),e.exit=e.kill=e.umask=e.dlopen=e.uptime=e.memoryUsage=e.uvCounters=function(){},e.features={}},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){var r=n(4),o=n(0),i=n(31),s=n(33),u=n(10),c=function(t,e,n){var l,a,f,p=t&c.F,h=t&c.G,v=t&c.S,y=t&c.P,g=t&c.B,d=t&c.W,m=h?o:o[e]||(o[e]={}),b=m.prototype,w=h?r:v?r[e]:(r[e]||{}).prototype;h&&(n=e);for(l in n)(a=!p&&w&&void 0!==w[l])&&u(m,l)||(f=a?w[l]:n[l],m[l]=h&&"function"!=typeof w[l]?n[l]:g&&a?i(f,r):d&&w[l]==f?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e.prototype=t.prototype,e}(f):y&&"function"==typeof f?i(Function.call,f):f,y&&((m.virtual||(m.virtual={}))[l]=f,t&c.R&&b&&!b[l]&&s(b,l,f)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e,n){var r=n(8);t.exports=function(t){return Object(r(t))}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e,n){var r=n(20),o=n(29);t.exports=Object.keys||function(t){return r(t,o)}},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var r=n(12),o=n(8);t.exports=function(t){return r(o(t))}},function(t,e,n){var r=n(21);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(34),o=n(35),i=n(37),s=Object.defineProperty;e.f=n(1)?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return s(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){"use strict";(function(e){function r(t){return t&&t.__esModule?t:{default:t}}var o=n(17),i=r(o),s=n(39),u=r(s),c=n(45),l=r(c),a=n(46),f=r(a),p=n(50),h=n(51).format,v=n(55).EventEmitter,y=e.type&&"renderer"===e.type,g=!(y||!e.version),d={DEBUG:"DEBUG",INFO:"INFO",WARN:"WARN",ERROR:"ERROR",NONE:"NONE"},m=d.DEBUG,b=null,w=new v,_={Black:0,Red:1,Green:2,Yellow:3,Blue:4,Magenta:5,Cyan:6,Grey:7,White:9,Default:9};g||(_={Black:"Black",Red:"IndianRed",Green:"LimeGreen",Yellow:"Orange",Blue:"RoyalBlue",Magenta:"Orchid",Cyan:"SkyBlue",Grey:"DimGrey",White:"White",Default:"Black"});var x=[_.Cyan,_.Green,_.Yellow,_.Red,_.Default],O={useColors:!0,color:_.Default,showTimestamp:!0,useLocalTime:!1,showLevel:!0,filename:b,appendFile:!0},L=function(){function t(e,n){(0,l.default)(this,t),this.category=e;var r={};(0,u.default)(r,O),(0,u.default)(r,n),this.options=r,this.debug=this.debug.bind(this),this.log=this.log.bind(this),this.info=this.info.bind(this),this.warn=this.warn.bind(this),this.error=this.error.bind(this)}return(0,f.default)(t,[{key:"debug",value:function(){this._shouldLog(d.DEBUG)&&this._write(d.DEBUG,h.apply(null,arguments))}},{key:"log",value:function(){this._shouldLog(d.DEBUG)&&this.debug.apply(this,arguments)}},{key:"info",value:function(){this._shouldLog(d.INFO)&&this._write(d.INFO,h.apply(null,arguments))}},{key:"warn",value:function(){this._shouldLog(d.WARN)&&this._write(d.WARN,h.apply(null,arguments))}},{key:"error",value:function(){this._shouldLog(d.ERROR)&&this._write(d.ERROR,h.apply(null,arguments))}},{key:"_write",value:function(t,e){(this.options.filename||b)&&!this.fileWriter&&g&&(this.fileWriter=p.openSync(this.options.filename||b,this.options.appendFile?"a+":"w+"));var n=this._format(t,e),r=this._createLogMessage(t,e),o=this._createLogMessage(t,e,n.timestamp,n.level,n.category,n.text);this.fileWriter&&g&&p.writeSync(this.fileWriter,r+"\n",null,"utf-8"),g||!this.options.useColors?(console.log(o),w.emit("data",this.category,t,e)):t===d.ERROR?this.options.showTimestamp&&this.options.showLevel?console.error(o,n.timestamp,n.level,n.category,n.text):this.options.showTimestamp&&!this.options.showLevel?console.error(o,n.timestamp,n.category,n.text):!this.options.showTimestamp&&this.options.showLevel?console.error(o,n.level,n.category,n.text):console.error(o,n.category,n.text):this.options.showTimestamp&&this.options.showLevel?console.log(o,n.timestamp,n.level,n.category,n.text):this.options.showTimestamp&&!this.options.showLevel?console.log(o,n.timestamp,n.category,n.text):!this.options.showTimestamp&&this.options.showLevel?console.log(o,n.level,n.category,n.text):console.log(o,n.category,n.text)}},{key:"_format",value:function(t,e){var n="",r="",o="",s=": ";if(this.options.useColors){var u=(0,i.default)(d).map(function(t){return d[t]}).indexOf(t),c=this.options.color;g?(this.options.showTimestamp&&(n="[3"+_.Grey+"m"),this.options.showLevel&&(r="[3"+x[u]+";22m"),o="[3"+c+";1m",s=": "):(this.options.showTimestamp&&(n="color:"+_.Grey),this.options.showLevel&&(r="color:"+x[u]),o="color:"+c+"; font-weight: bold")}return{timestamp:n,level:r,category:o,text:s}}},{key:"_createLogMessage",value:function(t,e,n,r,o,i){n=n||"",r=r||"",o=o||"",i=i||": ",!g&&this.options.useColors&&(this.options.showTimestamp&&(n="%c"),this.options.showLevel&&(r="%c"),o="%c",i=": %c");var s="";return this.options.showTimestamp&&!this.options.useLocalTime&&(s+=(new Date).toISOString()+" "),this.options.showTimestamp&&this.options.useLocalTime&&(s+=(new Date).toLocaleString()+" "),s=n+s,this.options.showLevel&&(s+=r+"["+t+"]"+(t===d.INFO||t===d.WARN?" ":"")+" "),s+=o+this.category,s+=i+e}},{key:"_shouldLog",value:function(t){var n=void 0!==e&&void 0!==e.env&&void 0!==e.env.LOG?e.env.LOG.toUpperCase():null;n="undefined"!=typeof window&&window.LOG?window.LOG.toUpperCase():n;var r=n||m,o=(0,i.default)(d).map(function(t){return d[t]});return o.indexOf(t)>=o.indexOf(r)}}]),t}();t.exports={Colors:_,LogLevels:d,setLogLevel:function(t){m=t},setLogfile:function(t){b=t},create:function(t,e){return new L(t,e)},forceBrowserMode:function(t){return g=!t},events:w}}).call(e,n(3))},function(t,e,n){(function(t){function n(t,e){for(var n=0,r=t.length-1;r>=0;r--){var o=t[r];"."===o?t.splice(r,1):".."===o?(t.splice(r,1),n++):n&&(t.splice(r,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}function r(t,e){if(t.filter)return t.filter(e);for(var n=[],r=0;r=-1&&!o;i--){var s=i>=0?arguments[i]:t.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,o="/"===s.charAt(0))}return e=n(r(e.split("/"),function(t){return!!t}),!o).join("/"),(o?"/":"")+e||"."},e.normalize=function(t){var o=e.isAbsolute(t),i="/"===s(t,-1);return t=n(r(t.split("/"),function(t){return!!t}),!o).join("/"),t||o||(t="."),t&&i&&(t+="/"),(o?"/":"")+t},e.isAbsolute=function(t){return"/"===t.charAt(0)},e.join=function(){var t=Array.prototype.slice.call(arguments,0);return e.normalize(r(t,function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t}).join("/"))},e.relative=function(t,n){function r(t){for(var e=0;e=0&&""===t[n];n--);return e>n?[]:t.slice(e,n-e+1)}t=e.resolve(t).substr(1),n=e.resolve(n).substr(1);for(var o=r(t.split("/")),i=r(n.split("/")),s=Math.min(o.length,i.length),u=s,c=0;cc;)r(u,n=e[c++])&&(~i(l,n)||l.push(n));return l}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e,n){var r=n(11),o=n(23),i=n(24);t.exports=function(t){return function(e,n,s){var u,c=r(e),l=o(c.length),a=i(s,l);if(t&&n!=n){for(;l>a;)if((u=c[a++])!=u)return!0}else for(;l>a;a++)if((t||a in c)&&c[a]===n)return t||a||0;return!t&&-1}}},function(t,e,n){var r=n(13),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e,n){var r=n(13),o=Math.max,i=Math.min;t.exports=function(t,e){return t=r(t),t<0?o(t+e,0):i(t,e)}},function(t,e,n){var r=n(26)("keys"),o=n(28);t.exports=function(t){return r[t]||(r[t]=o(t))}},function(t,e,n){var r=n(0),o=n(4),i=o["__core-js_shared__"]||(o["__core-js_shared__"]={});(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n(27)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(t,e){t.exports=!0},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(5),o=n(0),i=n(2);t.exports=function(t,e){var n=(o.Object||{})[t]||Object[t],s={};s[t]=e(n),r(r.S+r.F*i(function(){n(1)}),"Object",s)}},function(t,e,n){var r=n(32);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){var r=n(14),o=n(38);t.exports=n(1)?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var r=n(6);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e,n){t.exports=!n(1)&&!n(2)(function(){return 7!=Object.defineProperty(n(36)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(6),o=n(4).document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},function(t,e,n){var r=n(6);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){t.exports={default:n(40),__esModule:!0}},function(t,e,n){n(41),t.exports=n(0).Object.assign},function(t,e,n){var r=n(5);r(r.S+r.F,"Object",{assign:n(42)})},function(t,e,n){"use strict";var r=n(9),o=n(43),i=n(44),s=n(7),u=n(12),c=Object.assign;t.exports=!c||n(2)(function(){var t={},e={},n=Symbol(),r="abcdefghijklmnopqrst";return t[n]=7,r.split("").forEach(function(t){e[t]=t}),7!=c({},t)[n]||Object.keys(c({},e)).join("")!=r})?function(t,e){for(var n=s(t),c=arguments.length,l=1,a=o.f,f=i.f;c>l;)for(var p,h=u(arguments[l++]),v=a?r(h).concat(a(h)):r(h),y=v.length,g=0;y>g;)f.call(h,p=v[g++])&&(n[p]=h[p]);return n}:c},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){"use strict";e.__esModule=!0,e.default=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e,n){"use strict";e.__esModule=!0;var r=n(47),o=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default=function(){function t(t,e){for(var n=0;n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(n)?r.showHidden=n:n&&e._extend(r,n),_(r.showHidden)&&(r.showHidden=!1),_(r.depth)&&(r.depth=2),_(r.colors)&&(r.colors=!1),_(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=i),c(r,t,r.depth)}function i(t,e){var n=o.styles[e];return n?"["+o.colors[n][0]+"m"+t+"["+o.colors[n][1]+"m":t}function s(t,e){return t}function u(t){var e={};return t.forEach(function(t,n){e[t]=!0}),e}function c(t,n,r){if(t.customInspect&&n&&E(n.inspect)&&n.inspect!==e.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,t);return b(o)||(o=c(t,o,r)),o}var i=l(t,n);if(i)return i;var s=Object.keys(n),y=u(s);if(t.showHidden&&(s=Object.getOwnPropertyNames(n)),j(n)&&(s.indexOf("message")>=0||s.indexOf("description")>=0))return a(n);if(0===s.length){if(E(n)){var g=n.name?": "+n.name:"";return t.stylize("[Function"+g+"]","special")}if(x(n))return t.stylize(RegExp.prototype.toString.call(n),"regexp");if(L(n))return t.stylize(Date.prototype.toString.call(n),"date");if(j(n))return a(n)}var d="",m=!1,w=["{","}"];if(v(n)&&(m=!0,w=["[","]"]),E(n)){d=" [Function"+(n.name?": "+n.name:"")+"]"}if(x(n)&&(d=" "+RegExp.prototype.toString.call(n)),L(n)&&(d=" "+Date.prototype.toUTCString.call(n)),j(n)&&(d=" "+a(n)),0===s.length&&(!m||0==n.length))return w[0]+d+w[1];if(r<0)return x(n)?t.stylize(RegExp.prototype.toString.call(n),"regexp"):t.stylize("[Object]","special");t.seen.push(n);var _;return _=m?f(t,n,r,y,s):s.map(function(e){return p(t,n,r,y,e,m)}),t.seen.pop(),h(_,d,w)}function l(t,e){if(_(e))return t.stylize("undefined","undefined");if(b(e)){var n="'"+JSON.stringify(e).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return t.stylize(n,"string")}return m(e)?t.stylize(""+e,"number"):y(e)?t.stylize(""+e,"boolean"):g(e)?t.stylize("null","null"):void 0}function a(t){return"["+Error.prototype.toString.call(t)+"]"}function f(t,e,n,r,o){for(var i=[],s=0,u=e.length;s-1&&(u=i?u.split("\n").map(function(t){return" "+t}).join("\n").substr(2):"\n"+u.split("\n").map(function(t){return" "+t}).join("\n"))):u=t.stylize("[Circular]","special")),_(s)){if(i&&o.match(/^\d+$/))return u;s=JSON.stringify(""+o),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=t.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=t.stylize(s,"string"))}return s+": "+u}function h(t,e,n){var r=0;return t.reduce(function(t,e){return r++,e.indexOf("\n")>=0&&r++,t+e.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60?n[0]+(""===e?"":e+"\n ")+" "+t.join(",\n ")+" "+n[1]:n[0]+e+" "+t.join(", ")+" "+n[1]}function v(t){return Array.isArray(t)}function y(t){return"boolean"==typeof t}function g(t){return null===t}function d(t){return null==t}function m(t){return"number"==typeof t}function b(t){return"string"==typeof t}function w(t){return"symbol"==typeof t}function _(t){return void 0===t}function x(t){return O(t)&&"[object RegExp]"===k(t)}function O(t){return"object"==typeof t&&null!==t}function L(t){return O(t)&&"[object Date]"===k(t)}function j(t){return O(t)&&("[object Error]"===k(t)||t instanceof Error)}function E(t){return"function"==typeof t}function S(t){return null===t||"boolean"==typeof t||"number"==typeof t||"string"==typeof t||"symbol"==typeof t||void 0===t}function k(t){return Object.prototype.toString.call(t)}function R(t){return t<10?"0"+t.toString(10):t.toString(10)}function M(){var t=new Date,e=[R(t.getHours()),R(t.getMinutes()),R(t.getSeconds())].join(":");return[t.getDate(),z[t.getMonth()],e].join(" ")}function T(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var N=/%[sdj%]/g;e.format=function(t){if(!b(t)){for(var e=[],n=0;n=i)return t;switch(t){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return t}}),u=r[n];n0&&this._events[t].length>o&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace()),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){function n(){this.removeListener(t,n),o||(o=!0,e.apply(this,arguments))}if(!r(e))throw TypeError("listener must be a function");var o=!1;return n.listener=e,this.on(t,n),this},n.prototype.removeListener=function(t,e){var n,o,s,u;if(!r(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(n=this._events[t],s=n.length,o=-1,n===e||r(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(i(n)){for(u=s;u-- >0;)if(n[u]===e||n[u].listener&&n[u].listener===e){o=u;break}if(o<0)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(o,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[t],r(n))this.removeListener(t,n);else if(n)for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){return this._events&&this._events[t]?r(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(r(e))return 1;if(e)return e.length}return 0},n.listenerCount=function(t,e){return t.listenerCount(e)}}]); -------------------------------------------------------------------------------- /es5/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _keys = require('babel-runtime/core-js/object/keys'); 4 | 5 | var _keys2 = _interopRequireDefault(_keys); 6 | 7 | var _assign = require('babel-runtime/core-js/object/assign'); 8 | 9 | var _assign2 = _interopRequireDefault(_assign); 10 | 11 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); 12 | 13 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); 14 | 15 | var _createClass2 = require('babel-runtime/helpers/createClass'); 16 | 17 | var _createClass3 = _interopRequireDefault(_createClass2); 18 | 19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 20 | 21 | var fs = require('fs'); 22 | var format = require('util').format; 23 | var EventEmitter = require('events').EventEmitter; 24 | 25 | var isElectronRenderer = process.type && process.type === 'renderer'; 26 | var isNodejs = !isElectronRenderer && process.version ? true : false; 27 | 28 | var LogLevels = { 29 | 'DEBUG': 'DEBUG', 30 | 'INFO': 'INFO', 31 | 'WARN': 'WARN', 32 | 'ERROR': 'ERROR', 33 | 'NONE': 'NONE' 34 | }; 35 | 36 | // Global log level 37 | var GlobalLogLevel = LogLevels.DEBUG; 38 | 39 | // Global log file name 40 | var GlobalLogfile = null; 41 | 42 | var GlobalEvents = new EventEmitter(); 43 | 44 | // ANSI colors 45 | var Colors = { 46 | 'Black': 0, 47 | 'Red': 1, 48 | 'Green': 2, 49 | 'Yellow': 3, 50 | 'Blue': 4, 51 | 'Magenta': 5, 52 | 'Cyan': 6, 53 | 'Grey': 7, 54 | 'White': 9, 55 | 'Default': 9 56 | }; 57 | 58 | // CSS colors 59 | if (!isNodejs) { 60 | Colors = { 61 | 'Black': 'Black', 62 | 'Red': 'IndianRed', 63 | 'Green': 'LimeGreen', 64 | 'Yellow': 'Orange', 65 | 'Blue': 'RoyalBlue', 66 | 'Magenta': 'Orchid', 67 | 'Cyan': 'SkyBlue', 68 | 'Grey': 'DimGrey', 69 | 'White': 'White', 70 | 'Default': 'Black' 71 | }; 72 | } 73 | 74 | var loglevelColors = [Colors.Cyan, Colors.Green, Colors.Yellow, Colors.Red, Colors.Default]; 75 | 76 | var defaultOptions = { 77 | useColors: true, 78 | color: Colors.Default, 79 | showTimestamp: true, 80 | useLocalTime: false, 81 | showLevel: true, 82 | filename: GlobalLogfile, 83 | appendFile: true 84 | }; 85 | 86 | var Logger = function () { 87 | function Logger(category, options) { 88 | (0, _classCallCheck3.default)(this, Logger); 89 | 90 | this.category = category; 91 | var opts = {}; 92 | (0, _assign2.default)(opts, defaultOptions); 93 | (0, _assign2.default)(opts, options); 94 | this.options = opts; 95 | this.debug = this.debug.bind(this); 96 | this.log = this.log.bind(this); 97 | this.info = this.info.bind(this); 98 | this.warn = this.warn.bind(this); 99 | this.error = this.error.bind(this); 100 | } 101 | 102 | (0, _createClass3.default)(Logger, [{ 103 | key: 'debug', 104 | value: function debug() { 105 | if (this._shouldLog(LogLevels.DEBUG)) this._write(LogLevels.DEBUG, format.apply(null, arguments)); 106 | } 107 | }, { 108 | key: 'log', 109 | value: function log() { 110 | if (this._shouldLog(LogLevels.DEBUG)) this.debug.apply(this, arguments); 111 | } 112 | }, { 113 | key: 'info', 114 | value: function info() { 115 | if (this._shouldLog(LogLevels.INFO)) this._write(LogLevels.INFO, format.apply(null, arguments)); 116 | } 117 | }, { 118 | key: 'warn', 119 | value: function warn() { 120 | if (this._shouldLog(LogLevels.WARN)) this._write(LogLevels.WARN, format.apply(null, arguments)); 121 | } 122 | }, { 123 | key: 'error', 124 | value: function error() { 125 | if (this._shouldLog(LogLevels.ERROR)) this._write(LogLevels.ERROR, format.apply(null, arguments)); 126 | } 127 | }, { 128 | key: '_write', 129 | value: function _write(level, text) { 130 | if ((this.options.filename || GlobalLogfile) && !this.fileWriter && isNodejs) this.fileWriter = fs.openSync(this.options.filename || GlobalLogfile, this.options.appendFile ? 'a+' : 'w+'); 131 | 132 | var format = this._format(level, text); 133 | var unformattedText = this._createLogMessage(level, text); 134 | var formattedText = this._createLogMessage(level, text, format.timestamp, format.level, format.category, format.text); 135 | 136 | if (this.fileWriter && isNodejs) fs.writeSync(this.fileWriter, unformattedText + '\n', null, 'utf-8'); 137 | 138 | if (isNodejs || !this.options.useColors) { 139 | console.log(formattedText); 140 | GlobalEvents.emit('data', this.category, level, text); 141 | } else { 142 | // TODO: clean this up 143 | if (level === LogLevels.ERROR) { 144 | if (this.options.showTimestamp && this.options.showLevel) { 145 | console.error(formattedText, format.timestamp, format.level, format.category, format.text); 146 | } else if (this.options.showTimestamp && !this.options.showLevel) { 147 | console.error(formattedText, format.timestamp, format.category, format.text); 148 | } else if (!this.options.showTimestamp && this.options.showLevel) { 149 | console.error(formattedText, format.level, format.category, format.text); 150 | } else { 151 | console.error(formattedText, format.category, format.text); 152 | } 153 | } else { 154 | if (this.options.showTimestamp && this.options.showLevel) { 155 | console.log(formattedText, format.timestamp, format.level, format.category, format.text); 156 | } else if (this.options.showTimestamp && !this.options.showLevel) { 157 | console.log(formattedText, format.timestamp, format.category, format.text); 158 | } else if (!this.options.showTimestamp && this.options.showLevel) { 159 | console.log(formattedText, format.level, format.category, format.text); 160 | } else { 161 | console.log(formattedText, format.category, format.text); 162 | } 163 | } 164 | } 165 | } 166 | }, { 167 | key: '_format', 168 | value: function _format(level, text) { 169 | var timestampFormat = ''; 170 | var levelFormat = ''; 171 | var categoryFormat = ''; 172 | var textFormat = ': '; 173 | 174 | if (this.options.useColors) { 175 | var levelColor = (0, _keys2.default)(LogLevels).map(function (f) { 176 | return LogLevels[f]; 177 | }).indexOf(level); 178 | var categoryColor = this.options.color; 179 | 180 | if (isNodejs) { 181 | if (this.options.showTimestamp) timestampFormat = '\x1B[3' + Colors.Grey + 'm'; 182 | 183 | if (this.options.showLevel) levelFormat = '\x1B[3' + loglevelColors[levelColor] + ';22m'; 184 | 185 | categoryFormat = '\x1B[3' + categoryColor + ';1m'; 186 | textFormat = '\x1B[0m: '; 187 | } else { 188 | if (this.options.showTimestamp) timestampFormat = 'color:' + Colors.Grey; 189 | 190 | if (this.options.showLevel) levelFormat = 'color:' + loglevelColors[levelColor]; 191 | 192 | categoryFormat = 'color:' + categoryColor + '; font-weight: bold'; 193 | } 194 | } 195 | 196 | return { 197 | timestamp: timestampFormat, 198 | level: levelFormat, 199 | category: categoryFormat, 200 | text: textFormat 201 | }; 202 | } 203 | }, { 204 | key: '_createLogMessage', 205 | value: function _createLogMessage(level, text, timestampFormat, levelFormat, categoryFormat, textFormat) { 206 | timestampFormat = timestampFormat || ''; 207 | levelFormat = levelFormat || ''; 208 | categoryFormat = categoryFormat || ''; 209 | textFormat = textFormat || ': '; 210 | 211 | if (!isNodejs && this.options.useColors) { 212 | if (this.options.showTimestamp) timestampFormat = '%c'; 213 | 214 | if (this.options.showLevel) levelFormat = '%c'; 215 | 216 | categoryFormat = '%c'; 217 | textFormat = ': %c'; 218 | } 219 | 220 | var result = ''; 221 | 222 | if (this.options.showTimestamp && !this.options.useLocalTime) result += '' + new Date().toISOString() + ' '; 223 | 224 | if (this.options.showTimestamp && this.options.useLocalTime) result += '' + new Date().toLocaleString() + ' '; 225 | 226 | result = timestampFormat + result; 227 | 228 | if (this.options.showLevel) result += levelFormat + '[' + level + ']' + (level === LogLevels.INFO || level === LogLevels.WARN ? ' ' : '') + ' '; 229 | 230 | result += categoryFormat + this.category; 231 | result += textFormat + text; 232 | return result; 233 | } 234 | }, { 235 | key: '_shouldLog', 236 | value: function _shouldLog(level) { 237 | var envLogLevel = typeof process !== "undefined" && process.env !== undefined && process.env.LOG !== undefined ? process.env.LOG.toUpperCase() : null; 238 | envLogLevel = typeof window !== "undefined" && window.LOG ? window.LOG.toUpperCase() : envLogLevel; 239 | 240 | var logLevel = envLogLevel || GlobalLogLevel; 241 | var levels = (0, _keys2.default)(LogLevels).map(function (f) { 242 | return LogLevels[f]; 243 | }); 244 | var index = levels.indexOf(level); 245 | var levelIdx = levels.indexOf(logLevel); 246 | return index >= levelIdx; 247 | } 248 | }]); 249 | return Logger; 250 | }(); 251 | 252 | ; 253 | 254 | /* Public API */ 255 | module.exports = { 256 | Colors: Colors, 257 | LogLevels: LogLevels, 258 | setLogLevel: function setLogLevel(level) { 259 | GlobalLogLevel = level; 260 | }, 261 | setLogfile: function setLogfile(filename) { 262 | GlobalLogfile = filename; 263 | }, 264 | create: function create(category, options) { 265 | var logger = new Logger(category, options); 266 | return logger; 267 | }, 268 | forceBrowserMode: function forceBrowserMode(force) { 269 | return isNodejs = !force; 270 | }, // for testing, 271 | events: GlobalEvents 272 | }; 273 | -------------------------------------------------------------------------------- /example/browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/bundle.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { 40 | /******/ configurable: false, 41 | /******/ enumerable: true, 42 | /******/ get: getter 43 | /******/ }); 44 | /******/ } 45 | /******/ }; 46 | /******/ 47 | /******/ // getDefaultExport function for compatibility with non-harmony modules 48 | /******/ __webpack_require__.n = function(module) { 49 | /******/ var getter = module && module.__esModule ? 50 | /******/ function getDefault() { return module['default']; } : 51 | /******/ function getModuleExports() { return module; }; 52 | /******/ __webpack_require__.d(getter, 'a', getter); 53 | /******/ return getter; 54 | /******/ }; 55 | /******/ 56 | /******/ // Object.prototype.hasOwnProperty.call 57 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58 | /******/ 59 | /******/ // __webpack_public_path__ 60 | /******/ __webpack_require__.p = ""; 61 | /******/ 62 | /******/ // Load entry module and return exports 63 | /******/ return __webpack_require__(__webpack_require__.s = 15); 64 | /******/ }) 65 | /************************************************************************/ 66 | /******/ ([ 67 | /* 0 */ 68 | /***/ (function(module, exports) { 69 | 70 | var core = module.exports = { version: '2.5.7' }; 71 | if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef 72 | 73 | 74 | /***/ }), 75 | /* 1 */ 76 | /***/ (function(module, exports, __webpack_require__) { 77 | 78 | // Thank's IE8 for his funny defineProperty 79 | module.exports = !__webpack_require__(2)(function () { 80 | return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; 81 | }); 82 | 83 | 84 | /***/ }), 85 | /* 2 */ 86 | /***/ (function(module, exports) { 87 | 88 | module.exports = function (exec) { 89 | try { 90 | return !!exec(); 91 | } catch (e) { 92 | return true; 93 | } 94 | }; 95 | 96 | 97 | /***/ }), 98 | /* 3 */ 99 | /***/ (function(module, exports, __webpack_require__) { 100 | 101 | exports.nextTick = function nextTick(fn) { 102 | setTimeout(fn, 0); 103 | }; 104 | 105 | exports.platform = exports.arch = 106 | exports.execPath = exports.title = 'browser'; 107 | exports.pid = 1; 108 | exports.browser = true; 109 | exports.env = {}; 110 | exports.argv = []; 111 | 112 | exports.binding = function (name) { 113 | throw new Error('No such module. (Possibly not yet loaded)') 114 | }; 115 | 116 | (function () { 117 | var cwd = '/'; 118 | var path; 119 | exports.cwd = function () { return cwd }; 120 | exports.chdir = function (dir) { 121 | if (!path) path = __webpack_require__(17); 122 | cwd = path.resolve(dir, cwd); 123 | }; 124 | })(); 125 | 126 | exports.exit = exports.kill = 127 | exports.umask = exports.dlopen = 128 | exports.uptime = exports.memoryUsage = 129 | exports.uvCounters = function() {}; 130 | exports.features = {}; 131 | 132 | 133 | /***/ }), 134 | /* 4 */ 135 | /***/ (function(module, exports) { 136 | 137 | // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 138 | var global = module.exports = typeof window != 'undefined' && window.Math == Math 139 | ? window : typeof self != 'undefined' && self.Math == Math ? self 140 | // eslint-disable-next-line no-new-func 141 | : Function('return this')(); 142 | if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef 143 | 144 | 145 | /***/ }), 146 | /* 5 */ 147 | /***/ (function(module, exports, __webpack_require__) { 148 | 149 | var global = __webpack_require__(4); 150 | var core = __webpack_require__(0); 151 | var ctx = __webpack_require__(32); 152 | var hide = __webpack_require__(34); 153 | var has = __webpack_require__(10); 154 | var PROTOTYPE = 'prototype'; 155 | 156 | var $export = function (type, name, source) { 157 | var IS_FORCED = type & $export.F; 158 | var IS_GLOBAL = type & $export.G; 159 | var IS_STATIC = type & $export.S; 160 | var IS_PROTO = type & $export.P; 161 | var IS_BIND = type & $export.B; 162 | var IS_WRAP = type & $export.W; 163 | var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); 164 | var expProto = exports[PROTOTYPE]; 165 | var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; 166 | var key, own, out; 167 | if (IS_GLOBAL) source = name; 168 | for (key in source) { 169 | // contains in native 170 | own = !IS_FORCED && target && target[key] !== undefined; 171 | if (own && has(exports, key)) continue; 172 | // export native or passed 173 | out = own ? target[key] : source[key]; 174 | // prevent global pollution for namespaces 175 | exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] 176 | // bind timers to global for call from export context 177 | : IS_BIND && own ? ctx(out, global) 178 | // wrap global constructors for prevent change them in library 179 | : IS_WRAP && target[key] == out ? (function (C) { 180 | var F = function (a, b, c) { 181 | if (this instanceof C) { 182 | switch (arguments.length) { 183 | case 0: return new C(); 184 | case 1: return new C(a); 185 | case 2: return new C(a, b); 186 | } return new C(a, b, c); 187 | } return C.apply(this, arguments); 188 | }; 189 | F[PROTOTYPE] = C[PROTOTYPE]; 190 | return F; 191 | // make static versions for prototype methods 192 | })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; 193 | // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% 194 | if (IS_PROTO) { 195 | (exports.virtual || (exports.virtual = {}))[key] = out; 196 | // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% 197 | if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); 198 | } 199 | } 200 | }; 201 | // type bitmap 202 | $export.F = 1; // forced 203 | $export.G = 2; // global 204 | $export.S = 4; // static 205 | $export.P = 8; // proto 206 | $export.B = 16; // bind 207 | $export.W = 32; // wrap 208 | $export.U = 64; // safe 209 | $export.R = 128; // real proto method for `library` 210 | module.exports = $export; 211 | 212 | 213 | /***/ }), 214 | /* 6 */ 215 | /***/ (function(module, exports) { 216 | 217 | module.exports = function (it) { 218 | return typeof it === 'object' ? it !== null : typeof it === 'function'; 219 | }; 220 | 221 | 222 | /***/ }), 223 | /* 7 */ 224 | /***/ (function(module, exports, __webpack_require__) { 225 | 226 | // 7.1.13 ToObject(argument) 227 | var defined = __webpack_require__(8); 228 | module.exports = function (it) { 229 | return Object(defined(it)); 230 | }; 231 | 232 | 233 | /***/ }), 234 | /* 8 */ 235 | /***/ (function(module, exports) { 236 | 237 | // 7.2.1 RequireObjectCoercible(argument) 238 | module.exports = function (it) { 239 | if (it == undefined) throw TypeError("Can't call method on " + it); 240 | return it; 241 | }; 242 | 243 | 244 | /***/ }), 245 | /* 9 */ 246 | /***/ (function(module, exports, __webpack_require__) { 247 | 248 | // 19.1.2.14 / 15.2.3.14 Object.keys(O) 249 | var $keys = __webpack_require__(21); 250 | var enumBugKeys = __webpack_require__(30); 251 | 252 | module.exports = Object.keys || function keys(O) { 253 | return $keys(O, enumBugKeys); 254 | }; 255 | 256 | 257 | /***/ }), 258 | /* 10 */ 259 | /***/ (function(module, exports) { 260 | 261 | var hasOwnProperty = {}.hasOwnProperty; 262 | module.exports = function (it, key) { 263 | return hasOwnProperty.call(it, key); 264 | }; 265 | 266 | 267 | /***/ }), 268 | /* 11 */ 269 | /***/ (function(module, exports, __webpack_require__) { 270 | 271 | // to indexed object, toObject with fallback for non-array-like ES3 strings 272 | var IObject = __webpack_require__(12); 273 | var defined = __webpack_require__(8); 274 | module.exports = function (it) { 275 | return IObject(defined(it)); 276 | }; 277 | 278 | 279 | /***/ }), 280 | /* 12 */ 281 | /***/ (function(module, exports, __webpack_require__) { 282 | 283 | // fallback for non-array-like ES3 and non-enumerable old V8 strings 284 | var cof = __webpack_require__(22); 285 | // eslint-disable-next-line no-prototype-builtins 286 | module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { 287 | return cof(it) == 'String' ? it.split('') : Object(it); 288 | }; 289 | 290 | 291 | /***/ }), 292 | /* 13 */ 293 | /***/ (function(module, exports) { 294 | 295 | // 7.1.4 ToInteger 296 | var ceil = Math.ceil; 297 | var floor = Math.floor; 298 | module.exports = function (it) { 299 | return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); 300 | }; 301 | 302 | 303 | /***/ }), 304 | /* 14 */ 305 | /***/ (function(module, exports, __webpack_require__) { 306 | 307 | var anObject = __webpack_require__(35); 308 | var IE8_DOM_DEFINE = __webpack_require__(36); 309 | var toPrimitive = __webpack_require__(38); 310 | var dP = Object.defineProperty; 311 | 312 | exports.f = __webpack_require__(1) ? Object.defineProperty : function defineProperty(O, P, Attributes) { 313 | anObject(O); 314 | P = toPrimitive(P, true); 315 | anObject(Attributes); 316 | if (IE8_DOM_DEFINE) try { 317 | return dP(O, P, Attributes); 318 | } catch (e) { /* empty */ } 319 | if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); 320 | if ('value' in Attributes) O[P] = Attributes.value; 321 | return O; 322 | }; 323 | 324 | 325 | /***/ }), 326 | /* 15 */ 327 | /***/ (function(module, exports, __webpack_require__) { 328 | 329 | "use strict"; 330 | 331 | 332 | /* 333 | Using the ES5 module for the sake of example. 334 | To use the regular ES6 version, one would include it with: 335 | const Logger = require('logplease') 336 | */ 337 | 338 | var Logger = __webpack_require__(16); 339 | 340 | var logger1 = Logger.create('daemon', { filename: 'debug.log', useColors: false, appendFile: true }); 341 | var logger2 = Logger.create('utils'); 342 | var logger3 = Logger.create('logger3', { color: Logger.Colors.Magenta, showTimestamp: false, showLevel: false }); 343 | var logger4 = Logger.create('logger4-local-time', { useLocalTime: true }); 344 | 345 | var red = Logger.create('red', { color: Logger.Colors.Red, showTimestamp: false, showLevel: false }); 346 | var green = Logger.create('green', { color: Logger.Colors.Green, showTimestamp: false, showLevel: false }); 347 | var yellow = Logger.create('yellow', { color: Logger.Colors.Yellow, showTimestamp: false, showLevel: false }); 348 | var blue = Logger.create('blue', { color: Logger.Colors.Blue, showTimestamp: false, showLevel: false }); 349 | var magenta = Logger.create('magenta', { color: Logger.Colors.Magenta, showTimestamp: false, showLevel: false }); 350 | var cyan = Logger.create('cyan', { color: Logger.Colors.Cyan, showTimestamp: false, showLevel: false }); 351 | 352 | Logger.setLogLevel(Logger.LogLevels.DEBUG); 353 | 354 | // CAVEAT: log functions can't take any parameters, if you need params, use interpolated strings 355 | var number = 5; 356 | logger1.debug('This is a debug message #' + number); 357 | logger1.info('This is an info message #' + number); 358 | logger1.warn('This is a warning message #' + number); 359 | logger1.error('This is an error message #' + number); 360 | 361 | logger2.debug('This is a debug message #' + number); 362 | logger2.info('This is an info message #' + number); 363 | logger2.warn('This is a warning message #' + number); 364 | logger2.error('This is an error message #' + number); 365 | 366 | logger3.debug('This is a debug message #' + number); 367 | logger3.info('This is an info message #' + number); 368 | logger3.warn('This is a warning message #' + number); 369 | logger3.error('This is an error message #' + number); 370 | 371 | logger4.debug('This is a debug message #' + number); 372 | logger4.info('This is an info message #' + number); 373 | logger4.warn('This is a warning message #' + number); 374 | logger4.error('This is an error message #' + number); 375 | 376 | red.log('Red log message'); // log() is an alias for debug() 377 | green.log('Green log message'); 378 | yellow.log('Yellow log message'); 379 | blue.log('Blue log message'); 380 | magenta.log('Magenta log message'); 381 | cyan.log('Cyan log message'); 382 | 383 | /***/ }), 384 | /* 16 */ 385 | /***/ (function(module, exports, __webpack_require__) { 386 | 387 | "use strict"; 388 | /* WEBPACK VAR INJECTION */(function(process) { 389 | 390 | var _keys = __webpack_require__(18); 391 | 392 | var _keys2 = _interopRequireDefault(_keys); 393 | 394 | var _assign = __webpack_require__(40); 395 | 396 | var _assign2 = _interopRequireDefault(_assign); 397 | 398 | var _classCallCheck2 = __webpack_require__(46); 399 | 400 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); 401 | 402 | var _createClass2 = __webpack_require__(47); 403 | 404 | var _createClass3 = _interopRequireDefault(_createClass2); 405 | 406 | function _interopRequireDefault(obj) { 407 | return obj && obj.__esModule ? obj : { default: obj }; 408 | } 409 | 410 | var fs = __webpack_require__(51); 411 | var format = __webpack_require__(52).format; 412 | var EventEmitter = __webpack_require__(56).EventEmitter; 413 | 414 | var isElectronRenderer = process.type && process.type === 'renderer'; 415 | var isNodejs = !isElectronRenderer && process.version ? true : false; 416 | 417 | var LogLevels = { 418 | 'DEBUG': 'DEBUG', 419 | 'INFO': 'INFO', 420 | 'WARN': 'WARN', 421 | 'ERROR': 'ERROR', 422 | 'NONE': 'NONE' 423 | }; 424 | 425 | // Global log level 426 | var GlobalLogLevel = LogLevels.DEBUG; 427 | 428 | // Global log file name 429 | var GlobalLogfile = null; 430 | 431 | var GlobalEvents = new EventEmitter(); 432 | 433 | // ANSI colors 434 | var Colors = { 435 | 'Black': 0, 436 | 'Red': 1, 437 | 'Green': 2, 438 | 'Yellow': 3, 439 | 'Blue': 4, 440 | 'Magenta': 5, 441 | 'Cyan': 6, 442 | 'Grey': 7, 443 | 'White': 9, 444 | 'Default': 9 445 | }; 446 | 447 | // CSS colors 448 | if (!isNodejs) { 449 | Colors = { 450 | 'Black': 'Black', 451 | 'Red': 'IndianRed', 452 | 'Green': 'LimeGreen', 453 | 'Yellow': 'Orange', 454 | 'Blue': 'RoyalBlue', 455 | 'Magenta': 'Orchid', 456 | 'Cyan': 'SkyBlue', 457 | 'Grey': 'DimGrey', 458 | 'White': 'White', 459 | 'Default': 'Black' 460 | }; 461 | } 462 | 463 | var loglevelColors = [Colors.Cyan, Colors.Green, Colors.Yellow, Colors.Red, Colors.Default]; 464 | 465 | var defaultOptions = { 466 | useColors: true, 467 | color: Colors.Default, 468 | showTimestamp: true, 469 | useLocalTime: false, 470 | showLevel: true, 471 | filename: GlobalLogfile, 472 | appendFile: true 473 | }; 474 | 475 | var Logger = function () { 476 | function Logger(category, options) { 477 | (0, _classCallCheck3.default)(this, Logger); 478 | 479 | this.category = category; 480 | var opts = {}; 481 | (0, _assign2.default)(opts, defaultOptions); 482 | (0, _assign2.default)(opts, options); 483 | this.options = opts; 484 | this.debug = this.debug.bind(this); 485 | this.log = this.log.bind(this); 486 | this.info = this.info.bind(this); 487 | this.warn = this.warn.bind(this); 488 | this.error = this.error.bind(this); 489 | } 490 | 491 | (0, _createClass3.default)(Logger, [{ 492 | key: 'debug', 493 | value: function debug() { 494 | if (this._shouldLog(LogLevels.DEBUG)) this._write(LogLevels.DEBUG, format.apply(null, arguments)); 495 | } 496 | }, { 497 | key: 'log', 498 | value: function log() { 499 | if (this._shouldLog(LogLevels.DEBUG)) this.debug.apply(this, arguments); 500 | } 501 | }, { 502 | key: 'info', 503 | value: function info() { 504 | if (this._shouldLog(LogLevels.INFO)) this._write(LogLevels.INFO, format.apply(null, arguments)); 505 | } 506 | }, { 507 | key: 'warn', 508 | value: function warn() { 509 | if (this._shouldLog(LogLevels.WARN)) this._write(LogLevels.WARN, format.apply(null, arguments)); 510 | } 511 | }, { 512 | key: 'error', 513 | value: function error() { 514 | if (this._shouldLog(LogLevels.ERROR)) this._write(LogLevels.ERROR, format.apply(null, arguments)); 515 | } 516 | }, { 517 | key: '_write', 518 | value: function _write(level, text) { 519 | if ((this.options.filename || GlobalLogfile) && !this.fileWriter && isNodejs) this.fileWriter = fs.openSync(this.options.filename || GlobalLogfile, this.options.appendFile ? 'a+' : 'w+'); 520 | 521 | var format = this._format(level, text); 522 | var unformattedText = this._createLogMessage(level, text); 523 | var formattedText = this._createLogMessage(level, text, format.timestamp, format.level, format.category, format.text); 524 | 525 | if (this.fileWriter && isNodejs) fs.writeSync(this.fileWriter, unformattedText + '\n', null, 'utf-8'); 526 | 527 | if (isNodejs || !this.options.useColors) { 528 | console.log(formattedText); 529 | GlobalEvents.emit('data', this.category, level, text); 530 | } else { 531 | // TODO: clean this up 532 | if (level === LogLevels.ERROR) { 533 | if (this.options.showTimestamp && this.options.showLevel) { 534 | console.error(formattedText, format.timestamp, format.level, format.category, format.text); 535 | } else if (this.options.showTimestamp && !this.options.showLevel) { 536 | console.error(formattedText, format.timestamp, format.category, format.text); 537 | } else if (!this.options.showTimestamp && this.options.showLevel) { 538 | console.error(formattedText, format.level, format.category, format.text); 539 | } else { 540 | console.error(formattedText, format.category, format.text); 541 | } 542 | } else { 543 | if (this.options.showTimestamp && this.options.showLevel) { 544 | console.log(formattedText, format.timestamp, format.level, format.category, format.text); 545 | } else if (this.options.showTimestamp && !this.options.showLevel) { 546 | console.log(formattedText, format.timestamp, format.category, format.text); 547 | } else if (!this.options.showTimestamp && this.options.showLevel) { 548 | console.log(formattedText, format.level, format.category, format.text); 549 | } else { 550 | console.log(formattedText, format.category, format.text); 551 | } 552 | } 553 | } 554 | } 555 | }, { 556 | key: '_format', 557 | value: function _format(level, text) { 558 | var timestampFormat = ''; 559 | var levelFormat = ''; 560 | var categoryFormat = ''; 561 | var textFormat = ': '; 562 | 563 | if (this.options.useColors) { 564 | var levelColor = (0, _keys2.default)(LogLevels).map(function (f) { 565 | return LogLevels[f]; 566 | }).indexOf(level); 567 | var categoryColor = this.options.color; 568 | 569 | if (isNodejs) { 570 | if (this.options.showTimestamp) timestampFormat = '\x1B[3' + Colors.Grey + 'm'; 571 | 572 | if (this.options.showLevel) levelFormat = '\x1B[3' + loglevelColors[levelColor] + ';22m'; 573 | 574 | categoryFormat = '\x1B[3' + categoryColor + ';1m'; 575 | textFormat = '\x1B[0m: '; 576 | } else { 577 | if (this.options.showTimestamp) timestampFormat = 'color:' + Colors.Grey; 578 | 579 | if (this.options.showLevel) levelFormat = 'color:' + loglevelColors[levelColor]; 580 | 581 | categoryFormat = 'color:' + categoryColor + '; font-weight: bold'; 582 | } 583 | } 584 | 585 | return { 586 | timestamp: timestampFormat, 587 | level: levelFormat, 588 | category: categoryFormat, 589 | text: textFormat 590 | }; 591 | } 592 | }, { 593 | key: '_createLogMessage', 594 | value: function _createLogMessage(level, text, timestampFormat, levelFormat, categoryFormat, textFormat) { 595 | timestampFormat = timestampFormat || ''; 596 | levelFormat = levelFormat || ''; 597 | categoryFormat = categoryFormat || ''; 598 | textFormat = textFormat || ': '; 599 | 600 | if (!isNodejs && this.options.useColors) { 601 | if (this.options.showTimestamp) timestampFormat = '%c'; 602 | 603 | if (this.options.showLevel) levelFormat = '%c'; 604 | 605 | categoryFormat = '%c'; 606 | textFormat = ': %c'; 607 | } 608 | 609 | var result = ''; 610 | 611 | if (this.options.showTimestamp && !this.options.useLocalTime) result += '' + new Date().toISOString() + ' '; 612 | 613 | if (this.options.showTimestamp && this.options.useLocalTime) result += '' + new Date().toLocaleString() + ' '; 614 | 615 | result = timestampFormat + result; 616 | 617 | if (this.options.showLevel) result += levelFormat + '[' + level + ']' + (level === LogLevels.INFO || level === LogLevels.WARN ? ' ' : '') + ' '; 618 | 619 | result += categoryFormat + this.category; 620 | result += textFormat + text; 621 | return result; 622 | } 623 | }, { 624 | key: '_shouldLog', 625 | value: function _shouldLog(level) { 626 | var envLogLevel = typeof process !== "undefined" && process.env !== undefined && process.env.LOG !== undefined ? process.env.LOG.toUpperCase() : null; 627 | envLogLevel = typeof window !== "undefined" && window.LOG ? window.LOG.toUpperCase() : envLogLevel; 628 | 629 | var logLevel = envLogLevel || GlobalLogLevel; 630 | var levels = (0, _keys2.default)(LogLevels).map(function (f) { 631 | return LogLevels[f]; 632 | }); 633 | var index = levels.indexOf(level); 634 | var levelIdx = levels.indexOf(logLevel); 635 | return index >= levelIdx; 636 | } 637 | }]); 638 | return Logger; 639 | }(); 640 | 641 | ; 642 | 643 | /* Public API */ 644 | module.exports = { 645 | Colors: Colors, 646 | LogLevels: LogLevels, 647 | setLogLevel: function setLogLevel(level) { 648 | GlobalLogLevel = level; 649 | }, 650 | setLogfile: function setLogfile(filename) { 651 | GlobalLogfile = filename; 652 | }, 653 | create: function create(category, options) { 654 | var logger = new Logger(category, options); 655 | return logger; 656 | }, 657 | forceBrowserMode: function forceBrowserMode(force) { 658 | return isNodejs = !force; 659 | }, // for testing, 660 | events: GlobalEvents 661 | }; 662 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 663 | 664 | /***/ }), 665 | /* 17 */ 666 | /***/ (function(module, exports, __webpack_require__) { 667 | 668 | /* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors. 669 | // 670 | // Permission is hereby granted, free of charge, to any person obtaining a 671 | // copy of this software and associated documentation files (the 672 | // "Software"), to deal in the Software without restriction, including 673 | // without limitation the rights to use, copy, modify, merge, publish, 674 | // distribute, sublicense, and/or sell copies of the Software, and to permit 675 | // persons to whom the Software is furnished to do so, subject to the 676 | // following conditions: 677 | // 678 | // The above copyright notice and this permission notice shall be included 679 | // in all copies or substantial portions of the Software. 680 | // 681 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 682 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 683 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 684 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 685 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 686 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 687 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 688 | 689 | // resolves . and .. elements in a path array with directory names there 690 | // must be no slashes, empty elements, or device names (c:\) in the array 691 | // (so also no leading and trailing slashes - it does not distinguish 692 | // relative and absolute paths) 693 | function normalizeArray(parts, allowAboveRoot) { 694 | // if the path tries to go above the root, `up` ends up > 0 695 | var up = 0; 696 | for (var i = parts.length - 1; i >= 0; i--) { 697 | var last = parts[i]; 698 | if (last === '.') { 699 | parts.splice(i, 1); 700 | } else if (last === '..') { 701 | parts.splice(i, 1); 702 | up++; 703 | } else if (up) { 704 | parts.splice(i, 1); 705 | up--; 706 | } 707 | } 708 | 709 | // if the path is allowed to go above the root, restore leading ..s 710 | if (allowAboveRoot) { 711 | for (; up--; up) { 712 | parts.unshift('..'); 713 | } 714 | } 715 | 716 | return parts; 717 | } 718 | 719 | // Split a filename into [root, dir, basename, ext], unix version 720 | // 'root' is just a slash, or nothing. 721 | var splitPathRe = 722 | /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; 723 | var splitPath = function(filename) { 724 | return splitPathRe.exec(filename).slice(1); 725 | }; 726 | 727 | // path.resolve([from ...], to) 728 | // posix version 729 | exports.resolve = function() { 730 | var resolvedPath = '', 731 | resolvedAbsolute = false; 732 | 733 | for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { 734 | var path = (i >= 0) ? arguments[i] : process.cwd(); 735 | 736 | // Skip empty and invalid entries 737 | if (typeof path !== 'string') { 738 | throw new TypeError('Arguments to path.resolve must be strings'); 739 | } else if (!path) { 740 | continue; 741 | } 742 | 743 | resolvedPath = path + '/' + resolvedPath; 744 | resolvedAbsolute = path.charAt(0) === '/'; 745 | } 746 | 747 | // At this point the path should be resolved to a full absolute path, but 748 | // handle relative paths to be safe (might happen when process.cwd() fails) 749 | 750 | // Normalize the path 751 | resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { 752 | return !!p; 753 | }), !resolvedAbsolute).join('/'); 754 | 755 | return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; 756 | }; 757 | 758 | // path.normalize(path) 759 | // posix version 760 | exports.normalize = function(path) { 761 | var isAbsolute = exports.isAbsolute(path), 762 | trailingSlash = substr(path, -1) === '/'; 763 | 764 | // Normalize the path 765 | path = normalizeArray(filter(path.split('/'), function(p) { 766 | return !!p; 767 | }), !isAbsolute).join('/'); 768 | 769 | if (!path && !isAbsolute) { 770 | path = '.'; 771 | } 772 | if (path && trailingSlash) { 773 | path += '/'; 774 | } 775 | 776 | return (isAbsolute ? '/' : '') + path; 777 | }; 778 | 779 | // posix version 780 | exports.isAbsolute = function(path) { 781 | return path.charAt(0) === '/'; 782 | }; 783 | 784 | // posix version 785 | exports.join = function() { 786 | var paths = Array.prototype.slice.call(arguments, 0); 787 | return exports.normalize(filter(paths, function(p, index) { 788 | if (typeof p !== 'string') { 789 | throw new TypeError('Arguments to path.join must be strings'); 790 | } 791 | return p; 792 | }).join('/')); 793 | }; 794 | 795 | 796 | // path.relative(from, to) 797 | // posix version 798 | exports.relative = function(from, to) { 799 | from = exports.resolve(from).substr(1); 800 | to = exports.resolve(to).substr(1); 801 | 802 | function trim(arr) { 803 | var start = 0; 804 | for (; start < arr.length; start++) { 805 | if (arr[start] !== '') break; 806 | } 807 | 808 | var end = arr.length - 1; 809 | for (; end >= 0; end--) { 810 | if (arr[end] !== '') break; 811 | } 812 | 813 | if (start > end) return []; 814 | return arr.slice(start, end - start + 1); 815 | } 816 | 817 | var fromParts = trim(from.split('/')); 818 | var toParts = trim(to.split('/')); 819 | 820 | var length = Math.min(fromParts.length, toParts.length); 821 | var samePartsLength = length; 822 | for (var i = 0; i < length; i++) { 823 | if (fromParts[i] !== toParts[i]) { 824 | samePartsLength = i; 825 | break; 826 | } 827 | } 828 | 829 | var outputParts = []; 830 | for (var i = samePartsLength; i < fromParts.length; i++) { 831 | outputParts.push('..'); 832 | } 833 | 834 | outputParts = outputParts.concat(toParts.slice(samePartsLength)); 835 | 836 | return outputParts.join('/'); 837 | }; 838 | 839 | exports.sep = '/'; 840 | exports.delimiter = ':'; 841 | 842 | exports.dirname = function(path) { 843 | var result = splitPath(path), 844 | root = result[0], 845 | dir = result[1]; 846 | 847 | if (!root && !dir) { 848 | // No dirname whatsoever 849 | return '.'; 850 | } 851 | 852 | if (dir) { 853 | // It has a dirname, strip trailing slash 854 | dir = dir.substr(0, dir.length - 1); 855 | } 856 | 857 | return root + dir; 858 | }; 859 | 860 | 861 | exports.basename = function(path, ext) { 862 | var f = splitPath(path)[2]; 863 | // TODO: make this comparison case-insensitive on windows? 864 | if (ext && f.substr(-1 * ext.length) === ext) { 865 | f = f.substr(0, f.length - ext.length); 866 | } 867 | return f; 868 | }; 869 | 870 | 871 | exports.extname = function(path) { 872 | return splitPath(path)[3]; 873 | }; 874 | 875 | function filter (xs, f) { 876 | if (xs.filter) return xs.filter(f); 877 | var res = []; 878 | for (var i = 0; i < xs.length; i++) { 879 | if (f(xs[i], i, xs)) res.push(xs[i]); 880 | } 881 | return res; 882 | } 883 | 884 | // String.prototype.substr - negative index don't work in IE8 885 | var substr = 'ab'.substr(-1) === 'b' 886 | ? function (str, start, len) { return str.substr(start, len) } 887 | : function (str, start, len) { 888 | if (start < 0) start = str.length + start; 889 | return str.substr(start, len); 890 | } 891 | ; 892 | 893 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 894 | 895 | /***/ }), 896 | /* 18 */ 897 | /***/ (function(module, exports, __webpack_require__) { 898 | 899 | module.exports = { "default": __webpack_require__(19), __esModule: true }; 900 | 901 | /***/ }), 902 | /* 19 */ 903 | /***/ (function(module, exports, __webpack_require__) { 904 | 905 | __webpack_require__(20); 906 | module.exports = __webpack_require__(0).Object.keys; 907 | 908 | 909 | /***/ }), 910 | /* 20 */ 911 | /***/ (function(module, exports, __webpack_require__) { 912 | 913 | // 19.1.2.14 Object.keys(O) 914 | var toObject = __webpack_require__(7); 915 | var $keys = __webpack_require__(9); 916 | 917 | __webpack_require__(31)('keys', function () { 918 | return function keys(it) { 919 | return $keys(toObject(it)); 920 | }; 921 | }); 922 | 923 | 924 | /***/ }), 925 | /* 21 */ 926 | /***/ (function(module, exports, __webpack_require__) { 927 | 928 | var has = __webpack_require__(10); 929 | var toIObject = __webpack_require__(11); 930 | var arrayIndexOf = __webpack_require__(23)(false); 931 | var IE_PROTO = __webpack_require__(26)('IE_PROTO'); 932 | 933 | module.exports = function (object, names) { 934 | var O = toIObject(object); 935 | var i = 0; 936 | var result = []; 937 | var key; 938 | for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); 939 | // Don't enum bug & hidden keys 940 | while (names.length > i) if (has(O, key = names[i++])) { 941 | ~arrayIndexOf(result, key) || result.push(key); 942 | } 943 | return result; 944 | }; 945 | 946 | 947 | /***/ }), 948 | /* 22 */ 949 | /***/ (function(module, exports) { 950 | 951 | var toString = {}.toString; 952 | 953 | module.exports = function (it) { 954 | return toString.call(it).slice(8, -1); 955 | }; 956 | 957 | 958 | /***/ }), 959 | /* 23 */ 960 | /***/ (function(module, exports, __webpack_require__) { 961 | 962 | // false -> Array#indexOf 963 | // true -> Array#includes 964 | var toIObject = __webpack_require__(11); 965 | var toLength = __webpack_require__(24); 966 | var toAbsoluteIndex = __webpack_require__(25); 967 | module.exports = function (IS_INCLUDES) { 968 | return function ($this, el, fromIndex) { 969 | var O = toIObject($this); 970 | var length = toLength(O.length); 971 | var index = toAbsoluteIndex(fromIndex, length); 972 | var value; 973 | // Array#includes uses SameValueZero equality algorithm 974 | // eslint-disable-next-line no-self-compare 975 | if (IS_INCLUDES && el != el) while (length > index) { 976 | value = O[index++]; 977 | // eslint-disable-next-line no-self-compare 978 | if (value != value) return true; 979 | // Array#indexOf ignores holes, Array#includes - not 980 | } else for (;length > index; index++) if (IS_INCLUDES || index in O) { 981 | if (O[index] === el) return IS_INCLUDES || index || 0; 982 | } return !IS_INCLUDES && -1; 983 | }; 984 | }; 985 | 986 | 987 | /***/ }), 988 | /* 24 */ 989 | /***/ (function(module, exports, __webpack_require__) { 990 | 991 | // 7.1.15 ToLength 992 | var toInteger = __webpack_require__(13); 993 | var min = Math.min; 994 | module.exports = function (it) { 995 | return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 996 | }; 997 | 998 | 999 | /***/ }), 1000 | /* 25 */ 1001 | /***/ (function(module, exports, __webpack_require__) { 1002 | 1003 | var toInteger = __webpack_require__(13); 1004 | var max = Math.max; 1005 | var min = Math.min; 1006 | module.exports = function (index, length) { 1007 | index = toInteger(index); 1008 | return index < 0 ? max(index + length, 0) : min(index, length); 1009 | }; 1010 | 1011 | 1012 | /***/ }), 1013 | /* 26 */ 1014 | /***/ (function(module, exports, __webpack_require__) { 1015 | 1016 | var shared = __webpack_require__(27)('keys'); 1017 | var uid = __webpack_require__(29); 1018 | module.exports = function (key) { 1019 | return shared[key] || (shared[key] = uid(key)); 1020 | }; 1021 | 1022 | 1023 | /***/ }), 1024 | /* 27 */ 1025 | /***/ (function(module, exports, __webpack_require__) { 1026 | 1027 | var core = __webpack_require__(0); 1028 | var global = __webpack_require__(4); 1029 | var SHARED = '__core-js_shared__'; 1030 | var store = global[SHARED] || (global[SHARED] = {}); 1031 | 1032 | (module.exports = function (key, value) { 1033 | return store[key] || (store[key] = value !== undefined ? value : {}); 1034 | })('versions', []).push({ 1035 | version: core.version, 1036 | mode: __webpack_require__(28) ? 'pure' : 'global', 1037 | copyright: '© 2018 Denis Pushkarev (zloirock.ru)' 1038 | }); 1039 | 1040 | 1041 | /***/ }), 1042 | /* 28 */ 1043 | /***/ (function(module, exports) { 1044 | 1045 | module.exports = true; 1046 | 1047 | 1048 | /***/ }), 1049 | /* 29 */ 1050 | /***/ (function(module, exports) { 1051 | 1052 | var id = 0; 1053 | var px = Math.random(); 1054 | module.exports = function (key) { 1055 | return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); 1056 | }; 1057 | 1058 | 1059 | /***/ }), 1060 | /* 30 */ 1061 | /***/ (function(module, exports) { 1062 | 1063 | // IE 8- don't enum bug keys 1064 | module.exports = ( 1065 | 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' 1066 | ).split(','); 1067 | 1068 | 1069 | /***/ }), 1070 | /* 31 */ 1071 | /***/ (function(module, exports, __webpack_require__) { 1072 | 1073 | // most Object methods by ES6 should accept primitives 1074 | var $export = __webpack_require__(5); 1075 | var core = __webpack_require__(0); 1076 | var fails = __webpack_require__(2); 1077 | module.exports = function (KEY, exec) { 1078 | var fn = (core.Object || {})[KEY] || Object[KEY]; 1079 | var exp = {}; 1080 | exp[KEY] = exec(fn); 1081 | $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp); 1082 | }; 1083 | 1084 | 1085 | /***/ }), 1086 | /* 32 */ 1087 | /***/ (function(module, exports, __webpack_require__) { 1088 | 1089 | // optional / simple context binding 1090 | var aFunction = __webpack_require__(33); 1091 | module.exports = function (fn, that, length) { 1092 | aFunction(fn); 1093 | if (that === undefined) return fn; 1094 | switch (length) { 1095 | case 1: return function (a) { 1096 | return fn.call(that, a); 1097 | }; 1098 | case 2: return function (a, b) { 1099 | return fn.call(that, a, b); 1100 | }; 1101 | case 3: return function (a, b, c) { 1102 | return fn.call(that, a, b, c); 1103 | }; 1104 | } 1105 | return function (/* ...args */) { 1106 | return fn.apply(that, arguments); 1107 | }; 1108 | }; 1109 | 1110 | 1111 | /***/ }), 1112 | /* 33 */ 1113 | /***/ (function(module, exports) { 1114 | 1115 | module.exports = function (it) { 1116 | if (typeof it != 'function') throw TypeError(it + ' is not a function!'); 1117 | return it; 1118 | }; 1119 | 1120 | 1121 | /***/ }), 1122 | /* 34 */ 1123 | /***/ (function(module, exports, __webpack_require__) { 1124 | 1125 | var dP = __webpack_require__(14); 1126 | var createDesc = __webpack_require__(39); 1127 | module.exports = __webpack_require__(1) ? function (object, key, value) { 1128 | return dP.f(object, key, createDesc(1, value)); 1129 | } : function (object, key, value) { 1130 | object[key] = value; 1131 | return object; 1132 | }; 1133 | 1134 | 1135 | /***/ }), 1136 | /* 35 */ 1137 | /***/ (function(module, exports, __webpack_require__) { 1138 | 1139 | var isObject = __webpack_require__(6); 1140 | module.exports = function (it) { 1141 | if (!isObject(it)) throw TypeError(it + ' is not an object!'); 1142 | return it; 1143 | }; 1144 | 1145 | 1146 | /***/ }), 1147 | /* 36 */ 1148 | /***/ (function(module, exports, __webpack_require__) { 1149 | 1150 | module.exports = !__webpack_require__(1) && !__webpack_require__(2)(function () { 1151 | return Object.defineProperty(__webpack_require__(37)('div'), 'a', { get: function () { return 7; } }).a != 7; 1152 | }); 1153 | 1154 | 1155 | /***/ }), 1156 | /* 37 */ 1157 | /***/ (function(module, exports, __webpack_require__) { 1158 | 1159 | var isObject = __webpack_require__(6); 1160 | var document = __webpack_require__(4).document; 1161 | // typeof document.createElement is 'object' in old IE 1162 | var is = isObject(document) && isObject(document.createElement); 1163 | module.exports = function (it) { 1164 | return is ? document.createElement(it) : {}; 1165 | }; 1166 | 1167 | 1168 | /***/ }), 1169 | /* 38 */ 1170 | /***/ (function(module, exports, __webpack_require__) { 1171 | 1172 | // 7.1.1 ToPrimitive(input [, PreferredType]) 1173 | var isObject = __webpack_require__(6); 1174 | // instead of the ES6 spec version, we didn't implement @@toPrimitive case 1175 | // and the second argument - flag - preferred type is a string 1176 | module.exports = function (it, S) { 1177 | if (!isObject(it)) return it; 1178 | var fn, val; 1179 | if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; 1180 | if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; 1181 | if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; 1182 | throw TypeError("Can't convert object to primitive value"); 1183 | }; 1184 | 1185 | 1186 | /***/ }), 1187 | /* 39 */ 1188 | /***/ (function(module, exports) { 1189 | 1190 | module.exports = function (bitmap, value) { 1191 | return { 1192 | enumerable: !(bitmap & 1), 1193 | configurable: !(bitmap & 2), 1194 | writable: !(bitmap & 4), 1195 | value: value 1196 | }; 1197 | }; 1198 | 1199 | 1200 | /***/ }), 1201 | /* 40 */ 1202 | /***/ (function(module, exports, __webpack_require__) { 1203 | 1204 | module.exports = { "default": __webpack_require__(41), __esModule: true }; 1205 | 1206 | /***/ }), 1207 | /* 41 */ 1208 | /***/ (function(module, exports, __webpack_require__) { 1209 | 1210 | __webpack_require__(42); 1211 | module.exports = __webpack_require__(0).Object.assign; 1212 | 1213 | 1214 | /***/ }), 1215 | /* 42 */ 1216 | /***/ (function(module, exports, __webpack_require__) { 1217 | 1218 | // 19.1.3.1 Object.assign(target, source) 1219 | var $export = __webpack_require__(5); 1220 | 1221 | $export($export.S + $export.F, 'Object', { assign: __webpack_require__(43) }); 1222 | 1223 | 1224 | /***/ }), 1225 | /* 43 */ 1226 | /***/ (function(module, exports, __webpack_require__) { 1227 | 1228 | "use strict"; 1229 | 1230 | // 19.1.2.1 Object.assign(target, source, ...) 1231 | var getKeys = __webpack_require__(9); 1232 | var gOPS = __webpack_require__(44); 1233 | var pIE = __webpack_require__(45); 1234 | var toObject = __webpack_require__(7); 1235 | var IObject = __webpack_require__(12); 1236 | var $assign = Object.assign; 1237 | 1238 | // should work with symbols and should have deterministic property order (V8 bug) 1239 | module.exports = !$assign || __webpack_require__(2)(function () { 1240 | var A = {}; 1241 | var B = {}; 1242 | // eslint-disable-next-line no-undef 1243 | var S = Symbol(); 1244 | var K = 'abcdefghijklmnopqrst'; 1245 | A[S] = 7; 1246 | K.split('').forEach(function (k) { B[k] = k; }); 1247 | return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; 1248 | }) ? function assign(target, source) { // eslint-disable-line no-unused-vars 1249 | var T = toObject(target); 1250 | var aLen = arguments.length; 1251 | var index = 1; 1252 | var getSymbols = gOPS.f; 1253 | var isEnum = pIE.f; 1254 | while (aLen > index) { 1255 | var S = IObject(arguments[index++]); 1256 | var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S); 1257 | var length = keys.length; 1258 | var j = 0; 1259 | var key; 1260 | while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key]; 1261 | } return T; 1262 | } : $assign; 1263 | 1264 | 1265 | /***/ }), 1266 | /* 44 */ 1267 | /***/ (function(module, exports) { 1268 | 1269 | exports.f = Object.getOwnPropertySymbols; 1270 | 1271 | 1272 | /***/ }), 1273 | /* 45 */ 1274 | /***/ (function(module, exports) { 1275 | 1276 | exports.f = {}.propertyIsEnumerable; 1277 | 1278 | 1279 | /***/ }), 1280 | /* 46 */ 1281 | /***/ (function(module, exports, __webpack_require__) { 1282 | 1283 | "use strict"; 1284 | 1285 | 1286 | exports.__esModule = true; 1287 | 1288 | exports.default = function (instance, Constructor) { 1289 | if (!(instance instanceof Constructor)) { 1290 | throw new TypeError("Cannot call a class as a function"); 1291 | } 1292 | }; 1293 | 1294 | /***/ }), 1295 | /* 47 */ 1296 | /***/ (function(module, exports, __webpack_require__) { 1297 | 1298 | "use strict"; 1299 | 1300 | 1301 | exports.__esModule = true; 1302 | 1303 | var _defineProperty = __webpack_require__(48); 1304 | 1305 | var _defineProperty2 = _interopRequireDefault(_defineProperty); 1306 | 1307 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1308 | 1309 | exports.default = function () { 1310 | function defineProperties(target, props) { 1311 | for (var i = 0; i < props.length; i++) { 1312 | var descriptor = props[i]; 1313 | descriptor.enumerable = descriptor.enumerable || false; 1314 | descriptor.configurable = true; 1315 | if ("value" in descriptor) descriptor.writable = true; 1316 | (0, _defineProperty2.default)(target, descriptor.key, descriptor); 1317 | } 1318 | } 1319 | 1320 | return function (Constructor, protoProps, staticProps) { 1321 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 1322 | if (staticProps) defineProperties(Constructor, staticProps); 1323 | return Constructor; 1324 | }; 1325 | }(); 1326 | 1327 | /***/ }), 1328 | /* 48 */ 1329 | /***/ (function(module, exports, __webpack_require__) { 1330 | 1331 | module.exports = { "default": __webpack_require__(49), __esModule: true }; 1332 | 1333 | /***/ }), 1334 | /* 49 */ 1335 | /***/ (function(module, exports, __webpack_require__) { 1336 | 1337 | __webpack_require__(50); 1338 | var $Object = __webpack_require__(0).Object; 1339 | module.exports = function defineProperty(it, key, desc) { 1340 | return $Object.defineProperty(it, key, desc); 1341 | }; 1342 | 1343 | 1344 | /***/ }), 1345 | /* 50 */ 1346 | /***/ (function(module, exports, __webpack_require__) { 1347 | 1348 | var $export = __webpack_require__(5); 1349 | // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) 1350 | $export($export.S + $export.F * !__webpack_require__(1), 'Object', { defineProperty: __webpack_require__(14).f }); 1351 | 1352 | 1353 | /***/ }), 1354 | /* 51 */ 1355 | /***/ (function(module, exports) { 1356 | 1357 | /* (ignored) */ 1358 | 1359 | /***/ }), 1360 | /* 52 */ 1361 | /***/ (function(module, exports, __webpack_require__) { 1362 | 1363 | /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. 1364 | // 1365 | // Permission is hereby granted, free of charge, to any person obtaining a 1366 | // copy of this software and associated documentation files (the 1367 | // "Software"), to deal in the Software without restriction, including 1368 | // without limitation the rights to use, copy, modify, merge, publish, 1369 | // distribute, sublicense, and/or sell copies of the Software, and to permit 1370 | // persons to whom the Software is furnished to do so, subject to the 1371 | // following conditions: 1372 | // 1373 | // The above copyright notice and this permission notice shall be included 1374 | // in all copies or substantial portions of the Software. 1375 | // 1376 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1377 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1378 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 1379 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 1380 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 1381 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 1382 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 1383 | 1384 | var formatRegExp = /%[sdj%]/g; 1385 | exports.format = function(f) { 1386 | if (!isString(f)) { 1387 | var objects = []; 1388 | for (var i = 0; i < arguments.length; i++) { 1389 | objects.push(inspect(arguments[i])); 1390 | } 1391 | return objects.join(' '); 1392 | } 1393 | 1394 | var i = 1; 1395 | var args = arguments; 1396 | var len = args.length; 1397 | var str = String(f).replace(formatRegExp, function(x) { 1398 | if (x === '%%') return '%'; 1399 | if (i >= len) return x; 1400 | switch (x) { 1401 | case '%s': return String(args[i++]); 1402 | case '%d': return Number(args[i++]); 1403 | case '%j': 1404 | try { 1405 | return JSON.stringify(args[i++]); 1406 | } catch (_) { 1407 | return '[Circular]'; 1408 | } 1409 | default: 1410 | return x; 1411 | } 1412 | }); 1413 | for (var x = args[i]; i < len; x = args[++i]) { 1414 | if (isNull(x) || !isObject(x)) { 1415 | str += ' ' + x; 1416 | } else { 1417 | str += ' ' + inspect(x); 1418 | } 1419 | } 1420 | return str; 1421 | }; 1422 | 1423 | 1424 | // Mark that a method should not be used. 1425 | // Returns a modified function which warns once by default. 1426 | // If --no-deprecation is set, then it is a no-op. 1427 | exports.deprecate = function(fn, msg) { 1428 | // Allow for deprecating things in the process of starting up. 1429 | if (isUndefined(global.process)) { 1430 | return function() { 1431 | return exports.deprecate(fn, msg).apply(this, arguments); 1432 | }; 1433 | } 1434 | 1435 | if (process.noDeprecation === true) { 1436 | return fn; 1437 | } 1438 | 1439 | var warned = false; 1440 | function deprecated() { 1441 | if (!warned) { 1442 | if (process.throwDeprecation) { 1443 | throw new Error(msg); 1444 | } else if (process.traceDeprecation) { 1445 | console.trace(msg); 1446 | } else { 1447 | console.error(msg); 1448 | } 1449 | warned = true; 1450 | } 1451 | return fn.apply(this, arguments); 1452 | } 1453 | 1454 | return deprecated; 1455 | }; 1456 | 1457 | 1458 | var debugs = {}; 1459 | var debugEnviron; 1460 | exports.debuglog = function(set) { 1461 | if (isUndefined(debugEnviron)) 1462 | debugEnviron = process.env.NODE_DEBUG || ''; 1463 | set = set.toUpperCase(); 1464 | if (!debugs[set]) { 1465 | if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { 1466 | var pid = process.pid; 1467 | debugs[set] = function() { 1468 | var msg = exports.format.apply(exports, arguments); 1469 | console.error('%s %d: %s', set, pid, msg); 1470 | }; 1471 | } else { 1472 | debugs[set] = function() {}; 1473 | } 1474 | } 1475 | return debugs[set]; 1476 | }; 1477 | 1478 | 1479 | /** 1480 | * Echos the value of a value. Trys to print the value out 1481 | * in the best way possible given the different types. 1482 | * 1483 | * @param {Object} obj The object to print out. 1484 | * @param {Object} opts Optional options object that alters the output. 1485 | */ 1486 | /* legacy: obj, showHidden, depth, colors*/ 1487 | function inspect(obj, opts) { 1488 | // default options 1489 | var ctx = { 1490 | seen: [], 1491 | stylize: stylizeNoColor 1492 | }; 1493 | // legacy... 1494 | if (arguments.length >= 3) ctx.depth = arguments[2]; 1495 | if (arguments.length >= 4) ctx.colors = arguments[3]; 1496 | if (isBoolean(opts)) { 1497 | // legacy... 1498 | ctx.showHidden = opts; 1499 | } else if (opts) { 1500 | // got an "options" object 1501 | exports._extend(ctx, opts); 1502 | } 1503 | // set default options 1504 | if (isUndefined(ctx.showHidden)) ctx.showHidden = false; 1505 | if (isUndefined(ctx.depth)) ctx.depth = 2; 1506 | if (isUndefined(ctx.colors)) ctx.colors = false; 1507 | if (isUndefined(ctx.customInspect)) ctx.customInspect = true; 1508 | if (ctx.colors) ctx.stylize = stylizeWithColor; 1509 | return formatValue(ctx, obj, ctx.depth); 1510 | } 1511 | exports.inspect = inspect; 1512 | 1513 | 1514 | // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics 1515 | inspect.colors = { 1516 | 'bold' : [1, 22], 1517 | 'italic' : [3, 23], 1518 | 'underline' : [4, 24], 1519 | 'inverse' : [7, 27], 1520 | 'white' : [37, 39], 1521 | 'grey' : [90, 39], 1522 | 'black' : [30, 39], 1523 | 'blue' : [34, 39], 1524 | 'cyan' : [36, 39], 1525 | 'green' : [32, 39], 1526 | 'magenta' : [35, 39], 1527 | 'red' : [31, 39], 1528 | 'yellow' : [33, 39] 1529 | }; 1530 | 1531 | // Don't use 'blue' not visible on cmd.exe 1532 | inspect.styles = { 1533 | 'special': 'cyan', 1534 | 'number': 'yellow', 1535 | 'boolean': 'yellow', 1536 | 'undefined': 'grey', 1537 | 'null': 'bold', 1538 | 'string': 'green', 1539 | 'date': 'magenta', 1540 | // "name": intentionally not styling 1541 | 'regexp': 'red' 1542 | }; 1543 | 1544 | 1545 | function stylizeWithColor(str, styleType) { 1546 | var style = inspect.styles[styleType]; 1547 | 1548 | if (style) { 1549 | return '\u001b[' + inspect.colors[style][0] + 'm' + str + 1550 | '\u001b[' + inspect.colors[style][1] + 'm'; 1551 | } else { 1552 | return str; 1553 | } 1554 | } 1555 | 1556 | 1557 | function stylizeNoColor(str, styleType) { 1558 | return str; 1559 | } 1560 | 1561 | 1562 | function arrayToHash(array) { 1563 | var hash = {}; 1564 | 1565 | array.forEach(function(val, idx) { 1566 | hash[val] = true; 1567 | }); 1568 | 1569 | return hash; 1570 | } 1571 | 1572 | 1573 | function formatValue(ctx, value, recurseTimes) { 1574 | // Provide a hook for user-specified inspect functions. 1575 | // Check that value is an object with an inspect function on it 1576 | if (ctx.customInspect && 1577 | value && 1578 | isFunction(value.inspect) && 1579 | // Filter out the util module, it's inspect function is special 1580 | value.inspect !== exports.inspect && 1581 | // Also filter out any prototype objects using the circular check. 1582 | !(value.constructor && value.constructor.prototype === value)) { 1583 | var ret = value.inspect(recurseTimes, ctx); 1584 | if (!isString(ret)) { 1585 | ret = formatValue(ctx, ret, recurseTimes); 1586 | } 1587 | return ret; 1588 | } 1589 | 1590 | // Primitive types cannot have properties 1591 | var primitive = formatPrimitive(ctx, value); 1592 | if (primitive) { 1593 | return primitive; 1594 | } 1595 | 1596 | // Look up the keys of the object. 1597 | var keys = Object.keys(value); 1598 | var visibleKeys = arrayToHash(keys); 1599 | 1600 | if (ctx.showHidden) { 1601 | keys = Object.getOwnPropertyNames(value); 1602 | } 1603 | 1604 | // IE doesn't make error fields non-enumerable 1605 | // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx 1606 | if (isError(value) 1607 | && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { 1608 | return formatError(value); 1609 | } 1610 | 1611 | // Some type of object without properties can be shortcutted. 1612 | if (keys.length === 0) { 1613 | if (isFunction(value)) { 1614 | var name = value.name ? ': ' + value.name : ''; 1615 | return ctx.stylize('[Function' + name + ']', 'special'); 1616 | } 1617 | if (isRegExp(value)) { 1618 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); 1619 | } 1620 | if (isDate(value)) { 1621 | return ctx.stylize(Date.prototype.toString.call(value), 'date'); 1622 | } 1623 | if (isError(value)) { 1624 | return formatError(value); 1625 | } 1626 | } 1627 | 1628 | var base = '', array = false, braces = ['{', '}']; 1629 | 1630 | // Make Array say that they are Array 1631 | if (isArray(value)) { 1632 | array = true; 1633 | braces = ['[', ']']; 1634 | } 1635 | 1636 | // Make functions say that they are functions 1637 | if (isFunction(value)) { 1638 | var n = value.name ? ': ' + value.name : ''; 1639 | base = ' [Function' + n + ']'; 1640 | } 1641 | 1642 | // Make RegExps say that they are RegExps 1643 | if (isRegExp(value)) { 1644 | base = ' ' + RegExp.prototype.toString.call(value); 1645 | } 1646 | 1647 | // Make dates with properties first say the date 1648 | if (isDate(value)) { 1649 | base = ' ' + Date.prototype.toUTCString.call(value); 1650 | } 1651 | 1652 | // Make error with message first say the error 1653 | if (isError(value)) { 1654 | base = ' ' + formatError(value); 1655 | } 1656 | 1657 | if (keys.length === 0 && (!array || value.length == 0)) { 1658 | return braces[0] + base + braces[1]; 1659 | } 1660 | 1661 | if (recurseTimes < 0) { 1662 | if (isRegExp(value)) { 1663 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); 1664 | } else { 1665 | return ctx.stylize('[Object]', 'special'); 1666 | } 1667 | } 1668 | 1669 | ctx.seen.push(value); 1670 | 1671 | var output; 1672 | if (array) { 1673 | output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); 1674 | } else { 1675 | output = keys.map(function(key) { 1676 | return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); 1677 | }); 1678 | } 1679 | 1680 | ctx.seen.pop(); 1681 | 1682 | return reduceToSingleString(output, base, braces); 1683 | } 1684 | 1685 | 1686 | function formatPrimitive(ctx, value) { 1687 | if (isUndefined(value)) 1688 | return ctx.stylize('undefined', 'undefined'); 1689 | if (isString(value)) { 1690 | var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') 1691 | .replace(/'/g, "\\'") 1692 | .replace(/\\"/g, '"') + '\''; 1693 | return ctx.stylize(simple, 'string'); 1694 | } 1695 | if (isNumber(value)) 1696 | return ctx.stylize('' + value, 'number'); 1697 | if (isBoolean(value)) 1698 | return ctx.stylize('' + value, 'boolean'); 1699 | // For some reason typeof null is "object", so special case here. 1700 | if (isNull(value)) 1701 | return ctx.stylize('null', 'null'); 1702 | } 1703 | 1704 | 1705 | function formatError(value) { 1706 | return '[' + Error.prototype.toString.call(value) + ']'; 1707 | } 1708 | 1709 | 1710 | function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { 1711 | var output = []; 1712 | for (var i = 0, l = value.length; i < l; ++i) { 1713 | if (hasOwnProperty(value, String(i))) { 1714 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, 1715 | String(i), true)); 1716 | } else { 1717 | output.push(''); 1718 | } 1719 | } 1720 | keys.forEach(function(key) { 1721 | if (!key.match(/^\d+$/)) { 1722 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, 1723 | key, true)); 1724 | } 1725 | }); 1726 | return output; 1727 | } 1728 | 1729 | 1730 | function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { 1731 | var name, str, desc; 1732 | desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; 1733 | if (desc.get) { 1734 | if (desc.set) { 1735 | str = ctx.stylize('[Getter/Setter]', 'special'); 1736 | } else { 1737 | str = ctx.stylize('[Getter]', 'special'); 1738 | } 1739 | } else { 1740 | if (desc.set) { 1741 | str = ctx.stylize('[Setter]', 'special'); 1742 | } 1743 | } 1744 | if (!hasOwnProperty(visibleKeys, key)) { 1745 | name = '[' + key + ']'; 1746 | } 1747 | if (!str) { 1748 | if (ctx.seen.indexOf(desc.value) < 0) { 1749 | if (isNull(recurseTimes)) { 1750 | str = formatValue(ctx, desc.value, null); 1751 | } else { 1752 | str = formatValue(ctx, desc.value, recurseTimes - 1); 1753 | } 1754 | if (str.indexOf('\n') > -1) { 1755 | if (array) { 1756 | str = str.split('\n').map(function(line) { 1757 | return ' ' + line; 1758 | }).join('\n').substr(2); 1759 | } else { 1760 | str = '\n' + str.split('\n').map(function(line) { 1761 | return ' ' + line; 1762 | }).join('\n'); 1763 | } 1764 | } 1765 | } else { 1766 | str = ctx.stylize('[Circular]', 'special'); 1767 | } 1768 | } 1769 | if (isUndefined(name)) { 1770 | if (array && key.match(/^\d+$/)) { 1771 | return str; 1772 | } 1773 | name = JSON.stringify('' + key); 1774 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { 1775 | name = name.substr(1, name.length - 2); 1776 | name = ctx.stylize(name, 'name'); 1777 | } else { 1778 | name = name.replace(/'/g, "\\'") 1779 | .replace(/\\"/g, '"') 1780 | .replace(/(^"|"$)/g, "'"); 1781 | name = ctx.stylize(name, 'string'); 1782 | } 1783 | } 1784 | 1785 | return name + ': ' + str; 1786 | } 1787 | 1788 | 1789 | function reduceToSingleString(output, base, braces) { 1790 | var numLinesEst = 0; 1791 | var length = output.reduce(function(prev, cur) { 1792 | numLinesEst++; 1793 | if (cur.indexOf('\n') >= 0) numLinesEst++; 1794 | return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; 1795 | }, 0); 1796 | 1797 | if (length > 60) { 1798 | return braces[0] + 1799 | (base === '' ? '' : base + '\n ') + 1800 | ' ' + 1801 | output.join(',\n ') + 1802 | ' ' + 1803 | braces[1]; 1804 | } 1805 | 1806 | return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; 1807 | } 1808 | 1809 | 1810 | // NOTE: These type checking functions intentionally don't use `instanceof` 1811 | // because it is fragile and can be easily faked with `Object.create()`. 1812 | function isArray(ar) { 1813 | return Array.isArray(ar); 1814 | } 1815 | exports.isArray = isArray; 1816 | 1817 | function isBoolean(arg) { 1818 | return typeof arg === 'boolean'; 1819 | } 1820 | exports.isBoolean = isBoolean; 1821 | 1822 | function isNull(arg) { 1823 | return arg === null; 1824 | } 1825 | exports.isNull = isNull; 1826 | 1827 | function isNullOrUndefined(arg) { 1828 | return arg == null; 1829 | } 1830 | exports.isNullOrUndefined = isNullOrUndefined; 1831 | 1832 | function isNumber(arg) { 1833 | return typeof arg === 'number'; 1834 | } 1835 | exports.isNumber = isNumber; 1836 | 1837 | function isString(arg) { 1838 | return typeof arg === 'string'; 1839 | } 1840 | exports.isString = isString; 1841 | 1842 | function isSymbol(arg) { 1843 | return typeof arg === 'symbol'; 1844 | } 1845 | exports.isSymbol = isSymbol; 1846 | 1847 | function isUndefined(arg) { 1848 | return arg === void 0; 1849 | } 1850 | exports.isUndefined = isUndefined; 1851 | 1852 | function isRegExp(re) { 1853 | return isObject(re) && objectToString(re) === '[object RegExp]'; 1854 | } 1855 | exports.isRegExp = isRegExp; 1856 | 1857 | function isObject(arg) { 1858 | return typeof arg === 'object' && arg !== null; 1859 | } 1860 | exports.isObject = isObject; 1861 | 1862 | function isDate(d) { 1863 | return isObject(d) && objectToString(d) === '[object Date]'; 1864 | } 1865 | exports.isDate = isDate; 1866 | 1867 | function isError(e) { 1868 | return isObject(e) && 1869 | (objectToString(e) === '[object Error]' || e instanceof Error); 1870 | } 1871 | exports.isError = isError; 1872 | 1873 | function isFunction(arg) { 1874 | return typeof arg === 'function'; 1875 | } 1876 | exports.isFunction = isFunction; 1877 | 1878 | function isPrimitive(arg) { 1879 | return arg === null || 1880 | typeof arg === 'boolean' || 1881 | typeof arg === 'number' || 1882 | typeof arg === 'string' || 1883 | typeof arg === 'symbol' || // ES6 symbol 1884 | typeof arg === 'undefined'; 1885 | } 1886 | exports.isPrimitive = isPrimitive; 1887 | 1888 | exports.isBuffer = __webpack_require__(54); 1889 | 1890 | function objectToString(o) { 1891 | return Object.prototype.toString.call(o); 1892 | } 1893 | 1894 | 1895 | function pad(n) { 1896 | return n < 10 ? '0' + n.toString(10) : n.toString(10); 1897 | } 1898 | 1899 | 1900 | var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 1901 | 'Oct', 'Nov', 'Dec']; 1902 | 1903 | // 26 Feb 16:19:34 1904 | function timestamp() { 1905 | var d = new Date(); 1906 | var time = [pad(d.getHours()), 1907 | pad(d.getMinutes()), 1908 | pad(d.getSeconds())].join(':'); 1909 | return [d.getDate(), months[d.getMonth()], time].join(' '); 1910 | } 1911 | 1912 | 1913 | // log is just a thin wrapper to console.log that prepends a timestamp 1914 | exports.log = function() { 1915 | console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); 1916 | }; 1917 | 1918 | 1919 | /** 1920 | * Inherit the prototype methods from one constructor into another. 1921 | * 1922 | * The Function.prototype.inherits from lang.js rewritten as a standalone 1923 | * function (not on Function.prototype). NOTE: If this file is to be loaded 1924 | * during bootstrapping this function needs to be rewritten using some native 1925 | * functions as prototype setup using normal JavaScript does not work as 1926 | * expected during bootstrapping (see mirror.js in r114903). 1927 | * 1928 | * @param {function} ctor Constructor function which needs to inherit the 1929 | * prototype. 1930 | * @param {function} superCtor Constructor function to inherit prototype from. 1931 | */ 1932 | exports.inherits = __webpack_require__(55); 1933 | 1934 | exports._extend = function(origin, add) { 1935 | // Don't do anything if add isn't an object 1936 | if (!add || !isObject(add)) return origin; 1937 | 1938 | var keys = Object.keys(add); 1939 | var i = keys.length; 1940 | while (i--) { 1941 | origin[keys[i]] = add[keys[i]]; 1942 | } 1943 | return origin; 1944 | }; 1945 | 1946 | function hasOwnProperty(obj, prop) { 1947 | return Object.prototype.hasOwnProperty.call(obj, prop); 1948 | } 1949 | 1950 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(53), __webpack_require__(3))) 1951 | 1952 | /***/ }), 1953 | /* 53 */ 1954 | /***/ (function(module, exports) { 1955 | 1956 | var g; 1957 | 1958 | // This works in non-strict mode 1959 | g = (function() { 1960 | return this; 1961 | })(); 1962 | 1963 | try { 1964 | // This works if eval is allowed (see CSP) 1965 | g = g || Function("return this")() || (1,eval)("this"); 1966 | } catch(e) { 1967 | // This works if the window reference is available 1968 | if(typeof window === "object") 1969 | g = window; 1970 | } 1971 | 1972 | // g can still be undefined, but nothing to do about it... 1973 | // We return undefined, instead of nothing here, so it's 1974 | // easier to handle this case. if(!global) { ...} 1975 | 1976 | module.exports = g; 1977 | 1978 | 1979 | /***/ }), 1980 | /* 54 */ 1981 | /***/ (function(module, exports) { 1982 | 1983 | module.exports = function isBuffer(arg) { 1984 | return arg && typeof arg === 'object' 1985 | && typeof arg.copy === 'function' 1986 | && typeof arg.fill === 'function' 1987 | && typeof arg.readUInt8 === 'function'; 1988 | } 1989 | 1990 | /***/ }), 1991 | /* 55 */ 1992 | /***/ (function(module, exports) { 1993 | 1994 | if (typeof Object.create === 'function') { 1995 | // implementation from standard node.js 'util' module 1996 | module.exports = function inherits(ctor, superCtor) { 1997 | ctor.super_ = superCtor 1998 | ctor.prototype = Object.create(superCtor.prototype, { 1999 | constructor: { 2000 | value: ctor, 2001 | enumerable: false, 2002 | writable: true, 2003 | configurable: true 2004 | } 2005 | }); 2006 | }; 2007 | } else { 2008 | // old school shim for old browsers 2009 | module.exports = function inherits(ctor, superCtor) { 2010 | ctor.super_ = superCtor 2011 | var TempCtor = function () {} 2012 | TempCtor.prototype = superCtor.prototype 2013 | ctor.prototype = new TempCtor() 2014 | ctor.prototype.constructor = ctor 2015 | } 2016 | } 2017 | 2018 | 2019 | /***/ }), 2020 | /* 56 */ 2021 | /***/ (function(module, exports) { 2022 | 2023 | // Copyright Joyent, Inc. and other Node contributors. 2024 | // 2025 | // Permission is hereby granted, free of charge, to any person obtaining a 2026 | // copy of this software and associated documentation files (the 2027 | // "Software"), to deal in the Software without restriction, including 2028 | // without limitation the rights to use, copy, modify, merge, publish, 2029 | // distribute, sublicense, and/or sell copies of the Software, and to permit 2030 | // persons to whom the Software is furnished to do so, subject to the 2031 | // following conditions: 2032 | // 2033 | // The above copyright notice and this permission notice shall be included 2034 | // in all copies or substantial portions of the Software. 2035 | // 2036 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2037 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2038 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 2039 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 2040 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2041 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2042 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 2043 | 2044 | function EventEmitter() { 2045 | this._events = this._events || {}; 2046 | this._maxListeners = this._maxListeners || undefined; 2047 | } 2048 | module.exports = EventEmitter; 2049 | 2050 | // Backwards-compat with node 0.10.x 2051 | EventEmitter.EventEmitter = EventEmitter; 2052 | 2053 | EventEmitter.prototype._events = undefined; 2054 | EventEmitter.prototype._maxListeners = undefined; 2055 | 2056 | // By default EventEmitters will print a warning if more than 10 listeners are 2057 | // added to it. This is a useful default which helps finding memory leaks. 2058 | EventEmitter.defaultMaxListeners = 10; 2059 | 2060 | // Obviously not all Emitters should be limited to 10. This function allows 2061 | // that to be increased. Set to zero for unlimited. 2062 | EventEmitter.prototype.setMaxListeners = function(n) { 2063 | if (!isNumber(n) || n < 0 || isNaN(n)) 2064 | throw TypeError('n must be a positive number'); 2065 | this._maxListeners = n; 2066 | return this; 2067 | }; 2068 | 2069 | EventEmitter.prototype.emit = function(type) { 2070 | var er, handler, len, args, i, listeners; 2071 | 2072 | if (!this._events) 2073 | this._events = {}; 2074 | 2075 | // If there is no 'error' event listener then throw. 2076 | if (type === 'error') { 2077 | if (!this._events.error || 2078 | (isObject(this._events.error) && !this._events.error.length)) { 2079 | er = arguments[1]; 2080 | if (er instanceof Error) { 2081 | throw er; // Unhandled 'error' event 2082 | } else { 2083 | // At least give some kind of context to the user 2084 | var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); 2085 | err.context = er; 2086 | throw err; 2087 | } 2088 | } 2089 | } 2090 | 2091 | handler = this._events[type]; 2092 | 2093 | if (isUndefined(handler)) 2094 | return false; 2095 | 2096 | if (isFunction(handler)) { 2097 | switch (arguments.length) { 2098 | // fast cases 2099 | case 1: 2100 | handler.call(this); 2101 | break; 2102 | case 2: 2103 | handler.call(this, arguments[1]); 2104 | break; 2105 | case 3: 2106 | handler.call(this, arguments[1], arguments[2]); 2107 | break; 2108 | // slower 2109 | default: 2110 | args = Array.prototype.slice.call(arguments, 1); 2111 | handler.apply(this, args); 2112 | } 2113 | } else if (isObject(handler)) { 2114 | args = Array.prototype.slice.call(arguments, 1); 2115 | listeners = handler.slice(); 2116 | len = listeners.length; 2117 | for (i = 0; i < len; i++) 2118 | listeners[i].apply(this, args); 2119 | } 2120 | 2121 | return true; 2122 | }; 2123 | 2124 | EventEmitter.prototype.addListener = function(type, listener) { 2125 | var m; 2126 | 2127 | if (!isFunction(listener)) 2128 | throw TypeError('listener must be a function'); 2129 | 2130 | if (!this._events) 2131 | this._events = {}; 2132 | 2133 | // To avoid recursion in the case that type === "newListener"! Before 2134 | // adding it to the listeners, first emit "newListener". 2135 | if (this._events.newListener) 2136 | this.emit('newListener', type, 2137 | isFunction(listener.listener) ? 2138 | listener.listener : listener); 2139 | 2140 | if (!this._events[type]) 2141 | // Optimize the case of one listener. Don't need the extra array object. 2142 | this._events[type] = listener; 2143 | else if (isObject(this._events[type])) 2144 | // If we've already got an array, just append. 2145 | this._events[type].push(listener); 2146 | else 2147 | // Adding the second element, need to change to array. 2148 | this._events[type] = [this._events[type], listener]; 2149 | 2150 | // Check for listener leak 2151 | if (isObject(this._events[type]) && !this._events[type].warned) { 2152 | if (!isUndefined(this._maxListeners)) { 2153 | m = this._maxListeners; 2154 | } else { 2155 | m = EventEmitter.defaultMaxListeners; 2156 | } 2157 | 2158 | if (m && m > 0 && this._events[type].length > m) { 2159 | this._events[type].warned = true; 2160 | console.error('(node) warning: possible EventEmitter memory ' + 2161 | 'leak detected. %d listeners added. ' + 2162 | 'Use emitter.setMaxListeners() to increase limit.', 2163 | this._events[type].length); 2164 | if (typeof console.trace === 'function') { 2165 | // not supported in IE 10 2166 | console.trace(); 2167 | } 2168 | } 2169 | } 2170 | 2171 | return this; 2172 | }; 2173 | 2174 | EventEmitter.prototype.on = EventEmitter.prototype.addListener; 2175 | 2176 | EventEmitter.prototype.once = function(type, listener) { 2177 | if (!isFunction(listener)) 2178 | throw TypeError('listener must be a function'); 2179 | 2180 | var fired = false; 2181 | 2182 | function g() { 2183 | this.removeListener(type, g); 2184 | 2185 | if (!fired) { 2186 | fired = true; 2187 | listener.apply(this, arguments); 2188 | } 2189 | } 2190 | 2191 | g.listener = listener; 2192 | this.on(type, g); 2193 | 2194 | return this; 2195 | }; 2196 | 2197 | // emits a 'removeListener' event iff the listener was removed 2198 | EventEmitter.prototype.removeListener = function(type, listener) { 2199 | var list, position, length, i; 2200 | 2201 | if (!isFunction(listener)) 2202 | throw TypeError('listener must be a function'); 2203 | 2204 | if (!this._events || !this._events[type]) 2205 | return this; 2206 | 2207 | list = this._events[type]; 2208 | length = list.length; 2209 | position = -1; 2210 | 2211 | if (list === listener || 2212 | (isFunction(list.listener) && list.listener === listener)) { 2213 | delete this._events[type]; 2214 | if (this._events.removeListener) 2215 | this.emit('removeListener', type, listener); 2216 | 2217 | } else if (isObject(list)) { 2218 | for (i = length; i-- > 0;) { 2219 | if (list[i] === listener || 2220 | (list[i].listener && list[i].listener === listener)) { 2221 | position = i; 2222 | break; 2223 | } 2224 | } 2225 | 2226 | if (position < 0) 2227 | return this; 2228 | 2229 | if (list.length === 1) { 2230 | list.length = 0; 2231 | delete this._events[type]; 2232 | } else { 2233 | list.splice(position, 1); 2234 | } 2235 | 2236 | if (this._events.removeListener) 2237 | this.emit('removeListener', type, listener); 2238 | } 2239 | 2240 | return this; 2241 | }; 2242 | 2243 | EventEmitter.prototype.removeAllListeners = function(type) { 2244 | var key, listeners; 2245 | 2246 | if (!this._events) 2247 | return this; 2248 | 2249 | // not listening for removeListener, no need to emit 2250 | if (!this._events.removeListener) { 2251 | if (arguments.length === 0) 2252 | this._events = {}; 2253 | else if (this._events[type]) 2254 | delete this._events[type]; 2255 | return this; 2256 | } 2257 | 2258 | // emit removeListener for all listeners on all events 2259 | if (arguments.length === 0) { 2260 | for (key in this._events) { 2261 | if (key === 'removeListener') continue; 2262 | this.removeAllListeners(key); 2263 | } 2264 | this.removeAllListeners('removeListener'); 2265 | this._events = {}; 2266 | return this; 2267 | } 2268 | 2269 | listeners = this._events[type]; 2270 | 2271 | if (isFunction(listeners)) { 2272 | this.removeListener(type, listeners); 2273 | } else if (listeners) { 2274 | // LIFO order 2275 | while (listeners.length) 2276 | this.removeListener(type, listeners[listeners.length - 1]); 2277 | } 2278 | delete this._events[type]; 2279 | 2280 | return this; 2281 | }; 2282 | 2283 | EventEmitter.prototype.listeners = function(type) { 2284 | var ret; 2285 | if (!this._events || !this._events[type]) 2286 | ret = []; 2287 | else if (isFunction(this._events[type])) 2288 | ret = [this._events[type]]; 2289 | else 2290 | ret = this._events[type].slice(); 2291 | return ret; 2292 | }; 2293 | 2294 | EventEmitter.prototype.listenerCount = function(type) { 2295 | if (this._events) { 2296 | var evlistener = this._events[type]; 2297 | 2298 | if (isFunction(evlistener)) 2299 | return 1; 2300 | else if (evlistener) 2301 | return evlistener.length; 2302 | } 2303 | return 0; 2304 | }; 2305 | 2306 | EventEmitter.listenerCount = function(emitter, type) { 2307 | return emitter.listenerCount(type); 2308 | }; 2309 | 2310 | function isFunction(arg) { 2311 | return typeof arg === 'function'; 2312 | } 2313 | 2314 | function isNumber(arg) { 2315 | return typeof arg === 'number'; 2316 | } 2317 | 2318 | function isObject(arg) { 2319 | return typeof arg === 'object' && arg !== null; 2320 | } 2321 | 2322 | function isUndefined(arg) { 2323 | return arg === void 0; 2324 | } 2325 | 2326 | 2327 | /***/ }) 2328 | /******/ ]); -------------------------------------------------------------------------------- /example/example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | Using the ES5 module for the sake of example. 5 | To use the regular ES6 version, one would include it with: 6 | const Logger = require('logplease') 7 | */ 8 | const Logger = require('../es5/index'); 9 | 10 | const logger1 = Logger.create('daemon', { filename: 'debug.log', useColors: false, appendFile: true }); 11 | const logger2 = Logger.create('utils'); 12 | const logger3 = Logger.create('logger3', { color: Logger.Colors.Magenta, showTimestamp: false, showLevel: false }); 13 | const logger4 = Logger.create('logger4-local-time', { useLocalTime: true }); 14 | 15 | const red = Logger.create('red', { color: Logger.Colors.Red, showTimestamp: false, showLevel: false }); 16 | const green = Logger.create('green', { color: Logger.Colors.Green, showTimestamp: false, showLevel: false }); 17 | const yellow = Logger.create('yellow', { color: Logger.Colors.Yellow, showTimestamp: false, showLevel: false }); 18 | const blue = Logger.create('blue', { color: Logger.Colors.Blue, showTimestamp: false, showLevel: false }); 19 | const magenta = Logger.create('magenta', { color: Logger.Colors.Magenta, showTimestamp: false, showLevel: false }); 20 | const cyan = Logger.create('cyan', { color: Logger.Colors.Cyan, showTimestamp: false, showLevel: false }); 21 | 22 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 23 | 24 | // CAVEAT: log functions can't take any parameters, if you need params, use interpolated strings 25 | const number = 5; 26 | logger1.debug(`This is a debug message #${number}`); 27 | logger1.info(`This is an info message #${number}`); 28 | logger1.warn(`This is a warning message #${number}`); 29 | logger1.error(`This is an error message #${number}`); 30 | 31 | logger2.debug(`This is a debug message #${number}`); 32 | logger2.info(`This is an info message #${number}`); 33 | logger2.warn(`This is a warning message #${number}`); 34 | logger2.error(`This is an error message #${number}`); 35 | 36 | logger3.debug(`This is a debug message #${number}`); 37 | logger3.info(`This is an info message #${number}`); 38 | logger3.warn(`This is a warning message #${number}`); 39 | logger3.error(`This is an error message #${number}`); 40 | 41 | logger4.debug(`This is a debug message #${number}`); 42 | logger4.info(`This is an info message #${number}`); 43 | logger4.warn(`This is a warning message #${number}`); 44 | logger4.error(`This is an error message #${number}`); 45 | 46 | red.log(`Red log message`); // log() is an alias for debug() 47 | green.log(`Green log message`); 48 | yellow.log(`Yellow log message`); 49 | blue.log(`Blue log message`); 50 | magenta.log(`Magenta log message`); 51 | cyan.log(`Cyan log message`); 52 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logplease", 3 | "version": "1.2.15", 4 | "description": "Simple Javascript logger for Node.js and Browsers", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "mocha", 8 | "example": "node example/example.js", 9 | "build": "npm run build:dist && npm run build:examples && npm run build:es5", 10 | "build:dist": "./node_modules/.bin/webpack --config webpack.config.js", 11 | "build:examples": "./node_modules/.bin/webpack --config webpack.example.config.js", 12 | "build:es5": "babel -o ./es5/index.js --presets babel-preset-es2015 --plugins babel-plugin-transform-runtime ./src/index.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/haadcode/logplease.git" 17 | }, 18 | "browser": { 19 | "fs": false 20 | }, 21 | "keywords": [ 22 | "log", 23 | "logger", 24 | "logging" 25 | ], 26 | "author": "Haad", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/haadcode/logplease/issues" 30 | }, 31 | "homepage": "https://github.com/haadcode/logplease#readme", 32 | "devDependencies": { 33 | "babel-cli": "^6.26.0", 34 | "babel-core": "^6.26.0", 35 | "babel-loader": "^7.1.2", 36 | "babel-plugin-transform-runtime": "^6.23.0", 37 | "babel-preset-es2015": "^6.24.1", 38 | "buffer": "^5.0.7", 39 | "mocha": "^5.2.0", 40 | "webpack": "^3.5.5" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haadcode/logplease/cae19f2fe98dead3133ebfa2735eeea2c2ba8d0b/screenshot.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const format = require('util').format; 5 | const EventEmitter = require('events').EventEmitter; 6 | 7 | let isElectronRenderer = process.type && process.type === 'renderer'; 8 | let isNodejs = !isElectronRenderer && process.version ? true : false; 9 | 10 | const LogLevels = { 11 | 'DEBUG': 'DEBUG', 12 | 'INFO': 'INFO', 13 | 'WARN': 'WARN', 14 | 'ERROR': 'ERROR', 15 | 'NONE': 'NONE', 16 | }; 17 | 18 | // Global log level 19 | let GlobalLogLevel = LogLevels.DEBUG; 20 | 21 | // Global log file name 22 | let GlobalLogfile = null; 23 | 24 | let GlobalEvents = new EventEmitter(); 25 | 26 | // ANSI colors 27 | let Colors = { 28 | 'Black': 0, 29 | 'Red': 1, 30 | 'Green': 2, 31 | 'Yellow': 3, 32 | 'Blue': 4, 33 | 'Magenta': 5, 34 | 'Cyan': 6, 35 | 'Grey': 7, 36 | 'White': 9, 37 | 'Default': 9, 38 | }; 39 | 40 | // CSS colors 41 | if(!isNodejs) { 42 | Colors = { 43 | 'Black': 'Black', 44 | 'Red': 'IndianRed', 45 | 'Green': 'LimeGreen', 46 | 'Yellow': 'Orange', 47 | 'Blue': 'RoyalBlue', 48 | 'Magenta': 'Orchid', 49 | 'Cyan': 'SkyBlue', 50 | 'Grey': 'DimGrey', 51 | 'White': 'White', 52 | 'Default': 'Black', 53 | }; 54 | } 55 | 56 | const loglevelColors = [Colors.Cyan, Colors.Green, Colors.Yellow, Colors.Red, Colors.Default]; 57 | 58 | const defaultOptions = { 59 | useColors: true, 60 | color: Colors.Default, 61 | showTimestamp: true, 62 | useLocalTime: false, 63 | showLevel: true, 64 | filename: GlobalLogfile, 65 | appendFile: true, 66 | }; 67 | 68 | class Logger { 69 | constructor(category, options) { 70 | this.category = category; 71 | let opts = {}; 72 | Object.assign(opts, defaultOptions); 73 | Object.assign(opts, options); 74 | this.options = opts; 75 | this.debug = this.debug.bind(this); 76 | this.log = this.log.bind(this); 77 | this.info = this.info.bind(this); 78 | this.warn = this.warn.bind(this); 79 | this.error = this.error.bind(this); 80 | } 81 | 82 | debug() { 83 | if(this._shouldLog(LogLevels.DEBUG)) 84 | this._write(LogLevels.DEBUG, format.apply(null, arguments)); 85 | } 86 | 87 | log() { 88 | if(this._shouldLog(LogLevels.DEBUG)) 89 | this.debug.apply(this, arguments); 90 | } 91 | 92 | info() { 93 | if(this._shouldLog(LogLevels.INFO)) 94 | this._write(LogLevels.INFO, format.apply(null, arguments)); 95 | } 96 | 97 | warn() { 98 | if(this._shouldLog(LogLevels.WARN)) 99 | this._write(LogLevels.WARN, format.apply(null, arguments)); 100 | } 101 | 102 | error() { 103 | if(this._shouldLog(LogLevels.ERROR)) 104 | this._write(LogLevels.ERROR, format.apply(null, arguments)); 105 | } 106 | 107 | _write(level, text) { 108 | if((this.options.filename || GlobalLogfile) && !this.fileWriter && isNodejs) 109 | this.fileWriter = fs.openSync(this.options.filename || GlobalLogfile, this.options.appendFile ? 'a+' : 'w+'); 110 | 111 | let format = this._format(level, text); 112 | let unformattedText = this._createLogMessage(level, text); 113 | let formattedText = this._createLogMessage(level, text, format.timestamp, format.level, format.category, format.text); 114 | 115 | if(this.fileWriter && isNodejs) 116 | fs.writeSync(this.fileWriter, unformattedText + '\n', null, 'utf-8'); 117 | 118 | if(isNodejs || !this.options.useColors) { 119 | console.log(formattedText) 120 | GlobalEvents.emit('data', this.category, level, text) 121 | } else { 122 | // TODO: clean this up 123 | if(level === LogLevels.ERROR) { 124 | if(this.options.showTimestamp && this.options.showLevel) { 125 | console.error(formattedText, format.timestamp, format.level, format.category, format.text) 126 | } else if(this.options.showTimestamp && !this.options.showLevel) { 127 | console.error(formattedText, format.timestamp, format.category, format.text) 128 | } else if(!this.options.showTimestamp && this.options.showLevel) { 129 | console.error(formattedText, format.level, format.category, format.text) 130 | } else { 131 | console.error(formattedText, format.category, format.text) 132 | } 133 | } else { 134 | if(this.options.showTimestamp && this.options.showLevel) { 135 | console.log(formattedText, format.timestamp, format.level, format.category, format.text) 136 | } else if(this.options.showTimestamp && !this.options.showLevel) { 137 | console.log(formattedText, format.timestamp, format.category, format.text) 138 | } else if(!this.options.showTimestamp && this.options.showLevel) { 139 | console.log(formattedText, format.level, format.category, format.text) 140 | } else { 141 | console.log(formattedText, format.category, format.text) 142 | } 143 | } 144 | } 145 | } 146 | 147 | _format(level, text) { 148 | let timestampFormat = ''; 149 | let levelFormat = ''; 150 | let categoryFormat = ''; 151 | let textFormat = ': '; 152 | 153 | if(this.options.useColors) { 154 | const levelColor = Object.keys(LogLevels).map((f) => LogLevels[f]).indexOf(level); 155 | const categoryColor = this.options.color; 156 | 157 | if(isNodejs) { 158 | if(this.options.showTimestamp) 159 | timestampFormat = '\u001b[3' + Colors.Grey + 'm'; 160 | 161 | if(this.options.showLevel) 162 | levelFormat = '\u001b[3' + loglevelColors[levelColor] + ';22m'; 163 | 164 | categoryFormat = '\u001b[3' + categoryColor + ';1m'; 165 | textFormat = '\u001b[0m: '; 166 | } else { 167 | if(this.options.showTimestamp) 168 | timestampFormat = 'color:' + Colors.Grey; 169 | 170 | if(this.options.showLevel) 171 | levelFormat = 'color:' + loglevelColors[levelColor]; 172 | 173 | categoryFormat = 'color:' + categoryColor + '; font-weight: bold'; 174 | } 175 | } 176 | 177 | return { 178 | timestamp: timestampFormat, 179 | level: levelFormat, 180 | category: categoryFormat, 181 | text: textFormat 182 | }; 183 | } 184 | 185 | _createLogMessage(level, text, timestampFormat, levelFormat, categoryFormat, textFormat) { 186 | timestampFormat = timestampFormat || ''; 187 | levelFormat = levelFormat || ''; 188 | categoryFormat = categoryFormat || ''; 189 | textFormat = textFormat || ': '; 190 | 191 | if(!isNodejs && this.options.useColors) { 192 | if(this.options.showTimestamp) 193 | timestampFormat = '%c'; 194 | 195 | if(this.options.showLevel) 196 | levelFormat = '%c'; 197 | 198 | categoryFormat = '%c'; 199 | textFormat = ': %c'; 200 | } 201 | 202 | let result = ''; 203 | 204 | if(this.options.showTimestamp && !this.options.useLocalTime) 205 | result += '' + new Date().toISOString() + ' '; 206 | 207 | if(this.options.showTimestamp && this.options.useLocalTime) 208 | result += '' + new Date().toLocaleString() + ' '; 209 | 210 | result = timestampFormat + result; 211 | 212 | if(this.options.showLevel) 213 | result += levelFormat + '[' + level +']' + (level === LogLevels.INFO || level === LogLevels.WARN ? ' ' : '') + ' '; 214 | 215 | result += categoryFormat + this.category; 216 | result += textFormat + text; 217 | return result; 218 | } 219 | 220 | _shouldLog(level) { 221 | let envLogLevel = (typeof process !== "undefined" && process.env !== undefined && process.env.LOG !== undefined) ? process.env.LOG.toUpperCase() : null; 222 | envLogLevel = (typeof window !== "undefined" && window.LOG) ? window.LOG.toUpperCase() : envLogLevel; 223 | 224 | const logLevel = envLogLevel || GlobalLogLevel; 225 | const levels = Object.keys(LogLevels).map((f) => LogLevels[f]); 226 | const index = levels.indexOf(level); 227 | const levelIdx = levels.indexOf(logLevel); 228 | return index >= levelIdx; 229 | } 230 | }; 231 | 232 | /* Public API */ 233 | module.exports = { 234 | Colors: Colors, 235 | LogLevels: LogLevels, 236 | setLogLevel: (level) => { 237 | GlobalLogLevel = level; 238 | }, 239 | setLogfile: (filename) => { 240 | GlobalLogfile = filename; 241 | }, 242 | create: (category, options) => { 243 | const logger = new Logger(category, options); 244 | return logger; 245 | }, 246 | forceBrowserMode: (force) => isNodejs = !force, // for testing, 247 | events: GlobalEvents, 248 | }; 249 | -------------------------------------------------------------------------------- /test/logplease.test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const assert = require('assert') 4 | const fs = require('fs') 5 | const stream = require('stream') 6 | const Logger = require('../src/index') 7 | 8 | const logfile = 'test123.log' 9 | 10 | describe('logplease', function() { 11 | this.timeout(1000) 12 | 13 | before((done) => { 14 | done() 15 | }) 16 | 17 | afterEach(() => { 18 | try { 19 | fs.statSync(logfile) 20 | fs.unlinkSync(logfile) 21 | } catch(e) { 22 | } 23 | }) 24 | 25 | describe('Public API', () => { 26 | it('Colors', () => { 27 | assert(Logger.Colors) 28 | }) 29 | 30 | it('LogLevels', () => { 31 | assert(Logger.Colors) 32 | }) 33 | 34 | it('setLogLevel', () => { 35 | assert(Logger.Colors) 36 | }) 37 | 38 | it('setLogfile', () => { 39 | assert(Logger.Colors) 40 | }) 41 | 42 | it('create', () => { 43 | assert(Logger.create) 44 | }) 45 | }) 46 | 47 | describe('create', () => { 48 | it('creates a logger', (done) => { 49 | const log = Logger.create('test1') 50 | assert(log) 51 | assert.equal(log.category, 'test1') 52 | done() 53 | }) 54 | 55 | it('uses default options', (done) => { 56 | const log = Logger.create('test1') 57 | assert(log) 58 | assert.equal(log.options.useColors, true) 59 | assert.equal(log.options.color, Logger.Colors.Default) 60 | assert.equal(log.options.showTimestamp, true) 61 | assert.equal(log.options.showLevel, true) 62 | assert.equal(log.options.filename, null) 63 | assert.equal(log.options.appendFile, true) 64 | done() 65 | }) 66 | 67 | it('sets options', (done) => { 68 | const options = { 69 | useColors: false, 70 | color: Logger.Colors.Yellow, 71 | showTimestamp: false, 72 | useLocalTime: true, 73 | showLevel: false, 74 | filename: 'test.log', 75 | appendFile: false, 76 | } 77 | 78 | const log = Logger.create('test1', options) 79 | assert(log) 80 | assert.equal(log.options.useColors, false) 81 | assert.equal(log.options.color, Logger.Colors.Yellow) 82 | assert.equal(log.options.showTimestamp, false) 83 | assert.equal(log.options.useLocalTime, true) 84 | assert.equal(log.options.showLevel, false) 85 | assert.equal(log.options.filename, 'test.log') 86 | assert.equal(log.options.appendFile, false) 87 | done() 88 | }) 89 | 90 | it('sets some options', (done) => { 91 | const options = { 92 | useColors: false, 93 | color: Logger.Colors.Yellow, 94 | } 95 | 96 | const log = Logger.create('test1', options) 97 | assert(log) 98 | assert.equal(log.options.useColors, false) 99 | assert.equal(log.options.color, Logger.Colors.Yellow) 100 | assert.equal(log.options.showTimestamp, true) 101 | assert.equal(log.options.useLocalTime, false) 102 | assert.equal(log.options.showLevel, true) 103 | assert.equal(log.options.filename, null) 104 | assert.equal(log.options.appendFile, true) 105 | done() 106 | }) 107 | }) 108 | 109 | describe('_write', () => { 110 | it('logs according to global log level: DEBUG', (done) => { 111 | let out = '' 112 | let old = console.log 113 | console.log = (d) => out += d 114 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 115 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 116 | log.debug("hi") 117 | console.log = old 118 | assert.equal(out, '[DEBUG] test1: hi') 119 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 120 | done() 121 | }) 122 | 123 | it('logs according to global log level: INFO', (done) => { 124 | let out = '' 125 | let old = console.log 126 | console.log = (d) => out += d 127 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 128 | Logger.setLogLevel(Logger.LogLevels.INFO) 129 | log.debug("hi") 130 | log.info("hi2") 131 | console.log = old 132 | assert.equal(out, '[INFO] test1: hi2') 133 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 134 | done() 135 | }) 136 | 137 | it('logs according to global log level: WARN', (done) => { 138 | let out = '' 139 | let old = console.log 140 | console.log = (d) => out += d 141 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 142 | Logger.setLogLevel(Logger.LogLevels.WARN) 143 | log.debug("hi") 144 | log.info("hi2") 145 | log.warn("hi3") 146 | console.log = old 147 | assert.equal(out, '[WARN] test1: hi3') 148 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 149 | done() 150 | }) 151 | 152 | it('logs according to global log level: ERROR', (done) => { 153 | let out = '' 154 | let old = console.log 155 | console.log = (d) => out += d 156 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 157 | Logger.setLogLevel(Logger.LogLevels.ERROR) 158 | log.debug("hi") 159 | log.info("hi2") 160 | log.warn("hi3") 161 | log.error("hi4") 162 | console.log = old 163 | assert.equal(out, '[ERROR] test1: hi4') 164 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 165 | done() 166 | }) 167 | 168 | it('logs according to global log level: NONE', (done) => { 169 | let out = '' 170 | let old = console.log 171 | console.log = (d) => out += d 172 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 173 | Logger.setLogLevel(Logger.LogLevels.NONE) 174 | log.debug("hi") 175 | log.info("hi2") 176 | log.warn("hi3") 177 | log.error("hi4") 178 | console.log = old 179 | assert.equal(out, '') 180 | Logger.setLogLevel(Logger.LogLevels.DEBUG) 181 | done() 182 | }) 183 | 184 | it('writes timestamp in iso time', (done) => { 185 | let out = '' 186 | let old = console.log 187 | // ignore seconds when comparing times 188 | let isoTime = new Date().toISOString().slice(0, 19) 189 | console.log = (d) => out += d 190 | const log = Logger.create('test1') 191 | log.debug("hi") 192 | console.log = old 193 | assert.equal(out.split(" ").length, 4) 194 | assert.equal(out.split(" ")[3], 'hi') 195 | let loggedTime = out.split(" ")[0].replace('\u001b[37m', '').slice(0, 19) 196 | assert.equal(isoTime, loggedTime) 197 | done() 198 | }) 199 | 200 | it('writes timestamp in local time', (done) => { 201 | let out = '' 202 | let old = console.log 203 | let localTime = new Date().toLocaleString() 204 | console.log = (d) => out += d 205 | const log = Logger.create('test1', {useLocalTime: true}) 206 | log.debug("hi") 207 | console.log = old 208 | let logArray = out.split(" ") 209 | assert.equal(logArray[logArray.length - 1], 'hi') 210 | let loggedTime = logArray.slice(0, logArray.length - 3).join(' ').replace('\u001b[37m', '') 211 | assert.equal(localTime, loggedTime) 212 | done() 213 | }) 214 | 215 | it('doesn\'t write timestamp', (done) => { 216 | let out = '' 217 | let old = console.log 218 | console.log = (d) => out += d 219 | const log = Logger.create('test1', { showTimestamp: false }) 220 | log.debug("hi") 221 | console.log = old 222 | assert.equal(out.split(" ").length, 3) 223 | assert.equal(out.split(" ")[2], 'hi') 224 | done() 225 | }) 226 | 227 | it('writes log level', (done) => { 228 | let out = '' 229 | let old = console.log 230 | console.log = (d) => out += d 231 | const log = Logger.create('test1', { useColors: false }) 232 | log.debug("hi") 233 | console.log = old 234 | assert.equal(out.split(" ").length, 4) 235 | assert.equal(out.split(" ")[1], '[DEBUG]') 236 | done() 237 | }) 238 | 239 | it('doesn\'t write log level', (done) => { 240 | let out = '' 241 | let old = console.log 242 | console.log = (d) => out += d 243 | const log = Logger.create('test1', { showLevel: false, useColors: false }) 244 | log.debug("hi") 245 | console.log = old 246 | assert.equal(out.split(" ").length, 3) 247 | assert.notEqual(out.split(" ")[1], '[DEBUG]') 248 | done() 249 | }) 250 | 251 | it('uses colors in terminal', (done) => { 252 | let out = '' 253 | let old = console.log 254 | console.log = (d) => out += d 255 | const log = Logger.create('test1', { useColors: true, showTimestamp: false }) 256 | log.debug("hi") 257 | console.log = old 258 | assert.equal(out, '\u001b[36;22m[DEBUG] \u001b[39;1mtest1\u001b[0m: hi') 259 | done() 260 | }) 261 | 262 | it('uses colors in browser', (done) => { 263 | let out = '' 264 | let old = console.log 265 | console.log = (d) => out += d 266 | Logger.forceBrowserMode(true) 267 | const log = Logger.create('test1', { useColors: true, showTimestamp: false }) 268 | log.debug("hi") 269 | console.log = old 270 | assert.equal(out, '%c[DEBUG] %ctest1: %chi') 271 | Logger.forceBrowserMode(false) 272 | done() 273 | }) 274 | 275 | it('doesn\'t use colors in terminal', (done) => { 276 | let out = '' 277 | let old = console.log 278 | console.log = (d) => out += d 279 | const log = Logger.create('test1', { useColors: false, showTimestamp: false }) 280 | log.debug("hi") 281 | console.log = old 282 | assert.equal(out, '[DEBUG] test1: hi') 283 | done() 284 | }) 285 | 286 | it('doesn\'t use colors in browser', (done) => { 287 | let out = '' 288 | let old = console.log 289 | console.log = (d) => out += d 290 | Logger.forceBrowserMode(true) 291 | const log = Logger.create('test1', { useColors: false, showTimestamp: false }) 292 | log.debug("hi") 293 | console.log = old 294 | assert.equal(out, '[DEBUG] test1: hi') 295 | Logger.forceBrowserMode(false) 296 | done() 297 | }) 298 | 299 | it('sets the logger name', (done) => { 300 | let out = '' 301 | let old = console.log 302 | console.log = (d) => out += d 303 | const log = Logger.create('test1234', { useColors: false }) 304 | log.debug("hi") 305 | console.log = old 306 | assert.equal(out.split(" ").length, 4) 307 | assert.equal(out.split(" ")[2], 'test1234:') 308 | done() 309 | }) 310 | 311 | it('formats strings using %d, %s', (done) => { 312 | let out = '' 313 | let old = console.log 314 | console.log = (d) => out += d 315 | const log = Logger.create('test1234', { useColors: false }) 316 | log.debug('hi %d %s', 314, 'THISISASTRING') 317 | console.log = old 318 | let result = out.split(' ').slice(3).join(' ') 319 | assert.equal(result, 'hi 314 THISISASTRING') 320 | done() 321 | }) 322 | }) 323 | 324 | describe('_write', () => { 325 | it('creates a log file', (done) => { 326 | const log = Logger.create('test1', { filename: logfile, appendFile: false, showTimestamp: false }) 327 | assert(!fs.existsSync(logfile)) 328 | log.debug('hello') 329 | assert(fs.existsSync(logfile)) 330 | done() 331 | }) 332 | 333 | it('writes to a log file', (done) => { 334 | const log = Logger.create('test1', { filename: logfile, appendFile: false, showTimestamp: false }) 335 | assert(!fs.existsSync(logfile)) 336 | log.debug('hello') 337 | assert(fs.existsSync(logfile)) 338 | const f = fs.readFileSync(logfile, 'utf-8') 339 | assert.equal(f, '[DEBUG] test1: hello\n') 340 | done() 341 | }) 342 | 343 | it('appends to a log file', (done) => { 344 | const log = Logger.create('test1', { filename: logfile, appendFile: true, showTimestamp: false }) 345 | assert(!fs.existsSync(logfile)) 346 | log.debug('hello') 347 | log.debug('hello2') 348 | assert(fs.existsSync(logfile)) 349 | const f = fs.readFileSync(logfile, 'utf-8') 350 | assert.equal(f, '[DEBUG] test1: hello\n[DEBUG] test1: hello2\n') 351 | done() 352 | }) 353 | 354 | it('writes to a global log file', (done) => { 355 | const log1 = Logger.create('test1', { showTimestamp: false }) 356 | const log2 = Logger.create('test2', { showTimestamp: false }) 357 | Logger.setLogfile(logfile) 358 | log1.debug('hello1') 359 | log2.debug('hello2') 360 | assert(fs.existsSync(logfile)) 361 | const f = fs.readFileSync(logfile, 'utf-8') 362 | assert.equal(f, '[DEBUG] test1: hello1\n[DEBUG] test2: hello2\n') 363 | done() 364 | }) 365 | 366 | }) 367 | 368 | describe('LOG environment variable', () => { 369 | it('logs according to LOG environment variable', (done) => { 370 | let out = '' 371 | let old = console.log 372 | console.log = (d) => out += d 373 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 374 | Logger.setLogLevel(Logger.LogLevels.NONE) 375 | process.env.LOG = 'debug' 376 | log.warn("hi") 377 | console.log = old 378 | assert.equal(out, '[WARN] test1: hi') 379 | delete process.env.LOG 380 | done() 381 | }) 382 | }) 383 | 384 | describe('emits events', () => { 385 | const log = Logger.create('test1', { showTimestamp: false, useColors: false }) 386 | 387 | it('emits \'data\'', (done) => { 388 | Logger.setLogLevel(Logger.LogLevels.WARN) 389 | Logger.events.on('data', (source, level, text) => { 390 | assert.equal(source, 'test1') 391 | assert.equal(level, 'WARN') 392 | assert.equal(text, 'hi') 393 | Logger.events.removeAllListeners('data') 394 | done() 395 | }) 396 | log.warn("hi") 397 | }) 398 | 399 | it('doesn\'t emit \'data\' when below log level', (done) => { 400 | Logger.setLogLevel(Logger.LogLevels.NONE) 401 | Logger.events.on('data', (source, level, text) => { 402 | console.log(source) 403 | assert.equal('Should not fire data event', null) 404 | }) 405 | log.warn("hi") 406 | setTimeout(() => { 407 | Logger.events.removeAllListeners('data') 408 | done() 409 | }, 100) 410 | }) 411 | }) 412 | 413 | }) 414 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --reporter spec 2 | --colors 3 | --recursive 4 | --exit -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | 3 | module.exports = { 4 | entry: './src/index.js', 5 | output: { 6 | libraryTarget: 'var', 7 | library: 'Logger', 8 | filename: './dist/logplease.min.js' 9 | }, 10 | node: { 11 | console: false, 12 | process: 'mock' 13 | }, 14 | plugins: [ 15 | new webpack.optimize.UglifyJsPlugin({ 16 | mangle: true, 17 | compress: { warnings: false } 18 | }) 19 | ], 20 | module: { 21 | rules: [{ 22 | test: /\.js$/, 23 | exclude: /node_modules/, 24 | loader: 'babel-loader', 25 | options: { 26 | presets: require.resolve('babel-preset-es2015'), 27 | plugins: require.resolve('babel-plugin-transform-runtime') 28 | } 29 | }] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /webpack.example.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './example/example.js', 3 | output: { 4 | filename: './example/bundle.js' 5 | }, 6 | node: { 7 | console: false, 8 | process: 'mock' 9 | }, 10 | module: { 11 | rules: [{ 12 | test: /\.js$/, 13 | exclude: /node_modules/, 14 | loader: 'babel-loader', 15 | options: { 16 | presets: ['es2015'], 17 | plugins: ['transform-runtime'] 18 | } 19 | }] 20 | } 21 | } 22 | --------------------------------------------------------------------------------